最干净的拖放代码在JavaScript Canvas中 [英] cleanest Drag and Drop code in Javascript Canvas
问题描述
我正在寻找最快和最轻的方式拖放形状和精灵在JS画布上的游戏开发目的。
I'm looking for the fastest and lightest way to drag and drop shapes and sprites on a JS Canvas for game-development purposes.
我开始使用当前的鼠标位置和圆的原点进行距离检查。它工作,但是当它们重叠时,我们有问题,我不知道这将在多个精灵和其他形状在每个框架测试时如何工作。
I've started by doing distance checks using the current mouse position and the origins of circles. It works, but when they overlap we have problems and I don't know how well this will work when testing for multiple sprites and other shapes yet on each 'frame'.
任何评论或指向更好的方法的赞赏!
Any comments or pointers to better methods are appreciated!
我宁愿不使用像jQuery这样的库,因为我要去纯粹的速度和轻量,当然要学习实际的方法!这里是我在哪里:
I'd rather not use a library like jQuery since I'm going for pure speed and lightness and of course to learn the actual methods! Here's where I'm at:
//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;
}
推荐答案
用于拖动单个项。我不能告诉你是否要拖拽多个东西,这是一个小小的修改。
Here's the setup I've used for dragging a single item. I can't tell if you want to drag multiple things or not, that'd be a slight modification.
在文字:在mousedown搜索一个命中的对象在保留顺序你绘制对象(所以最顶端的项目被首先命中),存储这个命中项目,然后mousedrag只是管道协调/三角洲到那个项目。
In words: in mousedown search for a hit object in the reserved order you drew the objects (so the topmost item gets hit first), store this hit item, then mousedrag is simply piping the coords/delta to that item.
//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用于保持项目跳转到光标时点击你也可以只存储旧的鼠标坐标,并为您的项目添加一个增量。
My js is rusty at the moment but this should give the idea. The dragOffsetX/Y is used to keep the item from jumping to the cursor when clicked. You could also just store the old mouse coordinate and add a delta to your item.
此外,不是存储一个索引到你的拖动项目,你可以存储一个引用,引用拖动多个项目,而不是直接操作你的项目,你可以放一个mousedown / drag / up接口,让他们处理它,这将使它更容易混合在其他类型的项目。
Also, instead of storing an index to your drag item you could store a reference to it, or maybe an array of references to drag multiple items. And instead of directly manipulating your items you could put a mousedown/drag/up interface on them to let them handle it. This'll make it easier to mix in other types of items.
我不确定的另一件事是你如何计算你的坐标,我做一些不同的东西,但它是旧的代码,我猜你的方式措施,以及。-t
Another thing I'm not sure about is how you're calculating your coordinates. I do something different but it's older code and I'm guessing your way measures just as well. -t
这篇关于最干净的拖放代码在JavaScript Canvas中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!