Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(web): add timeline manager #718

Merged
merged 23 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
317fbe4
wip: timeline manager
airslice Sep 13, 2023
f9c4248
Merge branch 'main' into chore/add-timeline-manager
airslice Sep 15, 2023
0b0a93a
Merge branch 'main' into chore/add-timeline-manager
airslice Sep 25, 2023
581bac7
Merge branch 'main' into chore/add-timeline-manager
airslice Sep 27, 2023
4fb104b
wip
airslice Sep 29, 2023
13e78a2
Merge branch 'main' into chore/add-timeline-manager
airslice Oct 2, 2023
e5617e7
feat: wip
airslice Oct 3, 2023
90d4ad1
Merge branch 'main' into chore/add-timeline-manager
airslice Oct 3, 2023
c725945
refactor: rename & clean up
airslice Oct 4, 2023
3c0ffc3
refactor: rename & clean up
airslice Oct 4, 2023
cf40c00
refactor: remove unnecessary get
airslice Oct 4, 2023
2d8165f
refactor: add stepType and rangeType to API
airslice Oct 4, 2023
906418d
Merge branch 'main' into chore/add-timeline-manager
airslice Oct 4, 2023
ff3decc
refactor: scene property override & plugin API
airslice Oct 4, 2023
585ff51
refactor: add timelineManagerRef to MapRef
airslice Oct 4, 2023
afce984
refactor: use timelineManagerRef
airslice Oct 5, 2023
b8fb997
Merge branch 'main' into chore/add-timeline-manager
airslice Oct 5, 2023
90ec5fe
refactor: add source type
airslice Oct 5, 2023
8ee6db2
refactor: type
airslice Oct 5, 2023
bf84435
Merge branch 'main' into chore/add-timeline-manager
airslice Oct 5, 2023
4c033ce
Merge branch 'main' into chore/add-timeline-manager
airslice Oct 10, 2023
f8e0ece
Merge branch 'main' into chore/add-timeline-manager
airslice Oct 11, 2023
cf3772d
Merge branch 'main' into chore/add-timeline-manager
airslice Oct 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading