diff --git a/src/components/organisms/EarthEditor/core/CanvasArea/convert.ts b/src/components/organisms/EarthEditor/core/CanvasArea/convert.ts index 6e60afbc70..77eaba5587 100644 --- a/src/components/organisms/EarthEditor/core/CanvasArea/convert.ts +++ b/src/components/organisms/EarthEditor/core/CanvasArea/convert.ts @@ -167,7 +167,7 @@ export const convertWidgets = ( floatingWidgets: InternalWidget[]; alignSystem: WidgetAlignSystem; layoutConstraint: { [w in string]: WidgetLayoutConstraint } | undefined; - ownBuiltinWidgets: { [K in keyof BuiltinWidgets]?: BuiltinWidgets[K] }; + ownBuiltinWidgets: (keyof BuiltinWidgets)[]; } | undefined => { if (!data || !data.node || data.node.__typename !== "Scene" || !data.node.widgetAlignSystem) { @@ -258,17 +258,10 @@ export const convertWidgets = ( }; }; - const ownBuiltinWidgets = data.node.widgets.reduce<{ - [K in keyof BuiltinWidgets]?: BuiltinWidgets[K]; - }>((res, next) => { + const ownBuiltinWidgets = data.node.widgets.reduce<(keyof BuiltinWidgets)[]>((res, next) => { const id = `${next.pluginId}/${next.extensionId}`; - return isBuiltinWidget(id) - ? { - ...res, - [id]: true, - } - : res; - }, {}); + return isBuiltinWidget(id) && next.enabled ? [...res, id] : res; + }, []); return { floatingWidgets, diff --git a/src/components/organisms/EarthEditor/core/CanvasArea/index.tsx b/src/components/organisms/EarthEditor/core/CanvasArea/index.tsx index 93c9c061d2..6d62c751d1 100644 --- a/src/components/organisms/EarthEditor/core/CanvasArea/index.tsx +++ b/src/components/organisms/EarthEditor/core/CanvasArea/index.tsx @@ -67,6 +67,7 @@ const CanvasArea: React.FC = ({ isBuilt, inEditor }) => { widgetAlignSystem={widgets?.alignSystem} floatingWidgets={widgets?.floatingWidgets} widgetLayoutConstraint={widgets?.layoutConstraint} + ownBuiltinWidgets={widgets?.ownBuiltinWidgets} selectedLayerId={selectedLayerId} selectedBlockId={selectedBlockId} selectedWidgetArea={selectedWidgetArea} diff --git a/src/core/Crust/Widgets/Widget/builtin.ts b/src/core/Crust/Widgets/Widget/builtin.ts index a23b381ce1..0918aed4f5 100644 --- a/src/core/Crust/Widgets/Widget/builtin.ts +++ b/src/core/Crust/Widgets/Widget/builtin.ts @@ -24,17 +24,24 @@ export type BuiltinWidgets = Record< T >; -const BUILTIN_WIDGET_ID_LIST: BuiltinWidgets = { - [MENU_BUILTIN_WIDGET_ID]: true, - [BUTTON_BUILTIN_WIDGET_ID]: true, - [SPLASHSCREEN_BUILTIN_WIDGET_ID]: true, - [STORYTELLING_BUILTIN_WIDGET_ID]: true, - [TIMELINE_BUILTIN_WIDGET_ID]: true, - [NAVIGATOR_BUILTIN_WIDGET_ID]: true, +const BUILTIN_WIDGET_OPTIONS: BuiltinWidgets<{ animation?: boolean }> = { + [MENU_BUILTIN_WIDGET_ID]: {}, + [BUTTON_BUILTIN_WIDGET_ID]: {}, + [SPLASHSCREEN_BUILTIN_WIDGET_ID]: {}, + [STORYTELLING_BUILTIN_WIDGET_ID]: {}, + [TIMELINE_BUILTIN_WIDGET_ID]: { + animation: true, + }, + [NAVIGATOR_BUILTIN_WIDGET_ID]: { + animation: true, + }, }; +export const getBuiltinWidgetOptions = (id: string) => + BUILTIN_WIDGET_OPTIONS[id as keyof BuiltinWidgets]; + export const isBuiltinWidget = (id: string): id is keyof BuiltinWidgets => - !!BUILTIN_WIDGET_ID_LIST[id as keyof BuiltinWidgets]; + !!builtin[id as keyof BuiltinWidgets]; const builtin: BuiltinWidgets = { [MENU_BUILTIN_WIDGET_ID]: Menu, diff --git a/src/core/Crust/Widgets/Widget/index.tsx b/src/core/Crust/Widgets/Widget/index.tsx index a375accae7..21a18a3a09 100644 --- a/src/core/Crust/Widgets/Widget/index.tsx +++ b/src/core/Crust/Widgets/Widget/index.tsx @@ -16,7 +16,7 @@ import type { } from "./types"; export type { WidgetLayout } from "../types"; -export { isBuiltinWidget, type BuiltinWidgets } from "./builtin"; +export { isBuiltinWidget, type BuiltinWidgets, getBuiltinWidgetOptions } from "./builtin"; export type Props = { widget: InternalWidget; diff --git a/src/core/Visualizer/hooks.ts b/src/core/Visualizer/hooks.ts index 1ec2bb9a7a..6e162d9de7 100644 --- a/src/core/Visualizer/hooks.ts +++ b/src/core/Visualizer/hooks.ts @@ -3,7 +3,8 @@ import { useWindowSize } from "react-use"; import { type DropOptions, useDrop } from "@reearth/util/use-dnd"; -import type { Block } from "../Crust"; +import type { Block, BuiltinWidgets } from "../Crust"; +import { getBuiltinWidgetOptions } from "../Crust/Widgets/Widget"; import type { ComputedFeature, Feature } from "../mantle"; import type { Ref as MapRef, @@ -27,6 +28,7 @@ export default function useHooks({ isEditable, rootLayerId, zoomedLayerId, + ownBuiltinWidgets, onLayerSelect, onBlockSelect, onCameraChange, @@ -38,6 +40,7 @@ export default function useHooks({ rootLayerId?: string; sceneProperty?: SceneProperty; zoomedLayerId?: string; + ownBuiltinWidgets?: (keyof BuiltinWidgets)[]; onLayerSelect?: ( layerId: string | undefined, featureId: string | undefined, @@ -159,6 +162,14 @@ export default function useHooks({ } }, [zoomedLayerId, onZoomToLayer]); + // shouldRender + const shouldRender = useMemo(() => { + const shouldWidgetAnimate = ownBuiltinWidgets?.some( + id => !!getBuiltinWidgetOptions(id).animation, + ); + return shouldWidgetAnimate; + }, [ownBuiltinWidgets]); + return { mapRef, wrapperRef, @@ -172,6 +183,7 @@ export default function useHooks({ overriddenSceneProperty, isDroppable, infobox, + shouldRender, handleLayerSelect, handleBlockSelect: selectBlock, handleCameraChange: changeCamera, diff --git a/src/core/Visualizer/index.tsx b/src/core/Visualizer/index.tsx index ac4770ab9f..f44e043783 100644 --- a/src/core/Visualizer/index.tsx +++ b/src/core/Visualizer/index.tsx @@ -12,6 +12,7 @@ import Crust, { type ExternalPluginProps, type InternalWidget, WidgetAreaType, + BuiltinWidgets, } from "../Crust"; import { Tag } from "../mantle"; import Map, { @@ -48,6 +49,7 @@ export type Props = { rootLayerId?: string; widgetAlignSystem?: WidgetAlignSystem; widgetLayoutConstraint?: { [w: string]: WidgetLayoutConstraint }; + ownBuiltinWidgets?: (keyof BuiltinWidgets)[]; widgetAlignSystemEditing?: boolean; floatingWidgets?: InternalWidget[]; sceneProperty?: SceneProperty; @@ -118,6 +120,7 @@ export default function Visualizer({ widgetAlignSystemEditing, widgetLayoutConstraint, floatingWidgets, + ownBuiltinWidgets, small, ready, tags, @@ -163,6 +166,7 @@ export default function Visualizer({ overriddenSceneProperty, isDroppable, infobox, + shouldRender, handleLayerSelect, handleBlockSelect, handleCameraChange, @@ -176,6 +180,7 @@ export default function Visualizer({ selectedBlockId, sceneProperty, zoomedLayerId, + ownBuiltinWidgets, onLayerSelect, onBlockSelect, onCameraChange, @@ -239,6 +244,7 @@ export default function Visualizer({ isLayerDragging={isLayerDragging} meta={meta} style={style} + shouldRender={shouldRender} // overrides={overrides} // not used for now property={overriddenSceneProperty} selectedLayerId={selectedLayerId}