javascript - Canvas:动画贝塞尔曲线绘制

标签 javascript jquery html canvas

我正在尝试制作一条从左到右穿过 Canvas 的线。我仍处于实现该目标的早期阶段,我正在使用以下功能来执行逐步动画

timer = window.setInterval(draw_line, 30);

我的绘图函数是这样的

function draw_line()
    {
        context.fillStyle = "#000";
        context.fillRect(0, 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, p2 ,cp1,cp2
            // now here is my problem
    }

我知道我需要移动 p1.x+= 一个随机数; 并且对于 cp1 和 cp2 也是一样的,但是 p2 它应该的终点呢沿着相同的轨道走!我怎样才能做到这一点?

谢谢

最佳答案

编辑后的答案

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

为了让终点沿着起点穿过 Canvas 的路径,您必须存储历史值。在这个例子中,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, 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;
    }    
});​

之前的回答留在下方,以供历史引用。

我不确定我是否完全理解您要实现的目标,但我认为您需要做的就是将您的所有观点转换为相同的值。这将导致穿过 Canvas 的线保持相同的形状。像这样:

JSFiddle

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;
};

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, 0, c.width, c.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();

    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);        
    }
}

除非我误解了目标...

关于javascript - Canvas:动画贝塞尔曲线绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11798053/

相关文章:

javascript - 如何防止将数据传递给 Controller

javascript - 在元素上添加/删除最新应用的类

javascript - 如何在条件下显示 anchor 标记以及单击 anchor 时显示内容,否则不显示( Angular 新手)?

javascript - 在脚本标签后添加按钮

html - CSS 布局信息框

html - 如何让一列自动调整大小,同时给另一列一个固定的位置?

javascript - React Native 可重用组件的设置状态问题

javascript - knockout : Nested observableArrays and Nested ForEach

javascript - 我们可以使用 Html.Partial Helper 在 jQuery 中附加( block )HTML 吗? C# ASP.Net MVC 5

javascript - 将字符串转换为 JSON