Горизонтальная анимация при вертикальной прокрутке
Есть изображение вагона поезда. Хочу сделать эффект бесконечного движения вагонов слева направо при прокрутке страницы вниз. Этот поезд будет размещён в фиксированном блоке, прилипшем к низу браузера. Посоветуйте пожалуйста, как лучше сделать этот эффект анимации, и как его связать с прокруткой? Спасибо.
Ответы (1 шт):
Автор решения: Vladislav G.
→ Ссылка
Как-то так
const trainOptions = {
width: 300,
space: 20,
speed: 0.2,
scrollTrigger: null
};
function initTarin (container, template) {
container.innerHTML = '';
const count = Math.ceil(container.offsetWidth / trainOptions.width) + 2;
for (let i = 0; i < count; i++) {
container.append(template.cloneNode(true));
}
container.scrollLeft = trainOptions.width + trainOptions.space;
trainOptions.scrollTrigger = trainOptions.width;
}
function checkScroll (container, template, sign) {
if (sign && container.scrollLeft <= trainOptions.scrollTrigger) {
container.prepend(template.cloneNode(true));
container.children[container.children.length - 1].remove();
container.scrollLeft = trainOptions.scrollTrigger * 2 + trainOptions.space;
}
else if (!sign && container.scrollLeft >= container.scrollWidth - container.offsetWidth - trainOptions.scrollTrigger) {
container.append(template.cloneNode(true));
container.children[0].remove();
container.scrollLeft = container.scrollWidth - container.offsetWidth - trainOptions.scrollTrigger * 2 - trainOptions.space;
}
}
function initContent (container) {
for (let i = 0; i < 20; i++) {
const content = document.createElement('p');
content.textContent = 'много какого то контента';
content.classList.add('content');
container.append(content);
}
}
(function app () {
const page = document.body;
const trainContainer = document.querySelector('.train-container');
const trainTemplate = document.querySelector('#train-template').content.querySelector('.train');
initContent(page);
initTarin(trainContainer, trainTemplate);
page.addEventListener('wheel', evt => {
trainContainer.scrollLeft += -evt.deltaY * trainOptions.speed;
const sign = evt.deltaY > 0 ? true : false;
checkScroll(trainContainer, trainTemplate, sign);
});
new ResizeObserver(() => {
initTarin(trainContainer, trainTemplate);
}).observe(trainContainer);
})();
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.page {
background-color: #333;
}
.content {
margin: 20px auto;
padding: 200px 0;
width: 50%;
background-color: rgba(80, 80, 100, 0.5);
border-radius: 20px;
color: #fff;
text-align: center;
}
.train-container {
position: fixed;
bottom: 0;
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
height: 200px;
background-color: #222;
overflow: hidden;
z-index: -1;
}
.train {
display: flex;
flex-direction: row;
justify-content: space-evenly;
margin-left: 20px;
padding-top: 20px;
min-width: 300px;
height: 50%;
border-radius: 8px;
background-color: #575;
}
.window {
width: 30px;
height: 30px;
border-radius: 6px;
background-color: #ddf;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body class="page">
<div class="train-container"></div>
<template id="train-template">
<div class="train">
<div class="window"></div>
<div class="window"></div>
<div class="window"></div>
<div class="window"></div>
<div class="window"></div>
</div>
</template>
<script src="main.js"></script>
</body>
</html>