Capítulo 933 de 988
Creates an effect factory that can be passed to the effects prop of Remotion canvas components.
type Rgb = readonly [number, number, number];
type PaletteMapParams = {
readonly palette?: readonly string[];
readonly amount?: number;
};
const DEFAULT_PALETTE = ['#111827', '#06b6d4', '#facc15'] as const;
const paletteMapSchema = {
palette: {
type: 'array',
item: {
type: 'color',
},
default: DEFAULT_PALETTE,
newItemDefault: '#ffffff',
minLength: 1,
description: 'Palette',
},
amount: {
type: 'number',
min: 0,
max: 1,
step: 0.01,
default: 1,
description: 'Amount',
hiddenFromList: false,
},
} as const satisfies InteractivitySchema;
const parseCssColor = (color: string, target: HTMLCanvasElement): Rgb => {
const canvas = target.ownerDocument.createElement('canvas');
canvas.width = 1;
canvas.height = 1;
const ctx = canvas.getContext('2d');
if (!ctx) {
throw new Error('Could not get a 2D context');
}
ctx.fillStyle = color;
ctx.fillRect(0, 0, 1, 1);
const data = ctx.getImageData(0, 0, 1, 1).data;
return [data[0], data[1], data[2]];
};
const distanceSquared = (a: Rgb, b: Rgb): number => {
return (
(a[0] - b[0]) ** 2 +
(a[1] - b[1]) ** 2 +
(a[2] - b[2]) ** 2
);
};
const findClosestColor = (color: Rgb, palette: Rgb[]): Rgb => {
let closest = palette[0] ?? color;
let closestDistance = distanceSquared(color, closest);
for (const candidate of palette) {
con
// ...(truncated)