|
|
|
@ -11,7 +11,7 @@ const {
|
|
|
|
|
paddingX,
|
|
|
|
|
hollowPath,
|
|
|
|
|
} = settings;
|
|
|
|
|
const font = `${fontSize}px RoGSanSrfStd-Bd, GlowSansSC-Normal-Heavy_diff, apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif`;
|
|
|
|
|
const font = 'RoGSanSrfStd-Bd, GlowSansSC-Normal-Heavy_diff, apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif';
|
|
|
|
|
|
|
|
|
|
export default class LogoCanvas {
|
|
|
|
|
public canvas: HTMLCanvasElement;
|
|
|
|
@ -26,11 +26,12 @@ export default class LogoCanvas {
|
|
|
|
|
private textWidthR = 0;
|
|
|
|
|
private graphOffset = graphOffset;
|
|
|
|
|
private transparentBg = false;
|
|
|
|
|
private scaleLevel = 1;
|
|
|
|
|
constructor() {
|
|
|
|
|
this.canvas = document.querySelector('#canvas')!;
|
|
|
|
|
this.ctx = this.canvas.getContext('2d')!;
|
|
|
|
|
this.canvas.height = canvasHeight;
|
|
|
|
|
this.canvas.width = canvasWidth;
|
|
|
|
|
this.canvas.height = canvasHeight * this.scaleLevel;
|
|
|
|
|
this.canvas.width = canvasWidth * this.scaleLevel;
|
|
|
|
|
this.bindEvent();
|
|
|
|
|
}
|
|
|
|
|
async draw() {
|
|
|
|
@ -38,12 +39,13 @@ export default class LogoCanvas {
|
|
|
|
|
loading.classList.remove('hidden');
|
|
|
|
|
const c = this.ctx;
|
|
|
|
|
//predict canvas width
|
|
|
|
|
await loadFont(this.textL + this.textR);
|
|
|
|
|
await loadFont(this.textL + this.textR, this.scaleLevel);
|
|
|
|
|
loading.classList.add('hidden');
|
|
|
|
|
c.font = font;
|
|
|
|
|
c.font = `${fontSize * this.scaleLevel}px ${font}`;
|
|
|
|
|
this.textMetricsL = c.measureText(this.textL);
|
|
|
|
|
this.textMetricsR = c.measureText(this.textR);
|
|
|
|
|
this.setWidth();
|
|
|
|
|
this.canvas.height = canvasHeight * this.scaleLevel;
|
|
|
|
|
//clear canvas
|
|
|
|
|
c.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
|
|
|
//Background
|
|
|
|
@ -54,7 +56,7 @@ export default class LogoCanvas {
|
|
|
|
|
//guide line
|
|
|
|
|
if (import.meta.env.DEV) {
|
|
|
|
|
c.strokeStyle = '#00cccc';
|
|
|
|
|
c.lineWidth = 1;
|
|
|
|
|
c.lineWidth = 1 * this.scaleLevel;
|
|
|
|
|
c.beginPath();
|
|
|
|
|
c.moveTo(this.canvasWidthL, 0);
|
|
|
|
|
c.lineTo(this.canvasWidthL, this.canvas.height);
|
|
|
|
@ -68,7 +70,7 @@ export default class LogoCanvas {
|
|
|
|
|
c.stroke();
|
|
|
|
|
}
|
|
|
|
|
//blue text -> halo -> black text -> cross
|
|
|
|
|
c.font = font;
|
|
|
|
|
c.font = `${fontSize * this.scaleLevel}px ${font}`;
|
|
|
|
|
c.fillStyle = '#128AFA';
|
|
|
|
|
c.textAlign = 'end';
|
|
|
|
|
c.setTransform(1, 0, horizontalTilt, 1, 0, 0);
|
|
|
|
@ -76,10 +78,10 @@ export default class LogoCanvas {
|
|
|
|
|
c.resetTransform(); //restore don't work
|
|
|
|
|
c.drawImage(
|
|
|
|
|
window.halo,
|
|
|
|
|
this.canvasWidthL - this.canvas.height / 2 + this.graphOffset.X,
|
|
|
|
|
this.graphOffset.Y,
|
|
|
|
|
canvasHeight,
|
|
|
|
|
canvasHeight
|
|
|
|
|
this.canvasWidthL - this.canvas.height / 2 + (this.graphOffset.X * this.scaleLevel),
|
|
|
|
|
this.graphOffset.Y * this.scaleLevel,
|
|
|
|
|
canvasHeight * this.scaleLevel,
|
|
|
|
|
canvasHeight * this.scaleLevel
|
|
|
|
|
);
|
|
|
|
|
c.fillStyle = '#2B2B2B';
|
|
|
|
|
c.textAlign = 'start';
|
|
|
|
@ -87,25 +89,25 @@ export default class LogoCanvas {
|
|
|
|
|
c.globalCompositeOperation = 'destination-out';
|
|
|
|
|
}
|
|
|
|
|
c.strokeStyle = 'white';
|
|
|
|
|
c.lineWidth = 12;
|
|
|
|
|
c.lineWidth = 12 * this.scaleLevel;
|
|
|
|
|
c.setTransform(1, 0, horizontalTilt, 1, 0, 0);
|
|
|
|
|
c.strokeText(this.textR, this.canvasWidthL, this.canvas.height * textBaseLine);
|
|
|
|
|
c.globalCompositeOperation = 'source-over';
|
|
|
|
|
c.fillText(this.textR, this.canvasWidthL, this.canvas.height * textBaseLine);
|
|
|
|
|
c.resetTransform();
|
|
|
|
|
const graph = {
|
|
|
|
|
X: this.canvasWidthL - this.canvas.height / 2 + graphOffset.X,
|
|
|
|
|
Y: this.graphOffset.Y,
|
|
|
|
|
X: this.canvasWidthL - this.canvas.height / 2 + (graphOffset.X * this.scaleLevel),
|
|
|
|
|
Y: this.graphOffset.Y * this.scaleLevel,
|
|
|
|
|
};
|
|
|
|
|
c.beginPath();
|
|
|
|
|
c.moveTo(
|
|
|
|
|
graph.X + (hollowPath[0][0] / 500) * canvasHeight,
|
|
|
|
|
graph.Y + (hollowPath[0][1] / 500) * canvasHeight
|
|
|
|
|
graph.X + ((hollowPath[0][0] * this.scaleLevel) / (500 * this.scaleLevel)) * (canvasHeight * this.scaleLevel),
|
|
|
|
|
graph.Y + ((hollowPath[0][1] * this.scaleLevel) / (500 * this.scaleLevel)) * (canvasHeight * this.scaleLevel)
|
|
|
|
|
);
|
|
|
|
|
for (let i = 1; i < 4; i++) {
|
|
|
|
|
c.lineTo(
|
|
|
|
|
graph.X + (hollowPath[i][0] / 500) * canvasHeight,
|
|
|
|
|
graph.Y + (hollowPath[i][1] / 500) * canvasHeight
|
|
|
|
|
graph.X + ((hollowPath[i][0] * this.scaleLevel) / (500 * this.scaleLevel)) * (canvasHeight * this.scaleLevel),
|
|
|
|
|
graph.Y + ((hollowPath[i][1] * this.scaleLevel) / (500 * this.scaleLevel)) * (canvasHeight * this.scaleLevel)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
c.closePath();
|
|
|
|
@ -117,10 +119,10 @@ export default class LogoCanvas {
|
|
|
|
|
c.globalCompositeOperation = 'source-over';
|
|
|
|
|
c.drawImage(
|
|
|
|
|
window.cross,
|
|
|
|
|
this.canvasWidthL - this.canvas.height / 2 + graphOffset.X,
|
|
|
|
|
this.graphOffset.Y,
|
|
|
|
|
canvasHeight,
|
|
|
|
|
canvasHeight
|
|
|
|
|
this.canvasWidthL - this.canvas.height / 2 + (graphOffset.X * this.scaleLevel),
|
|
|
|
|
this.graphOffset.Y * this.scaleLevel,
|
|
|
|
|
canvasHeight * this.scaleLevel,
|
|
|
|
|
canvasHeight * this.scaleLevel
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
bindEvent() {
|
|
|
|
@ -163,46 +165,51 @@ export default class LogoCanvas {
|
|
|
|
|
this.graphOffset.Y = parseInt(gy.value);
|
|
|
|
|
this.draw();
|
|
|
|
|
});
|
|
|
|
|
const scaleInput = document.querySelector('#scaleLevel')! as HTMLInputElement;
|
|
|
|
|
scaleInput.addEventListener('input', () => {
|
|
|
|
|
this.scaleLevel = parseInt(scaleInput.value);
|
|
|
|
|
this.draw();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
setWidth() {
|
|
|
|
|
this.textWidthL =
|
|
|
|
|
this.textMetricsL!.width -
|
|
|
|
|
(textBaseLine * canvasHeight + this.textMetricsL!.fontBoundingBoxDescent) * horizontalTilt;
|
|
|
|
|
(textBaseLine * (canvasHeight * this.scaleLevel) + this.textMetricsL!.fontBoundingBoxDescent) * horizontalTilt;
|
|
|
|
|
this.textWidthR =
|
|
|
|
|
this.textMetricsR!.width +
|
|
|
|
|
(textBaseLine * canvasHeight - this.textMetricsR!.fontBoundingBoxAscent) * horizontalTilt;
|
|
|
|
|
(textBaseLine * (canvasHeight * this.scaleLevel) - this.textMetricsR!.fontBoundingBoxAscent) * horizontalTilt;
|
|
|
|
|
//extend canvas
|
|
|
|
|
if (this.textWidthL + paddingX > canvasWidth / 2) {
|
|
|
|
|
this.canvasWidthL = this.textWidthL + paddingX;
|
|
|
|
|
if (this.textWidthL + (paddingX * this.scaleLevel) > (canvasWidth * this.scaleLevel) / 2) {
|
|
|
|
|
this.canvasWidthL = this.textWidthL + (paddingX * this.scaleLevel);
|
|
|
|
|
} else {
|
|
|
|
|
this.canvasWidthL = canvasWidth / 2;
|
|
|
|
|
this.canvasWidthL = (canvasWidth * this.scaleLevel) / 2;
|
|
|
|
|
}
|
|
|
|
|
if (this.textWidthR + paddingX > canvasWidth / 2) {
|
|
|
|
|
this.canvasWidthR = this.textWidthR + paddingX;
|
|
|
|
|
if (this.textWidthR + (paddingX * this.scaleLevel) > (canvasWidth * this.scaleLevel) / 2) {
|
|
|
|
|
this.canvasWidthR = this.textWidthR + (paddingX * this.scaleLevel);
|
|
|
|
|
} else {
|
|
|
|
|
this.canvasWidthR = canvasWidth / 2;
|
|
|
|
|
this.canvasWidthR = (canvasWidth * this.scaleLevel) / 2;
|
|
|
|
|
}
|
|
|
|
|
this.canvas.width = this.canvasWidthL + this.canvasWidthR;
|
|
|
|
|
}
|
|
|
|
|
generateImg() {
|
|
|
|
|
let outputCanvas: HTMLCanvasElement;
|
|
|
|
|
if (
|
|
|
|
|
this.textWidthL + paddingX < canvasWidth / 2 ||
|
|
|
|
|
this.textWidthR + paddingX < canvasWidth / 2
|
|
|
|
|
this.textWidthL + (paddingX * this.scaleLevel) < (canvasWidth * this.scaleLevel) / 2 ||
|
|
|
|
|
this.textWidthR + (paddingX * this.scaleLevel) < (canvasWidth * this.scaleLevel) / 2
|
|
|
|
|
) {
|
|
|
|
|
outputCanvas = document.createElement('canvas');
|
|
|
|
|
outputCanvas.width = this.textWidthL + this.textWidthR + paddingX * 2;
|
|
|
|
|
outputCanvas.width = this.textWidthL + this.textWidthR + (paddingX * this.scaleLevel) * 2;
|
|
|
|
|
outputCanvas.height = this.canvas.height;
|
|
|
|
|
const ctx = outputCanvas.getContext('2d')!;
|
|
|
|
|
ctx.drawImage(
|
|
|
|
|
this.canvas,
|
|
|
|
|
canvasWidth / 2 - this.textWidthL - paddingX,
|
|
|
|
|
(canvasWidth * this.scaleLevel) / 2 - this.textWidthL - (paddingX * this.scaleLevel),
|
|
|
|
|
0,
|
|
|
|
|
this.textWidthL + this.textWidthR + paddingX * 2,
|
|
|
|
|
this.textWidthL + this.textWidthR + (paddingX * this.scaleLevel) * 2,
|
|
|
|
|
this.canvas.height,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
this.textWidthL + this.textWidthR + paddingX * 2,
|
|
|
|
|
this.textWidthL + this.textWidthR + (paddingX * this.scaleLevel) * 2,
|
|
|
|
|
this.canvas.height
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|