2

Javascriptでキャンバスに円弧を描画しようとしていますが、Javascriptが自動的に描画する線を削除したいと思います。線が引かれている場合、2つの問題があります:a)fill()の誤動作b)弓のように見える

これが私が持っているものと私が欲しいもののイメージです:アーク 左は私がJSで持っているものであり、右は私がJavaで持っているものです。Javaの実装はかなり非効率的であり、すでに利用可能な関数を使用したいと思います。

関連するJS関数は次のとおりです。

function pointAt(center, l, theta){
    return {
        x : Math.sin(theta) * l + center.x,
        y : Math.cos(theta) * l + center.y
    };
}

function drawArc(ctx, center, l, theta, sweep, label, thickness){
    var p0 = pointAt(center, l, theta);
    var p1 = pointAt(center, l + thickness, theta);
    var p2 = pointAt(center, l + thickness, theta + sweep);
    var p3 = pointAt(center, l, theta + sweep);
    ctx.fillStyle = "red";
    drawPoint(ctx, p0);
    ctx.fillStyle = "blue";
    drawPoint(ctx, p1);
    ctx.fillStyle = "green";
    drawPoint(ctx, p2);
    ctx.fillStyle = "yellow";
    drawPoint(ctx, p3);

    ctx.beginPath();
    ctx.moveTo(p0.x, p0.y);
    ctx.lineTo(p1.x, p1.y);
    ctx.arc(center.x, center.y, l + thickness, theta, theta + sweep, false);
    ctx.moveTo(p2.x, p2.y);
    ctx.lineTo(p3.x, p3.y);
    ctx.arc(center.x, center.y, l, theta + sweep, theta, true)
    ctx.closePath();
    ctx.fill();
    ctx.stroke();

    //TODO: draw label!!!
}

function drawPoint(ctx, p){
    ctx.fillRect(p.x - 4, p.y - 4, 8, 8);
}

これがJavaで機能する実装です。

       private static void drawArc(Graphics g, Point center, int l, double theta, double sweep, String label, int thickness){
        for (double i = 0; i < thickness; i+=.5) { //hardcoded
            Point last = pointAt(center, l + i, theta);
            for(double t = theta; t < theta + sweep; t+=.01){
                Point cur = pointAt(center, l + i, t);
                g.drawLine(last.x, last.y, cur.x, cur.y);
                last = cur;
            }
        }
        double t = theta + sweep / 2;
        Point p = pointAt(center, l + 15, t);
        int size = g.getFontMetrics().stringWidth(label);
        BufferedImage img = new BufferedImage(size * 2, size * 2, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        g2.setColor(Color.RED);
        double rot = (Math.PI / 2 - t);
//      System.out.println(rot / Math.PI + "PI");
        boolean b = true;
        if(rot < -Math.PI / 2){
            rot += Math.PI;
            b = false;
        }
        g2.setTransform(AffineTransform.getRotateInstance(rot, size, size));
        g2.drawString(label, size, size);
        g2.dispose();
        if(!b)
            size *= 1.75; //magic value or hardcoded???
        g.drawImage(img, p.x - size, p.y - size, null);
    }

だから私の質問:バナナを太い弧に変えるにはどうすればいいですか?

4

3 に答える 3

3

外側の弧を時計回りに描き、次に内側の弧を反時計回りに描きます。キャンバスは自動的に端を直線で閉じます。

var c = document.getElementById('c');
var ctx = c.getContext('2d');
ctx.beginPath();
ctx.arc(0,0,50,0,-Math.PI * 0.5, false);
ctx.arc(0,0,25,-Math.PI * 0.5,0, true);
ctx.fillStyle = '#0f0';
ctx.fill();
ctx.strokeStyle = '#0f0';
ctx.stroke();
ctx.closePath();

http://jsfiddle.net/tMEdq/

また、ここに良い参考文献があります: http://diveintohtml5.ep.io/canvas.html#divingin http://www.nihilogic.dk/labs/canvas_sheet/HTML5_Canvas_Cheat_Sheet.png

于 2011-06-29T18:59:19.997 に答える
2

あまりにも多くの描画呼び出しがあります - 必要なのはこれだけです:

ctx.beginPath();
ctx.arc(center.x, center.y, l + thickness, theta, theta + sweep, false);
ctx.arc(center.x, center.y, l, theta + sweep, theta, true);
ctx.closePath();
ctx.fill();
ctx.stroke();

最初の円弧を描くだけで、自動的に次の円弧に結合され、パスを閉じてループを完成させます。

また、間違った方法でsinand を呼び出しています-X軸ではなく、Y軸座標を変更する必要があります!cospointAt()sin()

http://jsfiddle.net/alnitak/zChSe/の動作デモ

于 2011-06-29T19:03:42.313 に答える
1

ただ行う:

function drawArc(ctx, center, l, theta, sweep, label, thickness){
    var p0 = pointAt(center, l, theta);
    var p1 = pointAt(center, l + thickness, theta);
    var p2 = pointAt(center, l + thickness, theta + sweep);
    var p3 = pointAt(center, l, theta + sweep);
    ctx.fillStyle = "red";
    drawPoint(ctx, p0);
    ctx.fillStyle = "blue";
    drawPoint(ctx, p1);
    ctx.fillStyle = "green";
    drawPoint(ctx, p2);
    ctx.fillStyle = "yellow";
    drawPoint(ctx, p3);

    ctx.beginPath();
    //ctx.moveTo(p0.x, p0.y);
    //ctx.lineTo(p1.x, p1.y);
    ctx.arc(center.x, center.y, l + thickness, theta, theta + sweep, false);
    //ctx.moveTo(p2.x, p2.y);
    //ctx.lineTo(p3.x, p3.y);
    ctx.arc(center.x, center.y, l, theta + sweep, theta, true);
    ctx.closePath();
    ctx.fill();
    ctx.stroke();

    //TODO: draw label!!!
}

「横」の線は暗黙的に配置されます。 http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-arcを参照してください。

于 2011-06-29T18:57:48.493 に答える