Saya ingin membuat aplikasi melukis kecil menggunakan kanvas. Jadi saya perlu menemukan posisi mouse di atas kanvas.
javascript
Ben Shelock
sumber
sumber
Jawaban:
Untuk orang yang menggunakan JQuery:
Terkadang, ketika Anda memiliki elemen bersarang, salah satunya dengan peristiwa yang menyertainya, bisa membingungkan untuk memahami apa yang dilihat browser Anda sebagai induknya. Di sini, Anda dapat menentukan induk yang mana.
Anda mengambil posisi mouse, dan kemudian kurangi dari posisi offset elemen induk.
Jika Anda mencoba untuk mendapatkan posisi mouse pada halaman di dalam panel gulir:
Atau posisi relatif ke halaman:
Perhatikan pengoptimalan kinerja berikut:
Dengan cara ini, JQuery tidak harus mencari
#element
setiap baris.Memperbarui
Ada versi yang lebih baru, khusus JavaScript di bawah ini oleh @anytimecoder di bawah ini untuk peramban yang mendukung getBoundingClientRect () .
sumber
var y = (evt.pageY - $('#element').offset().left) + $(window).scrollTop();
kevar y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();
Karena saya tidak menemukan jawaban bebas jQuery yang dapat saya salin / tempel, inilah solusi yang saya gunakan:
JSFiddle dari contoh lengkap
sumber
e.currentTarget
, bukan e.target. Jika tidak, elemen anak-anak akan mempengaruhinyaYang berikut ini menghitung relasi posisi mouse ke elemen kanvas:
Dalam contoh ini,
this
mengacu padaexample
elemen, dane
adalahonmousemove
acara.sumber
var example = document.getElementById('example'); example.onmousemove = function(e) { var X = e.pageX - this.offsetLeft; var Y = e.pageY - this.offsetTop; }
this
kee.currentTarget
, yang akan membuat Anda posisi relatif terhadap elemen yang Anda tambahkan pendengar acara.Tidak ada jawaban di javascript murni yang mengembalikan koordinat relatif ketika elemen referensi bersarang di dalam orang lain yang dapat dengan posisi absolut. Berikut ini solusi untuk skenario ini:
sumber
html
elemen akun diimbangiwhile(reference !== undefined)
denganwhile(reference)
. Setidaknya di Chrome, offsetParent tidak berakhirundefined
, tetapinull
. Hanya memeriksa apakahreference
kebenaran akan memastikan itu berfungsi dengan baikundefined
dannull
.offsetParent
properti, yang ternyata sangat berguna dalam situasi lain!scrollLeft
danscrollTop
mengkompensasi keturunan yang digulir.Tulisan yang bagus tentang kesulitan masalah ini dapat ditemukan di sini: http://www.quirksmode.org/js/events_properties.html#position
Dengan menggunakan teknik yang dijelaskan di sana Anda dapat menemukan posisi mouse dalam dokumen. Kemudian Anda hanya memeriksa untuk melihat apakah di dalam kotak berlari dari elemen Anda, yang dapat Anda temukan dengan panggilan
element.getBoundingClientRect()
yang akan mengembalikan objek dengan properti berikut:{ bottom, height, left, right, top, width }
. Dari sana sepele untuk mencari tahu apakah peristiwa itu terjadi di dalam elemen Anda atau tidak.sumber
Saya mencoba semua solusi ini dan karena pengaturan khusus saya dengan wadah yang diubah matriks (perpustakaan panzoom) tidak ada yang berhasil. Ini mengembalikan nilai yang benar, bahkan jika diperbesar dan digeser:
Tetapi hanya jika tidak ada elemen anak di jalan. Ini dapat dielakkan dengan membuatnya 'tidak terlihat' pada acara tersebut, menggunakan CSS:
sumber
Saya menemukan pertanyaan ini, tetapi untuk membuatnya berfungsi untuk kasus saya (menggunakan dragover pada elemen DOM (tidak menjadi kanvas dalam kasus saya)), saya menemukan bahwa Anda hanya perlu menggunakan
offsetX
danoffsetY
pada acara dragover-mouse .sumber
Saya memberi +1 jawaban Mark van Wyk karena membuat saya berada di arah yang benar, tetapi tidak cukup menyelesaikannya untuk saya. Saya masih memiliki offset pada lukisan dalam elemen-elemen yang terdapat dalam elemen lain.
Bagaimana memecahkannya untuk saya:
Dengan kata lain - saya hanya menumpuk semua offset dari semua elemen yang bersarang
sumber
Tidak ada jawaban di atas yang IMO memuaskan, jadi inilah yang saya gunakan:
Dan jika Anda perlu mengetahui posisi gulir Y saat ini dari halaman:
sumber
Bagi Anda yang mengembangkan situs web biasa atau PWA (Progressive Web Apps) untuk perangkat seluler dan / atau laptop / monitor dengan layar sentuh, maka Anda telah mendarat di sini karena Anda mungkin terbiasa dengan acara tetikus dan baru dalam pengalaman Touch yang terkadang menyakitkan. acara ... yay!
Hanya ada 3 aturan:
mousemove
atautouchmove
acara.mousedown
atautouchstart
acara.Tak perlu dikatakan, hal-hal lebih rumit dengan
touch
peristiwa karena bisa ada lebih dari satu dan mereka lebih fleksibel (rumit) daripada peristiwa mouse. Saya hanya akan membahas satu sentuhan di sini. Ya, saya malas, tapi itu jenis sentuhan yang paling umum, jadi itulah.Lebih suka menggunakan Vue.js ? Saya lakukan! Maka HTML Anda akan terlihat seperti ini:
sumber
Anda bisa mendapatkannya dengan
sumber
Diambil dari tutorial ini , dengan koreksi dilakukan berkat komentar teratas:
Gunakan pada kanvas sebagai berikut:
sumber
Saya sadar saya sedikit terlambat, tetapi ini bekerja dengan javascript PURE, dan bahkan memberi Anda koordinat pointer dalam elemen jika elemen lebih besar dari viewport dan pengguna telah menggulir.
Hal pertama yang kami lakukan adalah mendapatkan lokasi elemen HTML (area konten) relatif terhadap viewport saat ini. Jika halaman tersebut memiliki scrollbar dan digulir, maka nomor tersebut dikembalikan oleh
getBoundingClientRect().left
untuk tag html akan negatif. Kami kemudian menggunakan nomor ini untuk menghitung jarak antara elemen dan kiri area konten. Denganelement_offset_x = element.getBoundingClientRect().left......;
Mengetahui jarak elemen dari area konten.
event.clientX
memberi kita jarak pointer dari viewport. Penting untuk dipahami bahwa viewport dan area konten adalah dua entitas yang berbeda, viewport dapat bergerak jika halaman tersebut digulir. Oleh karena itu, clientX akan mengembalikan nomor SAMA meskipun halaman tersebut digulir.Untuk mengimbangi ini, kita perlu menambahkan posisi x dari pointer (relatif ke viewport), ke posisi x viewport (relatif terhadap area konten). Posisi X viewport ditemukan dengan
window.pageXOffset.
sumber
Berdasarkan solusi @ Spider, versi non JQuery saya adalah ini:
Ini berfungsi baik dengan menggulir dan memperbesar (dalam hal ini kadang-kadang mengembalikan mengapung).
sumber
Koordinat mouse di dalam kanvas dapat diperoleh berkat event.offsetX dan event.offsetY. Berikut cuplikan kecil untuk membuktikan pendapat saya:
sumber
HTMLElement.offsetLeft
Properti
HTMLElement.offsetLeft
baca-saja mengembalikan jumlah piksel yang sudut kiri atas elemen saat ini diimbangi ke kiri dalamHTMLElement.offsetParent
node.Untuk unsur blok-tingkat,
offsetTop
,offsetLeft
,offsetWidth
, danoffsetHeight
menggambarkan kotak perbatasan elemen relatif terhadapoffsetParent
.Namun, untuk elemen level-inline (seperti
span
) yang dapat membungkus dari satu baris ke baris berikutnya,offsetTop
danoffsetLeft
menggambarkan posisi kotak batas pertama (gunakanElement.getClientRects()
untuk mendapatkan lebar dan tinggi), sementaraoffsetWidth
danoffsetHeight
menggambarkan dimensi kotak batas pembatas (gunakanElement.getBoundingClientRect()
untuk mendapatkan posisinya). Oleh karena itu, sebuah kotak dengan kiri, atas, lebar dan tinggioffsetLeft
,offsetTop
,offsetWidth
danoffsetHeight
tidak akan menjadi kotak berlari untuk rentang dengan teks dibungkus.HTMLElement.offsetTop
Properti
HTMLElement.offsetTop
read-only mengembalikan jarak elemen saat ini relatif ke atasoffsetParent
node.MouseEvent.pageX
Properti
pageX
baca-saja mengembalikan koordinat X (horizontal) dalam piksel acara relatif ke seluruh dokumen. Properti ini memperhitungkan setiap pengguliran horizontal halaman.MouseEvent.pageY
Properti
MouseEvent.pageY
baca-saja mengembalikan koordinat Y (vertikal) dalam piksel acara relatif ke seluruh dokumen. Properti ini memperhitungkan setiap pengguliran vertikal halaman.Untuk penjelasan lebih lanjut, silakan lihat Jaringan Pengembang 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
sumber
page
danoffset
akan sangat membantu saya. Terima kasih telah mempertimbangkan permintaan ini!Saya menerapkan solusi lain yang saya pikir sangat sederhana, jadi saya pikir saya akan berbagi dengan kalian.
Jadi, masalah bagi saya adalah bahwa div yang diseret akan melompat ke 0,0 untuk kursor mouse. Jadi saya perlu menangkap posisi mouse pada div untuk menyesuaikan posisi divs baru.
Saya membaca div PageX dan PageY dan mengatur bagian atas dan kiri sesuai dengan itu dan kemudian untuk mendapatkan nilai-nilai untuk menyesuaikan koordinat untuk menjaga kursor pada posisi awal di div saya menggunakan pendengar onDragStart dan menyimpan e.nativeEvent .layerX dan e.nativeEvent.layerY yang hanya di trigger awal memberi Anda posisi mouse di dalam div yang dapat ditarik.
Kode contoh:
Saya harap ini akan membantu seseorang yang mengalami masalah yang sama seperti yang saya alami :)
sumber
ini berfungsi ok!
sumber
Anda harus mengetahui struktur halaman Anda, karena jika kanvas Anda adalah anak dari div yang pada gilirannya adalah anak dari div lain ... maka ceritanya menjadi lebih rumit. Inilah kode saya untuk kanvas yang ada di dalam 2 level div s:
});
sumber
Jawaban orisinal mengatakan untuk meletakkannya di iframe. Solusi yang lebih baik adalah dengan menggunakan peristiwa offsetX dan offsetY pada kanvas yang memiliki padding set ke 0px.
sumber
Inilah yang saya dapat.
sumber
Anda dapat menggunakan
getBoudingClientRect()
orangrelative
tua.sumber