@fabi-play/engine 0.5.0 → 0.7.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/README.md +14 -0
- package/dist/fabi-play-engine.d.ts +65 -5
- package/dist/fabi-play-engine.js +13 -13
- package/dist/fabi-play-engine.lite.d.ts +65 -5
- package/dist/fabi-play-engine.lite.js +13 -13
- package/dist/fabi-play-engine.lite.umd.js +118 -20
- package/dist/fabi-play-engine.lite.umd.min.js +13 -13
- package/dist/fabi-play-engine.umd.js +118 -20
- package/dist/fabi-play-engine.umd.min.js +13 -13
- package/dist/index.d.ts +65 -5
- package/dist/index.development.js +117 -19
- package/dist/index.js +13 -13
- package/dist/integrity.json +9 -9
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -71,6 +71,36 @@ export interface BackdropView {
|
|
|
71
71
|
/** Height, a fraction of the viewport's height. */
|
|
72
72
|
h: number;
|
|
73
73
|
}
|
|
74
|
+
/** A hand: the child's own left or right. */
|
|
75
|
+
export type HandSide = "left" | "right";
|
|
76
|
+
declare class AimHold {
|
|
77
|
+
readonly holdMs: number;
|
|
78
|
+
private readonly last;
|
|
79
|
+
constructor(holdMs?: number);
|
|
80
|
+
/** A number for a player's hand. */
|
|
81
|
+
static key(player: number, side: HandSide): number;
|
|
82
|
+
/** The aim to use at time t (ms) for the hand key, given what aimPoint said now (p, or null if lost). */
|
|
83
|
+
at(key: number, p: Point | null, t: number): Point | null;
|
|
84
|
+
/** Forgets every hand. */
|
|
85
|
+
clear(): void;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The parts of the game's viewport a phone's notch, rounded corners or home bar may cover, in fractions of the
|
|
89
|
+
* viewport (top and bottom of its height, left and right of its width; each 0–0.25). The game's frame cannot read
|
|
90
|
+
* env(safe-area-inset-*), so the screen sends it (init.safeArea): keep buttons, scores and targets out of it, and
|
|
91
|
+
* still paint the background under it. Zeros where nothing is covered (a TV, a tablet, older hosts).
|
|
92
|
+
*/
|
|
93
|
+
export interface SafeArea {
|
|
94
|
+
top: number;
|
|
95
|
+
bottom: number;
|
|
96
|
+
left: number;
|
|
97
|
+
right: number;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* A screen's orientation: 'landscape' when its width is at least its height, else 'portrait' (see orientationOf).
|
|
101
|
+
* GameManifest.orientations lists those a game supports; HostMessage init.orientation says the one it starts in.
|
|
102
|
+
*/
|
|
103
|
+
export type Orientation = "landscape" | "portrait";
|
|
74
104
|
/**
|
|
75
105
|
* Small pure helpers: 2D affine matrices, colours, easing. No DOM here, so they run in Node tests.
|
|
76
106
|
*/
|
|
@@ -1324,11 +1354,18 @@ export declare function wrists(body: Body): {
|
|
|
1324
1354
|
}[];
|
|
1325
1355
|
/** A player's colour (CSS), as the TV draws them: player 1 orange, 2 blue, 3 green, 4 lilac, then again. */
|
|
1326
1356
|
export declare const playerColor: (player: number) => "#EE6A43" | "#6FA0E0" | "#8CC9A0" | "#C49BE0";
|
|
1357
|
+
/** handsOf's aim: the screen's orientation and, in portrait, what keeps hands through short losses (and its clock, ms). */
|
|
1358
|
+
export interface HandsAim {
|
|
1359
|
+
orientation?: Orientation;
|
|
1360
|
+
hold?: AimHold;
|
|
1361
|
+
t?: number;
|
|
1362
|
+
}
|
|
1327
1363
|
/**
|
|
1328
|
-
* Every player's hands in stage units
|
|
1329
|
-
*
|
|
1364
|
+
* Every player's hands in stage units, where they aim (the protocol's aimPoint), times the stage size; bodyOf(frame)
|
|
1365
|
+
* is the body to read (null: the frame's own). Landscape (the default): its wrists through toScreen (player space to
|
|
1366
|
+
* screen fractions). Portrait (aim.orientation): the wrists stretched to the whole screen, held by aim.hold if given.
|
|
1330
1367
|
*/
|
|
1331
|
-
export declare function handsOf(frames: readonly PlayerFrame[], toScreen: (p: Point) => Point, width: number, height: number, bodyOf?: (f: PlayerFrame) => Body | null): Hand[];
|
|
1368
|
+
export declare function handsOf(frames: readonly PlayerFrame[], toScreen: (p: Point) => Point, width: number, height: number, bodyOf?: (f: PlayerFrame) => Body | null, aim?: HandsAim): Hand[];
|
|
1332
1369
|
/** What a node offers to hit tests: its world transform, size and anchor, or a radius. */
|
|
1333
1370
|
export interface Hittable {
|
|
1334
1371
|
/** The node's transform to the stage. */
|
|
@@ -1505,6 +1542,10 @@ export interface PlayLike {
|
|
|
1505
1542
|
readonly backdrop?: Backdrop;
|
|
1506
1543
|
/** Where the camera image is on the screen, in fractions; null if unknown. */
|
|
1507
1544
|
readonly view?: BackdropView | null;
|
|
1545
|
+
/** The screen's orientation at the start ('landscape' if unknown): in 'portrait' the hands aim (see Engine.hands). */
|
|
1546
|
+
readonly orientation?: Orientation;
|
|
1547
|
+
/** What a phone's notch and home bar cover, fractions of the viewport (see Engine.safeArea). */
|
|
1548
|
+
readonly safeArea?: SafeArea;
|
|
1508
1549
|
/** The screen's sound is off. */
|
|
1509
1550
|
readonly muted?: boolean;
|
|
1510
1551
|
/** What the screen knows about the device (init.device): a starting tier and the display's rate. */
|
|
@@ -1614,6 +1655,18 @@ export interface Engine {
|
|
|
1614
1655
|
readonly backdrop: Backdrop;
|
|
1615
1656
|
/** Where the camera image is on the screen, in fractions; null if the host didn't say. */
|
|
1616
1657
|
readonly view: BackdropView | null;
|
|
1658
|
+
/**
|
|
1659
|
+
* The screen's orientation when the game started: 'landscape' (a TV, a tablet; also before the host says) or
|
|
1660
|
+
* 'portrait' (a phone held upright). It decides where hands() are (see there).
|
|
1661
|
+
*/
|
|
1662
|
+
readonly orientation: Orientation;
|
|
1663
|
+
/**
|
|
1664
|
+
* What a phone's notch, rounded corners and home bar cover, in fractions of the viewport (top and bottom of its
|
|
1665
|
+
* height, left and right of its width; each 0–0.25; zeros on a TV, a tablet, and from hosts that don't say). The
|
|
1666
|
+
* game's frame can't read env(safe-area-inset-*): keep buttons, scores and targets out of it (in stage units, top
|
|
1667
|
+
* × 720, left × stage.width), still paint the background under it.
|
|
1668
|
+
*/
|
|
1669
|
+
readonly safeArea: Readonly<SafeArea>;
|
|
1617
1670
|
/** Paused by the host (pause, break) or by pause(): game time, tweens, particles and sound are stopped. */
|
|
1618
1671
|
readonly paused: boolean;
|
|
1619
1672
|
/** Sounds and tones, quiet while paused or muted. */
|
|
@@ -1700,9 +1753,16 @@ export interface Engine {
|
|
|
1700
1753
|
* bitmap fonts (.fnt, or a BMFont .json, + page images), sounds and fonts, by name.
|
|
1701
1754
|
*/
|
|
1702
1755
|
load(assets: Record<string, string>): Promise<void>;
|
|
1703
|
-
/**
|
|
1756
|
+
/**
|
|
1757
|
+
* This frame's hands (of one player, or everyone's), stage units, where they aim: what they touch, catch, press.
|
|
1758
|
+
* Landscape (a TV, a tablet): in the avatar's hands, or on the real ones over the video. Portrait (a phone held
|
|
1759
|
+
* upright, where the camera image is small at the bottom): the wrists stretched around the shoulders to the whole
|
|
1760
|
+
* stage (the protocol's aimPoint), so arms straight up reach the top (y ≈ 0.15 × 720) and arms out the sides, held
|
|
1761
|
+
* for 300 ms when the camera loses a wrist; the avatars are still drawn small in the view. To draw on the body
|
|
1762
|
+
* itself, use toScreen(wrist) of the SDK. touched() and handMarkers() use these hands.
|
|
1763
|
+
*/
|
|
1704
1764
|
hands(player?: number): Hand[];
|
|
1705
|
-
/** The first hand (of one player, or anyone's) touching the node, or null. padding: stage units. */
|
|
1765
|
+
/** The first hand (of one player, or anyone's) touching the node, or null; the hands are hands()'s. padding: stage units. */
|
|
1706
1766
|
touched(node: Node, player?: number, opts?: {
|
|
1707
1767
|
padding?: number;
|
|
1708
1768
|
}): Hand | null;
|
|
@@ -28,7 +28,77 @@ var DEFAULT_AVATARS_BY_AGE = {
|
|
|
28
28
|
};
|
|
29
29
|
var DEFAULT_AVATARS = DEFAULT_AVATARS_BY_AGE["6-8"];
|
|
30
30
|
var toScreen = (view, p) => view ? { x: view.x + p.x * view.w, y: view.y + p.y * view.h } : { x: p.x, y: p.y };
|
|
31
|
+
var AIM_VISIBLE = 0.5;
|
|
32
|
+
var HAND_SPACE = { left: 1.6, top: 1.6, w: 3.2, h: 3 };
|
|
33
|
+
var TORSO_PER_SHOULDER_WIDTH = 1.2;
|
|
34
|
+
function aimPoint(who, side, opts = {}) {
|
|
35
|
+
const body = Array.isArray(who) ? who : who.body;
|
|
36
|
+
if (!Array.isArray(body)) return null;
|
|
37
|
+
const w2 = side === "left" ? P.leftWrist : P.rightWrist;
|
|
38
|
+
const at = (i) => isNumber(body[i * 3]) && isNumber(body[i * 3 + 1]) && (body[i * 3 + 2] ?? 0) >= AIM_VISIBLE ? i : -1;
|
|
39
|
+
if (at(w2) < 0) return null;
|
|
40
|
+
const wx = body[w2 * 3];
|
|
41
|
+
const wy = body[w2 * 3 + 1];
|
|
42
|
+
if (opts.orientation !== "portrait") return toScreen(opts.view, { x: wx, y: wy });
|
|
43
|
+
if (at(P.leftShoulder) < 0 || at(P.rightShoulder) < 0) return null;
|
|
44
|
+
const ls = P.leftShoulder * 3;
|
|
45
|
+
const rs = P.rightShoulder * 3;
|
|
46
|
+
const sx = (body[ls] + body[rs]) / 2;
|
|
47
|
+
const sy = (body[ls + 1] + body[rs + 1]) / 2;
|
|
48
|
+
const lh = P.leftHip * 3;
|
|
49
|
+
const rh = P.rightHip * 3;
|
|
50
|
+
const hx = (body[lh] + body[rh]) / 2;
|
|
51
|
+
const hy = (body[lh + 1] + body[rh + 1]) / 2;
|
|
52
|
+
let torso = isNumber(hx) && isNumber(hy) ? Math.hypot(hx - sx, hy - sy) : 0;
|
|
53
|
+
if (at(P.leftHip) < 0 || at(P.rightHip) < 0) torso = Math.max(torso, TORSO_PER_SHOULDER_WIDTH * Math.hypot(body[ls] - body[rs], body[ls + 1] - body[rs + 1]));
|
|
54
|
+
torso = Math.max(torso, 0.01);
|
|
55
|
+
return {
|
|
56
|
+
x: clamp01((wx - sx + HAND_SPACE.left * torso) / (HAND_SPACE.w * torso)),
|
|
57
|
+
y: clamp01((wy - sy + HAND_SPACE.top * torso) / (HAND_SPACE.h * torso))
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
var AIM_HOLD_MS = 300;
|
|
61
|
+
var AimHold = class {
|
|
62
|
+
constructor(holdMs = AIM_HOLD_MS) {
|
|
63
|
+
__publicField(this, "holdMs", holdMs);
|
|
64
|
+
__publicField(this, "last", /* @__PURE__ */ new Map());
|
|
65
|
+
}
|
|
66
|
+
/** A number for a player's hand. */
|
|
67
|
+
static key(player, side) {
|
|
68
|
+
return player * 2 + (side === "right" ? 1 : 0);
|
|
69
|
+
}
|
|
70
|
+
/** The aim to use at time t (ms) for the hand key, given what aimPoint said now (p, or null if lost). */
|
|
71
|
+
at(key, p, t) {
|
|
72
|
+
const l = this.last.get(key);
|
|
73
|
+
if (p) {
|
|
74
|
+
if (l) {
|
|
75
|
+
l.x = p.x;
|
|
76
|
+
l.y = p.y;
|
|
77
|
+
l.t = t;
|
|
78
|
+
} else this.last.set(key, { x: p.x, y: p.y, t });
|
|
79
|
+
return p;
|
|
80
|
+
}
|
|
81
|
+
if (!l) return null;
|
|
82
|
+
if (t - l.t <= this.holdMs) return { x: l.x, y: l.y };
|
|
83
|
+
this.last.delete(key);
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
/** Forgets every hand. */
|
|
87
|
+
clear() {
|
|
88
|
+
this.last.clear();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
var MAX_SAFE_INSET = 0.25;
|
|
92
|
+
var NO_SAFE_AREA = Object.freeze({ top: 0, bottom: 0, left: 0, right: 0 });
|
|
93
|
+
function parseSafeArea(v) {
|
|
94
|
+
if (!isObject(v)) return void 0;
|
|
95
|
+
const f = (n) => isNumber(n) ? Math.min(Math.max(n, 0), MAX_SAFE_INSET) : 0;
|
|
96
|
+
return { top: f(v.top), bottom: f(v.bottom), left: f(v.left), right: f(v.right) };
|
|
97
|
+
}
|
|
31
98
|
var COVER_ASPECT = 16 / 9;
|
|
99
|
+
var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
100
|
+
var isNumber = (v) => typeof v === "number" && Number.isFinite(v);
|
|
101
|
+
var clamp01 = (n) => Math.min(Math.max(n, 0), 1);
|
|
32
102
|
var POSE_HEADER = 12;
|
|
33
103
|
var POSE_BODY_BYTES = LANDMARKS * 4;
|
|
34
104
|
var poseBytes = (bodies) => POSE_HEADER + bodies * POSE_BODY_BYTES;
|
|
@@ -4336,11 +4406,20 @@ function wrists(body) {
|
|
|
4336
4406
|
return out;
|
|
4337
4407
|
}
|
|
4338
4408
|
var playerColor = (player) => PLAYER_COLORS[((player - 1) % PLAYER_COLORS.length + PLAYER_COLORS.length) % PLAYER_COLORS.length];
|
|
4339
|
-
|
|
4409
|
+
var SIDES = ["left", "right"];
|
|
4410
|
+
function handsOf(frames, toScreen2, width, height, bodyOf = () => null, aim = {}) {
|
|
4340
4411
|
const out = [];
|
|
4341
4412
|
for (const f of frames) {
|
|
4342
4413
|
const body = bodyOf(f) ?? f.body;
|
|
4343
4414
|
if (!Array.isArray(body)) continue;
|
|
4415
|
+
if (aim.orientation === "portrait") {
|
|
4416
|
+
for (const side of SIDES) {
|
|
4417
|
+
let p = aimPoint(body, side, { orientation: "portrait" });
|
|
4418
|
+
if (aim.hold) p = aim.hold.at(AimHold.key(f.id, side), p, aim.t ?? 0);
|
|
4419
|
+
if (p) out.push({ player: f.id, side, x: p.x * width, y: p.y * height, color: playerColor(f.id) });
|
|
4420
|
+
}
|
|
4421
|
+
continue;
|
|
4422
|
+
}
|
|
4344
4423
|
for (const w2 of wrists(body)) {
|
|
4345
4424
|
const s = toScreen2(w2);
|
|
4346
4425
|
out.push({ player: f.id, side: w2.side, x: s.x * width, y: s.y * height, color: playerColor(f.id) });
|
|
@@ -5002,6 +5081,10 @@ var HandMarkers = class extends Node {
|
|
|
5002
5081
|
}
|
|
5003
5082
|
};
|
|
5004
5083
|
var now = () => performance.now();
|
|
5084
|
+
var frozenSafeArea = (v) => {
|
|
5085
|
+
const sa = parseSafeArea(v);
|
|
5086
|
+
return sa && Object.freeze(sa);
|
|
5087
|
+
};
|
|
5005
5088
|
async function createEngine(opts = {}) {
|
|
5006
5089
|
const play = opts.play ?? null;
|
|
5007
5090
|
let canvas = opts.canvas ?? null;
|
|
@@ -5136,6 +5219,8 @@ async function createEngine(opts = {}) {
|
|
|
5136
5219
|
ro?.observe(canvas);
|
|
5137
5220
|
let backdrop = play?.backdrop === "video" ? "video" : "none";
|
|
5138
5221
|
let view = play?.view ?? null;
|
|
5222
|
+
let orientation = play?.orientation === "portrait" ? "portrait" : "landscape";
|
|
5223
|
+
let safeArea = frozenSafeArea(play?.safeArea) ?? NO_SAFE_AREA;
|
|
5139
5224
|
let livePlayers = [];
|
|
5140
5225
|
let lastPlayersAt = -Infinity;
|
|
5141
5226
|
let hostPaused = false;
|
|
@@ -5163,7 +5248,7 @@ async function createEngine(opts = {}) {
|
|
|
5163
5248
|
lastPlayersAt = now();
|
|
5164
5249
|
}
|
|
5165
5250
|
};
|
|
5166
|
-
const
|
|
5251
|
+
const hold2 = (on) => {
|
|
5167
5252
|
hostPaused = on;
|
|
5168
5253
|
syncSound();
|
|
5169
5254
|
};
|
|
@@ -5177,6 +5262,11 @@ async function createEngine(opts = {}) {
|
|
|
5177
5262
|
};
|
|
5178
5263
|
unlisten.push(
|
|
5179
5264
|
play.on("start", (m) => lateHint(m?.device)),
|
|
5265
|
+
play.on("start", (m) => {
|
|
5266
|
+
if (m?.orientation === "portrait" || m?.orientation === "landscape") orientation = m.orientation;
|
|
5267
|
+
const sa = frozenSafeArea(m?.safeArea);
|
|
5268
|
+
if (sa) safeArea = sa;
|
|
5269
|
+
}),
|
|
5180
5270
|
// The simple API knows muted only from the start (its getter is false before): read it again then.
|
|
5181
5271
|
play.on("start", (m) => {
|
|
5182
5272
|
if (typeof m?.muted === "boolean") sound.muted = m.muted;
|
|
@@ -5185,11 +5275,11 @@ async function createEngine(opts = {}) {
|
|
|
5185
5275
|
play.on("players", (m) => setPlayers(m?.players)),
|
|
5186
5276
|
play.on("backdrop", (m) => setBackdrop(m?.backdrop, m?.view)),
|
|
5187
5277
|
play.on("start", (m) => setBackdrop(m?.backdrop, m?.view ?? play.view)),
|
|
5188
|
-
play.on("pause", () =>
|
|
5189
|
-
play.on("resume", () =>
|
|
5190
|
-
play.on("break-start", () =>
|
|
5191
|
-
play.on("break-done", () =>
|
|
5192
|
-
play.on("break-end", () =>
|
|
5278
|
+
play.on("pause", () => hold2(true)),
|
|
5279
|
+
play.on("resume", () => hold2(false)),
|
|
5280
|
+
play.on("break-start", () => hold2(true)),
|
|
5281
|
+
play.on("break-done", () => hold2(false)),
|
|
5282
|
+
play.on("break-end", () => hold2(false))
|
|
5193
5283
|
);
|
|
5194
5284
|
sound.muted = play.muted === true;
|
|
5195
5285
|
}
|
|
@@ -5200,11 +5290,13 @@ async function createEngine(opts = {}) {
|
|
|
5200
5290
|
let tick = 0;
|
|
5201
5291
|
const live = () => now() - lastPlayersAt < 1e3 ? livePlayers : [];
|
|
5202
5292
|
const toScreen2 = (p) => play ? play.toScreen(p) : toScreen(view, p);
|
|
5293
|
+
const hold = new AimHold();
|
|
5203
5294
|
const allHands = () => {
|
|
5204
5295
|
if (handsAt === tick) return handsCache;
|
|
5205
5296
|
handsAt = tick;
|
|
5206
|
-
const
|
|
5207
|
-
|
|
5297
|
+
const portrait = orientation === "portrait";
|
|
5298
|
+
const bodyOf = backdrop === "video" && !portrait || !play?.smoothedBody ? () => null : (f) => play.smoothedBody(f);
|
|
5299
|
+
handsCache = handsOf(live(), toScreen2, stageW, STAGE_HEIGHT, bodyOf, portrait ? { orientation, hold, t: now() } : void 0);
|
|
5208
5300
|
return handsCache;
|
|
5209
5301
|
};
|
|
5210
5302
|
const box = { x: 0, y: 0, w: 1, h: 1 };
|
|
@@ -5367,6 +5459,12 @@ async function createEngine(opts = {}) {
|
|
|
5367
5459
|
get view() {
|
|
5368
5460
|
return view;
|
|
5369
5461
|
},
|
|
5462
|
+
get orientation() {
|
|
5463
|
+
return orientation;
|
|
5464
|
+
},
|
|
5465
|
+
get safeArea() {
|
|
5466
|
+
return safeArea;
|
|
5467
|
+
},
|
|
5370
5468
|
get paused() {
|
|
5371
5469
|
return hostPaused || userPaused;
|
|
5372
5470
|
},
|
|
@@ -6226,7 +6324,7 @@ ${msg}`);
|
|
|
6226
6324
|
};
|
|
6227
6325
|
|
|
6228
6326
|
// src/filters.ts
|
|
6229
|
-
var
|
|
6327
|
+
var clamp012 = (v) => Math.min(Math.max(v, 0), 1);
|
|
6230
6328
|
var pos = (v) => Math.max(v, 0);
|
|
6231
6329
|
var Base = class {
|
|
6232
6330
|
constructor() {
|
|
@@ -6278,11 +6376,11 @@ var Contrast = class extends Amount {
|
|
|
6278
6376
|
};
|
|
6279
6377
|
var Invert = class extends Amount {
|
|
6280
6378
|
toMatrix(m) {
|
|
6281
|
-
const a =
|
|
6379
|
+
const a = clamp012(this.amount);
|
|
6282
6380
|
linear(m, 1 - 2 * a, a);
|
|
6283
6381
|
}
|
|
6284
6382
|
css() {
|
|
6285
|
-
return `invert(${
|
|
6383
|
+
return `invert(${clamp012(this.amount)})`;
|
|
6286
6384
|
}
|
|
6287
6385
|
};
|
|
6288
6386
|
var Saturate = class extends Amount {
|
|
@@ -6305,7 +6403,7 @@ var Saturate = class extends Amount {
|
|
|
6305
6403
|
};
|
|
6306
6404
|
var Grayscale = class extends Amount {
|
|
6307
6405
|
toMatrix(m) {
|
|
6308
|
-
const k = 1 -
|
|
6406
|
+
const k = 1 - clamp012(this.amount);
|
|
6309
6407
|
m9[0] = 0.2126 + 0.7874 * k;
|
|
6310
6408
|
m9[1] = 0.7152 - 0.7152 * k;
|
|
6311
6409
|
m9[2] = 0.0722 - 0.0722 * k;
|
|
@@ -6318,12 +6416,12 @@ var Grayscale = class extends Amount {
|
|
|
6318
6416
|
rgb3(m, m9);
|
|
6319
6417
|
}
|
|
6320
6418
|
css() {
|
|
6321
|
-
return `grayscale(${
|
|
6419
|
+
return `grayscale(${clamp012(this.amount)})`;
|
|
6322
6420
|
}
|
|
6323
6421
|
};
|
|
6324
6422
|
var Sepia = class extends Amount {
|
|
6325
6423
|
toMatrix(m) {
|
|
6326
|
-
const k = 1 -
|
|
6424
|
+
const k = 1 - clamp012(this.amount);
|
|
6327
6425
|
m9[0] = 0.393 + 0.607 * k;
|
|
6328
6426
|
m9[1] = 0.769 - 0.769 * k;
|
|
6329
6427
|
m9[2] = 0.189 - 0.189 * k;
|
|
@@ -6336,7 +6434,7 @@ var Sepia = class extends Amount {
|
|
|
6336
6434
|
rgb3(m, m9);
|
|
6337
6435
|
}
|
|
6338
6436
|
css() {
|
|
6339
|
-
return `sepia(${
|
|
6437
|
+
return `sepia(${clamp012(this.amount)})`;
|
|
6340
6438
|
}
|
|
6341
6439
|
};
|
|
6342
6440
|
var HueRotate = class extends Amount {
|
|
@@ -6385,7 +6483,7 @@ var Tint = class extends Amount {
|
|
|
6385
6483
|
return i + 2;
|
|
6386
6484
|
}
|
|
6387
6485
|
toMatrix(m) {
|
|
6388
|
-
const a =
|
|
6486
|
+
const a = clamp012(this.amount);
|
|
6389
6487
|
linear(m, 1 - a, 0);
|
|
6390
6488
|
m[4] = (this.c >> 16 & 255) / 255 * a;
|
|
6391
6489
|
m[9] = (this.c >> 8 & 255) / 255 * a;
|
|
@@ -6396,7 +6494,7 @@ var Tint = class extends Amount {
|
|
|
6396
6494
|
return null;
|
|
6397
6495
|
}
|
|
6398
6496
|
paint2d(ctx, x, y, w2, h) {
|
|
6399
|
-
const a =
|
|
6497
|
+
const a = clamp012(this.amount);
|
|
6400
6498
|
if (a <= 0) return;
|
|
6401
6499
|
ctx.save();
|
|
6402
6500
|
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
@@ -6462,7 +6560,7 @@ var DropShadow = class extends Base {
|
|
|
6462
6560
|
return this.a;
|
|
6463
6561
|
}
|
|
6464
6562
|
set opacity(v) {
|
|
6465
|
-
this.a =
|
|
6563
|
+
this.a = clamp012(v);
|
|
6466
6564
|
}
|
|
6467
6565
|
get color() {
|
|
6468
6566
|
return this.rgb;
|