小说爽文看完了,索然无味。学习一下JS动画吧。
抬头一看,还挺麻烦。(因为怕麻烦,在家好几天没吃顿正经饭,吃的干粮。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
function Linear(t, b, c, d) { return c*t/d + b; }
function QuadIn(t, b, c, d) { return c*(t/=d)*t + b; }
function QuadOut(t, b, c, d) { return -c*(t/=d)*(t-2) + b; }
function BackIn(t, b, c, d, s) { if(s == undefined) s = 1.70158; return c*(t/=d)*t( (s+1)*t - s ) + b; }
|
废话不多说,直接上图。图呢?还没画好。稍等我去下载一个 gnuplot。啥也不会。
(图片暂时只能凑合。和我想画出来的还有些出入。要想写MathML好像还不行,没用过。麻烦,先不折腾了。)
我们需要构造一个函数 t ↦ s,t ∈ [0, d],s ∈ R,并且还得满足 0 ↦ b 和 d ↦ b+c。也就是初始(t=0)值为 b,结束(t=d) 值为 b+c。
当然,我们用的时候还需要离散化。t取值 0, 1, 2, …, d。
验证上面 Linear(0, b, c, d) = b, Linear(d, b, c, d) = b+c; BackIn(0, b, c, d, s) = b, BackIn(d, b, c, d, s) = b+c
。
不过上面的写法看起来有点猥琐。
1 2 3
| function QuadIn(t, b, c, d) { return c*(t/=d)*t + b; }
|
其实就是
1 2 3
| function QuadIn(t, b, c, d) { return c*(t/d)*(t/d) + b; }
|
动画前,b,c,d都应该确定好。所以上面的函数其实只有一个“真参数” t。(不排除,途中,修改了其他参数,不过这就产生另一个新的函数了。)
设 k = t/d,则 t = kd。这个函数就是 k ↦ t,k ∈ [0, 1],t ∈ [0, d],而且 t=kd。 这和上面的函数 t ↦ s 复合一下,就产生新函数 k ↦ s,k ∈ [0, 1],s ∈ R,并且还得满足 0 ↦ b 和 1 ↦ b+c。好像也没什么卵用。
我瞅了一眼tween.js中这一部分,它应该是这么弄得。(意思一下,源码不是这样)
1 2 3 4 5 6 7 8
| function QuadIn_k(k) { return k*k; }
function QuadIn(t,b, c, d) { return c * QuadIn_k(t/d) + b; }
|
修正量 b,c和 k 隔离开了。
说了这么多,我也不知道在讲什么。关键其实是如何构造一个函数?
那我就随便构造一个吧。弄个抛物线吧,取 d/3为对称轴,过 (0, b) (d, b+c)。经过艰苦计算得出(老了,一个抛物线算了一个小时)
t ↦ 3*c/d/d*(t-d/3)^2 + b - c/3
t ↦ -3*c/d/d*(t-d/3)^2 + b + c/3
我们随便娶一个
1 2 3
| function QuadFun_1_3(t, b, c, d) { return 3*c/d/d*(t-d/3)*(t-d/3) + b - c/3; }
|
谈不上构造,你只要想办法把弄条曲线,通过 (0, b) (d, b+c) 就行了。
- 比如 Linear 就是条直线。
- 比如 QuadIn 就是对称轴为s轴的抛物线。
- ……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| <!DOCTYPE html> <html> <head> <title>tween</title> <style> #test { width: 500px; height: 500px; background-color: lightgreen; position: absolute; left: 500px; top: 200px; }
#test > div { position: absolute; background-color: red; width: 3px; height: 3px; } </style> </head> <body> <div id="test"></div> <script>
function ElasticEaseIn(t,b,c,d,a,p) { if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; if (!a || a < Math.abs(c)) { a=c; var s=p/4; } else var s = p/(2*Math.PI) * Math.asin (c/a); return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; }
function backIn(t, b, c, d, s) { if(s===undefined) s=1.70158; return c*(t/d)*(t/d)*((s+1)*(t/d)-s) + b; }
function QuadFun_1_3(t, b, c, d) { return 3*c/d/d*(t-d/3)*(t-d/3) + b - c/3; }
var t = 0; var b = 0; var c = 400; var d = 60; var result = []; var raf; var raf = requestAnimationFrame(function chuizi() { var div;
if(t <= d) { p = QuadFun_1_3(t, b, c, d); result.push({t: t, T: Date.now(), p: p}); div = document.createElement('div'); div.style.left = 6*t + "px"; div.style.top = p + "px"; test.appendChild(div); t++; requestAnimationFrame(chuizi); } }); </script> </body> </html>
|
用js库的时候,就可以自己选个合适的 动画函数 塞进去。