209 lines
6.9 KiB
JavaScript
209 lines
6.9 KiB
JavaScript
// 获取图片信息,这里主要要获取图片缓存地址
|
||
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)
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|