小程序绘制海报

发布时间 2023-12-14 15:53:13作者: 张玮h5

html canvas api

https://blog.csdn.net/web220507/article/details/124925691

https://www.jianshu.com/p/b869580ff48b

小程序绘制海报

https://zhuanlan.zhihu.com/p/603629548?utm_id=0

https://codeleading.com/article/38663680885/

绘制图片

        
  // 图片对象
const image = canvas.createImage()
// 图片加载完成回调
image.onload = () => {
    // 将图片绘制到 canvas 上
    ctx.drawImage(image,50,50,50,50, 0, 0,100,200)
}
// 设置图片src
image.src = 'https://img0.baidu.com/it/u=1302187753,1022585962&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1699376400&t=8e1590a6a32b9a6746e054af95e34fb8'

https://mp.weixin.qq.com/s?__biz=MjM5MDA2MTI1MA==&mid=2649093263&idx=1&sn=48009508cd3bad0cc417cbfe259b5152&chksm=be5bd322892c5a34986ac924bd6ee9ddd88f4f6e4bc9ec0b6dc0221116944787e28a6db9e2a0&scene=27

http://doofuu.com/article/4156180.html&wd=&eqid=91a2ebf500004a4b0000000664658446

什么是离屏canvas https://blog.csdn.net/zdluoa/article/details/80598326

离屏canvas分享海报: https://blog.csdn.net/qq_41261218/article/details/133958064

生成二维码的插件 weapp-qrcode

https://gitcode.com/mirrors/yingye/weapp-qrcode/overview?utm_source=csdn_github_accelerator

https://blog.csdn.net/qq_56835359/article/details/131443331

小程序新版canvas

Canvas-2d

https://developers.weixin.qq.com/miniprogram/dev/component/canvas.html

weapp-qrcode-canvas-2d 新的canvas生成二维码

https://developers.weixin.qq.com/community/develop/article/doc/000e88e73a415835ed9b46d7956013

https://gitee.com/WeiDoctor/weapp-qrcode-canvas-2d

//---1--- 引入生成二维码的插件
import drawQrcode from 'weapp-qrcode-canvas-2d'


//---2--- 使用插件生成二维码

// 创建离屏 2D canvas 实例 
const canvas = wx.createOffscreenCanvas({type: '2d', width: 300, height: 150}) 
// 使用插件生成二维码
drawQrcode({
  canvas: canvas,
  canvasId: 'myQrcode',
  width: 260,
  padding: 30,
  background: '#ffffff',
  foreground: '#000000',
  text: 'abc',
})
//--- 将二维码 canvas 专为二维码图片地址,本可以使用canvasToTempFilePath 但是 在真机测试的时候 报错 所以改为下面的方式
let base64 = canvas.toDataURL();
const time = new Date().getTime();
const imgPath = wx.env.USER_DATA_PATH + "/poster" + time + "share" + ".png";
//如果图片字符串不含要清空的前缀,可以不执行下行代码.
const imageData = base64.replace(/^data:image\/\w+;base64,/, "");
const fs = wx.getFileSystemManager();
fs.writeFileSync(imgPath, imageData, "base64");
fs.close()

// 二维码图片的临时地址
this.setData({
  qrcodeUrl:imgPath
})

wxml-to-canvas

https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/extended/component-plus/wxml-to-canvas.html

使用规则

https://developers.weixin.qq.com/community/develop/article/doc/00040e7a6140f83f904e8468251813

https://developers.weixin.qq.com/community/develop/article/doc/000204eb9f80386c1f80bf25966413

https://developers.weixin.qq.com/community/develop/article/doc/000ac686c5c5506f18b87ee825b013

canvasToTempFilePath在iOS 真机调试时报错 fail invalid viewId

https://developers.weixin.qq.com/community/develop/article/doc/000ce88f738e781b23609445961c13

demo 使用wxml-to-canvas 绘制canvas

生成二维码的插件

npm i weapp-qrcode-canvas-2d

​ 使用wxml-to-canvas

npm install --save wxml-to-canvas
{
  "usingComponents": {
    "wxml-to-canvas": "wxml-to-canvas",
  }
}


//生成二维码的插件
import drawQrcode from 'weapp-qrcode-canvas-2d'
//wxml-to-canvas的 绘制canvas的样式
const style = {
  container: {
    textAlign:'center',
    width: 300,
    height: 475,
    //------ 可以使用flex布局
    //     flexDirection: 'row',
		//     justifyContent: 'space-around',
		//     backgroundColor: '#ccc',
		//     alignItems: 'center',
  },
  imgbg:{//背景图片 图片和文字都要设置宽高值
    width: 300,
    height: 475,
    position:'absolute',
    top:0,
    left:0
  },
  contentBox:{
    backgroundColor:'#ff0',
    height:100,
    width:200,
    borderWidth:5
  },
  titleText:{//图片和文字都要设置宽高值
    height:100,
    width:200,
    color:'#000',
    fontSize:20,
    textAlign: 'left',
    verticalAlign: 'middle',
  },
  imgBox:{
    position:'absolute',
    top:0,
    left:0,
    height:90,
    width:190,

  },
  shareText:{//图片和文字都要设置宽高值
    height:90,
    width:190,
    color:"#ff0" ,
    fontSize:30
  },
  qrcode:{ //图片和文字都要设置宽高值
    width:200,
    height:200
  }
}

Page({
  data: {
    isShowMasker:false,//是否显示遮罩
    qrcodeUrl:'',//二维码图片地址
  },
  renderToCanvas() {
    this.widget = this.selectComponent('.widget')

         // 创建离屏 2D canvas 实例 
        const canvas = wx.createOffscreenCanvas({type: '2d', width: 300, height: 150}) 
        // 使用插件生成二维码
        drawQrcode({
            canvas: canvas,
            canvasId: 'myQrcode',
            width: 260,
            padding: 30,
            background: '#ffffff',
            foreground: '#000000',
            text: 'abc',
        })
        //--- 将二维码 canvas 专为二维码图片地址,本可以使用canvasToTempFilePath 但是 在真机测试的时候 报错 所以改为下面的方式
        let base64 = canvas.toDataURL();
        const time = new Date().getTime();
        const imgPath = wx.env.USER_DATA_PATH + "/poster" + time + "share" + ".png";
        //如果图片字符串不含要清空的前缀,可以不执行下行代码.
        const imageData = base64.replace(/^data:image\/\w+;base64,/, "");
        const fs = wx.getFileSystemManager();
        fs.writeFileSync(imgPath, imageData, "base64");
        fs.close()

        // 二维码图片的临时地址
        this.setData({
          qrcodeUrl:imgPath
        })
      


        // --------canvas的模版    
        const wxml = `
        <view class="container" >
        <image class="imgbg" src="https://picnew13.photophoto.cn/20190310/daqichuangyijihetuxingxiacuxiaohaibao-33122220_1.jpg"></image>
        <view class="content-box">
        <image class="img-box" src="https://img0.baidu.com/it/u=925843206,3288141497&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=769"></image>
              <text class="title-text">你的好友:66 邀请您来观看</text>
         </view>
         <text class="share-text">分享二维码</text>
         <image class="qrcode"  src="${this.data.qrcodeUrl}"></image>
        </view>
        `
        // 渲染canvas
        const p1 = this.widget.renderToCanvas({ wxml, style })
        p1.then((res) => {
          // console.log('container****', res)
          this.container = res
        }).catch(err=>{
          console.log('---errhaha',err)
        })
  },
  // 保存图片
  extraImage() {
    const p2 = this.widget.canvasToTempFilePath()
    p2.then(res => {
      console.log('=======',res)
      // 保存图片
      wx.saveImageToPhotosAlbum({
        filePath:res.tempFilePath,
        success(res) { 
          wx.showToast({
            title: '保存成功',
          })
        }
      })
      this.setData({
        qrcodeUrl: res.tempFilePath,
        width: this.container.layoutBox.width,
        height: this.container.layoutBox.height
      })
    })
  },
  // 点击 分享海报
  changeShowMasker(){
    // 显示遮罩
    this.setData({
      isShowMasker:true
    })
    setTimeout(()=>{
      // 渲染海报
      this.renderToCanvas();
    },300)
  }
})

小程序绘制canvas

绘制canvas 封装好的函数 引入调用即可

//--------- ./uCanvas.js
/**
 * 绘制矩形  zw
 * 参数:cxt、x坐标、y坐标、宽度、高度、圆角、颜色
 */
function fillRoundRect(cxt, x, y, width, height, radius, fillColor) {
    cxt.beginPath();
    //圆的直径必然要小于矩形的宽高
    if (2 * radius > width || 2 * radius > height) {
        return false;
    }
    cxt.save();
    // //绘制圆角矩形的各个边
    drawRoundRectPath(x,y,cxt, width, height, radius);
    cxt.fillStyle = fillColor || '#000'; //若是给定了值就用给定的值否则给予默认值
    cxt.fill();   
    cxt.restore();
}
// 绘制矩形各个边过程   在fillRoundRect函数中使用了
function drawRoundRectPath(x,y,cxt, width, height, radius) {
    cxt.save()
    cxt.beginPath(0);
    //从右下角顺时针绘制,弧度从0到1/2PI
    cxt.arc(x+width - radius, y+height - radius, radius, 0, Math.PI / 2);
    //矩形下边线
    cxt.lineTo(x+radius, y+height);
    //左下角圆弧,弧度从1/2PI到PI
    cxt.arc(x+radius, y+height - radius, radius, Math.PI / 2, Math.PI);
    //矩形左边线
    cxt.lineTo(x+0, y+radius);
    //左上角圆弧,弧度从PI到3/2PI
    cxt.arc(x+radius, y+radius, radius, Math.PI, (Math.PI * 3) / 2);
    //上边线
    cxt.lineTo(x+width - radius, y+0);
    //右上角圆弧
    cxt.arc(x+width - radius, y+radius, radius, (Math.PI * 3) / 2, Math.PI * 2);
    //右边线
    cxt.lineTo(x+width, y+height - radius);

    cxt.closePath();
}
/** 绘制矩形边框  zw
 * 参数:cxt、x坐标、y坐标、宽度、高度、圆角、border宽度,border颜色
 */
function roundRectBorder(cxt, x, y, w, h, r, borderWidth = 0,fillColor) {
    if (w < 2 * r) r = w / 2;
    if (h < 2 * r) r = h / 2;
    cxt.beginPath();
    cxt.moveTo(x + r, y);
    cxt.arcTo(x + w, y, x + w, y + h, r);
    cxt.arcTo(x + w, y + h, x, y + h, r);
    cxt.arcTo(x, y + h, x, y, r);
    cxt.arcTo(x, y, x + w, y, r);
    cxt.closePath();
    cxt.lineWidth = borderWidth
    cxt.strokeStyle=fillColor || '#000'
    console.log('borderWidth',borderWidth,fillColor)
    cxt.stroke()
}
//加载图片   这个好像在其他函数中没有使用
function getImageInfo(image) {
    return new Promise((req, rj) => {
        // #ifndef APP-PLUS
        wx.getImageInfo({
            src: image,
            success: function (res) {
                req(res)
            },
        });
        // #endif
        // #ifdef APP-PLUS
        // if (wx.getSystemInfoSync().platform == 'ios') {
        //     uni.downloadFile({
        //         url: image,
        //         success: (res) => {
        //             res.path = res.tempFilePath
        //             req(res)
        //         },
        //     })
        // } else {
        //     wx.getImageInfo({
        //         src: image,
        //         success: function (res) {
        //             req(res)
        //         },
        //     });
        // }
        // #endif
    })
}

/**zw
 * 绘制圆形头像  可以webp格式的图片  放在前面会不显示其他绘制过的图形,推荐在调用的时候 放到最后
 * 也可以使用drawImgCover 方法绘制头像
 * x,y为头像的位置
 * 参数:canvas,cxt、图标路径path、x坐标、y坐标、宽度、高度
 */
function drawCircular(canvas,ctx, url, x, y, width, height) {
    //画圆形头像
    var avatarurl_width = width;
    var avatarurl_heigth = height;
    var avatarurl_x = x;
    var avatarurl_y = y;
    ctx.save();
    ctx.beginPath();
    ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math.PI * 2,
        false);
    ctx.clip();

      // 图片对象
      const image = canvas.createImage()
      // 图片加载完成回调
      image.onload = () => {
          ctx.drawImage(image,avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth);
          ctx.restore();
      }
      // 设置图片src
      image.src = url


  
}

/* zw
 * 使用场景: 可以用为背景图片 头像 可以设置圆角 圆形
 * 绘制图片cover   
 * canvas 
 * t:cxt;
 * src 图片地址  不能使用webp图片
 * s:x坐标
 * o:y坐标
 * i:绘制图片宽度
 * a:绘制图片高度
 * radius 圆角
 * isTop 图片是否在最上面
 */
function drawImgCover(canvas,t, src, s, o, i, a, radius = 0,isTop) {
    let e; // * e:图片属性(通过getImageInfo获取) 
    //获取图片信息
    wx.getImageInfo({
      src:src,
      success:(res)=>{
        e=res;
        //创建img
        let img = canvas.createImage();
        img.src = src;
        img.onload = () => {
          // 图片为异步 绘制的,后画,所以设置 层叠关系
         
          if(isTop){
            console.log('**t*',isTop)
            t.globalCompositeOperation = 'source-over'
          }else{
            console.log('**f*',isTop)
            t.globalCompositeOperation = 'destination-over'
          }
         
          t.save();
          //绘制圆角矩形的各个边
          if( radius !== 0){
            roundRectBorder(t, s, o, i, a, radius)
            t.clip();
          }
          if (e.width / e.height >= i / a) {
              var r = e.height,
                  n = Math.ceil(i / a * r);
            
              t.drawImage(img, (e.width - n) / 2, 0, n, e.height, s, o, i, a)
          } else {
              var c = e.width,
                  l = Math.ceil(a / i * c);
             
              t.drawImage(img, 0, (e.height - l) / 2, e.width, l, s, o, i, a)
          }
          t.restore();
        };
       
      },
      fail:(err)=>{
        console.log('图片信息失败',err)
      
      }
    })

}

/* zw
 * 文本自定义换行---已适配英文不截断换行(2022.7.22更新)
 * family = " 'PingFang SC',tahoma,arial,'helvetica neue','hiragino sans gb','microsoft yahei',sans-serif";
 * var options = {
                font:"22px" + family,  字体大小 字体系列
                color:'red'
                ctx:ctx,    
                word:"文字",      文字
                maxWidth:750,     最大宽度
                maxLine:2,        最大行数
                x:100,            x坐标
                y:100,            y坐标
                l_h:40,           行高
                textCenter:false, 是否居中
                cvsW:cvsW,        画布总宽--用于计算文字居中
            }
 * callback 自定义函数
 */
function dealWords(options, callback) {
    options.ctx.font = options.font; //设置字体
    options.ctx.fillStyle = options.color;
    callback && callback();
    var allRow = getLineNum(options.ctx, options.word, options.maxWidth)
   
    var allRow = Math.ceil(options.ctx.measureText(options.word).width / options.maxWidth);
    

     //实际总共能分多少行--默认多加一行,预留有英文截断
    var count = allRow >= options.maxLine ? options.maxLine : allRow; //实际能分多少行与设置的最大显示行数比,谁小就用谁做循环次数
  
    var endPos = 0; //当前字符串的截断点
    for (var j = 0; j < count; j++) {
        if (endPos >= options.word.length) {
            break;
        }
        var nowStr = options.word.slice(endPos); //当前剩余的字符串
        var rowWid = 0; //每一行当前宽度    
        if (options.ctx.measureText(nowStr).width > options.maxWidth) { //如果当前的字符串宽度大于最大宽度,然后开始截取   
           
          for (var m = 0; m < nowStr.length; m++) {
                rowWid += options.ctx.measureText(nowStr[m]).width; //当前字符串总宽度
                if (rowWid > options.maxWidth) {
                    endPos += m; //下次截断点

                    var isBlock = false //是否被截断了
                    var num = 1 //前几位数是空'',判断从这个点换行
                    // 判断最后一个是否字母--判断是否截断了英文
                    var jy = /^[a-zA-Z]*$/
                    if (jy.test(nowStr[m - 1])) {
                        // console.log(m - 1, nowStr[m - 1], '最后一个是字母')
                        for (var n = 1; n < (m - 1); n++) {
                            if (!jy.test(nowStr[m - 1 - n])) {
                                console.log(m - 1 - n, nowStr[m - 1 - n], num, endPos, '这个位置是空字符')
                                endPos = endPos - num
                                isBlock = true
                                break;
                            }
                            num++
                        }
                    }
                    if (j === options.maxLine - 1) { //如果是最后一行
                        options.ctx.fillText(nowStr.slice(0, m - 1) + '...', options.textCenter ? (options.cvsW -
                            options.ctx.measureText(nowStr.slice(0, m - 1)).width) / 2 : options.x, options.y +
                        (j + 1) * options.l_h); //(j+1)*18这是每一行的高度 
                    } else {
                        options.ctx.fillText(nowStr.slice(0, isBlock ? (m - num) : m), options.textCenter ? (options
                            .cvsW - options.ctx.measureText(nowStr.slice(0, isBlock ? (m - num) : m)).width) /
                            2 : options.x, options.y + (j + 1) * options.l_h);
                    }
                    break;
                }
            }
        } else { //如果当前的字符串宽度小于最大宽度就直接输出
         

            options.ctx.fillText(nowStr.slice(0), options.textCenter ? (options.cvsW - options.ctx.measureText(nowStr
                .slice(0)).width) / 2 : options.x, options.y + (j + 1) * options.l_h);
        }
    }
}


/* zw 在dealWords 函数中使用了
 * 计算文字有几行--针对英文换行不截断的计算行数 
 * ctx:cxt;
 * str:文案内容
 * maxWidth:文字最大宽度
 */
function getLineNum(ctx, str, maxWidth) {
    var allRow = Math.ceil(ctx.measureText(str).width / maxWidth) + 1; //实际总共能分多少行--默认多加一行,预留有英文截断
    var endPos = 0; //当前字符串的截断点
    var lineNum = 0 //行数
    for (var j = 0; j < allRow; j++) {
        var nowStr = str.slice(endPos); //当前剩余的字符串
        var rowWid = 0; //每一行当前宽度    
        if (ctx.measureText(nowStr).width > maxWidth) { //如果当前的字符串宽度大于最大宽度,然后开始截取
            for (var m = 0; m < nowStr.length; m++) {
                rowWid += ctx.measureText(nowStr[m]).width; //当前字符串总宽度
                if (rowWid > maxWidth) {
                    endPos += m; //下次截断点

                    var isBlock = false //是否被截断了
                    var num = 1 //前几位数是空'',判断从这个点换行
                    // 判断最后一个是否字母--判断是否截断了英文
                    var jy = /^[a-zA-Z]*$/
                    if (jy.test(nowStr[m - 1])) {
                        console.log(m - 1, nowStr[m - 1], '最后一个是字母')
                        for (var n = 1; n < (m - 1); n++) {
                            if (!jy.test(nowStr[m - 1 - n])) {
                                console.log(m - 1 - n, nowStr[m - 1 - n], num, endPos, '这个位置是空字符')
                                endPos = endPos - num
                                isBlock = true
                                break;
                            }
                            num++
                        }
                    }
                    break;
                }
            }
        } else {
            lineNum = j + 1
            console.log(nowStr.slice(0), lineNum, j, '最后一行')
            break;
        }
    }
    console.log(lineNum, '总行数')
    return lineNum
}


/*zw
 * 绘制圆角按钮 
 * ctx:createCanvasContext
 * color:背景颜色;
 * x:x坐标
 * y:y坐标
 * width:宽
 * height:高
 * radius:圆角
 * text:文字
 * fontColor:文字颜色
 * textAlign: left/center/right
 * fontStyle:字体的样式  默认样式为: 'normal bold 42px sans-serif'
 */
function drawButton(ctx, color, x, y, width, height, radius, text, fontColor, textAlign,fontStyle) {
    //分为4条直线4个圆角绘制
    ctx.beginPath();
    ctx.fillStyle = color;
    ctx.moveTo(x + radius, y);
    ctx.lineTo(x + width - radius, y);
    ctx.arc(x + width - radius, y + radius, radius, Math.PI * 3 / 2, Math.PI * 2);
    ctx.lineTo(x + width, y + height - radius);
    ctx.arc(x + width - radius, y + height - radius, radius, Math.PI, Math.PI / 2);
    ctx.lineTo(x + radius, y + height);
    ctx.arc(x + radius, y + height - radius, radius, Math.PI / 2, Math.PI);
    ctx.lineTo(x, y + radius);
    ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2);
    ctx.fill();
    ctx.closePath();

    ctx.beginPath();
    ctx.fillStyle = fontColor;
  
    ctx.font = fontStyle?fontStyle:'normal bold 42px sans-serif';
    ctx.textAlign=textAlign;
    ctx.textBaseline = "middle";
    ctx.fillText(text, x + width / 2, y + height / 2);
}

export default {
    fillRoundRect: fillRoundRect, //绘制矩形
    roundRectBorder: roundRectBorder, //绘制矩形+边框
    getImageInfo: getImageInfo, //加载图片
    drawCircular: drawCircular, //绘制圆形头像
    drawImgCover: drawImgCover, //绘制图片cover
    dealWords: dealWords, //文本自定义换行
    drawButton: drawButton, //绘制圆角按钮
    getLineNum: getLineNum, //计算内容行数
  
}
//---- drawCanvas/drawCanvas.wxml
<view>
  <button type="primary" bind:tap="changeShowMasker">分享给好友</button>
</view>

<!-- 遮罩 -->
<view class="masker" wx:if="{{isShowMasker}}">
  <!-- 分享海报 -->
  <canvas type="2d" id="myCanvas" width="300" height="400" style="border: 2rpx solid;"></canvas>
  <!-- 保存图片 -->
  <view>
  <button type="primary" bind:tap="extraImage">保存图片</button>
  </view>
</view>
//--- drawCanvas/drawCanvas.wxss
.masker{
  width: 100%;
  height: 100%;
  position: fixed;
  left: 0;
  top:0;
  background-color: rgba(0,0,0,.5);

}
#myCanvas{
  width: 600rpx;
  height: 950rpx;
  margin: 30rpx auto;
  background-color: #f5efef;
}
//----- drawCanvas/drawCanvas.js
//生成二维码的插件
import drawQrcode from 'weapp-qrcode-canvas-2d'
import uCanvas from './uCanvas.js'



Page({
  data: {
    isShowMasker:false,//是否显示遮罩
    qrcodeUrl:'',//二维码图片地址
  },
  renderToCanvas() {
       //=================1=== 创建二维码
       // 创建离屏 2D canvas 实例 
        const canvas = wx.createOffscreenCanvas({type: '2d', width: 300, height: 150}) 
        // 使用插件生成二维码
        drawQrcode({
            canvas: canvas,
            canvasId: 'myQrcode',
            width: 260,
            padding: 30,
            background: '#ffffff',
            foreground: '#000000',
            text: 'abc',
        })
        //--- 将二维码 canvas 专为二维码图片地址,本可以使用canvasToTempFilePath 但是 在真机测试的时候 报错 所以改为下面的方式
        let base64 = canvas.toDataURL();
        const time = new Date().getTime();
        const imgPath = wx.env.USER_DATA_PATH + "/poster" + time + "share" + ".png";
        //如果图片字符串不含要清空的前缀,可以不执行下行代码.
        const imageData = base64.replace(/^data:image\/\w+;base64,/, "");
        const fs = wx.getFileSystemManager();
        fs.writeFileSync(imgPath, imageData, "base64");
        fs.close()

        // 二维码图片的临时地址
        this.setData({
          qrcodeUrl:imgPath
        })


        //===============2==== 绘制canvas
        const query = wx.createSelectorQuery()
        query.select('#myCanvas')
          .fields({ node: true, size: true })
          .exec((res) => {
            const canvas = res[0].node
            this.canvas=canvas;
            const ctx = canvas.getContext('2d')
    
            const dpr = wx.getSystemInfoSync().pixelRatio
            canvas.width = 600 * dpr
            canvas.height = 950 * dpr
            ctx.scale(dpr, dpr)
       
           
            //=======2.2==调用封装好的绘制canvas的函数 调用哪些方法视情况而定
            // **************
              uCanvas.drawImgCover(canvas,ctx,this.data.qrcodeUrl,200,500,200,200,100,true)
              uCanvas.drawImgCover(canvas,ctx,'/images/haibao.jpeg',0,0,600,950,50,false)
              uCanvas.roundRectBorder(ctx,200,0,100,100,50,2,'blue')
              uCanvas.drawButton(ctx,'green',0,0,100,100,10,'提交','blue','center')
              uCanvas.dealWords({
                font:"30px PingFang SC",
                color:'green',
                ctx:ctx,    
                word:"文8的粉sdfv十分广泛发色 阿瑟费的v啊但是阿斯顿 复古v是对方感受到风是电饭锅阿斯顿",      
                maxWidth:600,     
                maxLine:3,       
                x:0,            
                y:0,          
                l_h:40,          
                textCenter:false, 
                cvsW:600,       
              })
              uCanvas.fillRoundRect(ctx,200,200,200,200,10,'red')
              uCanvas.fillRoundRect(ctx,0,700,100,100,0,'rgba(0,0,0,0.6)')
              // 绘制圆形图像 推荐放在最后
              uCanvas.drawCircular(canvas,ctx,'/images/1122.webp',200,300,500,500)
              // **************

         })
      
  },
  // 保存图片
  extraImage() {

        //把当前画布指定区域的内容导出生成指定大小的图片
        wx.canvasToTempFilePath({
          x: 0,
          y: 0,
          width: 600,
          height: 950,
          destWidth: 600,
          destHeight: 950,
          canvas: this.canvas,
          success(res) {
            // console.log(res.tempFilePath)
               // 保存图片
              wx.saveImageToPhotosAlbum({
                filePath:res.tempFilePath,
                success(res) { 
                  // 保存图片成功后提示信息
                  wx.showToast({
                    title: '保存成功',
                  })
                }
              })
          }
        })
  },
  // 点击 分享海报
  changeShowMasker(){
    // 显示遮罩
    this.setData({
      isShowMasker:true
    })
    //  创建二维码 绘制canvas
     this.renderToCanvas();

  }
})