微信小程序 canvas画海报

1、Canvas 2D 

<view class="main_box">
   <!--weui加载中动画-如果不需要可去掉--->
  <mp-loading show="{{showLoad}}"></mp-loading>
  <canvas style="width: {{canvas_width}}px;height: {{canvas_height}}px;" type="2d" id="myCanvas" class="canvas"></canvas>
</view>
<view class="btn_box">
  <button class="btn " bind:tap="saveImg">保存海报</button>
</view>
<view class="" style="height: 60rpx;"></view>

.json文件

{
  "usingComponents": {
    "mp-loading": "weui-miniprogram/loading/loading"
  }
}
const APP = new getApp();
Page({
  data: {
    userInfo:{},
    goodsId:'',
    canvasImg:{},
    helpData:{},
    help_id:'',
    canvas_width:'',
    canvas_height:'',
    showLoad:true,
    rpx:1,
    canvas:{},
    qrcode:"",
  },
  onLoad(options) {
    this.setData({goodsId:options.id,help_id:options.help_id});
    this.getUserinfo();
  },
  init(){//初始化canvas
    const query = wx.createSelectorQuery();
    const dpr = wx.getSystemInfoSync().pixelRatio;
    let rpx = wx.getSystemInfoSync().windowWidth / 375; //适配
    query.select('#myCanvas')
      .fields({ node: true, size: true })
      .exec((res) => {
        const canvas = res[0].node
        const ctx = canvas.getContext('2d')
        canvas.width = 355*rpx*dpr;
        canvas.height = 600*rpx*dpr;

        ctx.fillStyle="#fff";//背景颜色
        ctx.fillRect(0,0,canvas.width,canvas.height); 
        ctx.fillStyle="#000000";

        this.setData({
          canvas_width:355*rpx,
          canvas_height:600*rpx,
          canvas:canvas
        })
        ctx.scale(dpr, dpr)
        // ctx.fillRect(0, 0, 100, 100)
        this.crateCanvas(canvas,ctx)
      })
  },
  crateCanvas(canvas,ctx){
    let that = this;
    let rpx = wx.getSystemInfoSync().windowWidth / 375;
    that.setData({rpx:rpx})
    
    ctx.save(); // 先保存状态 已便于画完圆再用
    ctx.beginPath()
    ctx.arc(50 * rpx, 50 * rpx, 30 * rpx, 0, Math.PI * 2, false);  //false代表顺时针  图片的位置加半径
    ctx.strokeStyle="#fff" //线条颜色
    ctx.stroke();
    // ctx.fillStyle="yellow" //填充圆形
    // ctx.fill()  
    // ctx.draw(true)
    ctx.clip();//画了圆 再剪切  原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
    let img = canvas.createImage();
    img.src = that.data.userInfo.wx_avatar_url;  // 引入本地图片
    img.onload = (e) => {
       ctx.drawImage(img, 20*rpx, 10*rpx, 60*rpx, 60*rpx); 
     }
     ctx.restore()//恢复之前保存的绘图上下文 恢复之前保存的绘图上下文即状态 可以继续绘制
     
    // ctx.clearRect(0, 0, canvas.width, canvas.height)// 清空画布
    ctx.font = "bold  18px Microsoft YaHei";
    ctx.fillText(that.data.userInfo.nick_name, 90*rpx, 40*rpx);
    ctx.font = "15px Microsoft YaHei";
    ctx.fillText("正在参加助力活动!",90*rpx, 65*rpx);
    let img_goods = canvas.createImage();
    img_goods.src = that.data.helpData.images;  // 引入本地图片
    img_goods.onload = (e) => {
       ctx.drawImage(img_goods, 15*rpx, 80*rpx, 330*rpx, 320*rpx ); 
     }
     ctx.font = "14px Microsoft YaHei";
     ctx.fillText( that.data.helpData.goods_title,20*rpx,420*rpx );

     ctx.fillStyle = '#d5313a'; 
     ctx.fillText("价格¥",20*rpx, 470*rpx);
     ctx.font = "20px Microsoft YaHei";
     ctx.fillText(that.data.helpData.extend_data.selling_price,60*rpx, 470*rpx);
     ctx.fillStyle = '#666'; 
     ctx.font = "14px Microsoft YaHei";
     ctx.fillText("原价¥"+that.data.helpData.extend_data.show_price,20*rpx, 500*rpx);
     ctx.fillText("已售"+that.data.helpData.extend_data.selling_num,20*rpx, 540*rpx);
     ctx.fillText("仅剩"+that.data.helpData.extend_data.remain_num,80*rpx, 540*rpx);

     let img_code = canvas.createImage();
     img_code.src = that.data.qrcode;  // 引入本地图片
     img_code.onload = (e) => {
        ctx.drawImage(img_code, 240*rpx, 440*rpx, 100*rpx, 100*rpx); 
      }
    ctx.font = "12px Microsoft YaHei";
    ctx.fillStyle = '#666'; 
    // ctx.textAlign = 'center'
     ctx.fillText("长按识别小程序码",242*rpx,560*rpx);

     this.setData({
      showLoad:false
     })
  },
  getGoods(){ //获取商品信息
    let that = this;
    APP.request.get(APP.api.goods, {
      m: "goodsDetail",
      id: this.data.id,
      record:1
    }, (res) => {
      this.setData({
        helpData: res,
      });
    //   wx.downloadFile({ //获本地临时路径
    //     url: res.img,
    //     success: function (res2) {
    //       that.setData({
    //         qrcode: res2.tempFilePath
    //       });
    //     }
    //   })
      that.init();
    });
  },
  getUserinfo(){
    let that = this;
    APP.request.get(APP.api.user, {
      m: "getUserInfo",
    }, (res) => {
      that.setData({userInfo: res});
      that.getGoods();
    })
  },
  saveImg(){
    var that = this;
    wx.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: that.data.canvas_width * 3,
      height: that.data.canvas_height * 3,
      destWidth:that.data.canvas_width *3,
      destHeight: that.data.canvas_height*3,
      canvas: this.data.canvas,
      success: function (res) {
        //调取小程序当中获取图片
        console.log(res.tempFilePath);
        that.setData({isrc:res.tempFilePath})
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success(res) {
            wx.showToast({
              title: '保存成功',
            })
          }
        })
      },
    })
  },
})
.main_box{width:calc(100% - 40rpx) ;background-color: #f5f5f5;padding: 20rpx;}
.canvas{width: 100%;height: 100%;background-color: #fff;}
.btn_box{width: 90%;margin: auto;margin-top: 30rpx;}
.btn_box .btn{
  width: 80%;
  height: 70rpx;
  line-height: 70rpx;
  margin: auto;
  background-color: #f9592e;
  color:#f5f5f5;
}

2、老版接口 

<canvas canvas-id="myCanvas" style="width:{{375 * rpx}}px;height:{{723 * rpx}}px"/>

<view class="bottom_box">
  <view bindtap='saveImg' class='btn'>保存海报</view>
</view>
   //图片需要先下载到本地,获取本地连接,然后再画到canvas
  getbg(){
    let that = this;
    wx.downloadFile({
      url: "https://img.alicdn.com/imgextra-2-tps-206-240.png",
      success: function (res3) {
        that.setData({
          bg_img: res3.tempFilePath
        });
      }
    })
  },
canvasImg() {
    let that = this;
    var res = wx.getSystemInfoSync();
    var rpx = res.windowWidth / 375; //iphone6
    console.log("rpx",rpx)
    that.setData({
      rpx: res.windowWidth / 375
    })
    const ctx = wx.createCanvasContext('myCanvas');
    ctx.setFillStyle('#f5f5f5');                             //为创建的canvans上下文添充颜色  如果没有设置 fillStyle,默认颜色为 black。
    ctx.fillRect(0, 0, 375 * rpx, 724 * rpx)
    ctx.save(); // 先保存状态 已便于画完圆再用
    ctx.beginPath(); //开始绘制
    ctx.drawImage(that.data.bg_img, 0, 0, 375 * rpx, 724 * rpx);//绘制背景图片
    //先画个圆
    ctx.arc(190 * rpx, 140 * rpx, 30 * rpx, 0, Math.PI * 2, false);  //false代表顺时针  图片的位置加半径
    // ctx.setStrokeStyle('#ffffff')
    ctx.stroke(); //画出当前路径的边框。默认颜色色为黑色。
    ctx.clip();//画了圆 再剪切  原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
    ctx.drawImage(https://mhsimg.flashnet.cn/9a611f4e3108db22/7e63628891c50f7b.png, 160 * rpx, 110 * rpx, that.data.image.width * rpx, that.data.image.heigth * rpx); // 推进去图片
    ctx.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下文即状态 可以继续绘制

    ctx.setFillStyle("#f5f5f5");
    ctx.setFontSize(16 * rpx);                               //字大小
    ctx.setTextAlign('center');                        //是否居中显示,参考点画布中线
    ctx.fillText(半仙儿, 188 * rpx, 200 * rpx);

    ctx.setFillStyle("#f5f5f5");
    ctx.setFontSize(14 * rpx);                               //字大小
    ctx.setTextAlign('center');  
    ctx.fillText('向您推荐了一个好东西!', 190 * rpx, 220 * rpx);
    
    //  裁剪一个圆角区域,显示图片二维码
    const x = 155 * rpx, y = 580 * rpx, w = 70 * rpx, h = 70 * rpx, r = 10 * rpx;
    ctx.beginPath();
    ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
    ctx.lineTo(x + w - r, y);
    ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
    ctx.lineTo(x + w, y + h - r);
    ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
    ctx.lineTo(x + r, y + h);
    ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);
    ctx.closePath();
    ctx.clip();
    ctx.drawImage(that.data.code, x, y, w, h);
    // ctx.draw(true);
    ctx.draw();
    wx.hideLoading()
  },
saveImg() {
    let that = this;
    var res = wx.getSystemInfoSync()
    var rpx = res.windowWidth / 375
    that.setData({
      rpx: res.windowWidth / 375
    })
    wx.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: 375 * rpx,                     //画布宽高
      height: 724 * rpx,
      destWidth: 375 * 3  * rpx,                 //画布宽高*dpr 以iphone6为准
      destHeight: 724 * 3 * rpx,                //放大2倍以上,解决保存的图片模糊的问题
      canvasId: 'myCanvas',
      fileType:'png',
      success: function (res) {
        console.log(res.tempFilePath) //生成的临时图片路径
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success: function (res) {
            console.log(res);
            wx.showToast({
              title: '保存成功',
            })
          },
          fail: function () {
            console.log('a')
          }
        })
      }
    })
  },

<image src="{{canvasImgSrc}}" mode="aspectFit" style="width:100vw;height:calc(100vh - 120rpx)"></image>

covertImg(){ //把canvas转换为图片,方便修改样式
    var res = wx.getSystemInfoSync()
    var rpx = res.windowWidth / 375
    setTimeout(() => {
      wx.canvasToTempFilePath({
        x: 0,
        y: 0,
        width: 375 *3* rpx,
        height: 700 *3* rpx,
        canvasId: 'myCanvas',
        success: (res) => {
          this.setData({ canvasImgSrc: res.tempFilePath });
          wx.hideLoading();
        }
      });
    },500)
  },

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值