2016-12-27 2 views
2

Я пишу приложение, которое рисует прямоугольники на холсте HTML, используя функцию fillRect. В настоящее время я отслеживаю движение мыши и обнаруживаю, когда указатель мыши нависает над прямоугольником, чтобы выделить его:Как сохранить точное определение наведения курсора после масштабирования холста?

Вот как я сейчас обнаруживаю столкновение, которое отлично работает.

//boxes2 is my array of rectangles 
var l = boxes2.length; 

    for (var i = l - 1; i >= 0; i--) { 

     if (mouseX >= boxes2[i].x && mouseX <= (boxes2[i].x + boxes2[i].w) && 
      mouseY >= boxes2[i].y && mouseY <= (boxes2[i].y + boxes2[i].h)) { 

      selectedBoxNum = i; 

     } 

    } 

Моя проблема в том, что обнаружение парения больше не работает хорошо после увеличения/уменьшения, как фактические границы прямоугольников рассинхронизации от их значений в моем прямоугольнике массиве.

var currentZoomValue = 1; 
function myOnMouseWheel(event) { 

    event.preventDefault(); 

    // Normalize wheel to +1 or -1. 
    var wheel = event.wheelDelta/120; 

    if (wheel == 1) { 
     zoom = 1.1; 
    } 
    else { 
     zoom = .9; 
    } 

    currentZoomValue = currentZoomValue * zoom 
    canvas.style.transform = "scale(" + currentZoomValue + ")"; 

} 

То, что я пробовал:

Масштабирование значений в массиве, как я увеличить/уменьшить масштаб так, что Прямоугольная будет оставаться в синхронизации

Это не будет работать меня, потому что функция масштаба растягивает мой холст, чтобы увеличить размер прямоугольников. Если я также сделаю их более крупными, они будут увеличены вдвое и будут превосходить масштаб моего холста.

компенсирующие мое обнаружение парения основано на моем текущем уровне масштабирования

Я пытался что-то вроде:

if (mouseX >= boxes2[i].x && mouseX <= (boxes2[i].x + (boxes2[i].w * currentZoomValue)) && 
mouseY >= boxes2[i].y && mouseY <= (boxes2[i].y + (boxes2[i].h * currentZoomValue))) { 

     selectedBoxNum = i; 

    } 

Мои попытки это не работает, потому что в то время как высота прямоугольника и ширина этого масштаба в легко предсказуемым образом, координаты x, y не соответствуют. При масштабировании прямоугольники будут выделяться из центра, поэтому некоторые прямоугольники получат значение x, а другие теряют на основе их положения. Я также подумал о сохранении второго массива прямоугольников, который я мог бы использовать только для обнаружения зависания, но решил против этого по этой причине.

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

+0

http://stackoverflow.com/questions/40600192/how-to-get-mouse-position-on-transformed-html5-canvas/40611738#40611738 – Kaiido

ответ

1

Поскольку есть no standard way of knowing page zoom level, я бы предложил поймать событие click с абсолютно расположенным div.

Вы можете получить смещение вашего элемента холста с помощью метода getBoundingClientRect().

Тогда код будет выглядеть примерно так:

boxes2.forEach(function(box, i) { 

    cx.fillRect(box.x, box.y, box.w, box.h); 

    /* We create an empty div */ 
    var div = document.createElement("div"); 
    /* We get the position of the canvas */ 
    var rect = canvas.getBoundingClientRect(); 

    div.style.position = "absolute"; 
    div.style.left = (rect.left + box.x) + "px"; //Don't forget the pixels!!! 
    div.style.top = (rect.top + box.y) + "px"; 
    div.style.width = box.w + "px"; 
    div.style.height = box.h + "px"; 

    /* For demonstration purposes we display a border */ 
    div.style.border = "1px dashed black" 

    div.onclick = function() {/* Your event handler */} 

    document.body.appendChild(div); 

}); 

Вот live demonstration. По крайней мере, в моем браузере, регионы остаются неизменными, даже если я увеличиваю и уменьшаю страницу.

+0

Я масштабируюсь с использованием метода scale(), а не браузера масштабирования. GetBoundingClientRect, похоже, не помогает поддерживать выравнивание div с моими прямоугольниками в моем тестировании. – bradyGilley

+0

Используете ли вы метод context.scale() 'или css' transform: scale() '? Вы говорите, что при масштабировании прямоугольников излучают из центра. Используете ли вы 'context.translate()' для некоторой конкретной точки перед масштабированием? – mauroc8

+1

Я использовал transform: scale(). Хотя ваш ответ не решал мою проблему напрямую, это вдохновляло меня размещать невидимые divs под прямоугольником, который правильно масштабируется с прямоугольниками и может справиться с обнаружением обнаружения зависания. – bradyGilley

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