Saya baru-baru ini menggunakan html2canvas.js saat menulis proyek, yang dapat mewujudkan fungsi tangkapan layar halaman, tetapi saya menemui banyak kendala, jadi saya akan menulis esai untuk mencatatnya.
Saat menggunakan html2canvas, Anda mungkin mengalami masalah seperti hanya antarmuka visual yang dapat ditangkap, tangkapan layar tidak memiliki warna latar belakang, dan tag svg tidak dapat ditangkap.
1. Impor html2canvas.jsTak perlu dikatakan lagi, ini dapat diperoleh dari github: https://github.com/niklasvh/html2canvas
Anda juga bisa mengimpor tautan secara langsung: <script src=https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.js></script>
Ini juga sangat mudah digunakan. Anda dapat menemukan API spesifik secara online dan cukup gunakan image/png untuk menghasilkan gambar png.
Diantaranya, $(#xxx) adalah div yang ingin Anda intersepsi. Tentu saja, dapat diperoleh melalui jquery.
html2canvas($(#xxx), { dirender: fungsi (kanvas) { var url = canvas.toDataURL(image/png); window.location.href = url; } });
Untuk jenis gambar lain seperti jpg, gambar/jpeg, dll, Anda dapat menanyakan sendiri API-nya.
Faktanya, tangkapan layar sederhana telah selesai di sini. Jika antarmukanya sedikit lebih rumit, berbagai kendala mungkin muncul. Mari kita selesaikan satu per satu.
2. Masalah yang svg tidak dapat dicegatSaat kita mencegat sebuah div, jika ada tag svg di div tersebut, maka dalam keadaan normal tidak dapat dicegat. Misalnya, jika kita mencegat diagram alur, kita akan mendapatkan sesuatu seperti ini:
Terlihat garis-garis pada flow chart tidak terpotong yaitu svg tidak terpotong. Solusinya kali ini adalah mengubah svg menjadi kanvas lalu mengambil screenshot dan langsung mengupload kodenya.
Setiap loop di sini adalah mengulang semua tag svg dan mengonversi semuanya menjadi kanvas
if (typeof html2canvas !== 'undefinisi') { //Berikut ini adalah proses dari svg var nodeToRecover = []; var nodeToRemove = []; var svgElem = cloneDom.find('svg'); ( indeks, simpul) { var parentNode = node.parentNode; var svg = node.outerHTML.trim(); var kanvas = dokumen.createElement('kanvas'); kanvas.lebar = 650; kanvas.tinggi = 798; canvg(kanvas, svg); .posisi; kanvas.gaya.kiri += simpul.gaya.kiri; kanvas.gaya.top += simpul.gaya.top; } nodeToRecover.push({ induk: simpul induk, anak: simpul }); parentNode.removeChild(node); nodeToRemove.push({ induk: parentNode, anak: kanvas });
Canvg.js dan file ketergantungannya rgbcolor.js diperlukan di sini. Mereka dapat diunduh langsung dari Internet atau diimpor langsung.
3. Masalah transparansi latar belakangIni sebenarnya sangat sederhana, karena secara default transparan. Ada parameter background di html2canvas untuk menambahkan warna background, sebagai berikut:
html2canvas(cloneDom, { dirender: function(canvas) { var url =canvas.toDataURL(image/png); }, background:#fafafa});4. Masalahnya hanya bisa menangkap bagian yang terlihat saja
Jika div yang perlu dicegat melebihi antarmuka, Anda mungkin mengalami masalah intersepsi tidak lengkap. Seperti yang ditunjukkan pada gambar di atas, hanya ada separuh konten. Hal ini karena bagian yang tidak terlihat disembunyikan, dan html2canvas tidak dapat mencegatnya DOM tersembunyi.
Jadi solusinya saat ini adalah dengan menggunakan kloning, letakkan salinan bagian yang perlu disadap di bagian bawah halaman, lalu gunakan html2canvas untuk mencegat div yang lengkap. Setelah intersepsi selesai, hapus bagian ini isinya. Kode lengkapnya adalah sebagai berikut:
function showQRCode() { scrollTo(0, 0); //Klon node, defaultnya adalah false, yaitu atribut metode tidak disalin, dan true adalah semua salinan. var cloneDom = $(#d1).clone(true); //Atur atribut z-index dari node yang dikloning, asalkan lebih rendah dari node yang dikloning. cloneDom.css({ warna latar: #fafafa, posisi: absolut, atas: 0px, indeks-z: -1, tinggi: 798, lebar: 650 }); if (typeof html2canvas !== 'tidak ditentukan') {/ / /Berikut ini adalah pemrosesan svg var nodeToRecover = []; var nodeToRemove = []; cloneDom.find('svg');//divReport adalah id dom yang perlu dicegat ke dalam gambar svgElem.each(function (index, node) { var parentNode = node.parentNode; var svg = node.outerHTML .trim(); var kanvas = dokumen.createElement('kanvas'); canvg(kanvas, svg); if (simpul.gaya.posisi) { kanvas.gaya.posisi += simpul.gaya.posisi; kanvas.gaya.kiri += simpul.gaya.kiri; .style.top; } nodeToRecover.push({ induk: parentNode, anak: simpul }); canvas }); parentNode.appendChild(canvas }); //Menambahkan node yang dikloning ke badan secara dinamis. $(body).append(cloneDom); html2canvas(cloneDom, { dirender: fungsi(kanvas) { var url =canvas.toDataURL(image/png); window.location.href = url ; cloneDom.remove(); // Hapus konten kloning}, latar belakang:#fafafa });
Di sini, pertama-tama kloning div yang akan dicegat dan atur indeks-z ke minimum untuk menghindari antarmuka yang tidak sedap dipandang. Kemudian svg diproses, yang telah dianalisis di atas. Terakhir, node klon ditambahkan ke badan Can.
Saat dirender, kita bisa langsung menggunakan location.href untuk melompat melihat gambar, menyimpannya, atau menulis url ke dalam src dari img dan menampilkannya di antarmuka, seperti $('#imgId').attr('src ' ,url);
Terakhir, gambar yang baru saja diambil dapat ditampilkan di antarmuka:
5. Unggah gambar dan simpan ke database, dan dapatkan gambar untuk ditampilkan di antarmuka.Setelah URL diperoleh, URL tersebut perlu diunggah ke backend, disimpan dalam database, dan kemudian dimuat ke antarmuka lain yang ditampilkan. Saya biasanya terbiasa menggunakan url untuk menyimpan jalur gambar alih-alih penyimpanan gumpalan.
Karena saya perlu mendapatkan gambar di antarmuka lain, saya menyimpan gambar di direktori sumber daya pada level yang sama dengan aplikasi web. Kodenya adalah sebagai berikut:
//Menyimpan gambar dan mengembalikan jalur gambar BASE64Decoder decoder = new BASE64Decoder(); byte[] b = decoder.decodeBuffer(product.getProPic().substring(data:image/png;base64,.length())); ByteArrayInputStream bais = new ByteArrayInputStream(b); BufferedImage bi1 = ImageIO.read(bais); url = user_resource + File.separator + img + File.separator + product_+UUID.randomUUID().toString().replace(-, )+.png; String totalUrl = System.getProperty(root) + File w2 = File baru(totalUrl); ImageIO.write(bi1, png, w2); //Menyimpan jalur relatif gambar ke dalam database int res = productMapper.insertSelective(product);
Karena logika lain terlibat di sini, hanya sebagian kode yang disertakan.
BASE64Decoder disini digunakan untuk menyimpan gambar. Setelah kita mendapatkan gambarnya, kita perlu menggunakan substring untuk mencegat isi data:image/png;base64, karena berikut ini url gambarnya, url.substring(data:image/png;base64,.length())
.
Untuk jalurnya, url pada kode di atas adalah konten yang saya simpan di database, dan totalUrl adalah jalur sebenarnya yang disimpan selama operasi penulisan aktual ImageIO. Direktori root proyek yang diperoleh dengan metode getProperty() dapat berupa dikonfigurasi di web.xml Konten berikut, dan kemudian System.getProperty(root) dapat digunakan.
<!-- Konfigurasikan sistem untuk mendapatkan direktori root proyek--><context-param> <param-name>webAppRootKey</param-name> <param-value>root</param-value></context-param ><listener > <kelas pendengar> org.springframework.web.util.WebAppRootListener </listener-class></listener>
Sekarang URL gambar disimpan dalam database, dan gambar itu sendiri disimpan dalam direktori proyek di bawah Tomcat.
Terakhir, untuk mendapatkannya dari antarmuka, cukup tambahkan nama proyek di depan url saat ini < img class =depot-img src =<%=request.getContextPath()%>/`+e.proPic+` >
.
Kemudian Anda dapat melihat gambar yang ditampilkan di antarmuka:
Di atas adalah keseluruhan isi artikel ini, saya harap dapat bermanfaat untuk pembelajaran semua orang. Saya juga berharap semua orang mendukung VeVb Wulin Network.