详解html5 canvas 微信海报分享(个人爬坑)
程序员文章站
2022-06-21 09:49:49
这篇文章主要介绍了详解html5 canvas 微信海报分享(个人爬坑)的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧... 18-01-12...
本文介绍了canvas 微信海报分享,分享给大家,具体如下:
- 随机产生一张图片
- 拿到微信用户的头像和称呢(自己调后端的接口获取)
- 把用户头像和称呢和随机产生一张图片合成一张海报
- 可能上一页用户还有填入的心愿文本也要填入图片中
实现效果图
记录下在实现功能过程中遇到的问题
- canvas在微信浏览器中长按无效不能像img一样长按分享(那我就转成img呗)
- 转成img后在微信开发者工具中能显示,真机无效(欲哭无泪),度娘说可能是图片跨域^-^
- 用户头像合成还要圆角,我表示不会啊,直接看canvas api文档了对度娘无爱了
- canvas填入文字超过指定宽度也要换行,我表示只知道不超多指定宽度的各种文字对齐方式 ctx.textalign = 'center' ;
- canvas在高清屏下模糊的问题(超简单的不知道度娘怎么会那么啰嗦)不就是canvas.witdt=innerwidth*devicepixelratio
html结构
<div class="imgbox" v-cloak> <img :src='imgsrc' v-if="imgsrc" /> </div>
css
<style> *{ margin:0; padding:0; } body, html { width: 100%; height: 100%; } .imgbox { width: 100%; height: 100%; } img { width: 100%; display: block; } </style>
script
// js主要结构 new vue({ el:'imgbox', data:{ urlparam: {},//获取url中的传值对象 randomnum: 1,//随机数用于确定那个祈福页 username: '',//用户称呢 imgsrc: '',//合成最终图片 userimg: '',//用户头像图片 usermessage: '',//用户留言 }, methods: { // 分享到盆友圈 wxsharefriends: function () {}, // 初始化请求头 wxhttp: function () { $.ajaxsetup({ headers: { 'x-csrf-token': $('meta[name="csrf-token"]').attr('content') } }); }, // 获取随机数[1,10] randomnumbers() { this.randomnum = math.ceil(math.random() * 10) }, // 获取微信用户头像和称呢和用户输入祝福语 getuserinfo() { var vm = this; $.post('api请求地址', function (data) { if (data.code == 1) { vm.userimg = data.data.headimg; vm.username = data.data.nickname; if (vm.randomnum % 2 == 0) { vm.usermessage= '红尘相遇,年华已老。岁月花开多少不在,古往今来相遇是一件既微妙。而又神圣的事情,红尘的情网中' } else { vm.usermessage = '红尘相遇,年华已老' } } vm.$nexttick(function () { vm.drawcanvasbgimg(); }) }) }, // 获取页面dpr和宽度 getwindowinfo() { var windowinfo = {}; windowinfo.dpr = window.devicepixelratio; if (window.innerwidth) { windowinfo.width = window.innerwidth; } else { windowinfo.width = document.body.clientwidth; } return windowinfo; }, // 画活动页分享背景大图 drawcanvasbgimg () {}, // 在背景图片的画布上截取一个圆然后填充入用户头像 drawcanvasuserimg(canvas, ctx, dpr) {}, // 填写用户称呢或者用户留言 canvasfilltext (canvas, ctx, dpr, circler) {}, // 合成base64位分享图 convertcanvastoimage (canvas) { this.imgsrc = canvas.todataurl("image/jpeg");//png有毒在安卓机下识别二维码无法跳转 this.$spin.hide(); } } })
画图方法步骤
- drawcanvasbgimg ()
- drawcanvasuserimg (canvas, ctx, dpr)
- canvasfilltext (canvas, ctx, dpr, circler)
- convertcanvastoimage (canvas)
画活动页分享背景大图 drawcanvasbgimg ()
//拿到数据后开始画背景大图 想法很简单就是把图片画到canvas中然后在画布上再画头像文字让后转成img drawcanvasbgimg () { var vm = this; var canvas = document.createelement("canvas"); var ctx = canvas.getcontext("2d"); var clientwidth = this.getwindowinfo().width; //获取屏幕宽度用于canvas宽度自适应移动端屏幕 var dpr = this.getwindowinfo().dpr; ctx.globalcompositeoperation = "source-atop";//** 坑锯齿感觉没什么用不知道是不是用错地方了 ** canvas.width = dpr * clientwidth; //由于手机屏幕时retina屏,都会多倍渲染,用dpr来动态设置画布宽高,避免图片模糊 canvas.height = dpr * clientwidth * 609 / 375;//去掉微信头部的状态栏应该是603 没搞懂603还是不能让图片满屏直接多加到了609 var img = new image(); img.crossorigin = '';//死坑的图片跨域 (img.crossorigin = "anonymous"这种写法还是不能显示base64格式图片) img.src = "http://xxx" + this.randomnum + ".jpg"; img.onload = function () { ctx.drawimage(img, 0, 0, canvas.width, canvas.height); vm.drawcanvasuserimg(canvas, ctx, dpr); } },
用户头像 drawcanvasuserimg (canvas, ctx, dpr)
// 在背景图片的画布上截取一个圆然后填充入用户头像 drawcanvasuserimg: function (canvas, ctx, dpr) { var vm = this; var circler = 50 * dpr;//半径 var circlex = canvas.width / 2;//圆心x坐标 var circley = 50 * dpr;//圆心y坐标 var imgx = circlex - circler;//图片x开始坐标 var imgy = circley - circler;//图片y开始坐标 var imgwidth = 2 * circler;//图片按圆形大小 var img = new image(); img.crossorigin = ''; img.src = this.userimg; img.onload = function () { ctx.save(); // 保存当前ctx的状态 ctx.arc(circlex, circley, circler, 0, 2 * math.pi); //画出圆 ctx.clip(); //裁剪上面的圆形 ctx.drawimage(img, imgx, imgy, imgwidth, imgwidth); // 在刚刚裁剪的园上画图 ctx.restore(); // 还原状态 vm.canvasfilltext(canvas, ctx, dpr, circler); } },
在canvas中画文字
// 填写用户称呢或者用户留言 canvasfilltext (canvas, ctx, dpr, circler) { var fontsizethis = dpr * 20 + 'px' + ' arial'; var usernamey = 0;//用户名y轴坐标 var usermessagex = dpr * 40;//用户留言x轴坐标 var usermessagey = 0;//用户留言y轴坐标 var lastsubstrindex = 0;//字符串下标 var linewidth = 0;//一行宽度 var alltextwidth = 0;//所有字符宽度 ctx.font = fontsizethis; // 需要用户名是写入用户名 if (this.username) { usernamey = circler * 2.5; ctx.fillstyle = "#0094ff"; ctx.textalign = 'center'; ctx.filltext(this.username, canvas.width / 2, usernamey); } if (this.usermessage) { usermessagey = usernamey + dpr * 35; ctx.fillstyle = "#000"; // 获取字符宽度 for (var i = 0; i < this.usermessage.length; i++) { alltextwidth += ctx.measuretext(this.usermessage[i]).width; } // 字符串长度大于画布区域要换行 if (alltextwidth > canvas.width - 2* usermessagex) { for (var i = 0; i < this.usermessage.length; i++) { linewidth += ctx.measuretext(this.usermessage[i]).width; if (linewidth > canvas.width - 2*usermessagex) { ctx.textalign = 'left'; ctx.filltext(this.usermessage.substring(lastsubstrindex, i), usermessagex, usermessagey); usermessagey += dpr * 25;//设置行高 linewidth = 0; lastsubstrindex = i; } if (i == this.usermessage.length - 1) { ctx.filltext(this.usermessage.substring(lastsubstrindex, i + 1), usermessagex, usermessagey); } } } else { // 小于者居中显示 ctx.textalign = 'center'; ctx.filltext(this.usermessage, canvas.width / 2, usermessagey); } } this.convertcanvastoimage(canvas); },
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: 详解html5页面 rem 布局适配方法