Improve Brand Accent Renderer
This commit is contained in:
1 parent
0801ed3c70
commit
02f936b345
1 file changed
+50
-58
@@ -6,7 +6,7 @@ import {
|
|||||||
inject,
|
inject,
|
||||||
NgZone,
|
NgZone,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
ViewChild,
|
viewChild,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { SettingsService } from '../../services/settings.service';
|
import { SettingsService } from '../../services/settings.service';
|
||||||
@@ -19,7 +19,7 @@ import { SettingsService } from '../../services/settings.service';
|
|||||||
styleUrl: './brand-accent.scss',
|
styleUrl: './brand-accent.scss',
|
||||||
})
|
})
|
||||||
export class BrandAccent implements OnDestroy {
|
export class BrandAccent implements OnDestroy {
|
||||||
@ViewChild('canvasElement') canvasRef!: ElementRef<HTMLCanvasElement>;
|
canvasRef = viewChild<ElementRef<HTMLCanvasElement>>('canvasElement');
|
||||||
private ctx!: CanvasRenderingContext2D;
|
private ctx!: CanvasRenderingContext2D;
|
||||||
private settingsService = inject(SettingsService);
|
private settingsService = inject(SettingsService);
|
||||||
|
|
||||||
@@ -27,8 +27,8 @@ export class BrandAccent implements OnDestroy {
|
|||||||
private bgGradient!: CanvasGradient;
|
private bgGradient!: CanvasGradient;
|
||||||
private gridGradient!: CanvasGradient;
|
private gridGradient!: CanvasGradient;
|
||||||
|
|
||||||
private offscreenCanvas!: OffscreenCanvas;
|
private readonly offscreenCanvas!: OffscreenCanvas;
|
||||||
private offscreenCtx!: OffscreenCanvasRenderingContext2D;
|
private readonly offscreenCtx!: OffscreenCanvasRenderingContext2D;
|
||||||
|
|
||||||
private resizeObserver?: ResizeObserver;
|
private resizeObserver?: ResizeObserver;
|
||||||
private intersectionObserver?: IntersectionObserver;
|
private intersectionObserver?: IntersectionObserver;
|
||||||
@@ -68,69 +68,69 @@ export class BrandAccent implements OnDestroy {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterNextRender(() => {
|
afterNextRender(() => {
|
||||||
this.ctx = this.canvasRef.nativeElement.getContext('2d', { colorSpace: 'srgb' })!;
|
const nativeElement = this.canvasRef()?.nativeElement;
|
||||||
|
|
||||||
this.ngZone.runOutsideAngular(() => {
|
if (nativeElement) {
|
||||||
this.resizeObserver = new ResizeObserver((entries) => {
|
this.ctx = nativeElement.getContext('2d', { colorSpace: 'srgb' })!;
|
||||||
for (let entry of entries) {
|
|
||||||
const { inlineSize: width, blockSize: height } = entry.borderBoxSize[0];
|
|
||||||
this.resize(width, height);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.resizeObserver.observe(this.canvasRef.nativeElement);
|
|
||||||
|
|
||||||
this.intersectionObserver = new IntersectionObserver(
|
this.ngZone.runOutsideAngular(() => {
|
||||||
(entries) => {
|
this.resizeObserver = new ResizeObserver((entries) => {
|
||||||
if (entries[0].isIntersecting) {
|
for (let entry of entries) {
|
||||||
if (!this.animation.id) this.animate(performance.now());
|
const { inlineSize: width, blockSize: height } = entry.borderBoxSize[0];
|
||||||
} else if (this.animation.id) {
|
this.resize(width, height);
|
||||||
cancelAnimationFrame(this.animation.id);
|
|
||||||
this.animation.id = undefined;
|
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
{ rootMargin: '200px' },
|
this.resizeObserver.observe(nativeElement);
|
||||||
);
|
|
||||||
this.intersectionObserver.observe(this.canvasRef.nativeElement);
|
|
||||||
|
|
||||||
// Safe Initialization
|
this.intersectionObserver = new IntersectionObserver(
|
||||||
const rect = this.canvasRef.nativeElement.getBoundingClientRect();
|
(entries) => {
|
||||||
this.resize(rect.width, rect.height);
|
if (entries[0].isIntersecting) {
|
||||||
|
if (!this.animation.id) this.animate(performance.now());
|
||||||
|
} else if (this.animation.id) {
|
||||||
|
cancelAnimationFrame(this.animation.id);
|
||||||
|
this.animation.id = undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ rootMargin: '200px' },
|
||||||
|
);
|
||||||
|
this.intersectionObserver.observe(nativeElement);
|
||||||
|
|
||||||
this.animation.startTime = performance.now();
|
// Safe Initialization
|
||||||
|
const rect = nativeElement.getBoundingClientRect();
|
||||||
|
this.resize(rect.width, rect.height);
|
||||||
|
|
||||||
this.draw();
|
this.animation.startTime = performance.now();
|
||||||
// this.animate(performance.now());
|
this.draw();
|
||||||
});
|
// this.animate(performance.now());
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private resize(width: number, height: number) {
|
private resize(width: number, height: number) {
|
||||||
const canvas = this.canvasRef.nativeElement;
|
const canvas = this.canvasRef()?.nativeElement;
|
||||||
const dpr = window.devicePixelRatio || 1;
|
if (canvas) {
|
||||||
|
const dpr = window.devicePixelRatio || 1;
|
||||||
|
|
||||||
this.rendererScale = dpr;
|
this.rendererScale = dpr;
|
||||||
|
|
||||||
canvas.width = width * dpr;
|
canvas.width = width * dpr;
|
||||||
canvas.height = height * dpr;
|
canvas.height = height * dpr;
|
||||||
|
|
||||||
if (this.offscreenCanvas) {
|
if (this.offscreenCanvas) {
|
||||||
this.offscreenCanvas.width = width;
|
this.offscreenCanvas.width = width;
|
||||||
this.offscreenCanvas.height = height;
|
this.offscreenCanvas.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.canvasNativeSize = [width, height];
|
||||||
|
|
||||||
|
this.ctx.scale(dpr, dpr);
|
||||||
|
this.updateAnimationInfo();
|
||||||
|
this.animate(performance.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ctx.scale(dpr, dpr);
|
|
||||||
this.updateAnimationInfo();
|
|
||||||
|
|
||||||
this.update(performance.now());
|
|
||||||
this.draw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateAnimationInfo() {
|
private updateAnimationInfo() {
|
||||||
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,
|
||||||
@@ -209,14 +209,6 @@ export class BrandAccent implements OnDestroy {
|
|||||||
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();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in new issue
Block a user