微信小程序2D canvas绘制分享海报

2021-07-26  本文已影响0人  小李不小
id:true 是否返回节点 id
node:true 是否返回节点对应的 Node 实例
size:true 是否返回节点尺寸(width height)
  onReady(){
    const query = wx.createSelectorQuery()
    query.select('#canvas_box')
    .fields({
      id: true,
      node: true,
      size: true
    })
    .exec(this.init.bind(this))
   
  },
wx.createSelectorQuery()

返回一个 SelectorQuery 对象实例。在自定义组件或包含自定义组件的页面中,应使用 this.createSelectorQuery() 来代替。

全部代码
wxml

<canvas
  type="2d"
  id="canvas_box"
  style="width:260px;height:420px "
></canvas>


<button class='bottom' catchtap="bc" canvas-id="mycanvas"> 保存到相册    </button>

js

const app = getApp()

Page({
  data: {
    resqrCodeUrl:"https://tmawx.shenzhenair.com/Shwxcharfile/ts/oEy5O5Xdz-aSL5TUV89AFBwsYdsk/oEy5O5Xdz-aSL5TUV89AFBwsYdsk.jpeg", //二维码
    CodeUrlbg:'https://tmawx.shenzhenair.com/Shwxcharfile/ts/app/img_invite_privilege.png',//背景图片
     destMinWidth: 690, //背景宽度
    maxHeight: 995,//背景高度
    destMul: 2,   //画布写出倍数
  },
 

  //init函数 通过 Canvas.getContext('2d') 接口可以获取 CanvasRenderingContext2D 对象,实现了 [HTML Canvas 2D Context](https://www.w3.org/TR/2dcontext/) 定义的属性、方法。

  init(res) {
    console.log('init----',res)
    const canvas = res[0].node
    const ctx = canvas.getContext('2d')
    const dpr = wx.getSystemInfoSync().pixelRatio;//获取屏幕的像素比  值为2

     //新接口需显示设置画布宽高; w*2 h*2
     canvas.width = res[0].width * dpr;
     canvas.height = res[0].height * dpr;
     ctx.scale(dpr, dpr); //缩放

     this.setData({
      canvas,
      ctx
    });


  //渲染bg图片和二维码还有文字,必须按照顺序来,先渲染背景,再渲染logo,最后渲染文字,如果顺序不统一,logo先渲染,就会导致背景图片加载不出来。

  //向画布载入图片的方法
  this.canvasDraw(ctx,canvas).then(res=>{
    console.log('1',res)
      // 向画布载入logo的方法
    return this.code(ctx)
  }).then(rrr=>{
    console.log('2',rrr)
    //图片头像渲染完成之后,渲染文字
    this.title(ctx)
  })

  },


  // 封面图  使用 pormise方法来输出 代码执行成功,返回一个成功标识出去
  canvasDraw(ctx,canvas) {
    return new Promise(res=>{
      let img = this.data.canvas.createImage(); //创建img对象
      img.src =this.data.CodeUrlbg;
      img.onload = () => {
        console.log(img.complete); //true
        this.data.ctx.drawImage(img, 0, 0,260, 430);
          setTimeout(() => {
            res(true)
          }, 100);
      };  
    })

},

  // 头像 使用 pormise方法来输出 代码执行成功,返回一个成功标识出去
  code(ctx) {
    const that=this;
    return new Promise(rrr=>{
      let code = this.data.canvas.createImage(); //创建img对象
      code.onload = () => {
        this.data.ctx.drawImage(code, 75,20, 105, 110);
      };
      code.src =this.data.resqrCodeUrl;
      setTimeout(() => {
        rrr(true)
      }, 100);
    })
  },

//文字模块,不使用pormise,因为他是最后模块,所有不需要了
  title(ctx) {
    let text = '接小程序开发,web开发,H5开发,小程序云开发,PHP开发'
    let moy =  '有需要的直接微信扫码'
    ctx.font = 'normal bold 12px sans-serif';
    ctx.fillStyle = "rgba(60, 59, 59)";
    console.log('======,', text.length)


      let firstLine = text.substring(0, 20); //文字切割方法
      let secondLine = text.substring(20, 38);
      ctx.fillText(firstLine, 10, 275, 280)
      ctx.fillText(secondLine, 10, 290, 280)
      ctx.fillStyle = "rgba(0,0,0)";//添加颜色
      ctx.font = 'normal bold 16px sans-serif';//指定文字样式
      ctx.fillStyle = "red"; //新增样式
      ctx.fillText(moy, 10, 315, 280) //    ctx.fillText(文字, 像素, 移动y, 移动x) 
    
  },

  bc() {
    // 保存到相册
    console.log('保存canvasId',this.data.canvas._canvasId)
    wx.canvasToTempFilePath({     //将canvas生成图片
      canvas:this.data.canvas,
      x: 0,
      y: 0,
      width: 690,
      height: 995,
      destWidth: 690*2,     //截取canvas的宽度
      destHeight:995*2,   //截取canvas的高度
      success: function (res) {
        console.log('生成图片成功:',res)
        wx.saveImageToPhotosAlbum({  //保存图片到相册
          filePath: res.tempFilePath,
          success: function (res) {
            wx.showToast({
              title: "保存图片成功!",
              duration: 2000
            })
          }
        })
 
      },
    },this)
  
  },
onShow(){
 
},
  onLoad: function () {
   
  },
  onReady(){
    const query = wx.createSelectorQuery()
    query.select('#canvas_box')
    .fields({
      id: true,
      node: true,
      size: true
    })
    .exec(this.init.bind(this))
   
  },
})

结果

logo模块是logo图片
背后花花的是背景图片
文字为最后

image.png
上一篇 下一篇

猜你喜欢

热点阅读