mirror of
https://github.com/midou36o/midou36o.github.io
synced 2026-11-13 22:23:12 +05:30
jit test
This commit is contained in:
1 parent
3c4eed6b3a
commit
4132289815
2 files changed
+86
-18
No files matched your search
@@ -5,14 +5,29 @@
|
||||
let { reading = false }: { reading?: boolean } = $props();
|
||||
let frame: HTMLDivElement;
|
||||
let canvas: HTMLCanvasElement;
|
||||
let ready = $state(false);
|
||||
let checked = $state(false);
|
||||
let revealDelay = $state(4000);
|
||||
|
||||
onMount(() => {
|
||||
const controller = new BackgroundController(canvas, frame);
|
||||
const revealAt = performance.now() + 4000;
|
||||
const controller = new BackgroundController(canvas, frame, () => {
|
||||
revealDelay = Math.max(0, revealAt - performance.now());
|
||||
checked = true;
|
||||
});
|
||||
ready = true;
|
||||
return () => controller.destroy();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="scene-background bg-gray-300 dark:bg-black" class:reading bind:this={frame}>
|
||||
<div
|
||||
class="scene-background bg-gray-300 dark:bg-black"
|
||||
class:reading
|
||||
class:ready
|
||||
class:checked
|
||||
style:--background-reveal-delay={`${revealDelay}ms`}
|
||||
bind:this={frame}
|
||||
>
|
||||
<canvas bind:this={canvas} aria-hidden="true"></canvas>
|
||||
</div>
|
||||
|
||||
@@ -49,6 +64,21 @@
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.ready.checked canvas {
|
||||
animation: background-reveal 900ms ease var(--background-reveal-delay) both;
|
||||
}
|
||||
|
||||
@keyframes background-reveal {
|
||||
from {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.scene-background {
|
||||
transition:
|
||||
width 650ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
@@ -95,6 +125,11 @@
|
||||
cursor: default;
|
||||
touch-action: auto;
|
||||
}
|
||||
|
||||
.ready canvas {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
canvas {
|
||||
@@ -103,5 +138,12 @@
|
||||
height: 100%;
|
||||
touch-action: none;
|
||||
cursor: default;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.ready.checked canvas {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
</style>
|
||||
@@ -7,8 +7,10 @@ const clamp = (value: number, min: number, max: number) => Math.max(min, Math.mi
|
||||
|
||||
const PROTECTED_CONTENT = 'a, button, h1, h2, h3, h4, h5, h6, p, pre, blockquote, table, img';
|
||||
|
||||
const FRAME_CPU_BUDGET_MS = 1000 / 60;
|
||||
const PERFORMANCE_SAMPLE_FRAMES = 8;
|
||||
const FRAME_CPU_BUDGET_MS = 50;
|
||||
const PERFORMANCE_WARMUP_MS = 1000;
|
||||
const PERFORMANCE_WINDOW_MS = 2000;
|
||||
const PERFORMANCE_MIN_FRAMES = 8;
|
||||
|
||||
export class BackgroundController {
|
||||
private readonly fluid = new FluidField();
|
||||
@@ -18,6 +20,8 @@ export class BackgroundController {
|
||||
private performanceFallback = false;
|
||||
private sampledFrames = 0;
|
||||
private sampledCpuTime = 0;
|
||||
private sampleWindowStart = 0;
|
||||
private initialCheckComplete = false;
|
||||
|
||||
private get still(): boolean {
|
||||
return this.softwareFallback || this.performanceFallback || this.reducedMotion.matches;
|
||||
@@ -47,7 +51,8 @@ export class BackgroundController {
|
||||
|
||||
constructor(
|
||||
private readonly canvas: HTMLCanvasElement,
|
||||
private readonly frame: HTMLElement
|
||||
private readonly frame: HTMLElement,
|
||||
private readonly onPerformanceReady: () => void
|
||||
) {
|
||||
const result = createRenderer(canvas);
|
||||
this.renderer = result.renderer;
|
||||
@@ -97,6 +102,7 @@ export class BackgroundController {
|
||||
const height = Math.max(1, Math.round(bounds.height));
|
||||
const dpr = Math.min(window.devicePixelRatio || 1, 2);
|
||||
if (width === this.cssWidth && height === this.cssHeight && dpr === this.dpr) return;
|
||||
this.resetPerformanceSampling();
|
||||
this.cssWidth = width;
|
||||
this.cssHeight = height;
|
||||
this.dpr = dpr;
|
||||
@@ -202,12 +208,23 @@ export class BackgroundController {
|
||||
this.draw();
|
||||
};
|
||||
|
||||
private resetPerformanceSampling(): void {
|
||||
this.sampledFrames = 0;
|
||||
this.sampledCpuTime = 0;
|
||||
this.sampleWindowStart = performance.now() + PERFORMANCE_WARMUP_MS;
|
||||
}
|
||||
|
||||
private finishInitialCheck(): void {
|
||||
if (this.initialCheckComplete) return;
|
||||
this.initialCheckComplete = true;
|
||||
this.onPerformanceReady();
|
||||
}
|
||||
|
||||
private syncPlayback = () => {
|
||||
cancelAnimationFrame(this.animation);
|
||||
this.animation = 0;
|
||||
this.lastTime = 0;
|
||||
this.sampledFrames = 0;
|
||||
this.sampledCpuTime = 0;
|
||||
this.resetPerformanceSampling();
|
||||
if (this.disposed) return;
|
||||
if (this.still) {
|
||||
this.endDrag();
|
||||
@@ -218,6 +235,7 @@ export class BackgroundController {
|
||||
this.scene.renderPreset();
|
||||
this.draw();
|
||||
}
|
||||
this.finishInitialCheck();
|
||||
return;
|
||||
}
|
||||
this.staticComposition = false;
|
||||
@@ -242,18 +260,26 @@ export class BackgroundController {
|
||||
this.scene.update(elapsed, this.time);
|
||||
this.fluid.step(elapsed, this.time, this.scene);
|
||||
this.draw();
|
||||
this.sampledCpuTime += performance.now() - started;
|
||||
this.sampledFrames++;
|
||||
if (this.sampledFrames === PERFORMANCE_SAMPLE_FRAMES) {
|
||||
if (this.sampledCpuTime > FRAME_CPU_BUDGET_MS * PERFORMANCE_SAMPLE_FRAMES) {
|
||||
this.performanceFallback = true;
|
||||
this.canvas.style.pointerEvents = 'none';
|
||||
this.canvas.style.touchAction = 'auto';
|
||||
this.syncPlayback();
|
||||
return;
|
||||
const cpuTime = performance.now() - started;
|
||||
if (started >= this.sampleWindowStart) {
|
||||
this.sampledCpuTime += cpuTime;
|
||||
this.sampledFrames++;
|
||||
if (
|
||||
started - this.sampleWindowStart >= PERFORMANCE_WINDOW_MS &&
|
||||
this.sampledFrames >= PERFORMANCE_MIN_FRAMES
|
||||
) {
|
||||
if (this.sampledCpuTime / this.sampledFrames > FRAME_CPU_BUDGET_MS) {
|
||||
this.performanceFallback = true;
|
||||
this.canvas.style.pointerEvents = 'none';
|
||||
this.canvas.style.touchAction = 'auto';
|
||||
this.syncPlayback();
|
||||
return;
|
||||
}
|
||||
this.sampledFrames = 0;
|
||||
this.sampledCpuTime = 0;
|
||||
this.sampleWindowStart = started;
|
||||
this.finishInitialCheck();
|
||||
}
|
||||
this.sampledFrames = 0;
|
||||
this.sampledCpuTime = 0;
|
||||
}
|
||||
this.animation = requestAnimationFrame(this.tick);
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user