CSS: aspect ratio animation
Inspired by https://twitter.com/ryanseddon/status/1026321377228349440
by Julien Roche
HTML
<h1>Natural ratio</h1>
<img class="ratio-image" src="https://images.pexels.com/photos/289225/pexels-photo-289225.jpeg?auto=compress&cs=tinysrgb&h=650&w=940" />
CSS
:root {
--animation-duration: 2s;
--ratio-width: 100vw;
--ratio-height-16-9: calc(var(--ratio-width) * 9 / 16);
--ratio-height-21-9: calc(var(--ratio-width) * 9 / 21);
--ratio-height-4-3: calc(var(--ratio-width) * 3 / 4);
}
html,
body {
border: none;
margin: 0 0 0 0;
padding: 0 0 0 0;
}
img {
height: 539px;
width: 940px;
transition-delay: 0s;
transition-duration: var(--animation-duration);
transition-property: all;
transition-timing-function: ease;
}
.ratio-image--none {
height: 539px;
width: 940px;
}
.ratio-image--21-9 {
height: var(--ratio-height-21-9);
width: var(--ratio-width);
}
.ratio-image--16-9 {
height: var(--ratio-height-16-9);
width: var(--ratio-width);
}
.ratio-image--4-3 {
height: var(--ratio-height-4-3);
width: var(--ratio-width);
}
Babel + JSX
const imageElement = document.querySelector('img');
const durationTime = 2000;
const ratios = [
'ratio-image--none',
'ratio-image--21-9',
'ratio-image--16-9',
'ratio-image--4-3'
];
let index = 1;
function debounce (fn, time) {
let timeout;
return function() {
const functionCall = () => fn.apply(this, arguments);
clearTimeout(timeout);
timeout = setTimeout(functionCall, time);
}
}
function changeImageRatio() {
console.info('apply', ratios[index]);
imageElement.classList.value = ratios[index];
index++;
if (index > ratios.length) {
index = 0;
}
}
imageElement.addEventListener('transitionend', debounce(changeImageRatio, 150), false);
changeImageRatio();