5

まず、私はたくさんの研究をして、成功せずに自分自身を試したと言いたいです。

Canvasを使用してMSPaintのようなアプリケーションに取り組んでおり、手作りの描画のようにリアルに見える鉛筆ツールを作成したいと思います...デフォルトのツールを使用した以下のリンクの例を次に示します: http://www.onemotion .com / flash / Sketch-paint /

mousespeedプロパティとlinewidthプロパティを試してみましたが、うまく機能していません(マウスを動かすと、行全体が拡大および縮小します)。ピクセルの生データに作用するアルゴリズムがわかりません。

既存の何か、または適用するのに適したアルゴリズムを知っていますか?ご助力ありがとうございます

編集

多くの人が興味を持っているように見えるので、私が選んだソリューションを追加することにしました。したがって、これまでに見つけた最良の方法は、http: //css.dzone.com/articles/sketching-html5-canvas-andで説明されている手法を使用して、キャンバスに画像を描画することです。それは魅力のように機能し、結果は本当に説得力があり、これは非常に簡単に実装できます。ここで試してみてください:http://tricedesigns.com/portfolio/sketch/brush.html#

4

1 に答える 1

29

次のデモのようなものを試すことができます

ライブデモ

moveToパスを使用して作成する可能性が最も高いlineToのは、パスを閉じるまで、パスのプロパティが共有されるようにする場合です。したがって、厚さを変更するたびに、呼び出す必要がありclosePathますbeginPath

私の例では、ブレゼンハムの線アルゴリズムを使用して点をプロットします。基本的にオンマウスダウンでペイントを開始します。次に、onmousemoveは現在の座標を最後の座標と比較し、その間のすべてのポイントをプロットします。fillRect塗装にも使用しています。線の移動速度に基づいて、線が太くなったり細くなったりします。

描画関数のコードは次のとおりです

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    painting = false,
    lastX = 0,
    lastY = 0,
    lineThickness = 1;

canvas.width = canvas.height = 600;
ctx.fillRect(0, 0, 600, 600);

canvas.onmousedown = function(e) {
    painting = true;
    ctx.fillStyle = "#ffffff";
    lastX = e.pageX - this.offsetLeft;
    lastY = e.pageY - this.offsetTop;
};

canvas.onmouseup = function(e){
    painting = false;
}

canvas.onmousemove = function(e) {
    if (painting) {
        mouseX = e.pageX - this.offsetLeft;
        mouseY = e.pageY - this.offsetTop;

        // find all points between        
        var x1 = mouseX,
            x2 = lastX,
            y1 = mouseY,
            y2 = lastY;


        var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
        if (steep){
            var x = x1;
            x1 = y1;
            y1 = x;

            var y = y2;
            y2 = x2;
            x2 = y;
        }
        if (x1 > x2) {
            var x = x1;
            x1 = x2;
            x2 = x;

            var y = y1;
            y1 = y2;
            y2 = y;
        }

        var dx = x2 - x1,
            dy = Math.abs(y2 - y1),
            error = 0,
            de = dy / dx,
            yStep = -1,
            y = y1;

        if (y1 < y2) {
            yStep = 1;
        }

        lineThickness = 5 - Math.sqrt((x2 - x1) *(x2-x1) + (y2 - y1) * (y2-y1))/10;
        if(lineThickness < 1){
            lineThickness = 1;   
        }

        for (var x = x1; x < x2; x++) {
            if (steep) {
                ctx.fillRect(y, x, lineThickness , lineThickness );
            } else {
                ctx.fillRect(x, y, lineThickness , lineThickness );
            }

            error += de;
            if (error >= 0.5) {
                y += yStep;
                error -= 1.0;
            }
        }



        lastX = mouseX;
        lastY = mouseY;

    }
}

</ p>

于 2012-04-12T19:49:56.700 に答える