vintage-frames 0.12.7 → 0.13.0
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/custom-elements.json +19 -19
- package/dist/chrome.d.ts +1 -1
- package/dist/components/vf-container.d.ts +5 -7
- package/dist/components/vf-container.js +1 -5
- package/dist/components/vf-desktop.d.ts +4 -5
- package/dist/components/vf-desktop.js +13 -18
- package/dist/components/vf-progress-bar.d.ts +2 -2
- package/dist/components/vf-progress-bar.js +55 -41
- package/dist/components/vf-slider.js +11 -11
- package/dist/components/vf-swatch.d.ts +2 -2
- package/dist/components/vf-swatch.js +37 -38
- package/dist/components/vf-window.d.ts +6 -9
- package/dist/components/vf-window.js +76 -77
- package/dist/index.d.ts +10 -9
- package/dist/index.js +62 -62
- package/dist/pattern-fill.d.ts +21 -50
- package/dist/pattern-fill.js +19 -54
- package/dist/scroll-rail.d.ts +6 -6
- package/dist/scroll-rail.js +24 -29
- package/dist/styles/recipes/pattern.d.ts +19 -10
- package/dist/styles/recipes/pattern.js +27 -18
- package/dist/styles/recipes/scroll-rail.d.ts +14 -7
- package/dist/styles/recipes/scroll-rail.js +14 -24
- package/dist/styles/recipes/tile.d.ts +11 -3
- package/dist/styles/recipes/tile.js +12 -12
- package/dist/tile-grid.d.ts +98 -64
- package/dist/tile-grid.js +63 -30
- package/dist/track-width.d.ts +1 -2
- package/docs/SPEC.md +11 -11
- package/editor/vscode.html-custom-data.json +2 -2
- package/editor/web-types.json +3 -3
- package/package.json +1 -1
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The trough's 25% lattice is the library's `gray-25` — QuickDraw's
|
|
3
|
+
* `ltGray`, and the UI kit's "Scroll bg" sprite — on its minimal cell: a
|
|
4
|
+
* 4×2-system-px motif with a dot at (0,0) and (2,1). The DOM trough repeats
|
|
5
|
+
* it as a tile drawn at the display's resolution (`--_vf-trough-tile`,
|
|
6
|
+
* written by `ScrollRailController` — 1-bit at every scale, zoom-minted ones
|
|
7
|
+
* included); the SVG span tile below is the forced-colors mask, which
|
|
8
|
+
* repaints the same art in the remapped ink token.
|
|
9
|
+
*/
|
|
10
|
+
export declare const TROUGH: import("../../patterns.js").PatternMotif;
|
|
4
11
|
/**
|
|
5
12
|
* System 7 scroll rails, drawn by the kit as ordinary shadow DOM — the skin
|
|
6
13
|
* for the subtree `renderScrollRail()` (src/scroll-rail.ts) produces. The
|
|
@@ -17,7 +24,7 @@ export declare const TROUGH_RECTS: readonly import("./tile.js").TileRect[];
|
|
|
17
24
|
* is kit art: subpixel layout device-snaps at paint like every other element,
|
|
18
25
|
* and the whole defect class is unrepresentable. It also renders identically
|
|
19
26
|
* in every engine (Firefox included), is assertable headless, and lets the
|
|
20
|
-
* trough adopt the
|
|
27
|
+
* trough adopt the repeating tile the other dithers use.
|
|
21
28
|
*
|
|
22
29
|
* Geometry (system px) — the classic 16px cell, of which the outermost line
|
|
23
30
|
* is the component's own 1px frame: the rail element is the 15 inside it —
|
|
@@ -52,9 +59,9 @@ export declare const TROUGH_RECTS: readonly import("./tile.js").TileRect[];
|
|
|
52
59
|
* through the vfBase token remap like every other element. The arrows are
|
|
53
60
|
* inline `currentColor` SVG now, so they re-ink with the palette (the old
|
|
54
61
|
* `::-webkit-scrollbar` skin's one genuine residual — mask-image is ignored
|
|
55
|
-
* on scrollbar pseudos — dies here). The trough
|
|
56
|
-
* it
|
|
57
|
-
*
|
|
62
|
+
* on scrollbar pseudos — dies here). The trough's tile keeps literal ink, so
|
|
63
|
+
* it goes and the trough repaints as the ink token masked by the same art
|
|
64
|
+
* (the vfDots idiom; the span mask keeps the zoom caveat every masked
|
|
58
65
|
* surface has, an accepted residual).
|
|
59
66
|
*/
|
|
60
67
|
export declare const vfScrollRail: import("lit").CSSResult;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { tileImage as e, tileRects as t, vfTileMaskSize as n } from "./tile.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { vfRepeatTileSize as r } from "../../tile-grid.js";
|
|
3
|
+
import { PATTERNS as i, patternMotif as a } from "../../patterns.js";
|
|
4
|
+
import { css as o, unsafeCSS as s } from "lit";
|
|
4
5
|
//#region src/styles/recipes/scroll-rail.ts
|
|
5
|
-
var
|
|
6
|
+
var c = a(i["gray-25"]), l = e(c.width, c.height, t(c.rects)), u = o`
|
|
6
7
|
/* Hide the native bar, keep the native scrolling. Both lines ship:
|
|
7
8
|
scrollbar-width reaches Chromium 121+/Firefox/Safari 18.2+, the pseudo
|
|
8
9
|
covers older WebKit — the last scrollbar pseudo left in the kit.
|
|
@@ -117,25 +118,16 @@ var s = i(r["gray-25"]), c = s.width, l = s.height, u = s.rects, d = e(c, l, t(u
|
|
|
117
118
|
min-width: 0;
|
|
118
119
|
min-height: 0;
|
|
119
120
|
}
|
|
120
|
-
/* The trough: the token base color
|
|
121
|
-
|
|
121
|
+
/* The trough: the dither over the token base color — the repeating tile
|
|
122
|
+
ScrollRailController writes (src/tile-grid.ts), 1-bit at every scale. */
|
|
122
123
|
.vf-rail-trough {
|
|
123
124
|
position: absolute;
|
|
124
125
|
inset: 0;
|
|
125
|
-
overflow: hidden;
|
|
126
126
|
background-color: var(--vf-scrollbar-track, var(--vf-white, #fff));
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
/* The dither raster ScrollRailController sizes and writes — one image px
|
|
130
|
-
per system px, magnified nearest-neighbor (the vf-img idiom), so the
|
|
131
|
-
lattice is 1-bit at every scale. */
|
|
132
|
-
.vf-rail-trough-art {
|
|
133
|
-
position: absolute;
|
|
134
|
-
top: 0;
|
|
135
|
-
left: 0;
|
|
136
|
-
background-size: 100% 100%;
|
|
137
|
-
background-repeat: no-repeat;
|
|
127
|
+
background-image: var(--_vf-trough-tile, none);
|
|
128
|
+
${r}
|
|
138
129
|
image-rendering: pixelated;
|
|
130
|
+
pointer-events: none;
|
|
139
131
|
}
|
|
140
132
|
/* The fixed System 7 thumb (never proportional): a white 16px box spanning
|
|
141
133
|
the channel. Its border reads as inset 1px from each channel rail — the
|
|
@@ -207,21 +199,19 @@ var s = i(r["gray-25"]), c = s.width, l = s.height, u = s.rects, d = e(c, l, t(u
|
|
|
207
199
|
display: none;
|
|
208
200
|
}
|
|
209
201
|
|
|
210
|
-
/* Forced colors: the
|
|
202
|
+
/* Forced colors: the tile keeps literal ink, so it goes and the trough
|
|
211
203
|
repaints as the remapped ink token masked by the same art (the vfDots
|
|
212
204
|
idiom — and like every masked tile, the span mask keeps the zoom
|
|
213
205
|
caveat). Everything else re-inks through the vfBase token remap; the
|
|
214
206
|
arrows are currentColor SVG and follow the palette by themselves. */
|
|
215
207
|
@media (forced-colors: active) {
|
|
216
208
|
.vf-rail-trough {
|
|
209
|
+
background-image: none;
|
|
217
210
|
background-color: var(--vf-black, #000);
|
|
218
|
-
mask-image: ${
|
|
219
|
-
${n(c,
|
|
220
|
-
}
|
|
221
|
-
.vf-rail-trough-art {
|
|
222
|
-
display: none;
|
|
211
|
+
mask-image: ${s(l)};
|
|
212
|
+
${n(c.width, c.height)}
|
|
223
213
|
}
|
|
224
214
|
}
|
|
225
215
|
`;
|
|
226
216
|
//#endregion
|
|
227
|
-
export { c as
|
|
217
|
+
export { c as TROUGH, u as vfScrollRail };
|
|
@@ -61,8 +61,9 @@ export type TileRect = readonly [x: number, y: number, w: number, h: number, fil
|
|
|
61
61
|
export declare function tileRects(rects: readonly TileRect[]): string;
|
|
62
62
|
/**
|
|
63
63
|
* The motif tiled over `spanWidth × spanHeight` system px as a RASTER image —
|
|
64
|
-
* a PNG data URI at
|
|
65
|
-
*
|
|
64
|
+
* a PNG data URI at `density` image px per system px (one by default) — the
|
|
65
|
+
* encoder behind the tile every kit surface repeats (`repeatTile`,
|
|
66
|
+
* src/tile-grid.ts).
|
|
66
67
|
*
|
|
67
68
|
* A raster because of how engines rasterize a fill's art, not how they place
|
|
68
69
|
* its box. Chromium rasterizes an SVG image at the box's *stored* (layout)
|
|
@@ -79,8 +80,15 @@ export declare function tileRects(rects: readonly TileRect[]): string;
|
|
|
79
80
|
* out as a data URI and released — kit art only, so there is nothing
|
|
80
81
|
* cross-origin to taint). Where canvas is unavailable the SVG tile is
|
|
81
82
|
* returned instead, so the declaration still paints.
|
|
83
|
+
*
|
|
84
|
+
* `density` draws each system px as a `density × density` block of whole
|
|
85
|
+
* image px. An image drawn at the device px per system px it will be shown
|
|
86
|
+
* at is copied 1:1 onto the device grid, so no engine's image filter has
|
|
87
|
+
* anything to decide — Safari smooths a magnified image on its repeating
|
|
88
|
+
* path whatever `image-rendering` says. It is still one pattern bit per
|
|
89
|
+
* system px; only who scales it changes.
|
|
82
90
|
*/
|
|
83
|
-
export declare function tileRaster(motifWidth: number, motifHeight: number, rects: readonly TileRect[], spanWidth?: number, spanHeight?: number): string;
|
|
91
|
+
export declare function tileRaster(motifWidth: number, motifHeight: number, rects: readonly TileRect[], spanWidth?: number, spanHeight?: number, density?: number): string;
|
|
84
92
|
/**
|
|
85
93
|
* `background-size` for a REPEATING tile — stated as the motif, sized as the
|
|
86
94
|
* span that motif tiles at ({@link tileSpan}).
|
|
@@ -11,18 +11,18 @@ function i(e, t, n, i = r(e), a = r(t)) {
|
|
|
11
11
|
function a(e) {
|
|
12
12
|
return e.map(([e, t, n, r, i]) => `%3Crect ${(e ? `x='${e}' ` : "") + (t ? `y='${t}' ` : "")}width='${n}' height='${r}'${i ? ` fill='${encodeURIComponent(i)}'` : ""}/%3E`).join("");
|
|
13
13
|
}
|
|
14
|
-
function o(e, t, n, o = r(e), s = r(t)) {
|
|
15
|
-
let
|
|
16
|
-
if (typeof document > "u") return
|
|
17
|
-
let
|
|
18
|
-
|
|
19
|
-
let
|
|
20
|
-
if (!
|
|
21
|
-
for (let [e, t, r, i, a] of n)
|
|
22
|
-
let
|
|
23
|
-
|
|
24
|
-
let
|
|
25
|
-
return !
|
|
14
|
+
function o(e, t, n, o = r(e), s = r(t), c = 1) {
|
|
15
|
+
let l = () => i(e, t, a(n), o, s);
|
|
16
|
+
if (typeof document > "u") return l();
|
|
17
|
+
let u = document.createElement("canvas");
|
|
18
|
+
u.width = e * c, u.height = t * c;
|
|
19
|
+
let d = u.getContext("2d");
|
|
20
|
+
if (!d) return l();
|
|
21
|
+
for (let [e, t, r, i, a] of n) d.fillStyle = a ?? "#000000", d.fillRect(e * c, t * c, r * c, i * c);
|
|
22
|
+
let f = document.createElement("canvas");
|
|
23
|
+
f.width = o * c, f.height = s * c;
|
|
24
|
+
let p = f.getContext("2d"), m = p?.createPattern(u, "repeat");
|
|
25
|
+
return !p || !m ? l() : (p.fillStyle = m, p.fillRect(0, 0, f.width, f.height), `url("${f.toDataURL("image/png")}")`);
|
|
26
26
|
}
|
|
27
27
|
function s(t, n = t) {
|
|
28
28
|
return e`
|
package/dist/tile-grid.d.ts
CHANGED
|
@@ -1,51 +1,39 @@
|
|
|
1
|
-
import { type CSSResult, type TemplateResult } from 'lit';
|
|
1
|
+
import { type CSSResult, type ReactiveController, type ReactiveControllerHost, type TemplateResult } from 'lit';
|
|
2
2
|
import { type TileRect } from './styles/recipes/tile.js';
|
|
3
3
|
/**
|
|
4
|
-
* The tiled-fill machinery
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* The tiled-fill machinery behind the kit's patterned surfaces — the desktop
|
|
5
|
+
* and container patterns, the windoid dots, the swatch checker, the barber
|
|
6
|
+
* stripes and the scroll trough.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
8
|
+
* **Kit art is a CSS repeat of one pre-scaled tile** ({@link repeatTile}):
|
|
9
|
+
* the motif laid over {@link REPEAT_TILE} system px square and drawn at n
|
|
10
|
+
* image px per system px, n = `--vf-scale × trueDpr` — whole by the scale
|
|
11
|
+
* contract — so the engine copies the tile to the device grid 1:1 and has no
|
|
12
|
+
* filtering to choose. The surface states the tile's size as
|
|
13
|
+
* {@link vfRepeatTileSize}, a length every engine holds exactly at every
|
|
14
|
+
* density and zoom, so each repeat lands exactly. The tile depends only on
|
|
15
|
+
* the art and n: it is encoded once per pair for the whole page, drawn again
|
|
16
|
+
* when zoom or the display changes n, and never on a resize.
|
|
17
|
+
* {@link RepeatTileController} keeps a box's tile current.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
19
|
+
* Why 120, and why pre-scaled (TILE-REPEAT-PLAN.md, in git history at
|
|
20
|
+
* commit 5bc45c2, has the measurements): Safari smooths a repeated image it
|
|
21
|
+
* has to magnify, whatever
|
|
22
|
+
* `image-rendering` says, so the image must already be at device
|
|
23
|
+
* resolution; and WebKit on a 3× display now and then draws one small tile a
|
|
24
|
+
* device px narrow and resamples it, which tiles of 192 device px and up
|
|
25
|
+
* never showed. The repeat replaced one raster the size of the whole surface,
|
|
26
|
+
* re-encoded as it was resized.
|
|
21
27
|
*
|
|
22
|
-
* **
|
|
23
|
-
*
|
|
24
|
-
* as a raster image at one image px per system px (`tileRaster`), stretched
|
|
25
|
-
* `background-size: 100% 100%` under `image-rendering: pixelated`. Exact at
|
|
26
|
-
* every scale, holdable or not, for two measured reasons: nearest-neighbor
|
|
27
|
-
* sampling can only produce source colors, and ONE box has no interior
|
|
28
|
-
* boundaries — Chromium paints an image background to the box's *unsnapped*
|
|
29
|
-
* layout rect with antialiased edges, so any fill assembled from several
|
|
30
|
-
* boxes blends a one-device-px line at every interior seam at a zoom-minted
|
|
31
|
-
* scale, no matter how exactly the boxes were placed. (That measurement is
|
|
32
|
-
* what buried both this plan's original per-tile form and SVG art of any
|
|
33
|
-
* kind: Chromium rasterizes SVG images at the fractional layout size and
|
|
34
|
-
* ignores `image-rendering` for them.) The box's own edge is the one place a
|
|
35
|
-
* partial device pixel remains — the same status every component box already
|
|
36
|
-
* has. The sampling stays exact because the box's stored length errs at most
|
|
37
|
-
* 1/128 CSS px over the WHOLE surface: the relative error shrinks as the
|
|
38
|
-
* surface grows, so the nearest-neighbor grid cannot slip a pixel at any
|
|
39
|
-
* realistic size.
|
|
40
|
-
*
|
|
41
|
-
* **Consumer art (token set): the placed tile grid** — a flat set of
|
|
42
|
-
* absolutely positioned `.vf-tile` boxes, each `T × T` system px at
|
|
28
|
+
* **Consumer art (a pattern token set): the placed tile grid** — a flat set
|
|
29
|
+
* of absolutely positioned `.vf-tile` boxes, each `T × T` system px at
|
|
43
30
|
* `left: calc(var(--vf-scale, 1) * kT px)`: one single-multiplication length
|
|
44
31
|
* per tile, quantized once, so each box paint-snaps onto the device grid
|
|
45
32
|
* independently and the documented tile geometry (`--vf-*-pattern` art on a
|
|
46
|
-
* 30- or 60-system-px tile) renders verbatim.
|
|
47
|
-
*
|
|
48
|
-
*
|
|
33
|
+
* 30- or 60-system-px tile) renders verbatim. A token is any CSS image —
|
|
34
|
+
* SVG included — so it cannot be pre-scaled the way kit art is. Positions
|
|
35
|
+
* never accumulate error; at a scale the layout grid cannot hold, what
|
|
36
|
+
* remains is a hairline per tile boundary, never surface-wide smear. Raster
|
|
49
37
|
* consumer art additionally magnifies nearest-neighbor (the `vf-img` idiom).
|
|
50
38
|
*
|
|
51
39
|
* The trap that must not come back: NEVER lay tiles out with CSS grid,
|
|
@@ -55,22 +43,18 @@ import { type TileRect } from './styles/recipes/tile.js';
|
|
|
55
43
|
* returns. Flat absolute placement with one multiplication per tile is the
|
|
56
44
|
* correctness, not a style choice.
|
|
57
45
|
*
|
|
58
|
-
* Wiring: the *container* — the layer the fill
|
|
46
|
+
* Wiring the grid: the *container* — the layer the fill paints on, or a
|
|
59
47
|
* dedicated child filling it — takes the `vf-tile-grid` class (clip and
|
|
60
48
|
* pointer transparency; it must be positioned, which every kit layer already
|
|
61
|
-
* is).
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* path the component renders a `.vf-tile-raster` child whose
|
|
65
|
-
* `background-image` it writes from `tileRaster(...)`, regenerated only when
|
|
66
|
-
* the declared system-px size changes (density and zoom re-render nothing:
|
|
67
|
-
* the box lengths are live against `--vf-scale`).
|
|
49
|
+
* is). It resolves `--_vf-tile-image` — the pattern-token `var()` each tile
|
|
50
|
+
* stretches over its box, stated once so no data URI is repeated per tile —
|
|
51
|
+
* and {@link tileGrid} renders the tiles.
|
|
68
52
|
*
|
|
69
|
-
* Forced colors keeps each surface's existing
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
53
|
+
* Forced colors keeps each surface's existing branches (flat Canvas desktop,
|
|
54
|
+
* span-masked dots, barber and trough, the swatch's forced-color-adjust) — no
|
|
55
|
+
* mask pipeline rasterizes exactly at a zoom-minted scale (image-rendering
|
|
56
|
+
* does not reach masks), so forced-colors-plus-zoom remains the one accepted
|
|
57
|
+
* residual.
|
|
74
58
|
*/
|
|
75
59
|
export declare const vfTileGrid: CSSResult;
|
|
76
60
|
/**
|
|
@@ -89,9 +73,9 @@ export declare function tileGrid({ cols, rows, tile, }: {
|
|
|
89
73
|
}): TemplateResult[];
|
|
90
74
|
/**
|
|
91
75
|
* The consumer's override of a pattern token, or `''` when the token is unset
|
|
92
|
-
* and the surface should paint its own art — how a
|
|
93
|
-
*
|
|
94
|
-
*
|
|
76
|
+
* and the surface should paint its own art — how a surface picks between its
|
|
77
|
+
* repeating kit tile and its placed tile grid (consumer art at the
|
|
78
|
+
* documented tile geometry).
|
|
95
79
|
*
|
|
96
80
|
* Read with `getComputedStyle` at update time, not observed live: a pattern
|
|
97
81
|
* token swapped at runtime without touching the component wants a nudge (any
|
|
@@ -99,15 +83,65 @@ export declare function tileGrid({ cols, rows, tile, }: {
|
|
|
99
83
|
* contract the component's other measured inputs follow.
|
|
100
84
|
*/
|
|
101
85
|
export declare function patternOverride(el: Element, token: string): string;
|
|
86
|
+
/** A motif as rect data over the cell it tiles at, in system px. */
|
|
87
|
+
export interface TileMotif {
|
|
88
|
+
readonly width: number;
|
|
89
|
+
readonly height: number;
|
|
90
|
+
readonly rects: readonly TileRect[];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The side of a kit repeat tile in system px: a whole number of every motif
|
|
94
|
+
* the kit draws (8 × 15 — the 2-, 4-, 8- and 12-px cells all divide it), and
|
|
95
|
+
* a whole number of layout px in every engine at every density and zoom
|
|
96
|
+
* (120n device px over the engine's ratio: 40n at 3×, 60n at 2×).
|
|
97
|
+
*/
|
|
98
|
+
export declare const REPEAT_TILE = 120;
|
|
99
|
+
/**
|
|
100
|
+
* `background-size` for a {@link repeatTile}: {@link REPEAT_TILE} system px
|
|
101
|
+
* square, live against `--vf-scale`.
|
|
102
|
+
*/
|
|
103
|
+
export declare const vfRepeatTileSize: CSSResult;
|
|
102
104
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
|
|
108
|
-
|
|
105
|
+
* The motif laid over {@link REPEAT_TILE} system px square and drawn at `n`
|
|
106
|
+
* image px per system px, as a CSS `url()` — the image a
|
|
107
|
+
* {@link vfRepeatTileSize} repeat copies 1:1 at that density. Cached for the
|
|
108
|
+
* page by the motif's content and `n`.
|
|
109
|
+
*/
|
|
110
|
+
export declare function repeatTile(motif: TileMotif, n: number): string;
|
|
111
|
+
/**
|
|
112
|
+
* Device px per system px at `el`: its `--vf-scale` (a consumer override
|
|
113
|
+
* included) times the true device pixel ratio — the `n` a {@link repeatTile}
|
|
114
|
+
* shown there is drawn at.
|
|
115
|
+
*/
|
|
116
|
+
export declare function devicePxAt(el: Element): number;
|
|
117
|
+
/** What a component hands {@link RepeatTileController}. */
|
|
118
|
+
export interface RepeatTileOptions {
|
|
119
|
+
/** The element the tile's custom property is written on. */
|
|
120
|
+
getBox: () => HTMLElement | null | undefined;
|
|
121
|
+
/** The art to tile, or null to write nothing (a consumer token owns the
|
|
122
|
+
* surface, or the component isn't showing it). Return the same object for
|
|
123
|
+
* the same art: an unchanged motif and density cost nothing. */
|
|
124
|
+
getArt: () => TileMotif | null | undefined;
|
|
125
|
+
/** The custom property the surface's `background-image` reads. */
|
|
126
|
+
property: string;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Keeps a box's {@link repeatTile} current: writes it as a custom property on
|
|
130
|
+
* the box's inline style after each host update, drawn for the density at
|
|
131
|
+
* the box, and again when zoom or the display changes that density
|
|
132
|
+
* ({@link onScaleChange}); removes it the moment there is nothing to paint.
|
|
133
|
+
* A custom-property channel rather than `background-image` itself, so a
|
|
134
|
+
* surface's forced-colors rule can out-cascade it without `!important`.
|
|
135
|
+
*
|
|
136
|
+
* The surface's stylesheet does the rest: `background-image` from the
|
|
137
|
+
* property, {@link vfRepeatTileSize}, `background-repeat: repeat`, and
|
|
138
|
+
* `image-rendering: pixelated` for the frame between a zoom and the new
|
|
139
|
+
* tile.
|
|
109
140
|
*/
|
|
110
|
-
export declare class
|
|
141
|
+
export declare class RepeatTileController implements ReactiveController {
|
|
111
142
|
#private;
|
|
112
|
-
|
|
143
|
+
constructor(host: ReactiveControllerHost, opts: RepeatTileOptions);
|
|
144
|
+
hostConnected(): void;
|
|
145
|
+
hostDisconnected(): void;
|
|
146
|
+
hostUpdated(): void;
|
|
113
147
|
}
|
package/dist/tile-grid.js
CHANGED
|
@@ -1,53 +1,86 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { truePixelRatio as e } from "./zoom.js";
|
|
2
|
+
import { effectiveScale as t, onScaleChange as n, sysLength as r } from "./scale.js";
|
|
3
|
+
import { tileRaster as i } from "./styles/recipes/tile.js";
|
|
4
|
+
import { css as a, html as o } from "lit";
|
|
4
5
|
//#region src/tile-grid.ts
|
|
5
|
-
var
|
|
6
|
+
var s = a`
|
|
6
7
|
.vf-tile-grid {
|
|
7
8
|
/* Clip the overdraw: a fill overdrawn past a box that is not a whole
|
|
8
|
-
number of tiles
|
|
9
|
+
number of tiles crops here. */
|
|
9
10
|
overflow: hidden;
|
|
10
11
|
pointer-events: none;
|
|
11
12
|
}
|
|
12
|
-
.vf-tile
|
|
13
|
-
.vf-tile-raster {
|
|
13
|
+
.vf-tile {
|
|
14
14
|
position: absolute;
|
|
15
15
|
/* The box IS the size — never the image's intrinsic size, and never an
|
|
16
16
|
intra-box repeat: a consumer tile smaller than its box repeating
|
|
17
17
|
inside it would re-import the accumulation this module removes. */
|
|
18
|
+
background-image: var(--_vf-tile-image);
|
|
18
19
|
background-size: 100% 100%;
|
|
19
20
|
background-repeat: no-repeat;
|
|
20
|
-
/*
|
|
21
|
-
|
|
22
|
-
for SVG (which is why kit art is raster; see tileRaster). */
|
|
21
|
+
/* Consumer raster art samples nearest-neighbor — the vf-img idiom. A
|
|
22
|
+
no-op for SVG. */
|
|
23
23
|
image-rendering: pixelated;
|
|
24
24
|
}
|
|
25
|
-
.vf-tile {
|
|
26
|
-
background-image: var(--_vf-tile-image);
|
|
27
|
-
}
|
|
28
|
-
.vf-tile-raster {
|
|
29
|
-
top: 0;
|
|
30
|
-
left: 0;
|
|
31
|
-
}
|
|
32
25
|
`;
|
|
33
|
-
function
|
|
34
|
-
let
|
|
35
|
-
for (let s = 0; s <
|
|
26
|
+
function c({ cols: e, rows: t, tile: n }) {
|
|
27
|
+
let i = r(n), a = [];
|
|
28
|
+
for (let s = 0; s < t; s++) for (let t = 0; t < e; t++) a.push(o`<span
|
|
36
29
|
class="vf-tile"
|
|
37
|
-
style="left:${
|
|
30
|
+
style="left:${r(t * n)};top:${r(s * n)};width:${i};height:${i}"
|
|
38
31
|
></span>`);
|
|
39
|
-
return
|
|
32
|
+
return a;
|
|
40
33
|
}
|
|
41
|
-
function
|
|
34
|
+
function l(e, t) {
|
|
42
35
|
return typeof getComputedStyle > "u" ? "" : getComputedStyle(e).getPropertyValue(t).trim();
|
|
43
36
|
}
|
|
44
|
-
var
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
37
|
+
var u = 120, d = a`
|
|
38
|
+
background-size: calc(var(--vf-scale, 1) * ${120}px)
|
|
39
|
+
calc(var(--vf-scale, 1) * ${120}px);
|
|
40
|
+
`, f = /* @__PURE__ */ new Map();
|
|
41
|
+
function p(e, t) {
|
|
42
|
+
let n = `${e.width}×${e.height}|${t}|${e.rects.join(";")}`, r = f.get(n);
|
|
43
|
+
return r || (r = i(e.width, e.height, e.rects, 120, 120, t), f.set(n, r)), r;
|
|
44
|
+
}
|
|
45
|
+
function m(n) {
|
|
46
|
+
return Math.max(1, Math.round(t(n) * e()));
|
|
47
|
+
}
|
|
48
|
+
var h = class {
|
|
49
|
+
#e;
|
|
50
|
+
#t;
|
|
51
|
+
#n = null;
|
|
52
|
+
#r = null;
|
|
53
|
+
#i = 0;
|
|
54
|
+
#a = "";
|
|
55
|
+
constructor(e, t) {
|
|
56
|
+
this.#e = t, e.addController(this);
|
|
57
|
+
}
|
|
58
|
+
hostConnected() {
|
|
59
|
+
this.#t = n(() => this.#o());
|
|
60
|
+
}
|
|
61
|
+
hostDisconnected() {
|
|
62
|
+
this.#t?.(), this.#t = void 0;
|
|
63
|
+
}
|
|
64
|
+
hostUpdated() {
|
|
65
|
+
this.#o();
|
|
66
|
+
}
|
|
67
|
+
#o() {
|
|
68
|
+
let e = this.#e.getBox() ?? null;
|
|
69
|
+
e !== this.#n && (this.#s(), this.#n = e);
|
|
70
|
+
let t = this.#e.getArt() ?? null;
|
|
71
|
+
if (!e || !t) {
|
|
72
|
+
this.#s();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
let n = m(e);
|
|
76
|
+
if (t === this.#r && n === this.#i && this.#a) return;
|
|
77
|
+
this.#r = t, this.#i = n;
|
|
78
|
+
let r = p(t, n);
|
|
79
|
+
r !== this.#a && (this.#a = r, e.style.setProperty(this.#e.property, r));
|
|
80
|
+
}
|
|
81
|
+
#s() {
|
|
82
|
+
this.#r = null, this.#i = 0, this.#a && (this.#a = "", this.#n?.style.removeProperty(this.#e.property));
|
|
50
83
|
}
|
|
51
84
|
};
|
|
52
85
|
//#endregion
|
|
53
|
-
export {
|
|
86
|
+
export { u as REPEAT_TILE, h as RepeatTileController, m as devicePxAt, l as patternOverride, p as repeatTile, c as tileGrid, d as vfRepeatTileSize, s as vfTileGrid };
|
package/dist/track-width.d.ts
CHANGED
|
@@ -22,8 +22,7 @@ import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
|
22
22
|
* runs on every update.
|
|
23
23
|
*
|
|
24
24
|
* The height comes along from the same observation, for a box measured on
|
|
25
|
-
* both axes
|
|
26
|
-
* raster to a box whose extent nobody declared.
|
|
25
|
+
* both axes.
|
|
27
26
|
*/
|
|
28
27
|
export declare class TrackWidthController implements ReactiveController {
|
|
29
28
|
private readonly host;
|