#javascript #css #animation #css-animations
#javascript #css #Анимация #css-анимации
Вопрос:
Вчера я просматривал Интернет и нашел этот замечательный веб-сайт:https://durimel.io/nel . Просто посмотрите, как перечислены его работы… бесконечный список, в котором работает даже перекос при прокрутке мышью.
Мне нравится эта штука! Итак, я начал думать о том, как это можно было бы сделать, и начал немного экспериментировать самостоятельно. Я хочу прояснить, что моей целью не является копирование работы Лайонела… Я просто хочу научиться и понять, как создать такую фантастическую анимацию! (И, возможно, использовать некоторые похожие концепции в будущем 😊)
Теперь к моему вопросу: если вы посмотрите на мой код, я думаю, что мой список (более или менее) движется вправо. Оно бесконечно, оно прокручивается быстрее или медленнее в зависимости от того, сколько раз используется колесо мыши. Что касается этого, все должно быть в порядке 😜
Но функция skew() ведет себя некорректно. Чего мне здесь не хватает? У него нет реального / хорошего ускорения, поскольку он не искажается меньше при одном прокручивании или больше при более длинных прокрутках. Кроме того, если вы пытаетесь последовательно прокручивать вверх и вниз, это запаздывает и сотрясается. Как я могу решить эту проблему?
Вот мой код на данный момент. И, пожалуйста, не спрашивайте меня, почему я использовал такие странные числа или вычисления… Я не знаю, я просто играл с ними 😂
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TEST</title>
<style>
body {
overflow: hidden;
}
ul {
list-style: none;
}
li {
display: inline;
padding: 30px;
font-size: 90pt;
font-weight: bold;
border: solid 1px red;
position: absolute;
white-space: nowrap;
transform-origin: 50% 100%;
}
</style>
</head>
<body>
<ul>
<li>bla bla</li>
<li>adsf</li>
<li>234 777</li>
<li>jhgj</li>
<li>shsh hshs</li>
<li>looool</li>
<li>gaga</li>
</ul>
<script>
let a = document.getElementsByTagName('li');
let ticking = false;
let trans3d = 0;
let listEnd = 0;
let listStart = 0;
window.onload = function () {
let pos = 0;
for (let i = 0; i < a.length; i ) {
let prev = (i > 0) ? a[i - 1].offsetWidth 20 : 0;
pos = prev;
a[i].style.left = pos "px";
if (pos >= listEnd) {
listEnd = pos a[i].offsetWidth 20;
}
if (pos <= listStart) {
listStart = pos;
}
}
}
function changeListPos(item, moveToEnd) {
if (moveToEnd) {
item.style.left = listEnd "px";
listEnd = item.offsetWidth 20;
listStart = item.offsetWidth 20;
} else {
listStart -= item.offsetWidth 20;
listEnd -= item.offsetWidth 20;
item.style.left = listStart "px";
}
}
function scrollContent(scroll_pos) {
let qtyScroll = 40;
let easeOutSine = function (t, b, c, d) {
return c * Math.sin(t / d * (Math.PI / 2)) b;
};
for (let i = 0; i < qtyScroll; i ) {
(function (x) {
setTimeout(function () {
trans3d = easeOutSine(x, ((qtyScroll - x)) / 14, 0.05, qtyScroll) * (scroll_pos / Math.abs(scroll_pos));
let skew = easeOutSine(x, ((qtyScroll - x)) / 6, 0.05, qtyScroll) * (scroll_pos / Math.abs(scroll_pos));
console.log(skew);
for (let j = 0; j < a.length; j ) {
let prev = (j == 0) ? a[a.length - 1] : a[j - 1]
let curr = a[j];
if (scroll_pos < 0 amp;amp; curr.getBoundingClientRect().x < -(prev.getBoundingClientRect().width / 4) amp;amp; parseInt(prev.style.left) < parseInt(curr.style.left)) {
changeListPos(prev, true);
} else if (scroll_pos > 0 amp;amp; curr.getBoundingClientRect().x >= -(prev.getBoundingClientRect().width / 4) amp;amp; parseInt(prev.style.left) > parseInt(curr.style.left)) {
changeListPos(prev, false);
}
curr.style.transform = "skew(" skew "deg) translate3d(" trans3d "px, 0px, 0px)";
}
}, 55 * (x / 3));
})(i);
}
}
(function (window, document) {
let prefix = "", _addEventListener, support;
// detect event model
if (window.addEventListener) {
_addEventListener = "addEventListener";
} else {
_addEventListener = "attachEvent";
prefix = "on";
}
// detect available wheel event
support = "onwheel" in document.createElement("div") ? "wheel" : // Modern browsers support "wheel"
document.onmousewheel !== undefined ? "mousewheel" : // Webkit and IE support at least "mousewheel"
"DOMMouseScroll"; // let's assume that remaining browsers are older Firefox
window.addWheelListener = function (elem, callback, useCapture) {
_addWheelListener(elem, support, callback, useCapture);
// handle MozMousePixelScroll in older Firefox
if (support == "DOMMouseScroll") {
_addWheelListener(elem, "MozMousePixelScroll", callback, useCapture);
}
};
function _addWheelListener(elem, eventName, callback, useCapture) {
elem[_addEventListener](prefix eventName, support == "wheel" ? callback : function (originalEvent) {
!originalEvent amp;amp; (originalEvent = window.event);
// create a normalized event object
var event = {
// keep a ref to the original event object
originalEvent: originalEvent,
target: originalEvent.target || originalEvent.srcElement,
type: "wheel",
deltaMode: originalEvent.type == "MozMousePixelScroll" ? 0 : 1,
deltaX: 0,
deltaY: 0,
deltaZ: 0,
preventDefault: function () {
originalEvent.preventDefault ?
originalEvent.preventDefault() :
originalEvent.returnValue = false;
}
};
// calculate deltaY (and deltaX) according to the event
if (support == "mousewheel") {
event.deltaY = -1 / 40 * originalEvent.wheelDelta;
// Webkit also support wheelDeltaX
originalEvent.wheelDeltaX amp;amp; (event.deltaX = -1 / 40 * originalEvent.wheelDeltaX);
} else {
event.deltaY = originalEvent.deltaY || originalEvent.detail;
}
// it's time to fire the callback
return callback(event);
}, useCapture || false);
}
})(window, document);
addWheelListener(window, function (e) {
if (!ticking) {
window.requestAnimationFrame(function () {
scrollContent(e.deltaY);
ticking = false;
});
ticking = true;
}
});
</script>
</body>
</html>
Ответ №1:
Если вы добавите задержку перехода на skew
для li
элементов, перекосом будет чувствовать себя немного более «реалистичным»
transition: skew 1.5s;
В вашем блоке стилей:
<style>
body {
overflow: hidden;
}
ul {
list-style: none;
}
li {
display: inline;
padding: 30px;
font-size: 90pt;
font-weight: bold;
border: solid 1px red;
position: absolute;
white-space: nowrap;
transform-origin: 50% 100%;
transition: skew 1.5s;
}
</style>
Если вы хотите изменить угол перекоса, просто измените код, в котором skew
переменная инициируется внутри scrollContent()
функции:
let skew = easeOutSine(x, ((qtyScroll - x)) / 6, 0.1, qtyScroll) * (scroll_pos / Math.abs(scroll_pos));
Вы можете, например, изменить / 6
на / 3
, чтобы получить больше skew
. Если вы сделаете это, вы можете вместо этого увеличить transition: skew
до 2 или 3 секунд.