如何在anime.js中使用“seek”来控制滚动时的动画?请举个例子
Posted
技术标签:
【中文标题】如何在anime.js中使用“seek”来控制滚动时的动画?请举个例子【英文标题】:How to use "seek" in anime.js in order to control an animation while scrolling? With example, please 【发布时间】:2019-09-20 02:50:20 【问题描述】:更新的anime.js文档(Controls->Seek)说可以在滚动的时候控制动画,但是没有例子。
谁能举例说明如何设置animation.seek?
https://animejs.com/documentation/#seekAnim
var animation = anime(
targets: '.seek-anim-demo .el',
translateX: 270,
delay: function(el, i) return i * 100; ,
elasticity: 200,
easing: 'easeInOutSine',
autoplay: false
);
var seekProgressEl = document.querySelector('.seek-anim-demo .progress');
seekProgressEl.oninput = function()
animation.seek(animation.duration * (seekProgressEl.value / 100));
;
【问题讨论】:
【参考方案1】:这就是你要找的。p>
function getScrollPercent()
var h = document.documentElement,
b = document.body,
st = 'scrollTop',
sh = 'scrollHeight';
return (h[st] || b[st]) / ((h[sh] || b[sh]) - h.clientHeight) * 100;
const
// parent = document.querySelector('.outerHeight'),
els = document.querySelectorAll('.el'),
tl = anime.timeline( autoplay: false );
_.map(els, el =>
anime.set(el,
top: anime.random(0, 150) + 'vh',
left: anime.random(0, 100) + 'vw' );
tl.add(
targets: el,
translateX: anime.random(-500, 500) + '%',
translateY: anime.random(-500, 500) + '%',
scale: anime.random(0.3, 1.7),
rotate: anime.random(-365, 365) + 'deg',
duration: anime.random(500, 5000), easing: 'easeInOutCirc' ,
0);
);
// new AnimePlayer( add: tl )
window.addEventListener('scroll', () =>
const persentage = getScrollPercent();
tl.seek(tl.duration * (persentage * 0.01));
);
来源:Codepen (https://codepen.io/gaougalos/pen/bJXYZa)
【讨论】:
非常感谢您的示例。您知道是否有任何方法可以添加阻尼/平滑效果?例如,当滚动停止时,动画不会突然停止:university.webflow.com/article/interpolation-easing-smoothing @mr1031011 不,我不知道,我认为如果不进行大量调整就无法完成,因为您想为滚动添加缓动,而 AnimeJS 为目标提供缓动(时间轴动画)。 我已经成功了,任何有兴趣的人都可以在这里查看更多信息:github.com/juliangarnier/anime/issues/703 我只想说谢谢你提到它是“缓和滚动”。你是绝对正确的,缓动必须应用于seek函数的触发器而不是seek本身。当我读到你的评论时,那一刻真是令人惊叹。【参考方案2】:最后我找到了一个解决方案,使用 seek 和使用交叉点观察器来触发和控制动画。
但唯一的问题是 entry.boundingClientRect 不跟踪所有进度,而只跟踪触发器的进入或离开:
let observer_imgs_parallax;
let Element_imgs_parallax;
let prevRatio = 0.0;
let options_parallax =
root: null,
rootMargin: '0px',
threshold: buildThresholdList() //se parallax
;
// Set things up
Element_imgs_parallax = document.querySelector('.trigger-parallax-fake');
initObserver_parallax();
//////////////////////////////////////////////////////////////////////////////
function initObserver_parallax()
observer_imgs_parallax = new IntersectionObserver(callback_imgs_parallax, options_parallax);
observer_imgs_parallax.observe(Element_imgs_parallax);
/////////////////////////////////////////////////////////////////////////////
function buildThresholdList()
let thresholds = [];
let numSteps = 200;
for (let i=1.0; i<=numSteps; i++)
let ratio = i/numSteps;
thresholds.push(ratio);
thresholds.push(0);
return thresholds;
/////////////////////////////////////////////////////////////////////////////
var animazione_parallax = anime (
targets: '.immagini-parallax img',
translateY: ['15%','-15%'],
easing: 'easeInOutSine',
duration: 1000,
autoplay: false
);
////////////////////////////////////////////////////////////////////////////
//animazione parallax
function callback_imgs_parallax (entries, observer_imgs_parallax)
entries.forEach((entry) =>
if(entry.boundingClientRect.top < 0) //osservazione elemento da top
animazione_parallax.seek(animazione_parallax.duration * (entry.intersectionRatio)); //parallax
else animazione_parallax.seek(1000); //posizione dopo il passaggio
prevRatio = entry.intersectionRatio; //rimuove se non parallax
);
现在我网站中的每个动画都由交叉点观察器触发或控制,并由anime.js制作
链接:https://alessiopaolettidesign.it
【讨论】:
以上是关于如何在anime.js中使用“seek”来控制滚动时的动画?请举个例子的主要内容,如果未能解决你的问题,请参考以下文章
typescript animejs / anime.js TypeScript的类型定义。另请参见https://github.com/kohashi/types-npm-animejs