小程序自学之路--canvas生成弹幕海报

前言

  • 前段时间完成了初版的可配置装盘后,就在考虑下一个迭代的内容选什么好呢?想到微信小程序的优势除了无需下载且接近原生的体验,还能依靠微信巨大的用户群体,更容易链接转换成小程序用户。为了更好地转化用户那怎么能少了分享功能。

  • 分享主要有两种方式:一种是分享给朋友,微信的按钮组件有对应的api,这里就不做分享了,有疑问的可以查看index页源码;另一种是分享朋友圈,微信并没有分享朋友圈api,只能曲线救国,生成一些有意思的海报,引导用户发朋友圈。

  • 这篇文章主要是介绍使用canvas生成海报的实现过程。

  • 作者能力有限,可能会有所缺漏或者部分错误,欢迎读者指出。

  • 代码已在github开源:https://github.com/Spute/fun-turntable/tree/main

  • 可扫码试用小程序,查看效果:

需求分析

  • 先看原型,海报由以下三部分组成
    • 大小随机,转盘选项内容随机的弹幕背景
    • 位于中上部分的转盘标题
    • 位于中下方的小程序二维码

image.png

需求实现

  1. 弹幕背景:首先获取转盘选项列表(放在app data中),通过随机函数选择其中一个选项,随机字体大小,然后循环逐行打印。
  2. 转盘标题: 获取转盘标题,逐字换行显示。
  3. 小程序二维码:将二维码图片转换成base64编码的字符,写入到代码中,然后使用canvas绘制。使用base64格式会比存储png格式图片占用更少空间,且比使用网络请求获取图片的响应速度更快。

踩过的坑

版本问题

  • 该项目用的基础库是2.19.4,是改版后的canvas api。百度出来的绝大部分都是采用CanvasContext实现,这是基础库 2.7.0 之前的实现方式,是旧的实现方式。改版后的API接口变化很大,对于新手很难参照旧的api实现方式使用新的api重写实现。
  • 基础库 2.7.0 开始支持新版 [Canvas 2D]接口,与 Web一致,但官方文档没有具体的解释。所以我先在菜鸟教程学习基础的知识,用HTML canvas API绘画海报图,然后在微信小程序实现一遍(只需做一下适配,大部分不用变更)。

保存canvas图片失败:canvasToTempFilePath: fail canvas is empty?

  • 为了保存canvas图片需要使用wx.canvasToTempFilePath方法实现,指定canvas导出成图片,方法返回tempFilePath,即生成文件的临时路径(本地路径)
    ,格式如:http://tmp/KaUKCLOwnjRSf1bfc8c77b0ea04af287026bc62a5420.png
  • 开始我是通过传入canvasId参数指定canvas,运行后提示canvasToTempFilePath: fail canvas is empty?表示未找到相应的canvas。查看canvas组件官方文档canvs-id是canvas组件的唯一标识符,若指定了type则无需再指定该属性,刚好我又指定了type,所以怀疑是canvas-id与type冲突导致的。最后通过传递canvas对象解决了这个问题。代码如下:
    wx.canvasToTempFilePath({
      // canvasId: 'posterCanvas',
      canvas: canvas,
      success: function (res) {
        var tempFilePath = res.tempFilePath;
        console.log("res", res)
        pageObj.data.imagePath = tempFilePath;
      },
      fail: function (res) {
        console.log(res);
      }
    }, pageObj);
  • 顺便再吐槽一下官方文档,介绍的太少了,很多东西看的云里雾里。这都是啥描述,draw()方法是什么鬼,用了有问题不用反而可以。
    image.png

image.png

保存的海报二维码缺失

  • 因为image.onload图片加载完成后触发的回调函数,是个异步操作。保存图片时,回调函数的二维码绘制逻辑还未执行完成,导致保存的海报二维码缺失。
  • 解决方案:为了保证保存canvas图片逻辑在二维码绘制逻辑之后执行,将保存图片逻辑也放到回调函数执行。
  drawQRCode(canvas, ctx, endHieght, pageObj) {

    var image = canvas.createImage();
    const qrCodeBase64 = unit.imageData().qrCodeBase64
    image.src = "data:image/png;base64," + qrCodeBase64

    const imgWidth = 200,
      imgHeight = 200;

    // 图片加载完成后触发的回调函数
    image.onload = function () {
      //定位图像(左上角坐标),并规定图像的宽度和高度
      ctx.drawImage(image, canvas.width / 2 - imgWidth / 2, (canvas.height + endHieght) / 2 - imgHeight / 2, imgWidth, imgHeight);
      // canvas保存为图片
      pageObj.saveCanvasToFile(canvas, pageObj)
    };

  },

结束语

  • 在如今知识大爆炸时代,强大的搜索引擎让寻找答案变得简单,但前提是你能够提出一个‘好’问题(需要知识图谱帮助我们定位问题),否则你只会迷失在海量的数据中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值