vue中如何使用canvas循环生成多张海报?
一. 需求背景长按分享图片,图片中含有自己分享链接生成的二维码,需要把二维码和背景图合成一张海报,项目需求是循环生成多张海报二. canvas画布的生成条件要生成画布的html元素不能是隐藏状态。如果不想页面显示出来的话,可以给个 margin-top: -999999999px;生成画布方法需要在页面渲染结束之后执行。三. 如何生成单个画布 ?思路:根据自己的分享链接通过vue-qr生成一个二维
·
一. 需求背景
长按分享图片,图片中含有自己分享链接生成的二维码,需要把二维码和背景图合成一张海报,项目需求是循环生成多张海报
二. canvas画布的生成条件
- 要生成画布的html元素不能是隐藏状态。如果不想页面显示出来的话,可以给个 margin-top: -999999999px;
- 生成画布方法需要在页面渲染结束之后执行。
三. 如何生成单个画布 ?
思路:
根据自己的分享链接通过vue-qr生成一个二维码;
获取要生成画布的容器,比如通过id或者that.$refs获取页面元素外层的div
调用指定方法生成,生成出来的是base64的图片
通过canvas.toDataURL(“image/png”); 将canvas转为base64图片(eg. data:image/png;base64,ijskjlkj)
赋值给img标签的src即可
npm安装
npm install vue-qr --save //生成二维码
npm install html2canvas --save //html转canvas
页面引入
import vueQr from 'vue-qr'
import html2canvas from "html2canvas";
生成的二维码和背景图的具体定位,可通过css控制,这块代码忽略。
<template>
<div>
<!-- 生成图片的DOM -->
<div ref="box">
<!-- 背景图 -->
<img :src="item.img" class="img" />
<!-- 二维码 -->
<div style="width:60px;height:60px;position:absolute;right:5px;bottom:22px">
<vue-qr :text="invite_url" :size="500"></vue-qr>
</div>
</div>
<!--存放合成的图片-->
<img :src="imgUrl" alt="">
</div>
</template>
<script>
import vueQr from 'vue-qr'
import html2canvas from 'html2canvas';
export default {
data() {
return{
invite_url: "https://www.baidu.com/"
imgUrl:''
}
},
methods:{
draw(){
var that = this;
html2canvas(that.$refs.box).then(function(canvas) { //第一个参数是需要生成截图的元素
that.imgUrl = canvas.toDataURL()//将canvas转为base64图片(eg. data:image/png;base64,ijskjlkj)
});
}
},
mounted(){
this.draw()
}
};
</script>
四. 循环生成多个画布
思路:
// 1.循环的时候,根据索引生成不同的id
:id="`imgContainer_${index}`"
v-for="(item, index) in currentImgList"
// 2.获取页面元素的时候,也可以采用循环的方式,先拼接id
for (var i = 0; i < this.currentImgList.length; i++) {
var key = "imgContainer_" + i; //这里的i也是从0开始的,跟html中的id对应起来
// imgContainer_0,imgContainer_1 这种
var box = document.getElementById(key);
// 3.循环中根据id生成画布,push到一个数组即可
url = canvas.toDataURL("image/png");
img_arr.push({ img: url });
// 4.最后输出img_arr 这个数组到页面上即可
this.canvasImgList = img_arr;
具体代码
html
<template>
<div class="myself">
<div class="share" ref="parent_wrapper" v-show="is_share">
<van-icon
name="cross"
color="#fff"
size="20"
class="closeIcon"
@click="cancel()"
/>
<div class="info">
<p>长按保存或者截图分享</p>
</div>
<!--存放合成的图片;这个div因为固定在下方的第一个按钮不需要canvas生成海报-->
<div
class="wrapper_box"
style="min-height:100vh;"
ref="wrapper"
v-if="is_convas"
>
<div class="content" ref="wrapperChild">
<div
v-for="(item, index) in currentImgList"
:key="index"
class="imgItem"
>
<img :src="item.img" class="img" style="margin: 0 10px;" />
</div>
</div>
</div>
<div
class="wrapper_box"
style="min-height:100vh;
"
ref="wrapper"
v-else
>
<div class="content" ref="wrapperChild">
<!-- 生成图片的DOM -->
<div
:id="`imgContainer_${index}`"
v-for="(item, index) in currentImgList"
:key="index"
class="imgItem"
>
<!-- 循环的背景图 -->
<img :src="item.img" class="img" />
<!-- 生成的二维码 -->
<div
style="width:64px;height:64px;position:absolute;right:10px;bottom:22px"
>
<vue-qr :text="invite_url" :size="500"></vue-qr>
</div>
</div>
</div>
</div>
<p class="tips">
点击右上角选择【发送给朋友】或【分享到朋友圈】 邀请朋友一起成为合伙人。
</p>
</div>
<div class="page_bottom">
<div class="zzb_share" @click="go_zzb">按钮1</div>
<div class="zzb_share partner_share" @click="go_partner">按钮2</div>
</div>
</div>
</template>
js部分
<script>
import indexApi from "@/api/index.js";
import BScroll from "better-scroll";
import vueQr from "vue-qr";
import html2canvas from "html2canvas";
import { Popup, Button, Icon, Swipe, SwipeItem } from "vant";
export default {
data() {
return {
zzbList: [
{ img: require("../../assets/image/zzb_1.png") },
{ img: require("../../assets/image/zzb_2.png") },
{ img: require("../../assets/image/zzb_3.png") }
],
partnerList: [
{ img: require("../../assets/image/partner_1.jpg") },
{ img: require("../../assets/image/partner_2.jpg") },
{ img: require("../../assets/image/partner_3.jpg") }
],
invite_url: "https://www.baidu.com/"
currentImgList: [],
canvasImgList: [],
is_share: false,
is_convas: false,
};
},
mounted() {
//mounted 里面 初始化数组,初始化scroll
this.currentImgList = this.partnerList;
let authTimeTimer = setTimeout(() => {
if (this.invite_code) {
this.init_partner();
}
clearTimeout(authTimeTimer);
}, 500);
},
methods: {
cancel() {
this.is_share = false;
},
go_partner() {
this.$refs.parent_wrapper.classList.remove("code_p");
this.currentImgList = this.canvasImgList;
this.is_share = true;
this.is_convas = true; //展示只有合成图片的div
this.slide_x(); //better-scroll的滑动组件,忽略即可
},
init_partner() {
this.is_share = true;
this.is_convas = false; //展示有背景图,二维码的div
this.$refs.parent_wrapper.classList.add("code_p");
//this.currentImgList = this.partnerList;
// 生成convas;
let authTimeTimer = setTimeout(() => {
this.createCanvas();
clearTimeout(authTimeTimer);
});
},
createCanvas() {
var img_arr = [];
for (var i = 0; i < this.partnerList.length; i++) {
var key = "imgContainer_" + i;
// console.log(key);
var box = document.getElementById(key);
let url = "";
//第一个参数是需要生成截图的元素,第二个是自己需要配置的参数,宽高等
html2canvas(box, {
backgroundColor: null,
dpi: 192, // 将分辨率提高到特定的dpi,默认值为96
scale: 2, // 用于渲染的比例尺。默认为浏览器设备像素比率。默认值是1,手机端设置成2
useCORS: true // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题
}).then(canvas => {
url = canvas.toDataURL("image/png");
img_arr.push({ img: url });
});
}
this.canvasImgList = img_arr;
this.is_convas = true; //展示只有合成图片的div
}
},
.code_p {
// 这个是让 默认得元素的隐藏,并且能 截图海报 截取到的方法
margin-top: -999999999px;
}
关于canvas刚接触了解不太多,欢迎大家指正,一起进步~
更多推荐
已为社区贡献18条内容
所有评论(0)