废话很少说,先上DEMO~
http://jsrun.net/PxKKp?uid=483
再上源码~
https://github.com/Nelson2016...git
很简单的一个小特效,接下来来讲一下他的原理。github
显而易见,这小东西确定和抛物线确定有着割不开的情缘啦~app
上图!函数
那么咱们将跑速先单独拿出来看:动画
首先抛物线嘛~得有本身的方程啊,就像本身的身份证同样。ui
咱们假设抛物线的方程为 y = ax^2 + bx + c。this
为了计算方便呢,咱们另抛物线通过(0,0)这一点,那么c的值就为0了。spa
上图即为归零后的坐标系,对称轴直线为 x2 = -b / 2a..net
在抛物线方程中,a值得正负表明着抛物线的开口方向,那么a值的绝对值也和抛物线的开口大小有着反比例的关系。那么a值咱们即定位一个已知值做为参数传给运动。code
到如今为止,y = ax^2 + bx + c;方程中的a值与c之就为已知了
那么抛物线对称轴的x值-x2 在起始点坐标与终点坐标已知的状况下是苛求的,那么x2变为已知量。
经过x2 = -b / 2a便可就出b值,那么整个抛物线方程咱们就得出啦~
1.定义一个全局的对象。
nelsonAddtoCartAnimation{}
2.在nelsonAddtoCartAnimation中咱们定义几个值:
a:"",//抛物线系数 b:"",//抛物线系数 c:"",//抛物线系数 startX:"",//起始X坐标 startY:0,//其实Y坐标 endX:"",//终点X坐标 endY:0,//终点Y坐标 second:0,//动画总计时 speed:10,//动画速度
3.接下来咱们用一个init函数来初始化这个‘小球’:建立“小球”的DOM,把它放到起始位置,并计算动画须要的时间。
function init(startX,endX,rC,txt){ if(!document.getElementById("nelsonATCAContainer")){ var _nelsonATCAContainer = document.createElement("div"); _nelsonATCAContainer.className = "nelsonATCAContainer"; _nelsonATCAContainer.id = "nelsonATCAContainer"; _nelsonATCAContainer.innerText = txt?txt:""; _nelsonATCAContainer.style.left = startX + "px"; nelsonATCAControlBar.appendChild(_nelsonATCAContainer); nelsonATCAContainer = _nelsonATCAContainer; _nelsonATCAContainer = null; his.startX = startX; this.endX = endX; this.formula(rC); this.second = Math.abs(startX - endX) * this.speed / 1000; return this; } }
4.计算a、b、c的值:首先根据起点、终点坐标计算对称轴的坐标centerX,而后根据a值和centerX值计算b的值,因为咱们强制使抛物线通过(0,0)点,而实际中咱们须要对抛物线进行移动,根据抛物线终点坐标和起点坐标计算c的值,最终获得抛物线方程。
function formula(rC){ var centerX = (this.startX - this.endX) / 2 + this.endX; this.a = rC; this.b = -2 * this.a * centerX; this.c = -1 * this.a * this.startX * this.startX - this.b * this.startX; }
5.开始漂移
function move(){ var that = this; for(var i in prefixes){ nelsonATCAContainer.style[prefixes[i] + prefixes[i]?"A":"a" + "nimation"] = "moveAnimation " + that.second + "s forwards"; } nelsonATCAContainer.style.display = "block"; var s = setInterval(function(){ var startLeft = nelsonATCAContainer.offsetLeft; if(startLeft <= that.endX){ clearInterval(s); that.resetPosition(); return that; } nelsonATCAContainer.style.left = startLeft - 1 + "px"; startLeft = nelsonATCAContainer.offsetLeft; nelsonATCAContainer.style.top = that.a * startLeft * startLeft + that.b * startLeft + that.c + "px"; },that.speed) }
6.大功告成~