罗 乾 林
2020-08-04
最直接的想法 async function run_animator() { let _duration = 400 const start_pos = 100 const end_pos = 300 let h = end_pos - start_pos const animator = new Animator({ duration: _duration, easing: p => p ** 2 }); await animator.animate({ el: block, start: start_pos, end: end_pos }, ({ target: { el, start, end }, timing: { p, isFinished } }) => { const top = start * (1 - p) + end * p; el.style.top = `${top}px`; }); while (h > 2) { h /= 2 const top = end_pos - h _duration /= Math.sqrt(2) // console.log(`${h} ${_duration}`) const animator_up = new Animator({ duration: _duration, easing: p => p * (2 - p) }); const animator_down = new Animator({ duration: _duration, easing: p => p ** 2 }); await animator_up.animate({ el: block, start: end_pos, end: top }, ({ target: { el, start, end }, timing: { p, isFinished } }) => { const top = start * (1 - p) + end * p; el.style.top = `${top}px`; }); await animator_down.animate({ el: block, start: top, end: end_pos }, ({ target: { el, start, end }, timing: { p, isFinished } }) => { const top = start * (1 - p) + end * p; el.style.top = `${top}px`; }); } }
展开
作者回复: 挺好的
4
以梦为马
2020-08-22
老师你好,transform中Matrix是不是除了装B外就没什么用呀.... 一直没发现它的用武之地
作者回复: matrix可以更加灵活设置transform,背后原理就是前面讲的仿射变换
KaygNas
2023-06-05
来自广东
请问月影大大,将线性的 f(p) = p 映射成任意的函数有更通用的求解方式吗?
我叫张小咩²⁰¹⁹
2023-05-19
来自北京
import {Animator} from '../common/lib/animator/index.js'; const ball = document.querySelector('.ball'); (async function () { let start = 0; let end = 200; let _duration = 1000 while(start < 200) { // eslint-disable-next-line no-await-in-loop const animeFall = new Animator({duration: _duration, easing: p => p ** 2 }); await animeFall.animate(ball, ({target, timing: { p }}) => { const top = start * (1 - p) + end * p; target.style.top = `${top}px`; }); start = Math.ceil((end - start) / 2 + start) _duration /= Math.sqrt(2) const animeBound = new Animator({duration: _duration, easing: p => p * (2 - p) }); await animeBound.animate({ el: ball, start: end, end: start }, ({target: { el, start, end }, timing: { p }}) => { const top = start * (1 - p) + end * p; el.style.top = `${top}px`; }); console.log(start, end) } }());
展开
量子蔷薇
2022-10-29
来自上海
// 小试牛刀,这里给出关键代码,函数 fall: async function fall(h, duration, k = 0.5) { await new Animator({ duration, easing: p => p ** 2 }).animate(circle, ({ target, timing }) => { target.y = h * (1 - timing.p); }); const nextH = h * k; const nextDuration = (duration ** 2 * k) ** 0.5; if (nextDuration > 16) { await new Animator({ duration: nextDuration, easing: p => p * (2 - p) }).animate(circle, ({ target, timing }) => { target.y = nextH * timing.p; }); fall(nextH, nextDuration, k); } } // h 为下落高度,duration 为持续时间,k 是衰减系数,默认每次弹起后高度减半 // 利用了递归的思想,当 nextDuration 小于16(60fps 的帧间隔是16.666…)时停止弹起
展开
林逸舟
2022-02-07
const ball = document.querySelector('.ball') const downAnimator = new Animator({ duration: 700, iterations: 1, easing: p => p ** 2 }) const upAnimator = new Animator({ duration: 700, iterations: 1, easing: p => p * (2 - p) }) setTimeout(async () => { let start = 0; let end = 200; let T = 200; while (Math.round(start) !== end) { await downAnimator.animate({ el: ball, start, end }, (({ target: { el, start, end }, timing }) => { const { p } = timing const top = start * (1 - p) + end * p el.style.top = `${top}px` })) start += T /= 2; await upAnimator.animate({ el: ball, start: end, end: start }, (({ target: { el, start, end }, timing }) => { const { p } = timing const top = start * (1 - p) + end * p el.style.top = `${top}px` })) } }, 1000);
展开
MG.Fre
2021-08-10
// p = p ** 2; // 匀加速运动 // p = p * (2 - p); // 匀减速运动 let start = 0, end = 200, duration = 800; let distance = end - start; const animator = new Animator({ duration, easing: p => p ** 2 }); document.addEventListener('click', async () => { while(Math.abs(distance) >= 0.1){ // 根据方向更新动画函数 if(distance > 0) // 向下运动,匀加速 animator.updateTiming({easing: p => p ** 2}); else // 向上运动,匀减速 animator.updateTiming({easing: p => p * (2 - p)}); // 更新动画的周期时间(保持加速度恒定) animator.updateTiming({duration: duration *= 0.7}); await animator.animate({el: block, start, end}, ({target: {el, start, end}, timing: {p}}) => { const top = start * (1 - p) + end * p; el.style.top = `${top}px`; }); // 通过distance记录运动方向 distance = - distance / 2; // 更新开始与结束的位置变化 if(distance < 0){ [start, end] = [end, end + distance]; }else{ [start, end] = [end, start]; } } });
展开