<!-- Forked from: https://codepen.io/creativeocean/pen/ByBogvj -->
<div class="pov">
<div class="tray">
<div class="die">
<div class="cube">
<div class="face" style="font-size:60px">ProductDesign</div>
<div class="face" style="font-size:58px">UserExperience</div>
<div class="face" style="font-size:55px">UserInterface</div>
</div>
</div>
<!-- clones will go here -->
</div>
</div>
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@900&display=swap');
html, body {
font-family: "Montserrat", sans-serif;
font-optical-sizing: auto;
font-weight: 900;
font-style: normal;
background:#000;
overflow:hidden;
}
body, pov {
width:100%;
height:100vh;
display: flex;
align-items: center;
justify-content: center;
}
.die {
width: 400px;
height: 55px;
padding-bottom: 9px;
perspective: 999px;
}
.cube {
position: absolute;
width:100%;;
height:100%;
transform-style: preserve-3d;
}
.face {
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
/* letter-spacing:-1px; */
backface-visibility: hidden;
/* overflow:hidden; */
}
const n = 19
const rots = [
{ ry: 270, a:0.5 },
{ ry: 0, a:0.85 },
{ ry: 90, a:0.4 },
{ ry: 180, a:0.0 }
]
gsap.set(".face", {
z: 200,
rotateY: i => rots[i].ry,
transformOrigin: "50% 50% -201px"
});
for (let i=0; i<n; i++){
let die = document.querySelector('.die')
let cube = die.querySelector('.cube')
if (i>0){
let clone = document.querySelector('.die').cloneNode(true);
document.querySelector('.tray').append(clone);
cube = clone.querySelector('.cube')
}
gsap.timeline({repeat:-1, yoyo:true, defaults:{ease:'power3.inOut', duration:1}})
.fromTo(cube, {
rotateY:-90
},{
rotateY:90,
ease:'power1.inOut',
duration:2
})
.fromTo(cube.querySelectorAll('.face'), {
color:(j)=>'hsl('+(i/n*75+130)+', 67%,'+(100*[rots[3].a, rots[0].a, rots[1].a][j])+'%)'
},{
color:(j)=>'hsl('+(i/n*75+130)+', 67%,'+(100*[rots[0].a, rots[1].a, rots[2].a][j])+'%)'
}, 0)
.to(cube.querySelectorAll('.face'), {
color:(j)=>'hsl('+(i/n*75+130)+', 67%,'+(100*[rots[1].a, rots[2].a, rots[3].a][j])+'%)'
}, 1)
.progress(i/n)
}
gsap.timeline()
.from('.tray', {yPercent:-3, duration:2, ease:'power1.inOut', yoyo:true, repeat:-1}, 0)
.fromTo('.tray', {rotate:-15},{rotate:15, duration:4, ease:'power1.inOut', yoyo:true, repeat:-1}, 0)
.from('.die', {duration:0.01, opacity:0, stagger:{each:-0.05, ease:'power1.in'}}, 0)
.to('.tray', {scale:1.2, duration:2, ease:'power3.inOut', yoyo:true, repeat:-1}, 0)
window.onload = window.onresize = ()=> {
const h = n*56
gsap.set('.tray', {height:h})
gsap.set('.pov', {scale:innerHeight/h})
}
This Pen doesn't use any external CSS resources.