Pindahkan Kanvas HTML5 dengan gambar latar belakang

Saya ingin memvisualisasikan diagram besar yang digambar di kanvas HTML5. Seperti digambarkan di bawah ini, bayangkan saja peta dunia, tidak mungkin memvisualisasikan semuanya sekaligus dengan detail yang “layak”. Oleh karena itu, di kanvas saya, saya ingin menggesernya menggunakan mouse untuk melihat negara lain yang tidak terlihat.

Adakah yang tahu cara menerapkan panning semacam ini di kanvas HTML5? Fitur lainnya adalah zoom in dan out.

diagram kanvasSaya telah melihat beberapa contoh tetapi saya tidak dapat membuatnya berfungsi atau menjawab pertanyaan saya .

Terima kasih sebelumnya!


person Emanuel    schedule 05.08.2013    source sumber
comment
Jadi pada dasarnya Anda ingin memindahkan (menggeser) gambar di dalam objek kanvas HTML5, yang dikendalikan oleh mouse? Juga memperbesar/memperkecilnya.   -  person Eric    schedule 05.08.2013
comment
Tepat! Saya ingin menyeret gambar itu.   -  person Emanuel    schedule 05.08.2013


Jawaban (2)


Untuk mencapai fungsionalitas panning dengan lubang intip, ini hanya masalah dua operasi penarikan, satu penuh dan satu terpotong.

Untuk mendapatkan hasil ini Anda dapat melakukan hal berikut (lihat kode lengkap di sini):

Variabel pengaturan:

var ctx = canvas.getContext('2d'),

    ix = 0, iy = 0,           /// image position
    offsetX = 0, offsetY = 0, /// current offsets
    deltaX, deltaY,           /// deltas from mouse down
    mouseDown = false,        /// in mouse drag
    img = null,               /// background
    rect,                     /// rect position
    rectW = 200, rectH = 150; /// size of highlight area

Atur fungsi utama yang Anda gunakan untuk mengatur ukuran berdasarkan ukuran jendela (termasuk saat mengubah ukuran):

/// calc canvas w/h in relation to window as well as
/// setting rectangle in center with the pre-defined
/// width and height
function setSize() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    rect = [canvas.width * 0.5 - rectW * 0.5,
            canvas.height * 0.5 - rectH * 0.5,
            rectW, rectH]
    update();
}

/// window resize so recalc canvas and rect
window.onresize = setSize;

Fungsi utama dalam hal ini adalah fungsi draw. Di sini kita menggambar gambar pada posisi yang dihitung dengan gerakan mouse (lihat bagian selanjutnya).

  • Langkah pertama untuk mendapatkan tampilan yang pudar adalah dengan mengatur alpha ke sekitar 0,2 (Anda juga bisa menggambar persegi panjang transparan di atasnya tetapi ini lebih efisien).
  • Kemudian gambarlah gambar lengkapnya.
  • Setel ulang alfa
  • Gambarkan lubang intip menggunakan kliping dengan offset yang dikoreksi untuk sumbernya.

-

/// main draw
function update() {
    if (img === null) return;

    /// limit x/y as drawImage cannot draw with negative
    /// offsets for clipping
    if (ix + offsetX > rect[0]) ix = rect[0] - offsetX;
    if (iy + offsetY > rect[1]) iy = rect[1] - offsetY;

    /// clear background to clear off garbage
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    /// make everything transparent
    ctx.globalAlpha = 0.2;

    /// draw complete background
    ctx.drawImage(img, ix + offsetX, iy + offsetY);

    /// reset alpha as we need opacity for next draw
    ctx.globalAlpha = 1;

    /// draw a clipped version of the background and
    /// adjust for offset and image position
    ctx.drawImage(img, -ix - offsetX + rect[0],  /// sx
                       -iy - offsetY + rect[1],  /// sy
                       rect[2], rect[3],         /// sw/h

                       /// destination
                       rect[0], rect[1], rect[2], rect[3]);

    /// make a nice sharp border by offsetting it half pixel
    ctx.strokeRect(rect[0] + 0.5, rect[1] + 0.5, rect[2], rect[3]);
}

Sekarang tinggal mengendalikan mouse ke bawah, gerakkan ke atas dan hitung offsetnya -

Di bawah mouse kita menyimpan posisi mouse saat ini yang akan kita gunakan untuk menghitung delta saat pergerakan mouse:

canvas.onmousedown = function(e) {

    /// don't do anything until we have an image
    if (img === null) return;

    /// correct mouse pos
    var coords = getPos(e),
        x = coords[0],
        y = coords[1];

    /// store current position to calc deltas
    deltaX = x;
    deltaY = y;

    /// here we go..
    mouseDown = true;
}

Di sini kita menggunakan delta untuk menghindari lompatan gambar dengan mengatur sudut ke posisi mouse. Delta ditransfer sebagai offset ke fungsi update:

canvas.onmousemove = function(e) {

    /// in a drag?
    if (mouseDown === true) {

        var coords = getPos(e),
            x = coords[0],
            y = coords[1];

        /// offset = current - original position
        offsetX = x - deltaX;
        offsetY = y - deltaY; 

        /// redraw what we have so far
        update();
    }
}

Dan terakhir, dengan mengarahkan mouse ke atas, kita menjadikan offset sebagai bagian permanen dari posisi gambar:

document.onmouseup = function(e) {

    /// was in a drag?
    if (mouseDown === true) {
        /// not any more!!!
        mouseDown = false;

        /// make image pos. permanent
        ix += offsetX;
        iy += offsetY;

        /// so we need to reset offsets as well
        offsetX = offsetY = 0;
    }
}

Untuk memperbesar kanvas, saya yakin ini sudah terjawab di postingan ini - Anda seharusnya dapat menggabungkannya dengan jawaban yang diberikan di sini:
Perbesar Kanvas ke Kursor Mouse

person Community    schedule 05.08.2013
comment
Anda pasti memposting jawabannya, terima kasih banyak! Saya memiliki padding yang berfungsi sekarang, tetapi mengenai zoom saya sudah melihat postingan itu, tetapi dalam hal ini setiap kali kita ingin memperbesar kita harus menggambar ulang seluruh gambar latar belakang (terjemahan, skala), bukan? Saya mencoba bermain-main dengan fungsi drawImage agar dapat memperbesar dengan menangkap lebih banyak gambar latar belakang, dengan cara ini menghindari menggambar ulang latar belakang. Apakah ini mungkin? - person Emanuel; 06.08.2013
comment
@Emanuel maksudmu suka menggunakan kotak sebagai kaca pembesar? Jika demikian, Anda dapat melakukan sesuatu seperti ini: jsfiddle.net/AbdiasSoftware/Us9nH/3 - person ; 06.08.2013
comment
sekali lagi terima kasih banyak atas semua bantuan Anda! Memang seperti yang anda posting, tapi saya ingin bisa memperbesar tapi juga memperkecil sesuai dengan scroll mouse. Ngomong-ngomong, pernahkah kamu memperhatikan saat pertama kali kamu memutar mouse, ada semacam efek pembesaran saat kamu bergerak ke bagian bawah peta? Terima kasih! - person Emanuel; 07.08.2013
comment
Sebenarnya menurut saya efek ini karena sudah mencapai bagian akhir gambar. Bingkai sorotan mencapai akhir gambar dan menyesuaikan lebar bingkai yang diambil ke persegi panjang sehingga memberikan efek memanjang. - person Emanuel; 07.08.2013
comment
@KenFyrstenberg : Pak, bagaimana saya bisa membuat fungsi bergerak HANYA tersedia di dalam kanvas? Dan bagaimana saya bisa menyembunyikan luapan gambar sehubungan dengan kanvas? - person YouSer; 06.06.2014
comment
bukankah drawImg setiap kali tidak efisien - bukankah menggunakan terjemahan lebih baik? - person Jona; 13.02.2021

Untuk melakukan sesuatu seperti yang Anda minta, ini hanya masalah memiliki 2 kanvas, masing-masing dengan indeks-z berbeda. satu kanvas lebih kecil dari yang lain dan posisinya diatur ke x dan y mouse.

Kemudian Anda tinggal menampilkan di kanvas kecil gambar yang benar berdasarkan posisi x dan y di kanvas kecil dalam kaitannya dengan kanvas yang lebih besar.

Namun pertanyaan Anda menanyakan solusi spesifik, yang kecuali seseorang telah melakukannya dan mereka bersedia membuang kodenya, Anda akan kesulitan mendapatkan jawaban lengkap. Saya harap ini berjalan baik.

person Malcor    schedule 05.08.2013