JSFiddle - React, Tailwind, and code Playground
by Константин Дралюк
HTML
<div class="box" id="b">
<div>
<img src="https://cms-assets.tutsplus.com/uploads/users/107/posts/25888/image/flat-icon-design6-%5BConverted%5D.jpg" alt="" id="i">
</div>
<div class="xor-text -nixie" data-text="Nixie">Nixie</div>
<div class="xor-text -core" data-text="Core">Core</div>
</div>
CSS
body {
margin: 100px;
}
.box {
transform-style: preserve-3d;
perspective: 1000px;
display: table;
}
img {
width: 600px;
height: 400px;
display: block;
}
.xor-text {
position: absolute;
font-size: 50px;
font-weight: bold;
text-transform: uppercase;
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
color: transparent;
user-select: none;
pointer-events: none;
}
.xor-text:after, .xor-text:before {
content: attr(data-text);
position: absolute;
left: 0;
top: 0;
white-space: nowrap;
}
.xor-text:before {
mix-blend-mode: overlay;
color: #000;
}
.xor-text:after {
mix-blend-mode: color-dodge;
color: #fff;
}
.xor-text.-nixie {
left: -.65em;
top: 1em;
}
.xor-text.-core {
right: -.6em;
bottom: 1em;
}
#i {
transition: 1s ease-out;
}
JavaScript
const getCssString = (rx = 0, ry = 0, delta = 0.02, deep = 200) => {
return `rotateX(${rx * delta}deg) rotateY(${ry * delta}deg) translateZ(${deep}px) scale(${1 - deep / 1000})`
}
b.addEventListener('mousemove', e => {
const rects = b.getClientRects()[0]
const mouseX = e.offsetX - rects.width / 2
const mouseY = e.offsetY - rects.height / 2
i.style.transform = getCssString(-mouseY, mouseX, 0.05, 200)
t.style.transform = getCssString(-mouseY, mouseX, 0.05, 200)
})
b.addEventListener('mouseleave', e => {
i.style.transform = ''
})