3

AngularJS を使用して、KineticJS オブジェクトをデータに (双方向で) バインドするにはどうすればよいですか?
たとえば、キネティック シェイプの位置を変数またはテキスト ボックスにバインドします。

私はAngularJSなしでこれを行う方法を考え出しました:
(jQueryでKineticJSを使用)

box.on('dragmove', function() {
    $('#pos_x').val( myShape.getX() );
    $('#pos_y').val( myShape.getY() );
});

$('#pos_x').change(function() {
    var x = parseInt( $('#pos_x').val() );
    var y = parseInt( $('#pos_x').val() );
    box.setPosition( x, y );
});
// and the same for $('#pos_y');

コードの説明:
ボックスと 2 つのテキスト ボックスがあります。
ボックスをドラッグすると、ボックスの座標が両方のテキスト ボックスに表示されます。
両方のテキストボックスの値が変更されると、ボックスの位置も変更されます

しかし、私はAngularJSでそれを行う方法を知りたかった
(IMO、それぞれ独自のテキストボックスを持つオブジェクトが多数ある場合ははるかに簡単になります)

4

1 に答える 1

9

KineticJS と AngularJS を組み合わせようとすると、いくつかの統合の問題が発生します

AngularJS は DOM 要素のバインドに優れています。

しかし、KineticJS オブジェクトは DOM 要素ではなく、キャンバス上の単なるピクセルです。

したがって、AngularJS は Kinetic オブジェクトを直接制御することはできません。

テキスト入力の変更に応答してキネティック オブジェクトを移動させるには、AngularJS コントローラーを使用して、キネティック オブジェクトの setX/setY を呼び出します。

Kinetic オブジェクトがドラッグされるときにテキスト入力値を変更するには、Kinetic dragmove イベント ハンドラー内から AngularJS コントローラーを呼び出します。

複雑なのは、既定では、Angular と Kinetic の両方が独自の目的でマウス イベントを制御する必要があることです。

出来ないとは言いませんが…

KineticJS + AngularJS の統合は、既に取得している Kinetic + jQuery メソッドよりも複雑です。

Kinetic + jQuery をあきらめる前に

Kinetic オブジェクトとテキスト入力を統合するこのコードを確認してください。

図形とテキストのペアを必要な数だけすばやく作成できます。

また、各ペアは自動的に統合されるため、ドラッグまたはテキスト入力のいずれかで形状が移動し、テキスト入力の現在の位置が表示されます。

ところで、ここでは便宜上 jQuery を使用しましたが、これを純粋な JavaScript に非常に簡単に変換でき、外部ライブラリはまったく必要ありません。

ここに画像の説明を入力

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

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Prototype</title>
    <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.0.min.js"></script>

<style>
body{background:ivory; padding:10px;}
#container{
  border:solid 1px #ccc;
  margin-top: 10px;
  width:300px;
  height:300px;
}
.boundXY{
    width:105px;
    height:23px;
    color:white;
    padding:5px;
    border:2px solid lightgray;
}

</style>        
<script>
$(function(){

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


// each rect,textX,textY gets a unique id
var nextId=0;

// create some rect-textInput pairs in random colors
for(var i=0;i<6;i++){
    randomPair();
}


function randomPair(){
    var x=parseInt(Math.random()*250);
    var y=parseInt(Math.random()*250);
    var w=parseInt(Math.random()*40)+10;
    var h=parseInt(Math.random()*40)+10;
    addRectTextPair(nextId++,x,y,w,h,randomColor(),"lightgray");
}


function addRectTextPair(id,x,y,w,h,fill,stroke){

    // new kinetic rect
    var rect = new Kinetic.Rect({
        id:"rect"+id,
        x: x,
        y: y,
        width: w,
        height: h,
        fill: fill,
        stroke: stroke,
        strokeWidth: 3,
        draggable:true
    });
    rect.on('dragmove', function() {
        var id=this.getId().slice(4);
        $('#x'+id).val( parseInt(this.getX()) );
        $('#y'+id).val( parseInt(this.getY()) );
    });    
    layer.add(rect);

    // new div with same color as kinetic rect
    var div = document.createElement("div");
    div.id="div"+id;
    div.className="boundXY";
    div.style.background = fill;
    div.innerHTML = "X/Y:";
    // add xy text inputs   
    div.appendChild(newTextInput("x"+id,x));
    div.appendChild(newTextInput("y"+id,y));
    // add div to body
    document.body.appendChild(div);

    // change rect's X when the textInputX changes
    $('#x'+id).change(function(e) {
        var id=e.target.id.slice(1);
        var rect=layer.get("#rect"+id)[0];
        rect.setX( parseInt($(this).val()) );
        layer.draw();
    });

    // change rect's Y when the textInputY changes
    $('#y'+id).change(function(e) {
        var id=e.target.id.slice(1);
        var rect=layer.get("#rect"+id)[0];
        rect.setY( parseInt($(this).val()) );
        layer.draw();
    });

    layer.draw();
}


function randomColor(){
    return('#'+Math.floor(Math.random()*16777215).toString(16));
}


function newTextInput(id,value){
    var input=document.createElement("input");
    input.id=id;
    input.value=value;
    input.type="text";
    input.style.width="25px";
    input.style.marginLeft="5px";
    return(input);
}

$("#oneMore").click(function(){ randomPair(); });

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

</script>       
</head>

<body>
    <p>Reposition rectangles by dragging or changing X/Y</p>
    <button id="oneMore">Add another Rect and TextInput pair</button>
    <div id="container"></div>
</body>
</html>
于 2013-09-28T20:31:10.413 に答える