微信小程序 生成海报

<view class="masking" hidden="{{!textShow}}" catchtap="masking"></view>
<view class="canvas-container" hidden="{{!textShow}}" catchtap="masking">
  <canvas
    canvas-id="myCanvas"
    class="myCanvas"
    style="width: {{canvasWidth}}px; height: {{canvasHeight}}px;">
  </canvas>
  <view class="btn-save" catchtap="getTempFilePath">保存图片</view>
</view>
.canvas-container {
  display: block;
  margin: 0 auto;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
}
.myCanvas{
  margin-bottom: 50rpx;
}
.btn-save {
	width: 400rpx;
  height: 80rpx;
  line-height: 80rpx;
	background-color: #e4393c;
  border-radius: 40rpx;
	font-size: 36rpx;
  color: #ffffff;
  text-align: center;
  margin: auto;
  margin-top: 50rpx;
}
.masking{
  position: fixed;
  top: 0rpx;
  right: 0rpx;
  bottom: 0rpx;
  left: 0rpx;
  background: rgb(0, 0, 0, .5);
}
import '../../core/page_extend.js';
import common from '../../utils/common.js';

Page({

    /**
     * 页面的初始数据
     */
    data: {
      canvasWidth: 296, // 绘图区域宽度
      canvasHeight: 426, // 绘图区域高度
      card_url: '', // 生成图片的id
    },

    /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function (options) {
  
    },

    /**
     * 生命周期函数--监听页面显示
     */
    onShow: function () {

    },


    // 生成海报
    poster(e){
      let that = this;
      let { cid,istab } = e.currentTarget.dataset;
      console.log(istab)

      const { canvasWidth, canvasHeight} = this.data;
      // 定义画布对象
      const ctx = wx.createCanvasContext("myCanvas", this);
      this.setData({
        more_index: null
      })
      // if(istab == 3){
      //   wx.showToast({
      //     title: '已结束',
      //     icon: 'error',
      //     duration: 2000
      //   })
      //   return false
      // }
      common.post('app.php?c=coupon&a=coupon_poster_info', { cid }, (res) => {
        if (res.err_code == 0) {
          wx.showLoading({
            title: '生成海报中...',
          })
          let {
            backurl,
            face_money,
            is_all_product_text,
            name,
            receive_code,
            store_logo,
            store_name,
          } = res.err_msg
          let piece = 130 - ctx.measureText("¥"+ face_money).width + 10;

          // 获取图片
          Promise.all([
            this.getCode(backurl), // 背景
            this.getCode(store_logo), // 头像
            this.getCode(receive_code), // 二维码
          ]).then(res => {
            // 背景图
            ctx.drawImage(res[0].tempFilePath, 0, 0, canvasWidth, canvasHeight);

          
            //金额
            // ctx.font = "bold 20px Arial"; 
            ctx.fillStyle = "#ff3b4b";
            // ctx.fillText('¥', piece, 220);
            // // 文字拼接
            ctx.font = "bold 40px Arial";
            // ctx.fillText(face_money, piece+15, 220);
            
            ctx.textAlign = 'center';
            ctx.fillText( '¥'+face_money, 155, 220);
          
            // 类型
            ctx.font = "15px Arial"; 
            ctx.fillStyle = "#ff3b4b"; 
            ctx.textAlign = "center"
            ctx.fillText(is_all_product_text, 155, 240);

            // 二维码
            ctx.drawImage(res[2].tempFilePath, 97, 280, 100, 100);
            
            // 店铺名称
            ctx.font = "18px Arial";
            ctx.textAlign = "center";
            ctx.fillStyle = "#fff";
            ctx.fillText(store_name, 165, 65);

            // 头像
            that.circleImg(ctx, res[1].tempFilePath, 50, 30, 25);
          
            ctx.draw();
            setTimeout(() => {
              wx.hideLoading()
              that.setData({
                textShow: true
              })
            }, 1000);
          })

        }
      }, '', (err) => {
        console.error(err);
      }, 'Post');

    },
    masking(){
      this.setData({
        textShow: false
      })
    },
    // 头像
    circleImg: function (ctx, img, x, y, r) {  //圆形头像
      ctx.save();
      var d = 2 * r;
      var cx = x + r;
      var cy = y + r;
      ctx.beginPath();
      ctx.arc(cx, cy, r, 0, 2 * Math.PI);
      ctx.clip();
      ctx.drawImage(img, x, y, d, d);
    },

    // 保存图片
  getTempFilePath: function() {
    let that = this
    wx.canvasToTempFilePath({
      canvasId: 'myCanvas',
      success: (res) => {
        that.saveImageToPhotosAlbum(res.tempFilePath)
      }
    })
  },
  saveImageToPhotosAlbum: function(imgUrl) {
    let that = this;
    if (imgUrl) {      
      wx.saveImageToPhotosAlbum({
        filePath: imgUrl,
        success: (res) => {
          wx.showToast({
            title: '保存成功',
            icon: 'success',
            duration: 3000
          })
          that.masking()
        },
        fail: (err) => {
          console.log(err)
          wx.showToast({
            title: '保存失败',
            icon: 'error',
            duration: 3000
          })
          that.masking()
        }
      })
    } else {
      wx.showToast({
        title: '绘制中……',
        icon: 'loading',
        duration: 3000
      })
    }
},
  
    //把网路图片下载成本地图片
    getCode(img) {
      return new Promise((resolve, reject) => {
        wx.downloadFile({
          url: img,
          success: (res) => {
            resolve(res)
          }
        })
      })
    },


    /**
       * 工具  圆角矩形
       * x, y 坐标
       * width, height 宽高
       * 圆角: 左下, 右下, 右上, 左上
       */
    roundedRect(
      ctx,
      x,
      y,
      width,
      height,
      RTradius,
      RBradius,
      LBradius,
      LTradius
    ) {
      // ctx.strokeStyle = "#fffbff";
      ctx.beginPath();
      // 右上
      ctx.moveTo(x, y + RTradius);
      ctx.lineTo(x, y + height - RTradius);
      ctx.quadraticCurveTo(x, y + height, x + RTradius, y + height);
      // 右下
      ctx.lineTo(x + width - RBradius, y + height);
      ctx.quadraticCurveTo(
        x + width,
        y + height,
        x + width,
        y + height - RBradius
      );
      // 左下
      ctx.lineTo(x + width, y + LBradius);
      ctx.quadraticCurveTo(x + width, y, x + width - LBradius, y);
      // 左上
      ctx.lineTo(x + LTradius, y);
      ctx.quadraticCurveTo(x, y, x, y + LTradius);
      // ctx.stroke();
      ctx.closePath();
    },
    /**
     * 文本填充方法
     * @param {String} ctx 画布实例对象名
     * @param {Object} obj 文本属性
     * obj = {
        x: 绘制文本的左上角 x 坐标位置,如果这个文本要基于一个盒子水平居中,此值应该写盒子的左上角 x 坐标位置,
        y: 绘制文本的左上角 y 坐标位置,
        color: 绘制文本的颜色,
        size: 绘制文本的字体大小,
        isCenter: 文字的水平对齐方式(true,false),
        text: 在画布上输出的文本内容,
        width: 展示当前文本盒子的宽度,在文本需要水平居中是要加这个参数,
        bold: 字体是否需要加粗(true、false)
      }
    */
    drawText(ctx, obj) {
      ctx.save();
      ctx.fillStyle = obj.color;
      ctx.setTextBaseline("top");
      if (obj.bold) {
        ctx.font = `normal bold ${obj.size}px PingFangSC-Regular`;
      } else {
        ctx.font = `normal 100 ${obj.size}px PingFangSC-Regular`;
      }
      if (obj.isCenter && obj.width) {
        ctx.fillText(
          obj.text,
          obj.x + (obj.width - ctx.measureText(obj.text).width) / 2,
          obj.y
        );
      } else {
        ctx.fillText(obj.text, obj.x, obj.y);
      }
      ctx.restore();
      ctx.closePath();
    },
    // 文本宽度计算
    measureText(text, fontSize = 10) {
      let width = 0;
      String(text)
        .split("")
        .forEach(item => {
          if (/[a-zA-Z]/.test(item)) {
            width += 7;
          } else if (/[0-9]/.test(item)) {
            width += 5.5;
          } else if (/\./.test(item)) {
            width += 2.7;
          } else if (/-/.test(item)) {
            width += 3.25;
          } else if (/[\u4e00-\u9fa5]/.test(item)) {
            // 中文匹配
            width += 10;
          } else if (/\(|\)/.test(item)) {
            width += 3.73;
          } else if (/\s/.test(item)) {
            width += 2.5;
          } else if (/%/.test(item)) {
            width += 8;
          } else {
            width += 10;
          }
        });
      return (width * fontSize) / 10;
    },
    /**
     * 文本划线
     * @param {String} ctx 画布实例对象名
     * @param {Object} obj
     * obj = {
        sx: 划线的开始位置的 x 坐标位置,
        sy: 划线的开始位置的 y 坐标位置,
        ex: 划线的结束位置的 x 坐标位置,
        ey: 划线的结束位置的 y 坐标位置,
        lineWidth: 线条的宽度,
        color: 画线的颜色
      }
    */
    lineation(ctx, obj) {
      // 开始一个新的绘制路径
      ctx.beginPath();
      // 设置线条的宽度
      ctx.setLineWidth(1);
      // 定义直线的起点坐标为
      ctx.moveTo(obj.sx, obj.sy);
      // 定义直线的终点坐标为
      ctx.lineTo(obj.ex, obj.ey);
      // 设置画线的颜色
      ctx.strokeStyle = obj.color;
      // 沿着坐标点顺序的路径绘制直线
      ctx.stroke();
      // 关闭当前的绘制路径
      ctx.closePath();
    }


})

你可能感兴趣的:(微信小程序,微信小程序,javascript,前端)