Я хочу сделать небольшое приложение для рисования, используя холст. Поэтому мне нужно найти положение мыши на холсте.
javascript
Бен Шелок
источник
источник
Ответы:
Для людей, использующих JQuery:
Иногда, когда у вас есть вложенные элементы, один из которых с прикрепленным к нему событием, может быть непонятно, что ваш браузер видит как родительский. Здесь вы можете указать, какой родитель.
Вы берете позицию мыши, а затем вычитаете ее из позиции смещения родительского элемента.
Если вы пытаетесь определить положение мыши на странице внутри панели прокрутки:
Или положение относительно страницы:
Обратите внимание на следующую оптимизацию производительности:
Таким образом, JQuery не должен искать
#element
каждую строку.Обновить
Ниже приведена более новая версия только для JavaScript от @anytimecoder ниже для браузеров, поддерживающих getBoundingClientRect () .
источник
var y = (evt.pageY - $('#element').offset().left) + $(window).scrollTop();
доvar y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();
Поскольку я не нашел ответ без jQuery, который мог бы скопировать / вставить, вот решение, которое я использовал:
JSFiddle полного примера
источник
e.currentTarget
, а не e.target. Иначе на это будут влиять дочерние элементыДалее вычисляется отношение позиции мыши к элементу canvas:
В этом примере
this
ссылается наexample
элемент иe
являетсяonmousemove
событием.источник
var example = document.getElementById('example'); example.onmousemove = function(e) { var X = e.pageX - this.offsetLeft; var Y = e.pageY - this.offsetTop; }
this
наe.currentTarget
, чтобы получить положение относительно элемента, к которому вы добавили прослушиватель событий.В чистом javascript нет ответа, который возвращает относительные координаты, когда опорный элемент вложен в другие элементы, которые могут иметь абсолютное позиционирование. Вот решение этого сценария:
источник
html
смещение элементаwhile(reference !== undefined)
наwhile(reference)
. По крайней мере, в Chrome, offsetParent не заканчиваетсяundefined
, ноnull
. Просто проверка,reference
является ли правдивым, гарантирует, что это работает с обоимиundefined
иnull
.offsetParent
свойство, которое оказывается очень полезным и в других ситуациях!scrollLeft
иscrollTop
компенсировать прокрутить потомков.Хорошее описание сложности этой проблемы можно найти здесь: http://www.quirksmode.org/js/events_properties.html#position
Используя описанную там технику, вы можете найти позицию мыши в документе. Тогда вы просто проверить, если он находится внутри ограничивающей рамки вашего элемента, который вы можете найти по призванию ,
element.getBoundingClientRect()
который будет возвращать объект со следующими свойствами:{ bottom, height, left, right, top, width }
. Отсюда легко понять, произошло ли событие внутри вашего элемента или нет.источник
Я испробовал все эти решения, и из-за моей специальной настройки с контейнером с матричной трансформацией (библиотека panzoom) ни один из них не работал. Это возвращает правильное значение, даже если масштабирование и панорамирование:
Но только если на пути нет дочерних элементов. Это можно обойти, сделав их «невидимыми» для события, используя CSS:
источник
Я наткнулся на этот вопрос, но для того , чтобы заставить его работать на моем случае ( с использованием DragOver на DOM-элемент (не будучи холст в моем случае)), я обнаружил , что у вас есть только использовать
offsetX
иoffsetY
на события DragOver-мыши ,источник
Я +1 'Марк Марк Вик ответил, так как он направил меня в правильном направлении, но не совсем решил для меня. У меня все еще было смещение при рисовании элементов, содержащихся в другом элементе.
Следующие решили это для меня:
Другими словами - я просто сложил все смещения из всех вложенных элементов
источник
Ни один из приведенных выше ответов не является удовлетворительным IMO, так что вот что я использую:
И если вам когда-либо понадобится узнать текущую позицию прокрутки Y страницы:
источник
Для тех из вас, кто разрабатывает обычные веб-сайты или PWA (Progressive Web Apps) для мобильных устройств и / или ноутбуков / мониторов с сенсорными экранами, вы попали сюда, потому что вы могли бы привыкнуть к событиям мыши и плохо знакомы с иногда болезненным опытом Touch события ... ууу!
Всего 3 правила:
mousemove
илиtouchmove
события.mousedown
илиtouchstart
события.Излишне говорить, что с
touch
событиями все сложнее, потому что их может быть несколько, и они более гибкие (сложные), чем события мыши. Я собираюсь охватить только одно прикосновение здесь. Да, я ленивый, но это самый распространенный тип прикосновений, так что есть.Предпочитаете использовать Vue.js ? Я делаю! Тогда ваш HTML будет выглядеть так:
источник
Вы можете получить это по
источник
Взятые из этого урока , с исправлениями, сделанными благодаря верхнему комментарию:
Используйте на холсте следующим образом:
источник
Я понимаю, что немного опоздал, но это работает с PURE javascript и даже дает вам координаты указателя внутри элемента, если элемент больше, чем область просмотра, и пользователь прокрутил.
Первое, что мы делаем, это получаем местоположение элемента HTML (области содержимого) относительно текущего окна просмотра. Если страница имеет полосы прокрутки и прокручивается, то число, возвращаемое
getBoundingClientRect().left
тегом html, будет отрицательным. Затем мы используем это число для вычисления расстояния между элементом и левой частью области содержимого. С участиемelement_offset_x = element.getBoundingClientRect().left......;
Зная расстояние элемента от области содержимого.
event.clientX
дает нам расстояние указателя от области просмотра. Важно понимать, что область просмотра и область содержимого - это две разные сущности, область просмотра может перемещаться при прокрутке страницы. Следовательно, clientX вернет тот же номер, даже если страница прокручивается.Чтобы компенсировать это, нам нужно добавить позицию х указателя (относительно области просмотра), к позиции х области просмотра (относительно области содержимого). Положение X области просмотра найдено с
window.pageXOffset.
источник
Основываясь на решении @ Spider, моя не JQuery-версия такова:
Это работает как с прокруткой, так и с масштабированием (в этом случае иногда он возвращает значения с плавающей точкой).
источник
Координаты мыши внутри холста могут быть получены благодаря event.offsetX и event.offsetY. Вот небольшой фрагмент, чтобы доказать мою точку зрения:
источник
HTMLElement.offsetLeft
Свойство
HTMLElement.offsetLeft
только для чтения возвращает количество пикселей, на которые левый верхний угол текущего элемента смещен влево в пределахHTMLElement.offsetParent
узла.Для элементов уровня блока,
offsetTop
,offsetLeft
,offsetWidth
, иoffsetHeight
описывают границы блока элемента относительноoffsetParent
.Тем не менее, для встроенных элементов уровня (таких как
span
), которые могут переноситься с одной строки на следующую,offsetTop
иoffsetLeft
описывать позиции первого граничного блока (используйте,Element.getClientRects()
чтобы получить его ширину и высоту),offsetWidth
а такжеoffsetHeight
описывать размеры ограничивающего граничного блока (используйте,Element.getBoundingClientRect()
чтобы получить свою позицию). Таким образом, коробка с левой, верхней частью, шириной и высотойoffsetLeft
,offsetTop
,offsetWidth
иoffsetHeight
не будет представлять собой ограничивающий прямоугольником для диапазона с обернутым текстом.HTMLElement.offsetTop
Свойство
HTMLElement.offsetTop
только для чтения возвращает расстояние текущего элемента относительно вершиныoffsetParent
узла.MouseEvent.pageX
Свойство
pageX
только для чтения возвращает координату X (горизонтальную) в пикселях события относительно всего документа. Это свойство учитывает любую горизонтальную прокрутку страницы.MouseEvent.pageY
Свойство
MouseEvent.pageY
только для чтения возвращает координату Y (по вертикали) в пикселях события относительно всего документа. Это свойство учитывает любую вертикальную прокрутку страницы.Для дальнейшего объяснения, пожалуйста, смотрите Сеть разработчиков Mozilla:
https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageX https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageY https: // developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetLeft https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop
источник
page
иoffset
было бы очень полезно для меня. Спасибо за рассмотрение этого запроса!Я реализовал другое решение, которое мне кажется очень простым, поэтому я решил поделиться с вами, ребята.
Таким образом, проблема для меня заключалась в том, что перетаскиваемый div переместился бы к 0,0 для курсора мыши. Поэтому мне нужно было зафиксировать положение мышей в div, чтобы настроить div в новой позиции.
Я читаю divs PageX и PageY и устанавливаю верхнюю и левую часть в соответствии с этим, а затем получаю значения для корректировки координат, чтобы держать курсор в начальной позиции в div. Я использую слушатель onDragStart и сохраняю e.nativeEvent. .layerX и e.nativeEvent.layerY, которые только в начальном триггере дают вам позицию мыши в перетаскиваемом элементе div.
Пример кода:
Надеюсь, это поможет кому-то, кто пережил те же проблемы, что и я :)
источник
это работает хорошо!
источник
Вы должны знать структуру своей страницы, потому что, если ваш холст является потомком div, который, в свою очередь, является потомком другого div ... тогда история становится более сложной. Вот мой код для холста, который находится внутри двух уровней div s:
});
источник
Оригинальный ответ сказал, чтобы поместить его в iframe. Лучшее решение состоит в том, чтобы использовать события offsetX и offsetY на холсте с отступом 0px.
источник
Вот что я получил.
источник
Вы можете использовать
getBoudingClientRect()
вrelative
родителе.источник