栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > Vue.js

前端生成分享海报兼容H5和小程序

Vue.js 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

前端生成分享海报兼容H5和小程序

移动端分享海报生成

最近做项目需求是生成商品分享海报,并且保存到手机中要兼容H5和小程序

与后端同学沟通后,海报在前端生成最省性能和有较好的交互体验,先看做好的效果

github.crmeb.net/u/qiang

前端框架使用的是uni-app方便打包成H5和小程序
实现方案是拿到后端返回的数据后,利用canvas画布把各个数据拼在一起并且生成一张图片
主要的参数有:背景图、商品图、二维码、价格、原价、标题

首先拿到产品图和二维码之后需要把它们下载下来用uni-app的api就可以
先写一个下载方法并且在template 定义画布组件


onReady(){
  this.downloadFileImg('','pic');
  this.downloadFileImg('','code');
},
methods:{
  downloadFileImg(url,name){
    let self = this
    uni.downloadFile({
      url: url,
      success: function(res) {
 self[name] = res.tempFilePath;
      },
      fail: function(erros) {
 console.log(error)
      }
    });
  }
}

这样图片就暂时保存到本地临时文件了

uni.downloadFile 需要注意的是
在各个小程序平台运行时,网络相关的 API 在使用前需要配置域名白名单。在h5上是跨域的,用户需要处理好跨域问题。

下来编写canvas生成图片的方法


PosterCanvas: function(imgArr, store_name, price, ot_price, successFn) {
    let that = this;
    uni.showLoading({
 title: '海报生成中',
 mask: true
    });
    const ctx = uni.createCanvasContext('myCanvas');
    ctx.clearRect(0, 0, 0, 0);

    
    ctx.fillStyle = '#fff';
    ctx.fillRect(0, 0, 750, 1150);
    uni.getImageInfo({
 src: imgArr[0],
 success: function(res) {
     const WIDTH = res.width;
     const HEIGHT = res.height;
     ctx.drawImage(imgArr[1], 0, 0, WIDTH, WIDTH);
     ctx.save();
     let r = 110;
     let d = r * 2;
     let cx = 480;
     let cy = 790;
     ctx.arc(cx + r, cy + r, r, 0, 2 * Math.PI);
     // ctx.clip();
     ctx.drawImage(imgArr[2], cx, cy, d, d);
     ctx.restore();
     const CONTENT_ROW_LENGTH = 20;
     let [contentLeng, contentArray, contentRows] = that.textByteLength(store_name, CONTENT_ROW_LENGTH);
     if (contentRows > 2) {
  contentRows = 2;
  let textArray = contentArray.slice(0, 2);
  textArray[textArray.length - 1] += '……';
  contentArray = textArray;
     }
     ctx.setTextAlign('left');
     ctx.setFontSize(36);
     ctx.setFillStyle('#000');
     // let contentHh = 36 * 1.5;
     let contentHh = 36;
     for (let m = 0; m < contentArray.length; m++) {
  if (m) {
      ctx.fillText(contentArray[m], 50, 1000 + contentHh * m + 18, 1100);
  } else {
      ctx.fillText(contentArray[m], 50, 1000 + contentHh * m, 1100);
  }
     }
     ctx.setTextAlign('left')
     ctx.setFontSize(72);
     ctx.setFillStyle('#DA4F2A');
     ctx.fillText('¥' + price, 40, 820 + contentHh);

     ctx.setTextAlign('left')
     ctx.setFontSize(36);
     ctx.setFillStyle('#999');
     ctx.fillText('¥' + ot_price, 50, 876 + contentHh);
     var underline = function(ctx, text, x, y, size, color, thickness, offset) {
  var width = ctx.measureText(text).width;
  switch (ctx.textAlign) {
      case "center":
   x -= (width / 2);
   break;
      case "right":
   x -= width;
   break;
  }

  y += size + offset;
  ctx.beginPath();
  ctx.strokeStyle = color;
  ctx.lineWidth = thickness;
  ctx.moveTo(x, y);
  ctx.lineTo(x + width, y);
  ctx.stroke();
     }
     underline(ctx, '¥' + ot_price, 55, 865, 36, '#999', 2, 0)
     ctx.setTextAlign('left')
     ctx.setFontSize(28);
     ctx.setFillStyle('#999');
     ctx.fillText('长按或扫描查看', 490, 1030 + contentHh);
     ctx.draw(true, function() {
  uni.canvasToTempFilePath({
      canvasId: 'myCanvas',
      fileType: 'png',
      destWidth: WIDTH,
      destHeight: HEIGHT,
      success: function(res) {
   uni.hideLoading();
   successFn && successFn(res.tempFilePath);
      }
  })
     });
 },
 fail: function(err) {
     uni.hideLoading();
     that.Tips({
  title: '无法获取图片信息'
     });
 }
    })
},

首先创建一个canvas画布

获取背景图图片信息拿到宽和高再绘制商品图片并保存

接下来绘制二维码并把坐标放好并保存

在处理文字换行问题并设置大小颜色和对其方式

在相对应的设置价格和原价的颜色和大小还有坐标

由于价格还有条横线,我在网上又搜下了横线的做法直接看方法就行

最后生成图片信息并且使用uni.canvasToTempFilePath 方法把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径。

这样我们就得到一个.png的临时文件现在就剩最后一步把文件渲染到组件里了,从回调函数就可以回去到

此方法用的比方比较多我把它写到公共方法里面并且绑定到vue原型上面方便我们后面使用

现在编写方法调用

handelCanvas(){
    let imgArr = ['背景图路径',this.pic,this.code]
    this.$util.PosterCanvas(imgArr,'标题','价格','原价',function(tempFilePath){
 console.log(tempFilePath)
    })
}

这样就拿到生成好的图片的是一个临时文件 现在把他放到页面中展示就ok了
保存图片功能H5可以长按保存图片这里只用处理小程序的就行
首先检测授权拿到授权后调用uni-app的api就可以了

savePosterPath: function() {
    let that = this;
    uni.getSetting({
 success(res) {
     if (!res.authSetting['scope.writePhotosAlbum']) {
  uni.authorize({
      scope: 'scope.writePhotosAlbum',
      success() {
   uni.saveImageToPhotosAlbum({
filePath: 'canvas生成的临时图片',
success: function(res) {
    ....成功了
},
fail: function(res) {
    ....失败了
}
   });
      }
  });
     } else {
  uni.saveImageToPhotosAlbum({
      filePath: 'canvas生成的临时图片',
      success: function(res) {
   ....成功了
      },
      fail: function(res) {
   ....失败了
      }
  });
     }
 }
    });
},

这样前端生成海报就大功告成了,你学废了吗?

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号