2013-08-03 52 views
1

我剛開始學習html5,我正嘗試創建一個可拖動的戰艦界面。我需要幫助,使我的拖動方法的工作。我故意不使用圖書館,因爲我需要讓這些船可以在另一個帆布界面(戰艦艦)上拖曳,我無法弄清楚如何處理Kinetic庫。我覺得我很接近,但我無法弄清楚最後一點。該船舶應被順利拖,但他們似乎被點擊時捕捉到鼠標的位置...如何在畫布上製作HTML5可拖動對象?

這裏是我的clode:

<!doctype html> 
<html> 
    <head> 
     <meta charset="UTF-8" /> 
     <title>Canvas Drag and Drop Test</title> 
    </head> 
    <body> 
     <section> 

      <div align=center> 
       <canvas id="canvas" width="550" height="550"> 
        This text is displayed if your browser does not support HTML5 Canvas. 
       </canvas> 
      </div> 

      <script type="text/javascript"> 
       var canvas; 
       var ctx; 
       var x = 75; 
       var y = 50; 
       var WIDTH = 550; 
       var HEIGHT = 550; 
       var dragok = false; 
       var ships = []; 
       var ship; 
       var shipFill = "#FF0000"; 
       //Definitions 
       //Draggable Carrier 
       var caRectX = 100; 
       var caRectY = 50; 
       var caRectHeight = 50; 
       var caRectWidth = 5 * 50; 
       var carrier = { 
        x : caRectX, 
        y : caRectY, 
        width : caRectWidth, 
        height : caRectHeight, 
        fill : shipFill, 
        dragging : false, 
        offsetX : 0, 
        offsetY : 0, 

       }; 
       ships.push(carrier); 
       //Draggable Battleship 
       var bsRectX = 100; 
       var bsRectY = 150; 
       var bsRectHeight = 50; 
       var bsRectWidth = 4 * 50; 

       var battleship = { 
        x : bsRectX, 
        y : bsRectY, 
        width : bsRectWidth, 
        height : bsRectHeight, 
        fill : shipFill, 
        dragging : false, 
        offsetX : 0, 
        offsetY : 0, 

       }; 
       ships.push(battleship); 

       //Draggable Patrolboat 
       var pbRectX = 100; 
       var pbRectY = 250; 
       var pbRectHeight = 50; 
       var pbRectWidth = 2 * 50; 

       var patrolboat = { 
        x : pbRectX, 
        y : pbRectY, 
        width : pbRectWidth, 
        height : pbRectHeight, 
        fill : shipFill, 
        dragging : false, 
        offsetX : 0, 
        offsetY : 0, 

       }; 
       ships.push(patrolboat); 

       //Draggable Submarine 
       var suRectX = 100; 
       var suRectY = 350; 
       var suRectHeight = 50; 
       var suRectWidth = 3 * 50; 

       var submarine = { 
        x : suRectX, 
        y : suRectY, 
        width : suRectWidth, 
        height : suRectHeight, 
        fill : shipFill, 
        dragging : false, 
        offsetX : 0, 
        offsetY : 0, 

       }; 
       ships.push(submarine); 

       //Draggable destroyer 
       var deRectX = 100; 
       var deRectY = 450; 
       var deRectHeight = 50; 
       var deRectWidth = 3 * 50; 

       var destroyer = { 
        x : deRectX, 
        y : deRectY, 
        width : deRectWidth, 
        height : deRectHeight, 
        dragging : false, 
        fill : shipFill 
       }; 
       ships.push(destroyer) 

       function rect(x, y, w, h) { 
        ctx.beginPath(); 
        ctx.rect(x, y, w, h); 
        ctx.closePath(); 
        ctx.fill(); 
       } 

       function clear() { 
        ctx.clearRect(0, 0, WIDTH, HEIGHT); 
       } 

       function init() { 
        canvas = document.getElementById("canvas"); 
        ctx = canvas.getContext("2d"); 
        return setInterval(draw, 10); 
       } 

       function draw() { 
        clear(); 
        ctx.fillStyle = "#FAF7F8"; 
        rect(0, 0, WIDTH, HEIGHT); 
        ctx.fillStyle = "#444444"; 
        for (var i = 0; i < ships.length; i++) { 
         rect(ships[i].x, ships[i].y, ships[i].width, ships[i].height); 
        } 
       } 

       function myMove(e) { 
        if (ship.dragging) { 
         ship.x = e.pageX - canvas.offsetLeft; 
         ship.y = e.pageY - canvas.offsetTop; 
         draw() 
        } 
       } 

       function myDown(e) { 
        ship = getClickedShip(e.pageX,e.pageY); 
        if (ship!=null) { 
         ship.x = e.pageX - canvas.offsetLeft; 
         ship.y = e.pageY - canvas.offsetTop; 
         ship.dragging = true; 
         canvas.onmousemove = myMove(); 
        } 
       } 

       function myUp() { 
        ship.dragging = false; 
        canvas.onmousemove = null; 
       } 

       function getClickedShip(sx,sy){ 
        for (var i = 0; i < ships.length; i++){ 
         if(sx > (ships[i].x)+ canvas.offsetLeft && sx < (ships[i].x+ships[i].width+ canvas.offsetLeft) && sy > (ships[i].y + canvas.offsetTop) && sy < (ships[i].y+ships[i].height)) 
          return ships[i]; 
        } 
       } 
       init(); 
       canvas.onmousedown = myDown; 
       canvas.onmouseup = myUp; 

      </script> 

     </section> 
    </body> 
</html> 

回答

6

這是程序製作一個html形狀拖動

請注意,這已經回答了之前SO(很多次!)

但這個答案說明了新context.isPointInPath方法點擊測試點是否是一個html畫布裏面拍H。

希望,這個新的點擊測試方法將新&到OP有用的人:)

下面是在HTML畫布拖動形狀的一般程序:

在鼠標按下:

  • 將此鼠標X位置保存在一個變量中(lastX)
  • 將此鼠標位置保存在變量中(lastY)
  • 設置mouseIsDown標誌設置爲true

在mouseUp事件

  • 設置mouseIsDown標誌設置爲false

上的mouseMove

  • 命中測試每艘看如果它應該被拖動。

    function handleMouseDown(e){ 
    
        // get the current mouse position relative to the canvas 
    
        mouseX=parseInt(e.clientX-offsetX); 
        mouseY=parseInt(e.clientY-offsetY); 
    
        // save this last mouseX/mouseY 
    
        lastX=mouseX; 
        lastY=mouseY; 
    
        // set the mouseIsDown flag 
    
        mouseIsDown=true; 
    } 
    
  • 如果lastX/lastY是一個船舶的內部,即船舶正在由鼠標剛剛移動

的MouseDown處理程序代碼的距離拖拽

  • 移動拖船

    MouseUp處理程序代碼:

    function handleMouseUp(e){ 
    
        // clear the mouseIsDown flag 
    
        mouseIsDown=false; 
    } 
    

    的MouseMove處理程序代碼:

    此代碼示出了使用context.isPointInPath擊中測試一個html畫布路徑

    做的程序是:

    • 限定的路徑(但不畫它 - 沒有填充,沒有筆畫)
    • 使用context.isPointInPath(x,y)來測試x,y是否在上面定義的路徑內。

    下面是使用context.isPointInPath

    function handleMouseMove(e){ 
    
        // if the mouseIsDown flag is’nt set, no work to do 
    
        if(!mouseIsDown){ return; } 
        // get mouseX/mouseY 
    
        mouseX=parseInt(e.clientX-offsetX); 
        mouseY=parseInt(e.clientY-offsetY); 
    
        // for each ship in the ships array 
        // use context.isPointInPath to test if it’s being dragged 
    
        for(var i=0;i<ships.length;i++){ 
         var ship=ships[i]; 
         drawShip(ship); 
         if(ctx.isPointInPath(lastX,lastY)){ 
    
          // if this ship’s being dragged, 
          // move it by the change in mouse position from lastXY to currentXY 
    
          ship.x+=(mouseX-lastX); 
          ship.y+=(mouseY-lastY); 
          ship.right=ship.x+ship.width; 
          ship.bottom=ship.y+ship.height; 
         } 
        } 
    
        // update the lastXY to the current mouse position 
        lastX=mouseX; 
        lastY=mouseY; 
    
        // draw all ships in their new positions 
        drawAllShips(); 
    } 
    

    注意有關提高性能鼠標移動處理器:

    • 在生產中,你會希望有鼠標移動剛剛保存的鼠標位置。
    • 然後讓另一個程序檢索這些保存的位置並進行命中測試/重繪。
    • 其他過程可能會在像requestAnimationFrame這樣的定時循環內。

    這裏的代碼和一個小提琴:http://jsfiddle.net/m1erickson/sEBAC/

    <!doctype html> 
    <html> 
    <head> 
    <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> 
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 
    
    <style> 
        body{ background-color: ivory; } 
        canvas{border:1px solid red;} 
    </style> 
    
    <script> 
    $(function(){ 
    
        var canvas=document.getElementById("canvas"); 
        var ctx=canvas.getContext("2d"); 
        ctx.strokeStyle="lightgray"; 
    
        var canvasOffset=$("#canvas").offset(); 
        var offsetX=canvasOffset.left; 
        var offsetY=canvasOffset.top; 
    
        var mouseIsDown=false; 
        var lastX=0; 
        var lastY=0; 
    
        var ships=[]; 
    
        // make some ship 
        makeShip(20,30,50,25,"skyblue"); 
        makeShip(20,100,30,25,"skyblue"); 
        makeShip(20,170,50,25,"salmon"); 
        makeShip(20,240,30,25,"salmon"); 
    
        function makeShip(x,y,width,height,fill){ 
         var ship={ 
          x:x, 
          y:y, 
          width:width, 
          height:height, 
          right:x+width, 
          bottom:y+height, 
          fill:fill 
         } 
         ships.push(ship); 
         return(ship); 
        } 
    
        drawAllShips(); 
    
        function drawAllShips(){ 
         ctx.clearRect(0,0,canvas.width,canvas.height); 
         for(var i=0;i<ships.length;i++){ 
          var ship=ships[i] 
          drawShip(ship); 
          ctx.fillStyle=ship.fill; 
          ctx.fill(); 
          ctx.stroke(); 
         } 
        } 
    
        function drawShip(ship){ 
         ctx.beginPath(); 
         ctx.moveTo(ship.x,ship.y); 
         ctx.lineTo(ship.right,ship.y); 
         ctx.lineTo(ship.right+10,ship.y+ship.height/2); 
         ctx.lineTo(ship.right,ship.bottom); 
         ctx.lineTo(ship.x,ship.bottom); 
         ctx.closePath(); 
        } 
    
        function handleMouseDown(e){ 
         mouseX=parseInt(e.clientX-offsetX); 
         mouseY=parseInt(e.clientY-offsetY); 
    
         // mousedown stuff here 
         lastX=mouseX; 
         lastY=mouseY; 
         mouseIsDown=true; 
    
        } 
    
        function handleMouseUp(e){ 
         mouseX=parseInt(e.clientX-offsetX); 
         mouseY=parseInt(e.clientY-offsetY); 
    
         // mouseup stuff here 
         mouseIsDown=false; 
        } 
    
        function handleMouseMove(e){ 
         if(!mouseIsDown){ return; } 
    
         mouseX=parseInt(e.clientX-offsetX); 
         mouseY=parseInt(e.clientY-offsetY); 
    
         // mousemove stuff here 
         for(var i=0;i<ships.length;i++){ 
          var ship=ships[i]; 
          drawShip(ship); 
          if(ctx.isPointInPath(lastX,lastY)){ 
           ship.x+=(mouseX-lastX); 
           ship.y+=(mouseY-lastY); 
           ship.right=ship.x+ship.width; 
           ship.bottom=ship.y+ship.height; 
          } 
         } 
         lastX=mouseX; 
         lastY=mouseY; 
         drawAllShips(); 
        } 
    
        $("#canvas").mousedown(function(e){handleMouseDown(e);}); 
        $("#canvas").mousemove(function(e){handleMouseMove(e);}); 
        $("#canvas").mouseup(function(e){handleMouseUp(e);}); 
    
    }); // end $(function(){}); 
    </script> 
    
    </head> 
    
    <body> 
        <canvas id="canvas" width=300 height=300></canvas> 
    </body> 
    </html> 
    
  • +0

    我們能有相同的演示中,我們要使用圖片...多張圖片在畫布dragable情況下工作。 – StackUser

    +0

    在drawAllShips中使用'ctx.drawImage'而不是'ctx.fill和ctx.stroke'。圖像將顯示並且路徑仍然提供'isPointInPath'中使用的命中區域。我相信你可以做出必要的調整。乾杯! – markE

    +0

    工作得很好謝謝,除此之外,其實我有一些其他問題,以及關於畫布和所有[將不可能在這裏分享] ..我想從你這樣的人[完美]的建議。你是否也諮詢過外部堆棧溢出?如果可以的話,如果你可以給你一些時間,那將會很棒,也很感激。 – StackUser