@seatlayer/core 0.15.0 → 0.16.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/dist/index.cjs +89 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -2
- package/dist/index.d.ts +15 -2
- package/dist/index.js +89 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -522,6 +522,9 @@ interface ISeatmapRenderer {
|
|
|
522
522
|
/** Price-band filter (F4): dim free seats whose category is NOT in `keys`
|
|
523
523
|
* (null clears). The widget resolves which categories fall in the band. */
|
|
524
524
|
setCategoryFilter?(keys: string[] | null): void;
|
|
525
|
+
/** Smoothly frame the currently available seats in these categories. `null`
|
|
526
|
+
* returns to the full chart. Used after an explicit buyer price-filter action. */
|
|
527
|
+
focusCategories?(keys: string[] | null): void;
|
|
525
528
|
/** Dim the seats of these section/zone ids (organizer manager: held-back inventory). */
|
|
526
529
|
setDimmedSections?(ids: string[] | null): void;
|
|
527
530
|
/**
|
|
@@ -587,7 +590,7 @@ interface ISeatmapRenderer {
|
|
|
587
590
|
sectionMembers?(id: string): string[];
|
|
588
591
|
/**
|
|
589
592
|
* Smoothly glide (pan+zoom) the camera to frame a section (by id) or a world-
|
|
590
|
-
* space bounds rect over
|
|
593
|
+
* space bounds rect over a calm easeInOutCubic glide. `prefers-reduced-motion` snaps.
|
|
591
594
|
* A pointer-down (grab/pan) cancels an in-flight glide. Slice 5 "glide in".
|
|
592
595
|
*/
|
|
593
596
|
focusRegion?(target: string | {
|
|
@@ -597,6 +600,8 @@ interface ISeatmapRenderer {
|
|
|
597
600
|
height: number;
|
|
598
601
|
}, opts?: {
|
|
599
602
|
animate?: boolean;
|
|
603
|
+
minScale?: number;
|
|
604
|
+
durationMs?: number;
|
|
600
605
|
}): void;
|
|
601
606
|
/** Current LOD rung derived from zoom (for the ZONES/SECTIONS/SEATS pill). */
|
|
602
607
|
getRung?(): LodRung;
|
|
@@ -970,6 +975,9 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
|
|
|
970
975
|
* widget resolves which categories fall inside the buyer's chosen band.
|
|
971
976
|
*/
|
|
972
977
|
setCategoryFilter(keys: string[] | null): void;
|
|
978
|
+
/** Frame the currently available inventory that survived a buyer price
|
|
979
|
+
* filter. Clearing the filter glides back to the full venue. */
|
|
980
|
+
focusCategories(keys: string[] | null): void;
|
|
973
981
|
/**
|
|
974
982
|
* Switch the projection between flat top-down and the isometric "3D" view
|
|
975
983
|
* (rotate + y-squash about the chart centre, plus per-elevation lift). Tweens
|
|
@@ -1214,7 +1222,7 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
|
|
|
1214
1222
|
private zoomToBounds;
|
|
1215
1223
|
/**
|
|
1216
1224
|
* Smoothly glide the camera to frame a section (by id) or a world-space bounds
|
|
1217
|
-
* rect — the Slice 5 "glide in". Pan+zoom tween over
|
|
1225
|
+
* rect — the Slice 5 "glide in". Pan+zoom tween over a calm easeInOutCubic; the
|
|
1218
1226
|
* melt/LOD rides the camera every frame. `prefers-reduced-motion` (or
|
|
1219
1227
|
* `opts.animate === false`) snaps via zoomToBounds. A grab (pointer-down) or a
|
|
1220
1228
|
* newer glide cancels an in-flight one.
|
|
@@ -1227,6 +1235,7 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
|
|
|
1227
1235
|
}, opts?: {
|
|
1228
1236
|
animate?: boolean;
|
|
1229
1237
|
minScale?: number;
|
|
1238
|
+
durationMs?: number;
|
|
1230
1239
|
}): void;
|
|
1231
1240
|
/** Cancel an in-flight camera glide (a grab or a newer glide interrupts it). */
|
|
1232
1241
|
private cancelGlide;
|
|
@@ -1614,6 +1623,10 @@ declare class PickerController {
|
|
|
1614
1623
|
/** Price-band filter (F4): dim free seats whose category is outside `keys`
|
|
1615
1624
|
* (null clears). The widget resolves which categories fall in the band. */
|
|
1616
1625
|
setCategoryFilter(keys: string[] | null): void;
|
|
1626
|
+
/** An explicit buyer price-filter action should not only dim the rest of the
|
|
1627
|
+
* chart: clear any older section drill-in and guide the camera to the seats
|
|
1628
|
+
* that remain relevant. Clearing the filter glides back to the full chart. */
|
|
1629
|
+
focusCategoryFilter(keys: string[] | null): void;
|
|
1617
1630
|
/** World-space rect currently visible + full chart bounds (F3 minimap frame). */
|
|
1618
1631
|
getViewport(): {
|
|
1619
1632
|
visible: {
|
package/dist/index.d.ts
CHANGED
|
@@ -522,6 +522,9 @@ interface ISeatmapRenderer {
|
|
|
522
522
|
/** Price-band filter (F4): dim free seats whose category is NOT in `keys`
|
|
523
523
|
* (null clears). The widget resolves which categories fall in the band. */
|
|
524
524
|
setCategoryFilter?(keys: string[] | null): void;
|
|
525
|
+
/** Smoothly frame the currently available seats in these categories. `null`
|
|
526
|
+
* returns to the full chart. Used after an explicit buyer price-filter action. */
|
|
527
|
+
focusCategories?(keys: string[] | null): void;
|
|
525
528
|
/** Dim the seats of these section/zone ids (organizer manager: held-back inventory). */
|
|
526
529
|
setDimmedSections?(ids: string[] | null): void;
|
|
527
530
|
/**
|
|
@@ -587,7 +590,7 @@ interface ISeatmapRenderer {
|
|
|
587
590
|
sectionMembers?(id: string): string[];
|
|
588
591
|
/**
|
|
589
592
|
* Smoothly glide (pan+zoom) the camera to frame a section (by id) or a world-
|
|
590
|
-
* space bounds rect over
|
|
593
|
+
* space bounds rect over a calm easeInOutCubic glide. `prefers-reduced-motion` snaps.
|
|
591
594
|
* A pointer-down (grab/pan) cancels an in-flight glide. Slice 5 "glide in".
|
|
592
595
|
*/
|
|
593
596
|
focusRegion?(target: string | {
|
|
@@ -597,6 +600,8 @@ interface ISeatmapRenderer {
|
|
|
597
600
|
height: number;
|
|
598
601
|
}, opts?: {
|
|
599
602
|
animate?: boolean;
|
|
603
|
+
minScale?: number;
|
|
604
|
+
durationMs?: number;
|
|
600
605
|
}): void;
|
|
601
606
|
/** Current LOD rung derived from zoom (for the ZONES/SECTIONS/SEATS pill). */
|
|
602
607
|
getRung?(): LodRung;
|
|
@@ -970,6 +975,9 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
|
|
|
970
975
|
* widget resolves which categories fall inside the buyer's chosen band.
|
|
971
976
|
*/
|
|
972
977
|
setCategoryFilter(keys: string[] | null): void;
|
|
978
|
+
/** Frame the currently available inventory that survived a buyer price
|
|
979
|
+
* filter. Clearing the filter glides back to the full venue. */
|
|
980
|
+
focusCategories(keys: string[] | null): void;
|
|
973
981
|
/**
|
|
974
982
|
* Switch the projection between flat top-down and the isometric "3D" view
|
|
975
983
|
* (rotate + y-squash about the chart centre, plus per-elevation lift). Tweens
|
|
@@ -1214,7 +1222,7 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
|
|
|
1214
1222
|
private zoomToBounds;
|
|
1215
1223
|
/**
|
|
1216
1224
|
* Smoothly glide the camera to frame a section (by id) or a world-space bounds
|
|
1217
|
-
* rect — the Slice 5 "glide in". Pan+zoom tween over
|
|
1225
|
+
* rect — the Slice 5 "glide in". Pan+zoom tween over a calm easeInOutCubic; the
|
|
1218
1226
|
* melt/LOD rides the camera every frame. `prefers-reduced-motion` (or
|
|
1219
1227
|
* `opts.animate === false`) snaps via zoomToBounds. A grab (pointer-down) or a
|
|
1220
1228
|
* newer glide cancels an in-flight one.
|
|
@@ -1227,6 +1235,7 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
|
|
|
1227
1235
|
}, opts?: {
|
|
1228
1236
|
animate?: boolean;
|
|
1229
1237
|
minScale?: number;
|
|
1238
|
+
durationMs?: number;
|
|
1230
1239
|
}): void;
|
|
1231
1240
|
/** Cancel an in-flight camera glide (a grab or a newer glide interrupts it). */
|
|
1232
1241
|
private cancelGlide;
|
|
@@ -1614,6 +1623,10 @@ declare class PickerController {
|
|
|
1614
1623
|
/** Price-band filter (F4): dim free seats whose category is outside `keys`
|
|
1615
1624
|
* (null clears). The widget resolves which categories fall in the band. */
|
|
1616
1625
|
setCategoryFilter(keys: string[] | null): void;
|
|
1626
|
+
/** An explicit buyer price-filter action should not only dim the rest of the
|
|
1627
|
+
* chart: clear any older section drill-in and guide the camera to the seats
|
|
1628
|
+
* that remain relevant. Clearing the filter glides back to the full chart. */
|
|
1629
|
+
focusCategoryFilter(keys: string[] | null): void;
|
|
1617
1630
|
/** World-space rect currently visible + full chart bounds (F3 minimap frame). */
|
|
1618
1631
|
getViewport(): {
|
|
1619
1632
|
visible: {
|
package/dist/index.js
CHANGED
|
@@ -644,6 +644,7 @@ var ISO_ANGLE_DEG = -11.5;
|
|
|
644
644
|
var ISO_SQUASH = 0.58;
|
|
645
645
|
var LIFT_PER_STEP = 58;
|
|
646
646
|
var ISO_TWEEN_MS = 320;
|
|
647
|
+
var CAMERA_GLIDE_MS = 650;
|
|
647
648
|
var BLOCK_FILL_ALPHA = 0.85;
|
|
648
649
|
var SOLD_DARKEN = 0.5;
|
|
649
650
|
var SECTION_LABEL_PX = 20;
|
|
@@ -1598,6 +1599,40 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
1598
1599
|
this.seatLayer.batchDraw();
|
|
1599
1600
|
}
|
|
1600
1601
|
}
|
|
1602
|
+
/** Frame the currently available inventory that survived a buyer price
|
|
1603
|
+
* filter. Clearing the filter glides back to the full venue. */
|
|
1604
|
+
focusCategories(keys) {
|
|
1605
|
+
if (!keys?.length) {
|
|
1606
|
+
this.focusRegion(this.bounds, { durationMs: CAMERA_GLIDE_MS });
|
|
1607
|
+
return;
|
|
1608
|
+
}
|
|
1609
|
+
const wanted = new Set(keys);
|
|
1610
|
+
const matching = this.seats.filter((seat) => {
|
|
1611
|
+
if (!wanted.has(seat.categoryKey) || this.seatInClosedSection(seat.id)) return false;
|
|
1612
|
+
const status = this.statusById.get(seat.id) ?? "free";
|
|
1613
|
+
return status === "free" || this.ownedHold.has(seat.id);
|
|
1614
|
+
});
|
|
1615
|
+
if (!matching.length) return;
|
|
1616
|
+
let minX = Infinity;
|
|
1617
|
+
let maxX = -Infinity;
|
|
1618
|
+
let minY = Infinity;
|
|
1619
|
+
let maxY = -Infinity;
|
|
1620
|
+
for (const seat of matching) {
|
|
1621
|
+
minX = Math.min(minX, seat.x);
|
|
1622
|
+
maxX = Math.max(maxX, seat.x);
|
|
1623
|
+
minY = Math.min(minY, seat.y);
|
|
1624
|
+
maxY = Math.max(maxY, seat.y);
|
|
1625
|
+
}
|
|
1626
|
+
const pad = Math.max(24, this.seatR * 3);
|
|
1627
|
+
minX -= pad;
|
|
1628
|
+
maxX += pad;
|
|
1629
|
+
minY -= pad;
|
|
1630
|
+
maxY += pad;
|
|
1631
|
+
this.focusRegion(
|
|
1632
|
+
{ x: minX, y: minY, width: Math.max(40, maxX - minX), height: Math.max(40, maxY - minY) },
|
|
1633
|
+
{ durationMs: CAMERA_GLIDE_MS }
|
|
1634
|
+
);
|
|
1635
|
+
}
|
|
1601
1636
|
// ---- isometric ("3D") view mode -------------------------------------------
|
|
1602
1637
|
/**
|
|
1603
1638
|
* Switch the projection between flat top-down and the isometric "3D" view
|
|
@@ -1927,8 +1962,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
1927
1962
|
break;
|
|
1928
1963
|
}
|
|
1929
1964
|
if (boothLabel) {
|
|
1930
|
-
|
|
1931
|
-
boothLabel.text(status === "booked" ? "SOLD" : status === "held" ? owned ? "HELD BY YOU" : "HELD" : seat.label);
|
|
1965
|
+
boothLabel.text(status === "booked" ? "SOLD" : status === "held" ? "HELD" : seat.label);
|
|
1932
1966
|
boothLabel.fontSize(status === "free" ? 10 : Math.min(10, Math.max(6, this.boothDims.get(seat.rowId)?.width ?? 40) / 6));
|
|
1933
1967
|
boothLabel.fontStyle(status === "free" ? "600" : "800");
|
|
1934
1968
|
boothLabel.fill(status === "free" ? this.theme.seatLabelColor ?? DEF_SEAT_LABEL : "#ffffff");
|
|
@@ -3125,7 +3159,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
3125
3159
|
}
|
|
3126
3160
|
/**
|
|
3127
3161
|
* Smoothly glide the camera to frame a section (by id) or a world-space bounds
|
|
3128
|
-
* rect — the Slice 5 "glide in". Pan+zoom tween over
|
|
3162
|
+
* rect — the Slice 5 "glide in". Pan+zoom tween over a calm easeInOutCubic; the
|
|
3129
3163
|
* melt/LOD rides the camera every frame. `prefers-reduced-motion` (or
|
|
3130
3164
|
* `opts.animate === false`) snaps via zoomToBounds. A grab (pointer-down) or a
|
|
3131
3165
|
* newer glide cancels an in-flight one.
|
|
@@ -3157,13 +3191,13 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
3157
3191
|
return;
|
|
3158
3192
|
}
|
|
3159
3193
|
const start = performance.now();
|
|
3160
|
-
const
|
|
3194
|
+
const duration = Math.max(180, Math.min(1200, opts?.durationMs ?? CAMERA_GLIDE_MS));
|
|
3161
3195
|
const step = (now) => {
|
|
3162
3196
|
if (this.destroyed) {
|
|
3163
3197
|
this.glideRaf = 0;
|
|
3164
3198
|
return;
|
|
3165
3199
|
}
|
|
3166
|
-
const raw = Math.min(1, (now - start) /
|
|
3200
|
+
const raw = Math.min(1, (now - start) / duration);
|
|
3167
3201
|
const e = raw < 0.5 ? 4 * raw * raw * raw : 1 - Math.pow(-2 * raw + 2, 3) / 2;
|
|
3168
3202
|
const sc = fromScale + (toScale - fromScale) * e;
|
|
3169
3203
|
this.stage.scale({ x: sc, y: sc });
|
|
@@ -3288,15 +3322,49 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
3288
3322
|
if (seat.kind === "booth") continue;
|
|
3289
3323
|
if (seat.x < x0 || seat.x > x1 || seat.y < y0 || seat.y > y1) continue;
|
|
3290
3324
|
const status = this.statusById.get(seat.id) ?? "free";
|
|
3291
|
-
const
|
|
3325
|
+
const unavailable = status === "booked" || status === "held" && !this.ownedHold.has(seat.id);
|
|
3326
|
+
if (unavailable) {
|
|
3327
|
+
const cue = new Group({ x: seat.x, y: seat.y, listening: false });
|
|
3328
|
+
if (status === "held") {
|
|
3329
|
+
cue.add(new Rect({
|
|
3330
|
+
x: -4.2,
|
|
3331
|
+
y: -0.7,
|
|
3332
|
+
width: 8.4,
|
|
3333
|
+
height: 6.5,
|
|
3334
|
+
cornerRadius: 1.3,
|
|
3335
|
+
stroke: "#ffffff",
|
|
3336
|
+
strokeWidth: 1.25,
|
|
3337
|
+
listening: false
|
|
3338
|
+
}));
|
|
3339
|
+
cue.add(new Line({
|
|
3340
|
+
points: [-2.4, -0.8, -2.4, -2.7, -1.2, -4, 0, -4.35, 1.2, -4, 2.4, -2.7, 2.4, -0.8],
|
|
3341
|
+
stroke: "#ffffff",
|
|
3342
|
+
strokeWidth: 1.2,
|
|
3343
|
+
lineCap: "round",
|
|
3344
|
+
lineJoin: "round",
|
|
3345
|
+
listening: false
|
|
3346
|
+
}));
|
|
3347
|
+
} else {
|
|
3348
|
+
cue.add(new Line({
|
|
3349
|
+
points: [-4.2, 4.2, 4.2, -4.2],
|
|
3350
|
+
stroke: "#ffffff",
|
|
3351
|
+
strokeWidth: 1.8,
|
|
3352
|
+
lineCap: "round",
|
|
3353
|
+
listening: false
|
|
3354
|
+
}));
|
|
3355
|
+
}
|
|
3356
|
+
this.labelGroup.add(cue);
|
|
3357
|
+
if (++count >= MAX_LABELS) break;
|
|
3358
|
+
continue;
|
|
3359
|
+
}
|
|
3292
3360
|
const t2 = new Text({
|
|
3293
3361
|
x: seat.x,
|
|
3294
3362
|
y: seat.y,
|
|
3295
|
-
text:
|
|
3296
|
-
fontSize:
|
|
3297
|
-
fontStyle:
|
|
3363
|
+
text: seat.label,
|
|
3364
|
+
fontSize: 7,
|
|
3365
|
+
fontStyle: "600",
|
|
3298
3366
|
fontFamily: this.labelFont(),
|
|
3299
|
-
fill:
|
|
3367
|
+
fill: this.theme.seatLabelColor ?? DEF_SEAT_LABEL,
|
|
3300
3368
|
listening: false,
|
|
3301
3369
|
perfectDrawEnabled: false
|
|
3302
3370
|
});
|
|
@@ -3953,6 +4021,17 @@ var PickerController = class {
|
|
|
3953
4021
|
setCategoryFilter(keys) {
|
|
3954
4022
|
this.renderer?.setCategoryFilter?.(keys);
|
|
3955
4023
|
}
|
|
4024
|
+
/** An explicit buyer price-filter action should not only dim the rest of the
|
|
4025
|
+
* chart: clear any older section drill-in and guide the camera to the seats
|
|
4026
|
+
* that remain relevant. Clearing the filter glides back to the full chart. */
|
|
4027
|
+
focusCategoryFilter(keys) {
|
|
4028
|
+
const renderer = this.renderer;
|
|
4029
|
+
if (!renderer) return;
|
|
4030
|
+
renderer.clearSectionFocus?.();
|
|
4031
|
+
this.opts.onSectionFocus?.(null);
|
|
4032
|
+
if (renderer.focusCategories) renderer.focusCategories(keys);
|
|
4033
|
+
else renderer.zoomToFit();
|
|
4034
|
+
}
|
|
3956
4035
|
/** World-space rect currently visible + full chart bounds (F3 minimap frame). */
|
|
3957
4036
|
getViewport() {
|
|
3958
4037
|
const r = this.renderer;
|