
我们先将pa、pb两个点所连线段当做一阶曲线,之后再由两端一阶曲线分别表示pa、pb,最后就得到了我们的二阶曲线公式。仔细观察就能发现这和我们最初的完整公式是相同的:

其中n选择不同数值时就可以得出不同阶的曲线公式。同时从上面的推导过程也可以知道,不论是几阶曲线,我们都可以完全由一阶来表示,而这个“表示”的过程就是我们在上面看到的形成动画中那些辅助线。故可以感受下作者自己写的曲线形成动画中的效果,每段辅助线均由一阶曲线形成:

相关地址
物体跟随复杂曲线轨迹运动
当我们知道曲线的公式有何而来之后,如何让小球沿着曲线运动就很好理解了。我们生成的每段曲线都是可以用公式表示出来的,也正因如此我们就可以得到每个t值时的曲线坐标点。从而知道物体的绘制坐标。
//核心逻辑
LinearGradient.prototype.drawBall = function() {
var self = this
var item = ctrlNodesArr[ctrlDrawIndex]//存储了各段曲线的控制点
//各段曲线均为三阶贝塞尔,故下面计算x,y值代入到了三阶公式中
var ctrlAx = item.cAx,//各个控制点
ctrlAy = item.cAy,
ctrlBx = item.cBx,
ctrlBy = item.cBy,
...
if(item.t > 1) {
ctrlDrawIndex++ //当一段曲线的t>1说明曲线已经走到头
}else {
self.ctx.clearRect(0, 0, self.width, self.height)
item.t += 0.05
var ballX = ox * Math.pow((1 - item.t), 3) + 3 * ctrlAx * item.t * Math.pow((1 - item.t), 2) + 3 * ctrlBx * Math.pow(item.t, 2) * (1 - item.t) + x * Math.pow(item.t, 3)
var ballY = oy * Math.pow((1 - item.t), 3) + 3 * ctrlAy * item.t * Math.pow((1 - item.t), 2) + 3 * ctrlBy * Math.pow(item.t, 2) * (1 - item.t) + y * Math.pow(item.t, 3)
//代入三阶贝塞尔曲线公式算出小球的坐标值
self.ctx.beginPath()
self.ctx.arc(ballX, ballY, 5, 0, Math.PI * 2, false)
self.ctx.fill()
}
if(ctrlDrawIndex !== ctrlNodesArr.length) {
window.requestAnimationFrame(newMap.drawBall.bind(self))
}
}最后
demo地址:这里✨✨
源码地址:欢迎star









