<div class="z">
<div class="x">
<div class="y">
<b class="r"></b>
</div>
</div>
<div class="x">
<div class="y">
<span class="r"></span>
</div>
</div>
<div class="x">
<div class="y">
<p class="r"></p>
</div>
</div>
</div>
:root {
--primary: hsl(153, 70%, 60%);
--secondary: hsl(323, 70%, 60%);
--tertiary: hsl(43, 70%, 60%);
--x: 0;
--y: 0;
--z: 0;
--r: 0deg;
--rotation: var(--r);
--scale: .875;
--cubic1-1: .85;
--cubic1-2: .18;
--cubic1-3: .44;
--cubic1-4: 1.2;
--cubic2-1: .75;
--cubic2-2: -0.35;
--cubic2-3: 0;
--cubic2-4: .9;
--cubic1-change: 1;
--cubic2-change: 1;
--dim: 6vmin;
}
span, p, b, i {
display: block;
width: var(--dim);
height: var(--dim);
border-radius: 10%;
background: var(--primary);
}
p {
background: var(--secondary);
}
b {
background: var(--tertiary);
}
div {
will-change: transform;
transition: transform 1200ms ease-in-out;
}
.x {
transform: translateX(calc(var(--x) * 1px));
transition-timing-function: cubic-bezier(.85,.18,.44,1.2);
transition-timing-function: cubic-bezier(var(--cubic1-1),var(--cubic1-2),var(--cubic1-3),var(--cubic1-4));
position: absolute;
}
.advanced-calc .x {
transition-timing-function:
cubic-bezier(
calc(var(--cubic1-1) * var(--cubic1-change)),
calc(var(--cubic1-2) * var(--cubic1-change)),
calc(var(--cubic1-3) * var(--cubic1-change)),
calc(var(--cubic1-4) * var(--cubic1-change)));
}
.x:nth-of-type(2) {
--cubic1-change: .9;
}
.x:nth-of-type(3) {
--cubic1-change: .8;
}
.y {
transform: translateY(calc(var(--y) * 1px));
transition-timing-function: cubic-bezier(.75,-0.35,.07,.9);
transition-timing-function: cubic-bezier(var(--cubic2-1),var(--cubic2-2),var(--cubic2-3),var(--cubic2-4));
}
.advanced-calc .y {
transition-timing-function:
cubic-bezier(
calc(var(--cubic2-1) * var(--cubic2-change)),
calc(var(--cubic2-2) * var(--cubic2-change)),
calc(var(--cubic2-3) * var(--cubic2-change)),
calc(var(--cubic2-4) * var(--cubic2-change)));
}
.x:nth-of-type(2) .y {
--cubic2-change: .9;
}
.x:nth-of-type(3) .y {
--cubic2-change: .8;
}
.let-us-move-it .y {
//transition-timing-function: linear;
}
.z {
transform: translateZ(calc(var(--z) * 1px));
transition-timing-function: ease-in-out;
}
.r {
transform: translate3d(-50%, -50%, 0) scale(var(--scale));
transform: translate3d(-50%, -50%, 0) scale(var(--scale)) rotate(var(--rotation));
transition: transform 1200ms ease-in-out;
}
b.r {
--scale: .95;
}
p.r {
--scale: .8;
}
.advanced-calc b.r {
--rotation: calc(var(--r) * .5);
}
.advanced-calc p.r {
--rotation: calc(var(--r) * 1.5);
}
body {
min-height: 100vh;
overflow: hidden;
background: hsl(203, 28%, 12%);
perspective: 1000px;
perspective-origin: center center;
}
document.documentElement.classList.add(isCalcSupported() ? 'advanced-calc' : 'basic-calc');
if (window.PointerEvent) {
document.body.addEventListener('pointerup', jumpFromInteraction);
} else {
document.body.addEventListener('mouseup', jumpFromInteraction);
document.body.addEventListener('touchend', jumpFromInteraction);
}
var style = document.documentElement.style;
function jumpFromInteraction(e) {
if (beforeInteractionInterval) {
clearInterval(beforeInteractionInterval);
beforeInteractionInterval = undefined;
}
jump(e);
}
//Translate to the new point
function jump(e) {
var x = e.clientX || e.changedTouches[0].clientX;
var y = e.clientY || e.changedTouches[0].clientY;
var z = 0;//Math.random() * (-300);
var r = Math.random() * 720 - 360;
style.setProperty('--x', x);
style.setProperty('--y', y);
//style.setProperty('--z', z);
style.setProperty('--r', r + 'deg');
changeEasing();
}
//Change the four points of the cubic-bezier to up the non-linear ante
function changeEasing() {
style.setProperty('--cubic1-1', part(.8, .15));
style.setProperty('--cubic1-2', part(.1, .2));
style.setProperty('--cubic1-3', part(.35, .25));
style.setProperty('--cubic1-4', part(1, .25));
style.setProperty('--cubic2-1', part(.7, .15));
style.setProperty('--cubic2-2', part(-.35, .35));
style.setProperty('--cubic2-3', part(0, .1));
style.setProperty('--cubic2-4', part(.8, .2));
}
function part(min, offset) {
return Math.random() * offset + min;
}
//Do automatic animations while waiting for viewer to interact
setTimeout(freeJump,100);
let beforeInteractionInterval = setInterval(freeJump, 1200);
let freeJumpCount=0;
function freeJump() {
jump({
clientX: Math.floor(((freeJumpCount) % 4 < 2 ? (Math.random() * .3 + .7) : (Math.random() * .4 + .01)) * window.innerWidth),
clientY: Math.floor(((freeJumpCount++) % 2 == 0 ? (Math.random() * .2 + .8) : (Math.random() * .2 + .01)) * window.innerHeight)
});
}
//Check if Calc is supported inside cubic-bezier (ultimately a check to see if we are in Firefox)
function isCalcSupported() {
document.body.style.transitionTimingFunction = 'cubic-bezier(calc(1 * 1),calc(1 * 1),calc(1 * 1),calc(.5 * 1))';
return getComputedStyle(document.body).transitionTimingFunction != 'ease';
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.