会员权益
This commit is contained in:
208
common/poster.js
Normal file
208
common/poster.js
Normal file
@@ -0,0 +1,208 @@
|
||||
// 获取图片信息,这里主要要获取图片缓存地址
|
||||
export function loadImage(url) {
|
||||
return new Promise(resolve => {
|
||||
uni.getImageInfo({
|
||||
src: url,
|
||||
success: (res) => {
|
||||
resolve(res.path)
|
||||
},
|
||||
fail: () => {
|
||||
resolve("")
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
// 解析海报对象,绘制canvas海报
|
||||
export function createPoster(ctx, posterItemList) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
// 单行文本超出隐藏
|
||||
const textEllipsis = (text, maxWidth) => {
|
||||
let strWidth = ctx.measureText(text).width;
|
||||
const ellipsis = '…';
|
||||
const ellipsisWidth = ctx.measureText(ellipsis).width;
|
||||
if (strWidth > maxWidth && maxWidth > ellipsisWidth) {
|
||||
var len = text.length;
|
||||
while (strWidth >= (maxWidth - ellipsisWidth) && len-- > 0) {
|
||||
text = text.slice(0, len);
|
||||
strWidth = ctx.measureText(text).width;
|
||||
}
|
||||
text += ellipsis;
|
||||
}
|
||||
return text
|
||||
}
|
||||
// 文本换行
|
||||
const breakTextLines = (text, maxWidth) => {
|
||||
const words = text.split('');
|
||||
let line = '';
|
||||
const lines = [];
|
||||
for (let i = 0; i < words.length; i++) {
|
||||
const word = words[i];
|
||||
const testLine = line + word;
|
||||
const metrics = ctx.measureText(testLine);
|
||||
if (metrics.width > maxWidth && i > 0) {
|
||||
lines.push(line);
|
||||
line = word;
|
||||
} else {
|
||||
line = testLine;
|
||||
}
|
||||
}
|
||||
lines.push(line);
|
||||
return lines;
|
||||
};
|
||||
for (let i = 0; i < posterItemList.length; i++) {
|
||||
const temp = posterItemList[i];
|
||||
if (temp.type === 'image') {
|
||||
ctx.setStrokeStyle("rgba(255, 255, 255, 0)")
|
||||
ctx.save()
|
||||
var x = temp.config.x;
|
||||
var y = temp.config.y;
|
||||
var width = temp.config.w;
|
||||
var height = temp.config.h;
|
||||
var radius = temp.config.r || 0;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x + radius, y);
|
||||
ctx.lineTo(x + width - radius, y);
|
||||
ctx.arc(x + width - radius, y + radius, radius, -Math.PI / 2, 0); // 从右边绘制圆角
|
||||
ctx.lineTo(x + width, y + height - radius);
|
||||
ctx.arc(x + width - radius, y + height - radius, radius, 0, Math.PI / 2); // 从底部绘制圆角
|
||||
ctx.lineTo(x + radius, y + height);
|
||||
ctx.arc(x + radius, y + height - radius, radius, Math.PI / 2, Math.PI); // 从左边绘制圆角
|
||||
ctx.lineTo(x, y + radius)
|
||||
ctx.arc(x + radius, y + radius, radius, -Math.PI, -Math.PI / 2);
|
||||
ctx.closePath();
|
||||
ctx.clip();
|
||||
ctx.drawImage(temp.url, temp.config.x, temp.config.y, temp.config.w, temp.config.h);
|
||||
ctx.restore()
|
||||
} else if (temp.type === 'imageGroup') {
|
||||
let itemX = parseFloat(temp.config.x)
|
||||
for (let j in temp.group) {
|
||||
if (j >= 3) break;
|
||||
ctx.drawImage(temp.group[j], itemX, temp.config.y, temp.config.w, temp.config.h);
|
||||
itemX += parseFloat(temp.config.w) + parseFloat(temp.config.space)
|
||||
}
|
||||
} else if (temp.type === 'avatar') {
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
ctx.arc(temp.config.w / 2 + temp.config.x, temp.config.h / 2 + temp.config.y, temp.config
|
||||
.w / 2, 0, Math.PI * 2);
|
||||
ctx.clip();
|
||||
ctx.drawImage(temp.url, temp.config.x, temp.config.y, temp.config.w, temp.config.h);
|
||||
ctx.restore();
|
||||
ctx.setStrokeStyle('#fff');
|
||||
} else if (temp.type === 'text') {
|
||||
if (temp.config.font) ctx.font = temp.config.font
|
||||
else ctx.font = "10px sans-serif"
|
||||
temp.config.fontSize && ctx.setFontSize(temp.config.fontSize);
|
||||
temp.config.color && ctx.setFillStyle(temp.config.color);
|
||||
temp.config.textAlign && ctx.setTextAlign(temp.config.textAlign);
|
||||
ctx.setTextBaseline("middle")
|
||||
if (temp.config.wrap) {
|
||||
const maxWidth = temp.config.maxWidth;
|
||||
const lineHeight = temp.config.lineHeight;
|
||||
const lines = breakTextLines(temp.text, maxWidth);
|
||||
const lineNumber = temp.config.lineNumber || 2;
|
||||
if (temp.config.isVerticalCenter) {
|
||||
temp.config.y += lineHeight * lineNumber / 2 - lines.length * lineHeight / 2
|
||||
}
|
||||
for (let index = 0; index < lineNumber; index++) {
|
||||
if (index >= lines.length) break;
|
||||
let line = lines[index]
|
||||
if (index == lineNumber - 1 && (index + 1) < lines.length) {
|
||||
line = textEllipsis(line + "...", maxWidth)
|
||||
ctx.fillText(line, temp.config.x, temp.config.y + index * lineHeight);
|
||||
} else {
|
||||
ctx.fillText(line, temp.config.x, temp.config.y + index * lineHeight);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const lineHeight = temp.config.lineHeight;
|
||||
if (temp.config.isVerticalCenter) {
|
||||
temp.config.y += lineHeight / 2
|
||||
}
|
||||
temp.text = textEllipsis(temp.text, temp.config.maxWidth)
|
||||
ctx.fillText(temp.text, temp.config.x, temp.config.y);
|
||||
}
|
||||
ctx.stroke();
|
||||
} else if (temp.type === 'textGroup') {
|
||||
let itemX = temp.config.x
|
||||
for (var j in temp.group) {
|
||||
const item = temp.group[j]
|
||||
if (temp.font) ctx.font = temp.font
|
||||
else ctx.font = "10px sans-serif"
|
||||
item.fontSize && ctx.setFontSize(item.fontSize);
|
||||
item.color && ctx.setFillStyle(item.color);
|
||||
temp.config.textAlign && ctx.setTextAlign(temp.config.textAlign);
|
||||
ctx.setTextBaseline("middle")
|
||||
if (item.wrap) {
|
||||
const maxWidth = temp.config.maxWidth - itemX + parseFloat(temp.config.x); // 最大宽度
|
||||
const lineHeight = item.lineHeight; // 行高
|
||||
const lines = breakTextLines(item.text, maxWidth);
|
||||
const lineNumber = item.lineNumber || 2;
|
||||
for (let index = 0; index < lineNumber; index++) {
|
||||
if (index >= lines.length) break;
|
||||
let line = lines[index]
|
||||
if (index == lineNumber - 1 && (index + 1) < lines.length) {
|
||||
line = textEllipsis(line + "...", maxWidth)
|
||||
ctx.fillText(line, itemX, temp.config.y + index * lineHeight);
|
||||
} else {
|
||||
ctx.fillText(line, itemX, temp.config.y + index * lineHeight);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ctx.fillText(item.text, itemX, temp.config.y);
|
||||
}
|
||||
ctx.stroke();
|
||||
itemX += parseFloat(ctx.measureText(item.text).width)
|
||||
}
|
||||
} else if (temp.type === 'line') {
|
||||
ctx.beginPath()
|
||||
ctx.setLineWidth(temp.config.w)
|
||||
ctx.moveTo(temp.config.xo, temp.config.y)
|
||||
ctx.lineTo(temp.config.xt, temp.config.y)
|
||||
ctx.setStrokeStyle(temp.config.color)
|
||||
ctx.stroke()
|
||||
} else if (temp.type === 'function') {
|
||||
temp.function()
|
||||
}
|
||||
}
|
||||
ctx.draw();
|
||||
resolve()
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
// canvas转image图片
|
||||
export function canvasToTempFilePath(canvasId, vm, delay = 50) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 这里canvas绘制完成之后想要存缓存需要一定时间,这里设置了50毫秒
|
||||
setTimeout(() => {
|
||||
uni.canvasToTempFilePath({
|
||||
canvasId: canvasId,
|
||||
success(res) {
|
||||
if (res.errMsg && res.errMsg.indexOf('ok') != -1) resolve(res.tempFilePath);
|
||||
else reject(res)
|
||||
},
|
||||
fail(err) {
|
||||
reject(err)
|
||||
}
|
||||
}, vm);
|
||||
}, delay)
|
||||
})
|
||||
}
|
||||
// 保存图片到相册
|
||||
export function saveImageToPhotosAlbum(imagePath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: imagePath,
|
||||
success(res) {
|
||||
resolve(res)
|
||||
},
|
||||
fail(err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user