0

我有一个像http://s18.postimg.org/93lnr5sdl/img.png这样的图像,需要在画布上画五秒钟。

有什么选择吗?逐行(我知道应该绘制线条的顺序)。

我知道这不会是圣。喜欢

img = '...'; 
draw(img, 5000)

但我需要一个建议,什么搜索。

我的想法是让这个图像,放置在具有白色背景的空白元素上,并一个一个地设置为宽度:0(所以不要画线,而是显示隐藏在白色定位元素下的每条线。但是,有一个曲线或线条太近的问题(例如后窗)。

任何想法?谢谢。

4

1 回答 1

1

我认为您想要为汽车的绘图设置动画,就好像艺术家正在绘制每条线一样。

你可以这样做,但你需要做很多工作。

首先,获取 html canvas 绘图命令来绘制线条艺术的每个路径。

这部分实际上相当容易。

  • 使用 Adob​​e Illustrator 中的 Trace 工具获取线条艺术中每一行的路径。

  • 将路径保存到 .svg

  • 使用 canvg 或 Mike Swanson 的 AI 之类的工具将 .svg 转换为 html 画布绘图命令。

  • 清理生成的画布命令(转换工具并不完美)。由于您的绘图是单色的,因此您可以消除转换工具添加的许多多余的样式更改。

我为您的示例图像做了这个。

  • 您的图像的 svg 版本有 16 条路径和这些路径上的 135 个锚点。

  • 您的图像的画布版本有 336 个绘图命令,包括线条和贝塞尔曲线。

  • 画布版本可以简化一半以进行多余的样式更改(我没有这样做)

结果——这是你的画布的画布版本:

http://jsfiddle.net/m1erickson/aaSCB/

在此处输入图像描述

现在最困难的部分:动画绘制每条线和贝塞尔曲线。

您现在有 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} );
}

您需要在每条曲线上绘制每个点,以便在这些曲线点上进行动画处理。

这是沿贝塞尔曲线获取点的代码:

// 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 个控制点并在该贝塞尔曲线上设置动画。

......你完成了!

于 2014-01-15T17:12:07.760 回答