Canvas memiliki API yang sangat kuat yang disebut drawImage() (w3c):
Fungsi utamanya adalah untuk menggambar, video, bahkan kanvas lainnya.
pertanyaan:Dia datang ke sana dengan kagum, tetapi meleset dari sasaran. Ketika dia menundukkan kepalanya, dia melihat sebuah lubang besar di tanah.
Soalnya begini, setelah saya membaca pendahuluan w3c dan demo yang sangat meyakinkan dan mengajar, saya memutuskan untuk mencobanya berdasarkan ide berlatih untuk mendapatkan ilmu yang sebenarnya mencobanya~
Saya menetapkan tugas-tugas dasar berikut sesuai dengan proyek jalur perakitan:
1. tag kanvas+id
<kanvas id=kanvas1></kanvas>
2. Dapatkan kanvas + atur lebar dan tinggi
var cav1 = dokumen.getElementById('kanvas1'), wWidth = 800, wHeight = 600; cav1.width = wWidth;3. getContext('2d') menyiapkan kanvas
var ctx1 = cav1.getContext('2d');4. Buat objek Image() baru dan beri atribut gambar yang saya suka... (jangan terlalu banyak berpikir)
var bgImg = Gambar baru();bgImg.src = 'gambar/latar belakang.jpg';
5. Akhirnya tiba waktunya menggambar. Saya dengan bersemangat menulis kode ini:
ctx1.drawImage(bgImg,0,0,wWidth,wHeight);
Bingung, saya menekan F5 di browser.
Lalu terjadilah keheningan yang mematikan...
Saya pikir kodenya salah, jadi saya kembali dan memeriksanya dengan cermat, dan ternyata benar.
Salin nama atribut kunci dan metode w3c dan periksa lagi.
Kalau gambarnya dicetak, ada juga gambar ini (seseorang)!
Nanti kalau saya amati kasus W3C, perbedaannya dengan kode saya adalah gambarnya dalam HTML.
Lalu saya belajar memasukkan gambar ke dalam html,
<img src=./images/background.jpg id=imgs style=display:none></img>
Dan gunakan getElementById untuk mendapatkan elemen ini,
var bgImg = dokumen.getElementById('imgs')Menjalankan gambar kembali berhasil.
Dia sebenarnya bisa!
Saya pikir sedihnya, apakah harus secara fisik? Bukankah itu hanya ditempatkan di depan tag kanvas? js memuat juga memiliki entitas, dan saya masih menggunakan yang baru, betapa berbedanya dengan orang sungguhan!
Betul, bukannya ditaruh di depan saja? Ini melibatkan masalah urutan!
Memang benar gambar yang dimuat di js ditempatkan di depan gambar, tetapi akan memakan waktu lama untuk memuat gambar tersebut. Waktu perlu diberikan untuk buffering gambar. Tunggu hingga gambar berhasil dimuat sebelum Anda dapat menggambarnya. Metode drawImage tidak akan dipanggil ketika gambar digunakan sebelum dimuat. Menggambar akan gagal. Jadi begitu!
Apakah sebagian orang berpendapat bahwa gambar di tag img tidak memerlukan waktu lama untuk dimuat? Saat ini drawImage tidak dibatasi? ! Tapi jangan abaikan window.onload di awal js. Sekalipun gambar dimuat dengan lambat, meskipun urutan tag gambar setelah tag kanvas, tetapi saya memiliki window.onload yang menutupinya, gambar saya tidak bisa. dimuat, dan drawImage Anda tidak akan ada peluang, bukan?
Perkiraan urutannya adalah ini:
<img src=>window.onload = fungsi(){ drawImage}Jika gambar tidak dimasukkan ke dalam struktur html, batasan ini akan dilewati karena kecerobohan saya:
Sebagai permintaan sumber daya, ketika gambar dimuat di js, secara alami akan ada waktu pemuatan gambar.
Namun karena tidak ada batasan, dalam banyak kasus drawImage dipanggil ketika gambar belum dimuat, dan metode ini tidak akan berfungsi.
menyelesaikan:Jadi apakah ada cara yang baik untuk mengatasi masalah kegagalan menggambar drawImage karena urutan pemuatan gambar?
Saya telah merangkum tiga metode berikut:
1. tag+jendela.onload <img src=>window.onload = function(){ konteks.drawImage()}Solusi inti dari pendekatan ini adalah onload, yang memuat gambar dan drawImage secara terpisah. Img dimuat terlebih dahulu untuk memastikan bahwa gambar tersebut digunakan setelah pemuatan selesai.
1-2. Masukkan tag nanti? Apakah itu layakSalah satu situasinya adalah saat menggunakan fungsi tangkapan layar, Anda juga dapat menggunakan drawImage, dan tangkapan layar tidak mengambil tangkapan layar dari gambar Anda yang sudah ada, tetapi menggunakan alamat gambar sebagai parameter.
Saya rasa hal semacam ini memerlukan js untuk membuat img dan menetapkan alamatnya. Kemudian buat gambarnya dan ambil tangkapan layar.
var myImg = document.createElement('img');myImg.src = '///';document.body.appendChild(myImg);ctx1.drawImage(myImg,0,0,wWidth,wHeight);Tidak ingin menambahkan tag tambahan? Apakah saya perlu menggunakan js seperti gambar di bawah ini untuk membuat objek gambar baru?
var bgImg = Gambar baru();bgImg.src = 'gambar/latar belakang.jpg';
Seperti disebutkan sebelumnya, gambar semacam ini yang dibuat menggunakan new Image() memerlukan waktu untuk buffering gambar. Tunggu hingga gambar berhasil dimuat sebelum Anda dapat menggambarnya.
Objek gambar sudah siap, tapi bagaimana cara mengetahui kapan gambar sebenarnya sudah dimuat? Nah, ada cara lain:
Saat tugas js sedang dijalankan, menurut Anda apakah saya terlalu dekat dengan waktu eksekusi Anda? Bisakah Anda membawa saya keluar sendirian dan mengantri saya lagi, lalu menjalankannya lagi nanti?
2. Implementasi pengatur waktu asinkron setTimeout(fungsi(){ ctx1.drawImage(bgImg,0,0,wWidth,wHeight);},10)Mengapa ada penundaan dalam penulisan 10 di sini, bukan 1000 atau 0 yang biasa?
Karena dalam pengujian lingkungan wifi spesifik saya dan komputer desktop spesifik, 10 baru bisa keluar setelah gambar dimuat, tidak seperti 0 yang tidak keluar, dan saya tidak ingin menunggu setengah hari seperti 1000.
Namun bayangkan jika gambarnya diubah menjadi lebih besar, apakah 10 ini masih berlaku? Apakah 10 ini masih berlaku jika wifi diubah menjadi 2g?
Oleh karena itu, kelemahan dari pengatur waktu adalah tidak ada jaminan bahwa gambar akan dimuat setelah waktunya habis, dan masih akan terhenti jika jaringan tidak cepat.
3. img.onloadwindow.onload memberi kita gambaran. Tidak bisakah kita memantau langsung penyelesaian pemuatan?
Gunakan acara pemuatan img untuk memantau keberhasilan pemuatan gambar, lalu jalankan efek gambar kanvas.
bgImg.onload = function(){ console.log('Gambar berhasil dimuat'); console.log(ini); ctx1.drawImage(bgImg,0,0,wWidth,wHeight }Sebenarnya ketiga cara ini mempunyai inti yang sama yaitu membiarkan gambar dimuat terlebih dahulu. Artinya, pramuat gambar. Namun untuk gambar yang di-cache, pramuat gambar juga perlu menyelesaikan masalah pemantauan gambar yang di-cache ketika halaman tidak di-refresh.
Menemukan masalah lain. . . . Pertama, inilah tampilan background lukisan setelah selesai.
Kemudian gambar latar belakangnya akhirnya keluar, dan saya melanjutkan dengan gembira.
Jadi saya langsung menggambar garis merah agar tidak terlihat, saya juga menambah lebarnya menjadi 20:
bgImg.onload = function(){ ctx1.drawImage(bgImg,0,0,wWidth,wHeight); /* Gambarkan garis merah sebagai berikut: */ ctx1.beginPath(); ctx1.lineTo (10,wTinggi-100); ctx1.lineWidth = 20; ctx1.strokeStyle = 'merah'; ctx1.stroke();Namun saat saya tekan F5 tetap tidak ada perubahan dan garis merahnya masih belum terlihat.
Setelah lama mencari, saya tidak melihatnya sampai saya mematikan gambar latar belakang:
Ah, ternyata dia ditutupi oleh gambar backgroundnya!
Tapi kenapa?
Saya pikir ada dua kemungkinan
1. Masalah hierarki
2. Urutan masalah
Mengenai 1, rasanya seperti indeks-z CSS, yang gambar latar belakangnya menutupi garis merah. Mungkinkah level gambar latar lebih tinggi dari garis merah?
Saya tidak punya cara untuk menguji hipotesis ini, jadi saya menyerah pada kemungkinan pengungkapan kedua.
Tapi kenapa gambar backgroundnya ada di atas? Apakah karena gambar backgroundnya digambar nanti?
Hal ini paling mudah diamati melalui pencetakan console.log() untuk mengamati urutan eksekusi.
Ternyata pelakunya adalah panggilan balik onload. Seperti pengatur waktu, ini adalah tugas yang tidak sinkron. Tentu saja, ini berada di peringkat belakang tugas sinkronisasi (gambar garis di bawah)
Jadi onload tampaknya menjadi solusi yang baik, namun kekurangannya juga terungkap di sini.
Bagus sekali, sepertinya rencana pembelajaran yang menjanjikan harus dijadwal secepatnya! Ha ha ha
Di atas adalah keseluruhan isi artikel ini, saya harap dapat bermanfaat untuk pembelajaran semua orang. Saya juga berharap semua orang mendukung VeVb Wulin Network.