mirror of
https://github.com/ialley-workshop-open/uni-halo.git
synced 2026-06-12 21:29:31 +08:00
update: 优化文章详情海报图片在安卓下显示不完整问题
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
## 1.1.0(2023-07-05)
|
||||
优化APP端生成逻辑
|
||||
## 1.0.9(2023-07-04)
|
||||
优化
|
||||
## 1.0.8(2023-07-04)
|
||||
增加注意事项
|
||||
## 1.0.7(2023-07-04)
|
||||
修改本地图片不显示问题
|
||||
## 1.0.6(2023-06-26)
|
||||
优化
|
||||
## 1.0.5(2023-06-09)
|
||||
增加子集绘制
|
||||
## 1.0.4(2023-06-09)
|
||||
增加子集绘制
|
||||
## 1.0.3(2023-06-08)
|
||||
增加预览二维码
|
||||
## 1.0.2(2023-05-31)
|
||||
增加license
|
||||
## 1.0.1(2023-05-30)
|
||||
增加示例
|
||||
## 1.0.0(2023-05-30)
|
||||
初始化发布
|
||||
@@ -0,0 +1,377 @@
|
||||
<template>
|
||||
<view class="canvas-main">
|
||||
<canvas :style="'width:'+width+'rpx;height:'+height+'rpx;'" class="canvas-item" disable-scroll="true"
|
||||
canvas-id="canvasId" @error="error"></canvas>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
//画布宽度(rpx)
|
||||
width: {
|
||||
type: Number,
|
||||
default: 750
|
||||
},
|
||||
//画布高度(rpx)
|
||||
height: {
|
||||
type: Number,
|
||||
default: 750
|
||||
},
|
||||
//生成的图片格式(jpg或png)
|
||||
fileType: {
|
||||
type: String,
|
||||
default: 'png'
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pixelRatio: 0,
|
||||
context: null,
|
||||
canvasList: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async init(list) {
|
||||
uni.showLoading({
|
||||
title: '正在绘制...'
|
||||
})
|
||||
if (this.context) {
|
||||
await this.clear()
|
||||
this.canvasList = []
|
||||
this.context = null
|
||||
}
|
||||
this.canvasList = JSON.parse(JSON.stringify(list))
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
this.pixelRatio = systemInfo.pixelRatio
|
||||
this.context = uni.createCanvasContext('canvasId', this)
|
||||
this.start()
|
||||
},
|
||||
clear() {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
await this.context.clearRect(0, 0, this.width, this.height)
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
async start() {
|
||||
await Promise.all(this.canvasList.map(async res => {
|
||||
if (res.type == 'color') {
|
||||
await this.drawBg(res)
|
||||
} else if (res.type == 'image') {
|
||||
await this.drawImage(res)
|
||||
} else if (res.type == 'text') {
|
||||
await this.drawText(res)
|
||||
} else if (res.type == 'line') {
|
||||
await this.drawLine(res)
|
||||
}
|
||||
}))
|
||||
this.save()
|
||||
},
|
||||
drawBg(item) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
item.width = uni.upx2px(item.width)
|
||||
item.height = uni.upx2px(item.height)
|
||||
item.x = uni.upx2px(item.x)
|
||||
item.y = uni.upx2px(item.y)
|
||||
item.radius = uni.upx2px(item.radius)
|
||||
item.lineWidth = uni.upx2px(item.lineWidth)
|
||||
let gradient = ''
|
||||
if (item.colorObj && item.colorObj.colorList) {
|
||||
if (item.colorObj.colorList.length == 1) {
|
||||
this.context.fillStyle = item.colorObj.colorList[0]
|
||||
} else {
|
||||
if (item.colorObj.direction == 1) {
|
||||
gradient = this.context.createLinearGradient(0, 0, item.height, 0)
|
||||
} else if (item.colorObj.direction == 2) {
|
||||
gradient = this.context.createLinearGradient(0, 0, 0, item.height)
|
||||
} else if (item.colorObj.direction == 3) {
|
||||
gradient = this.context.createLinearGradient(0, 0, item.width, item.height)
|
||||
} else if (item.colorObj.direction == 4) {
|
||||
gradient = this.context.createLinearGradient(item.width, 0, 0, item.height)
|
||||
}
|
||||
gradient.addColorStop(0, item.colorObj.colorList[0])
|
||||
gradient.addColorStop(1, item.colorObj.colorList[1])
|
||||
this.context.fillStyle = gradient
|
||||
}
|
||||
} else {
|
||||
this.context.fillStyle = '#FFFFFF'
|
||||
}
|
||||
this.context.save()
|
||||
if (item.radius > 0) {
|
||||
this.context.beginPath()
|
||||
this.context.moveTo(item.x + item.radius, item.y)
|
||||
this.context.arcTo(item.x + item.width, item.y, item.x + item.width, item.y +
|
||||
item.radius, item.radius)
|
||||
this.context.lineTo(item.x + item.width, item.y + item.height - item.radius)
|
||||
this.context.arcTo(item.x + item.width, item.y + item.height, item.x + item
|
||||
.width - item.radius, item.y + item.height, item.radius)
|
||||
this.context.lineTo(item.x + item.radius, item.y + item.height)
|
||||
this.context.arcTo(item.x, item.y + item.height, item.x, item.y + item
|
||||
.height - item.radius, item.radius)
|
||||
this.context.lineTo(item.x, item.y + item.radius)
|
||||
this.context.arcTo(item.x, item.y, item.x + item.radius, item.y, item.radius)
|
||||
this.context.closePath()
|
||||
this.context.clip()
|
||||
}
|
||||
this.context.fillRect(item.x, item.y, item.width, item.height)
|
||||
if (item.lineWidth) {
|
||||
this.context.setLineDash([])
|
||||
this.context.lineWidth = item.lineWidth
|
||||
this.context.strokeStyle = item.lineColor
|
||||
this.context.beginPath()
|
||||
this.context.moveTo(item.x + item.radius, item.y)
|
||||
this.context.arcTo(item.x + item.width, item.y, item.x + item.width, item.y +
|
||||
item.radius, item.radius)
|
||||
this.context.lineTo(item.x + item.width, item.y + item.height - item.radius)
|
||||
this.context.arcTo(item.x + item.width, item.y + item.height, item.x + item
|
||||
.width - item.radius, item.y + item.height, item.radius)
|
||||
this.context.lineTo(item.x + item.radius, item.y + item.height)
|
||||
this.context.arcTo(item.x, item.y + item.height, item.x, item.y + item
|
||||
.height - item.radius, item.radius)
|
||||
this.context.lineTo(item.x, item.y + item.radius)
|
||||
this.context.arcTo(item.x, item.y, item.x + item.radius, item.y, item.radius)
|
||||
this.context.closePath()
|
||||
this.context.stroke()
|
||||
}
|
||||
this.context.restore()
|
||||
await this.context.draw(true)
|
||||
if (item.childs && item.childs.length > 0) {
|
||||
await Promise.all(item.childs.map(async res => {
|
||||
if (res.type == 'color') {
|
||||
await this.drawBg(res)
|
||||
} else if (res.type == 'image') {
|
||||
await this.drawImage(res)
|
||||
} else if (res.type == 'text') {
|
||||
await this.drawText(res)
|
||||
} else if (res.type == 'line') {
|
||||
await this.drawLine(res)
|
||||
}
|
||||
}))
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
drawImage(item) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
item.width = uni.upx2px(item.width)
|
||||
item.height = uni.upx2px(item.height)
|
||||
item.x = uni.upx2px(item.x)
|
||||
item.y = uni.upx2px(item.y)
|
||||
item.radius = uni.upx2px(item.radius)
|
||||
item.lineWidth = uni.upx2px(item.lineWidth)
|
||||
await this.getImageInfo(item.path).then(async res => {
|
||||
this.context.save()
|
||||
if (item.radius > 0) {
|
||||
this.context.beginPath()
|
||||
this.context.moveTo(item.x + item.radius, item.y)
|
||||
this.context.arcTo(item.x + item.width, item.y, item.x + item.width,
|
||||
item.y +
|
||||
item.radius, item.radius)
|
||||
this.context.lineTo(item.x + item.width, item.y + item.height - item
|
||||
.radius)
|
||||
this.context.arcTo(item.x + item.width, item.y + item.height, item.x +
|
||||
item
|
||||
.width - item.radius, item.y + item.height, item.radius)
|
||||
this.context.lineTo(item.x + item.radius, item.y + item.height)
|
||||
this.context.arcTo(item.x, item.y + item.height, item.x, item.y + item
|
||||
.height - item.radius, item.radius)
|
||||
this.context.lineTo(item.x, item.y + item.radius)
|
||||
this.context.arcTo(item.x, item.y, item.x + item.radius, item.y, item
|
||||
.radius)
|
||||
this.context.closePath()
|
||||
this.context.clip()
|
||||
}
|
||||
await this.context.drawImage(res, item.x, item.y, item.width, item
|
||||
.height)
|
||||
if (item.lineWidth) {
|
||||
this.context.setLineDash([])
|
||||
this.context.lineWidth = item.lineWidth
|
||||
this.context.strokeStyle = item.lineColor
|
||||
this.context.beginPath()
|
||||
this.context.moveTo(item.x + item.radius, item.y)
|
||||
this.context.arcTo(item.x + item.width, item.y, item.x + item.width,
|
||||
item.y +
|
||||
item.radius, item.radius)
|
||||
this.context.lineTo(item.x + item.width, item.y + item.height - item
|
||||
.radius)
|
||||
this.context.arcTo(item.x + item.width, item.y + item.height, item.x +
|
||||
item
|
||||
.width - item.radius, item.y + item.height, item.radius)
|
||||
this.context.lineTo(item.x + item.radius, item.y + item.height)
|
||||
this.context.arcTo(item.x, item.y + item.height, item.x, item.y + item
|
||||
.height - item.radius, item.radius)
|
||||
this.context.lineTo(item.x, item.y + item.radius)
|
||||
this.context.arcTo(item.x, item.y, item.x + item.radius, item.y, item
|
||||
.radius)
|
||||
this.context.closePath()
|
||||
this.context.stroke()
|
||||
}
|
||||
this.context.restore()
|
||||
await this.context.draw(true)
|
||||
if (item.childs && item.childs.length > 0) {
|
||||
await Promise.all(item.childs.map(async res => {
|
||||
if (res.type == 'color') {
|
||||
await this.drawBg(res)
|
||||
} else if (res.type == 'image') {
|
||||
await this.drawImage(res)
|
||||
} else if (res.type == 'text') {
|
||||
await this.drawText(res)
|
||||
} else if (res.type == 'line') {
|
||||
await this.drawLine(res)
|
||||
}
|
||||
}))
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
drawText(item) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
item.width = uni.upx2px(item.width)
|
||||
item.height = uni.upx2px(item.height)
|
||||
item.x = uni.upx2px(item.x)
|
||||
item.y = uni.upx2px(item.y)
|
||||
item.fontSize = uni.upx2px(item.fontSize)
|
||||
item.lineHeight = uni.upx2px(item.lineHeight)
|
||||
await this.drawTextInfo(item.content, item.x, item.y, item.fontSize, item.color, item
|
||||
.width, item.height, item.lineHeight, item.bold, true)
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
drawLine(item) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
item.width = uni.upx2px(item.width)
|
||||
item.startX = uni.upx2px(item.startX)
|
||||
item.startY = uni.upx2px(item.startY)
|
||||
item.endX = uni.upx2px(item.endX)
|
||||
item.endY = uni.upx2px(item.endY)
|
||||
this.context.setStrokeStyle(item.color)
|
||||
this.context.setLineWidth(item.width)
|
||||
this.context.setLineCap('round')
|
||||
if (item.lineType == 'dash') this.context.setLineDash([item.width * 5, item.width * 5], 0)
|
||||
else this.context.setLineDash([])
|
||||
this.context.beginPath()
|
||||
this.context.moveTo(item.startX, item.startY)
|
||||
this.context.lineTo(item.endX, item.endY)
|
||||
this.context.stroke()
|
||||
this.context.closePath()
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
drawTextInfo(text, x, y, fontSize, color, width, height, lineHeight, bold, ellipsis) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
this.context.setFillStyle(color)
|
||||
if (bold) this.context.font = 'bold ' + fontSize + 'px Arial'
|
||||
else this.context.font = fontSize + 'px Arial'
|
||||
this.context.setTextBaseline('bottom')
|
||||
let textArray = text.split('')
|
||||
let line = ''
|
||||
let lines = []
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
let testLine = line + textArray[i]
|
||||
let testWidth = this.context.measureText(testLine).width
|
||||
if (testWidth > width) {
|
||||
lines.push(line)
|
||||
line = textArray[i]
|
||||
} else {
|
||||
line = testLine
|
||||
}
|
||||
}
|
||||
lines.push(line)
|
||||
let firstWidth = this.context.measureText(lines[0]).width
|
||||
if (height >= lineHeight * lines.length) {
|
||||
await Promise.all(lines.map(async (res, i) => {
|
||||
let lineText = res
|
||||
let lineHeights = lineHeight * (i + 1)
|
||||
await this.context.fillText(lineText, x, y + lineHeights)
|
||||
}))
|
||||
} else {
|
||||
let sNum = parseInt(height / lineHeight)
|
||||
lines = lines.slice(0, sNum)
|
||||
await Promise.all(lines.map(async (res, i) => {
|
||||
let lineText = res
|
||||
let lineHeights = lineHeight * (i + 1)
|
||||
if (i == lines.length - 1) {
|
||||
if (this.context.measureText('...').width < fontSize) {
|
||||
lineText = lineText.substring(0, lineText.length - 1)
|
||||
lineText += '...'
|
||||
} else {
|
||||
lineText = lineText.substring(0, lineText.length - 2)
|
||||
lineText += '...'
|
||||
}
|
||||
}
|
||||
await this.context.fillText(lineText, x, y + lineHeights)
|
||||
}))
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
getImageInfo(src) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
if (src.indexOf('http') == -1) {
|
||||
setTimeout(() => {
|
||||
resolve(src)
|
||||
})
|
||||
} else {
|
||||
// #ifdef APP-PLUS
|
||||
uni.getImageInfo({
|
||||
src: src,
|
||||
success: (res) => {
|
||||
resolve(res.path)
|
||||
},
|
||||
fail(err) {
|
||||
resolve(src)
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
uni.downloadFile({
|
||||
url: src,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) resolve(res.tempFilePath)
|
||||
},
|
||||
fail: (err) => {
|
||||
resolve(src)
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
},
|
||||
save() {
|
||||
let timer = setTimeout(async () => {
|
||||
await this.context.draw(true, setTimeout(() => {
|
||||
uni.canvasToTempFilePath({
|
||||
canvasId: 'canvasId',
|
||||
fileType: this.fileType,
|
||||
quality: 1,
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
destWidth: this.width * this.pixelRatio,
|
||||
destHeight: this.height * this.pixelRatio,
|
||||
success: (res) => {
|
||||
uni.hideLoading()
|
||||
this.$emit('change', res.tempFilePath)
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('生成图片失败:', err)
|
||||
}
|
||||
}, this)
|
||||
}, 500))
|
||||
clearTimeout(timer)
|
||||
}, 500)
|
||||
},
|
||||
error(e) {
|
||||
console.log('错误信息:', e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.canvas-main {
|
||||
position: fixed;
|
||||
z-index: -999999 !important;
|
||||
opacity: 0;
|
||||
top: -5000rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,6 @@
|
||||
### 1、本插件可免费下载使用;
|
||||
### 2、未经许可,严禁复制本插件派生同类插件上传插件市场;
|
||||
### 3、未经许可,严禁在插件市场恶意复制抄袭本插件进行违规获利;
|
||||
### 4、对本软件的任何使用都必须遵守这些条款,违反这些条款的个人或组织将面临法律追究。
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"id": "liu-poster",
|
||||
"displayName": "canvas海报画板、海报生成、海报图",
|
||||
"version": "1.1.0",
|
||||
"description": "canvas海报画板、海报生成、海报图组件,配置简单,支持绘制背景色、绘制图片、绘制文本、绘制线条,自由生成海报图片",
|
||||
"keywords": [
|
||||
"海报",
|
||||
"生成海报",
|
||||
"canvas",
|
||||
"图片合成",
|
||||
"图片处理"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "component-vue",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "u"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "u",
|
||||
"app-nvue": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "u",
|
||||
"IE": "u",
|
||||
"Edge": "u",
|
||||
"Firefox": "u",
|
||||
"Safari": "u"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "u",
|
||||
"百度": "u",
|
||||
"字节跳动": "u",
|
||||
"QQ": "u",
|
||||
"钉钉": "u",
|
||||
"快手": "u",
|
||||
"飞书": "u",
|
||||
"京东": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
# liu-poster适用于uni-app项目的canvas海报画板、海报生成、海报图组件
|
||||
### 本组件目前兼容微信小程序、H5
|
||||
### 本组件是canvas海报画板、海报生成、海报图组件,配置简单,支持绘制背景色、绘制图片、绘制文本、绘制线条,自由生成海报图片
|
||||
# --- 扫码预览、关注我们 ---
|
||||
|
||||
## 扫码关注公众号,查看更多插件信息,预览插件效果!
|
||||
|
||||

|
||||
|
||||
### 属性说明
|
||||
| 名称 | 类型 | 默认值 | 描述 |
|
||||
| ----------------------------|--------------- | -------------------- | ---------------|
|
||||
| width | Number | 750 | 画布宽度(rpx)
|
||||
| height | Number | 750 | 画布高度(rpx)
|
||||
| fileType | String | png | 生成的图片格式(jpg或png)
|
||||
| @change | Function | | 海报绘制成功回调事件
|
||||
|
||||
### 使用示例
|
||||
```
|
||||
<template>
|
||||
<view class="tab-box">
|
||||
<view class="btn-complete" @click="open">一键生成海报</view>
|
||||
<liu-poster ref="liuPoster" :width="750" :height="1300" @change="change"></liu-poster>
|
||||
<image class="success-img" :src="url" @click="previewImg(url)"></image>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
canvasList: [{
|
||||
type: 'color', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 750, //宽度(rpx)
|
||||
height: 1300, //高度(rpx)
|
||||
x: 0, //x轴位置(离左边的距离rpx)
|
||||
y: 0, //y轴位置(离上边的距离rpx)
|
||||
radius: 100, //圆角(rpx)
|
||||
lineWidth: 40, //边框宽度(rpx)
|
||||
lineColor: '#000000', //边框颜色
|
||||
colorObj: {
|
||||
colorList: ['#6900FF', '#FFFFFF'], //传入1个值为纯色,2个值为渐变色
|
||||
direction: 2 //渐变色绘制方向(1:从左到右;2:从上到下;3:左上角到右下角;4:右上角到左下角)
|
||||
}, //type为color时必填
|
||||
}, {
|
||||
type: 'image', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 132, //宽度(rpx)
|
||||
height: 132, //高度(rpx)
|
||||
x: 40, //x轴位置(离左边的距离rpx)
|
||||
y: 120, //y轴位置(离上边的距离rpx)
|
||||
radius: 66, //圆角(rpx)
|
||||
lineWidth: 6, //边框宽度(rpx)
|
||||
lineColor: '#FFFFFF', //边框颜色
|
||||
path: 'https://img1.baidu.com/it/u=1471990434,2209509794&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400', //图片地址(type为image时必填)
|
||||
}, {
|
||||
type: 'text', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 400, //文本宽度(rpx)
|
||||
height: 40, //文本高度(rpx)
|
||||
x: 200, //x轴位置(离左边的距离rpx)
|
||||
y: 145, //y轴位置(离上边的距离rpx)
|
||||
color: '#FFFFFF', //文本颜色
|
||||
fontSize: 36, //文字大小(rpx)
|
||||
lineHeight: 36, //文字行高(rpx)
|
||||
bold: true, //文字是否加粗
|
||||
content: '好物分享猫猫虫', //文本内容(type为text时必填)
|
||||
}, {
|
||||
type: 'text', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 400, //文本宽度(rpx)
|
||||
height: 40, //文本高度(rpx)
|
||||
x: 200, //x轴位置(离左边的距离rpx)
|
||||
y: 195, //y轴位置(离上边的距离rpx)
|
||||
color: '#FFFFFF', //文本颜色
|
||||
fontSize: 28, //文字大小(rpx)
|
||||
lineHeight: 28, //文字行高(rpx)
|
||||
bold: false, //文字是否加粗
|
||||
content: '猫猫虫给你分享了一张美图', //文本内容(type为text时必填)
|
||||
}, {
|
||||
type: 'image', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 670, //宽度(rpx)
|
||||
height: 670, //高度(rpx)
|
||||
x: 40, //x轴位置(离左边的距离rpx)
|
||||
y: 300, //y轴位置(离上边的距离rpx)
|
||||
radius: 20, //圆角(rpx)
|
||||
lineWidth: 12, //边框宽度(rpx)
|
||||
lineColor: '#FFFFFF', //边框颜色
|
||||
path: 'https://img1.baidu.com/it/u=1471990434,2209509794&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400', //图片地址(type为image时必填)
|
||||
childs: [{
|
||||
type: 'text', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 400, //文本宽度(rpx)
|
||||
height: 40, //文本高度(rpx)
|
||||
x: 100, //x轴位置(离左边的距离rpx)
|
||||
y: 400, //y轴位置(离上边的距离rpx)
|
||||
color: '#FFFFFF', //文本颜色
|
||||
fontSize: 36, //文字大小(rpx)
|
||||
lineHeight: 36, //文字行高(rpx)
|
||||
bold: true, //文字是否加粗
|
||||
content: '好物分享猫猫虫', //文本内容(type为text时必填)
|
||||
}]
|
||||
}, {
|
||||
type: 'line', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 4, //线条宽度(rpx)
|
||||
color: '#FFFFFF', //线条颜色
|
||||
startX: 20, //起点x轴位置(离左边的距离rpx)
|
||||
startY: 270, //起点y轴位置(离上边的距离rpx)
|
||||
endX: 730, //终点x轴位置(离左边的距离rpx)
|
||||
endY: 270, //终点y轴位置(离上边的距离rpx)
|
||||
lineType: 'dash', //线条类型(solid:实线;dash:虚线)
|
||||
}, {
|
||||
type: 'line', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 4, //线条宽度(rpx)
|
||||
color: '#FFFFFF', //线条颜色
|
||||
startX: 20, //起点x轴位置(离左边的距离rpx)
|
||||
startY: 1000, //起点y轴位置(离上边的距离rpx)
|
||||
endX: 730, //终点x轴位置(离左边的距离rpx)
|
||||
endY: 1000, //终点y轴位置(离上边的距离rpx)
|
||||
lineType: 'dash', //线条类型(solid:实线;dash:虚线)
|
||||
}, {
|
||||
type: 'text', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 500, //文本宽度(rpx)
|
||||
height: 150, //文本高度(rpx)
|
||||
x: 40, //x轴位置(离左边的距离rpx)
|
||||
y: 1050, //y轴位置(离上边的距离rpx)
|
||||
color: '#9043FD', //文本颜色
|
||||
fontSize: 32, //文字大小(rpx)
|
||||
lineHeight: 45, //文字行高(rpx)
|
||||
bold: true, //文字是否加粗
|
||||
content: '这个是一段测试文字,这个是一段测试文字,这个是一段测试文字,这个是一段测试文字,这个是一段测试文字。', //文本内容(type为text时必填)
|
||||
}, {
|
||||
type: 'image', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 150, //宽度(rpx)
|
||||
height: 150, //高度(rpx)
|
||||
x: 550, //x轴位置(离左边的距离rpx)
|
||||
y: 1050, //y轴位置(离上边的距离rpx)
|
||||
radius: 4, //圆角(rpx)
|
||||
lineWidth: 6, //边框宽度(rpx)
|
||||
lineColor: '#FFFFFF', //边框颜色
|
||||
path: 'https://img1.baidu.com/it/u=1471990434,2209509794&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400', //图片地址(type为image时必填)
|
||||
}],
|
||||
url: ''
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
//开始绘制
|
||||
open() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.liuPoster.init(this.canvasList)
|
||||
})
|
||||
},
|
||||
//绘制成功返回生成的海报图片地址
|
||||
change(e) {
|
||||
this.url = e
|
||||
},
|
||||
//预览生成的海报图片
|
||||
previewImg(url) {
|
||||
if (!url) return
|
||||
uni.previewImage({
|
||||
urls: [url]
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tab-box {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
box-sizing: border-box;
|
||||
background-color: #f0f0f0;
|
||||
padding-top: 20rpx;
|
||||
|
||||
.btn-reset {
|
||||
width: 100%;
|
||||
height: 72rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 40rpx;
|
||||
border: 2rpx solid #FD430E;
|
||||
font-size: 30rpx;
|
||||
color: #3E3E3E;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-complete {
|
||||
width: 98%;
|
||||
height: 76rpx;
|
||||
border-radius: 40rpx;
|
||||
font-size: 30rpx;
|
||||
color: #FFFFFF;
|
||||
background-color: #FD430E;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.success-img {
|
||||
width: 100%;
|
||||
height: 1300rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### 传入的canvasList参数说明
|
||||
### 绘制类型有4种:color:背景色;image:图片;text:文字;line:线条
|
||||
```
|
||||
canvasList: [{
|
||||
type: 'color', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 750, //宽度(rpx)
|
||||
height: 1500, //高度(rpx)
|
||||
x: 0, //x轴位置(离左边的距离rpx)
|
||||
y: 0, //y轴位置(离上边的距离rpx)
|
||||
radius: 100, //圆角(rpx)
|
||||
lineWidth: 40, //边框宽度(rpx)
|
||||
lineColor: '#000000', //边框颜色
|
||||
colorObj: {
|
||||
colorList: ['#6900FF', '#FFFFFF'], //传入1个值为纯色,2个值为渐变色
|
||||
direction: 2 //渐变色绘制方向(1:从左到右;2:从上到下;3:左上角到右下角;4:右上角到左下角)
|
||||
}, //type为color时必填
|
||||
childs:[],//在背景色上绘制的内容放在childs里面即可
|
||||
}, {
|
||||
type: 'image', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 132, //宽度(rpx)
|
||||
height: 132, //高度(rpx)
|
||||
x: 40, //x轴位置(离左边的距离rpx)
|
||||
y: 150, //y轴位置(离上边的距离rpx)
|
||||
radius: 66, //圆角(rpx)
|
||||
lineWidth: 2, //边框宽度(rpx)
|
||||
lineColor: '#FFFFFF', //边框颜色
|
||||
path: 'https://img1.baidu.com/it/u=1471990434,2209509794&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400', //图片地址(type为image时必填)
|
||||
childs:[],//如果在图片上绘制其他内容则将要绘制的内容放在childs里面即可
|
||||
}, {
|
||||
type: 'text', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 400, //文本宽度(rpx)
|
||||
height: 100, //文本高度(rpx)
|
||||
x: 200, //x轴位置(离左边的距离rpx)
|
||||
y: 170, //y轴位置(离上边的距离rpx)
|
||||
color: '#FFFFFF', //文本颜色
|
||||
fontSize: 36, //文字大小(rpx)
|
||||
lineHeight: 45, //文字行高(rpx)
|
||||
bold: true, //文字是否加粗
|
||||
content: '好物分享猫猫虫好物分享猫猫虫好物分享猫猫虫好物分享猫猫虫好物分享猫猫虫好物分享猫猫虫好物分享猫猫虫', //文本内容(type为text时必填)
|
||||
}, {
|
||||
type: 'line', //绘制类型(color:背景色;image:图片;text:文字;line:线条),
|
||||
width: 2, //线条宽度(rpx)
|
||||
color: '#FFFFFF', //线条颜色
|
||||
startX: 0, //起点x轴位置(离左边的距离rpx)
|
||||
startY: 310, //起点y轴位置(离上边的距离rpx)
|
||||
endX: 750, //终点x轴位置(离左边的距离rpx)
|
||||
endY: 310, //终点y轴位置(离上边的距离rpx)
|
||||
lineType: 'dash', //线条类型(solid:实线;dash:虚线)
|
||||
}]
|
||||
```
|
||||
|
||||
### 注意
|
||||
# 1、H5端使用网络图片需要解决跨域问题;
|
||||
# 2、小程序使用网络图片需要在微信公众平台配置downloadFile合法域名。
|
||||
Reference in New Issue
Block a user