<h1 id="heading">
<div class="fills">
<div>
<span class="fill fill1">Strategy</span>
</div>
<div>
<div class="fill fill2">meets</div>
</div>
<div>
<span class="fill fill3">Creativity</span>
</div>
</div>
<div class="masks">
<div>
<span class="mask mask1">Strategy</span>
</div>
<div>
<div class="mask mask2">meets</div>
</div>
<div>
<span class="mask mask3">Creativity</span>
</div>
</div>
</h1>
:root {
--clip-position: 50% 50%;
--mask-position: 50% 50%;
}
body {
display: flex;
justify-content: center;
align-items: center;
background: url(https://i.imgur.com/6VI2vU9.jpg) no-repeat center;
background-size: cover;
min-height: 100vh;
padding-top: 2rem;
padding-bottom: 2rem;
}
h1 {
position: relative;
font-family: 'Open Sans', 'Arial', sans-serif;
font-size: 130px;
font-weight: 800;
letter-spacing: -0.04em;
line-height: 0.875;
text-transform: uppercase;
text-align: center;
width: 45rem;
overflow: hidden;
cursor: default;
.fill2,
.mask2 {
font-size: 100px;
font-weight: 300;
letter-spacing: 0.04em;
}
.fills {
// display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
.fill {
&.fill1,
&.fill3{
color: #E0E0E0;
}
&.fill2 {
color: rgb(119,170,193);
}
}
}
.masks {
clip-path: circle(400px at var(--clip-position));
-webkit-mask-image: radial-gradient(circle, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 66%);
-webkit-mask-size: 500px 500px;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: var(--mask-position);
.mask {
display: block;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
&.mask1 {
background-image: url(https://images.unsplash.com/photo-1496096265110-f83ad7f96608?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80); //jpg/png/gif/svg work
}
&.mask2 {
background-image: url(https://i.imgur.com/K62kzNz.jpg);
}
&.mask3 {
background-image: url(https://images.unsplash.com/photo-1524856781660-e5c92f4ac62a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80); //jpg/png/gif/svg work
}
}
}
}
@media only screen and (min-width: 1400px) {
h1 {
font-size: 230px;
width: 79rem;
.fill2,
.mask2 {
font-size: 150px;
}
.masks {
clip-path: circle(800px at var(--clip-position));
-webkit-mask-size: 800px 800px;
}
}
}
View Compiled
const mask = $('h1 .masks')
// Mousemove
window.addEventListener('mousemove', e => {
let halfMaskSize = 250
if (window.innerWidth >= 1400) {
halfMaskSize = 400
}
let h1 = document.getElementById('heading'),
h1Pos = h1.getBoundingClientRect(),
h1Width = h1.offsetWidth,
h1Height = h1.offsetHeight,
clipX = e.clientX - h1Pos.left,
clipY = e.clientY - h1Pos.top,
maskX = e.clientX - h1Pos.left - halfMaskSize,
maskY = e.clientY - h1Pos.top - halfMaskSize
// If cursor outside bounds of H1 set positions at bounds
if (e.clientY <= h1Pos.top) { //Top
clipY = 0
maskY = -(halfMaskSize)
}
if (e.clientX >= h1Pos.left + h1Width) { //Right
clipX = h1Width
maskX = -(halfMaskSize * 0.75) + h1Width
}
if (e.clientY >= h1Pos.top + h1Height) { //Bottom
clipY = h1Height
maskY = -(halfMaskSize * 0.75) + h1Height
}
if (e.clientX <= h1Pos.left) { //Left
clipX = 0
maskX = -(halfMaskSize)
}
// Change clip & mask position using GSAP
gsap.to(mask, {
duration: 1,
'--mask-position': maskX + 'px ' + maskY + 'px',
'--clip-position': clipX + 'px ' + clipY + 'px'
})
})