前端生成分享海报兼容H5和小程序
### 移动端分享海报生成
最近做项目需求是生成商品分享海报,并且保存到手机中要兼容H5和小程序<br>
与后端同学沟通后,海报在前端生成最省性能和有较好的交互体验,先看做好的效果

前端框架使用的是uni-app方便打包成H5和小程序
实现方案是拿到后端返回的数据后,利用canvas画布把各个数据拼在一起并且生成一张图片
主要的参数有:背景图、商品图、二维码、价格、原价、标题
首先拿到产品图和二维码之后需要把它们下载下来用uni-app的api就可以
先写一个下载方法并且在 template 定义画布组件
<template>
<canvas class="canvas" canvas-id="myCanvas" v-if="canvasStatus"></canvas>
</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生成图片的方法
/**
* 获取分享海报
* @param array imgArr 海报素材 0 背景图 1商品图 2二维码
* @param string store_name 素材文字
* @param string price 价格
* @param string ot_price 原始价格
* @param function successFn 回调函数
*/
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) {
....失败了
}
});
}
}
});
},
这样前端生成海报就大功告成了,你学废了吗?
最后打一波广告:
CRMEB商城一个免费开源项目
移动端使用uni-app框架目前已经适配公众号、小程序、app(暂未发布)
管理后台使用vue+iview框架
开源不易,希望各位关注下,说不定你会有意外收获!
地址:http://github.crmeb.net/u/qiang
前端生成分享海报兼容H5和小程序的更多相关文章
- Vue生成分享海报(含二维码)
本文已同步到专业技术网站 www.sufaith.com, 该网站专注于前后端开发技术与经验分享, 包含Web开发.Nodejs.Python.Linux.IT资讯等板块. 功能需求: 海报有1张背景 ...
- MpVue 致力打造H5与小程序的代码共用
MpVue是什么 基于 Vue.js 的小程序开发框架 从底层支持 Vue.js 语法和构建工具体系. 使用vue开发小程序 修改了 Vue.js 的 runtime 和 compiler 实现,使其 ...
- 移动端学习之理解WEB APP、Native APP、Hybrid APP以及React Native/uniapp包括H5、小程序等的区别与共通之处
因为工作需要,需要进一步了解移动端的开发,遂返回复习移动端的知识点,在开始学习之前,产生了疑惑WEB APP .Native APP .Hybrid APP.React Native.Uniapp.H ...
- 仅以一个前端开发人员的角度看微信小程序
看了几天的小程序(当然也包括了上手书写),才有了这篇博文,非技术贴,只是发表下个人观点,仅以个人技术能力来看小程序. 首先说下优点: 调试工具:官方的工具还是做了很多工作,包括监听文件变动自动刷新,编 ...
- 记录一些移动端H5,小程序视觉还原问题及方法
前端,特别是移动端如果对视觉还原要求比较高的时候.功能测试和性能测试完成之后.UI真的是一个像素一个像素的给你抠出来哪里还原不到位 之前项目要求还原度要达到98%以上.所以每到视觉还原的时候真的是挺痛 ...
- 小程序内嵌H5——判断小程序环境的坑
现在各种小程序风靡,这边H5的需求还没有搞定,产品又要求做小程序版本,做可以,关键是618前上线,我-- whatever,618要做推广,日期订了,剩下的就只能是排期,定方案,尽可能完成. 最后和产 ...
- uniapp 在h5和小程序上使用高德获取用户城市位置
开发文档 https://lbs.amap.com/api 错误状态 https://lbs.amap.com/api/webservice/guide/tools/info/ 虽然用的高德但是你还需 ...
- h5与小程序互相跳转,传参和获取参数
1.h5跳转到小程序 首先引入js文件 <script src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js">< ...
- uni-app开发经验分享二十: 微信小程序 授权登录 获取详细信息 获取手机号
授权页面 因为微信小程序提供的 权限弹窗 只能通用户确认授权 所以可以 写一个授权页面,让用户点击 来获取用户相关信息 然后再配合后台就可以完成登录 <button class="bt ...
随机推荐
- App icons generator
App icons generator https://appicon.co/ Drag or select an app icon image (1024x1024) to generate dif ...
- macOS & Catalina vs Big Sur
macOS & Catalina vs Big Sur 乍一看,macOS的色彩更加丰富,最大的变化就是明亮,略带卡通风格的iOS形状的图标. 一切都变得更加圆润,感觉一切都变得更大了. 这可 ...
- 钓鱼教程 All In One
钓鱼教程 All In One youtube https://www.youtube.com/results?search_query=钓鱼教程&sp=CAM%3D 钓鱼证 https:// ...
- Google & Chrome console & text adventure game
Google & Chrome console & text adventure game Google's text adventure game https://www.googl ...
- Flutter: Draggable和DragTarget 可拖动小部件
API class _MyHomeState extends State<MyHome> { List<Map<String, String>> _data1 = ...
- 「NGK每日快讯」2021.1.8日NGK第66期官方快讯!
- Echarts制作一张全球疫情图
一.获取全球疫情数据 1)获取API 使用用友提供的新冠肺炎实时数据,登录注册之后可以免费使用. 2)点击用户信息 这里的AIPCODE,复制并保存,用于后续的使用. 3)API的使用 用友有提供一个 ...
- 【.NET 与树莓派】控制舵机
不管是小马达,还是大马达,嗯,也就是电机,相信大伙伴们也不会陌生.四驱车是一种很优秀的玩具,从老周小时候就开始流行(动画片<四驱兄弟>估计很多大朋友都看过),直到现在还能看到很多卖四驱车的 ...
- 01、初识Java
目录 前言 一.认识Java 历史介绍 Java介绍 二.认识及安装JDK 1.认识JDK 2.安装JDK 配置与测试 配置注意及不生效解决 3.认识Java虚拟机 三.Java的工作方式 四.jav ...
- canal数据同步 客户端代码实现
1.引入相关依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId ...