一、Canvas应用的背景(个人理解)及基础语法

背景

从2012年开始,微信那个时候用户的积累的量已经非常大了,推出公众号,当然大屏智能手机在那个时候也流行,传统的大众媒体逐步消亡,像微信公众号这样的新媒体盛行。企业的广告投入开始从电视等传统媒体向基于圈层文化的新媒体精准营销转移,甚至很多企业尤其互联网企业开始思考如何利用用户的自传播这种方式去宣传企业、实现商业目标。而用户的自传播很好的途径就是生产个性化的海报。举个最常见的例子,我第一次使用Keep是因为在朋友圈看到朋友分享她运动量的一个截图,当时在我看来非常酷,有心率脉搏呀、时速运动量啊、消耗的卡路里等,还有一个二维码,然后我就点了下载了Keep,这整个获客成本几乎为0,秒秒钟就多了一个用户。而实现这一过程的技术手段就可以用canvas。所以,canvas的盛行,与企业的精准营销和用户的自传播有很大的关系。
如极客时间的一些实现案例:

大家看第一张图的话是在2017年末的时候,Qcon全球软件开发大会预热阶段的海报。然后我们为程序员做了一个生成2018年关键字的一张海报,文案都非常有趣啊。第二张的话是在2018年元旦的时候做的极客时间助手,这个小程序当初主要是为程序员做的2018年新年签。那面就是一些极客时间的专栏,包括用户留言,你留言随手可以生成一张海报,可以转发等等大概就是这样。

基础语法

Canvas本质是一个可以使用脚本(通常为JavaScript)来绘制图形的 HTML 元素,默认大小为300像素×150像素(宽×高,像素的单位是px),通过JavaScript上下文对象动态创建图像。比如,画线、画矩形、涂颜色甚至生成带二维码的海报。原理就是一笔一笔的画,画一条横线,再画一条横线等等,就是不断地创建路径、绘制路径,然后把这个路径封闭起来可以涂色之类的,他的底层的封装就是放到一个数组里形成一个路径的数组,将这个数组传到js底层的一个方法,然后去绘制。

  • 举个栗子:画一个头像

首先,你需要把这张图片画canvas上面,比如说你画你这个头像就是正方形,就在(0,0)开始画一个图片。那么你在这个图片的中心,作为原点,然后你画一个圆形。然后你再利用canvas语法画一个圆弧,在这个圆弧路径以外设置不可见以内设置可见,这个时候就形成了一个圆形头像。

  <canvas id="canvas" width="300" height="300"></canvas><script>const canvas = document.getElementById('canvas')const ctx = canvas.getContext('2d')const img = new Image()img.onload = function() {circleImg(ctx, img, 100, 100, 50)}img.src="https://avatar-static.segmentfault.com/289/811/2898115528-58c35e9b79717_big64"function circleImg(ctx, img, x, y, r) {ctx.save()let d = 2 * rlet cx = x + rlet cy = y + rctx.arc(cx, cy, r, 0, 2 * Math.PI)ctx.stroke();ctx.clip()ctx.drawImage(img, x, y, d, d)ctx.restore()}// 微信小程序中的[canvas](https://developers.weixin.qq.com/miniprogram/dev/component/canvas.html)与HTML5的canvas在语法有些区别,比如API就不一样,// 另外小程序中的canvas因为是原生组件的层级是最高的,所以页面中的其他组件无论设置 z-index 为多少,都无法覆盖原生组件</script>

二、常用的"生成海报"的方式

我们会经常在朋友圈看到什么算命、性格分析、测算你的智商、情商等等这些东西,都是由用户分享出一张图片(海报),这个图片就是用canvas做成的,上面画了二维码,二维码是一个数组两个或循环嵌套画小黑点用户识别这个二维码之后就进入他的程序,经过程序跑出来的测试结果啊什么的,点保存的时候,就会生成一张个性海报明白。怎么生成这种个性化海报呢?

2.1 字符串模板

此处应有案例

主要实现:与服务端约定好数据格式-->前端做好模板-->服务端用第三方工具渲染返回到客户端img
首先与服务端约定好数据格式,比如关键字是什么、头像URL、昵称等等,把所有放数据格式的地方用{{{}}}嵌套,告诉后端位置;然后,将前端模拟数据抠去,比如user.tags,把这一段html的字符串模板给到服务端,最后服务端拿到数据通过html2canvas这样的第三方工具把图片渲染返回给客户端展示,让用户可以长按这张图片保存到手机相册。这是比较传统的方式早些年基本上都是通过这种方式。
有什么弊端呢?
一是第三方工具维护不及时、不支持flex布局、ES6等语法,二是调试不方便,三是高并发的时候会出问题,特别是生成的是高清无码的海报的时候

2.2 canvas绘制

案例: '极客时间小助手'小程序
主要实现:前端直接通过canvas生成海报
摇晃手机抽取新年签跳到第一个页面,需要绘制头像、关键字以及保存按钮,黄色的保存按钮其实就是呃一张透明的png图片,把它画上去。那在这个button上面儿需要固定一个宽高和它差不多大小的一个空的、透明的div,在这个div上加点击事件,这个事件就是调第二张要保存的那个canvas。第二张这个是没有保存按钮的但有二维码。带二维码的这张canvas放哪里呢?一种方案是定位,给一个特别大的top或left,让它不显示在屏幕里边;另一个方案是层级,预览的这张canvas在真正要保存canvas图片之上,但是会有问题。手机浏览器版本低的话,定了层级不管用,一些安卓手机也会有问题,有时候会浮上来没被盖住。
当然,如果要实现保存高清图的话,还是需要处理的,那就是放大,不过这个是笨方法。最优的方法是拆解这张图像,确保导出的canvas是最高清的,而且对用户来说也是最省流量的。
解析:进到首页其实关键字在本地就随机取完了,在首页index.js中的onShow方法中就通过wx.getStorageSync缓存了要画的元素,比如关键字(这里是图片)、关键字解析语(也是图片,毕竟微信小程序的canvas不支持字体)等等。摇一摇触发重力感应事件wx.onAccelerometerChange监听里面的事件,获取用户授权拿到头像并跳转到poster页面。直接就开始画两张图片,一张有二维码的(shakepage1),一张有button的(shakepage2),这里二维码是'死码',button也是在图片的基础上覆盖一个view,画完之后调canvasToTempFilePath保导出那张带码的,此时带码的这张通过css设置visibility: hidden隐藏起来。点击按钮触发saveImageToPhotosAlbum将导出的这张 图片保存到手机相册,这里需要授权相应的要做一些处理,比如用户拒绝授权之后再次点击需要 wx.showModal再次请用户授权。基本代码如下:(详细源码))

      wx.canvasToTempFilePath({x: 0,y: 0,width: this.data.screenWidth,height: this.data.screenHeight,destWidth: this.data.screenWidth * this.data.pixelRatio,  // pixelRatio为设备的像素比  destHeight: this.data.screenHeight * this.data.pixelRatio,canvasId: "canvasid",success: function(e) {console.log(e)this.setData({bjtempFilePath: e.tempFilePath  // 拿到要保存的图片路径}, function() {});},fail: function(e) {console.log(e);}})
  onUserSaveImageRight: function () {console.log("-click-");var _this = this;if (!wx.saveImageToPhotosAlbum) return wx.showModal({title: "提示",content: "当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。"}), void console.log("version low");wx.getSetting({success: function (res) {res.authSetting["scope.writePhotosAlbum"] ? (console.log("1-已经授权《保存图片》权限"), _this.saveimgfn()) : wx.authorize({scope: "scope.writePhotosAlbum",success: function () {console.log("用户对相册-授权成功"), _this.saveimgfn();},fail: function () {wx.showModal({title: "提示",content: "请您授权保存到系统相册",showCancel: !1,success: function (res) {res.confirm && wx.openSetting({success: function (res) {res.authSetting["scope.writePhotosAlbum"] ? setTimeout(function () {_this.saveimgfn();}, 500) : wx.showModal({title: "提示",content: "您未授权,无法将海报保存到相册,你可以截屏得到海报,或者再次点击'保存海报'按钮并授权",showCancel: !1});}});}});}});}});},saveimgfn: function () {var filePath = this.data.bjtempFilePath;console.log(filePath), filePath ? wx.saveImageToPhotosAlbum({filePath: filePath,success: function (res) {wx.showToast({title: "保存成功",icon: "success",duration: 1500});},fail: function () {wx.showToast({title: "保存失败",icon: "fail",duration: 1500});}}) : this.saveImage()

三、极客时间小程序-生成各种海报的解决方案

微信小程序canvas与HTM5的canvas对比

  1. 微信小程序canvas中层级z-index失效,小程序中canvas拥有最高级,无法二次设置;
  2. 微信小程序canvas不支持字体功能,特殊字体只能用图片代替;
  3. 微信小程序canvas不支持绘制在线图片,需要下载再绘制(安全域名的锅)
  4. 微信小程序canvas可以实现不同尺寸屏幕自适应
    var rpx;//获取屏幕宽度,获取自适应单位wx.getSystemInfo({success: function(res) {rpx = res.windowWidth/750},})// 在绘制方法中将参数乘以相对单位即可实现自适应const s = wx.createCanvasContext("canvas")s.drawImage(Url, 0, 0, 265 * rpx, 262.5 * rpx) 

如何导出高清海报、如何封装;

wx.canvasToTempFilePath({canvasId: 'image-save',x: 0,y: 0,success: res => {wx.saveImageToPhotosAlbum({filePath: res.tempFilePath,success: () => {this.setData({saving: false})utils.success('保存成功')setTimeout(() => {wx.navigateBack()}, 500)},fail: err => {this.setData({saving: false})wx.getSetting({success: res => {if(!res.authSetting || !res.authSetting['scrop.writePhotoAlbum']){wx.openSetting()}}})}})}
})

Canvas绘图在微信小程序中的应用:生成个性化海报 1相关推荐

  1. Canvas绘图在微信小程序中的应用:生成个性化海报

    Canvas绘图在微信小程序中的应用:生成个性化海报 如极客时间的一些实现案例: 基础语法 Canvas本质是一个可以使用脚本(通常为JavaScript)来绘制图形的 HTML 元素,默认大小为30 ...

  2. 微信小程序在苹果手机上生成高像素海报失败白屏

    微信小程序中需求,根据屏幕像素生成海报,安卓中正常, 大屏ios机型,比如 pro max,会出现生成的海报白屏,ios15,ios16版本都会,暂未找到解决方案,通过兼容处理,降低像素

  3. 微信小程序 api+前端实现生成分享海报

    1.先看效果图,点击分享海报按钮,然后弹出分享海报 2.前端代码 这里用的组件有vant组件库还有canvas_drawer(一个画布组件) canvas_drawer下载地址https://gith ...

  4. 如何在微信小程序中生成二维码:一个最简单的案例就让你明白

    使用weapp.qrcode.js 在 微信小程序 中,快速生成二维码 一.效果 二.具体步骤.代码 下载weapp-qrcode代码 然后 将 dist 目录下的weapp.qrcode.esm.j ...

  5. 在H5、微信小程序中使用canvas绘制二维码、分享海报

    在H5.微信小程序中使用canvas绘制二维码.分享海报 文章目录 在H5.微信小程序中使用canvas绘制二维码.分享海报 前言 一.canvas绘制二维码 1.H5中使用canvas 2.微信小程 ...

  6. Canvas 动画引擎解析与微信小程序中的应用

    点击观看大咖分享 抗击疫情,腾讯云在行动.在开发微信小程序的过程中,我们经常需要展现一些图形和图表.目前市面上有好几款常用的图形库,在这些图形库的底层都有渲染引擎在支撑. ZRender 是其中一款非 ...

  7. 微信小程序setinterval_微信小程序中setInterval的使用方法

    微信小程序中setinterval的使用方法 看了下小程序的画布功能,简单的使用了一下,用蹩脚的逻辑做了个 "弹啊弹,弹走鱼尾纹的小球",一起来看下吧.过程不重要主要是画布的使用哦 ...

  8. 在微信小程序中绘制图表(part2)

    本期大纲 1.确定纵坐标的范围并绘制 2.根据真实数据绘制折线 相关阅读: 在微信小程序中绘制图表(part1) 在微信小程序中绘制图表(part3) 关注我的 github 项目 查看完整代码. 确 ...

  9. 微信小程序中绘制图表 (AntV F2 的使用)

    1.安装小程序F2组件 npm i @antv/f2-canvas 2.安装好相关依赖包之后,使用微信开发者工具运行项目,点击开发者工具顶部详情,勾选 使用npm模块,再点击菜单栏中工具下的构建npm ...

最新文章

  1. Paper1:HoPE: Horizontal Plane Extractor for Cluttered
  2. 机器学习_周志华_问题汇总_第1周
  3. 排除问题的时候不要随意修改系统筛选数据的逻辑
  4. 如何读取服务器的文件夹大小,请教如何获取outlook文件夹对话框中服务器数据大小?...
  5. linux命令:userdel
  6. 【Linux内核】虚拟地址空间布局架构
  7. 自定义的全局公共样式
  8. ECCV 2020 论文大盘点-自动驾驶篇
  9. 计算机工程与应用3天外审,200629计算机工程与应用.pdf
  10. Linux中main和初启函数,main 中的 argv和argc 到底是个啥意思?
  11. resiprocate之message
  12. 【转】elasticsearch的查询器query与过滤器filter的区别
  13. 技术人成长路径之我见
  14. 菜鸟网络后端java 一面总结
  15. 缉拿IP冲突之后的“真凶”
  16. 2021年R2移动式压力容器充装报名考试及R2移动式压力容器充装操作证考试
  17. 马王堆汉墓帛书‧老子——甲本释文(德经)
  18. 2021-10-01
  19. 深入浅出聊聊Java函数式编程思想
  20. HTML之 <p></p>标签 笔记

热门文章

  1. 原来QQ聊天记还能这样找回!学会之后再也不用担心删除了
  2. python在windows环境使用打印机
  3. 51单片机 LED点亮、闪烁以及流水灯实现
  4. 20230116测试
  5. 再送出10套机械键盘
  6. perl链接数据库实例
  7. JS中的$().each
  8. 分布式系统阅读笔记(十八)-----副本备份技术
  9. hdu 2955 01背包
  10. empty: false 关于这个问题的解决