Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/401.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_Jquery_Html_Canvas_Html5 Canvas - Fatal编程技术网

Javascript 如何在画布上画线

Javascript 如何在画布上画线,javascript,jquery,html,canvas,html5-canvas,Javascript,Jquery,Html,Canvas,Html5 Canvas,我想用下面的方式在画布上画一个圆圈内的一些线 我不知道如何画线,如下所示。但我有在画布上画直线和圆弧的基本知识。如何进行 您可以使用带有控制点的注释中建议的贝塞尔曲线,但是,这些曲线可能很难控制(没有双关语),因为它们不会通过您定义的点,并且您始终需要定义两个控制点 为了使用实际点实现点之间的直线,需要使用基数样条曲线 没有对这些的内置支持,但不久前我为JavaScript和canvas实现了这一点(代码可以下载,MIT许可证) 使用此功能,您可以简单地将三个点定义为最小值(以获得一条简单曲线)

我想用下面的方式在画布上画一个圆圈内的一些线

我不知道如何画线,如下所示。但我有在画布上画直线和圆弧的基本知识。如何进行


您可以使用带有控制点的注释中建议的贝塞尔曲线,但是,这些曲线可能很难控制(没有双关语),因为它们不会通过您定义的点,并且您始终需要定义两个控制点

为了使用实际点实现点之间的直线,需要使用基数样条曲线

没有对这些的内置支持,但不久前我为JavaScript和canvas实现了这一点(代码可以下载,MIT许可证)

使用此功能,您可以简单地将三个点定义为最小值(以获得一条简单曲线),该函数将负责在具有设定张力值的点之间绘制平滑曲线

例如,如果您定义了以下三点:

var pts = [10,100, 200,50, 390,100];
如果我们想说明这些要点(用于比较),您显然会得到a:

使用具有相同三个点的基数样条曲线:

以下代码生成上述曲线(没有显示点坐标的红点):

现在只需移动点(特别是中心点),曲线将采用。为用户添加张力滑块可能是一个优势:

例如,要获得以下结果,请执行0.8:

ctx.curve(pts, 0.8);

例如,0.3将使平滑度降低到:

ctx.curve(pts, 0.3);

还有其他参数(请参阅顶部的链接以获取文档),如果要添加超精细控制,您可以在点阵列中拥有“无限”数量的点

该实现扩展了画布上下文,但如果您心里不舒服,可以提取该方法并单独使用它。:-)

实现这个循环 我希望我在这里正确地解释了你的画。。。要将上述内容用于圆,只需执行以下操作:

  • 定义范围,即要绘制线的圆的边
  • 定义步骤,即每行之间的间距
假设你想在-70°和70°之间画线,最多画5条线,你可以这样做:

var ctx = canvas.getContext('2d'),
    cx = canvas.width * 0.5,
    cy = canvas.height * 0.5,
    pts,
    startAngle = -70,
    endAngle = 70,
    lines = 5,
    angle,
    range,
    steps,
    radius = 90,
    delta = 15,
    x, y,
    i;

ctx.lineWidth = 3;
ctx.strokeStyle = '#059';

/// draw arc
ctx.beginPath();
ctx.arc(cx, cy, radius, 0, 2 * Math.PI);
ctx.stroke();

/// calculate angle range normalized to 0 degrees
startAngle = startAngle * Math.PI / 180;
endAngle = endAngle * Math.PI / 180;

range = endAngle  - startAngle;
steps = range / (lines + 1);

/// calculate point at circle (vertical only)
for(i = 1; i <= lines; i++) {
    pts = [];
    /// right side
    x = cx + radius * Math.cos(startAngle + steps * i);
    y = cy + radius * Math.sin(startAngle + steps * i);
    
    pts.push(x, y);

    /// center
    pts.push(cx, y + delta * ((y - cy)/ cy));
    
    /// flip for left side
    x = cx - (x - cx);

    pts.push(x, y);

    ///  draw curve
    ctx.beginPath();
    ctx.curve(pts, 0.8);
    ctx.stroke();
}
var ctx=canvas.getContext('2d'),
cx=画布宽度*0.5,
cy=画布高度*0.5,
临时秘书处,
startAngle=-70,
端角=70,
行=5,
角度,
范围
步骤,
半径=90,
δ=15,
x、 y,,
我
ctx.lineWidth=3;
ctx.strokeStyle='#059';
///画弧
ctx.beginPath();
ctx.弧(cx,cy,半径,0,2*Math.PI);
ctx.stroke();
///计算标准化为0度的角度范围
startAngle=startAngle*Math.PI/180;
endAngle=endAngle*Math.PI/180;
范围=端角-星形缠结;
步数=范围/(行数+1);
///计算圆上的点(仅垂直)

对于(i=1;我你可以画贝塞尔曲线,我不需要手动方式。因为切割[水平线和垂直线]根据用户选择不同。请提供更简单和动态的方法。正如Mardie所说,您可以使用Bezier曲线,您只需根据用户输入计算参数+1个不错的效果,而且还可以调整(半径等)。是的,非常不错!
var ctx = canvas.getContext('2d'),
    cx = canvas.width * 0.5,
    cy = canvas.height * 0.5,
    pts,
    startAngle = -70,
    endAngle = 70,
    lines = 5,
    angle,
    range,
    steps,
    radius = 90,
    delta = 15,
    x, y,
    i;

ctx.lineWidth = 3;
ctx.strokeStyle = '#059';

/// draw arc
ctx.beginPath();
ctx.arc(cx, cy, radius, 0, 2 * Math.PI);
ctx.stroke();

/// calculate angle range normalized to 0 degrees
startAngle = startAngle * Math.PI / 180;
endAngle = endAngle * Math.PI / 180;

range = endAngle  - startAngle;
steps = range / (lines + 1);

/// calculate point at circle (vertical only)
for(i = 1; i <= lines; i++) {
    pts = [];
    /// right side
    x = cx + radius * Math.cos(startAngle + steps * i);
    y = cy + radius * Math.sin(startAngle + steps * i);
    
    pts.push(x, y);

    /// center
    pts.push(cx, y + delta * ((y - cy)/ cy));
    
    /// flip for left side
    x = cx - (x - cx);

    pts.push(x, y);

    ///  draw curve
    ctx.beginPath();
    ctx.curve(pts, 0.8);
    ctx.stroke();
}
/// calculate point at circle (vertical only)
for(i = 1; i <= lines; i++) {
    pts = [];
    /// right side
    x = cx + radius * Math.cos(startAngle + steps * i);
    y = cy + radius * Math.sin(startAngle + steps * i);
    
    pts.push(cx - radius, cy);
    pts.push(cx, y);   
    pts.push(cx + radius, cy);

    ///  draw ellipse side
    ctx.beginPath();
    drawEllipseSide(pts, true);
    ctx.stroke();
}
function drawEllipseSide(pts, horizontal) {

    var radiusX,
        radiusY,
        cx, cy,
        x, y,
        startAngle,
        endAngle,
        steps = Math.PI * 0.01,
        i = 0;
    
    if (horizontal) {
    
        radiusX = Math.abs(pts[4] - pts[0]) * 0.5;
        radiusY = pts[3] - pts[1];
        cx = pts[2];
        cy = pts[1];
        startAngle = 0;
        endAngle = Math.PI;
        
        x = cx + radiusX * Math.cos(startAngle);
        y = cy + radiusY * Math.sin(startAngle);
        
        ctx.moveTo(x, y);
        
        for(i = startAngle + steps; i < endAngle; i += steps) {
            x = cx + radiusX * Math.cos(i);
            y = cy + radiusY * Math.sin(i);
            ctx.lineTo(x, y);
        }
    }
}