微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript – Canvas:Animate贝塞尔曲线绘制

我试图从左到右划出一条穿过画布的线.即时通讯还处于早期阶段,要做到这一点,使用以下功能来做一步一步的动画

timer = window.setInterval(draw_line,30);

我的绘图功能是这样的

function draw_line()
    {
        context.fillStyle = "#000";
        context.fillRect(0,canv.width,canv.height);

            context.beginPath();
        context.linewidth = 2;
        context.strokeStyle = '#fff';

            //Where p1,p2,cp1,cp2 are point objects that has x & y values already defined    
        context.moveto(p1.x,p1.y);
        context.bezierCurveto(cp1.x,cp1.y,cp2.x,cp2.y,p2.x,p2.y);
        context.stroke();
        context.closePath();

            // Now i have to move p1,cp2
            // Now here is my problem
    }

我知道我需要移动p1.x =一个随机数;对于cp1和cp2来说也是一样的,但是p2的终点应该跟着同一条轨道一样!我怎么能实现这一目标?

谢谢

最佳答案
编辑回答

有了你的澄清,我想我现在可以适当地回答这个问题了.

为了使终点遵循起点通过画布的路径,您必须存储历史值.在这个例子中,http://jsfiddle.net/mobidevelop/bGgHQ/,我使用鼠标移动来填充最后16个位置的缓冲区,然后通过迭代RingBuffer使用它来形成穿过点的贝塞尔曲线.

function RingBuffer(length) {
    this.length = length;
    this.pointer = 0;
    this.buffer = [];
}
RingBuffer.prototype.get = function(index) {
    if (index < 0) {
        index += this.length;        
    }
    return this.buffer[index];
}
RingBuffer.prototype.push = function(value) {
    this.buffer[this.pointer] = value;
    this.pointer = (this.length + this.pointer +1) % this.length;    
}

var c = document.getElementById("myCanvas");
var context =c.getContext("2d");

timer = window.setInterval(draw_line,30);
function Point(x,y) {
    this.x = x;
    this.y = y;
}
Point.prototype.translateX = function(x) {
    return this.x += x;
};
Point.prototype.translateY = function(y) {
    return this.y += y;
};

function draw_line()
{
    context.fillStyle = "#000";
    context.fillRect(0,c.width,c.height);

    var pointer = history.pointer;
    context.beginPath();
    context.linewidth = 2;
    context.strokeStyle = '#F00';     
    for (iteration = 0,count = 15; iteration < count; iteration += 3) {
        var p1 = history.get(--pointer);
        var p2 = history.get(--pointer);
        var p3 = history.get(--pointer);
        var p4 = history.get(--pointer);        

        if (p1 && p2 && p3 && p4) {

            context.moveto(p1.x,p1.y);
            context.bezierCurveto(p2.x,p2.y,p3.x,p3.y,p4.x,p4.y);

        }
        pointer++;
    }
    context.stroke();
    context.closePath();    

}

var history = new RingBuffer(16);
var lastGrab = new Date();
c.addEventListener('mousemove',function() {
    Now = new Date();
    if (Now - lastGrab > 15) {
        history.push(new Point(event.clientX - c.offsetLeft,event.clientY - c.offsetTop)); 
        lastGrab = Now;
    }    
});​

出于历史目的,上面的答案留在下面.

我不确定我是否完全理解你想要实现的目标,但我认为你需要做的就是用相同的值翻译你的所有点数.这将导致遍历画布的线保持相同的形状.这样的事情:

JSFiddle

var c = document.getElementById("myCanvas");
var context =c.getContext("2d");

timer = window.setInterval(draw_line,y) {
    this.x = x;
    this.y = y;
}
Point.prototype.translateX = function(x) {
    return this.x += x;
};
Point.prototype.translateY = function(y) {
    return this.y += y;
};

var p1 = new Point(0,0);
var p2 = new Point(100,100);
var cp1 = new Point(15,45);
var cp2 = new Point(85,45);

function draw_line()
{
    context.fillStyle = "#000";
    context.fillRect(0,c.height);

    context.beginPath();
    context.linewidth = 2;
    context.strokeStyle = '#fff';

        //Where p1,cp2 are point objects that has x & y values already defined    
    context.moveto(p1.x,p1.y);
    context.bezierCurveto(cp1.x,p2.y);
    context.stroke();
    context.closePath();

    p1.translateX(1);
    p2.translateX(1);
    cp1.translateX(1);
    cp2.translateX(1);

    if (p1.x > 300) {
        p1.translateX(-400);
        p2.translateX(-400);
        cp1.translateX(-400);
        cp2.translateX(-400);        
    }
}

除非我误解目标……

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐