【微信小程序】canvas绘制海报插件(圆形头像,圆角图片,渐变圆角矩形,单行文本,多行文本,绘制base64图片)

canvas绘制海报插件

其功能包括

1. 绘制圆形头像
2. 绘制圆角矩形
3. 绘制单行文本
4. 绘制多行文本
5. 绘制base64图片
复制代码

像日常开发页面通常,根据设计稿标注传入rpx单位的数字就行git

使用方法

  1. const drawD = require('../../utils/canvasDraw.js');
  2. let draw = new drawD.canvasDraw('shareImg', that); // 参数为canvas-id , 和当前this对象
  3. draw.XXX 能够调用API中的方法,支持链式调用

注:为保证绘制出来的图片清晰,宽度和高度分别进行了2倍放大

data: {
    width: app.globalData.windowWidth * 2, // canvas 大小    
    height: app.globalData.windowHeight * 2,
  },
复制代码

插件地址       API 地址github

demo1源码canvas


demo2源码数组

因为canvas不能处理网络图片,因此要先拿到图片的临时路径, getImagesInfo(imgArr) 传入一个图片字符串数组,调用wx.getImageInfo方法,返回图片的临时路径及宽高等信息bash

注: 微信头像要使用wx.downloadFile来获取来获取临时路径,并配置域名白名单微信

let that = this;
let draw = new drawD.canvasDraw('shareImg', that);  // canvas-id  和当前this对象
复制代码

功能1: 绘制圆形头像

// x 坐标, y 坐标,  圆半径, 图片路径
draw.drawCricleImg(50, 50, 35, logo)
复制代码

注:x, y, 半径根据设计稿标注的大小传入数字就能够,当设计宽度为750px时

例如: 设计稿中头像距离左边50px,上边50px, 开发页面的时候写的样式就是50rpx, 这里直接传入50就好

原理:网络

this.ctx.arc(centerX, centerY, r, 0, 2 * Math.PI, false)//画一个圆形裁剪区域
this.ctx.clip()//裁剪
this.ctx.drawImage(logo, x, y, w, w)//绘制图片
复制代码

功能2: 绘制圆角图片

方法1:app

// img, sx, sy, swidth, sheight, x, y, width, height的用法用于drawImage(img, sx, sy, swidth, sheight, x, y, width, height)
// r 圆角半径
// bgColor 背景色
draw.drawFilletImg(img, sx, sy, swidth, sheight, x, y, width, height, r, bgColor = '#fff')
复制代码

方法2:xss

// img, x, y, width, height的用法用于drawImage(img, x, y, width, height)
// r 圆角半径
// bgColor 背景色
draw.drawFilletFillImg(img, x, y, width, height, r, bgColor = '#fff')
复制代码

: swidth, sheight, width, height 传入的值为字符串 例如: '650px' 或 '650rpx'

sx, sy, x, y 单位均是rpxide

原理:

左右两种圆角的部分, 左边是用背景色绘制了四个圆角,右边是用黑色绘制了四个圆角
绘制四个角的方法参考canvasDraw.js中的 roundRect(x, y, w, h, r, c) 方法

功能3: 单行文本

draw.drawText(str, x, y, fontSize, color, align = 'left')

注:x, y, fontSize根据设计稿标注的大小传入数字,单位为rpx

原理:

ctx.setFontSize(fontSize)
ctx.setTextAlign(align);
ctx.setFillStyle(color)
ctx.fillText(str, x, y);
复制代码

功能4: 多行文本

// 文本, x坐标,y坐标,文本最大宽度, 字体大小,最多显示几行, 颜色,对齐方法,末尾占位符
drawMultiLineText(str, x, y, width, fontSize, maxRow, color = '#000', align = 'left', suffixStr = '...')
#### 注:x, y, width, fontSize根据设计稿标注的大小传入数字,单位为rpx

例如:
drawMultiLineText(activityContent, 50, draw.nowHeight + 20, 650, 26, 3, '#666666')
复制代码

注:draw.nowHeight (rpx) 能够得到当前绘制的最后一个元素的左下角坐标,至关于已绘制的canvas高度
那绘制下一个元素y坐标为: draw.nowHeight + (距上一个元素的距离)

功能5: 绘制base64图片

draw.drawCode(base64Str) 调用此方法能够生成一个图片的临时路径
复制代码

例如:

draw.drawCode(base64Str).then((filePath) => {
    ctx.drawImage(filePath, x, y);
});
复制代码

功能6. drawFinally(callback)

绘制函数,会执行draw()方法,并执行回调,回调中能够调用canvasToPosterImg(destWidth, canvasHeight, callback)将canvas转为图片

功能7. canvasToPosterImg(destWidth, canvasHeight, callback)

// destWidth 生成图片,图片的目标宽度,单位为px
// canvasHeight canvas的高度,单位为px
draw.canvasToPosterImg(destWidth, canvasHeight, callback)
复制代码



功能8. drawFilletFillRect(x, y, width, height, r, isGrd, drawColor, bgColor = '#fff') 绘制渐变圆角矩形

// 用法同绘制圆角图片
isGrd true | false   是否渐变
drawColor Array    绘制矩形颜色数组,  渐变时数组传两个值,不渐变传一个值
复制代码



demo1的代码片断

js

// pages/drawPosterTest.js
const drawD = require('../../utils/canvasDraw.js');
const app = getApp();
Page({

  /**
   * 页面的初始数据
   */
  data: {
    width: wx.getSystemInfoSync().windowWidth * 2,
    height: wx.getSystemInfoSync().windowHeight * 2,
    imageWidth: 0,
    imageHeight: 0
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    let that = this;
    let draw = new drawD.canvasDraw('poster', that);
    let logo = 'https://avatars0.githubusercontent.com/u/34326830?s=400&u=2e69fbfaf577e896d414788c869e265e0d449a1b&v=4';
    let themeImg = 'https://orangleli.github.io/imagesResources/1.jpg';
    draw.getImagesInfo([themeImg, logo]).then((res) => {
      themeImg = res[0].path;
      logo = res[1].path;
      that.setData({
        imageWidth: res[0].width,
        imageHeight: res[0].height
      });
      that.drawShareImage(draw, themeImg, logo);
    })
  },
  drawShareImage(draw, themeImg, logo){
    let that = this; let drawHeight = 0;
    let x = 0, y = 0;
    let imageWidth = that.data.imageWidth;
    let imageHeight = that.data.imageHeight;

    drawHeight = (650 / imageWidth) * imageHeight;

    let part = '你身体里的每个原子都来自一颗爆炸了的恒星。造成你左手的原子可能和造成你右手的来自不一样的恒星。这是我所知的关于物理的最有诗意的事情:大家都是星尘。'

    draw
      .drawFilletFillImg(themeImg, 50, 50, 650, drawHeight, 10)
      .drawMultiLineText(part, 50, draw.nowHeight + 30, 650, 30, 0, '#000')
      .drawMultiLineText(part, 50, draw.nowHeight + 40, 650, 30, 1, '#000')
      .drawText('——《这里是出处》', 650 + 50, draw.nowHeight + 60, 30, '#000', 'right')
      .drawText('2019.09.06', 650 + 50, draw.nowHeight + 30, 32, 'rgba(34,34,34,.64)', 'right')
      .drawCricleImg(650, draw.nowHeight + 10, 25, logo)
      .drawFinally(function (ctx, nowHeight) {
        let canvasHeight = draw.getPx(nowHeight + 30);
        that.setData({
          height: canvasHeight
        })
        draw.drawEndImg(750, canvasHeight, function(res) {
          wx.hideLoading();
          that.setData({
            endImg: res.tempFilePath,
            isFinished: true
          })
        });
      });
  },
})
复制代码

wxml

<canvas class="posterCanvas offScreen" style="width: {{width}}px;height:{{height}}px;" canvas-id="poster"></canvas>
<image class="poster" src="{{endImg}}" mode='widthFix'></image>
复制代码

wxss

.posterCanvas{
  background-color: #fff;
}
.offScreen{
  position: fixed;
  top: -99999px;
  left: -99999px;
}
.posterCanvas{
  width: 100%;
}
.poster{
  width: 100%;
  background-color: #fff;
}
复制代码

说明:

  1. 此demo1绘制的图片为透明背景色, 能够自行绘制图片背景或者纯色背景
  2. demo2中有绘制背景色的代码:drawPoster/drawPoster.js/changeBgToWhite()
  3. 先设置背景色,再进行绘制的方法,会影响圆形头像的绘制,能够本身试一下

图片保存到相册

demo2中有完整实例

点击保存图片,当wx.saveImageToPhotosAlbum方法进入fail时: that.setData({ toAuthorize: true })
显示自定义组件弹框 components/authorizeModal/authorizeModal

这个弹框样式有些丑,emmm...

wx.saveImageToPhotosAlbum({
    filePath: that.data.endImg,
    success: function (re) {
      wx.showToast({
        title: '保存成功',
      });
      that.closeShareModal();
    },
    fail: function (err) {
      console.log(err)
      if (err.errMsg == "saveImageToPhotosAlbum:fail auth deny" || err.errMsg === "saveImageToPhotosAlbum:fail:auth denied") {
        console.log("打开设置窗口");
        that.setData({
          toAuthorize: true
        })
      }
    }
    })
复制代码
<button open-type="openSetting">
复制代码

点击 去受权 按钮 打开受权列表页,此按钮绑定toAuthorizeClick点击事件,隐藏自定义组件弹框authorizeModal

最后:

插件地址       API 地址

demo1源码


demo2源码

结束 🎉🎉

相关文章
相关标签/搜索