Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ <h1 class="i18n mt-24 mb-20 text-center font-bold" data-i18n="heading">BlueArchi
<span class="flex-1"><span class="mr-2">Y</span><input type="number" placeholder="Type here" value="0"
class="input input-bordered input-sm input-primary w-32" id="graphY" /></span>
</div>
<div class="flex items-center gap-2 my-4">
<div class="i18n" data-i18n="scale-level">Scale Level</div>
<input type="number" placeholder="1" value="1" min="1" max="4"
class="input input-bordered input-sm input-primary w-32" id="scaleLevel" />
</div>
</div>
</div>
</div>
Expand Down
79 changes: 43 additions & 36 deletions src/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -26,24 +26,26 @@ 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() {
const loading = document.querySelector('#loading')!;
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
Expand All @@ -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);
Expand All @@ -68,44 +70,44 @@ 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);
c.fillText(this.textL, this.canvasWidthL, this.canvas.height * textBaseLine);
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';
if (this.transparentBg) {
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();
Expand All @@ -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() {
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"transparent-background": "Transparent Background",
"advance": "Advance settings",
"halo-cross": "Halo & Cross position",
"scale-level": "Scale Level",
"font-title": "Used Fonts",
"main-font": "Main font: ",
"fallback-font": "Fallback font: ",
Expand Down
1 change: 1 addition & 0 deletions src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"transparent-background": "透明背景",
"advance": "高级设置",
"halo-cross": "光环位置微调",
"scale-level": "缩放等级",
"font-title": "使用的字体",
"main-font": "主要字体:",
"fallback-font": "Fallback 字体:",
Expand Down
2 changes: 1 addition & 1 deletion src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ h1 {
#canvas {
border-radius: 8px;
border: 1px solid #bbb;
max-width: 100%;
max-width: 900px;
}

@media (max-width: 900px){
Expand Down
4 changes: 2 additions & 2 deletions src/utils/loadFont.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import settings from '../settings';

export default async (content: string = 'A') => {
export default async (content: string = 'A', scaleLevel: number = 1) => {
// const G2B = new FontFace('G2B', 'url(../RoGSanSrfStd-Bd_other.woff2)');
// // const GSH = new FontFace('GSH', 'url(../GlowSansSC-Normal-Heavy.otf)');
// await Promise.all([G2B.load() /*, GSH.load()*/]).then((fonts) =>
Expand All @@ -9,7 +9,7 @@ export default async (content: string = 'A') => {
// const loadingSwitch = document.querySelector('#loading-switch') as HTMLInputElement;
// loadingSwitch.checked = true;
await document.fonts.load(
`${settings.fontSize}px RoGSanSrfStd-Bd, GlowSansSC-Normal-Heavy_diff`,
`${settings.fontSize * scaleLevel}px RoGSanSrfStd-Bd, GlowSansSC-Normal-Heavy_diff`,
content
);
// loadingSwitch.checked = false;
Expand Down