我有一个像http://s18.postimg.org/93lnr5sdl/img.png这样的图像,需要在画布中说五秒钟。
有什么选择怎么做?逐行(我知道应该绘制线的顺序)。
我知道它不会是圣经。喜欢
img = '...';
draw(img, 5000)
但我需要一个建议,搜索什么。
我的想法是将这个图像放在具有白色背景的空白元素上,并逐个动画宽度:0(所以不绘制线条,但显示隐藏在白色定位元素下的每条线条。 但是,曲线或线条过于靠近(例如后窗)存在问题。
有什么想法吗? 感谢。
答案 0 :(得分:1)
我认为你想要为汽车的绘图设置动画,好像艺术家正在描绘每一行。
你可以这样做,但你需要做很多工作。
首先,获取html画布绘制命令以绘制线条图的每个路径。
这部分实际上相当容易。
使用Adobe Illustrator中的“跟踪”工具获取线条图中每一行的路径。
将路径保存为.svg
使用像canvg或Mike Swanson的AI这样的工具将.svg转换为html画布绘图命令。
清理生成的画布命令(转换工具并不完美)。由于您的绘图是单色的,因此您可以消除转换工具添加的许多冗余样式更改。
我为你的示例图片做了这个。
图片的svg版本在这些路径上有16个路径和135个锚点。
图片的画布版本有336个绘图命令,包括直线和贝塞尔曲线。
对于多余的样式更改,画布版本可以简化一半(我没有这样做)
结果 - 这是画线的画布版本:
http://jsfiddle.net/m1erickson/aaSCB/
现在困难的部分:为每条线的绘制和Bezier曲线设置动画。
现在你有100(+ - )行和曲线用动画绘制。
为此,您需要在每一行上绘制每个点,以便为这些线点设置动画。
以下是获取某一点的代码:
// Supply T which is an interval along
// the line where you need an XY point
// T == 0.00 at the start of the line
// T == 1.00 at the end of the line
function getLineXYatT(startPt,endPt,T) {
var dx = endPt.x-startPt.x;
var dy = endPt.y-startPt.y;
var X = startPt.x + dx*T;
var Y = startPt.y + dy*T;
return( {x:X,y:Y} );
}
您需要绘制每条曲线上的每个点,以便为这些曲线点设置动画。
以下是沿Bezier曲线获取点的代码:
// Supply T which is an interval along
// the curve where you need an XY point
// T == 0.00 at the start of the line
// T == 1.00 at the end of the line
function getCubicBezierXYatT(startPt,controlPt1,controlPt2,endPt,T){
var x=CubicN(T,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
var y=CubicN(T,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
return({x:x,y:y});
}
// cubic helper formula at T distance
function CubicN(T, a,b,c,d) {
var t2 = T * T;
var t3 = t2 * T;
return a + (-a * 3 + T * (3 * a - a * T)) * T
+ (3 * b + T * (-6 * b + b * 3 * T)) * T
+ (c * 3 - c * 3 * T) * t2
+ d * t3;
}
最后,使用requestAnimationFrame沿线点和曲线点设置动画。
这是一个动画循环的示例,它以增量方式绘制一条线:
http://jsfiddle.net/m1erickson/keLPs/
在动画循环中画一条线:
var lineStart={x:50,y:50};
var lineEnd={x:150,y:150};
var T=0.00;
var previousPoint=lineStart;
animate();
function animate() {
// if the animation is not done, request another frame
if(T<=1.00){
requestAnimationFrame(animate);
}
// Drawing code goes here
var pt=getLineXYatT(lineStart,lineEnd,T);
ctx.beginPath();
ctx.moveTo(previousPoint.x,previousPoint.y);
ctx.lineTo(pt.x,pt.y);
ctx.stroke();
// increment for the next point on the line
T+=.01;
previousPoint=pt;
}
您可以创建上述函数的通用版本,该版本接收一行的起点/终点并在该行上设置动画。
创建一个广义曲线函数,该函数接收4个控制点并在Bezier曲线上设置动画。
......你已经完成了!