@arraypress/covers 1.1.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/README.md +18 -809
- package/package.json +2 -1
- package/recipes/flyers/afterglow-motion.json +540 -0
- package/recipes/flyers/afterglow.json +70 -0
- package/recipes/flyers/arcfield-mirror-motion.json +397 -0
- package/recipes/flyers/arcfield-mirror.json +364 -0
- package/recipes/flyers/bauhaus-oktav.json +319 -0
- package/recipes/flyers/bauhaus-ritmo.json +735 -0
- package/recipes/flyers/bauhaus-volta.json +394 -0
- package/recipes/flyers/bloomfall.json +99 -0
- package/recipes/flyers/drag-solenne-motion.json +444 -0
- package/recipes/flyers/drag-solenne.json +426 -0
- package/recipes/flyers/fennick-patches.json +874 -0
- package/recipes/flyers/ferro-pass.json +398 -0
- package/recipes/flyers/ferrova.json +812 -0
- package/recipes/flyers/grid-rest-rhythm.json +125 -0
- package/recipes/flyers/groovy-honeycomb.json +816 -0
- package/recipes/flyers/groovy-marigold.json +479 -0
- package/recipes/flyers/groovy-peachfuzz.json +974 -0
- package/recipes/flyers/halden-orbit-motion.json +381 -0
- package/recipes/flyers/halden-orbit.json +356 -0
- package/recipes/flyers/halvard.json +120 -0
- package/recipes/flyers/kairo-weekender.json +696 -0
- package/recipes/flyers/linger-motion.json +518 -0
- package/recipes/flyers/linger.json +67 -0
- package/recipes/flyers/little-orchard.json +105 -0
- package/recipes/flyers/lofi-hexmoth.json +912 -0
- package/recipes/flyers/lofi-lowbit-motion.json +888 -0
- package/recipes/flyers/lofi-lowbit.json +880 -0
- package/recipes/flyers/lofi-nullpoint.json +3013 -0
- package/recipes/flyers/lumio-stack-motion.json +648 -0
- package/recipes/flyers/lumio-stack.json +438 -0
- package/recipes/flyers/magazine-cover.json +168 -0
- package/recipes/flyers/magazine-extended.json +269 -0
- package/recipes/flyers/magazine-knockout.json +40 -0
- package/recipes/flyers/northfold-varsity.json +618 -0
- package/recipes/flyers/open-studio.json +69 -0
- package/recipes/flyers/orrin-merch.json +715 -0
- package/recipes/flyers/oxyde.json +113 -0
- package/recipes/flyers/quiet-fields.json +610 -0
- package/recipes/flyers/scrapbook-halcyon.json +948 -0
- package/recipes/flyers/solenne-ticket.json +730 -0
- package/recipes/flyers/solvane-motion.json +576 -0
- package/recipes/flyers/solvane.json +98 -0
- package/recipes/flyers/subduct.json +99 -0
- package/recipes/flyers/sunvale-lineup.json +584 -0
- package/recipes/flyers/tidewell.json +91 -0
- package/recipes/flyers/tour-kairo.json +535 -0
- package/recipes/flyers/velora-stickers.json +885 -0
- package/recipes/flyers/wheatpaste-black.json +313 -0
- package/recipes/flyers/wheatpaste-mark.json +198 -0
- package/recipes/flyers/wheatpaste-torn.json +114 -0
- package/recipes/flyers/wheatpaste-wall.json +984 -0
- package/recipes/flyers/wheatpaste-words.json +233 -0
- package/recipes/release/aura.json +137 -0
- package/recipes/release/chrome.json +433 -0
- package/recipes/release/collage.json +372 -0
- package/recipes/release/duotone.json +113 -0
- package/recipes/release/film-still.json +102 -0
- package/recipes/release/headline.json +70 -0
- package/recipes/release/instant.json +170 -0
- package/recipes/release/label.json +364 -0
- package/recipes/release/liquid-glass.json +301 -0
- package/recipes/release/odd-tile-dark.json +688 -0
- package/recipes/release/odd-tile-dense.json +1056 -0
- package/recipes/release/odd-tile-shift.json +541 -0
- package/recipes/release/odd-tile-split.json +571 -0
- package/recipes/release/odd-tile.json +633 -0
- package/recipes/release/off-edge.json +96 -0
- package/recipes/release/plinth.json +794 -0
- package/recipes/release/riso.json +108 -0
- package/recipes/release/series/fluid-label.json +561 -0
- package/recipes/release/series/fluid-pixel.json +334 -0
- package/recipes/release/series/hairline.json +305 -0
- package/recipes/release/series/halo.json +282 -0
- package/recipes/release/series/mark-crop.json +135 -0
- package/recipes/release/series/mark-window.json +150 -0
- package/recipes/release/series/photo-label.json +475 -0
- package/recipes/release/series/smear-field.json +345 -0
- package/recipes/release/series/smear.json +202 -0
- package/recipes/release/series/spin.json +172 -0
- package/recipes/release/series/split-ghost.json +230 -0
- package/recipes/release/series/zoom.json +168 -0
- package/recipes/release/small-print.json +114 -0
- package/recipes/release/stack.json +156 -0
- package/recipes/release/swiss.json +117 -0
- package/schema/recipe.schema.json +332 -65
- package/src/animate/index.d.ts +9 -19
- package/src/animate/index.js +6 -111
- package/src/animate/keyframes.d.ts +21 -0
- package/src/animate/keyframes.js +119 -0
- package/src/animate/marquee.d.ts +30 -0
- package/src/animate/marquee.js +93 -0
- package/src/animate/morph.d.ts +8 -0
- package/src/animate/morph.js +99 -0
- package/src/animate/motion.d.ts +59 -0
- package/src/animate/motion.js +63 -0
- package/src/animate/sheet.d.ts +19 -0
- package/src/animate/sheet.js +61 -0
- package/src/animate/timing.d.ts +28 -0
- package/src/animate/timing.js +146 -0
- package/src/animate/tracks.d.ts +18 -0
- package/src/animate/tracks.js +139 -0
- package/src/diagram.js +4 -3
- package/src/extract.js +2 -2
- package/src/fonts.js +1 -2
- package/src/geometry.js +4 -34
- package/src/grid.js +1 -1
- package/src/handmade.js +9 -7
- package/src/icons.js +1 -2
- package/src/index.d.ts +39 -48
- package/src/index.js +5 -5
- package/src/inter-data.js +1 -1
- package/src/json-recipe.js +23 -7
- package/src/layer-options.js +21 -1
- package/src/layers/barcode.js +3 -3
- package/src/layers/geometry.js +5 -5
- package/src/layers/perforation.js +3 -3
- package/src/layers/repeat.js +2 -2
- package/src/layers/shape.d.ts +2 -2
- package/src/layers/shape.js +5 -5
- package/src/layers/soft.js +2 -2
- package/src/layers/svg.js +2 -3
- package/src/layers/table.js +3 -3
- package/src/layers/tear.d.ts +1 -1
- package/src/layers/tear.js +4 -4
- package/src/layers/texture.js +3 -3
- package/src/layers/util.js +15 -2
- package/src/layers.js +10 -26
- package/src/{effects/paint.js → paint/index.js} +5 -5
- package/src/{effects/paint-presets.d.ts → paint/presets.d.ts} +1 -1
- package/src/{effects/paint-presets.js → paint/presets.js} +1 -1
- package/src/{effects → paint}/tile.d.ts +1 -1
- package/src/{effects → paint}/tile.js +4 -4
- package/src/palette.js +1 -1
- package/src/platform/files.d.ts +6 -0
- package/src/platform/files.js +41 -0
- package/src/platform/harfbuzz.js +1 -1
- package/src/platform/index.d.ts +3 -3
- package/src/platform/index.js +6 -4
- package/src/platform/load.js +1 -2
- package/src/print.js +9 -7
- package/src/recipes.js +1 -1
- package/src/render/backdrop.js +2 -2
- package/src/render/grain.js +1 -1
- package/src/render/group.js +3 -3
- package/src/render/key.js +1 -2
- package/src/{effects → render}/transform.d.ts +2 -1
- package/src/{effects → render}/transform.js +17 -5
- package/src/render/use.d.ts +1 -1
- package/src/render/use.js +2 -2
- package/src/render/wrap.js +5 -60
- package/src/render.js +55 -18
- package/src/text.js +1 -1
- package/src/type/auto-color.js +1 -1
- package/src/type/glyphs.js +2 -2
- package/src/type/line.js +1 -1
- package/src/type/live.js +1 -1
- package/src/type/path.js +2 -2
- package/src/type/pixel.d.ts +0 -2
- package/src/type/pixel.js +3 -33
- package/src/type/spans.js +2 -2
- package/src/type/typeset.js +19 -8
- package/src/version.js +1 -1
- package/src/color.js +0 -246
- package/src/effects/ascii.d.ts +0 -7
- package/src/effects/ascii.js +0 -93
- package/src/effects/buffer.d.ts +0 -60
- package/src/effects/buffer.js +0 -472
- package/src/effects/detail.d.ts +0 -12
- package/src/effects/detail.js +0 -124
- package/src/effects/digital.d.ts +0 -14
- package/src/effects/digital.js +0 -216
- package/src/effects/distort.d.ts +0 -20
- package/src/effects/distort.js +0 -314
- package/src/effects/dither.d.ts +0 -8
- package/src/effects/dither.js +0 -147
- package/src/effects/drop-shadow.d.ts +0 -4
- package/src/effects/drop-shadow.js +0 -45
- package/src/effects/extrude.d.ts +0 -5
- package/src/effects/extrude.js +0 -55
- package/src/effects/film.d.ts +0 -11
- package/src/effects/film.js +0 -204
- package/src/effects/glow.d.ts +0 -8
- package/src/effects/glow.js +0 -56
- package/src/effects/grade.d.ts +0 -30
- package/src/effects/grade.js +0 -274
- package/src/effects/halftone.d.ts +0 -8
- package/src/effects/halftone.js +0 -95
- package/src/effects/index.d.ts +0 -125
- package/src/effects/index.js +0 -277
- package/src/effects/ink.d.ts +0 -12
- package/src/effects/ink.js +0 -70
- package/src/effects/lens.d.ts +0 -14
- package/src/effects/lens.js +0 -277
- package/src/effects/light.d.ts +0 -10
- package/src/effects/light.js +0 -59
- package/src/effects/looks.d.ts +0 -9
- package/src/effects/looks.js +0 -74
- package/src/effects/mask.d.ts +0 -52
- package/src/effects/mask.js +0 -314
- package/src/effects/motion.d.ts +0 -6
- package/src/effects/motion.js +0 -60
- package/src/effects/newsprint.d.ts +0 -6
- package/src/effects/newsprint.js +0 -89
- package/src/effects/optics.d.ts +0 -10
- package/src/effects/optics.js +0 -213
- package/src/effects/options.d.ts +0 -6
- package/src/effects/options.js +0 -106
- package/src/effects/pixels.d.ts +0 -24
- package/src/effects/pixels.js +0 -138
- package/src/effects/polar.d.ts +0 -10
- package/src/effects/polar.js +0 -265
- package/src/effects/region.d.ts +0 -8
- package/src/effects/region.js +0 -136
- package/src/effects/round-border.d.ts +0 -5
- package/src/effects/round-border.js +0 -62
- package/src/effects/screen.d.ts +0 -14
- package/src/effects/screen.js +0 -212
- package/src/effects/sort.d.ts +0 -8
- package/src/effects/sort.js +0 -125
- package/src/effects/symmetry.d.ts +0 -6
- package/src/effects/symmetry.js +0 -74
- package/src/effects/tone.d.ts +0 -16
- package/src/effects/tone.js +0 -117
- package/src/effects/util.d.ts +0 -16
- package/src/effects/util.js +0 -85
- package/src/platform/bytes.d.ts +0 -22
- package/src/platform/bytes.js +0 -103
- package/src/platform/compress.d.ts +0 -12
- package/src/platform/compress.js +0 -81
- package/src/platform/node.d.ts +0 -26
- package/src/platform/node.js +0 -86
- package/src/png.js +0 -126
- package/src/raster/index.d.ts +0 -24
- package/src/raster/index.js +0 -171
- package/src/render/content.d.ts +0 -5
- package/src/render/content.js +0 -58
- package/src/render/tiles.d.ts +0 -6
- package/src/render/tiles.js +0 -77
- package/src/rng.js +0 -95
- package/src/svg.js +0 -69
- /package/src/{effects/paint.d.ts → paint/index.d.ts} +0 -0
package/src/index.d.ts
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* WebP / PNG / AVIF / JPEG.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
import type { LayerTransform
|
|
9
|
-
import type { Paint } from './
|
|
7
|
+
import type { Effect as AnyEffect, EffectKind, EffectMask as AnyEffectMask, Color, Length, Rng } from '@logomarks/image-effects';
|
|
8
|
+
import type { LayerTransform } from './render/transform.js';
|
|
9
|
+
import type { Paint } from './paint/index.js';
|
|
10
10
|
import type { TextPath } from './type/path.js';
|
|
11
11
|
import type { GroupLayer } from './render/group.js';
|
|
12
12
|
import type { DefsLayer, UseLayer } from './render/use.js';
|
|
@@ -16,29 +16,32 @@ import type { GlyphControl } from './type/glyphs.js';
|
|
|
16
16
|
import type { Cut } from './formats/cut.js';
|
|
17
17
|
import type { ShapeLayer, SvgLayer, TableLayer, BarcodeLayer, PerforationLayer, TearLayer, TextureLayer } from './layers/index.js';
|
|
18
18
|
import type { Zones, PrintInfo, FormatName } from './formats/index.js';
|
|
19
|
+
import type { Motion, MotionPreset, Easing } from './animate/index.js';
|
|
19
20
|
|
|
20
|
-
export type { RepeatLayer, DefsLayer, UseLayer, TextSpan, GlyphControl, Cut };
|
|
21
|
-
export type {
|
|
21
|
+
export type { RepeatLayer, DefsLayer, UseLayer, TextSpan, GlyphControl, Cut, Motion, MotionPreset, Easing };
|
|
22
|
+
export type { Color, Length, Rng, LayerTransform, EffectKind, Paint, TextPath, GroupLayer, ShapeLayer, SvgLayer, TableLayer, BarcodeLayer, PerforationLayer, TearLayer, TextureLayer, Zones, PrintInfo, FormatName };
|
|
22
23
|
export type { ShapeSpec, TableCell } from './layers/index.js';
|
|
23
24
|
export type { Format } from './formats/index.js';
|
|
24
25
|
export type { LintIssue } from './lint/index.js';
|
|
25
26
|
export type { Settings } from './platform/index.js';
|
|
26
27
|
|
|
27
28
|
export { safeBox } from './formats/index.js';
|
|
28
|
-
export { rasterize } from '
|
|
29
|
-
import type { RasterizeOptions } from '
|
|
29
|
+
export { rasterize } from '@logomarks/image-effects/raster';
|
|
30
|
+
import type { RasterizeOptions } from '@logomarks/image-effects/raster';
|
|
30
31
|
export type { RasterizeOptions };
|
|
31
32
|
export { lint } from './lint/index.js';
|
|
32
33
|
export { kit, KIT_FORMATS } from './kit/index.js';
|
|
33
34
|
export { FORMATS } from './formats/index.js';
|
|
34
35
|
export { configure } from './platform/index.js';
|
|
35
|
-
export { EFFECTS, EFFECT_OPTIONS } from '
|
|
36
|
-
export { valueAt } from './animate/index.js';
|
|
36
|
+
export { EFFECTS, EFFECT_OPTIONS } from '@logomarks/image-effects';
|
|
37
|
+
export { valueAt, MOTION_PRESETS } from './animate/index.js';
|
|
38
|
+
export { toHex, toOklch, fromOklch, mixOklab, mixOklch, onBackground, gradientAt } from '@logomarks/image-effects/color';
|
|
39
|
+
export { createRng, hashString } from '@logomarks/image-effects/rng';
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
export type
|
|
41
|
+
/** An effect on a layer (image-effects' effects, with masks and maps given as layers). */
|
|
42
|
+
export type Effect = AnyEffect<Layer>;
|
|
43
|
+
/** Where an effect applies: a gradient, or layers. */
|
|
44
|
+
export type EffectMask = AnyEffectMask<Layer>;
|
|
42
45
|
|
|
43
46
|
/** Where a box sits inside the safe area. */
|
|
44
47
|
export type Anchor =
|
|
@@ -136,6 +139,8 @@ export interface BaseLayer {
|
|
|
136
139
|
clip?: Layer[];
|
|
137
140
|
/** Draw the layer in a box: the print `'trim'` or `'safe'` area, or fractions of the canvas. */
|
|
138
141
|
area?: 'bleed' | 'trim' | 'safe' | Region;
|
|
142
|
+
/** Move in the SVG itself (CSS keyframes, no script): a motion, a preset name, or a list. */
|
|
143
|
+
motion?: Motion | MotionPreset | (Motion | MotionPreset)[];
|
|
139
144
|
}
|
|
140
145
|
|
|
141
146
|
export interface SolidLayer extends BaseLayer {
|
|
@@ -934,6 +939,10 @@ export interface CoverOptions extends RecipeOptions {
|
|
|
934
939
|
textRender?: 'outline' | 'live';
|
|
935
940
|
/** Seconds: the length of an animated cover's loop (keyframes with `loop` wrap at it). */
|
|
936
941
|
loop?: number;
|
|
942
|
+
/** `false`: `renderSvg` draws a still, no CSS (layers' `motion` at the `poster` time, else at rest). */
|
|
943
|
+
animate?: boolean;
|
|
944
|
+
/** Seconds: the frame stills show (`renderImage`, `renderBlob`, `animate: false`, and an animated SVG under reduced motion). Default: the layers at rest. */
|
|
945
|
+
poster?: number;
|
|
937
946
|
}
|
|
938
947
|
|
|
939
948
|
/** A resolved cover (from {@link cover}). */
|
|
@@ -958,13 +967,16 @@ export interface Cover {
|
|
|
958
967
|
pages?: string[];
|
|
959
968
|
overlay?: boolean;
|
|
960
969
|
loop?: number;
|
|
970
|
+
/** `false` when the cover is drawn as a still. */
|
|
971
|
+
animate?: false;
|
|
972
|
+
poster?: number;
|
|
961
973
|
textRender?: 'outline' | 'live';
|
|
962
974
|
}
|
|
963
975
|
|
|
964
976
|
export interface RenderImageOptions {
|
|
965
977
|
/** Default `'webp'`. */
|
|
966
978
|
format?: 'webp' | 'png' | 'avif' | 'jpeg';
|
|
967
|
-
/** Default 90 for WebP, 72 for AVIF, 88 for JPEG (high enough to keep the grain; see
|
|
979
|
+
/** Default 90 for WebP, 72 for AVIF, 88 for JPEG (high enough to keep the grain; see docs/performance.md). */
|
|
968
980
|
quality?: number;
|
|
969
981
|
/** Lossless WebP / AVIF (default: the recipe's preference, else lossy). */
|
|
970
982
|
lossless?: boolean;
|
|
@@ -974,16 +986,6 @@ export interface RenderImageOptions {
|
|
|
974
986
|
cache?: boolean | string;
|
|
975
987
|
}
|
|
976
988
|
|
|
977
|
-
/** Seeded random stream. */
|
|
978
|
-
export interface Rng {
|
|
979
|
-
next(): number;
|
|
980
|
-
range(min: number, max: number): number;
|
|
981
|
-
int(min: number, max: number): number;
|
|
982
|
-
pick<T>(items: readonly T[]): T;
|
|
983
|
-
shuffle<T>(items: readonly T[]): T[];
|
|
984
|
-
chance(p?: number): boolean;
|
|
985
|
-
}
|
|
986
|
-
|
|
987
989
|
/** An Iconify JSON set (`@iconify-json/<prefix>/icons.json`). */
|
|
988
990
|
export interface IconSet {
|
|
989
991
|
prefix: string;
|
|
@@ -998,13 +1000,23 @@ export interface IconSet {
|
|
|
998
1000
|
/** Resolve a cover's size and palette and expand its recipe. Pure and synchronous. */
|
|
999
1001
|
export function cover(options: CoverOptions | Cover): Cover;
|
|
1000
1002
|
|
|
1001
|
-
/**
|
|
1002
|
-
export
|
|
1003
|
+
/** How `renderSvg` draws. */
|
|
1004
|
+
export interface RenderSvgOptions {
|
|
1005
|
+
/** A still at this time, in seconds, for keyframed layers and `motion` (instead of playing it). */
|
|
1006
|
+
t?: number;
|
|
1007
|
+
/** `'webp'`: embedded photos and pixel effects re-encoded as WebP where smaller (needs sharp). For SVGs shown in browsers; librsvg (sharp) can't draw WebP. */
|
|
1008
|
+
images?: 'webp';
|
|
1009
|
+
/** WebP quality for photos (JPEG sources), 1–100. Default 82. PNG sources go lossless. */
|
|
1010
|
+
quality?: number;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
/** Render to an SVG string (text and icons as outlines; byte-identical for the same input). */
|
|
1014
|
+
export function renderSvg(input: CoverOptions | Cover, options?: RenderSvgOptions): Promise<string>;
|
|
1003
1015
|
|
|
1004
1016
|
/** Render each page of a two-sided piece: `{ front, back }`. */
|
|
1005
1017
|
export function renderPages(input: CoverOptions, options?: { pages?: string[] }): Promise<Record<string, string>>;
|
|
1006
1018
|
|
|
1007
|
-
/** Render to an image in the browser (a canvas; no sharp). */
|
|
1019
|
+
/** Render to an image in the browser (a canvas; no sharp): a still, the `poster` frame or the layers at rest. */
|
|
1008
1020
|
export function renderBlob(input: CoverOptions | Cover, options?: RasterizeOptions): Promise<Blob>;
|
|
1009
1021
|
|
|
1010
1022
|
/** Register a font for every cover. */
|
|
@@ -1043,21 +1055,6 @@ export function resolvePalette(input?: PaletteInput | Palette): Palette;
|
|
|
1043
1055
|
/** Derive a palette from a theme's tokens (or just an accent). */
|
|
1044
1056
|
export function derivePalette(tokens: { accent: Color; bg?: Color; text?: Color; colors?: Color[]; mode?: 'light' | 'dark' }): Palette;
|
|
1045
1057
|
|
|
1046
|
-
/** Parse a CSS colour to `#rrggbb`. */
|
|
1047
|
-
export function toHex(color: Color): string;
|
|
1048
|
-
/** A colour in OKLCH (lightness 0–1, chroma, hue in degrees). */
|
|
1049
|
-
export function toOklch(color: Color): { l: number; c: number; h: number };
|
|
1050
|
-
/** OKLCH to `#rrggbb` (chroma reduced to fit sRGB). */
|
|
1051
|
-
export function fromOklch(lch: { l: number; c: number; h: number }): string;
|
|
1052
|
-
/** Mix two colours in OKLab. */
|
|
1053
|
-
export function mixOklab(a: Color, b: Color, t: number): string;
|
|
1054
|
-
/** `prefer` if it clears `ratio` on every background, else the better of white and near-black (3:1 suits icons, WCAG 1.4.11). */
|
|
1055
|
-
export function onBackground(backgrounds: Color | Color[], ratio?: number, prefer?: 'white' | 'black' | Color): string;
|
|
1056
|
-
/** The colour of an eased multi-stop gradient at t (0–1), as the gradient layers draw it. */
|
|
1057
|
-
export function gradientAt(colors: Color[], t: number, ease?: boolean): string;
|
|
1058
|
-
/** Mix two colours in OKLCH (hue the short way; stays vivid). */
|
|
1059
|
-
export function mixOklch(a: Color, b: Color, t: number): string;
|
|
1060
|
-
|
|
1061
1058
|
/** Register an Iconify icon set (no `@iconify-json/*` install needed). */
|
|
1062
1059
|
export function registerIcons(set: IconSet): void;
|
|
1063
1060
|
|
|
@@ -1067,17 +1064,11 @@ export function resolveSize(options?: { width?: number; height?: number; aspect?
|
|
|
1067
1064
|
/** Named aspect ratios (width / height). */
|
|
1068
1065
|
export const ASPECTS: Readonly<{ '1:1': number; '16:9': number; '4:5': number; '3:2': number; '4:3': number; '2:1': number; '9:16': number; og: number }>;
|
|
1069
1066
|
|
|
1070
|
-
/** A seeded random stream (for custom recipes). */
|
|
1071
|
-
export function createRng(seed: string | number): Rng;
|
|
1072
|
-
|
|
1073
1067
|
/** Dominant colours of a photo, most common first (needs sharp). */
|
|
1074
1068
|
export function extractPalette(src: string | Uint8Array, options?: { count?: number }): Promise<string[]>;
|
|
1075
1069
|
|
|
1076
1070
|
/** Classic risograph inks, by name (approximations). */
|
|
1077
1071
|
export const RISO_INKS: Readonly<Record<'pink' | 'blue' | 'yellow' | 'teal' | 'red' | 'green' | 'orange' | 'purple' | 'navy' | 'black', string>>;
|
|
1078
1072
|
|
|
1079
|
-
/** Hash a string to a 32-bit unsigned integer. */
|
|
1080
|
-
export function hashString(str: string, salt?: number): number;
|
|
1081
|
-
|
|
1082
1073
|
/** The layer renderers, by type (for introspection). */
|
|
1083
1074
|
export const layers: Readonly<Record<Layer['type'], (layer: any, context: any) => unknown>>;
|
package/src/index.js
CHANGED
|
@@ -10,18 +10,18 @@ export { cover, renderSvg, renderImage, renderPages, renderBlob, coverKey, safeB
|
|
|
10
10
|
export { recipes } from './recipes.js';
|
|
11
11
|
export { defineRecipe, loadRecipe } from './json-recipe.js';
|
|
12
12
|
export { palettes, resolvePalette, derivePalette } from './palette.js';
|
|
13
|
-
export { toHex, toOklch, fromOklch, mixOklab, mixOklch, onBackground, gradientAt } from '
|
|
13
|
+
export { toHex, toOklch, fromOklch, mixOklab, mixOklch, onBackground, gradientAt } from '@logomarks/image-effects/color';
|
|
14
14
|
export { registerIcons } from './icons.js';
|
|
15
15
|
export { registerFont } from './fonts.js';
|
|
16
16
|
export { configure } from './platform/index.js';
|
|
17
17
|
export { resolveSize, ASPECTS } from './geometry.js';
|
|
18
18
|
export { FORMATS } from './formats/index.js';
|
|
19
|
-
export { createRng, hashString } from '
|
|
19
|
+
export { createRng, hashString } from '@logomarks/image-effects/rng';
|
|
20
20
|
export { LAYERS as layers } from './layers.js';
|
|
21
21
|
export { extractPalette } from './extract.js';
|
|
22
22
|
export { RISO_INKS } from './print.js';
|
|
23
|
-
export { EFFECTS, EFFECT_OPTIONS } from '
|
|
24
|
-
export { rasterize } from '
|
|
23
|
+
export { EFFECTS, EFFECT_OPTIONS } from '@logomarks/image-effects';
|
|
24
|
+
export { rasterize } from '@logomarks/image-effects/raster';
|
|
25
25
|
export { lint } from './lint/index.js';
|
|
26
26
|
export { kit, KIT_FORMATS } from './kit/index.js';
|
|
27
|
-
export { valueAt } from './animate/index.js';
|
|
27
|
+
export { valueAt, MOTION_PRESETS } from './animate/index.js';
|
package/src/inter-data.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Generated by scripts/generate.mjs from fonts/*.woff. Do not edit.
|
|
2
2
|
// Inter is © The Inter Project Authors, SIL Open Font License 1.1 (fonts/OFL.txt).
|
|
3
3
|
|
|
4
|
-
import { fromBase64 } from './platform/
|
|
4
|
+
import { fromBase64 } from './platform/index.js';
|
|
5
5
|
|
|
6
6
|
/** @type {Record<number, string>} */
|
|
7
7
|
const DATA = {
|
package/src/json-recipe.js
CHANGED
|
@@ -55,15 +55,16 @@
|
|
|
55
55
|
|
|
56
56
|
import { readTextSync, node } from './platform/index.js';
|
|
57
57
|
import { readableText } from '@arraypress/color-utils';
|
|
58
|
-
import { createRng } from '
|
|
59
|
-
import { len
|
|
60
|
-
import {
|
|
58
|
+
import { createRng } from '@logomarks/image-effects/rng';
|
|
59
|
+
import { len } from '@logomarks/image-effects/length';
|
|
60
|
+
import { ANCHORS } from './geometry.js';
|
|
61
|
+
import { toHex, mixOklab, mixOklch, onBackground, gradientAt } from '@logomarks/image-effects/color';
|
|
61
62
|
import { LAYERS, toneColor } from './layers.js';
|
|
62
|
-
import { LAYER_OPTIONS, COMMON } from './layer-options.js';
|
|
63
|
-
import { EFFECT_OPTIONS, EFFECT_COMMON } from '
|
|
64
|
-
import { MASK_GRADIENTS } from './effects/mask.js';
|
|
63
|
+
import { LAYER_OPTIONS, COMMON, MOTION_OPTIONS } from './layer-options.js';
|
|
64
|
+
import { EFFECT_OPTIONS, EFFECT_COMMON, MASK_GRADIENTS } from '@logomarks/image-effects';
|
|
65
65
|
import { shapesOnly } from './layers/svg.js';
|
|
66
66
|
import { LAYOUT_FIELDS } from './type/layout-ref.js';
|
|
67
|
+
import { MOTION_PRESETS } from './animate/timing.js';
|
|
67
68
|
|
|
68
69
|
/** Options every recipe can read without declaring them. */
|
|
69
70
|
const CONTENT = ['title', 'label', 'icon', 'image', 'name', 'mark', 'photo', 'cutout', 'date', 'dates', 'time', 'venue', 'address', 'lines', 'lineup', 'tracklist', 'price', 'meta', 'page'];
|
|
@@ -181,7 +182,7 @@ export function loadRecipe(path) {
|
|
|
181
182
|
* @property {Record<string, unknown>} params
|
|
182
183
|
* @property {Record<string, unknown>} vars
|
|
183
184
|
* @property {any} c - The recipe context.
|
|
184
|
-
* @property {() => import('
|
|
185
|
+
* @property {() => import('@logomarks/image-effects/rng').Rng} rng - The current stream.
|
|
185
186
|
*/
|
|
186
187
|
|
|
187
188
|
/**
|
|
@@ -546,6 +547,8 @@ export function validate(json) {
|
|
|
546
547
|
if (!Object.hasOwn(known, k)) fail(`${path}.${k}`, `"${layer.type}" layers have no option "${k}" (${Object.keys(known).join(', ')})`);
|
|
547
548
|
if (k === 'effects') {
|
|
548
549
|
checkEffects(`${path}.effects`, v);
|
|
550
|
+
} else if (k === 'motion') {
|
|
551
|
+
checkMotion(`${path}.motion`, v);
|
|
549
552
|
} else if (NESTED.includes(k) && Array.isArray(v) && v.every((x) => isPlain(x) && typeof x.type === 'string')) {
|
|
550
553
|
v.forEach((x, j) => checkLayer(`${path}.${k}[${j}]${x.id ? ` (${x.id})` : ''}`, x));
|
|
551
554
|
} else if (k === 'layer' && isPlain(v) && typeof v.type === 'string') {
|
|
@@ -583,6 +586,19 @@ export function validate(json) {
|
|
|
583
586
|
}
|
|
584
587
|
});
|
|
585
588
|
};
|
|
589
|
+
// Motion: known presets and options (values are checked as values).
|
|
590
|
+
const checkMotion = (/** @type {string} */ path, /** @type {any} */ v) => {
|
|
591
|
+
(Array.isArray(v) ? v : [v]).forEach((m, i) => {
|
|
592
|
+
const at = Array.isArray(v) ? `${path}[${i}]` : path;
|
|
593
|
+
const preset = typeof m === 'string' ? m : m?.preset;
|
|
594
|
+
if (typeof preset === 'string' && !/[{$@]/.test(preset) && !Object.hasOwn(MOTION_PRESETS, preset)) fail(at, `unknown motion preset "${preset}" (${Object.keys(MOTION_PRESETS).join(', ')})`);
|
|
595
|
+
if (!isPlain(m)) return checkValue(at, m);
|
|
596
|
+
for (const [k, x] of Object.entries(m)) {
|
|
597
|
+
if (!Object.hasOwn(MOTION_OPTIONS, k)) fail(`${at}.${k}`, `motions have no option "${k}" (${Object.keys(MOTION_OPTIONS).join(', ')})`);
|
|
598
|
+
checkValue(`${at}.${k}`, x);
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
};
|
|
586
602
|
const checkEffectMask = (/** @type {string} */ path, /** @type {any} */ m) => {
|
|
587
603
|
const keys = ['gradient', 'from', 'to', 'center', 'angle', 'aspect', 'invert', 'ease', 'layers'];
|
|
588
604
|
for (const k of Object.keys(m)) if (!keys.includes(k)) fail(`${path}.${k}`, `unknown mask option (${keys.join(', ')})`);
|
package/src/layer-options.js
CHANGED
|
@@ -49,8 +49,28 @@ export const LAYER_OPTIONS = {
|
|
|
49
49
|
export const COMMON = {
|
|
50
50
|
opacity: '0–1.', blend: 'A CSS mix-blend-mode.', seed: "This layer's own random stream.",
|
|
51
51
|
transform: '{ translate, rotate, scale, skewX, skewY, mirror: x | y, origin } (on text, a case keyword is still the case).',
|
|
52
|
-
effects: '[{ kind, mask, colorSpace, … }]: filters, pixel effects and copies, in order (see
|
|
52
|
+
effects: '[{ kind, mask, colorSpace, … }]: filters, pixel effects and copies, in order (see docs/effects.md; kinds in EFFECTS).',
|
|
53
53
|
mask: 'Layers whose luminance masks this one (white shows).', knockout: 'Layers cut out of this one.', clip: 'Layers this one shows only inside.',
|
|
54
54
|
area: 'trim | safe | bleed, or { x, y, width, height } fractions: draw the layer in that box.',
|
|
55
|
+
motion: 'A motion, a preset name (drift | spin | breathe | blink | marquee), or a list: plays in the SVG as CSS keyframes (see MOTION_OPTIONS).',
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/** @type {Record<string, string>} A motion's options. */
|
|
59
|
+
export const MOTION_OPTIONS = {
|
|
60
|
+
preset: 'drift | spin | breathe | blink | marquee: its defaults, under whatever else is set.',
|
|
61
|
+
translate: '[x, y] to move by (px in the layer\'s grid, "%" or lengths), or a list of points [[0, 0], [x, y], …].',
|
|
62
|
+
path: 'Travel a path from where the layer is: path data, { d }, or a text-path kind ({ kind: circle | ellipse | arc | wave, … }).',
|
|
63
|
+
rotate: 'Degrees to turn to, or a list of angles.',
|
|
64
|
+
scale: 'A factor to grow to, or a list.', scaleX: 'Horizontal factor, or a list.', scaleY: 'Vertical factor, or a list.',
|
|
65
|
+
opacity: '0–1 to fade to (times the layer\'s own), or a list.',
|
|
66
|
+
origin: '[x, y] the turn and scale are about (px, "%" or lengths). Default the centre.',
|
|
67
|
+
vary: 'Layer options as lists of stops ({ axes: { wdth: [62, 150] } }): drawn frame by frame, played as outline morphs.',
|
|
68
|
+
frames: 'vary: frames drawn per stop. Default 12.',
|
|
69
|
+
marquee: 'true: text on a path runs along it, one repeat of its words per duration (they must repeat).',
|
|
70
|
+
duration: 'Seconds per iteration. Default 2 (or the preset\'s).',
|
|
71
|
+
delay: 'Seconds before it starts; negative starts it part-way.',
|
|
72
|
+
easing: 'linear | ease | in | out | inOut | step, or [x1, y1, x2, y2]: between each pair of stops.',
|
|
73
|
+
direction: 'normal | reverse | alternate | alternate-reverse',
|
|
74
|
+
iterations: 'A number, or "infinite" (the default).',
|
|
55
75
|
};
|
|
56
76
|
|
package/src/layers/barcode.js
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* @module layers/barcode
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { attrs, num } from '
|
|
8
|
-
import { len } from '
|
|
9
|
-
import { toHex } from '
|
|
7
|
+
import { attrs, num } from '@logomarks/image-effects/svg';
|
|
8
|
+
import { len } from '@logomarks/image-effects/length';
|
|
9
|
+
import { toHex } from '@logomarks/image-effects/color';
|
|
10
10
|
import { faceFor, setLine } from '../type/line.js';
|
|
11
11
|
import { pos, wrap, contentOf } from './util.js';
|
|
12
12
|
import { code128 } from './code128.js';
|
package/src/layers/geometry.js
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
* @module layers/geometry
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { attrs, num } from '
|
|
10
|
-
import { len } from '
|
|
9
|
+
import { attrs, num } from '@logomarks/image-effects/svg';
|
|
10
|
+
import { len } from '@logomarks/image-effects/length';
|
|
11
11
|
import { pos } from './util.js';
|
|
12
12
|
import { cutPath } from '../formats/cut.js';
|
|
13
|
-
import { invert, apply } from '../
|
|
13
|
+
import { invert, apply } from '../render/transform.js';
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -18,7 +18,7 @@ import { invert, apply } from '../effects/transform.js';
|
|
|
18
18
|
*
|
|
19
19
|
* @param {[number, number]} a @param {[number, number]} b
|
|
20
20
|
* @param {{ kind: string, size: number, step: number }} e
|
|
21
|
-
* @param {import('
|
|
21
|
+
* @param {import('@logomarks/image-effects/rng').Rng} rng
|
|
22
22
|
* @returns {[number, number][]} Points from a (exclusive) to b (inclusive).
|
|
23
23
|
*/
|
|
24
24
|
function edgePoints(a, b, e, rng) {
|
|
@@ -211,7 +211,7 @@ export function geometry(s, ctx) {
|
|
|
211
211
|
*
|
|
212
212
|
* @param {{ x: number, y: number, width: number, height: number, cut?: any, mm?: number } | undefined} cut - Trim box and cut, canvas px.
|
|
213
213
|
* @param {number} outset - Grow (or, negative, shrink) the outline, in the layer's units.
|
|
214
|
-
* @param {import('../
|
|
214
|
+
* @param {import('../render/transform.js').Affine | undefined} matrix - Layer units to canvas px.
|
|
215
215
|
* @param {{ width: number, height: number }} canvas
|
|
216
216
|
* @returns {{ d: string, box: { x: number, y: number, width: number, height: number } }}
|
|
217
217
|
*/
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* @module layers/perforation
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { attrs, num } from '
|
|
8
|
-
import { len } from '
|
|
9
|
-
import { toHex } from '
|
|
7
|
+
import { attrs, num } from '@logomarks/image-effects/svg';
|
|
8
|
+
import { len } from '@logomarks/image-effects/length';
|
|
9
|
+
import { toHex } from '@logomarks/image-effects/color';
|
|
10
10
|
import { pos, wrap } from './util.js';
|
|
11
11
|
|
|
12
12
|
|
package/src/layers/repeat.js
CHANGED
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
* @module layers/repeat
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import { num } from '
|
|
23
|
-
import { len } from '
|
|
22
|
+
import { num } from '@logomarks/image-effects/svg';
|
|
23
|
+
import { len } from '@logomarks/image-effects/length';
|
|
24
24
|
import { pos } from './util.js';
|
|
25
25
|
import { fill, evaluate } from './expr.js';
|
|
26
26
|
|
package/src/layers/shape.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// The `shape` layer.
|
|
2
2
|
import type { Color, Length, BaseLayer, Anchor } from '../index.js';
|
|
3
3
|
import type { RenderContext, Markup } from '../render/context.js';
|
|
4
|
-
import type { Paint } from '../
|
|
4
|
+
import type { Paint } from '../paint/index.js';
|
|
5
5
|
|
|
6
|
-
/** One exact shape (see the
|
|
6
|
+
/** One exact shape (see the `shape` row in docs/layers.md). */
|
|
7
7
|
export interface ShapeSpec {
|
|
8
8
|
kind?: 'rect' | 'circle' | 'ellipse' | 'line' | 'polygon' | 'polyline' | 'star' | 'burst' | 'scallop' | 'rays' | 'ring' | 'sector' | 'arch' | 'wave' | 'path' | 'cut';
|
|
9
9
|
x?: Length | `${number}%`; y?: Length | `${number}%`; width?: Length | `${number}%`; height?: Length | `${number}%`;
|
package/src/layers/shape.js
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* @module layers/shape
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { attrs, num } from '
|
|
8
|
-
import { len } from '
|
|
9
|
-
import { toHex } from '
|
|
10
|
-
import { paint } from '../
|
|
11
|
-
import { presetStrokes } from '../
|
|
7
|
+
import { attrs, num } from '@logomarks/image-effects/svg';
|
|
8
|
+
import { len } from '@logomarks/image-effects/length';
|
|
9
|
+
import { toHex } from '@logomarks/image-effects/color';
|
|
10
|
+
import { paint } from '../paint/index.js';
|
|
11
|
+
import { presetStrokes } from '../paint/presets.js';
|
|
12
12
|
import { wrap, pos } from './util.js';
|
|
13
13
|
import { geometry } from './geometry.js';
|
|
14
14
|
import { soften } from './soft.js';
|
package/src/layers/soft.js
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* @module layers/soft
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { attrs, num } from '
|
|
10
|
-
import { toBase64 } from '../platform/
|
|
9
|
+
import { attrs, num } from '@logomarks/image-effects/svg';
|
|
10
|
+
import { toBase64 } from '../platform/index.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Blur markup by `sigma` (px in the layer's units). In `renderImage`, the markup
|
package/src/layers/svg.js
CHANGED
|
@@ -4,11 +4,10 @@
|
|
|
4
4
|
* @module layers/svg
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { attrs, esc, num } from '
|
|
7
|
+
import { attrs, esc, num } from '@logomarks/image-effects/svg';
|
|
8
8
|
import { unit } from '../geometry.js';
|
|
9
9
|
import { pos, wrap } from './util.js';
|
|
10
|
-
import { expandDropShadows } from '
|
|
11
|
-
import { filterReach } from '../effects/region.js';
|
|
10
|
+
import { expandDropShadows, filterReach } from '@logomarks/image-effects';
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
/**
|
package/src/layers/table.js
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* @module layers/table
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { attrs, num } from '
|
|
8
|
-
import { len } from '
|
|
9
|
-
import { toHex } from '
|
|
7
|
+
import { attrs, num } from '@logomarks/image-effects/svg';
|
|
8
|
+
import { len } from '@logomarks/image-effects/length';
|
|
9
|
+
import { toHex } from '@logomarks/image-effects/color';
|
|
10
10
|
import { faceFor, setLine } from '../type/line.js';
|
|
11
11
|
import { pos, wrap, contentOf } from './util.js';
|
|
12
12
|
|
package/src/layers/tear.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// The `tear` layer.
|
|
2
2
|
import type { Color, Length, BaseLayer, Anchor } from '../index.js';
|
|
3
3
|
import type { RenderContext, Markup } from '../render/context.js';
|
|
4
|
-
import type { Paint } from '../
|
|
4
|
+
import type { Paint } from '../paint/index.js';
|
|
5
5
|
|
|
6
6
|
export interface TearLayer extends BaseLayer {
|
|
7
7
|
type: 'tear';
|
package/src/layers/tear.js
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* @module layers/tear
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { attrs, num } from '
|
|
8
|
-
import { len } from '
|
|
9
|
-
import { toHex } from '
|
|
10
|
-
import { paint } from '../
|
|
7
|
+
import { attrs, num } from '@logomarks/image-effects/svg';
|
|
8
|
+
import { len } from '@logomarks/image-effects/length';
|
|
9
|
+
import { toHex } from '@logomarks/image-effects/color';
|
|
10
|
+
import { paint } from '../paint/index.js';
|
|
11
11
|
import { pos, wrap } from './util.js';
|
|
12
12
|
|
|
13
13
|
|
package/src/layers/texture.js
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* @module layers/texture
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { attrs, num } from '
|
|
8
|
-
import { len } from '
|
|
9
|
-
import { toHex } from '
|
|
7
|
+
import { attrs, num } from '@logomarks/image-effects/svg';
|
|
8
|
+
import { len } from '@logomarks/image-effects/length';
|
|
9
|
+
import { toHex } from '@logomarks/image-effects/color';
|
|
10
10
|
import { pos, wrap } from './util.js';
|
|
11
11
|
|
|
12
12
|
|
package/src/layers/util.js
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* @module layers/util
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { attrs, esc } from '
|
|
9
|
-
import { len } from '
|
|
8
|
+
import { attrs, esc } from '@logomarks/image-effects/svg';
|
|
9
|
+
import { len } from '@logomarks/image-effects/length';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* A coordinate: px as a number, `'50%'` of the canvas along `axis`, or a
|
|
@@ -22,6 +22,19 @@ export function pos(v, axis, canvas) {
|
|
|
22
22
|
return len(/** @type {any} */ (v), canvas, 0);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Opacity and blend-mode attributes shared by every layer.
|
|
27
|
+
*
|
|
28
|
+
* @param {{ opacity?: number, blend?: string }} layer - The layer.
|
|
29
|
+
* @returns {Record<string, string | number | undefined>} Attributes for the layer's group.
|
|
30
|
+
*/
|
|
31
|
+
export function layerAttrs(layer) {
|
|
32
|
+
return {
|
|
33
|
+
opacity: layer.opacity != null && layer.opacity < 1 ? Math.max(0, layer.opacity) : undefined,
|
|
34
|
+
style: layer.blend && layer.blend !== 'normal' ? `mix-blend-mode:${layer.blend}` : undefined,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
25
38
|
/**
|
|
26
39
|
* Wrap markup in a group with the layer's `opacity` and `blend` (only when
|
|
27
40
|
* it has them).
|
package/src/layers.js
CHANGED
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
* @module layers
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { loadBytes } from './platform/index.js';
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import { len
|
|
21
|
-
import {
|
|
17
|
+
import { loadBytes, toBase64 } from './platform/index.js';
|
|
18
|
+
import { attrs, esc, num } from '@logomarks/image-effects/svg';
|
|
19
|
+
import { imageMime } from '@logomarks/image-effects';
|
|
20
|
+
import { len } from '@logomarks/image-effects/length';
|
|
21
|
+
import { place, anchorAlign, unit, regionPx } from './geometry.js';
|
|
22
|
+
import { toHex, mixOklab, toOklch, fromOklch } from '@logomarks/image-effects/color';
|
|
22
23
|
import { harfbuzz, loadFont, pickFont } from './fonts.js';
|
|
23
24
|
import { layout, runPath, caseText } from './text.js';
|
|
24
25
|
import { resolveIcon, parseSvgIcon } from './icons.js';
|
|
@@ -29,8 +30,8 @@ import { ink, dither, contour, waveform, tiles, rule } from './print.js';
|
|
|
29
30
|
import { typeset, wantsType } from './type/index.js';
|
|
30
31
|
import { recordLayout } from './type/layout-ref.js';
|
|
31
32
|
import { shape, svg, table, barcode, perforation, tear, texture } from './layers/index.js';
|
|
32
|
-
import { pos } from './layers/util.js';
|
|
33
|
-
import { paint } from './
|
|
33
|
+
import { pos, layerAttrs } from './layers/util.js';
|
|
34
|
+
import { paint } from './paint/index.js';
|
|
34
35
|
import { imageSize } from './lint/image-size.js';
|
|
35
36
|
|
|
36
37
|
/**
|
|
@@ -41,7 +42,7 @@ import { imageSize } from './lint/image-size.js';
|
|
|
41
42
|
* @property {number} height - Canvas height in px.
|
|
42
43
|
* @property {{ width: number, height: number }} canvas - The same, as an object.
|
|
43
44
|
* @property {import('./index.js').Palette} palette - The resolved palette.
|
|
44
|
-
* @property {import('
|
|
45
|
+
* @property {import('@logomarks/image-effects/rng').Rng} rng - This layer's own random stream.
|
|
45
46
|
* @property {string} id - A unique id prefix for this layer's defs.
|
|
46
47
|
* @property {import('./index.js').FontSource[]} fonts - Available fonts (Inter last).
|
|
47
48
|
* @property {any} [sharp] - The `sharp` module, when available.
|
|
@@ -421,7 +422,7 @@ export async function image(layer, ctx) {
|
|
|
421
422
|
const fit = layer.fit ?? 'cover';
|
|
422
423
|
const focus = layer.focus ?? 'center';
|
|
423
424
|
let bytes = typeof layer.src === 'string' || layer.src instanceof URL ? await readSource(layer.src) : await loadBytes(layer.src, 'image');
|
|
424
|
-
let mime =
|
|
425
|
+
let mime = imageMime(bytes);
|
|
425
426
|
let preserve = fit === 'stretch' ? 'none' : `${alignFor(focus)} ${fit === 'contain' ? 'meet' : 'slice'}`;
|
|
426
427
|
let sharpBlurred = false;
|
|
427
428
|
|
|
@@ -548,23 +549,6 @@ async function readSource(src) {
|
|
|
548
549
|
return loadBytes(src, 'image');
|
|
549
550
|
}
|
|
550
551
|
|
|
551
|
-
/**
|
|
552
|
-
* Sniff an image's MIME type from its first bytes.
|
|
553
|
-
*
|
|
554
|
-
* @param {Uint8Array} b - Image bytes.
|
|
555
|
-
* @returns {string | undefined} The MIME type.
|
|
556
|
-
*/
|
|
557
|
-
export function sniff(b) {
|
|
558
|
-
if (b[0] === 0x89 && b[1] === 0x50) return 'image/png';
|
|
559
|
-
if (b[0] === 0xff && b[1] === 0xd8) return 'image/jpeg';
|
|
560
|
-
if (b[0] === 0x47 && b[1] === 0x49) return 'image/gif';
|
|
561
|
-
const head = latin1(b.subarray(0, 32));
|
|
562
|
-
if (head.startsWith('RIFF') && head.slice(8, 12) === 'WEBP') return 'image/webp';
|
|
563
|
-
if (head.slice(4, 12) === 'ftypavif' || head.slice(4, 12) === 'ftypavis') return 'image/avif';
|
|
564
|
-
if (/^\s*(<\?xml|<svg)/i.test(utf8(b.subarray(0, 256)))) return 'image/svg+xml';
|
|
565
|
-
return undefined;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
552
|
// ---------------------------------------------------------------------------
|
|
569
553
|
// Texture
|
|
570
554
|
// ---------------------------------------------------------------------------
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
* radial fields with `rx`/`ry`), a `tile` pattern (checker, stripes, dots,
|
|
5
5
|
* grid or a custom tile), or a named preset (`'chrome'`).
|
|
6
6
|
*
|
|
7
|
-
* @module
|
|
7
|
+
* @module paint
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { attrs, num } from '
|
|
11
|
-
import { len } from '
|
|
12
|
-
import { toHex } from '
|
|
13
|
-
import { PRESETS } from './
|
|
10
|
+
import { attrs, num } from '@logomarks/image-effects/svg';
|
|
11
|
+
import { len } from '@logomarks/image-effects/length';
|
|
12
|
+
import { toHex } from '@logomarks/image-effects/color';
|
|
13
|
+
import { PRESETS } from './presets.js';
|
|
14
14
|
import { tile } from './tile.js';
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* horizon a little past the middle, warm ground below it, and a light
|
|
5
5
|
* bounce at the very bottom. Pair it with a light keyline (`strokes`).
|
|
6
6
|
*
|
|
7
|
-
* @module
|
|
7
|
+
* @module paint/presets
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/** Paint presets, by name. A paint `{ preset, …fields }` overrides any of them. */
|