2011-12-16 2 views
7

Я ищу самый быстрый и легкий способ перетаскивания фигур и спрайтов на JS Canvas для целей разработки игр.Самый чистый код перетаскивания в Javascript Canvas

Я начал с выполнения дистанционных проверок с использованием текущей позиции мыши и истоков кругов. Он работает, но когда они перекрываются, у нас есть проблемы, и я не знаю, насколько хорошо это будет работать при тестировании для нескольких спрайтов и других фигур еще на каждом «фрейме».

Любые комментарии или указатели на лучшие методы оцениваются!

Я бы предпочел не использовать библиотеку, такую ​​как 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

Вот настройка, которую я использовал для перетаскивания одного элемента. Я не могу сказать, хотите ли вы перетащить несколько вещей или нет, это будет небольшая модификация.

В мусороре поиск объекта-хита в зарезервированном порядке вы нарисовали объекты (так что самый верхний элемент попадает в первую очередь), сохраните этот элемент удара, затем 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 используется для того, чтобы элемент не переходил на курсор при нажатии. Вы также можете просто сохранить старую координату мыши и добавить дельта к своему элементу.

Кроме того, вместо хранения указателя на элемент перетаскивания вы можете сохранить ссылку на него или массив ссылок для перетаскивания нескольких элементов. Вместо того, чтобы напрямую манипулировать вашими предметами, вы можете поместить на них интерфейс mousedown/drag/up, чтобы позволить им обрабатывать его. Это облегчит смешивание в других типах предметов.

Другое дело, что я не уверен в том, как вы рассчитываете свои координаты. Я делаю что-то другое, но это более старый код, и я угадываю ваши меры так же хорошо. -t

+0

Я уверен, что 'circArray [dragIdx] .x = mouseX + dragOffsetX;' на самом деле должен быть 'circArray [dragIdx] .x = mouseX - dragOffsetX; '. Так что dragOffset вычитается из местоположения мыши. – JaAnTr

Смежные вопросы