uniapp使用wxml-to-canvas开发小程序保存canvas图片

2024-01-10 23:44

本文主要是介绍uniapp使用wxml-to-canvas开发小程序保存canvas图片,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

微信小程序官方解决方案:wxml-to-canvas

使用wxml-to-canvas要知道一些前提条件
1、只能画view,text,image
2、每个元素必须要设置宽高
3、默认是flex布局,可以通过flexDirection: "column"来改变排列方式
4、文字 必须放在text中,放在view中无法显示,且text不支持字体加粗
5、如果你要设置背景颜色,请使用backgroundColor,而非background,border同理~
6、多个absolute元素时,因为没有z-index,template元素自上而下渲染,对应z-index依次增高
7、导出图片过大,可以通过canvasToTempFilePath({fileType, quality})配置里面的quality字段来减小
8、image只支持临时地址和网络地址,不支持base64和本地图片,可以通过writeFile 把base64转成临时地址
如下:
const fs = wx.getFileSystemManager();
let qrcodeBase64 = QRresult.data;
let qrcodeLink = `${wx.env.USER_DATA_PATH}/qrcodeLink.gif`;
fs.writeFile({filePath: qrcodeLink,data: qrcodeBase64,encoding: 'base64',success: res => {console.log(res)shopJson.qrcode = qrcodeLink;this.renderToCanvas();},fail(res) {console.error(res)}
})9、Canvas 初始化问题:为了正确绘制图像,需要确保在调用 canvas.draw() 之前完成所有绘制操作。
10、不支持实时更新:一旦 Canvas 绘制完成,它将成为静态图像,无法实时更新。如果需要实时更新数据可视化图表,可以考虑
使用其他库或组件。
11、长按保存图片问题:wxml-to-canvas 组件默认无法通过长按保存图片功能保存 Canvas 图像。你可能需要自行实现该功能,
并适配不同平台的实现方式。
12、对低版本小程序的兼容性问题:某些较旧的微信小程序版本可能无法完全支持 wxml-to-canvas 组件。在开发之前,请确保目
标用户群体的微信小程序版本。
13、性能问题:复杂的数据可视化图表可能会影响性能,尤其是在绘制大量数据时。尽量优化绘制逻辑,以避免出现卡顿或延迟。
14、与其他组件的兼容性问题:wxml-to-canvas 组件可能与其他小程序组件存在一些兼容性问题,导致样式错乱或布局问题。建
议在使用时进行充分的测试和调试。
15、跨平台问题:wxml-to-canvas 组件目前主要针对微信小程序,可能无法直接适用于其他小程序平台或移动端框架。如果需要
在其他平台上实现类似的功能,可能需要另行寻找适合的解决方案。
16、Canvas 绘图能力限制:由于 Canvas 的绘图能力有限,某些高级的数据可视化需求可能无法直接通过 wxml-to-canvas 组
件实现。在确定方案之前,建议先了解 Canvas 绘图的限制和特性。
17、样式定制问题:某些样式属性或效果可能难以通过 wxml-to-canvas 组件实现,例如阴影、渐变色等。需要根据具体需求考虑
是否能够满足所需的样式效果。
18、开发者工具与真机表现差异:在进行调试和预览时,开发者工具上的表现可能与真机上存在一些差异。建议进行真机测试,以
确保数据可视化图表在不同设备上正常显示。等等...其他未知问题...

一、安装

npm install --save wxml-to-canvas

二、在程序根目录下新建 wxcomponents 文件夹,将node_modules下的 widget-ui 和 wxml-to-canvas 两个文件夹复制进去。

注意:这里有的安装后生成的node_modules还不一样,可直接复制dist里面的即可(如下图)

 三、将/wxcomponents/wxml-to-canvas/index.js中的

module.exports = require("widget-ui");
//改为
module.exports = require("../widget-ui/index.js")

 四、配置pages.json (这样uni-app才会打包wxcomponents)

  • 1. 在需要用到的页面配置
"pages": [{"path": "pages/xxx","style": {"usingComponents": {"wxml-to-canvas": "/wxcomponents/wxml-to-canvas/index"}}},
...
]
  • 2. 或者在globalStyle里面全局配置
"globalStyle": {"navigationBarTextStyle": "black","navigationBarTitleText": "uni-app","navigationBarBackgroundColor": "#F8F8F8","backgroundColor": "#F8F8F8","usingComponents": {"wxml-to-canvas": "/wxcomponents/wxml-to-canvas/index"}
},

五、重点来了,如何使用?

  •  页面配置

<!-- 测试页面,可复制使用 -->
<template><view class="wrap"><!-- 保存canvas测试 --><view class="share-page"><view class="share-page-box" id="box" v-if="show":style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"><wxml-to-canvas class="widget" :width="canvasWidth" :height="canvasHeight"></wxml-to-canvas></view><view class="share-page-box msg-box" v-else :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }">{{ msg }}</view><view class="share-page-btn" @tap="extraImage"><button class="btn-big" :style="getBtnStyle">保存图片</button></view></view></view>
</template><script>
import { wxml, style } from './DomData';
export default {data() {return {show: false, // 是否显示canvascanvasWidth: 320, // 默认canvas宽高canvasHeight: 480,screenWidth: null, // 设备宽度screenHeight: null, // 设备高度// name: '',// pic: '',// chapter1: '',// chapter2: '',widget: null,msg: '加载中,请稍等...', // 提示语listData:[{type:'1',title:'标题一',auther: '张三  2024-01-10',imgsrc:'https://pic1.zhimg.com/80/v2-58fe538a59f870407b1435bfd45893ed_720w.jpeg',text:'本报讯(记者 杜晨薇)上海正在建设东方枢纽项目,浦东国际机场与沪通铁路将实现连通,枢纽周边临空产业、重点项目布局正在规划设计中。为落实上海市政府与中国东方航空集团有限公司(以下简称“中国东航”)合作协议要求,充分利用东方枢纽建设发展机遇期进一步深化合作发展,昨天下午,浦东新区政府与中国东航签署深化合作战略协议。'},{type: '2',title: '标题二',auther: '张三  2024-01-10',imgsrc: 'https://pic1.zhimg.com/80/v2-58fe538a59f870407b1435bfd45893ed_720w.jpeg',text: '本报讯(记者 杜晨薇)上海正在建设东方枢纽项目,浦东国际机场与沪通铁路将实现连通,枢纽周边临空产业、重点项目布局正在规划设计中。为落实上海市政府与中国东方航空集团有限公司(以下简称“中国东航”)合作协议要求,充分利用东方枢纽建设发展机遇期进一步深化合作发展,昨天下午,浦东新区政府与中国东航签署深化合作战略协议。'},{type: '3',title: '标题三',auther: '张三  2024-01-10',imgsrc: 'https://pic1.zhimg.com/80/v2-58fe538a59f870407b1435bfd45893ed_720w.jpeg',text: '本报讯(记者 杜晨薇)上海正在建设东方枢纽项目,浦东国际机场与沪通铁路将实现连通,枢纽周边临空产业、重点项目布局正在规划设计中。为落实上海市政府与中国东方航空集团有限公司(以下简称“中国东航”)合作协议要求,充分利用东方枢纽建设发展机遇期进一步深化合作发展,昨天下午,浦东新区政府与中国东航签署深化合作战略协议。'},{type: '4',title: '标题四',auther: '张三  2024-01-10',imgsrc: 'https://pic1.zhimg.com/80/v2-58fe538a59f870407b1435bfd45893ed_720w.jpeg',text: '本报讯(记者 杜晨薇)上海正在建设东方枢纽项目,浦东国际机场与沪通铁路将实现连通,枢纽周边临空产业、重点项目布局正在规划设计中。为落实上海市政府与中国东方航空集团有限公司(以下简称“中国东航”)合作协议要求,充分利用东方枢纽建设发展机遇期进一步深化合作发展,昨天下午,浦东新区政府与中国东航签署深化合作战略协议。'},{type: '5',title: '标题五',auther: '张三  2024-01-10',imgsrc: 'https://pic1.zhimg.com/80/v2-58fe538a59f870407b1435bfd45893ed_720w.jpeg',text: '本报讯(记者 杜晨薇)上海正在建设东方枢纽项目,浦东国际机场与沪通铁路将实现连通,枢纽周边临空产业、重点项目布局正在规划设计中。为落实上海市政府与中国东方航空集团有限公司(以下简称“中国东航”)合作协议要求,充分利用东方枢纽建设发展机遇期进一步深化合作发展,昨天下午,浦东新区政府与中国东航签署深化合作战略协议。'},]}},methods: {// wxml 转 canvasrenderToCanvas() {console.log('canvasStyle.widget', this.widget)const _wxml = wxml(this.listData);console.log('this.widget', _wxml)const _style = style(this.screenWidth, this.canvasWidth, this.canvasHeight) //this.canvasHeightconst p1 = this.widget.renderToCanvas({ wxml: _wxml, style: _style })console.log('renderToCanvas', p1)p1.then((res) => {console.log('海报生成成功', res);wx.hideLoading()}).catch((err) => {console.log('生成失败', err)})},// 保存到朋友圈extraImage() {if (!this.show) {wx.showToast({ title: '海报生成失败,无法分享到朋友圈', icon: 'none' })return}wx.showLoading({ title: '海报生成中...' })const p2 = this.widget.canvasToTempFilePath({ fileType:'jpg', quality :0.5})let that = this;p2.then(result => {let path = result.tempFilePathwx.getSetting({success: res => {wx.hideLoading()// 非初始化且未授权的情况,需要再次弹窗提示授权if (res.authSetting['scope.writePhotosAlbum'] != undefined && res.authSetting['scope.writePhotosAlbum'] != true) {wx.showModal({title: '是否授权相册权限',content: '需要获取相册权限,请确认授权,否则无法使用相关功能',success: res => {if (res.confirm) {wx.openSetting({success: dataAu => {if (dataAu.authSetting["scope.writePhotosAlbum"] == true) {wx.showToast({title: '授权成功',icon: 'none',duration: 1000});that.saveIMg(path);} else {wx.showToast({title: '授权失败',icon: 'success',duration: 1000});}}});}}});} else {// 初始化且未授权,系统默认会弹窗提示授权// 非初始化且已授权,也会进入这里that.saveIMg(path);}}});})},// 保存到相册async saveIMg(tempFilePath) {wx.saveImageToPhotosAlbum({filePath: tempFilePath,success: async (res) => {wx.showModal({content: '图片已保存,分享给好友吧!',showCancel: false,confirmText: '好的',confirmColor: '#333',success: function (res) {wx.navigateBack({//返回delta: 1});},fail: function (res) {console.log('res', res);}});},fail: function (res) {wx.showToast({title: '您取消了授权',icon: 'none',duration: 2000})}});},},onLoad(options) {console.log('options', options);// 获取设备信息wx.getSystemInfo({success: (res) => {console.log('屏幕',res)this.screenWidth = res.screenWidth;this.canvasWidth = this.screenWidth;this.canvasHeight = this.screenWidth * 8.5;console.log('海报高度:', this.canvasHeight)this.show = true// 数字容器宽度 动态设置 setTimeout(() => {wx.showLoading({ title: '海报加载中...' })this.widget = this.selectComponent('.widget')this.renderToCanvas()}, 1000)}});},
}</script><style lang="scss">
.share-page {background: #cc0202;position: relative;overflow: hidden;// padding: 10rpx;
//   min-height: 100vh;.msg-box {display: flex;align-items: center;text-align: center;justify-content: center;}.share-page-box {margin: 0 auto;position: relative;overflow: hidden;box-shadow: 0rpx 6rpx 20rpx 6rpx rgba(0, 0, 0, 0.2);}.share-page-btn {margin: 0 10rpx 0 10rpx;img {width: 100%;height: 100%;}}
}
</style>
  • DomData.js

/**** @param {*} listData  canvas数据*/export const wxml = (listData) => `
<view class="container">${listData.map(item=>{return `<view class="contentWrap"><view ><image src="`+ item.imgsrc + `"  class="pic1"/><text class="name">`+ item.title + `</text><text class="subtitle">`+ item.auther + `</text></view><view class="bottomcss"><image src="`+ item.imgsrc + `"  class="imgbc"/><view class="tapContent1"><text class="tapname">`+ item.text+`</text></view></view></view>`}).join('')}
</view>
`
/***** @param {*} screenWidth 屏幕宽度* @param {*} canvasWidth  画布宽度* @param {*} canvasHeight  画布高度* @param {*} numberWidth  数字宽度,动态设置* @return {*} */export const style = (screenWidth, canvasWidth, canvasHeight) => {return {"container": {width: canvasWidth,minHeight: canvasHeight,position:'relative',backgroundColor: '#ffffff',justifyContent: 'center',alignItems:'center',overflow: 'hidden'},"bottomcss":{marginTop: 0,},"contentWrap":{position: 'relative',width: canvasWidth * 0.99,marginBottom: 20,marginTop: 5,marginLeft: 1,borderRadius: 20,overflow:'hidden',backgroundColor: '#333333',},"imgbc":{justifyContent: 'center',alignItems: 'center',width: canvasWidth * 0.97,height: canvasWidth,marginBottom: 4,marginLeft: 4,marginTop: 10,borderRadius: 20,overflow: 'hidden',},"tapContent1":{position:'absolute',top: 0,left: 0,},"tapname":{fontSize: 18,color: '#fff',marginLeft: 15,marginTop: 50,overflow: 'hidden',width: canvasWidth * 0.92,height: 400,textAlign: 'left',},"name":{fontSize: 20,color: '#fff',marginLeft: canvasWidth * 0.08,width: canvasWidth * 0.84,height: 30,textAlign: 'center',},"subtitle":{fontSize: 14,color: '#9E9C9C',marginLeft: canvasWidth * 0.08,width: canvasWidth * 0.84,height: 20,textAlign: 'center',},"content": {fontSize: 14,color: '#333',width: canvasWidth * 0.84,height: screenWidth * 0.15,marginLeft: canvasWidth * 0.08,},"pic1": {width: canvasWidth * 0.3,height: screenWidth * 0.3,marginTop: canvasWidth * 0.1,marginLeft: canvasWidth * 0.35,marginBottom: canvasWidth * 0.05,borderRadius: screenWidth * 0.14,overflow: 'hidden',},"pic2": {width: canvasWidth ,height: canvasWidth ,marginTop:10,},"bottom":{width: canvasWidth,height: screenWidth * 0.2,flexDirection: 'row',justifyContent: 'self-start',alignItems: 'center',backgroundColor: '#fafafa',position: 'absolute',bottom: 0,left: 0,},"qr": {width: canvasWidth * 0.14,height: screenWidth * 0.14,marginLeft: canvasWidth * 0.04,marginRight: canvasWidth * 0.04,},"msg": {fontSize: 14,color: '#a1a1a1',width: canvasWidth * 0.74,height: 14,textAlign: 'left'},}
}

 


六、生成的效果图

 


...... 全 剧 终 ......

这篇关于uniapp使用wxml-to-canvas开发小程序保存canvas图片的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/592471

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听