簡體   English   中英

如何在畫布中繪制線條

[英]How to draw the line in canvas

我想以下面的方式在畫布上的圓圈內繪制一些線條。

我不知道如何繪制如下所示的線條。 但我掌握了在畫布上繪制線條和弧線的基本知識。 如何進行?

在此輸入圖像描述

您可以使用帶有控制點的注釋中建議的貝塞爾曲線,但是,這些曲線很難控制(沒有雙關語),因為它們不會通過您定義的點,並且您始終需要定義兩個控制點。

為了使用實際點實現直線穿越,您需要使用基數樣條曲線。

沒有內置的支持,但不久前我為JavaScript和canvas做了一個實現(代碼可以從這里下載,MIT許可證)。

通過這種方式,您可以簡單地將三個點定義為最小值(以獲得簡單的曲線),並且該函數將負責在具有設定張力值的點之間繪制平滑曲線。

例如,如果您定義了以下三點:

var pts = [10,100, 200,50, 390,100];

如果我們想要說明這些點(用於比較),你顯然會得到一個像這樣簡單折線

行

使用具有相同三個點的基數樣條曲線 可以為您提供

紅衣主教樣條

以下代碼生成上面的曲線(沒有顯示點坐標的紅點):

ctx.beginPath();
ctx.curve(pts);
ctx.stroke();

現在只需移動點(特別是中心點)就可以采用曲線。 為用戶添加張力滑塊可能是一個優勢:

將張力增加到例如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();
}

哪會導致這個:

地球

在這里小提琴

現在只需要玩弄值(例如delta)並計算水平行 - 我將把它作為OP的練習:

使用橢圓邊繪制線條

話雖這么說 - 如果你想要地球更多,圓形:-S,你也可以使用一個函數來計算橢圓的一部分,並將其繪制為線條。 如果是與上面相同的實現,但具有子函數,使用線和中間點之間的差異作為半徑來計算左側和右側之間的橢圓。

例如:

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

導致這一點(我在最后的繪圖中作了一點作用,給出了一個更清晰的畫面(沒有雙關語),如果你繼續沿着這些行繼續下去將會是什么樣的結果(沒有雙關語,我是雙關語),這里給出了:):

地球

在這里小提琴

我的代碼-OCD踢了:-P但是你至少應該有一些選擇。 研究代碼以了解如何計算垂直線並采用橫向線。

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM