资讯专栏INFORMATION COLUMN

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

vpants / 1628人阅读

摘要:解析进到首页其实关键字在本地就随机取完了,在首页中的方法中就通过缓存了要画的元素,比如关键字这里是图片关键字解析语也是图片毕竟微信小程序的不支持字体等等。

一、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做成的,上面画了二维码,二维码是一个数组两个或循环嵌套画小黑点用户识别这个二维码之后就进入他的程序,经过程序跑出来的测试结果啊什么的,点保存的时候,就会生成一张个性海报明白。怎么生成这种个性化海报呢?

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对比

微信小程序canvas中层级z-index失效,小程序中canvas拥有最高级,无法二次设置;

微信小程序canvas不支持字体功能,特殊字体只能用图片代替;

微信小程序canvas不支持绘制在线图片,需要下载再绘制(安全域名的锅)

微信小程序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()
               }
             }
           })
         }
       })
    }
})

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98072.html

相关文章

  • 信小程序 海报生成踩坑记

    摘要:最近有个需求是要生成分享海报,让用户可以将图片保存到本地然后分享到朋友圈。本来以为是一个很简单的需求,可是万万没想到,微信会这么坑。 最近有个需求是要生成分享海报,让用户可以将图片保存到本地然后分享到朋友圈。本来以为是一个很简单的需求,可是万万没想到,微信会这么坑。刚开始的思路是这样的: 后台根据小程序传过来的参数获取对应的小程序码,然后与背景图合成之后将base64格式的图片传给小程...

    lidashuang 评论0 收藏0
  • 在微信小程序中绘制图表(part1)

    摘要:微信小程序中提供了的支持,利用自行绘制图表。关注我的项目查看完整代码。 微信小程序中图表现状 由于微信小程序本身框架的限制,很难集成目前已有的图表工具,显示图表目前有两种方案:1、服务器端渲染图表,输出图片,微信小程序中直接显示渲染好的图片,比如highcharts提供了服务端渲染的能力hightcharts server render,这种方式需要后台有一套渲染服务,并且有一定的网络...

    chaosx110 评论0 收藏0
  • 程序如何生成海报分享朋友圈

    摘要:项目需求写完有一段时间了,但是还是想回过来总结一下,一是对项目的回顾优化等,二是对坑的地方做个记录,避免以后遇到类似的问题。需求利用微信强大的社交能力通过小程序达到裂变的目的,拉取新用户。摘要: 小程序开发必备技能啊... 原文:小程序如何生成海报分享朋友圈 作者:小白 Fundebug经授权转载,版权归原作者所有。 项目需求写完有一段时间了,但是还是想回过来总结一下,一是对项目的回顾优...

    lemon 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<