feat: 首次提交
This commit is contained in:
206
components/firstui/fui-poster/fui-poster.vue
Normal file
206
components/firstui/fui-poster/fui-poster.vue
Normal file
@ -0,0 +1,206 @@
|
||||
<!--本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号: 1 8614 07 2 549,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。-->
|
||||
<template>
|
||||
<!-- #ifndef MP-QQ -->
|
||||
<canvas :style="{ width: w + 'px', height: h + 'px' }" :canvas-id="canvasId" :id="canvasId"
|
||||
class="fui-poster__canvas" v-if="canvasId"></canvas>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- #ifdef MP-QQ -->
|
||||
<canvas :style="{ width: w + 'px', height: h + 'px' }" canvas-id="canvas_poster"
|
||||
class="fui-poster__canvas"></canvas>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// #ifdef MP-WEIXIN
|
||||
const canvasId = `fui_${Math.ceil(Math.random() * 10e5).toString(36)}`
|
||||
// #endif
|
||||
//注意:h5、app-vue 中单个尺寸过大的 canvas 在 iOS/Safari 无法绘制(具体限制尺寸未公布)
|
||||
import poster from './index.js';
|
||||
export default {
|
||||
name: "fui-poster",
|
||||
emits: ['ready'],
|
||||
props: {
|
||||
//画布宽度,单位rpx
|
||||
width: {
|
||||
type: [Number, String],
|
||||
default: 750
|
||||
},
|
||||
//画布高度,单位rpx
|
||||
height: {
|
||||
type: [Number, String],
|
||||
default: 1024
|
||||
},
|
||||
//像素比率,缩放比
|
||||
pixelRatio: {
|
||||
type: [Number, String],
|
||||
// #ifdef MP-ALIPAY
|
||||
default: 3
|
||||
// #endif
|
||||
// #ifndef MP-ALIPAY
|
||||
default: 2
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
data() {
|
||||
//如果小程序端无法识别,则使用固定值
|
||||
// #ifndef MP-WEIXIN || MP-QQ
|
||||
const canvasId = `fui_${Math.ceil(Math.random() * 10e5).toString(36)}`
|
||||
// #endif
|
||||
//vue3下QQ小程序无法使用动态id
|
||||
// #ifdef MP-QQ
|
||||
const canvasId = 'canvas_poster'
|
||||
// #endif
|
||||
return {
|
||||
canvasId,
|
||||
w: 375,
|
||||
h: 512
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
width(val) {
|
||||
this.w = this._toPx(val)
|
||||
},
|
||||
height(val) {
|
||||
this.h = this._toPx(val)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.w = this._toPx(this.width)
|
||||
this.h = this._toPx(this.height)
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
poster.create(Number(this.pixelRatio), this.canvasId, this)
|
||||
this.$emit('ready')
|
||||
}, 50)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
_toPx(rpx) {
|
||||
return uni.upx2px(Number(rpx) * Number(this.pixelRatio))
|
||||
},
|
||||
_getPosterData(texts, blocks, lines, imgs) {
|
||||
let queue = [].concat(texts.map((item) => {
|
||||
item.type = 'text';
|
||||
item.zIndex = item.zIndex || 0;
|
||||
return item;
|
||||
})).concat(blocks.map((item) => {
|
||||
item.type = 'block';
|
||||
item.zIndex = item.zIndex || 0;
|
||||
return item;
|
||||
})).concat(lines.map((item) => {
|
||||
item.type = 'line';
|
||||
item.zIndex = item.zIndex || 0;
|
||||
return item;
|
||||
})).concat(imgs.map((item) => {
|
||||
item.type = 'image';
|
||||
item.zIndex = item.zIndex || 0;
|
||||
return item;
|
||||
}));
|
||||
// 按照顺序排序
|
||||
queue.sort((a, b) => a.zIndex - b.zIndex);
|
||||
return queue;
|
||||
},
|
||||
//生成海报
|
||||
generatePoster(params, callback) {
|
||||
let {
|
||||
texts = [], imgs = [], blocks = [], lines = []
|
||||
} = params;
|
||||
//需要看平台支持情况,如果对应平台不支持将会绘制失败
|
||||
//图片处理 type:1-无需处理(base64、本地路径、网络路径等,需在平台支持下),2-网络图片,下载 3-base64转本地图片(只支持App,微信小程序,H5)
|
||||
if (imgs.length > 0) {
|
||||
let funcArr = []
|
||||
let idxArr = []
|
||||
imgs.forEach((item, index) => {
|
||||
if (item.type == 2) {
|
||||
funcArr.push(poster.getImage(item.imgResource))
|
||||
idxArr.push(index)
|
||||
}
|
||||
// #ifdef APP-PLUS || H5 || MP-WEIXIN
|
||||
if (item.type == 3) {
|
||||
funcArr.push(poster.getImagebyBase64(item.imgResource))
|
||||
idxArr.push(index)
|
||||
}
|
||||
// #endif
|
||||
})
|
||||
if (funcArr.length > 0) {
|
||||
Promise.all(funcArr).then(res => {
|
||||
res.forEach((imgRes, idx) => {
|
||||
let item = imgs[idxArr[idx]]
|
||||
item.imgResource = imgRes
|
||||
// console.log(imgRes)
|
||||
})
|
||||
const queue = this._getPosterData(texts, blocks, lines, imgs);
|
||||
poster.generatePoster(this.width, this.height, queue, callback)
|
||||
|
||||
}).catch(err => {
|
||||
// console.log(err)
|
||||
uni.showToast({
|
||||
title: '图片资源处理失败',
|
||||
icon: 'none'
|
||||
})
|
||||
})
|
||||
} else {
|
||||
const queue = this._getPosterData(texts, blocks, lines, imgs);
|
||||
poster.generatePoster(this.width, this.height, queue, callback)
|
||||
}
|
||||
} else {
|
||||
const queue = this._getPosterData(texts, blocks, lines, imgs);
|
||||
poster.generatePoster(this.width, this.height, queue, callback)
|
||||
}
|
||||
},
|
||||
saveImage(filePath) {
|
||||
poster.saveImage(filePath)
|
||||
},
|
||||
//删除已缓存文件,防止超出存储空间大小限制 【备用】
|
||||
//App、微信小程序、支付宝小程序、百度小程序、抖音小程序、飞书小程序、QQ小程序、京东小程序
|
||||
removeSavedFile() {
|
||||
//使用前请先查看支持平台
|
||||
let count = 0;
|
||||
return new Promise((resolve, reject) => {
|
||||
// #ifdef APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-JD || MP-QQ || MP-LARK
|
||||
uni.getSavedFileList({
|
||||
success(res) {
|
||||
count = res.fileList.length;
|
||||
if (count > 0) {
|
||||
let num = 0;
|
||||
let list = res.fileList || []
|
||||
list.forEach(item => {
|
||||
uni.removeSavedFile({
|
||||
filePath: item.filePath,
|
||||
complete(res) {
|
||||
num++;
|
||||
if (num === count) {
|
||||
resolve(true)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
resolve(true)
|
||||
}
|
||||
},
|
||||
fail() {
|
||||
reject(false)
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-JD || MP-QQ || MP-LARK
|
||||
resolve(true)
|
||||
// #endif
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.fui-poster__canvas {
|
||||
position: fixed;
|
||||
left: -6666px;
|
||||
bottom: 0;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user