Optimize Brand Accent Component

This commit is contained in:
copecone committed 2026-04-03 15:22:20 +09:00
1 parent 33e8b61065
commit e6b6947e08
2 files changed
+56 -36

No files matched your search

+56 -19
View File
@@ -14,6 +14,8 @@ export class BrandAccent implements OnDestroy {
private resizeObserver?: ResizeObserver; private resizeObserver?: ResizeObserver;
private canvasNativeSize: [number, number] = [0, 0]; private canvasNativeSize: [number, number] = [0, 0];
private bgGradient!: CanvasGradient;
private gridGradient!: CanvasGradient;
private animation: { private animation: {
id?: number; id?: number;
@@ -59,20 +61,48 @@ export class BrandAccent implements OnDestroy {
this.ctx.scale(dpr, dpr); this.ctx.scale(dpr, dpr);
this.updateAnimationInfo(); this.updateAnimationInfo();
this.draw();
} }
private updateAnimationInfo() { private updateAnimationInfo() {
this.canvasNativeSize = [this.canvasRef.nativeElement.clientWidth, this.canvasRef.nativeElement.clientHeight]; this.canvasNativeSize = [
this.canvasRef.nativeElement.clientWidth,
this.canvasRef.nativeElement.clientHeight,
];
this.animation.gridDimension = [ this.animation.gridDimension = [
Math.trunc(this.canvasNativeSize[0] / this.animation.gridSquareSize) + 3, Math.trunc(this.canvasNativeSize[0] / this.animation.gridSquareSize) + 3,
Math.trunc(this.canvasNativeSize[1] / this.animation.gridSquareSize) + 3, Math.trunc(this.canvasNativeSize[1] / this.animation.gridSquareSize) + 3,
]; ];
this.cacheGradients();
}
private cacheGradients() {
let w = this.canvasNativeSize[0];
let h = this.canvasNativeSize[1];
this.bgGradient = this.ctx.createLinearGradient(0, 0, w, h);
this.bgGradient.addColorStop(0, 'oklch(1 0 0 / 0.6)');
this.bgGradient.addColorStop(1, 'oklch(0.7938 0.1292 47.77 / 0.6)');
this.gridGradient = this.ctx.createLinearGradient(0, 0, w, h);
this.gridGradient.addColorStop(0, 'rgba(0, 0, 0, 0)');
this.gridGradient.addColorStop(1, 'rgba(0, 0, 0, 0.2)');
} }
private animate = (currentTime: number) => { private animate = (currentTime: number) => {
this.animation.id = requestAnimationFrame(this.animate); this.animation.id = requestAnimationFrame(this.animate);
const canvas = this.canvasRef.nativeElement;
if (
canvas.clientWidth !== this.canvasNativeSize[0] ||
canvas.clientHeight !== this.canvasNativeSize[1]
) {
return;
}
this.update(currentTime); this.update(currentTime);
this.draw(); this.draw();
}; };
@@ -89,42 +119,49 @@ export class BrandAccent implements OnDestroy {
this.ctx.clearRect(0, 0, this.canvasNativeSize[0], this.canvasNativeSize[1]); this.ctx.clearRect(0, 0, this.canvasNativeSize[0], this.canvasNativeSize[1]);
this.ctx.globalCompositeOperation = 'source-over'; this.ctx.globalCompositeOperation = 'source-over';
const linearGradient = this.ctx.createLinearGradient(0, 0, this.canvasNativeSize[0], this.canvasNativeSize[1]); this.ctx.fillStyle = this.bgGradient;
linearGradient.addColorStop(0, 'oklch(1 0 0 / 0.6)');
linearGradient.addColorStop(1, 'oklch(0.7938 0.1292 47.77 / 0.6)');
this.ctx.fillStyle = linearGradient;
this.ctx.fillRect(0, 0, this.canvasNativeSize[0], this.canvasNativeSize[1]); this.ctx.fillRect(0, 0, this.canvasNativeSize[0], this.canvasNativeSize[1]);
this.ctx.globalCompositeOperation = 'multiply'; this.ctx.globalCompositeOperation = 'multiply';
const gridGradient = this.ctx.createLinearGradient(0, 0, this.canvasNativeSize[0], this.canvasNativeSize[1]);
gridGradient.addColorStop(0, 'rgba(0, 0, 0, 0)');
gridGradient.addColorStop(1, 'rgba(0, 0, 0, 0.2)');
this.ctx.beginPath(); this.ctx.beginPath();
this.ctx.lineWidth = 2; this.ctx.lineWidth = 2;
this.ctx.strokeStyle = gridGradient; this.ctx.strokeStyle = this.gridGradient;
this.ctx.lineCap = 'round'; this.ctx.lineCap = 'round';
const lineRenderMargin = this.animation.gridSquareSize * 2; const lineRenderMargin = this.animation.gridSquareSize * 2;
const xOffset = (this.canvasNativeSize[0] - this.animation.gridDimension[0] * this.animation.gridSquareSize) / 2; const xOffset =
const yOffset = (this.canvasNativeSize[1] - this.animation.gridDimension[1] * this.animation.gridSquareSize) / 2; (this.canvasNativeSize[0] - this.animation.gridDimension[0] * this.animation.gridSquareSize) /
2;
const yOffset =
(this.canvasNativeSize[1] - this.animation.gridDimension[1] * this.animation.gridSquareSize) /
2;
const movingOffset = -(this.animation.gridSquareSize * this.animation.progress); const movingOffset = -(this.animation.gridSquareSize * this.animation.progress);
for (let y = 0; y < this.animation.gridDimension[1]; y++) { for (let y = 0; y < this.animation.gridDimension[1]; y++) {
this.ctx.moveTo(-lineRenderMargin, y * this.animation.gridSquareSize + yOffset + movingOffset); this.ctx.moveTo(
this.ctx.lineTo(this.canvasNativeSize[0] + lineRenderMargin, y * this.animation.gridSquareSize + yOffset + movingOffset); -lineRenderMargin,
y * this.animation.gridSquareSize + yOffset + movingOffset,
);
this.ctx.lineTo(
this.canvasNativeSize[0] + lineRenderMargin,
y * this.animation.gridSquareSize + yOffset + movingOffset,
);
} }
for (let x = 0; x < this.animation.gridDimension[0]; x++) { for (let x = 0; x < this.animation.gridDimension[0]; x++) {
this.ctx.moveTo(x * this.animation.gridSquareSize + xOffset + movingOffset, -lineRenderMargin); this.ctx.moveTo(
this.ctx.lineTo(x * this.animation.gridSquareSize + xOffset + movingOffset, this.canvasNativeSize[1] + lineRenderMargin); x * this.animation.gridSquareSize + xOffset + movingOffset,
-lineRenderMargin,
);
this.ctx.lineTo(
x * this.animation.gridSquareSize + xOffset + movingOffset,
this.canvasNativeSize[1] + lineRenderMargin,
);
} }
this.ctx.stroke() this.ctx.stroke();
} }
ngOnDestroy() { ngOnDestroy() {
@@ -1,19 +1,5 @@
@use "sass:map"; @use "sass:map";
$breakpoints: (
'narrow': 1400px
);
@mixin respond-to($breakpoint) {
@if map.has-key($breakpoints, $breakpoint) {
@media (max-width: map.get($breakpoints, $breakpoint)) {
@content;
}
} @else {
@warn "해당 브레이크포인트가 없습니다: #{$breakpoint}";
}
}
:host { :host {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@@ -126,9 +112,6 @@ $breakpoints: (
} }
span { span {
@include respond-to(narrow) {
display: none;
}
/*text-box-trim: trim-both; /*text-box-trim: trim-both;
text-box-edge: cap alphabetic;*/ text-box-edge: cap alphabetic;*/
} }