canvas生成海报,动态计算图片的大小适配海报的高度

1.js代码

// pages/nav/nav.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    nav: ['全部', '水果蔬菜', '家电', '图书', '生活用品', '测试', '还是测试', '依然是测试'],
    // 当前项目
    current: 2,
    // 滚动栏滚动距离
    scrollLeft: 0,
    // 窗体宽度
    windowWidth: 0,
    canvasImg: '',
    share: false, //是否分享
    base64Qr: '', //二维码接口获取的base64的图片
    drawing: false, //是否绘制海报中
    loading: false, //点击分享时,是否绘制海报中
    sourceUrl1: "https://purchasing-miniapp-cdn.a2milk.com/a2/img/invitenow/share1.png", //网络图片
    sourceUrl: "http://campaigncdn.herdsric.com/a2/adjust/100.jpg", //网络图片
    sizeHeight: '',
    newheight: '',
    pixelRatio: '',
    windowH: '',
    windowW: '',
    tempNum: '',
    testTop: ''
  },

  onLoad: function (options) {
    // 设置标题
    wx.setNavigationBarTitle({
      title: '导航栏案例',
    });

    // 获取窗体宽度
    wx.getSystemInfo({
      success: (result) => {
        this.setData({
          windowW: result.windowWidth,
          windowH: result.windowHeight,
          windowWidth: result.windowWidth,
          pixelRatio: result.pixelRatio
        })
      },
    })
    // this.shareShow()
  },
  //显示遮罩层
  shareShow() {
    this.setData({
      canvasImg: '',
      drawing: true
    })
    setTimeout(() => {
      this.setShareCanvas(); // 分享绘图
    }, 800)

    // wx.showLoading({
    //   title: '海报生成中',
    // })
  },

  setShareCanvas() {
    const that = this;
    const query = wx.createSelectorQuery();
    query.select('#shareCanvas')
      .fields({
        node: true,
        size: true
      }).exec((res) => {
        const canvas = res[0].node //拿到canvas对象
        that.setData({ //这里保存canvas对象是因为下面保存相片要用这个对象
          canvas
        })
        const ctx = canvas.getContext('2d') //返回用于在画布上绘图的环境
        const dpr = that.data.pixelRatio //拿到设备像素比
        canvas.width = res[0].width * dpr //缩放画布
        canvas.height = res[0].height * dpr
        ctx.scale(dpr, dpr)
        // 设置背景为白色
        ctx.fillStyle = "#fff";
        new Promise(function (resolve) {
          //2、绘制图片及文字
          const imggood = canvas.createImage()
          imggood.src = that.data.sourceUrl
          imggood.onload = (e) => {
            var newheight = that.fitSize(240) * imggood.height / imggood.width
            that.setData({
              newheight: newheight
            })
            if (newheight > that.fitSize(240)) {
              newheight = that.fitSize(240)
              that.setData({
                heightNew: 1,
                newheight: newheight
              })
              console.log(that.data.heightNew, newheight, '00000')
            }
            let cutHeight = imggood.height
            if (imggood.height > imggood.width) {
              cutHeight = imggood.width
            }
            const tempNum = 20
            that.setData({
              tempNum: tempNum
            })
            ctx.fillRect(0, 0, that.fitSize(275), that.fitSize(78) + newheight + tempNum + that.fitSize(48) + tempNum + that.fitSize(48))
            console.log(that.fitSize(78) + newheight + tempNum + that.fitSize(48) + tempNum + that.fitSize(48), '0')
            that.setData({
              sizeHeight: that.fitSize(78) + newheight + tempNum + that.fitSize(48) + tempNum + that.fitSize(48)
            })
            ctx.drawImage(imggood, 0, 0, imggood.width, cutHeight, that.fitSize(17), that.fitSize(78), that.fitSize(240), newheight);
            let str = '获取a2™品牌素材,解锁专属会员福利!'
            let chr = str.split("");
            let temp = "";
            let row = [];
            ctx.font = `${parseInt(that.fitSize(12))}px FZabj-small`;
            ctx.fillStyle = '#4E4E4E';
            for (let a = 0; a < chr.length; a++) {
              if (ctx.measureText(temp).width < (that.fitSize(136))) {
                temp += chr[a];
              } else {
                a--;
                row.push(temp);
                temp = "";
              }
            }
            row.push(temp);
            if (row.length > 2) {
              let rowCut = row.slice(0, 2);
              let rowPart = rowCut[1];
              let test = "";
              let empty = [];
              for (let a = 0; a < rowPart.length; a++) {
                if (ctx.measureText(test).width < (that.fitSize(140))) {
                  test += rowPart[a];
                } else {
                  break;
                }
              }
              empty.push(test);
              let group = empty[0] + "..." //这里只显示两行,超出的用...表示
              rowCut.splice(1, 1, group);
              row = rowCut;
            }
            let testTop = 13
            that.setData({
              testTop: testTop
            })
            //修改文字距离图片的距离
            for (let b = 0; b < row.length; b++) {
              ctx.fillText(row[b], that.fitSize(32), that.fitSize(78) + newheight + that.data.tempNum + b * 17 + that.fitSize(testTop));
            }
            resolve(true);
          }
        }).then(function () {
          return new Promise(function (resolve) {
            const imgbg = canvas.createImage()
            imgbg.src = 'https://purchasing-miniapp-cdn.a2milk.com/a2/img/adjust/hbwz1.png'
            imgbg.onload = (e) => {
              ctx.drawImage(imgbg, that.fitSize(64), that.fitSize(22), that.fitSize(150), that.fitSize(39))
              resolve(true);
            }
          })
        }).then(function () {
          return new Promise(function (resolve) {
            //绘制小程序二维码图片
            const imgqrcode = canvas.createImage()
            imgqrcode.src = 'https://campaigncdn.herdsric.com/a2/adjust/qrCode.jpg'
            imgqrcode.onload = (e) => {
              console.log(that.data.newheight)
              //绘制二维码
              ctx.drawImage(imgqrcode, that.fitSize(192), that.fitSize(78) + that.data.newheight + that.data.testTop, that.fitSize(48), that.fitSize(48))
              resolve(true);
            }
          })
        }).then(function () {
          return new Promise(function (resolve) {
            const radius = 6; // 设置半径为10px
            ctx.moveTo(that.fitSize(17), that.fitSize(78))
            ctx.lineTo(that.fitSize(257), that.fitSize(78))
            let boxLine = that.fitSize(78) + that.fitSize(48) + that.data.newheight + that.data.testTop + that.fitSize(15)
            // 右下角弧度
            ctx.arcTo(that.fitSize(257), boxLine, that.fitSize(78), boxLine, radius); // 从起始点到结束点绘制圆弧路径
            ctx.lineTo(that.fitSize(257) - radius, boxLine)
            // 左下角弧度
            ctx.arcTo(that.fitSize(17), boxLine, that.fitSize(17), 100, radius); // 从起始点到结束点绘制圆弧路径
            ctx.lineTo(that.fitSize(17), boxLine - radius)
            ctx.lineTo(that.fitSize(17), that.fitSize(78))
            // 设置边框的样式和颜色
            ctx.lineWidth = 0.2; // 边框宽度
            ctx.strokeStyle = 'gray'; // 边框颜色

            // 设置阴影属性并绘制边框
            ctx.shadowColor = '#000'; // 阴影颜色
            ctx.shadowBlur = 10; // 阴影模糊半径
            ctx.shadowOffsetX = -5; // 阴影水平偏移
            ctx.shadowOffsetY = 6; // 阴影垂直偏移
            ctx.stroke()
            resolve(true);
          })
        }).then(function () {
          return new Promise(function (resolve) {
            //绘制底部文字
            const imgWz = canvas.createImage()
            imgWz.src = 'https://purchasing-miniapp-cdn.a2milk.com/a2/img/adjust/hbwz2.png'
            imgWz.onload = (e) => {
              ctx.drawImage(imgWz, that.fitSize(80), that.fitSize(78) + that.data.newheight + 4 + that.data.testTop + that.fitSize(53) + that.data.tempNum, that.fitSize(115.6), that.fitSize(28.8))
              resolve(true);
            }
          })
        }).then(function () {
          return new Promise(function (resolve) {
            console.log('绘制完毕,转换成图片', canvas)
            that.transferCanvasToImage(canvas)
            resolve(true);
          })
        }).catch((err) => {
          that.setData({

          })
        })
      })
  },

  transferCanvasToImage(canvas) {
    const that = this;
    wx.canvasToTempFilePath({
      canvas: canvas,
      x: 0,
      y: 0,
      width: (that.fitSize(275)),
      height: (that.data.sizeHeight),
      success(res) {
        console.log('canvas分享图片地址', res.tempFilePath)
        that.data.loading && wx.hideLoading()
        that.setData({
          canvasImg: res.tempFilePath
        })
        wx.hideLoading()
      },
      fail: (err) => {
        console.log(err, '转换失败')
      }
    })
  },

  //点击图片进行预览,长按保存分享图片
  preImg: function (e) {
    var img = this.data.canvasImg
    wx.previewImage({
      current: img, // 当前显示图片的http链接
      urls: [img] // 需要预览的图片http链接列表
    })
  },

  fitSize(coordinate) {
    let that = this;
    let windowW = that.data.windowW; //这个windowWidth指的是该设备宽度,可以onLoad监听页面加载中获取
    let v = 375 / windowW; //375是设计稿的大小,得到的v值是:设计稿和设备宽度的比例关系,也可理解成在设计稿的大小基础上放大或缩小的倍数
    return coordinate / v; //返回的是当前坐标值或者大小与v的比例
  },


})

2.wxml代码

 <view class="canvas-box" wx:if="{{drawing}}">
    <view class="card-cancle" >
      <canvas type="2d" id="shareCanvas" canvas-id="Canvas" style="width: {{windowW}}px; height: {{ windowH }}px;position:fixed;top:9999px"></canvas>
      <image src="{{canvasImg}}" bindtap="preImg"  	show-menu-by-longpress class="share-image" mode="widthFix" ></image>
    </view>
  </view>
  <view bindtap="shareShow">生成海报</view>

3.wxss代码

.canvas-box{
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  z-index: 10;
  background: rgba(0, 0, 0, .7);

}
.card-cancle {
  /* margin-top: 276rpx; */
  width: 540rpx;
  height: 844rpx;
  /* background: #FFFFFF; */
  border-radius: 8rpx;
    margin: 0 auto;
    margin-top: 310rpx;
}
.share-image {
  width: 540rpx;
  height: 900rpx;

  padding: 1px;
  /* margin-top: 90px; */
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值