功能需求:
- 海报有1张背景图, 海报上的文案内容动态变化
- 在背景图的某个位置上添加二维码图片
- 水印功能
大致思路
- html页面部分, 包括背景图,接口得来的数据,以及二维码图片的位置
- 使用 qrcodejs2库生成二维码图片,展现到预定位置
- 添加水印(canvas | html 两种方式 后边会分别进行介绍)
- 使用 html2canvas库 将页面整体转换成一张海报
关键代码
1. html 图片部分 (以uni-app举例)
| <view class="posterArea" id="posterTem"> |
| <img @load="loadImgFinish" class="image" :src="posterSrcNew" mode="scaleToFill" style="width:100%;margin-bottom: 7vh;" /> |
| |
| <view class="qrcode"><view id="qrcodeImg"></view></view> |
| </view> |
| |
| 注: |
| 1. 需要为该div添加一个id 如 'posterArea', 供html2canvas需要使用 |
2. qrcodejs生成二维码(如果二维码是固定的即可跳过这一步)
| import QRCode from 'qrcodejs2' |
| |
| createQrcode(text) { |
| |
| const qrcodeImgEl = document.getElementById('qrcodeImg') |
| qrcodeImgEl.innerHTML = '' |
| let qrcode = new QRCode(qrcodeImgEl, { |
| width: 200, |
| height: 200, |
| colorDark: '#000000', |
| colorLight: '#ffffff', |
| correctLevel: QRCode.CorrectLevel.H |
| }) |
| qrcode.makeCode(text) |
| }, |
| |
| 关于容错级别: |
| QRCode.CorrectLevel.L(最大 7% 的错误能够被纠正) |
| QRCode.CorrectLevel.M(最大 15% 的错误能够被纠正) |
| QRCode.CorrectLevel.Q(最大 25% 的错误能够被纠正) |
3. 添加水印(二选一即可)
使用html方式生成 ,然后作为组件导入到页面中即可(个人推荐此方式,速度上比canvas快一些)
| <template> |
| <view> |
| <view v-if="imgHeight" class="copyRightBox" :style="{height:imgHeight?imgHeight+'px':'850upx'}"> |
| <view class="font" ref='sy' v-for="(item,index) in 30" :key='index'> |
| {{sytext}} |
| </view> |
| </view> |
| </view> |
| </template> |
| <script> |
| export default { |
| data() { |
| return {}; |
| }, |
| props: { |
| sytext: String, |
| imgHeight:String, |
| }, |
| mounted() {} |
| } |
| </script> |
| <style> |
| .copyRightBox { |
| overflow: hidden; |
| width: 100%; |
| height: 850upx; |
| pointer-events: none; |
| position: fixed; |
| top: 0px; |
| left:-50upx; |
| z-index: 99998; |
| } |
| .font { |
| float: left; |
| transform: rotate(-30deg); |
| margin-top: 220upx; |
| margin-left: 100upx; |
| font-size: 75upx; |
| color: rgba(0,0,0,0.2); |
| } |
| </style> |
使用canvas生成
| const canvas = document.createElement("canvas"); |
| let _ix = img.width; |
| let _iy = img.height; |
| canvas.width = _ix; |
| canvas.height = _iy; |
| const ctx = canvas.getContext("2d"); |
| ctx.fillStyle = "rgba(51,51,51,0.4)"; |
| ctx.font = '50px "微软雅黑"'; |
| ctx.drawImage(img, 0, 0); |
| for (let j = 50; j <= img.height * 2;) { |
| ctx.fillText(remartText, img.width/2, j); |
| j += 260 |
| } |
4. 生成分享海报
| createPoster(domId, obj) { |
| let dom = document.querySelector(domId); |
| let res = { |
| height: dom.scrollHeight, |
| width: dom.scrollWidth |
| } |
| console.log('终版', res) |
| let canvas = await html2canvas(dom, { |
| useCORS: true, |
| |
| |
| |
| windowHeight: dom.scrollHeight, |
| windowWidth: dom.scrollWidth, |
| backgroundColor: null, |
| width: dom.scrollWidth, |
| height: dom.scrollHeight |
| }) |
| let imgRes = canvas.toDataURL(); |
| |
| console.log('图片的base64地址', imgRes) |
| } |
拿到海报的base64地址以后,我们就可以进行后续的业务操作了。
常见问题处理
1. 背景图片为透明时,生成海报变为黑色
解决办法:canvas填充白色
| |
| context.fillStyle = "#fff"; |
| context.fillRect(0, 0, canvas.width, canvas.height); |
| context.drawImage(image, 0, 0, image.width, image.height); |
2. 海报模糊
解决办法: 如果使用的是uni-app中的image标签 需要替换为 img标签,image标签在uni-app中其实是背景图片
3. 海报生成不全
解决办法: 有可能是图片等没有渲染完成,可利用图片的加载完成事件 @load ,等加载完成后再进行后续操作
<img @load="loadImgFinish" />
4. 图片显示跨域错误
解决办法:开启 html2canvas的跨域 ,如果还不行大概率是后端返回的图片跨域问题
| let canvas = await html2canvas(dom, { |
| useCORS: true, |
| }) |