<div class="tilebase">
<div class="tilemask" style="--depth: 0;"></div>
<div class="tilemask" style="--depth: 1;"></div>
<div class="tilemask" style="--depth: 2;"></div>
<div class="tilemask" style="--depth: 3;"></div>
<div class="tilemask" style="--depth: 4;"></div>
<div class="tilemask" style="--depth: 5;"></div>
<div class="tilemask" style="--depth: 6;"></div>
</div>
<div class="tile">
Tile:<br>
<input type="range" step="0.25" value="2" min="0.25" max="3" oninput="tile(this.value)">
</div>
<a style="position: absolute; bottom: 1rem; left: 50%; transform: translateX(-50%); color: white;" href="http://jane.propjockey.io/">Follow me on Twitter!</a>
<div class="accents">
Accent:
<label><input type="radio" name="accent" onclick="accent('initial')" checked> None</label>
<label><input type="radio" name="accent" onclick="accent('gold')"> Gold</label>
<label><input type="radio" name="accent" onclick="accent('cyan')"> Cyan</label>
<label><input type="radio" name="accent" onclick="accent('rebeccapurple')"> Purple</label>
<label><input type="radio" name="accent" onclick="accent('red')"> Red</label>
<label><input type="radio" name="accent" onclick="accent('white')"> White</label>
<label><input type="radio" name="accent" onclick="accent('black')"> Black</label>
</div>
* {
box-sizing: border-box;
margin: 0px;
padding: 0px;
font-family: sans-serif;
}
body {
display: grid;
height: 100vh;
overflow: hidden;
background: radial-gradient(circle at right, #8a8655, #62633a, #2c3416, #0c1800 80%);
}
.tilebase {
--wall: 512px;
--tile: 2;
--size: calc(var(--wall) / var(--tile));
--offset: (var(--size) / 40);
position: relative;
margin: auto;
transform-style: preserve-3d;
transform: perspective(2019px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateZ(50px);
width: var(--wall);
height: var(--wall);
background: var(--accent, url(https://i.imgur.com/lY6jkFw.png) 0 100% / var(--size) var(--size));
/* original/unmodified source of image: https://www.flickr.com/photos/robertjewett/25131705462/ */
}
.tilebase .tilemask {
position: absolute;
width: 100%;
height: 100%;
background: url(https://i.imgur.com/lY6jkFw.png) 0 100% / var(--size) var(--size);
transform: translateZ(calc(var(--depth) * var(--offset)));
-webkit-mask: url(https://i.imgur.com/0YebqQu.png) left 0 bottom calc(var(--size) * (var(--depth) + 1)) / var(--size) calc(var(--size) * 7);
mask: url(https://i.imgur.com/0YebqQu.png) left 0 bottom calc(var(--size) * (var(--depth) + 1)) / var(--size) calc(var(--size) * 7);
}
.accents {
font-weight: bold;
color: white;
position: absolute;
bottom: 0px;
right: 0px;
width: 7rem;
padding: 1rem;
}
.accents label {
display: block;
padding: 0.25rem;
}
.accents input {
float: right;
margin-top: 0.125rem;
}
.tile {
padding: 1rem;
font-weight: bold;
color: white;
text-align: center;
position: absolute;
left: 50%;
top: 0px;
transform: translateX(-50%);
}
const b = document.body
const t = b.querySelector(".tilebase")
b.addEventListener("pointermove", ev => {
const ang = 30
const w = (b.offsetWidth / 2)
const x = ev.pageX - w
const ax = Math.abs(x)
const sx = x === 0 ? 0 : x / ax
const h = (b.offsetHeight / 2)
const y = ev.pageY - h
const ay = Math.abs(y)
const sy = y === 0 ? 0 : (y / ay * -1)
const rx = Math.min(ang, ay / Math.min(512, h) * ang) * sy + "deg"
const ry = Math.min(ang, ax / Math.min(512, w) * ang) * sx + "deg"
t.style.setProperty("--rx", rx)
t.style.setProperty("--ry", ry)
})
const accent = c => {
t.style.setProperty("--accent", c)
}
const tile = v => {
t.style.setProperty("--tile", v)
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.