智慧教务系统UniApp前端项目(使用中2025-0517)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

167 lines
4.5 KiB

<!--本文件由FirstUI授权予内蒙古晟誉网络科技有限责任公司手机号15 14 822 8 108身份证尾号1R6T39专用请尊重知识产权勿私下传播违者追究法律责任-->
<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)
}
}
}
</script>
<style scoped>
.fui-poster__canvas {
position: fixed;
left: -6666px;
bottom: 0;
}
</style>