Skip to content

Commit

Permalink
chore(web): add timeline manager (#718)
Browse files Browse the repository at this point in the history
  • Loading branch information
airslice authored Oct 11, 2023
1 parent 8fea370 commit d4127b7
Show file tree
Hide file tree
Showing 24 changed files with 695 additions and 206 deletions.
3 changes: 3 additions & 0 deletions web/src/beta/lib/core/Crust/Plugins/Plugin/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ export function useAPI({
"tick",
"resize",
"layeredit",
"timelinecommit",
]);
}

Expand Down Expand Up @@ -424,12 +425,14 @@ export function useAPI({
moveWidget: onWidgetMove,
pluginPostMessage: ctx.pluginInstances.postMessage,
clientStorage: ctx.clientStorage,
timelineManagerRef: ctx.timelineManagerRef,
});
};
}, [
ctx?.reearth,
ctx?.pluginInstances,
ctx?.clientStorage,
ctx?.timelineManagerRef,
ctx?.overrideSceneProperty,
extensionId,
extensionType,
Expand Down
100 changes: 100 additions & 0 deletions web/src/beta/lib/core/Crust/Plugins/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Tag } from "@reearth/beta/lib/core/mantle/compat";
import { Events, Layer, LayersRef, NaiveLayer, LazyLayer } from "@reearth/beta/lib/core/Map";
import { merge } from "@reearth/beta/utils/object";

import { TimelineManagerRef } from "../../Map/useTimelineManager";
import type { Block } from "../Infobox";
import type { MapRef } from "../types";
import type { Widget, WidgetLocationOptions } from "../Widgets";
Expand Down Expand Up @@ -47,6 +48,7 @@ export function exposed({
moveWidget,
pluginPostMessage,
clientStorage,
timelineManagerRef,
}: {
render: (
html: string,
Expand Down Expand Up @@ -86,6 +88,7 @@ export function exposed({
moveWidget?: (widgetId: string, options: WidgetLocationOptions) => void;
pluginPostMessage: (extentionId: string, msg: any, sender: string) => void;
clientStorage: ClientStorage;
timelineManagerRef?: TimelineManagerRef;
}): GlobalThis {
return merge({
console: {
Expand Down Expand Up @@ -167,6 +170,103 @@ export function exposed({
};
},
}),
clock: merge(commonReearth.clock, {
get play() {
return () => {
timelineManagerRef?.current?.commit({
cmd: "PLAY",
committer: {
source: "pluginAPI",
id:
(plugin?.extensionType === "widget"
? widget?.()?.id
: plugin?.extensionType === "block"
? block?.()?.id
: "") ?? "",
},
});
};
},
get pause() {
return () =>
timelineManagerRef?.current?.commit({
cmd: "PAUSE",
committer: {
source: "pluginAPI",
id:
(plugin?.extensionType === "widget"
? widget?.()?.id
: plugin?.extensionType === "block"
? block?.()?.id
: "") ?? "",
},
});
},
get setTime() {
return (time: { start: Date | string; stop: Date | string; current: Date | string }) =>
timelineManagerRef?.current?.commit({
cmd: "SET_TIME",
payload: { ...time },
committer: {
source: "pluginAPI",
id:
(plugin?.extensionType === "widget"
? widget?.()?.id
: plugin?.extensionType === "block"
? block?.()?.id
: "") ?? "",
},
});
},
get setSpeed() {
return (speed: number) =>
timelineManagerRef?.current?.commit({
cmd: "SET_OPTIONS",
payload: { multiplier: speed },
committer: {
source: "pluginAPI",
id:
(plugin?.extensionType === "widget"
? widget?.()?.id
: plugin?.extensionType === "block"
? block?.()?.id
: "") ?? "",
},
});
},
get setStepType() {
return (stepType: "fixed" | "rate") =>
timelineManagerRef?.current?.commit({
cmd: "SET_OPTIONS",
payload: { stepType },
committer: {
source: "pluginAPI",
id:
(plugin?.extensionType === "widget"
? widget?.()?.id
: plugin?.extensionType === "block"
? block?.()?.id
: "") ?? "",
},
});
},
get setRangeType() {
return (rangeType: "unbounded" | "clamped" | "bounced") =>
timelineManagerRef?.current?.commit({
cmd: "SET_OPTIONS",
payload: { rangeType },
committer: {
source: "pluginAPI",
id:
(plugin?.extensionType === "widget"
? widget?.()?.id
: plugin?.extensionType === "block"
? block?.()?.id
: "") ?? "",
},
});
},
}),
plugin: {
get id() {
return plugin?.id;
Expand Down
99 changes: 84 additions & 15 deletions web/src/beta/lib/core/Crust/Plugins/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
type TickEventCallback,
} from "@reearth/beta/lib/core/Map";

import { TimelineCommitter } from "../../Map/useTimelineManager";
import { CameraOptions, FlyTo, FlyToDestination, LookAtDestination } from "../../types";

import { commonReearth } from "./api";
Expand All @@ -20,7 +21,7 @@ import usePluginInstances from "./usePluginInstances";

export type SelectedReearthEventType = Pick<
ReearthEventType,
"cameramove" | "select" | "tick" | "resize" | keyof MouseEvents | "layeredit"
"cameramove" | "select" | "tick" | "timelinecommit" | "resize" | keyof MouseEvents | "layeredit"
>;

export default function ({
Expand All @@ -38,6 +39,7 @@ export default function ({
floatingWidgets,
camera,
interactionMode,
timelineManagerRef,
overrideInteractionMode,
useExperimentalSandbox,
overrideSceneProperty,
Expand All @@ -62,19 +64,74 @@ export default function ({
const getTags = useGet(tags ?? []);
const getCamera = useGet(camera);
const getClock = useCallback(() => {
const clock = engineRef?.getClock();
return {
startTime: clock?.start,
stopTime: clock?.stop,
currentTime: clock?.current,
playing: clock?.playing,
paused: !clock?.playing,
speed: clock?.speed,
play: engineRef?.play,
pause: engineRef?.pause,
tick: engineRef?.tick,
get startTime() {
return timelineManagerRef?.current?.timeline?.start;
},
get stopTime() {
return timelineManagerRef?.current?.timeline?.stop;
},
get currentTime() {
return timelineManagerRef?.current?.timeline?.current;
},
get playing() {
return !!timelineManagerRef?.current?.options?.animation;
},
get paused() {
return !timelineManagerRef?.current?.options?.animation;
},
get speed() {
return timelineManagerRef?.current?.options?.multiplier;
},
get stepType() {
return timelineManagerRef?.current?.options?.stepType;
},
get rangeType() {
return timelineManagerRef?.current?.options?.rangeType;
},
play: () => {
timelineManagerRef?.current?.commit({
cmd: "PLAY",
committer: { source: "pluginAPI", id: "window" },
});
},
pause: () => {
timelineManagerRef?.current?.commit({
cmd: "PAUSE",
committer: { source: "pluginAPI", id: "window" },
});
},
setTime: (time: { start: Date | string; stop: Date | string; current: Date | string }) => {
timelineManagerRef?.current?.commit({
cmd: "SET_TIME",
payload: { ...time },
committer: { source: "pluginAPI", id: "window" },
});
},
setSpeed: (speed: number) => {
timelineManagerRef?.current?.commit({
cmd: "SET_OPTIONS",
payload: { multiplier: speed },
committer: { source: "pluginAPI", id: "window" },
});
},
setStepType: (stepType: "rate" | "fixed") => {
timelineManagerRef?.current?.commit({
cmd: "SET_OPTIONS",
payload: { stepType },
committer: { source: "pluginAPI", id: "window" },
});
},
setRangeType: (rangeType: "unbounded" | "clamped" | "bounced") => {
timelineManagerRef?.current?.commit({
cmd: "SET_OPTIONS",
payload: { rangeType },
committer: { source: "pluginAPI", id: "window" },
});
},
tick: timelineManagerRef?.current?.tick,
};
}, [engineRef]);
}, [timelineManagerRef]);
const getInteractionMode = useGet(
useMemo<InteractionMode>(
() => ({ mode: interactionMode, override: overrideInteractionMode }),
Expand Down Expand Up @@ -370,6 +427,7 @@ export default function ({
overrideSceneProperty,
pluginInstances,
clientStorage,
timelineManagerRef,
useExperimentalSandbox,
}),
[
Expand Down Expand Up @@ -421,6 +479,7 @@ export default function ({
overrideSceneProperty,
pluginInstances,
clientStorage,
timelineManagerRef,
useExperimentalSandbox,
findFeatureById,
findFeaturesByIds,
Expand Down Expand Up @@ -461,9 +520,16 @@ export default function ({

const onTickEvent = useCallback(
(fn: TickEventCallback) => {
mapRef?.current?.engine.onTick?.(fn);
timelineManagerRef?.current?.onTick(fn);
},
[mapRef],
[timelineManagerRef],
);

const onTimelineCommitEvent = useCallback(
(fn: (committer: TimelineCommitter) => void) => {
timelineManagerRef?.current?.onCommit(fn);
},
[timelineManagerRef],
);

useEffect(() => {
Expand Down Expand Up @@ -496,7 +562,10 @@ export default function ({
onTickEvent(e => {
emit("tick", e);
});
}, [emit, onMouseEvent, onLayerEdit, onTickEvent]);
onTimelineCommitEvent(e => {
emit("timelinecommit", e);
});
}, [emit, onMouseEvent, onLayerEdit, onTickEvent, onTimelineCommitEvent]);

// expose plugin API for developers
useEffect(() => {
Expand Down
12 changes: 12 additions & 0 deletions web/src/beta/lib/core/Crust/Plugins/plugin_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
Feature,
} from "@reearth/beta/lib/core/Map";

import { TimelineCommitter } from "../../Map/useTimelineManager";
import { CameraOptions, FlyToDestination, LookAtDestination } from "../../types";
import { Block } from "../Infobox";
import { InteractionModeType } from "../types";
Expand Down Expand Up @@ -181,9 +182,19 @@ export type Clock = {
paused?: boolean;
/** Speed of time. Specifies a multiplier for the speed of time in reality. Default is 1. */
speed?: number;
stepType?: "rate" | "fixed";
rangeType?: "unbounded" | "clamped" | "bounced";
readonly tick?: () => Date | void;
readonly play?: () => void;
readonly pause?: () => void;
readonly setTime?: (time: {
start: Date | string;
stop: Date | string;
current: Date | string;
}) => void;
readonly setSpeed?: (speed: number) => void;
readonly setRangeType?: (rangeType: "unbounded" | "clamped" | "bounced") => void;
readonly setStepType?: (stepType: "rate" | "fixed") => void;
};

export type InteractionMode = {
Expand Down Expand Up @@ -218,6 +229,7 @@ export type ReearthEventType = {
mouseleave: [props: MouseEvent];
wheel: [props: MouseEvent];
tick: [props: Date];
timelinecommit: [props: TimelineCommitter];
resize: [props: ViewportSize];
modalclose: [];
popupclose: [];
Expand Down
3 changes: 3 additions & 0 deletions web/src/beta/lib/core/Crust/Plugins/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
} from "@reearth/beta/lib/core/Map";
import type { Viewport } from "@reearth/beta/lib/core/Visualizer";

import { TimelineManagerRef } from "../../Map/useTimelineManager";
import type { MapRef, InteractionModeType } from "../types";
import type { InternalWidget, WidgetAlignSystem } from "../Widgets";

Expand All @@ -35,6 +36,7 @@ export type Props = PropsWithChildren<{
alignSystem?: WidgetAlignSystem;
floatingWidgets?: InternalWidget[];
useExperimentalSandbox?: boolean;
timelineManagerRef?: TimelineManagerRef;
overrideSceneProperty: (id: string, property: any) => void;
camera?: Camera;
interactionMode: InteractionModeType;
Expand All @@ -46,6 +48,7 @@ export type Context = {
reearth: CommonReearth;
pluginInstances: PluginInstances;
clientStorage: ClientStorage;
timelineManagerRef?: TimelineManagerRef;
useExperimentalSandbox?: boolean;
overrideSceneProperty: (id: string, property: any) => void;
};
Loading

0 comments on commit d4127b7

Please sign in to comment.