更新记录
0.0.1(2023-11-16)
下载此版本
完成基本功能
平台兼容性
App |
快应用 |
微信小程序 |
支付宝小程序 |
百度小程序 |
字节小程序 |
QQ小程序 |
HBuilderX 3.8.11 |
× |
√ |
× |
× |
× |
× |
钉钉小程序 |
快手小程序 |
飞书小程序 |
京东小程序 |
× |
× |
× |
× |
H5-Safari |
Android Browser |
微信浏览器(Android) |
QQ浏览器(Android) |
Chrome |
IE |
Edge |
Firefox |
PC-Safari |
× |
× |
× |
× |
× |
× |
× |
× |
× |
0.使用方法
下载zip包后解压,将文件夹内components文件夹复制到项目根目录,然后在任意页面直接引入即可
1.组件介绍
本组件用于将view界面中的text,image,view中的内容保存为图片
2.功能实现原理
本组件本质上是使用离屏canvas来绘制页面上的信息,实现过程如下:
(1)要获取界面中view,image,或text中的数据,可以通过uni.createSelectorQuery() API来获取需要绘制的信息,例如view的宽高,背景色。image的链接地址,绘制位置,大小尺寸等,下面使用说明会详细阐述
(2)将获取到的属性数据创建为一个数组,数组的格式在下面会详细说明。
(3)调用组件中的方法 drawCanvas(array)。组件即根据参数array数组中的数据,创建离屏canvas,并开始绘制。
(4)绘制完成后,可选择保存到本地,或发送给微信好友
3.使用示例
xml
<template>
<view class="content">
<tk-view2canvas ref="tkCanvas"
:canvas-width="canvasWidth"
:canvas-height="canvasHeight">
</tk-view2canvas>
<view class="queryInfo" data-type="view" data-bgcolor="#fff000"
style="display: flex;flex-direction:column; width: 750rpx;height: 960rpx;justify-content: center;align-items: center;" >
<image class="queryInfo" src="../../static/tp.jpg" style="width: 540rpx;height:960rpx;"
data-type="image" data-src="../../static/tp.jpg">
</image>
<text class="queryInfo" data-word="测试文本" data-size="50" data-color="#ff0000" data-type="text"
style="font-size: 50rpx;color: #ff0000;">
测试文本
</text>
</view>
<button @click="toCanvas">调用组件方法</button>
</view>
</template>
script
<script>
let arrayInfo = []
export default {
data() {
return {
canvasWidth: 1080, //canvas的width
canvasHeight: 1920, //canvas的height 我这里简单写成1080*1920.可以根据自己的业务需求去动态修改这个尺寸。
}
},
onLoad() {
},
methods: {
toCanvas(){
let that = this
arrayInfo = []
// 1.先查询要绘制的view,image,text相关属性数据
// 这里我将需要查询的所有view或text或image的类名都设置为queryInfo
uni.createSelectorQuery().selectAll('.queryInfo').boundingClientRect().exec((res)=>{
console.log('获取到信息:',res[0])
let resArray = res[0]
for(let i=0;i<resArray.length;i++){
//1.判断查询到的组件类别,如果是view类,就按照view对应的格式将创建的对象添加到数组中
if(resArray[i].dataset.type == 'view'){
console.log('view')
let bgColor = resArray[i].dataset.bgcolor
let width = resArray[i].width
let height = resArray[i].height
let posX = resArray[i].left
let posY = resArray[i].top
arrayInfo.push({
type:'view',
width: width,
height: height,
bgColor: bgColor,
posX:posX,
posY:posY
})
}//2.判断查询到的组件类别,如果是image类,就按照image对应的格式将创建的对象添加到数组中
else if(resArray[i].dataset.type == 'image'){
console.log('image')
let type = 'image'
let src= resArray[i].dataset.src
let posX = resArray[i].left
let posY = resArray[i].top
let width = resArray[i].width
let height = resArray[i].height
arrayInfo.push({
type:'image',
src: src,
width:width,
height: height,
posX:posX,
posY:posY
})
}//3.判断查询到的组件类别,如果是text类,就按照text对应的格式将创建的对象添加到数组中
else if(resArray[i].dataset.type == 'text'){
console.log('text')
let type = 'text'
let color= resArray[i].dataset.color
let word= resArray[i].dataset.word
let size= resArray[i].dataset.size
let posX = resArray[i].left
let posY = resArray[i].top
arrayInfo.push({
type:'text',
color:color,
word:word,
size:size,
posX:posX,
posY:posY
})
}
}
//查询完毕后,也就创建好了arrayInfo数组,下面将arrayInfo数组作为参数,传给组件的drawCanvas()方法
that.$refs.tkCanvas.drawCanvas(arrayInfo)
})
},
}
}
</script>
4.代码说明
xml中
<tk-view2canvas ref="tkCanvas" :canvas-width="canvasWidth" :canvas-height="canvasHeight">
上面这段代码中, canvas-width,canvas-height,是本组件的两个props
分别代表了,要绘制图片的宽度,高度
定义 ref="tkCanvas" 是为了后面调用这个组件的方法。
<view class="queryInfo" data-type="view" data-bgcolor="#ffffff"
style="display: flex;flex-direction:column; width: 750rpx;height: 960rpx;justify-content: center;align-items: center;" >
<image class="queryInfo" src="../../static/tp.jpg" style="width: 540rpx;height:960rpx;"
data-type="image" data-src="../../static/tp.jpg">
</image>
<text class="queryInfo" data-word="测试文本" data-size="50" data-color="#ff0000" data-type="text"
style="font-size: 50rpx;color: #ff0000;">
测试文本
</text>
</view>
上面这段代码,是要绘制的view,image和text,绘制不同的标签,需要对应不同的属性数据。
script中
由于script中我通过uni.createSelectorQuery() API来获取标签中的数据,所以我在xml代码中使用 data- 的方式来确定需要查询的属性数据。在实际使用中,不一定要按照我的方式来确定属性数据。只需要确保最后传送给组件方法 drawCanvas()* 中的参数格式正确即可。
5.组件方法
drawCanvas(array)
这个方法是实现组件功能最核心的东西,这个参数就是一个数组,这里以下面的数组为例说明
let array = [
{
type: "view",
width: 390,
height: 499,
bgColor: "#fff000",
posX: 0,
posY:0
},
{
type: "image",
src: "图片的网络地址或本地地址",
width: 280,
height: 464,
posX: 55,
posY:55},
{
type: "text",
color: "#ff0000",
word: "测试文本",
size: 50,
posX: 143,
posY: 150
}]
这个数组中,有三个对象:
第一个对象的属性 type 为 view,表示要绘制的是一个view,width表示view的宽度,height表示view的高度,bgColor表示view的背景色,posX表示X轴的位置,posY表示Y轴位置。
第二个对象的属性type 为 image,表示要绘制的是一个image,src表示图片地址,可以是本地图片,也可以是网络图片,width表示图片的宽度,height表示图片的高度,posX表示X轴的位置,posY表示Y轴位置。
第三个对象的属性type 为text,表示要绘制的是一个text文本,color表示文本的颜色,word表示要绘制的字,size,表示文本的字号,posX表示文本的X轴位置,posY表示文本的Y轴位置。
因为canvas的原点(0,0),对应于屏幕的左上角,所以x轴坐标就等于 uni.createSelectorQuery() 查询后得到的标签 left 属性值。y轴坐标就等于uni.createSelectorQuery() 查询后得到的标签 top 属性值
注意:目前本组件只支持这3种type种的对应的这几个属性,数组种添加其他属性是无效的
6.绘制顺序
上面对参数array已经做了详细说明,组件绘制图片的顺序也是根据这个数组的顺序进行绘制,所以再给数组中添加数据是需要确定好需要绘制的顺序是什么。推荐的顺序,就是第一个数据作为整体的背景色或背景图片,然后再根据需要将要添加的图片或文字依次往下排列。
7.存在的BUG
canvas在绘制文字时,其字体、位置、大小可能会和预想的有些出入,应该是跟canvas本身绘图的机制有关。如果大家有比较好的解决方法,希望给我留言,我会尽快完善好