微信小程序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 相关文章推荐
jquery库文件略庞大用纯js替换jquery的方法
Aug 12 Javascript
JavaScript实现添加、查找、删除元素
Jul 02 Javascript
详解JavaScript编程中的数组结构
Oct 24 Javascript
jQuery Mobile动态刷新页面样式的实现方法
May 28 Javascript
Vue.js 和 MVVM 的注意事项
Nov 07 Javascript
微信小程序 聊天室简单实现
Apr 19 Javascript
用js将long型数据转换成date型或datetime型的实例
Jul 03 Javascript
Extjs 中的 Treepanel 实现菜单级联选中效果及实例代码
Aug 22 Javascript
深入理解Vue2.x的虚拟DOM diff原理
Sep 27 Javascript
EasyUI的DataGrid绑定Json数据源的示例代码
Dec 16 Javascript
JS实现可视化文件上传
Sep 08 Javascript
原生js实现表格翻页和跳转
Sep 29 Javascript
解决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
php使用GD库创建图片缩略图的方法
2015/06/10 PHP
PHP6连接SQLServer2005的三部曲
2016/04/15 PHP
示例详解Laravel的注册重构
2016/08/14 PHP
网站被恶意镜像怎么办 php一段代码轻松搞定(全面版)
2018/10/23 PHP
修改Laravel自带的认证系统的User类的命名空间的步骤
2019/10/15 PHP
jQuery DOM操作小结与实例
2010/01/07 Javascript
JS 控件事件小结
2012/10/31 Javascript
jQuery 无刷新分页实例代码
2013/11/12 Javascript
jquery live()重复绑定的解决方法介绍
2014/01/03 Javascript
jQuery is()函数用法3例
2014/05/06 Javascript
jQuery实现的Tab滑动选项卡及图片切换(多种效果)小结
2015/09/14 Javascript
JavaScript的History API使搜索引擎抓取AJAX内容
2015/12/07 Javascript
jQuery简单实现仿京东分类导航层效果
2016/06/07 Javascript
Angular2内置指令NgFor和NgIf详解
2016/08/03 Javascript
js实现多行文本框统计剩余字数功能
2017/03/28 Javascript
JS实现禁止高频率连续点击的方法【基于ES6语法】
2017/04/25 Javascript
Vue结合SignalR实现前后端实时消息同步
2017/09/19 Javascript
JavaScript类的继承方法小结【组合继承分析】
2018/07/11 Javascript
[01:06:07]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS CIS
2014/05/22 DOTA
Python 过滤字符串的技巧,map与itertools.imap
2008/09/06 Python
Python实现list反转实例汇总
2014/11/11 Python
python对html代码进行escape编码的方法
2015/05/04 Python
python3实现往mysql中插入datetime类型的数据
2020/03/02 Python
Python学习之路之pycharm的第一个项目搭建过程
2020/06/18 Python
Python识别处理照片中的条形码
2020/11/16 Python
Missguided美国官网:英国时尚品牌
2018/01/18 全球购物
计算机工程学院个人求职信
2013/10/05 职场文书
《听鱼说话》教学反思
2014/02/15 职场文书
面试自我介绍演讲稿
2014/04/29 职场文书
幼儿园师德演讲稿
2014/05/06 职场文书
自主招生英文自荐信
2015/03/25 职场文书
党支部培养考察意见
2015/06/02 职场文书
开网店计划分析
2019/07/30 职场文书
详解Python requests模块
2021/06/21 Python
MySQL高速缓存启动方法及参数详解(query_cache_size)
2021/07/01 MySQL
vue elementUI表格控制对应列
2022/04/13 Vue.js