优化证书生成与正式部署配置
This commit is contained in:
@@ -4,8 +4,10 @@
|
||||
const state = document.getElementById("renderState");
|
||||
const qrScratch = document.getElementById("qrScratch");
|
||||
|
||||
const W = canvas.width;
|
||||
const H = canvas.height;
|
||||
const W = 1024;
|
||||
const H = 759;
|
||||
let scaleX = 1;
|
||||
let scaleY = 1;
|
||||
|
||||
const text = {
|
||||
loading: "\u52a0\u8f7d\u4e2d",
|
||||
@@ -53,8 +55,11 @@
|
||||
controls.showDebug = document.getElementById("showDebug");
|
||||
|
||||
const original = new Image();
|
||||
original.src = "./assets/original.jpg";
|
||||
original.onload = render;
|
||||
original.src = "./assets/original.png";
|
||||
original.onload = () => {
|
||||
syncCanvasSize(true);
|
||||
render();
|
||||
};
|
||||
original.onerror = () => {
|
||||
state.textContent = text.imageFailed;
|
||||
render();
|
||||
@@ -104,9 +109,12 @@
|
||||
function render() {
|
||||
try {
|
||||
state.textContent = text.rendering;
|
||||
ctx.clearRect(0, 0, W, H);
|
||||
|
||||
const usingOriginal = controls.showOriginal.checked && original.complete && original.naturalWidth;
|
||||
syncCanvasSize(usingOriginal);
|
||||
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.setTransform(scaleX, 0, 0, scaleY, 0, 0);
|
||||
|
||||
if (usingOriginal) {
|
||||
ctx.drawImage(original, 0, 0, W, H);
|
||||
@@ -115,7 +123,7 @@
|
||||
drawFallbackBase();
|
||||
}
|
||||
|
||||
drawStudentName();
|
||||
drawStudentName();
|
||||
drawMainText();
|
||||
drawIssueDate();
|
||||
drawCertificateNo();
|
||||
@@ -139,9 +147,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
function syncCanvasSize(usingOriginal) {
|
||||
const nextWidth = usingOriginal ? original.naturalWidth : W;
|
||||
const nextHeight = usingOriginal ? original.naturalHeight : H;
|
||||
if (canvas.width !== nextWidth) canvas.width = nextWidth;
|
||||
if (canvas.height !== nextHeight) canvas.height = nextHeight;
|
||||
scaleX = nextWidth / W;
|
||||
scaleY = nextHeight / H;
|
||||
}
|
||||
|
||||
const areas = [
|
||||
{ x: 150, y: 442, w: 760, h: 132, pad: 16 },
|
||||
{ x: 404, y: 675, w: 220, h: 38, pad: 10 }
|
||||
{ x: 150, y: 455, w: 760, h: 119, pad: 16 }
|
||||
];
|
||||
|
||||
function eraseEditableAreas() {
|
||||
@@ -152,11 +168,12 @@
|
||||
if (!original.complete || !original.naturalWidth) return;
|
||||
|
||||
const pad = area.pad || 8;
|
||||
const sourceX = 72;
|
||||
const sourceW = 88;
|
||||
const sourceX = Math.round((area.sourceX || 72) * scaleX);
|
||||
const sourceY = Math.round((area.sourceY || Math.max(0, area.y - pad)) * scaleY);
|
||||
const sourceW = Math.round(88 * scaleX);
|
||||
const patch = document.createElement("canvas");
|
||||
patch.width = area.w + pad * 2;
|
||||
patch.height = area.h + pad * 2;
|
||||
patch.width = Math.round((area.w + pad * 2) * scaleX);
|
||||
patch.height = Math.round((area.h + pad * 2) * scaleY);
|
||||
const p = patch.getContext("2d");
|
||||
|
||||
for (let x = 0; x < patch.width; x += sourceW) {
|
||||
@@ -164,7 +181,7 @@
|
||||
p.drawImage(
|
||||
original,
|
||||
sourceX,
|
||||
Math.max(0, area.y - pad),
|
||||
sourceY,
|
||||
tileW,
|
||||
patch.height,
|
||||
x,
|
||||
@@ -176,7 +193,7 @@
|
||||
|
||||
p.globalCompositeOperation = "destination-in";
|
||||
p.globalCompositeOperation = "source-over";
|
||||
p.globalAlpha = 0.38;
|
||||
p.globalAlpha = area.blendAlpha || 0.38;
|
||||
p.fillStyle = "#fbf7ef";
|
||||
p.fillRect(0, 0, patch.width, patch.height);
|
||||
p.globalAlpha = 1;
|
||||
@@ -199,7 +216,10 @@
|
||||
p.fillStyle = gx;
|
||||
p.fillRect(0, 0, patch.width, patch.height);
|
||||
|
||||
ctx.drawImage(patch, area.x - pad, area.y - pad);
|
||||
ctx.save();
|
||||
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
ctx.drawImage(patch, Math.round((area.x - pad) * scaleX), Math.round((area.y - pad) * scaleY));
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
function drawFallbackBase() {
|
||||
@@ -244,17 +264,17 @@
|
||||
let x = 185;
|
||||
const y = 494;
|
||||
x = drawInlineText(text.inWord, x, y, 24, 400, 18);
|
||||
x = drawInlineText(value("startYear"), x, y, 24, 900, 8, "dateNumber");
|
||||
x = drawInlineText(value("startYear"), x, y, 24, 400, 8);
|
||||
x = drawInlineText(text.year, x, y, 24, 400, 12);
|
||||
x = drawInlineText(value("startMonth"), x, y, 24, 900, 6, "dateNumber");
|
||||
x = drawInlineText(value("startMonth"), x, y, 24, 400, 6);
|
||||
x = drawInlineText(text.month, x, y, 24, 400, 12);
|
||||
x = drawInlineText(value("startDay"), x, y, 24, 900, 4, "dateNumber");
|
||||
x = drawInlineText(value("startDay"), x, y, 24, 400, 4);
|
||||
x = drawInlineText(`${text.day}${text.toWord}`, x, y, 24, 400, 12);
|
||||
x = drawInlineText(value("endYear"), x, y, 24, 900, 8, "dateNumber");
|
||||
x = drawInlineText(value("endYear"), x, y, 24, 400, 8);
|
||||
x = drawInlineText(text.year, x, y, 24, 400, 12);
|
||||
x = drawInlineText(value("endMonth"), x, y, 24, 900, 6, "dateNumber");
|
||||
x = drawInlineText(value("endMonth"), x, y, 24, 400, 6);
|
||||
x = drawInlineText(text.month, x, y, 24, 400, 12);
|
||||
x = drawInlineText(value("endDay"), x, y, 24, 900, 4, "dateNumber");
|
||||
x = drawInlineText(value("endDay"), x, y, 24, 400, 4);
|
||||
x = drawInlineText(`${text.day}\u5b8c\u6210\u4e86`, x, y, 24, 400, 8);
|
||||
drawInlineFlow([
|
||||
{ text: `\u201c${value("courseName")}\u201d`, style: "course" },
|
||||
@@ -346,9 +366,12 @@
|
||||
|
||||
function drawIssueDate() {
|
||||
ctx.textAlign = "center";
|
||||
ctx.fillStyle = "#43382f";
|
||||
ctx.fillStyle = "#111";
|
||||
ctx.font = '700 13px "SimSun", serif';
|
||||
ctx.fillText(`${text.issueDate}${value("issueDate")}`, W / 2, 704);
|
||||
const parts = (value("issueDate").match(/\d+/g) || []);
|
||||
ctx.fillText(parts[0] || "", 500, 688);
|
||||
ctx.fillText(parts[1] || "", 535, 688);
|
||||
ctx.fillText(parts[2] || "", 566, 688);
|
||||
}
|
||||
|
||||
function drawCertificateNo() {
|
||||
|
||||
Reference in New Issue
Block a user