Saya ingin dapat memperbesar titik di bawah mouse dalam kanvas HTML 5, seperti memperbesar di Google Maps . Bagaimana saya bisa mencapainya?
javascript
html
canvas
csiz
sumber
sumber
Jawaban:
Solusi yang lebih baik adalah dengan hanya memindahkan posisi viewport berdasarkan perubahan zoom. Titik zoom hanyalah titik di zoom lama dan zoom baru yang Anda ingin tetap sama. Yang mengatakan viewport pra-perbesar dan viewport pasca-diperbesar memiliki zoompoint relatif sama dengan viewport. Mengingat bahwa kami menskalakan relatif terhadap asal. Anda dapat menyesuaikan posisi viewport sesuai:
Jadi, Anda bisa menggeser ke bawah dan ke kanan saat memperbesar, dengan faktor seberapa besar Anda memperbesar, relatif terhadap titik yang Anda perbesar.
sumber
Akhirnya dipecahkan:
Kuncinya, seperti yang ditunjukkan oleh @Tatarize , adalah untuk menghitung posisi sumbu sedemikian rupa sehingga titik zoom (penunjuk mouse) tetap berada di tempat yang sama setelah zoom.
Awalnya mouse berada pada jarak
mouse/scale
dari sudut, kami ingin titik di bawah mouse tetap berada di tempat yang sama setelah zoom, tetapi ini beradamouse/new_scale
jauh dari sudut. Karena itu kita perlu menggeserorigin
(koordinat sudut) untuk memperhitungkan ini.Kode yang tersisa kemudian perlu menerapkan penskalaan dan menerjemahkan ke konteks draw sehingga asalnya bertepatan dengan sudut kanvas.
sumber
Ini sebenarnya masalah yang sangat sulit (secara matematis), dan saya sedang mengerjakan hal yang hampir sama. Saya mengajukan pertanyaan serupa pada Stackoverflow tetapi tidak mendapat tanggapan, tetapi diposting di DocType (StackOverflow untuk HTML / CSS) dan mendapat tanggapan. Lihatlah http://doctype.com/javascript-image-zoom-css3-transforms-calculate-origin-example
Saya sedang membangun plugin jQuery yang melakukan ini (Google Style zoom menggunakan CSS3 Transforms). Saya memiliki bit kursor zoom ke mouse berfungsi dengan baik, masih mencoba mencari cara untuk memungkinkan pengguna untuk menyeret kanvas sekitar seperti yang dapat Anda lakukan di Google Maps. Ketika saya membuatnya berfungsi saya akan memposting kode di sini, tetapi periksa tautan di atas untuk bagian mouse-zoom-to-point.
Saya tidak menyadari ada skala dan menerjemahkan metode pada konteks Canvas, Anda dapat mencapai hal yang sama menggunakan misalnya CSS3. menggunakan jQuery:
Pastikan Anda mengatur CSS3 transform-origin menjadi 0, 0 (-moz-transform-origin: 0 0). Menggunakan transformasi CSS3 memungkinkan Anda memperbesar apa pun, pastikan wadah DIV diatur ke melimpah: disembunyikan untuk menghentikan tepian yang diperbesar keluar dari samping.
Apakah Anda menggunakan transformasi CSS3, atau skala sendiri dan metode menerjemahkannya terserah Anda, tetapi periksa tautan di atas untuk perhitungannya.
Pembaruan: Meh! Saya hanya akan memposting kode di sini daripada membuat Anda mengikuti tautan:
Anda tentu saja perlu menyesuaikannya untuk menggunakan skala kanvas dan menerjemahkan metode.
Pembaruan 2: Saya perhatikan saya menggunakan transform-origin bersama dengan translate. Saya telah berhasil mengimplementasikan versi yang hanya menggunakan skala dan menerjemahkan sendiri, periksa di sini http://www.dominicpettifer.co.uk/Files/Mosaic/MosaicTest.html Tunggu gambar untuk diunduh kemudian gunakan Anda roda mouse untuk memperbesar, juga mendukung panning dengan menyeret gambar di sekitar. Itu menggunakan CSS3 Transforms tetapi Anda harus dapat menggunakan perhitungan yang sama untuk Kanvas Anda.
sumber
Saya mengalami masalah ini menggunakan c ++, yang mungkin seharusnya saya tidak punya saya hanya menggunakan matriks OpenGL untuk memulai dengan ... anyways, jika Anda menggunakan kontrol yang asalnya adalah sudut kiri atas, dan Anda ingin pan / zoom seperti google maps, inilah tata letaknya (menggunakan allegro sebagai pengendali acara saya):
sumber
Saya suka jawaban Tatarize , tetapi saya akan memberikan alternatif. Ini adalah masalah aljabar linier sepele, dan metode yang saya sajikan bekerja dengan baik dengan pan, zoom, condong, dll. Artinya, ini berfungsi dengan baik jika gambar Anda sudah diubah.
Ketika sebuah matriks diskalakan, skala berada pada titik (0, 0). Jadi, jika Anda memiliki gambar dan menskalakannya dengan faktor 2, titik kanan bawah akan berlipat ganda dalam arah x dan y (menggunakan konvensi bahwa [0, 0] adalah kiri atas gambar).
Jika Anda ingin memperbesar gambar tentang pusat, maka solusinya adalah sebagai berikut: (1) menerjemahkan gambar sedemikian rupa sehingga pusatnya berada di (0, 0); (2) skala gambar dengan faktor x dan y; (3) menerjemahkan kembali gambar. yaitu
Secara lebih abstrak, strategi yang sama berfungsi untuk setiap titik. Jika, misalnya, Anda ingin skala gambar pada titik P:
Dan terakhir, jika gambar sudah ditransformasikan dengan cara tertentu (misalnya, jika diputar, miring, diterjemahkan, atau diskalakan), maka transformasi saat ini perlu dipertahankan. Secara khusus, transformasi yang didefinisikan di atas harus dikalikan setelahnya (atau dikalikan kanan) oleh transformasi saat ini.
Itu dia. Di sini ada bungkusan yang menunjukkan tindakan ini. Gulir dengan roda mouse pada titik-titik dan Anda akan melihat bahwa mereka secara konsisten tetap diam. (Diuji hanya di Chrome.) Http://plnkr.co/edit/3aqsWHPLlSXJ9JCcJzgH?p=preview
sumber
Inilah solusi saya untuk gambar berorientasi pusat:
sumber
Berikut cara alternatif untuk melakukannya yang menggunakan setTransform () alih-alih skala () dan terjemahkan (). Semuanya disimpan di objek yang sama. Kanvas diasumsikan sebesar 0,0 pada halaman, jika tidak Anda harus mengurangi posisinya dari coords halaman.
Kode pendamping untuk menangani panning:
Untuk mendapatkan jawabannya sendiri, pertimbangkan bahwa koordinat halaman yang sama harus cocok dengan koordinat kanvas yang sama sebelum dan sesudah zoom. Maka Anda dapat melakukan beberapa aljabar mulai dari persamaan ini:
(pageCoords - terjemahan) / scale = canvasCoords
sumber
Saya ingin memberikan beberapa informasi kepada mereka di sini, yang secara terpisah menggambar dan memindahkannya.
Ini mungkin berguna ketika Anda ingin menyimpan zoom dan posisi viewport.
Di sini adalah laci:
Skala pemberitahuan HARUS menjadi yang pertama .
Dan di sini adalah zoomer:
dan, tentu saja, kita akan membutuhkan penyeret:
sumber
sumber
Berikut ini adalah implementasi kode dari jawaban @ tatarize, menggunakan PIXI.js. Saya memiliki viewport melihat bagian dari gambar yang sangat besar (misalnya gaya google maps).
$canvasContainer
adalah wadah html saya.imageContainer
adalah wadah PIXI saya yang memiliki gambar di dalamnya.mousePosOnImage
adalah posisi mouse relatif terhadap seluruh gambar (bukan hanya port tampilan).Inilah cara saya mendapatkan posisi mouse:
sumber
Anda harus mendapatkan titik di ruang dunia (berlawanan dengan ruang layar) sebelum dan sesudah zoom, dan kemudian terjemahkan oleh delta.
Posisi mouse ada di ruang layar, jadi Anda harus mengubahnya ke ruang dunia. Transformasi sederhana harus serupa dengan ini:
sumber
Anda dapat menggunakan fungsi scrollto (x, y) untuk menangani posisi scrollbar langsung ke titik yang harus ditunjukkan setelah zooming. Untuk menemukan posisi mouse gunakan event.clientX dan event.clientY. ini akan membantu Anda
sumber
Satu hal penting ... jika Anda memiliki sesuatu seperti:
Anda perlu membuat hal yang sama dalam kanvas:
sumber