微信小程序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 相关文章推荐
在JavaScript中,为什么要尽可能使用局部变量?
Apr 06 Javascript
JSQL 批量图片切换的实现代码
May 05 Javascript
JavaScript实现网页上的浮动广告的简单方法
Jun 14 Javascript
jquery等宽输出文字插件使用介绍
Sep 18 Javascript
javascript中的循环语句for语句深入理解
Apr 04 Javascript
javascript用函数实现对象的方法
May 14 Javascript
原生js实现倒计时功能(多种格式调用)
Jan 12 Javascript
echarts饼图扇区添加点击事件的实例
Oct 16 Javascript
分享vue.js devtools遇到一系列问题
Oct 24 Javascript
Vue2 SSR渲染根据不同页面修改 meta
Nov 20 Javascript
详解vue指令与$nextTick 操作DOM的不同之处
Aug 02 Javascript
解决LayUI表单获取不到data的问题
Aug 20 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打开文件fopen函数的使用说明
2013/07/05 PHP
php实现的PDO异常处理操作分析
2018/12/27 PHP
潜说js对象和数组
2011/05/25 Javascript
Dom操作之兼容技巧分享
2011/09/20 Javascript
JS判断不同分辨率调用不同的CSS样式文件实现思路及测试代码
2013/01/23 Javascript
jquery.gridrotator实现响应式图片展示画廊效果
2015/06/23 Javascript
javascript字符串函数汇总
2015/12/06 Javascript
深入浅析Extjs中store分组功能的使用方法
2016/04/20 Javascript
JS组件Bootstrap Select2使用方法解析
2016/05/30 Javascript
jQuery Validate让普通按钮触发表单验证的方法
2016/12/15 Javascript
vue.js学习笔记:如何加载本地json文件
2017/01/17 Javascript
js实现图片轮播效果学习笔记
2017/07/26 Javascript
微信小程序登录换取token的教程
2018/05/31 Javascript
JS使用栈判断给定字符串是否是回文算法示例
2019/03/04 Javascript
JS中的变量作用域(console版)
2020/07/18 Javascript
原生js实现点击按钮复制内容到剪切板
2020/11/19 Javascript
[02:19]DOTA2女子战队FOX视频专访:希望更多美眉一起加入
2013/10/15 DOTA
[57:12]完美世界DOTA2联赛循环赛 Inki vs Matador BO2第一场 10.31
2020/11/02 DOTA
python reduce 函数使用详解
2017/12/05 Python
对pytorch的函数中的group参数的作用介绍
2020/02/18 Python
sklearn线性逻辑回归和非线性逻辑回归的实现
2020/06/09 Python
PyQt5 QDockWidget控件应用详解
2020/08/12 Python
HTML5 层的叠加的实现
2020/07/07 HTML / CSS
Claire’s法国:时尚配饰、美容、珠宝、头发
2021/01/16 全球购物
简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程
2016/01/06 面试题
税务专业毕业生自荐信
2013/11/10 职场文书
高中语文教学反思
2014/01/16 职场文书
读书演讲主持词
2014/03/18 职场文书
幼儿园开学寄语
2014/04/03 职场文书
安全保证书范文
2014/04/29 职场文书
语文教育专业求职信
2014/06/28 职场文书
群众路线教育实践活动思想汇报(2014特荐篇)
2014/09/16 职场文书
幼儿园综治宣传月活动总结
2015/05/07 职场文书
《正比例》教学反思
2016/02/23 职场文书
三好学生竞选稿范文
2019/08/21 职场文书
导游词之丽江普济寺
2019/10/22 职场文书