Skip to content
This repository has been archived by the owner on Apr 25, 2023. It is now read-only.

Commit

Permalink
fix: camera flight bugs (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
rot1024 committed Oct 5, 2021
1 parent 2c3eaab commit b4f1ae2
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 10 deletions.
9 changes: 6 additions & 3 deletions src/components/molecules/Visualizer/Engine/Cesium/hooks.ts
Expand Up @@ -102,20 +102,23 @@ export default ({
}, []);

// call onCameraChange event after moving camera
const emittedCamera = useRef<Camera>();
const handleCameraMoveEnd = useCallback(() => {
const viewer = cesium?.current?.cesiumElement;
if (!viewer || viewer.isDestroyed()) return;
if (!viewer || viewer.isDestroyed() || !onCameraChange) return;

const c = getCamera(viewer);
if (c && !isEqual(c, camera)) {
onCameraChange?.(c);
emittedCamera.current = c;
onCameraChange(c);
}
}, [onCameraChange, camera]);

// camera
useEffect(() => {
if (camera) {
if (camera && (!emittedCamera.current || emittedCamera.current !== camera)) {
engineAPI.flyTo(camera, { duration: 0 });
emittedCamera.current = undefined;
}
}, [camera, engineAPI]);

Expand Down
17 changes: 14 additions & 3 deletions src/components/molecules/Visualizer/Engine/Cesium/useEngineRef.ts
@@ -1,5 +1,5 @@
import * as Cesium from "cesium";
import { useImperativeHandle, Ref, RefObject, useMemo } from "react";
import { useImperativeHandle, Ref, RefObject, useMemo, useRef } from "react";
import type { CesiumComponentRef } from "resium";

import { delayedObject, merge } from "@reearth/util/object";
Expand All @@ -22,6 +22,7 @@ export default function useEngineRef(
ref: Ref<EngineRef>,
cesium: RefObject<CesiumComponentRef<Cesium.Viewer>>,
): EngineRef {
const cancelCameraFlight = useRef<() => void>();
const e = useMemo((): EngineRef => {
const api = merge(exposed, {
get viewer(): Cesium.Viewer | undefined {
Expand Down Expand Up @@ -55,12 +56,22 @@ export default function useEngineRef(
flyTo: (camera, options) => {
const viewer = cesium.current?.cesiumElement;
if (!viewer || viewer.isDestroyed()) return;
flyTo(viewer.scene?.camera, { ...getCamera(viewer), ...camera }, options);
cancelCameraFlight.current?.();
cancelCameraFlight.current = flyTo(
viewer.scene?.camera,
{ ...getCamera(viewer), ...camera },
options,
);
},
lookAt: (camera, options) => {
const viewer = cesium.current?.cesiumElement;
if (!viewer || viewer.isDestroyed()) return;
lookAt(viewer.scene?.camera, { ...getCamera(viewer), ...camera }, options);
cancelCameraFlight.current?.();
cancelCameraFlight.current = lookAt(
viewer.scene?.camera,
{ ...getCamera(viewer), ...camera },
options,
);
},
zoomIn: amount => {
const viewer = cesium.current?.cesiumElement;
Expand Down
37 changes: 33 additions & 4 deletions src/components/molecules/Visualizer/Widget/Storytelling/hooks.ts
@@ -1,10 +1,11 @@
import { Math as CesiumMath } from "cesium";
import { useState, useCallback, useEffect, useMemo } from "react";
import { useState, useCallback, useEffect, useMemo, useRef } from "react";

import { Camera as CameraValue } from "@reearth/util/value";

import { useContext } from "../../Plugin";
import type { Layer } from "../../Plugin";
import type { CommonReearth } from "../../Plugin/api";

export type Story = {
title: string;
Expand Down Expand Up @@ -53,13 +54,41 @@ export default function ({
}>();

const { reearth } = useContext() ?? {};
const { lookAt, flyTo } = reearth?.visualizer.camera ?? {};
const {
findById: findLayerById,
selected: selectedLayer,
select: selectLayer,
} = reearth?.layers ?? {};

const timeout = useRef<number>();

const flyTo = useCallback(
(...args: Parameters<CommonReearth["visualizer"]["camera"]["lookAt"]>) => {
// Prioritize camera flight by the photo overlay
timeout.current = window.setTimeout(() => {
reearth?.visualizer.camera.flyTo(...args);
}, 100);
},
[reearth?.visualizer.camera],
);

const lookAt = useCallback(
(...args: Parameters<CommonReearth["visualizer"]["camera"]["lookAt"]>) => {
// Prioritize camera flight by the photo overlay
timeout.current = window.setTimeout(() => {
reearth?.visualizer.camera.lookAt(...args);
}, 100);
},
[reearth?.visualizer.camera],
);

useEffect(
() => () => {
window.clearTimeout(timeout.current);
},
[],
);

const stories = useMemo<Story[]>(() => {
if (!storiesData || !findLayerById) return [];
return storiesData.map(story => ({
Expand Down Expand Up @@ -133,7 +162,7 @@ export default function ({
}

if (selected.story.layerCamera) {
flyTo?.(selected.story.layerCamera, {
flyTo(selected.story.layerCamera, {
duration: selected.story.layerDuration ?? selected.duration,
});
return;
Expand All @@ -149,7 +178,7 @@ export default function ({

if (typeof position.lat !== "number" && typeof position.lng !== "number") return;

lookAt?.(
lookAt(
{
...position,
heading: selected.camera.heading,
Expand Down

0 comments on commit b4f1ae2

Please sign in to comment.