1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Vue.js结合Canvas制作二维码和图片的合成(html2canvas + Canvas2Image)--整理

Vue.js结合Canvas制作二维码和图片的合成(html2canvas + Canvas2Image)--整理

时间:2020-03-26 22:46:25

相关推荐

Vue.js结合Canvas制作二维码和图片的合成(html2canvas + Canvas2Image)--整理

之前写过一篇关于二维码和图片合成的博文,但是存在一些问题,本篇是本人整理最后在项目中使用的。

建议:如果是单张背景图或者是多张背景图且二维码在同一位置的话,建议直接在后台合成分享图直接给前端返回即可,我这次项目需求是多张背景图并且二维码的位置都不同,后台不方便处理,所以直接前端来处理了。

需求背景:

分享图片,图片中含有自己分享链接生成的二维码!!

大体思路:

第一步、将自己的分享码或其他字段传给后台,后台返回Base64格式的二维码图片;(至于为什么要使用Base64格式,如果返回其他格式的图片会出现二维码加载不出来的情况)第二步、二维码放在背景图的指定位置,再合成分享图片;

npm安装:

1.npm install html2canvas --save //html转canvas

2.npm installcanvas2image --save //canvas转图片

页面引入:

import html2canvas from 'html2canvas';

import Canvas2Image from 'canvas2image';

html:

<!-- 分享 --><template><div class="container share"><!-- 换一张按钮 --><div @click="shareChange" class="share_change" v-show="changeShow">换一张</div><!-- 背景列表 --><div class="mark" :class="markShow?'':'mark_position_left'"><p>--请选择生成图片--</p><div class="mark_item" v-for="(item,index) in imgUrls" :key="index" @click="getBgImg(item)"><img :src="item.imgurl" alt=""></div></div><!-- 生成图片的DOM --><div class="share_box" ref="box"><div class="img-box"><!-- 背景图 --><img class="shareBg" @load="bgImgload" :src="bgImg" alt=""><!-- 二维码 --><div class="shareQr" :class="imgUrls[(pid > 0 ? pid : 1) - 1].isClass"><img @load="qrcodeLoad" :src="qrCodeUrl" alt=""></div></div></div><!-- 存放合成的图片 --><div class="share-img" id="shareImg"></div></div></template>

js:

<script>import html2canvas from 'html2canvas';import Canvas2Image from 'canvas2image';export default {data () {return {changeShow:false,markShow:true,qrCode:false,pid:0,imgUrls:[{pid:1,imgurl:require("@/assets/images/share/share1.jpeg"),isClass:'shar1'},{pid:2,imgurl:require("@/assets/images/share/share3.jpeg"),isClass:'shar2'},{pid:3,imgurl:require("@/assets/images/share/share4.jpg"),isClass:'shar3'},{pid:4,imgurl:require("@/assets/images/share/share5.jpg"),isClass:'shar4'},{pid:5,imgurl:require("@/assets/images/share/share6.jpg"),isClass:'shar5'},{pid:6,imgurl:require("@/assets/images/share/share7.jpg"),isClass:'shar6'},{pid:7,imgurl:require("@/assets/images/share/share8.jpg"),isClass:'shar7'},{pid:8,imgurl:require("@/assets/images/share/share9.jpg"),isClass:'shar8'},{pid:9,imgurl:require("@/assets/images/share/share10.jpg"),isClass:'shar9'}],bgImg:'',qrCodeUrl:'',invitationCode:'',timer:null,}},created() {//邀请码this.invitationCode = this.$route.query.invitationCode;//获取二维码this.getQrCodeBase64();},mounted() {},methods: {//换一张shareChange(){this.changeShow = !this.changeShow;document.getElementById('shareImg').innerHTML = '';this.markShow = true;},//获取二维码getQrCodeBase64(){let that = this;that.$http.get('user/getInviteQrCode',{parmas:{code:that.invitationCode}}).then(res => {if(res && res.data.code == 0){that.qrCodeUrl = res.data.data;}})},//获取背景图getBgImg(e){let that = this;that.changeShow = true;that.markShow = false;if(e.pid == that.pid){//前一张加载过that.bgImgload();}else{//未加载过that.pid = e.pid;that.bgImg = e.imgurl;}},//二维码是否渲染完毕qrcodeLoad(){this.qrCode = true;},//背景图加载完回调bgImgload(){this.$indicator.open({text: '正在生成图片...',spinnerType: 'fading-circle'});this.creatImg();},//生成图片creatImg(){let that = this;if(that.qrCode){// 已经生成二维码clearInterval(this.timer)let element = that.$refs.box;html2canvas(element,{allowTaint:true,taintTest: false}).then(function(canvas) {document.getElementById('shareImg').appendChild(Canvas2Image.convertToPNG(canvas));that.$indicator.close(); that.$toast({message: '图片已生成,长按保存分享给你的好友吧',position: 'middle',duration: 2000}); });}else{that.timer = setInterval(() => {that.creatImg()},300)}}},destroyed () {this.$indicator.close(); clearInterval(this.timer)}}</script>

css:

.share {width: 100%;height: calc(100% - .6rem);background: #fff;.share_change {font-size: 14px;padding: .04rem .1rem;color: #fff;background: rgba(0, 0, 0, .4);border-radius: 100px;position: fixed;top: 1.5rem;right: .1rem;}.mark {width: 96%;height: 100%;margin: 0 auto;overflow-y: scroll;p {font-size: 14px;text-align: center;margin: .1rem 0;color: #888888;}.mark_item {width: 40%;margin: 0 5%;margin-bottom: .2rem;box-shadow: 1px 1px 1px 2px #ccc;float: left;}}.mark_position_left {position: fixed;top: 0;left: -100%;}.share_box {width: 100%;position: fixed;top: 0;left: -100%;}.img-box {position: relative;.shareBg {z-index: 3;}.shareQr {position: absolute;z-index: 5;}.shar1 {width: .49rem;height: .49rem;top: 6rem;left: .86rem;}.shar2 {width: .49rem;height: .49rem;top: 5.7rem;right: .24rem;}.shar3 {width: .75rem;height: .75rem;top: 4.88rem;right: .21rem;}.shar4 {width: .66rem;height: .66rem;top: 4.98rem;left: .17rem;}.shar5 {width: .6rem;height: .6rem;top: 5.05rem;left: .09rem;}.shar6 {width: .6rem;height: .6rem;top: 5.1rem;left: 1.56rem;}.shar7 {width: .64rem;height: .64rem;top: 4.69rem;left: 1.12rem;}.shar8 {width: .75rem;height: .75rem;top: 2.73rem;left: 1.5rem;}.shar9 {width: .65rem;height: .65rem;top: 2.72rem;left: 1.54rem;}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。