Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么我的画布javascript没有连接线?_Javascript_Canvas_Bezier - Fatal编程技术网

为什么我的画布javascript没有连接线?

为什么我的画布javascript没有连接线?,javascript,canvas,bezier,Javascript,Canvas,Bezier,我试图创建一个画布脚本,直观地绘制一个三次贝塞尔曲线,但到目前为止,我一直没有成功地使我的线连接。请参见此处的代码 var canvas=document.getElementById("canvas"); var c = canvas.getContext("2d"); // Bezier eq. code coord = function(x,y) { if(!x) var x=0; if(!y) var y=0; return {x: x, y: y}; } B1 = fu

我试图创建一个画布脚本,直观地绘制一个三次贝塞尔曲线,但到目前为止,我一直没有成功地使我的线连接。请参见此处的代码

 var canvas=document.getElementById("canvas");
 var c = canvas.getContext("2d");  
  // Bezier eq. code
 coord = function(x,y) { if(!x) var x=0; if(!y) var y=0; return {x: x, y: y}; }

B1 = function(t) { return (t*t*t); }
B2 = function(t) { return (3*t*t*(1-t)); } 
B3 = function(t) { return (3*t*(1-t)*(1-t)); }
B4 = function(t) { return ((1-t)*(1-t)*(1-t)); }

function getBezier(t,C1,C2,C3,C4) {
    var pos = new coord();
    pos.x = C1.x * B1(t) + C2.x * B2(t) +C3.x * B3(t) + C4.x * B4(t);
    pos.y = C1.y * B1(t) + C2.y * B2(t) + C3.y * B3(t) + C4.y * B4(t);
    return pos; 
}
//Ctrl points.
P1 = coord(12,12);
P2 = coord(90,1);
P3 = coord(0,190);
P4 = coord(150,150);


t=0;
function drawbez() {
  if (t == 0) {var interval = setInterval('drawbez()',1);}
  var curpos = getBezier(t2,P1,P2,P3,P4); // Staðan í ferlinum
  if (t > 1) { clearInterval(interval); return; }
  c2.moveTo(curpos.x,curpos.y);
  c2.lineTo(curpos.x+t2,curpos.y+t2);
  c2.stroke();
  t = t+0.01
 }
有什么想法吗

我使用完全相同的绘图命令使用随机数编写了一个代码,这实际上给了我连接线

参见HTML上的代码

使用贝塞尔曲线教程

我认为您的贝塞尔曲线存在一些更大的问题(lineTo而不是bezierCurveTo,甚至是QuadicialCurveTo),但断开的线是因为您在绘图之间移动光标。注释掉这一行:

  c2.moveTo(curpos.x,curpos.y);
或者更准确地说:

  c2.lineTo(curpos.x, curpos.y);  // remove the moveTo.

而且,部分原因是有人指责我(正确地说)早些时候高谈阔论。。。我不推荐使用画布绘制曲线。基本的体系结构是完全程序化的,这意味着即使是非常简单的图像,也需要数千个DOM绘图调用。SVG通常更好地使用,除非您需要仿射图像矩阵用于伪3D或类似的东西。

我认为您的bezier存在一些更大的问题(lineTo而不是bezier CurveTo,甚至是Quadicial CurveTo),但断开的线是因为您在绘图之间移动光标。注释掉这一行:

  c2.moveTo(curpos.x,curpos.y);
或者更准确地说:

  c2.lineTo(curpos.x, curpos.y);  // remove the moveTo.

而且,部分原因是有人指责我(正确地说)早些时候高谈阔论。。。我不推荐使用画布绘制曲线。基本的体系结构是完全程序化的,这意味着即使是非常简单的图像,也需要数千个DOM绘图调用。SVG通常更好地使用,除非您需要仿射图像矩阵用于伪3D或类似的东西。

嘿,我通过将代码更改为以下内容来实现它:

var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
// Bezier eq. code
coord = function(x, y) {
    if (!x) {
        x = 0;
    }
    if (!y) {
        y = 0;
    }
    return {
        x: x,
        y: y
    };
};

B1 = function(t) {
    return (t * t * t);
};
B2 = function(t) {
    return (3 * t * t * (1 - t));
};
B3 = function(t) {
    return (3 * t * (1 - t) * (1 - t));
};
B4 = function(t) {
    return ((1 - t) * (1 - t) * (1 - t));
};

function getBezier(t, C1, C2, C3, C4) {
    var pos = new coord();
    pos.x = C1.x * B1(t) + C2.x * B2(t) + C3.x * B3(t) + C4.x * B4(t);
    pos.y = C1.y * B1(t) + C2.y * B2(t) + C3.y * B3(t) + C4.y * B4(t);
    return pos;
}
//Ctrl points.
P1 = coord(12, 12);
P2 = coord(90, 1);
P3 = coord(0, 190);
P4 = coord(150, 150);

t = 0;

var drawbez = function() {
    var interval;
    if (t === 0) {
        interval = setInterval(drawbez, 1);
    }
    var curpos = getBezier(t, P1, P2, P3, P4); // Staðan í ferlinum
    if (t > 1) {
        if (interval) {
            clearInterval(interval);
        }
        return;
    }
    //c.moveTo(curpos.x, curpos.y);
    c.lineTo(curpos.x + t, curpos.y + t);
    c.stroke();
    t = t + 0.01;
};

drawbez();
请参阅以获取一个工作示例


基本上,
t2
从未声明过,
interval
超出了范围,对
drawbez
reference似乎超出了范围(可能是因为您指定了字符串函数名而不是直接对象引用),并且删除了
.moveTo()
正如约翰·格林在回答中提到的那样,给出了一条更加流畅的线。

嘿,我通过将您的代码更改为以下内容来实现这一点:

var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
// Bezier eq. code
coord = function(x, y) {
    if (!x) {
        x = 0;
    }
    if (!y) {
        y = 0;
    }
    return {
        x: x,
        y: y
    };
};

B1 = function(t) {
    return (t * t * t);
};
B2 = function(t) {
    return (3 * t * t * (1 - t));
};
B3 = function(t) {
    return (3 * t * (1 - t) * (1 - t));
};
B4 = function(t) {
    return ((1 - t) * (1 - t) * (1 - t));
};

function getBezier(t, C1, C2, C3, C4) {
    var pos = new coord();
    pos.x = C1.x * B1(t) + C2.x * B2(t) + C3.x * B3(t) + C4.x * B4(t);
    pos.y = C1.y * B1(t) + C2.y * B2(t) + C3.y * B3(t) + C4.y * B4(t);
    return pos;
}
//Ctrl points.
P1 = coord(12, 12);
P2 = coord(90, 1);
P3 = coord(0, 190);
P4 = coord(150, 150);

t = 0;

var drawbez = function() {
    var interval;
    if (t === 0) {
        interval = setInterval(drawbez, 1);
    }
    var curpos = getBezier(t, P1, P2, P3, P4); // Staðan í ferlinum
    if (t > 1) {
        if (interval) {
            clearInterval(interval);
        }
        return;
    }
    //c.moveTo(curpos.x, curpos.y);
    c.lineTo(curpos.x + t, curpos.y + t);
    c.stroke();
    t = t + 0.01;
};

drawbez();
请参阅以获取一个工作示例


基本上,
t2
从未声明过,
interval
超出了范围,对
drawbez
reference似乎超出了范围(可能是因为您指定了字符串函数名而不是直接对象引用),并且删除了
.moveTo()
正如约翰·格林在回答中提到的那样,给出了一条更加流畅的线。

你的逻辑不太正确。您的代码不断地从curpos到curpos+t2画一条线,这条线总是指向一条很小的线,因为在调用clearinterval之前,t2总是在一条线之下。我已经修改了下面的代码,它存储了prevcoord,并在每次调用drawBez时从以前的coord到新的coord绘制一条线

如果你想在画布上制作有效的动画,这绝对不是最好的方法。尝试搜索创建动画流的最佳实践(绘制更新调用等)


你的逻辑不太正确。您的代码不断地从curpos到curpos+t2画一条线,这条线总是指向一条很小的线,因为在调用clearinterval之前,t2总是在一条线之下。我已经修改了下面的代码,它存储了prevcoord,并在每次调用drawBez时从以前的coord到新的coord绘制一条线

如果你想在画布上制作有效的动画,这绝对不是最好的方法。尝试搜索创建动画流的最佳实践(绘制更新调用等)


速记。。。间隔仍然超出范围。它应该是全局的,因为每次回来时都会检查它。@John-很好,是的,它应该在
drawbez()函数之外声明。
函数。:)速记。。。间隔仍然超出范围。它应该是全局的,因为每次回来时都会检查它。@John-很好,是的,它应该在
drawbez()函数之外声明。
函数。:)