Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | 77x 77x 77x 42x 11x 11x 11x 11x 1x 10x 25x 7x 25x 25x 6x 8x 1x 1x 9x 9x 8x 8x 2x 2x 1x 1x 9x 9x 2x 2x 8x 8x 2x 2x 8x 8x 1x 1x | import { generateStoryboardKeyframes } from '../mods/thumbnail';
type Storyboard = {
cols?: unknown;
rows?: unknown;
width?: unknown;
height?: unknown;
};
type StoryboardGrid = {
cols: number;
rows: number;
totalFrames: number;
};
export type StoryboardAnimation = {
name: string;
styleId: string;
keyframes: string;
value: string;
};
const THUMBNAIL_SIZE = 48;
const MAX_FRAMES = 10_000;
function getGrid(storyboard: Storyboard | null): StoryboardGrid | null {
if (!storyboard?.cols || !storyboard?.rows) return null;
const cols = Math.trunc(Number(storyboard.cols));
const rows = Math.trunc(Number(storyboard.rows));
const totalFrames = cols * rows;
if (!Number.isFinite(cols) || !Number.isFinite(rows)
|| cols <= 0 || rows <= 0 || totalFrames > MAX_FRAMES) return null;
return { cols, rows, totalFrames };
}
function getDimensions(storyboard: Storyboard | null) {
if (!getGrid(storyboard)) return null;
const width = Number(storyboard?.width);
const height = Number(storyboard?.height);
if (!Number.isFinite(width) || width <= 0 || !Number.isFinite(height) || height <= 0) return null;
return { width, height };
}
export function storyboardUrl(url: string | null): string | null {
if (!url) return null;
const escapedUrl = url.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
return `url("${escapedUrl}")`;
}
export function storyboardSize(storyboard: Storyboard | null): string | null {
const grid = getGrid(storyboard);
return grid ? `${grid.cols * 100}% ${grid.rows * 100}%` : null;
}
export function storyboardMargin(storyboard: Storyboard | null): string | null {
const dimensions = getDimensions(storyboard);
if (!dimensions) return null;
const { width, height } = dimensions;
if (width > height) return `${(THUMBNAIL_SIZE - THUMBNAIL_SIZE * height / width) / 2}px 10px 0 0`;
const margin = (THUMBNAIL_SIZE - THUMBNAIL_SIZE * width / height) / 2;
return `0 ${margin + 10}px 0 ${margin}px`;
}
export function storyboardWidth(storyboard: Storyboard | null): string | null {
const dimensions = getDimensions(storyboard);
if (!dimensions) return null;
const { width, height } = dimensions;
return width > height ? `${THUMBNAIL_SIZE}px` : `${THUMBNAIL_SIZE * width / height}px`;
}
export function storyboardHeight(storyboard: Storyboard | null): string | null {
const dimensions = getDimensions(storyboard);
if (!dimensions) return null;
const { width, height } = dimensions;
return width > height ? `${THUMBNAIL_SIZE * height / width}px` : `${THUMBNAIL_SIZE}px`;
}
export function storyboardAnimation(storyboard: Storyboard | null): StoryboardAnimation | null {
const grid = getGrid(storyboard);
if (!grid || grid.totalFrames < 2) return null;
const name = `storyboard-slide-${grid.cols}x${grid.rows}`;
return {
name,
styleId: `style-${name}`,
keyframes: generateStoryboardKeyframes(name, grid.cols, grid.rows),
value: `${name} ${(grid.totalFrames * 0.4).toFixed(2)}s linear infinite`,
};
}
|