@lalalic/markcut 3.0.0 → 3.1.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/package.json +1 -1
- package/skills/markcut/SKILL.md +7 -0
- package/skills/markcut/docs/map-dynamic-camera.md +244 -0
- package/skills/markcut/docs/markdown-descriptive.md +2 -0
- package/src/descriptive/compiler.ts +41 -0
- package/src/descriptive/dsl.ts +42 -5
- package/src/descriptive/markdown.ts +5 -0
- package/src/descriptive/resolve.test.ts +5 -5
- package/src/descriptive/resolve.ts +51 -12
- package/src/player/bundle/player.js +448 -99
- package/src/player/pipeline.mjs +64 -13
- package/src/player/pipeline.ts +5 -4
- package/src/player/server.mjs +22 -42
- package/src/render/cli.mjs +54 -3
- package/src/render/validate-assets.mjs +140 -0
- package/src/schema/index.ts +56 -1
- package/src/spots/cli.mjs +266 -0
- package/src/types/Map.tsx +501 -127
- package/src/utils/tween.ts +49 -1
- package/tests/dsl.test.ts +43 -0
- package/tests/fixtures/map-dynamic.json +52 -0
- package/tests/fixtures/md/animate-diagrams.md +9 -7
- package/tests/fixtures/md/map-all-views.md +28 -0
- package/tests/md-descriptive.test.ts +58 -0
- package/tests/render.test.ts +1 -0
- package/tests/schema.test.ts +58 -1
- package/tests/validate-assets.test.ts +106 -0
- package/B] +0 -2
- package/tests/tmp/vision-1785081637127-video/videos/.normalized/segments/test-clip_0to3_seg_1100to3000.mp4 +0 -0
- package/tests/tmp/vision-1785081637127-video/videos/.normalized/test-clip_0to3.mp4 +0 -0
- package/tests/tmp/vision-1785081637127-video/videos/.normalized/test-clip_audio.mp3 +0 -0
- package/tests/tmp/vision-1785081637127-video/videos/metadata.json +0 -9
- package/tests/tmp/vision-1785081637127-video/videos/test-clip.mp4 +0 -0
- package/tests/tmp/vision-1785081637127-video/videos/test-clip.vtt +0 -5
|
@@ -239858,6 +239858,23 @@ function useTweenBindings(action) {
|
|
|
239858
239858
|
);
|
|
239859
239859
|
return { tween, interpolate };
|
|
239860
239860
|
}
|
|
239861
|
+
function resolveTween(frame2, fps, spec, start4, end2, fallback) {
|
|
239862
|
+
if (typeof spec === "number") return spec;
|
|
239863
|
+
const tween = spec?.__tween;
|
|
239864
|
+
if (!tween || tween.length < 2) return fallback;
|
|
239865
|
+
const from2 = Number(tween[0]);
|
|
239866
|
+
const to = Number(tween[1]);
|
|
239867
|
+
if (!Number.isFinite(from2) || !Number.isFinite(to)) return fallback;
|
|
239868
|
+
const easingName = typeof tween[2] === "string" ? tween[2] : void 0;
|
|
239869
|
+
const easingFn = easingName ? EASING_MAP[easingName] : void 0;
|
|
239870
|
+
const startF = Math.max(0, Math.floor(start4 * fps));
|
|
239871
|
+
const endF = Math.max(startF + 1, Math.floor(end2 * fps));
|
|
239872
|
+
return interpolate(frame2, [startF, endF], [from2, to], {
|
|
239873
|
+
extrapolateLeft: "clamp",
|
|
239874
|
+
extrapolateRight: "clamp",
|
|
239875
|
+
easing: easingFn
|
|
239876
|
+
});
|
|
239877
|
+
}
|
|
239861
239878
|
|
|
239862
239879
|
// src/types/Component.tsx
|
|
239863
239880
|
var import_jsx_runtime87 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -242326,6 +242343,20 @@ var Rectangle = (0, import_react127.forwardRef)((props, ref2) => {
|
|
|
242326
242343
|
return import_react127.default.createElement(import_react127.default.Fragment, null);
|
|
242327
242344
|
});
|
|
242328
242345
|
Rectangle.displayName = "Rectangle";
|
|
242346
|
+
function useMap3D(id39 = null) {
|
|
242347
|
+
const apiContext = (0, import_react127.useContext)(APIProviderContext);
|
|
242348
|
+
const map3dContext = (0, import_react127.useContext)(GoogleMaps3DContext);
|
|
242349
|
+
if (apiContext === null) {
|
|
242350
|
+
logErrorOnce("useMap3D(): failed to retrieve APIProviderContext. Make sure that the <APIProvider> component exists and that the component you are calling `useMap3D()` from is a child of the <APIProvider>.");
|
|
242351
|
+
return null;
|
|
242352
|
+
}
|
|
242353
|
+
const { map3dInstances } = apiContext;
|
|
242354
|
+
if (id39 !== null)
|
|
242355
|
+
return map3dInstances[id39] || null;
|
|
242356
|
+
if (map3dContext === null || map3dContext === void 0 ? void 0 : map3dContext.map3d)
|
|
242357
|
+
return map3dContext.map3d;
|
|
242358
|
+
return map3dInstances["default"] || null;
|
|
242359
|
+
}
|
|
242329
242360
|
|
|
242330
242361
|
// src/types/Map.tsx
|
|
242331
242362
|
var import_jsx_runtime89 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -242351,14 +242382,10 @@ function MapLeaf({ stream: stream3 }) {
|
|
|
242351
242382
|
const end2 = stream3.end ?? start4 + (stream3.duration ?? 1);
|
|
242352
242383
|
const totalDur = stream3.durationInSeconds ?? end2;
|
|
242353
242384
|
const apiKey = resolveApiKey(stream3);
|
|
242385
|
+
const view = stream3.view ?? "route";
|
|
242354
242386
|
useFrameEvents(stream3.on, Math.max(1, Math.floor(totalDur * fps)));
|
|
242355
|
-
if (waypoints.length === 0) return null;
|
|
242387
|
+
if ((view === "route" || view === "cinematic") && waypoints.length === 0) return null;
|
|
242356
242388
|
const durFrames = Math.max(1, Math.floor(fps * (end2 - start4)));
|
|
242357
|
-
const center4 = stream3.center ?? { lat: waypoints[0].lat, lng: waypoints[0].lng };
|
|
242358
|
-
const zoom2 = stream3.zoom ?? 10;
|
|
242359
|
-
const mapType = stream3.mapType ?? "roadmap";
|
|
242360
|
-
const travelMode = stream3.travelMode ?? "DRIVING";
|
|
242361
|
-
const markerEmoji = stream3.routeMarker ?? "\u{1F697}";
|
|
242362
242389
|
const mapLocale = import_react128.default.useMemo(
|
|
242363
242390
|
() => resolveMapLocale(stream3.language, stream3.region),
|
|
242364
242391
|
[stream3.language, stream3.region]
|
|
@@ -242366,7 +242393,7 @@ function MapLeaf({ stream: stream3 }) {
|
|
|
242366
242393
|
const mapLoadHandleRef = import_react128.default.useRef(null);
|
|
242367
242394
|
const mapLoadContinuedRef = import_react128.default.useRef(false);
|
|
242368
242395
|
import_react128.default.useEffect(() => {
|
|
242369
|
-
mapLoadHandleRef.current = delayRender("Waiting for map
|
|
242396
|
+
mapLoadHandleRef.current = delayRender("Waiting for map to load...");
|
|
242370
242397
|
mapLoadContinuedRef.current = false;
|
|
242371
242398
|
const fallbackTimer = window.setTimeout(() => {
|
|
242372
242399
|
if (!mapLoadContinuedRef.current && mapLoadHandleRef.current !== null) {
|
|
@@ -242383,63 +242410,369 @@ function MapLeaf({ stream: stream3 }) {
|
|
|
242383
242410
|
mapLoadHandleRef.current = null;
|
|
242384
242411
|
};
|
|
242385
242412
|
}, [stream3.id, start4, end2]);
|
|
242386
|
-
const
|
|
242413
|
+
const handleMapReady = import_react128.default.useCallback(() => {
|
|
242387
242414
|
if (!mapLoadContinuedRef.current && mapLoadHandleRef.current !== null) {
|
|
242388
242415
|
continueRender(mapLoadHandleRef.current);
|
|
242389
242416
|
mapLoadContinuedRef.current = true;
|
|
242390
242417
|
}
|
|
242391
242418
|
}, []);
|
|
242419
|
+
const use3d = view === "cinematic" && stream3.cinematic?.fallback === "none" && (stream3.cinematic.mode === "flyTo" || stream3.cinematic.mode === "orbit");
|
|
242392
242420
|
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
242393
242421
|
Sequence,
|
|
242394
242422
|
{
|
|
242395
242423
|
durationInFrames: durFrames,
|
|
242396
242424
|
from: Math.floor(fps * start4),
|
|
242397
242425
|
layout: "none",
|
|
242398
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime89.
|
|
242426
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
|
|
242399
242427
|
APIProvider,
|
|
242400
242428
|
{
|
|
242401
242429
|
apiKey,
|
|
242402
242430
|
language: mapLocale.language,
|
|
242403
242431
|
region: mapLocale.region,
|
|
242404
|
-
children:
|
|
242405
|
-
|
|
242406
|
-
{
|
|
242407
|
-
|
|
242408
|
-
|
|
242409
|
-
|
|
242410
|
-
|
|
242411
|
-
|
|
242412
|
-
|
|
242413
|
-
|
|
242414
|
-
|
|
242415
|
-
|
|
242416
|
-
|
|
242417
|
-
|
|
242418
|
-
|
|
242419
|
-
|
|
242420
|
-
|
|
242421
|
-
|
|
242422
|
-
|
|
242423
|
-
|
|
242424
|
-
|
|
242425
|
-
|
|
242426
|
-
|
|
242427
|
-
|
|
242432
|
+
children: [
|
|
242433
|
+
view === "overview" && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(OverviewMap, { stream: stream3, onTilesLoaded: handleMapReady }),
|
|
242434
|
+
view === "cinematic" && (use3d ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(CinematicMap3D, { stream: stream3, onReady: handleMapReady }) : /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(CinematicMap, { stream: stream3, onTilesLoaded: handleMapReady })),
|
|
242435
|
+
view === "streetview" && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(StreetViewLeaf, { stream: stream3, onPanoReady: handleMapReady }),
|
|
242436
|
+
view === "route" && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(RouteMap, { stream: stream3, onTilesLoaded: handleMapReady })
|
|
242437
|
+
]
|
|
242438
|
+
}
|
|
242439
|
+
)
|
|
242440
|
+
}
|
|
242441
|
+
);
|
|
242442
|
+
}
|
|
242443
|
+
function OverviewMap({
|
|
242444
|
+
stream: stream3,
|
|
242445
|
+
onTilesLoaded
|
|
242446
|
+
}) {
|
|
242447
|
+
const { fps } = useVideoConfig();
|
|
242448
|
+
const frame2 = useCurrentFrame();
|
|
242449
|
+
const start4 = stream3.start ?? 0;
|
|
242450
|
+
const end2 = stream3.end ?? start4 + (stream3.duration ?? 1);
|
|
242451
|
+
const fallbackCenter = stream3.center ?? { lat: 37.7749, lng: -122.4194 };
|
|
242452
|
+
const center4 = {
|
|
242453
|
+
lat: resolveTween(frame2, fps, stream3.camera?.center?.lat, start4, end2, fallbackCenter.lat),
|
|
242454
|
+
lng: resolveTween(frame2, fps, stream3.camera?.center?.lng, start4, end2, fallbackCenter.lng)
|
|
242455
|
+
};
|
|
242456
|
+
const zoom2 = resolveTween(frame2, fps, stream3.camera?.zoom, start4, end2, stream3.zoom ?? 10);
|
|
242457
|
+
const heading3 = resolveTween(frame2, fps, stream3.camera?.heading, start4, end2, 0);
|
|
242458
|
+
const tilt = resolveTween(frame2, fps, stream3.camera?.tilt, start4, end2, 0);
|
|
242459
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
242460
|
+
Map4,
|
|
242461
|
+
{
|
|
242462
|
+
mapId: String(stream3.id ?? "map-overview"),
|
|
242463
|
+
center: center4,
|
|
242464
|
+
zoom: zoom2,
|
|
242465
|
+
heading: heading3,
|
|
242466
|
+
tilt,
|
|
242467
|
+
mapTypeId: stream3.mapType ?? "roadmap",
|
|
242468
|
+
disableDefaultUI: true,
|
|
242469
|
+
zoomControl: false,
|
|
242470
|
+
onTilesLoaded,
|
|
242471
|
+
style: { width: "100%", height: "100%", position: "absolute" }
|
|
242472
|
+
}
|
|
242473
|
+
);
|
|
242474
|
+
}
|
|
242475
|
+
function RouteMap({
|
|
242476
|
+
stream: stream3,
|
|
242477
|
+
onTilesLoaded
|
|
242478
|
+
}) {
|
|
242479
|
+
const { fps } = useVideoConfig();
|
|
242480
|
+
const frame2 = useCurrentFrame();
|
|
242481
|
+
const waypoints = stream3.waypoints ?? [];
|
|
242482
|
+
const start4 = stream3.start ?? 0;
|
|
242483
|
+
const end2 = stream3.end ?? start4 + (stream3.duration ?? 1);
|
|
242484
|
+
const fallbackCenter = stream3.center ?? { lat: waypoints[0].lat, lng: waypoints[0].lng };
|
|
242485
|
+
const center4 = {
|
|
242486
|
+
lat: resolveTween(frame2, fps, stream3.camera?.center?.lat, start4, end2, fallbackCenter.lat),
|
|
242487
|
+
lng: resolveTween(frame2, fps, stream3.camera?.center?.lng, start4, end2, fallbackCenter.lng)
|
|
242488
|
+
};
|
|
242489
|
+
const zoom2 = resolveTween(frame2, fps, stream3.camera?.zoom, start4, end2, stream3.zoom ?? 10);
|
|
242490
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
242491
|
+
Map4,
|
|
242492
|
+
{
|
|
242493
|
+
mapId: String(stream3.id ?? "map-route"),
|
|
242494
|
+
center: center4,
|
|
242495
|
+
zoom: zoom2,
|
|
242496
|
+
mapTypeId: stream3.mapType ?? "roadmap",
|
|
242497
|
+
disableDefaultUI: true,
|
|
242498
|
+
zoomControl: false,
|
|
242499
|
+
onTilesLoaded,
|
|
242500
|
+
style: { width: "100%", height: "100%", position: "absolute" },
|
|
242501
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
242502
|
+
RouteWithMarker,
|
|
242503
|
+
{
|
|
242504
|
+
waypoints,
|
|
242505
|
+
travelMode: stream3.travelMode ?? "DRIVING",
|
|
242506
|
+
markerEmoji: stream3.routeMarker ?? "\u{1F697}",
|
|
242507
|
+
actionDuration: end2 - start4
|
|
242508
|
+
}
|
|
242509
|
+
)
|
|
242510
|
+
}
|
|
242511
|
+
);
|
|
242512
|
+
}
|
|
242513
|
+
function CinematicMap({
|
|
242514
|
+
stream: stream3,
|
|
242515
|
+
onTilesLoaded
|
|
242516
|
+
}) {
|
|
242517
|
+
const { fps } = useVideoConfig();
|
|
242518
|
+
const frame2 = useCurrentFrame();
|
|
242519
|
+
const waypoints = stream3.waypoints ?? [];
|
|
242520
|
+
const start4 = stream3.start ?? 0;
|
|
242521
|
+
const end2 = stream3.end ?? start4 + (stream3.duration ?? 1);
|
|
242522
|
+
const actionDuration = Math.max(0.1, end2 - start4);
|
|
242523
|
+
const mode = stream3.cinematic?.mode ?? "flyAlong";
|
|
242524
|
+
const headingFollow = stream3.cinematic?.headingFollow ?? true;
|
|
242525
|
+
const leg = useRouteLeg(waypoints, stream3.travelMode ?? "DRIVING");
|
|
242526
|
+
const seconds2 = frame2 / fps;
|
|
242527
|
+
const pos = routePositionAt(leg, waypoints, actionDuration, seconds2);
|
|
242528
|
+
const lookahead2 = routePositionAt(leg, waypoints, actionDuration, seconds2 + 0.4);
|
|
242529
|
+
const first3 = waypoints[0];
|
|
242530
|
+
const fallbackCenter = stream3.center ?? first3;
|
|
242531
|
+
let center4;
|
|
242532
|
+
if (mode === "flyAlong" && pos) {
|
|
242533
|
+
center4 = pos;
|
|
242534
|
+
} else if (mode === "flyTo") {
|
|
242535
|
+
center4 = {
|
|
242536
|
+
lat: resolveTween(frame2, fps, stream3.camera?.center?.lat, start4, end2, first3.lat),
|
|
242537
|
+
lng: resolveTween(frame2, fps, stream3.camera?.center?.lng, start4, end2, first3.lng)
|
|
242538
|
+
};
|
|
242539
|
+
} else {
|
|
242540
|
+
center4 = fallbackCenter;
|
|
242541
|
+
}
|
|
242542
|
+
let heading3 = resolveTween(frame2, fps, stream3.camera?.heading, start4, end2, 0);
|
|
242543
|
+
if (headingFollow && pos && lookahead2) {
|
|
242544
|
+
heading3 = bearing(pos, lookahead2);
|
|
242545
|
+
}
|
|
242546
|
+
const tilt = resolveTween(frame2, fps, stream3.cinematic?.tilt, start4, end2, 45);
|
|
242547
|
+
const zoom2 = resolveTween(frame2, fps, stream3.camera?.zoom, start4, end2, stream3.zoom ?? 13);
|
|
242548
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
242549
|
+
Map4,
|
|
242550
|
+
{
|
|
242551
|
+
mapId: String(stream3.id ?? "map-cinematic"),
|
|
242552
|
+
center: center4,
|
|
242553
|
+
zoom: zoom2,
|
|
242554
|
+
heading: heading3,
|
|
242555
|
+
tilt,
|
|
242556
|
+
mapTypeId: stream3.mapType ?? "roadmap",
|
|
242557
|
+
disableDefaultUI: true,
|
|
242558
|
+
zoomControl: false,
|
|
242559
|
+
onTilesLoaded,
|
|
242560
|
+
style: { width: "100%", height: "100%", position: "absolute" },
|
|
242561
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
242562
|
+
RouteWithMarker,
|
|
242563
|
+
{
|
|
242564
|
+
waypoints,
|
|
242565
|
+
travelMode: stream3.travelMode ?? "DRIVING",
|
|
242566
|
+
markerEmoji: stream3.routeMarker ?? "\u{1F697}",
|
|
242567
|
+
actionDuration
|
|
242428
242568
|
}
|
|
242429
242569
|
)
|
|
242430
242570
|
}
|
|
242431
242571
|
);
|
|
242432
242572
|
}
|
|
242573
|
+
function CinematicMap3D({
|
|
242574
|
+
stream: stream3,
|
|
242575
|
+
onReady
|
|
242576
|
+
}) {
|
|
242577
|
+
const { fps } = useVideoConfig();
|
|
242578
|
+
const frame2 = useCurrentFrame();
|
|
242579
|
+
const waypoints = stream3.waypoints ?? [];
|
|
242580
|
+
const start4 = stream3.start ?? 0;
|
|
242581
|
+
const end2 = stream3.end ?? start4 + (stream3.duration ?? 1);
|
|
242582
|
+
const actionDuration = Math.max(0.1, end2 - start4);
|
|
242583
|
+
const first3 = waypoints[0] ?? { lat: 37.7749, lng: -122.4194 };
|
|
242584
|
+
const map3dRef = import_react128.default.useRef(null);
|
|
242585
|
+
const map3d = useMap3D();
|
|
242586
|
+
const leg = useRouteLeg(waypoints, stream3.travelMode ?? "DRIVING");
|
|
242587
|
+
const range3 = resolveTween(frame2, fps, stream3.cinematic?.range, start4, end2, 2e3);
|
|
242588
|
+
const tilt = resolveTween(frame2, fps, stream3.cinematic?.tilt, start4, end2, 60);
|
|
242589
|
+
const roll = resolveTween(frame2, fps, stream3.cinematic?.roll, start4, end2, 0);
|
|
242590
|
+
const heading3 = resolveTween(frame2, fps, stream3.camera?.heading, start4, end2, 0);
|
|
242591
|
+
const center4 = {
|
|
242592
|
+
lat: resolveTween(frame2, fps, stream3.camera?.center?.lat, start4, end2, first3.lat),
|
|
242593
|
+
lng: resolveTween(frame2, fps, stream3.camera?.center?.lng, start4, end2, first3.lng),
|
|
242594
|
+
altitude: stream3.cinematic?.altitude ?? 100
|
|
242595
|
+
};
|
|
242596
|
+
const seconds2 = frame2 / fps;
|
|
242597
|
+
const pos = routePositionAt(leg, waypoints, actionDuration, seconds2);
|
|
242598
|
+
const legPath = import_react128.default.useMemo(() => {
|
|
242599
|
+
if (!leg) return null;
|
|
242600
|
+
const pts2 = [];
|
|
242601
|
+
for (const step3 of leg.steps ?? []) {
|
|
242602
|
+
for (const p4 of step3.path ?? []) pts2.push({ lat: p4.lat(), lng: p4.lng(), altitude: 0 });
|
|
242603
|
+
}
|
|
242604
|
+
return pts2.length ? pts2 : null;
|
|
242605
|
+
}, [leg]);
|
|
242606
|
+
import_react128.default.useEffect(() => {
|
|
242607
|
+
if (!map3d || !legPath) return;
|
|
242608
|
+
const el = document.createElement("gmp-polyline-3d");
|
|
242609
|
+
el.coordinates = legPath;
|
|
242610
|
+
el.strokeColor = stream3.routeColor ?? "#4285F4";
|
|
242611
|
+
el.strokeWidth = stream3.routeWeight ?? 4;
|
|
242612
|
+
map3d.appendChild(el);
|
|
242613
|
+
return () => {
|
|
242614
|
+
el.remove();
|
|
242615
|
+
};
|
|
242616
|
+
}, [map3d, legPath, stream3.routeColor, stream3.routeWeight]);
|
|
242617
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
242618
|
+
Map3D,
|
|
242619
|
+
{
|
|
242620
|
+
ref: map3dRef,
|
|
242621
|
+
mode: stream3.mapType === "hybrid" ? "HYBRID" : "SATELLITE",
|
|
242622
|
+
center: center4,
|
|
242623
|
+
range: range3,
|
|
242624
|
+
heading: heading3,
|
|
242625
|
+
tilt,
|
|
242626
|
+
roll,
|
|
242627
|
+
onSteadyChange: onReady,
|
|
242628
|
+
onAnimationEnd: onReady,
|
|
242629
|
+
style: { width: "100%", height: "100%", position: "absolute" },
|
|
242630
|
+
children: pos ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Marker3D, { position: { lat: pos.lat, lng: pos.lng, altitude: 0 } }) : null
|
|
242631
|
+
}
|
|
242632
|
+
);
|
|
242633
|
+
}
|
|
242634
|
+
function StreetViewLeaf({
|
|
242635
|
+
stream: stream3,
|
|
242636
|
+
onPanoReady
|
|
242637
|
+
}) {
|
|
242638
|
+
const containerRef = import_react128.default.useRef(null);
|
|
242639
|
+
const svLibrary = useMapsLibrary("streetView");
|
|
242640
|
+
const [pano, setPano] = import_react128.default.useState(null);
|
|
242641
|
+
const { fps } = useVideoConfig();
|
|
242642
|
+
const frame2 = useCurrentFrame();
|
|
242643
|
+
const start4 = stream3.start ?? 0;
|
|
242644
|
+
const end2 = stream3.end ?? start4 + (stream3.duration ?? 1);
|
|
242645
|
+
const sv = stream3.streetView;
|
|
242646
|
+
import_react128.default.useEffect(() => {
|
|
242647
|
+
if (!svLibrary || !containerRef.current) return;
|
|
242648
|
+
const pan2 = new svLibrary.StreetViewPanorama(containerRef.current, {
|
|
242649
|
+
disableDefaultUI: true
|
|
242650
|
+
});
|
|
242651
|
+
if (sv?.pano) {
|
|
242652
|
+
pan2.setPano(sv.pano);
|
|
242653
|
+
} else if (sv?.location) {
|
|
242654
|
+
pan2.setPosition(sv.location);
|
|
242655
|
+
} else if (sv?.route?.length) {
|
|
242656
|
+
pan2.setPosition(sv.route[0]);
|
|
242657
|
+
}
|
|
242658
|
+
if (sv?.pov) {
|
|
242659
|
+
pan2.setPov({
|
|
242660
|
+
heading: typeof sv.pov.heading === "number" ? sv.pov.heading : 0,
|
|
242661
|
+
pitch: typeof sv.pov.pitch === "number" ? sv.pov.pitch : 0
|
|
242662
|
+
});
|
|
242663
|
+
}
|
|
242664
|
+
if (typeof sv?.zoom === "number") {
|
|
242665
|
+
pan2.setZoom(sv.zoom);
|
|
242666
|
+
}
|
|
242667
|
+
setPano(pan2);
|
|
242668
|
+
return () => {
|
|
242669
|
+
pan2.setVisible(false);
|
|
242670
|
+
};
|
|
242671
|
+
}, [svLibrary, stream3.id, sv?.pano, sv?.location, sv?.route, sv?.pov, sv?.zoom]);
|
|
242672
|
+
import_react128.default.useEffect(() => {
|
|
242673
|
+
if (!pano) return;
|
|
242674
|
+
const pov = pano.getPov();
|
|
242675
|
+
const heading3 = resolveTween(frame2, fps, sv?.pov?.heading, start4, end2, pov.heading);
|
|
242676
|
+
const pitch = resolveTween(frame2, fps, sv?.pov?.pitch, start4, end2, pov.pitch);
|
|
242677
|
+
pano.setPov({ heading: heading3, pitch });
|
|
242678
|
+
const zoom2 = resolveTween(frame2, fps, sv?.zoom, start4, end2, pano.getZoom() ?? 0);
|
|
242679
|
+
pano.setZoom(zoom2);
|
|
242680
|
+
let movedPosition = false;
|
|
242681
|
+
if (sv?.route && sv.route.length > 1) {
|
|
242682
|
+
const t4 = Math.min(Math.max(frame2 / fps / Math.max(0.1, end2 - start4), 0), 1);
|
|
242683
|
+
const total = sv.route.length - 1;
|
|
242684
|
+
const segI = Math.min(Math.floor(t4 * total), total - 1);
|
|
242685
|
+
const segT = t4 * total - segI;
|
|
242686
|
+
const a3 = sv.route[segI];
|
|
242687
|
+
const b5 = sv.route[segI + 1];
|
|
242688
|
+
pano.setPosition({
|
|
242689
|
+
lat: a3.lat + (b5.lat - a3.lat) * segT,
|
|
242690
|
+
lng: a3.lng + (b5.lng - a3.lng) * segT
|
|
242691
|
+
});
|
|
242692
|
+
movedPosition = true;
|
|
242693
|
+
}
|
|
242694
|
+
const handle2 = delayRender(`Street View frame ${frame2}`);
|
|
242695
|
+
let done = false;
|
|
242696
|
+
const finish = () => {
|
|
242697
|
+
if (done) return;
|
|
242698
|
+
done = true;
|
|
242699
|
+
continueRender(handle2);
|
|
242700
|
+
onPanoReady();
|
|
242701
|
+
};
|
|
242702
|
+
const graceMs = movedPosition ? 1200 : 400;
|
|
242703
|
+
const onPano = () => setTimeout(finish, graceMs);
|
|
242704
|
+
const lPano = pano.addListener("pano_changed", onPano);
|
|
242705
|
+
const fallback = setTimeout(finish, movedPosition ? 3e3 : 600);
|
|
242706
|
+
return () => {
|
|
242707
|
+
google.maps.event.removeListener(lPano);
|
|
242708
|
+
clearTimeout(fallback);
|
|
242709
|
+
finish();
|
|
242710
|
+
};
|
|
242711
|
+
}, [pano, frame2, fps, start4, end2, sv?.route, sv?.pov, sv?.zoom, onPanoReady]);
|
|
242712
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
242713
|
+
"div",
|
|
242714
|
+
{
|
|
242715
|
+
ref: containerRef,
|
|
242716
|
+
style: { width: "100%", height: "100%", position: "absolute" }
|
|
242717
|
+
}
|
|
242718
|
+
);
|
|
242719
|
+
}
|
|
242433
242720
|
function RouteWithMarker({
|
|
242434
242721
|
waypoints,
|
|
242435
242722
|
travelMode,
|
|
242436
242723
|
markerEmoji,
|
|
242437
242724
|
actionDuration
|
|
242438
242725
|
}) {
|
|
242726
|
+
const leg = useRouteLeg(waypoints, travelMode);
|
|
242727
|
+
const position7 = useAnimatedPosition({ leg, actionDuration, waypoints });
|
|
242728
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_jsx_runtime89.Fragment, { children: [
|
|
242729
|
+
waypoints.map((wp, i5) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(AdvancedMarker, { position: wp, children: wp.media ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
242730
|
+
"div",
|
|
242731
|
+
{
|
|
242732
|
+
style: {
|
|
242733
|
+
width: 44,
|
|
242734
|
+
height: 44,
|
|
242735
|
+
borderRadius: 6,
|
|
242736
|
+
overflow: "hidden",
|
|
242737
|
+
border: "2px solid #fff",
|
|
242738
|
+
boxShadow: "0 1px 4px rgba(0,0,0,0.45)",
|
|
242739
|
+
background: "#fff",
|
|
242740
|
+
position: "relative",
|
|
242741
|
+
top: "-24px"
|
|
242742
|
+
},
|
|
242743
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
242744
|
+
"img",
|
|
242745
|
+
{
|
|
242746
|
+
src: wp.media,
|
|
242747
|
+
alt: "",
|
|
242748
|
+
style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
|
|
242749
|
+
}
|
|
242750
|
+
)
|
|
242751
|
+
}
|
|
242752
|
+
) : wp.label ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
242753
|
+
"div",
|
|
242754
|
+
{
|
|
242755
|
+
style: {
|
|
242756
|
+
background: "rgba(255,255,255,0.9)",
|
|
242757
|
+
borderRadius: "4px",
|
|
242758
|
+
padding: "2px 6px",
|
|
242759
|
+
fontSize: "12px",
|
|
242760
|
+
fontWeight: 700,
|
|
242761
|
+
color: "#333",
|
|
242762
|
+
whiteSpace: "nowrap",
|
|
242763
|
+
position: "relative",
|
|
242764
|
+
top: "-24px"
|
|
242765
|
+
},
|
|
242766
|
+
children: wp.label
|
|
242767
|
+
}
|
|
242768
|
+
) : null }, i5)),
|
|
242769
|
+
position7 ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(AdvancedMarker, { position: position7, children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Pin, { glyphText: markerEmoji, scale: 4 }) }) : null
|
|
242770
|
+
] });
|
|
242771
|
+
}
|
|
242772
|
+
function useRouteLeg(waypoints, travelMode) {
|
|
242439
242773
|
const map9 = useMap();
|
|
242440
242774
|
const routesLibrary = useMapsLibrary("routes");
|
|
242441
242775
|
const [leg, setLeg] = import_react128.default.useState(null);
|
|
242442
|
-
const [routeIndex, setRouteIndex] = import_react128.default.useState(0);
|
|
242443
242776
|
const handle2 = import_react128.default.useRef(null);
|
|
242444
242777
|
import_react128.default.useEffect(() => {
|
|
242445
242778
|
if (!routesLibrary || !map9 || waypoints.length < 2) return;
|
|
@@ -242455,7 +242788,6 @@ function RouteWithMarker({
|
|
|
242455
242788
|
provideRouteAlternatives: false
|
|
242456
242789
|
}).then((response) => {
|
|
242457
242790
|
renderer15.setDirections(response);
|
|
242458
|
-
setRouteIndex(0);
|
|
242459
242791
|
setLeg(response.routes[0]?.legs[0] ?? null);
|
|
242460
242792
|
if (handle2.current !== null) continueRender(handle2.current);
|
|
242461
242793
|
}).catch(() => {
|
|
@@ -242465,30 +242797,7 @@ function RouteWithMarker({
|
|
|
242465
242797
|
renderer15.setMap(null);
|
|
242466
242798
|
};
|
|
242467
242799
|
}, [routesLibrary, map9, waypoints, travelMode]);
|
|
242468
|
-
|
|
242469
|
-
setRouteIndex((prev2) => prev2);
|
|
242470
|
-
}, [routeIndex]);
|
|
242471
|
-
const position7 = useAnimatedPosition({ leg, actionDuration, waypoints });
|
|
242472
|
-
return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_jsx_runtime89.Fragment, { children: [
|
|
242473
|
-
waypoints.map((wp, i5) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(AdvancedMarker, { position: wp, children: wp.label ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
242474
|
-
"div",
|
|
242475
|
-
{
|
|
242476
|
-
style: {
|
|
242477
|
-
background: "rgba(255,255,255,0.9)",
|
|
242478
|
-
borderRadius: "4px",
|
|
242479
|
-
padding: "2px 6px",
|
|
242480
|
-
fontSize: "12px",
|
|
242481
|
-
fontWeight: 700,
|
|
242482
|
-
color: "#333",
|
|
242483
|
-
whiteSpace: "nowrap",
|
|
242484
|
-
position: "relative",
|
|
242485
|
-
top: "-24px"
|
|
242486
|
-
},
|
|
242487
|
-
children: wp.label
|
|
242488
|
-
}
|
|
242489
|
-
) : null }, i5)),
|
|
242490
|
-
position7 ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(AdvancedMarker, { position: position7, children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Pin, { glyphText: markerEmoji, scale: 4 }) }) : null
|
|
242491
|
-
] });
|
|
242800
|
+
return leg;
|
|
242492
242801
|
}
|
|
242493
242802
|
function useAnimatedPosition({
|
|
242494
242803
|
leg,
|
|
@@ -242497,46 +242806,50 @@ function useAnimatedPosition({
|
|
|
242497
242806
|
}) {
|
|
242498
242807
|
const frame2 = useCurrentFrame();
|
|
242499
242808
|
const { fps } = useVideoConfig();
|
|
242500
|
-
return import_react128.default.useMemo(
|
|
242501
|
-
|
|
242502
|
-
|
|
242503
|
-
|
|
242504
|
-
|
|
242505
|
-
|
|
242506
|
-
|
|
242507
|
-
|
|
242508
|
-
|
|
242509
|
-
|
|
242510
|
-
|
|
242511
|
-
|
|
242512
|
-
|
|
242513
|
-
|
|
242514
|
-
|
|
242515
|
-
|
|
242516
|
-
|
|
242517
|
-
|
|
242518
|
-
|
|
242519
|
-
|
|
242520
|
-
|
|
242521
|
-
|
|
242522
|
-
|
|
242523
|
-
|
|
242524
|
-
|
|
242525
|
-
|
|
242526
|
-
|
|
242527
|
-
|
|
242528
|
-
|
|
242529
|
-
|
|
242530
|
-
|
|
242531
|
-
|
|
242532
|
-
|
|
242533
|
-
|
|
242534
|
-
|
|
242535
|
-
|
|
242536
|
-
|
|
242537
|
-
|
|
242538
|
-
|
|
242539
|
-
|
|
242809
|
+
return import_react128.default.useMemo(
|
|
242810
|
+
() => routePositionAt(leg, waypoints, actionDuration, frame2 / fps),
|
|
242811
|
+
[leg, frame2, fps, actionDuration, waypoints]
|
|
242812
|
+
);
|
|
242813
|
+
}
|
|
242814
|
+
function routePositionAt(leg, waypoints, actionDuration, seconds2) {
|
|
242815
|
+
const linearFallback = () => {
|
|
242816
|
+
if (waypoints.length < 2) return null;
|
|
242817
|
+
const t4 = Math.min(seconds2 / actionDuration, 1);
|
|
242818
|
+
const total = waypoints.length - 1;
|
|
242819
|
+
const segI = Math.min(Math.floor(t4 * total), total - 1);
|
|
242820
|
+
const segT = t4 * total - segI;
|
|
242821
|
+
const a3 = waypoints[segI];
|
|
242822
|
+
const b5 = waypoints[segI + 1];
|
|
242823
|
+
if (!a3 || !b5) return null;
|
|
242824
|
+
return { lat: a3.lat + (b5.lat - a3.lat) * segT, lng: a3.lng + (b5.lng - a3.lng) * segT };
|
|
242825
|
+
};
|
|
242826
|
+
if (!leg || !leg.duration?.value) {
|
|
242827
|
+
return linearFallback();
|
|
242828
|
+
}
|
|
242829
|
+
const currentInSecond = seconds2 * (leg.duration.value / actionDuration);
|
|
242830
|
+
const { step: step3, elapsedInSeconds } = getCurrentStep(leg, currentInSecond);
|
|
242831
|
+
if (!step3 || !step3.path) {
|
|
242832
|
+
return linearFallback();
|
|
242833
|
+
}
|
|
242834
|
+
const stepElapsed = currentInSecond - elapsedInSeconds;
|
|
242835
|
+
const stepProgress = stepElapsed / (step3.duration?.value ?? 1);
|
|
242836
|
+
const pathIdx = Math.min(
|
|
242837
|
+
Math.max(0, Math.floor(stepProgress * step3.path.length)),
|
|
242838
|
+
step3.path.length - 1
|
|
242839
|
+
);
|
|
242840
|
+
const pt = step3.path[pathIdx];
|
|
242841
|
+
if (!pt) return null;
|
|
242842
|
+
return { lat: pt.lat(), lng: pt.lng() };
|
|
242843
|
+
}
|
|
242844
|
+
function bearing(a3, b5) {
|
|
242845
|
+
const toRad = (d4) => d4 * Math.PI / 180;
|
|
242846
|
+
const toDeg = (d4) => d4 * 180 / Math.PI;
|
|
242847
|
+
const lat1 = toRad(a3.lat);
|
|
242848
|
+
const lat2 = toRad(b5.lat);
|
|
242849
|
+
const dLng = toRad(b5.lng - a3.lng);
|
|
242850
|
+
const y7 = Math.sin(dLng) * Math.cos(lat2);
|
|
242851
|
+
const x7 = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLng);
|
|
242852
|
+
return (toDeg(Math.atan2(y7, x7)) + 360) % 360;
|
|
242540
242853
|
}
|
|
242541
242854
|
function getCurrentStep(leg, currentInSecond) {
|
|
242542
242855
|
let elapsedInSeconds = 0;
|
|
@@ -257754,8 +258067,41 @@ var mapWaypoint = external_exports.object({
|
|
|
257754
258067
|
label: external_exports.string().optional(),
|
|
257755
258068
|
media: external_exports.string().optional().describe("image/video src for waypoint marker")
|
|
257756
258069
|
});
|
|
258070
|
+
var tweenSpec = external_exports.object({
|
|
258071
|
+
__tween: external_exports.array(external_exports.union([external_exports.number(), external_exports.string()]))
|
|
258072
|
+
});
|
|
258073
|
+
var tweenableNumber = external_exports.union([external_exports.number(), tweenSpec]);
|
|
258074
|
+
var mapCamera = external_exports.object({
|
|
258075
|
+
zoom: tweenableNumber.optional(),
|
|
258076
|
+
center: external_exports.object({ lat: tweenableNumber, lng: tweenableNumber }).optional(),
|
|
258077
|
+
heading: tweenableNumber.optional(),
|
|
258078
|
+
tilt: tweenableNumber.optional()
|
|
258079
|
+
});
|
|
258080
|
+
var mapCinematic = external_exports.object({
|
|
258081
|
+
mode: external_exports.enum(["flyAlong", "flyTo", "orbit"]).optional().describe("camera move; default flyAlong"),
|
|
258082
|
+
followRoute: external_exports.boolean().optional().describe("center follows the animated marker; default true"),
|
|
258083
|
+
headingFollow: external_exports.boolean().optional().describe("heading = route bearing (forward is up); default true"),
|
|
258084
|
+
tilt: tweenableNumber.optional().describe("0 = top-down reveal, 45 = chase; tween(0,45) = tilt reveal; default 45"),
|
|
258085
|
+
range: tweenableNumber.optional().describe("3D camera distance (m); tween(8000,300) = fly-to"),
|
|
258086
|
+
altitude: external_exports.number().optional().describe("3D center altitude (m)"),
|
|
258087
|
+
roll: tweenableNumber.optional().describe("3D bank (deg); default 0"),
|
|
258088
|
+
fallback: external_exports.enum(["2d", "none"]).optional().describe("'2d' renders safe 2D chase; 'none' opts into experimental Map3D; default '2d'")
|
|
258089
|
+
});
|
|
258090
|
+
var mapStreetView = external_exports.object({
|
|
258091
|
+
pano: external_exports.string().optional().describe("explicit panorama id (deterministic)"),
|
|
258092
|
+
location: external_exports.object({ lat: external_exports.number(), lng: external_exports.number() }).optional().describe("else nearest-pano search"),
|
|
258093
|
+
route: external_exports.array(external_exports.object({ lat: external_exports.number(), lng: external_exports.number() })).optional().describe("walk/drive path (nearest pano per stop)"),
|
|
258094
|
+
radius: external_exports.number().optional().describe("nearest-pano search radius (m); default 50"),
|
|
258095
|
+
source: external_exports.enum(["default", "outdoor", "indoor"]).optional().describe("default 'default'"),
|
|
258096
|
+
pov: external_exports.object({
|
|
258097
|
+
heading: tweenableNumber.optional().describe("tween(200,320) = pan"),
|
|
258098
|
+
pitch: tweenableNumber.optional().describe("tween(0,-10) = tilt sweep")
|
|
258099
|
+
}).optional(),
|
|
258100
|
+
zoom: tweenableNumber.optional().describe("street view field-of-view zoom; tween(0,1) = dolly-zoom feel")
|
|
258101
|
+
});
|
|
257757
258102
|
var mapStream = base.extend({
|
|
257758
258103
|
type: external_exports.literal("map").default("map"),
|
|
258104
|
+
view: external_exports.enum(["overview", "route", "cinematic", "streetview"]).default("route").describe("camera experience: static/dolly overview, animated route, cinematic flyover, immersive street view"),
|
|
257759
258105
|
waypoints: external_exports.array(mapWaypoint).default(() => []),
|
|
257760
258106
|
routeColor: external_exports.string().default("#4285F4"),
|
|
257761
258107
|
routeWeight: external_exports.number().default(4),
|
|
@@ -257766,6 +258112,9 @@ var mapStream = base.extend({
|
|
|
257766
258112
|
region: external_exports.string().optional().describe("Google Maps region code, e.g. CN"),
|
|
257767
258113
|
travelMode: external_exports.enum(["DRIVING", "WALKING", "BICYCLING", "TRANSIT"]).default("DRIVING").describe("Directions API travel mode"),
|
|
257768
258114
|
routeMarker: external_exports.string().default("\u{1F697}").describe("emoji/character for the animated traveling marker"),
|
|
258115
|
+
camera: mapCamera.optional().describe("generic camera tween (dolly/pan/tilt)"),
|
|
258116
|
+
cinematic: mapCinematic.optional().describe("cinematic camera behavior"),
|
|
258117
|
+
streetView: mapStreetView.optional().describe("immersive street view config"),
|
|
257769
258118
|
googleMapsApiKey: external_exports.string().optional().describe("injected by compiler from GOOGLE_MAPS_API_KEY env var")
|
|
257770
258119
|
});
|
|
257771
258120
|
var stream2 = external_exports.discriminatedUnion("type", [
|