缓动动画
首先需要准备的几个函数
- Math.ceil(); //向上取整
- Math.floor(); // 向下取整
- Math.round(); // 四舍五入
- Math.sin(); // 正弦函数
缓动动画的解决方案
1.步长
采用步长作为速度变化的参考量
假设小球从最左侧移动到右侧目标区域,给这段距离作划分,则每一次前进的速度为小球当前位置与目标位置这段距离的的10分之1,即
speed = (target.left -ball.left)/10;
speed也是每次小球向前变化的增量
当速度减小到1以内时,直接去speed为1,让小球一像素一像素地向目标区域靠近。
到达目标区域,可强行设ball的left为target的left。
利用setInterval定时器完成移动动画。
封装代码:
function easyEaseMotion(ele, target) {
clearInterval(ele.t);
// 使用es6的let关键字,设置key的作用域
for (let key in target) {
let t = setInterval(function () {
// 设置步长(速度)
let speed = (target[key] - parseInt(getStyle(ele)[key])) / 10;
// 处理步长,如果大于0,正向移动,上取整,如果小于0 反方向移动,下去整,如 0.85 -> 1,-0.265 -> -1。
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
ele.style[key] = parseInt(getStyle(ele)[key]) + speed + "px";
// 如果当前的坐标与目标区域的距离小于步长,则强行拉回到目标区域,清除定时器
if (Math.abs(Number(getStyle(ele)[key]) - target)<= speed) {
ele.style[key] = target +"px";
clearInterval(t);
}
}, 30)
}
}
上述代码中,easyEaseMotion接收两个参数,第一个是需要移动的目标节点。
如页面中定义的
<div id="box"></div>
``
使用 var box = document.getElementById("box");
获取,传值box即可。
第二个参数为一个对象,可以设置小球的上下左右移动的目标。
如设置为 {left:900},或{left:900,top:900}
,小球将移动到指定位置。
easyEaseMotion(box,{left:900},
2.正弦函数
在正弦函数中,0~π/2 上,随x的增长,y增长为1的速度越来越慢,其斜率越来越小,逐步减为0。故可以考虑使用sin(x) 来控制速度的变化。
function sinMotion(ele,props){
// 循环获取目标所有的属性
for (let attr in props) {
// 获取属性的初值
let start = parseInt(getStyle(ele)[attr]);
// 初始化角度,距离,定时器
let degree = 0;
let distance = props[attr] - start;
let t = setInterval(function(){
// 角度每次加3
degree +=3;
// 改变目标样式
ele.style[attr] = start + Math.sin(Math.PI/180 * degree) * distance +"px";
// 只用三角函数的0-π/2,如果到达90度,则停止
if(degree == 90){
clearInterval(t);
}
},30)
}
}
传值同1。
附:用于解决兼容性的getStyle方法:
function getStyle(ele){
if(window.VBArray){
return ele.getCurrentStyle;
}
return getComputedStyle(ele);
}
运动轨迹: 使用以上数据
由于正弦函数满足条件,那么相应的余弦函数也可以实现相同的效果,但在同一区间下正弦的速度越来越快。可用于多种情境。