@seatlayer/core 0.7.3 → 0.9.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 +220 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -1
- package/dist/index.d.ts +37 -1
- package/dist/index.js +218 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1062,6 +1062,12 @@ interface PickerTransport {
|
|
|
1062
1062
|
release(key: string, labels: string[], holdId: string): Promise<unknown>;
|
|
1063
1063
|
/** Optional — the SDK omits booking (it hands the holdId to the host page). */
|
|
1064
1064
|
book?(key: string, labels: string[], holdId: string, bookingRef: string): Promise<unknown>;
|
|
1065
|
+
/** Optional (P4) — push an active hold's expiry out ("need more time?"). */
|
|
1066
|
+
extend?(key: string, holdId: string, ttlMs?: number): Promise<{
|
|
1067
|
+
holdId: string;
|
|
1068
|
+
expiresAt: number;
|
|
1069
|
+
extends?: number;
|
|
1070
|
+
}>;
|
|
1065
1071
|
socketUrl(key: string): string;
|
|
1066
1072
|
}
|
|
1067
1073
|
interface PickerCallbacks extends RendererCallbacks {
|
|
@@ -1168,6 +1174,15 @@ declare class PickerController {
|
|
|
1168
1174
|
* there's nothing to hold.
|
|
1169
1175
|
*/
|
|
1170
1176
|
hold(labelsArg?: string[], ttlMs?: number): Promise<HoldInfo | null>;
|
|
1177
|
+
/**
|
|
1178
|
+
* P4 "need more time?": extend the OPEN hold's server-side expiry and re-arm
|
|
1179
|
+
* the client expiry timer to match (via setHold), so the controller doesn't
|
|
1180
|
+
* fire a false expiry and start polling. Returns the new hold, or null if
|
|
1181
|
+
* there's no open hold or the transport can't extend / the server refused
|
|
1182
|
+
* (hold gone, expired, or at its renewal cap). Never throws for the refusal
|
|
1183
|
+
* case — the caller decides the copy.
|
|
1184
|
+
*/
|
|
1185
|
+
extendHold(ttlMs?: number): Promise<HoldInfo | null>;
|
|
1171
1186
|
/** Public GA inventory derived from the live synthetic-unit status stream. */
|
|
1172
1187
|
/**
|
|
1173
1188
|
* Live seats-left per category key (status 'free' right now). Recompute on
|
|
@@ -1294,6 +1309,27 @@ declare class PickerController {
|
|
|
1294
1309
|
private scheduleReconnect;
|
|
1295
1310
|
}
|
|
1296
1311
|
|
|
1312
|
+
/**
|
|
1313
|
+
* Synthetic view-from-seat panorama, generated from chart geometry alone.
|
|
1314
|
+
*
|
|
1315
|
+
* Draws a 2048×1024 equirectangular texture of a dark hall with the stage
|
|
1316
|
+
* placed at the correct bearing and angular size for THIS seat — closer seats
|
|
1317
|
+
* see a bigger stage, off-center seats see it at an angle. Used whenever the
|
|
1318
|
+
* organizer hasn't uploaded a real photo/360 for the seat; both go through the
|
|
1319
|
+
* same viewer.
|
|
1320
|
+
*
|
|
1321
|
+
* Equirectangular mapping: x = (yaw + 180°)/360° · W, y = (90° − pitch)/180° · H,
|
|
1322
|
+
* where yaw 0 = the direction the camera faces by default.
|
|
1323
|
+
*/
|
|
1324
|
+
|
|
1325
|
+
interface PanoramaResult {
|
|
1326
|
+
url: string;
|
|
1327
|
+
/** Meters from the stage, for the caption. */
|
|
1328
|
+
distanceM: number;
|
|
1329
|
+
}
|
|
1330
|
+
declare function generateSeatPanorama(seat: ExpandedSeat, focalPoint: Point, neighborSeats: ExpandedSeat[]): PanoramaResult;
|
|
1331
|
+
declare function generateSeatThumb(seat: ExpandedSeat, focalPoint: Point, _neighborSeats?: ExpandedSeat[]): PanoramaResult;
|
|
1332
|
+
|
|
1297
1333
|
/**
|
|
1298
1334
|
* i18n core — deliberately tiny and framework-free so the embed SDK can share
|
|
1299
1335
|
* it without dragging in a runtime library (the 60KB-gzipped SDK budget is a
|
|
@@ -1366,4 +1402,4 @@ declare function formatMoney(amount: number, currency?: string, fractionDigits?:
|
|
|
1366
1402
|
/** Bare symbol for input adornments ("€", "$", "₹"). */
|
|
1367
1403
|
declare function currencySymbol(currency?: string): string;
|
|
1368
1404
|
|
|
1369
|
-
export { ACCESSIBILITY_TYPES, type AccessibilityMeta, type AccessibilityType, type AvailabilityRule, type BoothObject, CHART_STORAGE_KEY, type Category, type CategoryTier, type ChartDoc, type ChartObject, type ChartTheme, DEFAULT_CURRENCY, type Dict, type ExpandedSeat, type Floor, type GAAreaObject, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, type ISeatmapRenderer, type Locale, type LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PickerCallbacks, PickerController, type PickerOptions, type PickerSeat, type PickerTransport, type Point, type RendererCallbacks, type RendererOptions, type RowObject, type RowSeatSlot, SUPPORTED_LOCALES, type SeatHoverDetails, type SeatOverride, type SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, type SectionObject, type SectionSummary, type SelectionLayer, type ShapeObject, type TableObject, type TextObject, UNGROUPED_ID, type ZoneDef, accessibilityMeta, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, floorObjects, floorsOf, formatDate, formatMoney, gaAreasOf, gaUnitLabel, gaUnitLabels, getLocale, hiddenObjectIds, isGaUnitLabel, isSectionHidden, layerOf, loadLocale, objectCenter, pointInPolygon, resolveLocale, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount };
|
|
1405
|
+
export { ACCESSIBILITY_TYPES, type AccessibilityMeta, type AccessibilityType, type AvailabilityRule, type BoothObject, CHART_STORAGE_KEY, type Category, type CategoryTier, type ChartDoc, type ChartObject, type ChartTheme, DEFAULT_CURRENCY, type Dict, type ExpandedSeat, type Floor, type GAAreaObject, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, type ISeatmapRenderer, type Locale, type LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PanoramaResult, type PickerCallbacks, PickerController, type PickerOptions, type PickerSeat, type PickerTransport, type Point, type RendererCallbacks, type RendererOptions, type RowObject, type RowSeatSlot, SUPPORTED_LOCALES, type SeatHoverDetails, type SeatOverride, type SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, type SectionObject, type SectionSummary, type SelectionLayer, type ShapeObject, type TableObject, type TextObject, UNGROUPED_ID, type ZoneDef, accessibilityMeta, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, floorObjects, floorsOf, formatDate, formatMoney, gaAreasOf, gaUnitLabel, gaUnitLabels, generateSeatPanorama, generateSeatThumb, getLocale, hiddenObjectIds, isGaUnitLabel, isSectionHidden, layerOf, loadLocale, objectCenter, pointInPolygon, resolveLocale, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount };
|
package/dist/index.d.ts
CHANGED
|
@@ -1062,6 +1062,12 @@ interface PickerTransport {
|
|
|
1062
1062
|
release(key: string, labels: string[], holdId: string): Promise<unknown>;
|
|
1063
1063
|
/** Optional — the SDK omits booking (it hands the holdId to the host page). */
|
|
1064
1064
|
book?(key: string, labels: string[], holdId: string, bookingRef: string): Promise<unknown>;
|
|
1065
|
+
/** Optional (P4) — push an active hold's expiry out ("need more time?"). */
|
|
1066
|
+
extend?(key: string, holdId: string, ttlMs?: number): Promise<{
|
|
1067
|
+
holdId: string;
|
|
1068
|
+
expiresAt: number;
|
|
1069
|
+
extends?: number;
|
|
1070
|
+
}>;
|
|
1065
1071
|
socketUrl(key: string): string;
|
|
1066
1072
|
}
|
|
1067
1073
|
interface PickerCallbacks extends RendererCallbacks {
|
|
@@ -1168,6 +1174,15 @@ declare class PickerController {
|
|
|
1168
1174
|
* there's nothing to hold.
|
|
1169
1175
|
*/
|
|
1170
1176
|
hold(labelsArg?: string[], ttlMs?: number): Promise<HoldInfo | null>;
|
|
1177
|
+
/**
|
|
1178
|
+
* P4 "need more time?": extend the OPEN hold's server-side expiry and re-arm
|
|
1179
|
+
* the client expiry timer to match (via setHold), so the controller doesn't
|
|
1180
|
+
* fire a false expiry and start polling. Returns the new hold, or null if
|
|
1181
|
+
* there's no open hold or the transport can't extend / the server refused
|
|
1182
|
+
* (hold gone, expired, or at its renewal cap). Never throws for the refusal
|
|
1183
|
+
* case — the caller decides the copy.
|
|
1184
|
+
*/
|
|
1185
|
+
extendHold(ttlMs?: number): Promise<HoldInfo | null>;
|
|
1171
1186
|
/** Public GA inventory derived from the live synthetic-unit status stream. */
|
|
1172
1187
|
/**
|
|
1173
1188
|
* Live seats-left per category key (status 'free' right now). Recompute on
|
|
@@ -1294,6 +1309,27 @@ declare class PickerController {
|
|
|
1294
1309
|
private scheduleReconnect;
|
|
1295
1310
|
}
|
|
1296
1311
|
|
|
1312
|
+
/**
|
|
1313
|
+
* Synthetic view-from-seat panorama, generated from chart geometry alone.
|
|
1314
|
+
*
|
|
1315
|
+
* Draws a 2048×1024 equirectangular texture of a dark hall with the stage
|
|
1316
|
+
* placed at the correct bearing and angular size for THIS seat — closer seats
|
|
1317
|
+
* see a bigger stage, off-center seats see it at an angle. Used whenever the
|
|
1318
|
+
* organizer hasn't uploaded a real photo/360 for the seat; both go through the
|
|
1319
|
+
* same viewer.
|
|
1320
|
+
*
|
|
1321
|
+
* Equirectangular mapping: x = (yaw + 180°)/360° · W, y = (90° − pitch)/180° · H,
|
|
1322
|
+
* where yaw 0 = the direction the camera faces by default.
|
|
1323
|
+
*/
|
|
1324
|
+
|
|
1325
|
+
interface PanoramaResult {
|
|
1326
|
+
url: string;
|
|
1327
|
+
/** Meters from the stage, for the caption. */
|
|
1328
|
+
distanceM: number;
|
|
1329
|
+
}
|
|
1330
|
+
declare function generateSeatPanorama(seat: ExpandedSeat, focalPoint: Point, neighborSeats: ExpandedSeat[]): PanoramaResult;
|
|
1331
|
+
declare function generateSeatThumb(seat: ExpandedSeat, focalPoint: Point, _neighborSeats?: ExpandedSeat[]): PanoramaResult;
|
|
1332
|
+
|
|
1297
1333
|
/**
|
|
1298
1334
|
* i18n core — deliberately tiny and framework-free so the embed SDK can share
|
|
1299
1335
|
* it without dragging in a runtime library (the 60KB-gzipped SDK budget is a
|
|
@@ -1366,4 +1402,4 @@ declare function formatMoney(amount: number, currency?: string, fractionDigits?:
|
|
|
1366
1402
|
/** Bare symbol for input adornments ("€", "$", "₹"). */
|
|
1367
1403
|
declare function currencySymbol(currency?: string): string;
|
|
1368
1404
|
|
|
1369
|
-
export { ACCESSIBILITY_TYPES, type AccessibilityMeta, type AccessibilityType, type AvailabilityRule, type BoothObject, CHART_STORAGE_KEY, type Category, type CategoryTier, type ChartDoc, type ChartObject, type ChartTheme, DEFAULT_CURRENCY, type Dict, type ExpandedSeat, type Floor, type GAAreaObject, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, type ISeatmapRenderer, type Locale, type LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PickerCallbacks, PickerController, type PickerOptions, type PickerSeat, type PickerTransport, type Point, type RendererCallbacks, type RendererOptions, type RowObject, type RowSeatSlot, SUPPORTED_LOCALES, type SeatHoverDetails, type SeatOverride, type SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, type SectionObject, type SectionSummary, type SelectionLayer, type ShapeObject, type TableObject, type TextObject, UNGROUPED_ID, type ZoneDef, accessibilityMeta, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, floorObjects, floorsOf, formatDate, formatMoney, gaAreasOf, gaUnitLabel, gaUnitLabels, getLocale, hiddenObjectIds, isGaUnitLabel, isSectionHidden, layerOf, loadLocale, objectCenter, pointInPolygon, resolveLocale, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount };
|
|
1405
|
+
export { ACCESSIBILITY_TYPES, type AccessibilityMeta, type AccessibilityType, type AvailabilityRule, type BoothObject, CHART_STORAGE_KEY, type Category, type CategoryTier, type ChartDoc, type ChartObject, type ChartTheme, DEFAULT_CURRENCY, type Dict, type ExpandedSeat, type Floor, type GAAreaObject, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, type ISeatmapRenderer, type Locale, type LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PanoramaResult, type PickerCallbacks, PickerController, type PickerOptions, type PickerSeat, type PickerTransport, type Point, type RendererCallbacks, type RendererOptions, type RowObject, type RowSeatSlot, SUPPORTED_LOCALES, type SeatHoverDetails, type SeatOverride, type SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, type SectionObject, type SectionSummary, type SelectionLayer, type ShapeObject, type TableObject, type TextObject, UNGROUPED_ID, type ZoneDef, accessibilityMeta, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, floorObjects, floorsOf, formatDate, formatMoney, gaAreasOf, gaUnitLabel, gaUnitLabels, generateSeatPanorama, generateSeatThumb, getLocale, hiddenObjectIds, isGaUnitLabel, isSectionHidden, layerOf, loadLocale, objectCenter, pointInPolygon, resolveLocale, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount };
|
package/dist/index.js
CHANGED
|
@@ -2816,6 +2816,26 @@ var PickerController = class {
|
|
|
2816
2816
|
throw err;
|
|
2817
2817
|
}
|
|
2818
2818
|
}
|
|
2819
|
+
/**
|
|
2820
|
+
* P4 "need more time?": extend the OPEN hold's server-side expiry and re-arm
|
|
2821
|
+
* the client expiry timer to match (via setHold), so the controller doesn't
|
|
2822
|
+
* fire a false expiry and start polling. Returns the new hold, or null if
|
|
2823
|
+
* there's no open hold or the transport can't extend / the server refused
|
|
2824
|
+
* (hold gone, expired, or at its renewal cap). Never throws for the refusal
|
|
2825
|
+
* case — the caller decides the copy.
|
|
2826
|
+
*/
|
|
2827
|
+
async extendHold(ttlMs) {
|
|
2828
|
+
const current = this.hold_;
|
|
2829
|
+
if (!current || !this.api.extend) return null;
|
|
2830
|
+
try {
|
|
2831
|
+
const result = await this.api.extend(this.key, current.holdId, ttlMs);
|
|
2832
|
+
if (this.hold_?.holdId !== current.holdId) return this.hold_;
|
|
2833
|
+
this.setHold({ holdId: current.holdId, labels: current.labels, expiresAt: result.expiresAt, items: current.items });
|
|
2834
|
+
return this.hold_;
|
|
2835
|
+
} catch {
|
|
2836
|
+
return null;
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2819
2839
|
/** Public GA inventory derived from the live synthetic-unit status stream. */
|
|
2820
2840
|
/**
|
|
2821
2841
|
* Live seats-left per category key (status 'free' right now). Recompute on
|
|
@@ -3401,6 +3421,202 @@ var PickerController = class {
|
|
|
3401
3421
|
}
|
|
3402
3422
|
};
|
|
3403
3423
|
|
|
3424
|
+
// src/view/generatePanorama.ts
|
|
3425
|
+
var W = 2048;
|
|
3426
|
+
var H = 1024;
|
|
3427
|
+
var UNIT = 0.55 / 24;
|
|
3428
|
+
var yawToX = (yawDeg) => (yawDeg + 180) / 360 * W;
|
|
3429
|
+
var pitchToY = (pitchDeg) => (90 - pitchDeg) / 180 * H;
|
|
3430
|
+
function generateSeatPanorama(seat, focalPoint, neighborSeats) {
|
|
3431
|
+
const canvas = document.createElement("canvas");
|
|
3432
|
+
canvas.width = W;
|
|
3433
|
+
canvas.height = H;
|
|
3434
|
+
const ctx = canvas.getContext("2d");
|
|
3435
|
+
const dx = focalPoint.x - seat.x;
|
|
3436
|
+
const dy = focalPoint.y - seat.y;
|
|
3437
|
+
const distU = Math.hypot(dx, dy);
|
|
3438
|
+
const distM = Math.max(2, distU * UNIT);
|
|
3439
|
+
const sky = ctx.createLinearGradient(0, 0, 0, H);
|
|
3440
|
+
sky.addColorStop(0, "#05070c");
|
|
3441
|
+
sky.addColorStop(0.42, "#11172a");
|
|
3442
|
+
sky.addColorStop(0.5, "#1a2238");
|
|
3443
|
+
sky.addColorStop(0.56, "#10141f");
|
|
3444
|
+
sky.addColorStop(1, "#07090f");
|
|
3445
|
+
ctx.fillStyle = sky;
|
|
3446
|
+
ctx.fillRect(0, 0, W, H);
|
|
3447
|
+
const stageHalfYaw = Math.min(80, Math.atan2(4, distM) * 180 / Math.PI);
|
|
3448
|
+
const stageTopPitch = Math.min(45, Math.atan2(5, distM) * 180 / Math.PI);
|
|
3449
|
+
const stageBasePitch = Math.max(-30, -Math.atan2(1.1, distM) * 180 / Math.PI);
|
|
3450
|
+
const sx0 = yawToX(-stageHalfYaw);
|
|
3451
|
+
const sx1 = yawToX(stageHalfYaw);
|
|
3452
|
+
const sy0 = pitchToY(stageTopPitch);
|
|
3453
|
+
const sy1 = pitchToY(stageBasePitch);
|
|
3454
|
+
const glow = ctx.createRadialGradient(W / 2, (sy0 + sy1) / 2, 10, W / 2, (sy0 + sy1) / 2, (sx1 - sx0) * 1.1);
|
|
3455
|
+
glow.addColorStop(0, "rgba(129, 140, 248, 0.5)");
|
|
3456
|
+
glow.addColorStop(0.5, "rgba(99, 102, 241, 0.16)");
|
|
3457
|
+
glow.addColorStop(1, "rgba(99, 102, 241, 0)");
|
|
3458
|
+
ctx.fillStyle = glow;
|
|
3459
|
+
ctx.fillRect(sx0 - (sx1 - sx0) * 0.6, sy0 - (sy1 - sy0) * 1.2, (sx1 - sx0) * 2.2, (sy1 - sy0) * 3.4);
|
|
3460
|
+
ctx.fillStyle = "#242c44";
|
|
3461
|
+
ctx.fillRect(sx0, sy0, sx1 - sx0, sy1 - sy0);
|
|
3462
|
+
const backdrop = ctx.createLinearGradient(0, sy0, 0, sy1);
|
|
3463
|
+
backdrop.addColorStop(0, "#7c5cff");
|
|
3464
|
+
backdrop.addColorStop(0.5, "#e1447a");
|
|
3465
|
+
backdrop.addColorStop(1, "#f59e0b");
|
|
3466
|
+
ctx.globalAlpha = 0.75;
|
|
3467
|
+
ctx.fillStyle = backdrop;
|
|
3468
|
+
const inset = (sx1 - sx0) * 0.06;
|
|
3469
|
+
ctx.fillRect(sx0 + inset, sy0 + (sy1 - sy0) * 0.12, sx1 - sx0 - inset * 2, (sy1 - sy0) * 0.62);
|
|
3470
|
+
ctx.globalAlpha = 1;
|
|
3471
|
+
ctx.fillStyle = "#0d1119";
|
|
3472
|
+
ctx.fillRect(sx0, sy1 - (sy1 - sy0) * 0.1, sx1 - sx0, (sy1 - sy0) * 0.1);
|
|
3473
|
+
const performerH = (sy1 - sy0) * 0.45;
|
|
3474
|
+
ctx.fillStyle = "rgba(8, 10, 16, 0.85)";
|
|
3475
|
+
for (const fx of [0.35, 0.5, 0.65]) {
|
|
3476
|
+
const px = sx0 + (sx1 - sx0) * fx;
|
|
3477
|
+
const py = sy1 - (sy1 - sy0) * 0.12;
|
|
3478
|
+
ctx.beginPath();
|
|
3479
|
+
ctx.arc(px, py - performerH * 0.82, performerH * 0.16, 0, Math.PI * 2);
|
|
3480
|
+
ctx.fill();
|
|
3481
|
+
ctx.fillRect(px - performerH * 0.14, py - performerH * 0.68, performerH * 0.28, performerH * 0.68);
|
|
3482
|
+
}
|
|
3483
|
+
ctx.globalAlpha = 0.14;
|
|
3484
|
+
ctx.fillStyle = "#c7d2fe";
|
|
3485
|
+
for (const fx of [0.3, 0.5, 0.7]) {
|
|
3486
|
+
const bx = sx0 + (sx1 - sx0) * fx;
|
|
3487
|
+
ctx.beginPath();
|
|
3488
|
+
ctx.moveTo(bx - 8, pitchToY(Math.min(60, stageTopPitch + 25)));
|
|
3489
|
+
ctx.lineTo(bx - (sx1 - sx0) * 0.09, sy1);
|
|
3490
|
+
ctx.lineTo(bx + (sx1 - sx0) * 0.09, sy1);
|
|
3491
|
+
ctx.lineTo(bx + 8, pitchToY(Math.min(60, stageTopPitch + 25)));
|
|
3492
|
+
ctx.closePath();
|
|
3493
|
+
ctx.fill();
|
|
3494
|
+
}
|
|
3495
|
+
ctx.globalAlpha = 1;
|
|
3496
|
+
ctx.fillStyle = "rgba(199, 210, 254, 0.8)";
|
|
3497
|
+
for (let i = 0; i < 26; i++) {
|
|
3498
|
+
const x = i / 26 * W;
|
|
3499
|
+
const y = pitchToY(55 + i % 3 * 6);
|
|
3500
|
+
ctx.beginPath();
|
|
3501
|
+
ctx.arc(x, y, 3.2, 0, Math.PI * 2);
|
|
3502
|
+
ctx.fill();
|
|
3503
|
+
}
|
|
3504
|
+
const stageBearing = Math.atan2(dx, -dy);
|
|
3505
|
+
ctx.fillStyle = "rgba(16, 20, 30, 0.95)";
|
|
3506
|
+
for (const other of neighborSeats) {
|
|
3507
|
+
if (other.id === seat.id) continue;
|
|
3508
|
+
const ox = other.x - seat.x;
|
|
3509
|
+
const oy = other.y - seat.y;
|
|
3510
|
+
const d = Math.hypot(ox, oy) * UNIT;
|
|
3511
|
+
if (d < 0.3 || d > 14) continue;
|
|
3512
|
+
const bearing = Math.atan2(ox, -oy) - stageBearing;
|
|
3513
|
+
const yaw = (bearing * 180 / Math.PI + 540) % 360 - 180;
|
|
3514
|
+
const headPitch = -Math.atan2(0.35, d) * 180 / Math.PI;
|
|
3515
|
+
const headR = Math.min(46, 260 / (d / UNIT / 24 + 1.2) / 4);
|
|
3516
|
+
const hx = yawToX(yaw);
|
|
3517
|
+
const hy = pitchToY(headPitch);
|
|
3518
|
+
ctx.beginPath();
|
|
3519
|
+
ctx.arc(hx, hy, headR, 0, Math.PI * 2);
|
|
3520
|
+
ctx.fill();
|
|
3521
|
+
ctx.beginPath();
|
|
3522
|
+
ctx.ellipse(hx, hy + headR * 1.4, headR * 1.7, headR * 0.9, 0, Math.PI, 0, true);
|
|
3523
|
+
ctx.fill();
|
|
3524
|
+
}
|
|
3525
|
+
const poleFade = ctx.createLinearGradient(0, 0, 0, H);
|
|
3526
|
+
poleFade.addColorStop(0, "rgba(0,0,0,0.85)");
|
|
3527
|
+
poleFade.addColorStop(0.12, "rgba(0,0,0,0)");
|
|
3528
|
+
poleFade.addColorStop(0.88, "rgba(0,0,0,0)");
|
|
3529
|
+
poleFade.addColorStop(1, "rgba(0,0,0,0.85)");
|
|
3530
|
+
ctx.fillStyle = poleFade;
|
|
3531
|
+
ctx.fillRect(0, 0, W, H);
|
|
3532
|
+
return { url: canvas.toDataURL("image/jpeg", 0.82), distanceM: Math.round(distM) };
|
|
3533
|
+
}
|
|
3534
|
+
var TW = 480;
|
|
3535
|
+
var TH = 270;
|
|
3536
|
+
var HALF_HFOV = 50;
|
|
3537
|
+
var HALF_VFOV = 30;
|
|
3538
|
+
var yawToTX = (yawDeg) => (yawDeg + HALF_HFOV) / (2 * HALF_HFOV) * TW;
|
|
3539
|
+
var pitchToTY = (pitchDeg) => (HALF_VFOV - pitchDeg) / (2 * HALF_VFOV) * TH;
|
|
3540
|
+
function generateSeatThumb(seat, focalPoint, _neighborSeats) {
|
|
3541
|
+
const canvas = document.createElement("canvas");
|
|
3542
|
+
canvas.width = TW;
|
|
3543
|
+
canvas.height = TH;
|
|
3544
|
+
const ctx = canvas.getContext("2d");
|
|
3545
|
+
const dx = focalPoint.x - seat.x;
|
|
3546
|
+
const dy = focalPoint.y - seat.y;
|
|
3547
|
+
const distM = Math.max(2, Math.hypot(dx, dy) * UNIT);
|
|
3548
|
+
const sky = ctx.createLinearGradient(0, 0, 0, TH);
|
|
3549
|
+
sky.addColorStop(0, "#05070c");
|
|
3550
|
+
sky.addColorStop(0.44, "#141b30");
|
|
3551
|
+
sky.addColorStop(0.5, "#1b2440");
|
|
3552
|
+
sky.addColorStop(0.58, "#10141f");
|
|
3553
|
+
sky.addColorStop(1, "#070910");
|
|
3554
|
+
ctx.fillStyle = sky;
|
|
3555
|
+
ctx.fillRect(0, 0, TW, TH);
|
|
3556
|
+
const stageHalfYaw = Math.min(HALF_HFOV - 2, Math.atan2(4, distM) * 180 / Math.PI);
|
|
3557
|
+
const stageTopPitch = Math.min(HALF_VFOV - 2, Math.atan2(5, distM) * 180 / Math.PI);
|
|
3558
|
+
const stageBasePitch = Math.max(-HALF_VFOV + 2, -Math.atan2(1.1, distM) * 180 / Math.PI);
|
|
3559
|
+
const sx0 = yawToTX(-stageHalfYaw);
|
|
3560
|
+
const sx1 = yawToTX(stageHalfYaw);
|
|
3561
|
+
const sy0 = pitchToTY(stageTopPitch);
|
|
3562
|
+
const sy1 = pitchToTY(stageBasePitch);
|
|
3563
|
+
const sw = sx1 - sx0;
|
|
3564
|
+
const sh = sy1 - sy0;
|
|
3565
|
+
const glow = ctx.createRadialGradient(TW / 2, (sy0 + sy1) / 2, 4, TW / 2, (sy0 + sy1) / 2, sw * 1.1);
|
|
3566
|
+
glow.addColorStop(0, "rgba(129,140,248,0.5)");
|
|
3567
|
+
glow.addColorStop(0.5, "rgba(99,102,241,0.15)");
|
|
3568
|
+
glow.addColorStop(1, "rgba(99,102,241,0)");
|
|
3569
|
+
ctx.fillStyle = glow;
|
|
3570
|
+
ctx.fillRect(sx0 - sw * 0.6, sy0 - sh * 1.2, sw * 2.2, sh * 3.4);
|
|
3571
|
+
ctx.fillStyle = "#242c44";
|
|
3572
|
+
ctx.fillRect(sx0, sy0, sw, sh);
|
|
3573
|
+
const backdrop = ctx.createLinearGradient(0, sy0, 0, sy1);
|
|
3574
|
+
backdrop.addColorStop(0, "#7c5cff");
|
|
3575
|
+
backdrop.addColorStop(0.5, "#e1447a");
|
|
3576
|
+
backdrop.addColorStop(1, "#f59e0b");
|
|
3577
|
+
ctx.globalAlpha = 0.78;
|
|
3578
|
+
ctx.fillStyle = backdrop;
|
|
3579
|
+
const inset = sw * 0.06;
|
|
3580
|
+
ctx.fillRect(sx0 + inset, sy0 + sh * 0.12, sw - inset * 2, sh * 0.62);
|
|
3581
|
+
ctx.globalAlpha = 1;
|
|
3582
|
+
ctx.fillStyle = "#0d1119";
|
|
3583
|
+
ctx.fillRect(sx0, sy1 - sh * 0.1, sw, sh * 0.1);
|
|
3584
|
+
const ph = sh * 0.45;
|
|
3585
|
+
ctx.fillStyle = "rgba(8,10,16,0.85)";
|
|
3586
|
+
for (const fx of [0.35, 0.5, 0.65]) {
|
|
3587
|
+
const px = sx0 + sw * fx;
|
|
3588
|
+
const py = sy1 - sh * 0.12;
|
|
3589
|
+
ctx.beginPath();
|
|
3590
|
+
ctx.arc(px, py - ph * 0.82, ph * 0.16, 0, Math.PI * 2);
|
|
3591
|
+
ctx.fill();
|
|
3592
|
+
ctx.fillRect(px - ph * 0.14, py - ph * 0.68, ph * 0.28, ph * 0.68);
|
|
3593
|
+
}
|
|
3594
|
+
ctx.globalAlpha = 0.15;
|
|
3595
|
+
ctx.fillStyle = "#c7d2fe";
|
|
3596
|
+
for (const fx of [0.3, 0.5, 0.7]) {
|
|
3597
|
+
const bx = sx0 + sw * fx;
|
|
3598
|
+
ctx.beginPath();
|
|
3599
|
+
ctx.moveTo(bx - 5, pitchToTY(Math.min(HALF_VFOV, stageTopPitch + 18)));
|
|
3600
|
+
ctx.lineTo(bx - sw * 0.09, sy1);
|
|
3601
|
+
ctx.lineTo(bx + sw * 0.09, sy1);
|
|
3602
|
+
ctx.lineTo(bx + 5, pitchToTY(Math.min(HALF_VFOV, stageTopPitch + 18)));
|
|
3603
|
+
ctx.closePath();
|
|
3604
|
+
ctx.fill();
|
|
3605
|
+
}
|
|
3606
|
+
ctx.globalAlpha = 1;
|
|
3607
|
+
ctx.fillStyle = "rgba(199,210,254,0.75)";
|
|
3608
|
+
for (let i = 0; i < 8; i++) {
|
|
3609
|
+
ctx.beginPath();
|
|
3610
|
+
ctx.arc((i + 0.5) / 8 * TW, pitchToTY(HALF_VFOV - 4 - i % 2 * 3), 2.2, 0, Math.PI * 2);
|
|
3611
|
+
ctx.fill();
|
|
3612
|
+
}
|
|
3613
|
+
ctx.fillStyle = "rgba(10,13,20,0.9)";
|
|
3614
|
+
ctx.fillRect(0, TH - 26, TW, 26);
|
|
3615
|
+
ctx.fillStyle = "rgba(30,37,54,0.9)";
|
|
3616
|
+
for (let i = 0; i < 9; i++) ctx.fillRect(i * (TW / 9) + 6, TH - 22, TW / 9 - 12, 14);
|
|
3617
|
+
return { url: canvas.toDataURL("image/jpeg", 0.8), distanceM: Math.round(distM) };
|
|
3618
|
+
}
|
|
3619
|
+
|
|
3404
3620
|
// src/i18n/bundles.ts
|
|
3405
3621
|
var LOADERS = {
|
|
3406
3622
|
es: () => import("./es-SKJTYKLL.js").then((m) => ({ default: m.es })),
|
|
@@ -3453,6 +3669,8 @@ export {
|
|
|
3453
3669
|
gaAreasOf,
|
|
3454
3670
|
gaUnitLabel,
|
|
3455
3671
|
gaUnitLabels,
|
|
3672
|
+
generateSeatPanorama,
|
|
3673
|
+
generateSeatThumb,
|
|
3456
3674
|
getLocale,
|
|
3457
3675
|
hiddenObjectIds,
|
|
3458
3676
|
isGaUnitLabel,
|