小程序利用canvas 绘制图案 (生成海报, 生成有特色的头像)

337 阅读3分钟

小程序利用canvas 绘制图案 (生成海报, 生成有特色的头像)

微信小程序生成特色头像,海报等是比较常见的。下面我来介绍下实现该类小程序的过程。

  1. 首先选择前端来通过 canvas 绘制。这样比较节省成本,效率也高。
  2. 小程序使用uniapp 来进行开发,方便后期打包为微信,百度等小程序。
  3. 可以扫码体验下 我的小程序 制作个性化的头像, 制作头像小程序
  4. 下面介绍使用 wxml2canvas 生成头像的小程序的制作过程

创建项目

  1. 使用HBuilderX 创建一个 uni-app 的项目,可以参照uniapp 官网。
  2. 下载项目使用的依赖 npm init 创建package.json
  3. yarn add less wxml2canvas

生成头像的重要步骤

  1. 首先思路是上传一张自己想做为头像的图片
  2. 然后选择自己想给该图片添加的元素,利用css 定位,使图片位置重叠,产生新的效果
  3. 讲最新的效果生成图片,并下载。

上传图片

上传图片可以提供两种思路,一种是直接使用微信头像。一种是用户自己上传图片

  1. 使用微信头像的方案
wxLogin() {
  let _this  = this;
  wx.getUserProfile({
    desc: '获取你的头像',
    success: res => {
      console.log(res)
      _this.headUrl = res.userInfo.avatarUrl
    },
    fail: () => {
      //拒绝授权
      wx.showToast({
        title: '您拒绝了请求,不能获取你的头像',
        icon: 'error',
        duration: 2000
      });
      return;
    }
  });
},
  1. 用户自己上传图片,可以直接从相册中选择,也可以使用相机。
pictureClick (selectid) {
  const _this = this;
  let typelist = selectid === 1 ? ['camera'] : ['album']
  uni.chooseImage({
      count: 1,
      sourceType: typelist, //这要注意,camera掉拍照,album是打开手机相册
      crop: {
        width: 320,
        height: 320
      },
      success: (res)=> {
          _this.$refs.gmyImgCropper.chooseImage(res)
      }
  });
},
  1. 自己上传的图片,需要使用canvas 来进行裁剪为头像比列相同的图片
<imgCropper ref="gmyImgCropper" :quality="1" cropperType="fixed" :imgSrc="headUrl" @getImg="getImg"></imgCropper>
// 上面 是裁剪图片的组件, 篇幅较大,可以参考项目源码

利用css 定位生成效果图

<view class="head-box" :style="{marginTop: headboxStyle, height: showImgW}">
  <canvas canvas-id="myCanvas" class="myCanvas" :style="{width: showImgW, height: showImgW}"></canvas>
  <view  class="showimg showimg-box head-img-border" :style="{width: showImgW, height: showImgW}">
    <pickerselect  @modelselect="modelselect">
      <view class="showimg normalimgbox" :style="{width: showImgW, height: showImgW, background: currentInfo.iconColor}">
        <image class="headimg normalimg"  src="https://bj.bcebos.com/txy-dev/txy/main/normal.png"/>
      </view>
      <view id="my-canvas" class="my_canvas">
        
        <view class="showimg" :style="{width: showImgW, height: showImgW}">
          <image mode="aspectFill " data-type="image" :data-url="headUrl"  class="headimg my_draw_canvas" :src="headUrl"/>
        </view>
        <view class="showimg" :style="{width: showImgW, height: showImgW}">
          <image mode="heightFix" data-type="image" :data-url="selectimg" class="headimg my_draw_canvas" :src="selectimg"/>
        </view>
      </view>
    </pickerselect>
  </view>
</view>

利用wxml2canvas 生成最终的头像图片

import Wxml2Canvas from 'wxml2canvas'
export const startDraw = ()=> {
  let that = this
  // 创建wxml2canvas对象
  let drawMyImage = new Wxml2Canvas({
    element: 'myCanvas', // canvas的id,
    obj: that, // 传入当前组件的this
    width: 200* 2,
    height: 200 * 2,
    background: '#141415', // 生成图片的背景色
    progress(percent) { // 进度
      console.log(percent);
    },
    finish(url) { // 生成的图片
      wx.hideLoading()
      savePoster(url)
    },
    error(res) { // 失败原因
      console.log(res);
      wx.hideLoading()
    }
  }, this);
  let data = {
      // 获取wxml数据
      list: [{
          type: 'wxml',
          class: '.my_canvas .my_draw_canvas',  // my_canvas要绘制的wxml元素根类名, my_draw_canvas单个元素的类名(所有要绘制的单个元素都要添加该类名)
          limit: '.my_canvas', // 要绘制的wxml元素根类名
          x: 0,
          y: 0
      }]
  }
  // 绘制canvas
  drawMyImage.draw(data, this);
}
export const drawMyCanvas = () => {
  wx.showLoading()
  const that = this
  wx.createSelectorQuery()
    .select('#my-canvas') // 在 WXML 中填入的 id
    .fields({ scrollOffset: true, size: true }, () => {
      startDraw()
    }).exec(() => {
      console.log(888)
    })
} 

将生成的图片下载到本地

export const savePoster = (url) => {
  const that = this
  wx.saveImageToPhotosAlbum({
    filePath: url,
    success: function() {
        wx.showToast({
            title: '保存成功',
            icon: 'none',
            duration: 1500
        });
    },
    fail(err) {
      if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg === "saveImageToPhotosAlbum:fail authorize no response") {
        wx.showModal({
          title: '提示',
          content: '需要您授权保存相册',
          showCancel: false,
          success: modalSuccess => {
            wx.openSetting({
              success(settingdata) {
                if (settingdata.authSetting['scope.writePhotosAlbum']) {
                    wx.saveImageToPhotosAlbum({
                        filePath: url,
                        success: function () {
                          wx.showToast({
                            title: '保存成功',
                            icon: 'success',
                            duration: 2000
                          })
                        },
                    })
                } else {
                    wx.showToast({
                        title: '授权失败,请稍后重新获取',
                        icon: 'none',
                        duration: 1500
                    });
                }
              }
            })
          }
        })
      }
    }
  })
}

下面是利用canvas 做的小应用,敲字不易,辛苦扫描体验,让我们共同进步

制作头像小程序

[项目代码] gitee.com/eyes-star/t…