viewCertDetail(data).then((res) => {
if (res.result === 200) {
const template = res.data;
const { templateinfo } = template;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 1089;
canvas.height = 768;
const loadResources = async () => {
const backgroundImg = new Image();
backgroundImg.crossOrigin = 'anonymous';
backgroundImg.src = templateinfo.img;
await new Promise((resolve, reject) => {
backgroundImg.onload = resolve;
backgroundImg.onerror = () => {
ELMessage.error('背景图加载失败');
console.error('背景图加载失败:', templateinfo.img);
reject(new Error('背景图加载失败'));
};
});
const signImgs = await Promise.all(
templateinfo.sign.map((item) => {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'anonymous';
img.src = item.url;
img.onload = () => resolve(img);
img.onerror = () => {
ELMessage.error('印章图片加载失败');
console.error('印章图片加载失败:', item.url);
reject(new Error('印章图片加载失败'));
};
});
})
);
const qrImgs = await Promise.all(
templateinfo.qrcode.map(() => {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'anonymous';
img.src = qrImg;
img.onload = () => resolve(img);
img.onerror = () => {
ELMessage.error('二维码图片加载失败');
console.error(
'二维码图片加载失败:',
'https://static.xinxin.pro/images/qrcode.png'
);
reject(new Error('二维码图片加载失败'));
};
});
})
);
const imgComponents = await Promise.all(
templateinfo.picture.map((item) => {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'anonymous';
img.src = Img;
img.onload = () => resolve(img);
img.onerror = () => {
ELMessage.error('图片组件加载失败');
console.error('图片组件加载失败:', item.url);
reject(new Error('图片组件加载失败'));
};
});
})
);
return {
backgroundImg,
signImgs,
qrImgs,
imgComponents,
};
};
const drawAll = async () => {
try {
const resources = await loadResources();
const { backgroundImg, signImgs, qrImgs, imgComponents } = resources;
const ratio = canvas.height / backgroundImg.height;
const drawWidth = backgroundImg.width * ratio;
const drawHeight = canvas.height;
const drawX = (canvas.width - drawWidth) / 2;
const drawY = 0;
ctx.drawImage(backgroundImg, drawX, drawY, drawWidth, drawHeight);
templateinfo.para.forEach((item, index) => {
console.log(item.font.size, item.font.family, 8888888888);
ctx.font = `${item.font.size}px ${item.font.family || ''}`;
ctx.fillStyle = item.font.color;
ctx.textBaseline = 'top';
const textWidth = ctx.measureText(item.size).width;
const textHeight = ctx.measureText(item.size).height;
console.log(item);
let drawX;
if (item.font.textalign === 'left') {
drawX = item.position.left;
} else if (item.font.textalign == 'center') {
drawX = item.position.left + textWidth / 2 - item.font.size * 1.6;
} else if (item.font.textalign == 'right') {
drawX =
item.position.left + item.size.width - item.text.length * 1;
} else {
drawX =
item.position.left + item.size.width / 2 - item.text.length * 1;
}
ctx.fillText(item.text, drawX, item.position.top);
item.variable.forEach((varItem, varIndex) => {
ctx.font = `${varItem.bold} ${varItem.size}px ${item.font.family}`;
ctx.fillStyle = varItem.color;
ctx.fillText(
varItem.name,
item.position.left + varItem.index * 10,
item.position.top + varIndex * 20
);
});
});
templateinfo.sign.forEach((item, index) => {
ctx.drawImage(
signImgs[index],
item.position.left,
item.position.top,
item.size.width,
item.size.height
);
});
templateinfo.qrcode.forEach((item, index) => {
ctx.drawImage(
qrImgs[index],
item.position.left,
item.position.top,
item.size.width,
item.size.height
);
});
templateinfo.picture.forEach((item, index) => {
ctx.drawImage(
imgComponents[index],
item.position.left,
item.position.top,
item.size.width,
item.size.height
);
});
if (templateinfo.watermark.text) {
ctx.save();
ctx.font = `${templateinfo.watermark.fontSize}px sans-serif`;
ctx.fillStyle = templateinfo.watermark.color;
ctx.globalAlpha = templateinfo.watermark.alpha;
const text = templateinfo.watermark.text;
const textWidth = ctx.measureText(text).width;
const textHeight =
parseInt(templateinfo.watermark.fontSize, 10) * 1.2;
const horizontalSpacing = templateinfo.watermark.xSpace || 0;
const verticalSpacing = templateinfo.watermark.ySpace || 0;
const offsetX = templateinfo.watermark.left || 0;
const offsetY = templateinfo.watermark.top || 0;
const rotation = (templateinfo.watermark.rotate * Math.PI) / 180;
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(rotation);
const rotatedWidth =
Math.abs(canvas.width * Math.cos(rotation)) +
Math.abs(canvas.height * Math.sin(rotation));
const rotatedHeight =
Math.abs(canvas.width * Math.sin(rotation)) +
Math.abs(canvas.height * Math.cos(rotation));
let startX = -rotatedWidth / 2 + offsetX;
let startY = -rotatedHeight / 2 + offsetY;
for (
let y = startY;
y < rotatedHeight;
y += textHeight + verticalSpacing
) {
for (
let x = startX;
x < rotatedWidth;
x += textWidth + horizontalSpacing
) {
ctx.fillText(text, x, y);
}
}
ctx.restore();
} else if (templateinfo.watermark.imgUrl) {
const img = new Image();
img.crossOrigin = 'anonymous';
img.src = templateinfo.watermark.imgUrl;
await new Promise((resolve, reject) => {
img.onload = resolve;
img.onerror = () => {
console.error(
'水印图片加载失败:',
templateinfo.watermark.imgUrl
);
reject(new Error('水印图片加载失败'));
};
});
ctx.save();
ctx.globalAlpha = templateinfo.watermark.alpha;
const horizontalSpacing = templateinfo.watermark.xSpace || 0;
const verticalSpacing = templateinfo.watermark.ySpace || 0;
const offsetX = templateinfo.watermark.left || 0;
const offsetY = templateinfo.watermark.top || 0;
const rotation = (templateinfo.watermark.rotate * Math.PI) / 180;
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(rotation);
const rotatedWidth =
Math.abs(canvas.width * Math.cos(rotation)) +
Math.abs(canvas.height * Math.sin(rotation));
const rotatedHeight =
Math.abs(canvas.width * Math.sin(rotation)) +
Math.abs(canvas.height * Math.cos(rotation));
let startX = -rotatedWidth / 2 + offsetX;
let startY = -rotatedHeight / 2 + offsetY;
const imgWidth = templateinfo.watermark.width || img.width;
const imgHeight = templateinfo.watermark.height || img.height;
for (
let y = startY;
y < rotatedHeight;
y += imgHeight + verticalSpacing
) {
for (
let x = startX;
x < rotatedWidth;
x += imgWidth + horizontalSpacing
) {
ctx.drawImage(img, x, y, imgWidth, imgHeight);
}
}
ctx.restore();
}
const imgDataUrl = canvas.toDataURL('image/png');
const newWindow = window.open('', '_blank');
if (newWindow) {
newWindow.document.write(`
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #f0f0f0;
}
img {
max-width: 100%;
max-height: 100vh;
object-fit: contain;
}
</style>
</head>
<body>
<img src="${imgDataUrl}" alt="Preview">
</body>
</html>
`);
} else {
console.error('无法打开新窗口,请检查浏览器设置。');
}
} catch (error) {
console.error('图片加载或绘制过程中出现错误:', error);
}
};
drawAll();
} else {
ElMessage.error(res.message);
}
});