0

kineticjs を使用して html5 キャンバスでペイント ブラシ機能を使用したいのですが、いくつかのチュートリアルを読んだ後、さまざまなポイントとして四角形を作成するのが良い方法であることがわかりました。しかし、これは形成されるラインに矛盾を生じさせています。マウスを速く動かすとよく壊れます。ここにフィドルへのリンクがあります。 http://jsfiddle.net/9bGdr/1/

var stage = new Kinetic.Stage({
    container:'canvas',
    width:500,
    height:500
});

var layer = new Kinetic.Layer();

var painting = false ;

stage.add(layer);

var canvas = $(stage.getContent());
    var lineThickness = 5 ;

canvas.mousedown(function(e) { 
    painting = true;

});

canvas.mousemove(function(e) { 

  if (painting) {

rect = new Kinetic.Rect({
x:e.pageX,
y:e.pageY,
width:lineThickness,
height:lineThickness,
fill:'black',
        stroke: 'black',
        strokeWidth: lineThickness,
        lineJoin: 'round',
        lineCap: 'round'
});

layer.add(rect);
layer.batchDraw();

}

});

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

1 に答える 1

1

mousemove ハンドラーが四角形のサイズを超えるドラッグ距離を検出した場合、ドラッグされた距離全体をカバーするために複数の四角形を描画する必要があります。

各マウス移動中に行うことは次のとおりです。

  • ドラッグ中にマウスが移動した距離を計算します。
  • その「ドラッグライン」をカバーするために必要な四角形の数を計算します。
  • 線形補間を使用して、ドラッグ ラインに沿って複数の四角形を描画します。

下の図では、T の下をすばやくドラッグしました。

コードがドラッグラインのすべての部分を複数の四角形で埋めていることに注意してください。

ここに画像の説明を入力

ここにコードとフィドルがあります: http://jsfiddle.net/m1erickson/D332T/

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.2.min.js"></script>
<style>
#canvas{
  border:solid 1px #ccc;
  margin-top: 0px;
  width:350px;
  height:350px;
}
</style>        
<script>
$(function(){

    var stage = new Kinetic.Stage({
        container:'canvas',
        width:350,
        height:350
    });
    var layer = new Kinetic.Layer();
    stage.add(layer);

    var painting = false ;
    var lineThickness = 5 ;
    var startX,startY;

    $(stage.getContent()).on('mousedown', function (event) {
        var pos=stage.getMousePosition();
        startX=parseInt(pos.x);
        startY=parseInt(pos.y);
        painting = true;
    });


    $(stage.getContent()).on('mousemove', function (event) {
        if(!painting){return;}
        var pos=stage.getMousePosition();
        var mouseX=parseInt(pos.x);
        var mouseY=parseInt(pos.y);
        var dx=mouseX-startX;
        var dy=mouseY-startY;
        var rectCount=Math.sqrt(dx*dx+dy*dy)/lineThickness;

        if(rectCount<=1){
            rect = new Kinetic.Rect({
                x:mouseX,
                y:mouseY,
                width:lineThickness,
                height:lineThickness,
                fill:'black',
                stroke: 'black',
                strokeWidth: lineThickness,
                lineJoin: 'round',
                lineCap: 'round'
            });
            layer.add(rect);
        }else{
            for(var i=0;i<rectCount;i++){
                  // calc an XY between starting & ending drag points
                  var nextX=startX+dx*i/rectCount;
                  var nextY=startY+dy*i/rectCount;
                  // add a rect at the calculated XY
                  rect = new Kinetic.Rect({
                      x:nextX,
                      y:nextY,
                      width:lineThickness,
                      height:lineThickness,
                      fill:'red',
                      stroke: 'black',
                      strokeWidth: lineThickness,
                      lineJoin: 'round',
                      lineCap: 'round'
                  });
                  layer.add(rect);
            }
        }
        layer.draw();
        startX=mouseX;
        startY=mouseY;
    });

    $(stage.getContent()).on('mouseup', function (event) {
        startX=null;
        startY=null;
        painting = false;
    });

    $(stage.getContent()).on('mouseout', function (event) {
        startX=null;
        startY=null;
        painting = false;
    });


}); // end $(function(){});

</script>       
</head>

<body>
    <div id="canvas"></div>
</body>
</html>

[OPの速度向上の必要性に基づく追加]

または、より高速で効率的な「スケッチ」の代替手段があります。

効率は、ドラッグ ラインをカバーするために多くの長方形の代わりに 1 つのポリラインを描画することです。

ここにフィドルがあります: http://jsfiddle.net/m1erickson/CCqhg/

ここに画像の説明を入力

ポリラインでスケッチするコードは次のとおりです。

マウスダウン時: マウスダウン座標から始まる新しいポリラインを作成します

// a flag we use to see if we're dragging the mouse
var isMouseDown=false;
// a reference to the line we are currently drawing
var newline;
// a reference to the array of points making newline
var points=[];

// On mousedown
// Set the isMouseDown flag to true
// Create a new line,
// Clear the points array for new points
// set newline reference to the newly created line
function onMousedown(event) {
    isMouseDown = true;
    points=[];
    points.push(stage.getMousePosition());
    var line = new Kinetic.Line({
        points: points,
        stroke: "green",
        strokeWidth: 5,
        lineCap: 'round',
        lineJoin: 'round'
    });
    layer.add(line);
    newline=line;
} 

mousemove: 現在のマウス座標に到達する線にセグメントを追加します。

// on mousemove
// Add the current mouse position to the points[] array
// Update newline to include all points in points[]
// and redraw the layer
function onMousemove(event) {
    if(!isMouseDown){return;};
    points.push(stage.getMousePosition());
    newline.setPoints(points);
    // use layer.drawScene
    // This avoids unnecessarily updating the hit canva
    layer.drawScene();
}
于 2013-10-12T02:57:13.167 に答える