前言
canvas 可增加圖形、文字到畫板,但當位置想要移動時就要回到 Javascript 內修改,所以找了一下有沒有可以直接拖移圖形的方式,發現可以用 isDragging
打開拖移功能並取得圖形的設定值,在點擊圖形時就執行變更設定達到移動的目的。
筆記
初始值
1 2 3 4 5 6 7 8 9
| var isDragging = false; var startX, startY;
var shapes=[];
var selectedShapeIndex;
|
載入圖形
因為需要判斷滑鼠是否在圖形上,所以就不是用 canvas 原本的方式
1 2 3 4 5 6 7 8 9 10
| ctx.fillStyle="#FF0000"; ctx.beginPath(); ctx.arc(30, 30, 15, 0, 2*Math.PI); ctx.closePath(); ctx.fill();
ctx.fillStyle = "#0000ff"; ctx.fillRect(100, -1, 75, 35);
|
而是先建立 陣列 和 物件 組合的方式
1 2 3 4 5 6 7 8 9 10 11 12
| var shapes=[];
shapes.push( {x:30, y:30, radius:15, color:'blue'} );
shapes.push( {x:100, y:-1, width:75, height:35, color:'red'} );
ctx.onmousedown = handleMouseDown; ctx.onmousemove = handleMouseMove; ctx.onmouseup = handleMouseUp; ctx.onmouseout = handleMouseOut;
|
再產生圖形
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| drawAll();
function drawAll(){ ctx.clearRect(0, 0, cw, ch); for(var i = 0; i < shapes.length; i++){ var shape = shapes[i]; if(shape.radius){ ctx.beginPath(); ctx.arc(shape.x, shape.y, shape.radius, 0, Math.PI*2); ctx.fillStyle = shape.color; ctx.fill(); }else if(shape.width){ ctx.fillStyle = shape.color; ctx.fillRect(shape.x, shape.y, shape.width, shape.height); } } }
|
載入文字
所以也可以載入文字
1 2 3 4 5 6 7 8 9
| shapes.push({x:50, y:50, text:'文字拖移', fontSize: 36}); if(shape.text){ ctx.textBaseline = 'top'; ctx.font = shape.fontSize + "px impact"; ctx.fillText(shape.text, shape.x, shape.y); }
|
載入圖片
載入圖片也可以置入到陣列中
1 2 3 4 5 6 7 8 9 10 11 12 13
| var card = new Image(); card.onload = function(){ shapes.push( {x:30, y:10, width:127, height:150, image:card} ); drawAll(); ctx.onmousedown = handleMouseDown; ctx.onmousemove = handleMouseMove; ctx.onmouseup = handleMouseUp; ctx.onmouseout = handleMouseOut; }; card.src = 'card.png';
|
判斷滑鼠是否在範圍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| function isMouseInShape(mx, my, shape){ if(shape.radius){ var dx = mx - shape.x; var dy = my - shape.y; if(dx*dx + dy*dy < shape.radius*shape.radius){ return(true); } }else if(shape.width){ var rLeft = shape.x; var rRight = shape.x + shape.width; var rTop = shape.y; var rBott = shape.y + shape.height; if( mx > rLeft && mx < rRight && my > rTop && my < rBott){ return(true); } }else if(shape.image){ var rLeft = shape.x; var rRight = shape.x + shape.imgWidth; var rTop = shape.y; var rBott = shape.y + shape.imgHeight; if( mx > rLeft && mx < rRight && my > rTop && my < rBott){ return(true); } }else if(shape.text){ var rLeft = shape.x; var rRight = shape.x + ctx.measureText(shape.text).width; var rTop = shape.y; var rBott = shape.y + shape.fontSize; if (mx > rLeft && mx < rRight && my > rTop && my < rBott) { return true; } } return(false); }
|
圖形拖移
- 滑鼠事件
- 元素重疊時,移動就需要停止 默認事件、冒泡事件
- 默認事件
event.preventDefault()
- 冒泡事件
event.stopPropagation()
滑鼠在圖形上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| ctx.onmousedown = handleMouseDown; function handleMouseDown(e){ e.preventDefault(); e.stopPropagation(); startX = parseInt(e.clientX-offsetX); startY = parseInt(e.clientY-offsetY); for(var i = 0; i < shapes.length; i++){ if(isMouseInShape(startX,startY,shapes[i])){ selectedShapeIndex=i; isDragging=true; return; } } }
ctx.onmousemove = handleMouseMove; function handleMouseMove(e){ if(!isDragging){return;} e.preventDefault(); e.stopPropagation(); mouseX = parseInt(e.clientX-offsetX); mouseY = parseInt(e.clientY-offsetY); var dx = mouseX - startX; var dy = mouseY - startY; var selectedShape=shapes[selectedShapeIndex]; selectedShape.x += dx; selectedShape.y += dy; drawAll(); startX = mouseX; startY = mouseY; }
|
滑鼠在圖形外
當放開 / 移開滑鼠,目的是一樣的 不拖移任何一個物件 ,所以 isDragging
就應該要是 false
,若是 true
時就要成 false
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ctx.onmouseup = handleMouseUp; ctx.onmouseout = handleMouseOut;
function handleMouseUp(e){ if(!isDragging){ return; } e.preventDefault(); e.stopPropagation(); isDragging = false; }
function handleMouseOut(e){ if(!isDragging){return;} e.preventDefault(); e.stopPropagation(); isDragging = false; }
|
參考
拖動 -畫布- 內的圖像
https://riptutorial.com/zh-TW/html5-canvas/example/18920/在-畫布-周圍拖動圖像
滑鼠事件
HTML DOM MouseEvent