微信小程序canvas分享海报功能


Posted in Javascript onOctober 31, 2019

微信小程序canvas分享海报,包含拒绝授权后重新打开授权设置。

这篇文章完善了第一次拒绝授权后再次点击可以打开授权设置,希望可以帮助到爱学习的道友

这里是效果图,图片可以百度上找。

微信小程序canvas分享海报功能

话不多说,直接上代码

最重要的一点,千万不要忘记在json文件里面注册组件和wxml里面引用组件

wxml

<button class='btn' catchtap='createPoster' >生成海报</button>
<my-poster id="getPoster" types="{{type}}" isflag="{{isflag}}" title="{{goods_title}}" bigImg="{{share.img}}" qrcode="{{share.rcode}}" >
</my-poster>

js

data:{ isflag: false // 海报模态框 }
// 生成海报
 createPoster:function(){
 this.setData({ 
 isflag: true
 })
 this.selectComponent('#getPoster').getAvaterInfo();
 },

组件wxml

<view hidden="{{!isflag}}" catchtouchmove="return" class="con-poster" bindtap='closePoster'>
 <!-- 模态框 -->
 <view class='modialog'>
 <view class='canvas-box' id='canvas-container'>
 <canvas canvas-id="myCanvas" style="width:100%;height:100%;"/>
 </view>
 </view>
 <!-- 保存图片按钮 -->
 <view class='save-img' catchtap='saveBtn'>保存图片</view>
</view>

组件wxss

.con-poster{
 width: 100%;
 height: 100%;
 background: rgba(0, 0, 0, 0.5);
 position: fixed;
 top: 0;
 left: 0;
 z-index: 999;
 }
 .modialog{
 width: 660rpx;
 height: 750rpx;
 margin: 100rpx auto 0;
 }
 .canvas-box{
 width: 660rpx;
 height: 750rpx;
 background: #fff;
 }
.save-img{
 width: 660rpx;
 height: 100rpx;
 margin: 30rpx auto 0;
 font-size: 32rpx;
 display: flex;
 justify-content: center;
 align-items: center;
 color: #fff;
 background:linear-gradient(90deg,rgba(56,219,248,1),rgba(81,171,255,1));
}

组件js

properties: {
 isflag:{ // 控制组件开关
 type: Boolean,
 value: true
 }
 bigImg:{ // 大图
 type: String,
 value: ''
 },
 qrcode:{ // 二维码
 type: String,
 value: ''
 },
 title:{ // 标题
 type: String,
 value: '大幅度开发'
 }
}

data: {
 imgHeight: 0
},

methods: {
 //关闭海报
 closePoster: function () {
 this.setData({
 isflag: false
 })
 },

 // 提示框
 toast: function(msg,callback){
 wx.showToast({
 title: msg,
 icon: 'none',
 success(){
 callback && (setTimeout(function(){
 callback()
 },1500))
 }
 })
 },
 
 //下载产品大图
 getAvaterInfo: function () {
 wx.showLoading({
 title: '生成中...',
 mask: true
 });
 var that = this;
 that.setData({
 isflag: true
 })
 var productImage = that.data.bigImg;
 if (productImage) {
 wx.downloadFile({
 url: productImage,
 success: function (res) {
 wx.hideLoading();
 if (res.statusCode === 200) {
 var productSrc = res.tempFilePath;
 that.calculateImg(productSrc, function (data) {
 that.getQrCode(productSrc, data);
 })
 } else {
 that.toast('产品图片下载失败!', () =>{
 var productSrc = "";
 that.getQrCode(productSrc);
 })
 }
 },
 fail: function (err) {
 wx.hideLoading();
 that.toast('请求失败,网络错误', () => {
 that.closePoster()
 })
 }
 })
 } else {
 wx.hideLoading();
 var productSrc = "";
 that.getQrCode(productSrc);
 }
 },
 
 //下载二维码
 getQrCode: function (productSrc, imgInfo = "") {
 wx.showLoading({
 title: '生成中...',
 mask: true,
 });
 var that = this;
 var productCode = that.data.qrcode;
 if (productCode) {
 wx.downloadFile({
 url: productCode,
 success: function (res) {
 wx.hideLoading();
 if (res.statusCode === 200) {
 var codeSrc = res.tempFilePath;
 that.sharePosteCanvas(productSrc, codeSrc, imgInfo);
 } else {
 that.toast('二维码下载失败!', () => {
 var codeSrc = "";
 that.sharePosteCanvas(productSrc, codeSrc, imgInfo);
 })
 }
 },
 fail: function () {
 wx.hideLoading();
 that.toast('请求失败,网络错误', () => {
 that.closePoster()
 })
 }
 })
 } else {
 wx.hideLoading();
 var codeSrc = "";
 that.sharePosteCanvas(productSrc, codeSrc);
 }
 },
 
 //canvas绘制分享海报
 sharePosteCanvas: function (avaterSrc, codeSrc, imgInfo){
 wx.showLoading({
 title: '生成中...',
 mask: true,
 })
 var that = this;
 const ctx = wx.createCanvasContext('myCanvas', that);
 var width = "";
 const query = wx.createSelectorQuery().in(this);
 query.select('#canvas-container').boundingClientRect(function (rect) {
 var width = rect.width;
 var height = rect.height;
 var left = rect.left;
 ctx.setFillStyle('#fff');
 ctx.fillRect(0, 0, width, height);

 //海报大图
 if (avaterSrc) {
 if (imgInfo) {
 var imgheght = parseFloat(imgInfo);
 }
 ctx.drawImage(avaterSrc, 0, 0, width, imgheght ? imgheght : width);
 ctx.setFontSize(14);
 ctx.setFillStyle('#fff');
 ctx.setTextAlign('left');
 }
 
 //海报标题
 if (that.data.title) {
 const CONTENT_ROW_LENGTH = 22; // 正文 单行显示字符长度
 let [contentLeng, contentArray, contentRows] = that.textByteLength((that.data.title).substr(0, 40), CONTENT_ROW_LENGTH);
 ctx.setTextAlign('left');
 ctx.setFillStyle('#000');
 ctx.setFontSize(15);
 let contentHh = 22 * 1;
 for (let m = 0; m < contentArray.length; m++) {
 ctx.fillText(contentArray[m], 15, imgheght + 35 + contentHh * m);
 }
 }
 
 // 绘制二维码
 if (codeSrc) {
 ctx.drawImage(codeSrc, left + 215, imgheght + 20, width / 4, width / 4)
 ctx.setFontSize(10);
 ctx.setFillStyle('#000');
 }
 }).exec()
 setTimeout(function () {
 ctx.draw();
 wx.hideLoading();
 }, 1000)
 },
 
 // 封装每行显示的文本字数
 textByteLength(text, num) { // text为传入的文本 num为单行显示的字节长度
 let strLength = 0;
 let rows = 1;
 let str = 0;
 let arr = [];
 for (let j = 0; j < text.length; j++) {
 if (text.charCodeAt(j) > 255) {
 strLength += 2;
 if (strLength > rows * num) {
 strLength++;
 arr.push(text.slice(str, j));
 str = j;

 rows++;
 }
 } else {
 strLength++;
 if (strLength > rows * num) {
 arr.push(text.slice(str, j));
 str = j;
 rows++;
 }
 }
 }
 arr.push(text.slice(str, text.length));
 return [strLength, arr, rows] // [处理文字的总字节长度,每行显示内容的数组,行数]
 },
 
 //计算图片尺寸
 calculateImg: function (src, cb) {
 var that = this;
 wx.getSystemInfo({
 success(res2) {
 var imgHeight = (res2.windowWidth * 0.65) + 130;
 that.setData({
 imgHeight: imgHeight
 })
 cb(imgHeight - 130);
 }
 })
 },
 
 // 点击保存按钮
 saveBtn(){
 var _this = this
 wx.getSetting({
 success(res) {
 if (res.authSetting['scope.writePhotosAlbum']) { // 第一次授权,并且成功
 _this.saveShareImg();
 } else if (res.authSetting['scope.writePhotosAlbum'] === undefined) { // 未授权
 wx.authorize({
 scope: 'scope.writePhotosAlbum',
 success() {
 _this.saveShareImg();
 },
 fail() {
 _this.toast('您没有授权,无法保存到相册')
 }
 })
 } else { // 第一次授权失败,现在打开设置
 wx.showModal({
 title: '警告',
 content: '请打开授权,否则无法将图片保存在相册中!',
 success(result) {
 if (result.confirm) {
  wx.openSetting({
  success(settingResult) {
  if (settingResult.authSetting['scope.writePhotosAlbum']) {
  _this.saveShareImg();
  } else {
  _this.toast('您没有授权,无法保存到相册')
  }
  }
  })
 }
 }
 })
 }
 }
 })
 },
 
 // 保存到相册
 saveShareImg: function () {
 var that = this;
 wx.showLoading({
 title: '正在保存',
 mask: true,
 })
 setTimeout(function () {
 wx.canvasToTempFilePath({
 canvasId: 'myCanvas',
 success: function (res) {
 var tempFilePath = res.tempFilePath;
 wx.saveImageToPhotosAlbum({
 filePath: tempFilePath,
 success() { // 保存
 wx.hideLoading()
 that.toast('图片保存成功', () =>{
  that.closePoster();
 })
 },
 fail: function (err) { // 取消保存
 wx.hideLoading()
 that.toast('保存失败')
 }
 })
 }
 }, that);
 }, 1000);
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
YUI的Tab切换实现代码
Apr 11 Javascript
jQuery 遍历- 关于closest() 的方法介绍以及与parents()的方法区别分析
Apr 26 Javascript
JS分页控件 可用于无刷新分页
Jul 23 Javascript
jQuery 追加元素的方法如append、prepend、before
Jan 16 Javascript
jquery实现的横向二级导航效果代码
Aug 26 Javascript
Bootstrap 组件之按钮(二)
May 11 Javascript
jQuery中ajax错误调试分析
Dec 01 Javascript
微信小程序 简单教程实例详解
Jan 13 Javascript
jQuery阻止移动端遮罩层后页面滚动
Mar 15 Javascript
Bootstrap + AngularJS 实现简单的数据过滤字符查找功能
Jul 27 Javascript
基于JavaScript实现大文件上传后端代码实例
Aug 18 Javascript
jQuery实现鼠标拖动图片功能
Mar 04 jQuery
解决vue初始化项目时,一直卡在Project description上的问题
Oct 31 #Javascript
vue项目初始化到登录login页面的示例
Oct 31 #Javascript
vue3 源码解读之 time slicing的使用方法
Oct 31 #Javascript
vue data恢复初始化数据的实现方法
Oct 31 #Javascript
vue和iview实现Scroll 数据无限滚动功能
Oct 31 #Javascript
vue 使用鼠标滚动加载数据的例子
Oct 31 #Javascript
axios 实现post请求时把对象obj数据转为formdata
Oct 31 #Javascript
You might like
jquery 输入框数字限制插件
2009/11/10 Javascript
javascript 模拟点击广告
2010/01/02 Javascript
最新的10款jQuery内容滑块插件分享
2011/09/18 Javascript
原生JavaScript+LESS实现瀑布流
2014/12/12 Javascript
5分钟打造简易高效的webpack常用配置
2017/07/04 Javascript
Koa2 之文件上传下载的示例代码
2018/03/29 Javascript
微信小程序实现底部导航
2018/11/05 Javascript
Vue自定义属性实例分析
2019/02/23 Javascript
vue组件之间的数据传递方法详解
2019/04/19 Javascript
微信小程序 下拉刷新及上拉加载原理解析
2019/11/06 Javascript
vue中如何添加百度统计代码
2020/12/19 Vue.js
[04:11]DOTA2上海特级锦标赛主赛事首日TOP10
2016/03/03 DOTA
跟老齐学Python之总结参数的传递
2014/10/10 Python
Python中的id()函数指的什么
2017/10/17 Python
django在接受post请求时显示403forbidden实例解析
2018/01/25 Python
Python之inspect模块实现获取加载模块路径的方法
2018/10/16 Python
Python面向对象实现一个对象调用另一个对象操作示例
2019/04/08 Python
基于Django静态资源部署404的解决方法
2019/07/28 Python
深入浅析Python科学计算库Scipy及安装步骤
2019/10/12 Python
django日志默认打印request请求信息的方法示例
2020/05/17 Python
python opencv pytesseract 验证码识别的实现
2020/08/28 Python
python 基于PYMYSQL使用MYSQL数据库
2020/12/24 Python
Canvas 文本填充线性渐变的使用详解
2020/06/22 HTML / CSS
这76道Java面试题及答案,祝你能成功通过面试
2016/04/16 面试题
企业演讲稿范文大全
2014/05/20 职场文书
党员个人公开承诺书
2014/08/29 职场文书
软件测试专业推荐信
2014/09/18 职场文书
2014年招商工作总结
2014/11/22 职场文书
煤矿施工安全协议书
2016/03/22 职场文书
女人创业励志语录,句句蕴含能量,激发你的潜能
2019/08/20 职场文书
python基础之while循环语句的使用
2021/04/20 Python
测量JavaScript函数的性能各种方式对比
2021/04/27 Javascript
tensorflow中的数据类型dtype用法说明
2021/05/26 Python
浅谈react useEffect闭包的坑
2021/06/08 Javascript
jQuery实现广告显示和隐藏动画
2021/07/04 jQuery
解决Mysql多行子查询的使用及空值问题
2022/01/22 MySQL