chore: normalize line endings

This commit is contained in:
Maze Winther
2026-03-29 15:56:48 +02:00
parent 82817cb50c
commit 4d127a038b
736 changed files with 73880 additions and 73782 deletions
@@ -1,81 +1,81 @@
import type { CanvasRenderer } from "../canvas-renderer";
import { effectsRegistry, resolveEffectPasses } from "@/lib/effects";
import type { ParamValues } from "@/lib/params";
import { BaseNode } from "./base-node";
import { webglEffectRenderer } from "../webgl/webgl-effect-renderer";
const TIME_EPSILON = 1e-6;
export type EffectLayerNodeParams = {
effectType: string;
effectParams: ParamValues;
timeOffset: number;
duration: number;
};
function isInRange({
time,
timeOffset,
duration,
}: {
time: number;
timeOffset: number;
duration: number;
}): boolean {
return (
time >= timeOffset - TIME_EPSILON &&
time < timeOffset + duration + TIME_EPSILON
);
}
// snapshots whatever is currently on the canvas, applies the effect, draws it back
export class EffectLayerNode extends BaseNode<EffectLayerNodeParams> {
async render({
renderer,
time,
}: {
renderer: CanvasRenderer;
time: number;
}): Promise<void> {
if (
!isInRange({
time,
timeOffset: this.params.timeOffset,
duration: this.params.duration,
})
) {
return;
}
const source = renderer.context.canvas as CanvasImageSource;
const effectDefinition = effectsRegistry.get(this.params.effectType);
const passes = resolveEffectPasses({
definition: effectDefinition,
effectParams: this.params.effectParams,
width: renderer.width,
height: renderer.height,
});
if (passes.length === 0) {
return;
}
const effectResult = webglEffectRenderer.applyEffect({
source,
width: renderer.width,
height: renderer.height,
passes,
});
renderer.context.save();
renderer.context.clearRect(0, 0, renderer.width, renderer.height);
renderer.context.drawImage(
effectResult,
0,
0,
renderer.width,
renderer.height,
);
renderer.context.restore();
}
}
import type { CanvasRenderer } from "../canvas-renderer";
import { effectsRegistry, resolveEffectPasses } from "@/lib/effects";
import type { ParamValues } from "@/lib/params";
import { BaseNode } from "./base-node";
import { webglEffectRenderer } from "../webgl/webgl-effect-renderer";
const TIME_EPSILON = 1e-6;
export type EffectLayerNodeParams = {
effectType: string;
effectParams: ParamValues;
timeOffset: number;
duration: number;
};
function isInRange({
time,
timeOffset,
duration,
}: {
time: number;
timeOffset: number;
duration: number;
}): boolean {
return (
time >= timeOffset - TIME_EPSILON &&
time < timeOffset + duration + TIME_EPSILON
);
}
// snapshots whatever is currently on the canvas, applies the effect, draws it back
export class EffectLayerNode extends BaseNode<EffectLayerNodeParams> {
async render({
renderer,
time,
}: {
renderer: CanvasRenderer;
time: number;
}): Promise<void> {
if (
!isInRange({
time,
timeOffset: this.params.timeOffset,
duration: this.params.duration,
})
) {
return;
}
const source = renderer.context.canvas as CanvasImageSource;
const effectDefinition = effectsRegistry.get(this.params.effectType);
const passes = resolveEffectPasses({
definition: effectDefinition,
effectParams: this.params.effectParams,
width: renderer.width,
height: renderer.height,
});
if (passes.length === 0) {
return;
}
const effectResult = webglEffectRenderer.applyEffect({
source,
width: renderer.width,
height: renderer.height,
passes,
});
renderer.context.save();
renderer.context.clearRect(0, 0, renderer.width, renderer.height);
renderer.context.drawImage(
effectResult,
0,
0,
renderer.width,
renderer.height,
);
renderer.context.restore();
}
}
@@ -1,92 +1,92 @@
import type { CanvasRenderer } from "../canvas-renderer";
import { createOffscreenCanvas } from "../canvas-utils";
import {
DEFAULT_GRAPHIC_SOURCE_SIZE,
getGraphicDefinition,
registerDefaultGraphics,
} from "@/lib/graphics";
import { resolveGraphicParamsAtTime } from "@/lib/animation";
import type { ParamValues } from "@/lib/params";
import { VisualNode, type VisualNodeParams } from "./visual-node";
export interface GraphicNodeParams extends VisualNodeParams {
definitionId: string;
params: ParamValues;
}
export class GraphicNode extends VisualNode<GraphicNodeParams> {
private cachedKey: string | null = null;
private cachedSource: OffscreenCanvas | HTMLCanvasElement | null = null;
constructor(params: GraphicNodeParams) {
super(params);
registerDefaultGraphics();
}
private getSource({
localTime,
}: {
localTime: number;
}): OffscreenCanvas | HTMLCanvasElement | null {
const definition = getGraphicDefinition({
definitionId: this.params.definitionId,
});
const resolvedParams = resolveGraphicParamsAtTime({
element: this.params,
localTime,
});
const cacheKey = JSON.stringify({
definitionId: this.params.definitionId,
params: resolvedParams,
});
if (this.cachedSource && this.cachedKey === cacheKey) {
return this.cachedSource;
}
const canvas = createOffscreenCanvas({
width: DEFAULT_GRAPHIC_SOURCE_SIZE,
height: DEFAULT_GRAPHIC_SOURCE_SIZE,
});
const ctx = canvas.getContext("2d") as
| CanvasRenderingContext2D
| OffscreenCanvasRenderingContext2D
| null;
if (!ctx) {
return null;
}
definition.render({
ctx,
params: resolvedParams,
width: DEFAULT_GRAPHIC_SOURCE_SIZE,
height: DEFAULT_GRAPHIC_SOURCE_SIZE,
});
this.cachedKey = cacheKey;
this.cachedSource = canvas;
return canvas;
}
async render({ renderer, time }: { renderer: CanvasRenderer; time: number }) {
await super.render({ renderer, time });
if (!this.isInRange({ time })) {
return;
}
const source = this.getSource({
localTime: this.getAnimationLocalTime({ time }),
});
if (!source) {
return;
}
this.renderVisual({
renderer,
source,
sourceWidth: DEFAULT_GRAPHIC_SOURCE_SIZE,
sourceHeight: DEFAULT_GRAPHIC_SOURCE_SIZE,
timelineTime: time,
});
}
}
import type { CanvasRenderer } from "../canvas-renderer";
import { createOffscreenCanvas } from "../canvas-utils";
import {
DEFAULT_GRAPHIC_SOURCE_SIZE,
getGraphicDefinition,
registerDefaultGraphics,
} from "@/lib/graphics";
import { resolveGraphicParamsAtTime } from "@/lib/animation";
import type { ParamValues } from "@/lib/params";
import { VisualNode, type VisualNodeParams } from "./visual-node";
export interface GraphicNodeParams extends VisualNodeParams {
definitionId: string;
params: ParamValues;
}
export class GraphicNode extends VisualNode<GraphicNodeParams> {
private cachedKey: string | null = null;
private cachedSource: OffscreenCanvas | HTMLCanvasElement | null = null;
constructor(params: GraphicNodeParams) {
super(params);
registerDefaultGraphics();
}
private getSource({
localTime,
}: {
localTime: number;
}): OffscreenCanvas | HTMLCanvasElement | null {
const definition = getGraphicDefinition({
definitionId: this.params.definitionId,
});
const resolvedParams = resolveGraphicParamsAtTime({
element: this.params,
localTime,
});
const cacheKey = JSON.stringify({
definitionId: this.params.definitionId,
params: resolvedParams,
});
if (this.cachedSource && this.cachedKey === cacheKey) {
return this.cachedSource;
}
const canvas = createOffscreenCanvas({
width: DEFAULT_GRAPHIC_SOURCE_SIZE,
height: DEFAULT_GRAPHIC_SOURCE_SIZE,
});
const ctx = canvas.getContext("2d") as
| CanvasRenderingContext2D
| OffscreenCanvasRenderingContext2D
| null;
if (!ctx) {
return null;
}
definition.render({
ctx,
params: resolvedParams,
width: DEFAULT_GRAPHIC_SOURCE_SIZE,
height: DEFAULT_GRAPHIC_SOURCE_SIZE,
});
this.cachedKey = cacheKey;
this.cachedSource = canvas;
return canvas;
}
async render({ renderer, time }: { renderer: CanvasRenderer; time: number }) {
await super.render({ renderer, time });
if (!this.isInRange({ time })) {
return;
}
const source = this.getSource({
localTime: this.getAnimationLocalTime({ time }),
});
if (!source) {
return;
}
this.renderVisual({
renderer,
source,
sourceWidth: DEFAULT_GRAPHIC_SOURCE_SIZE,
sourceHeight: DEFAULT_GRAPHIC_SOURCE_SIZE,
timelineTime: time,
});
}
}
@@ -1,37 +1,37 @@
import type { CanvasRenderer } from "../canvas-renderer";
import { VisualNode, type VisualNodeParams } from "./visual-node";
import { videoCache } from "@/services/video-cache/service";
export interface VideoNodeParams extends VisualNodeParams {
url: string;
file: File;
mediaId: string;
}
export class VideoNode extends VisualNode<VideoNodeParams> {
async render({ renderer, time }: { renderer: CanvasRenderer; time: number }) {
await super.render({ renderer, time });
if (!this.isInRange({ time })) {
return;
}
const videoTime = this.getSourceLocalTime({ time });
const frame = await videoCache.getFrameAt({
mediaId: this.params.mediaId,
file: this.params.file,
time: videoTime,
});
if (frame) {
this.renderVisual({
renderer,
source: frame.canvas,
sourceWidth: frame.canvas.width,
sourceHeight: frame.canvas.height,
timelineTime: time,
});
}
}
}
import type { CanvasRenderer } from "../canvas-renderer";
import { VisualNode, type VisualNodeParams } from "./visual-node";
import { videoCache } from "@/services/video-cache/service";
export interface VideoNodeParams extends VisualNodeParams {
url: string;
file: File;
mediaId: string;
}
export class VideoNode extends VisualNode<VideoNodeParams> {
async render({ renderer, time }: { renderer: CanvasRenderer; time: number }) {
await super.render({ renderer, time });
if (!this.isInRange({ time })) {
return;
}
const videoTime = this.getSourceLocalTime({ time });
const frame = await videoCache.getFrameAt({
mediaId: this.params.mediaId,
file: this.params.file,
time: videoTime,
});
if (frame) {
this.renderVisual({
renderer,
source: frame.canvas,
sourceWidth: frame.canvas.width,
sourceHeight: frame.canvas.height,
timelineTime: time,
});
}
}
}