我对canvas等技术有点陌生,所以如果问题很简单请原谅。
我想要能够按照贝塞尔路径(bezier path)定义的路径来动画化一个对象,但我不知道该如何实现。
我查看了Raphael库,但我无法弄清如何随着时间推移按照路径运动对象。
Cake JS在演示中看起来很有希望,但我真的很难理解文档,或者说缺乏文档。
有人有这方面的工作示例吗?
我对canvas等技术有点陌生,所以如果问题很简单请原谅。
我想要能够按照贝塞尔路径(bezier path)定义的路径来动画化一个对象,但我不知道该如何实现。
我查看了Raphael库,但我无法弄清如何随着时间推移按照路径运动对象。
Cake JS在演示中看起来很有希望,但我真的很难理解文档,或者说缺乏文档。
有人有这方面的工作示例吗?
.style.left
等内容,而是用新位置(和可选旋转)抹掉并重新绘制您的画布。
请注意,这在内部使用SVG轻松插值bézier曲线上的点,但您可以将其提供的点用于任何您想要的目的(包括在画布上绘制)。
如果我的网站无法访问,这里是库的当前快照:
function CurveAnimator(from,to,c1,c2){
this.path = document.createElementNS('http://www.w3.org/2000/svg','path');
if (!c1) c1 = from;
if (!c2) c2 = to;
this.path.setAttribute('d','M'+from.join(',')+'C'+c1.join(',')+' '+c2.join(',')+' '+to.join(','));
this.updatePath();
CurveAnimator.lastCreated = this;
}
CurveAnimator.prototype.animate = function(duration,callback,delay){
var curveAnim = this;
// TODO: Use requestAnimationFrame if a delay isn't passed
if (!delay) delay = 1/40;
clearInterval(curveAnim.animTimer);
var startTime = new Date;
curveAnim.animTimer = setInterval(function(){
var now = new Date;
var elapsed = (now-startTime)/1000;
var percent = elapsed/duration;
if (percent>=1){
percent = 1;
clearInterval(curveAnim.animTimer);
}
var p1 = curveAnim.pointAt(percent-0.01),
p2 = curveAnim.pointAt(percent+0.01);
callback(curveAnim.pointAt(percent),Math.atan2(p2.y-p1.y,p2.x-p1.x)*180/Math.PI);
},delay*1000);
};
CurveAnimator.prototype.stop = function(){
clearInterval(this.animTimer);
};
CurveAnimator.prototype.pointAt = function(percent){
return this.path.getPointAtLength(this.len*percent);
};
CurveAnimator.prototype.updatePath = function(){
this.len = this.path.getTotalLength();
};
CurveAnimator.prototype.setStart = function(x,y){
var M = this.path.pathSegList.getItem(0);
M.x = x; M.y = y;
this.updatePath();
return this;
};
CurveAnimator.prototype.setEnd = function(x,y){
var C = this.path.pathSegList.getItem(1);
C.x = x; C.y = y;
this.updatePath();
return this;
};
CurveAnimator.prototype.setStartDirection = function(x,y){
var C = this.path.pathSegList.getItem(1);
C.x1 = x; C.y1 = y;
this.updatePath();
return this;
};
CurveAnimator.prototype.setEndDirection = function(x,y){
var C = this.path.pathSegList.getItem(1);
C.x2 = x; C.y2 = y;
this.updatePath();
return this;
};
…这是如何使用它的示例:
var ctx = document.querySelector('canvas').getContext('2d');
ctx.fillStyle = 'red';
var curve = new CurveAnimator([50, 300], [350, 300], [445, 39], [1, 106]);
curve.animate(5, function(point, angle) {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fillRect(point.x-10, point.y-10, 20, 20);
});
以下是详细的版本:
t
是介于0和1之间的任意数字,代表时间;p0
、p1
、p2
、p3
对象分别代表起始点、第一个控制点、第二个控制点和终止点:
var at = 1 - t;
var green1x = p0.x * t + p1.x * at;
var green1y = p0.y * t + p1.y * at;
var green2x = p1.x * t + p2.x * at;
var green2y = p1.y * t + p2.y * at;
var green3x = p2.x * t + p3.x * at;
var green3y = p2.y * t + p3.y * at;
var blue1x = green1x * t + green2x * at;
var blue1y = green1y * t + green2y * at;
var blue2x = green2x * t + green3x * at;
var blue2y = green2y * t + green3y * at;
var finalx = blue1x * t + blue2x * at;
var finaly = blue1y * t + blue2y * at;
这里是一个使用<canvas>在JSfiddle上沿着路径运动的球:http://jsfiddle.net/JAChJ/3/
变量的名称来自于这个gif图,它是关于Bezier曲线的最好解释:http://en.wikipedia.org/wiki/File:Bezier_3_big.gif
以下是一段简短的代码,可供复制/粘贴使用:
var calcBezierPoint = function (t, p0, p1, p2, p3) {
var data = [p0, p1, p2, p3];
var at = 1 - t;
for (var i = 1; i < data.length; i++) {
for (var k = 0; k < data.length - i; k++) {
data[k] = {
x: data[k].x * at + data[k + 1].x * t,
y: data[k].y * at + data[k + 1].y * t
};
}
}
return data[0];
};
相关内容: