2011-12-16 4 views
7

私は、ゲーム開発目的でJSキャンバスにシェイプとスプライトをドラッグ&ドロップする方法を探しています。Javascriptでもっともきれいなドラッグ&ドロップコードキャンバス

私は、現在のマウスの位置と円の起源を使って距離チェックを行うことから始めました。それは動作しますが、重複すると問題が発生しますが、複数のスプライトやその他の図形をそれぞれのフレームでテストする際に、どれがうまく動作するかはわかりません。

より良い方法へのコメントやご指摘をいただければ幸いです。

私は純粋なスピードと軽さのために、実際の方法を学ぶために行くので、むしろjQueryのようなライブラリを使用したくないです!ここには私がいる場所があります:

//add the canvas listeners and functions 

canvas.addEventListener("mousemove",mousemove); 
canvas.addEventListener("mousedown",mousedown); 
canvas.addEventListener("mouseup",mouseup); 

function mousemove(e){ 
    mouseX = e.layerX - canvas.offsetLeft; 
    mouseY = e.layerY - canvas.offsetTop; 

//for each circle stored in my array of Circle objects, is my mouse within its'   
//bounds? If so, set the circles' (X,Y) to my mouse's (X,Y) 

    for(i=0;i<circArray.length;i++){ 
     dx = mouseX - circArray[i].x; 
     dy = mouseY - circArray[i].y; 
     dist = Math.sqrt((dx*dx) + (dy*dy)); 
     if(draggable && dist < circArray[i].r){   
      circArray[i].x = mouseX; 
      circArray[i].y = mouseY; 
     } 
    } 
} 

function mousedown(){ 
     draggable = true; 
} 

function mouseup(){ 
     draggable = false; 
} 
+1

あなたはjQuery UI draggables(http://jqueryui.com/demos/draggable/)を考えています。あなたがjQueryに行かなくても、私は高度化していないバージョンをチェックし、彼らが何をしているかを非常に助言します。開発者は、これらのパフォーマンスの問題のいくつかを間違いなく考えました。リベラルなライセンスのため、コードベースの小さな断片を切り抜ける可能性があります。 – buley

+1

[fabric.js](https://github.com/kangax/fabric.js)をご覧ください。ここにデモがあります:http://kangax.github.com/fabric.js/stickman/ –

答えて

3

これは私が1つのアイテムをドラッグするために使用した設定です。私はあなたが複数のものをドラッグしたいのかどうかは分かりませんが、それは少し修正されるでしょう。

mousedownでは、オブジェクトを描画した順番でヒットしたオブジェクトを検索し(最上位のアイテムが最初にヒットします)、このヒットアイテムを保存して、mousedragは単にアイテム/デルタをパイプしています。

//start with only the mousedown event attached 
canvas.addEventListener("mousedown",mousedown); 

//and some vars to track the dragged item 
var dragIdx = -1; 
var dragOffsetX, dragOffsetY; 

function mousedown(e){ 
    //...calc coords into mouseX, mouseY 
    for(i=circArray.length; i>=0; i--){ //loop in reverse draw order 
     dx = mouseX - circArray[i].x; 
     dy = mouseY - circArray[i].y; 
     if (Math.sqrt((dx*dx) + (dy*dy)) < circArray[i].r) {   
      //we've hit an item 
      dragIdx = i; //store the item being dragged 
      dragOffsetX = dx; //store offsets so item doesn't 'jump' 
      dragOffsetY = dy; 
      canvas.addEventListener("mousemove",mousemove); //start dragging 
      canvas.addEventListener("mouseup",mouseup); 
      return; 
     } 
    } 
} 

function mousemove(e) { 
    //...calc coords 
    circArray[dragIdx].x = mouseX + dragOffsetX; //drag your item 
    circArray[dragIdx].y = mouseY + dragOffsetY; 
    //...repaint(); 
} 

function mouseup(e) { 
    dragIdx = -1; //reset for next mousedown 
    canvas.removeListener(.... //remove the move/up events when done 
} 

私のjsは現時点では錆びていますが、これはアイデアを与えるはずです。 dragOffsetX/Yは、アイテムがクリックされたときにカーソルにジャンプしないようにするために使用されます。また、古いマウス座標を保存して、アイテムにデルタを追加することもできます。

また、ドラッグ項目にインデックスを格納する代わりに、その項目への参照を格納することも、複数の項目をドラッグするための参照配列を格納することもできます。そしてあなたのアイテムを直接操作するのではなく、それらを操作できるように、マウス/ドラッグ/アップのインターフェイスを置くことができます。これにより、他のタイプのアイテムに簡単に混在させることができます。

あなたが座標をどのように計算しているのか分かりません。私は何か違うことをしますが、それは古いコードなので、あなたのやり方もちょうどいいと思っています。 -t

+0

私は 'circArray [dragIdx] .x = mouseX + dragOffsetX;'は実際には 'circArray [dragIdx] .x = mouseX - dragOffsetX; ' dragOffsetがマウスの位置から減算されるようにします。 – JaAnTr

関連する問題