I. Preface
It is a common requirement to convert DOM into pictures in project development nowadays. So I decided to use html2 canvas as a plug-in. PS: There are many versions. Here is the latest version.
Two, code
1. Installing plug-ins
npm install html2canvas --save
2. Use (Picture class="pic" in this page is randomly selected, so the generated pictures are not specific)
<template> <div class="wrap"> /** DOM The final generated picture*/ <img class="posterImg" v-show="dataURL.length>20" :src="dataURL"/> /** DOM that needs to be converted into images, because PicUrl is not specific, ref cannot write fixed values*/ <div :ref="ImgRef" style="position:absolute;left:0;top:0;z-index:0"> <h1>Small fish Lei Lei</h1> <img class="pic" :src="PicUrl" /> </div> </div> </template> <style scoped> .wrap { width: 100%; height: 100vh; overflow-y: scroll; background-color: #fff; text-align: center; position: relative; } .posterImg{ width: 100%; height: auto; position: absolute; left:0; top:0; z-index: 2; } .pic { width: 100%; height: auto; display:block; } </style>
The following database URL is the base64 address of the final transformed image, which can be displayed in the img tag.
<script> export default { name: 'getImg', data(){ return{ dataURL:"", //DOM-generated images RandomNum:1, //random number ImgRef:"", //ref of DOM PicUrl:"", //Random pictures on the page ImgArr:[ ./static/img1.png, ./static/img2.png, ./static/img3.png, ] } }, beforeRouteEnter: (to, from, next) => { //does NOT have access to `this` component instance next(vm => { vm.Instance(); }); }, beforeRouteUpdate: function(to, from, next) { next(); this.Instance(); }, menthod:{ Instance(){ //Generate random integers [0, 2] this.RandomNum = Math.floor(Math.random() * (2 - 0 + 1) + 0); this.ImgRef = "PosterImg"+this.RandomNum; this.PicUrl = this.ImgArr[this.RandomNum-1]; setTimeout(()=>{ this.GetPosterUrl(); },3000) }, //Generate pictures from html GetPosterUrl(){ let ImgRef = "PosterImg"+this.RandomNum; this.$nextTick(() => { html2canvas(this.$refs[ImgRef], { allowTaint: true, backgroundColor: null // Solve the problem that the generated image has white edges }).then(canvas => { let dataURL = canvas.toDataURL("image/png"); this.dataURL = dataURL; console.log(this.dataURL); }); }); } } } </script>
3. Common bug s
1. The resulting picture has a white border.
Configure backgroundColor: null in the configuration item.
2. There are pictures that can't be displayed and there are errors (usually cross-domain errors)
This is the most common bug, that is, the plug-in can not generate cross domain pictures, and there is no good way for Baidu after reading the official document configuration. Finally, let the back-end directly convert the cross domain pictures to base64, which perfectly solves the problem.
3. After the image is generated, it will be covered on the original DOM to produce a flickering effect.
Let the generated image be hidden first, and then show it after it is generated.
4. Incomplete picture interception
(1) More resources, resulting in modules not fully loaded, have generated screenshots; add a timer for delay operation
setTimeout(()=>{ this.GetPosterUrl(); },3000)
(2) When the page exceeds one screen, only the visual area is intercepted.
Solution: Let the scroll attribute be set on the outermost element (. wrap), not on the body; and let the intercepted element detach from the document stream
.wrap{ width: 100%; height: 100vh; overflow-y: scroll; background-color: #fff; text-align: center; position: relative; } <div :ref="ImgRef" style="position:absolute;left:0;top:0;z-index:0"> <h1>Small fish Lei Lei</h1> <img class="pic" :src="PicUrl" /> </div>