mirror of
https://github.com/YuzuZensai/Pien-Studio.git
synced 2026-09-02 14:18:35 +00:00
✨ feat: layer effects, bucket fill, simple brush
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import type { LayerEffect } from "@pien-studio/types";
|
||||
import type { EffectRenderer, EffectRenderContext } from "./types";
|
||||
import { faceBlurRenderer } from "./face-blur";
|
||||
|
||||
const renderers: EffectRenderer[] = [faceBlurRenderer];
|
||||
|
||||
const effectRendererRegistry = new Map<string, EffectRenderer>(
|
||||
renderers.map((r) => [r.kind, r]),
|
||||
);
|
||||
|
||||
export function getEffectRenderer(kind: string): EffectRenderer | undefined {
|
||||
return effectRendererRegistry.get(kind);
|
||||
}
|
||||
|
||||
/** Draws a layer image applying all its effects in order. */
|
||||
export function renderLayerWithEffects(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
image: HTMLImageElement,
|
||||
effects: LayerEffect[],
|
||||
targetWidth: number,
|
||||
targetHeight: number,
|
||||
): void {
|
||||
const activeEffects = effects.filter((e) => {
|
||||
if (e.enabled === false) return false;
|
||||
return effectRendererRegistry.get(e.kind) !== undefined;
|
||||
});
|
||||
|
||||
if (activeEffects.length === 0) {
|
||||
ctx.drawImage(image, 0, 0, targetWidth, targetHeight);
|
||||
return;
|
||||
}
|
||||
|
||||
const context: EffectRenderContext = { ctx, image, targetWidth, targetHeight };
|
||||
|
||||
// The first effect owns the full layer render (draws base image + applies itself)
|
||||
const first = activeEffects[0];
|
||||
const firstRenderer = effectRendererRegistry.get(first.kind);
|
||||
firstRenderer?.renderLayer(context, first as never);
|
||||
|
||||
// Subsequent effects render on top (overlay only, no re-draw of base)
|
||||
for (let i = 1; i < activeEffects.length; i++) {
|
||||
const effect = activeEffects[i];
|
||||
const renderer = effectRendererRegistry.get(effect.kind);
|
||||
renderer?.render(context, effect as never);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user