Skip to content

Commit

Permalink
Merge pull request #249 from ubilabs/develop
Browse files Browse the repository at this point in the history
merge develop into master
  • Loading branch information
pwambach authored Dec 9, 2019
2 parents 849328e + eb535ca commit c9fdf3f
Show file tree
Hide file tree
Showing 17 changed files with 123 additions and 89 deletions.
7 changes: 5 additions & 2 deletions src/scripts/actions/set-globe-projection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ export const SET_GLOBE_PROJECTION = 'SET_GLOBE_PROJECTION';
export interface SetGlobeProjectionAction {
type: typeof SET_GLOBE_PROJECTION;
projection: GlobeProjection;
morphTime: number;
}

const setGlobeProjectionAction = (
projection: GlobeProjection
projection: GlobeProjection,
morphTime: number
): SetGlobeProjectionAction => ({
type: SET_GLOBE_PROJECTION,
projection
projection,
morphTime
});

export default setGlobeProjectionAction;
2 changes: 2 additions & 0 deletions src/scripts/components/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Story from '../story/story';
import UrlSync from '../url-sync/url-sync';
import LayerLoader from '../layer-loader/layer-loader';
import TimeSlider from '../time-slider/time-slider';
import DataSetInfo from '../data-set-info/data-set-info';
import Init from '../init/init';

import translations from '../../i18n';
Expand Down Expand Up @@ -51,6 +52,7 @@ const TranslatedApp: FunctionComponent = () => {
<Route
path={['/layers/:mainLayerId?/:compareLayerId?', '/']}
exact>
<DataSetInfo />
<TimeSlider />
<StoriesButton />
<div className={styles.nav}>
Expand Down
11 changes: 6 additions & 5 deletions src/scripts/components/data-set-info/data-set-info.styl
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
.dataSetInfo
position: absolute
top: 5px
z-index: 1
display: flex
flex-direction: column
flex-direction: row
width: 100%

.dataSetContent
top: 5px
width: 100%
text-align: center

Expand All @@ -18,5 +20,4 @@

.buttons
display: flex
flex-direction: row
align-self: center
justify-content: center
35 changes: 29 additions & 6 deletions src/scripts/components/data-set-info/data-set-info.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,47 @@
import React, {FunctionComponent} from 'react';
import RemoveCompare from '../remove-compare/remove-compare';
import {useParams} from 'react-router-dom';
import {useSelector} from 'react-redux';

import InfoButton from '../info-button/info-button';
import {State} from '../../reducers';
import {layerListItemSelector} from '../../selectors/layers/list-item';
import RemoveCompare from '../remove-compare/remove-compare';

import styles from './data-set-info.styl';
import {LayerListItem} from '../../types/layer-list';

import styles from './data-set-info.styl';

interface Props {
isMain?: boolean;
layer: LayerListItem | null;
isCompare?: boolean;
}

const DataSetInfo: FunctionComponent<Props> = ({layer, isMain}) => (
<div className={styles.dataSetInfo}>
const DataSetContent: FunctionComponent<Props> = ({layer, isCompare}) => (
<div className={styles.dataSetContent}>
<h1 className={styles.title}>{layer?.name}</h1>
<h2 className={styles.description}>{layer?.description}</h2>
<div className={styles.buttons}>
<InfoButton layer={layer} />
{!isMain && <RemoveCompare />}
{isCompare && <RemoveCompare />}
</div>
</div>
);

const DataSetInfo: FunctionComponent = () => {
const {mainLayerId, compareLayerId} = useParams();
const mainLayer = useSelector((state: State) =>
layerListItemSelector(state, mainLayerId)
);
const compareLayer = useSelector((state: State) =>
layerListItemSelector(state, compareLayerId)
);

return (
<div className={styles.dataSetInfo}>
<DataSetContent layer={mainLayer} />
{compareLayer && <DataSetContent layer={compareLayer} isCompare />}
</div>
);
};

export default DataSetInfo;
52 changes: 29 additions & 23 deletions src/scripts/components/globe/globe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ import {
flyToGlobeView
} from '../../libs/get-globe-view';

import DataSetInfo from '../data-set-info/data-set-info';

import {GlobeView} from '../../types/globe-view';
import {GlobeProjection} from '../../types/globe-projection';

import 'cesium/Source/Widgets/widgets.css';
import 'cesium/Build/Cesium/Cesium';

import {LayerListItem} from '../../types/layer-list';
import {GlobeProjectionState} from '../../types/globe-projection-state';

import styles from './globe.styl';

Expand Down Expand Up @@ -46,11 +44,9 @@ const cesiumOptions = {

interface Props {
active: boolean;
layer: LayerListItem | null;
isMain?: boolean;
layerType?: string;
view: GlobeView;
projection: GlobeProjection;
projectionState: GlobeProjectionState;
imageUrl: string | null;
flyTo: GlobeView | null;
onMouseEnter: () => void;
Expand All @@ -60,12 +56,10 @@ interface Props {

const Globe: FunctionComponent<Props> = ({
view,
projection,
projectionState,
imageUrl,
active,
layer,
layerType,
isMain,
flyTo,
onMouseEnter,
onChange,
Expand All @@ -86,7 +80,7 @@ const Globe: FunctionComponent<Props> = ({

// set correct scene mode
const sceneMode =
projection === GlobeProjection.Sphere
projectionState.projection === GlobeProjection.Sphere
? Cesium.SceneMode.SCENE3D
: Cesium.SceneMode.SCENE2D;

Expand Down Expand Up @@ -154,10 +148,10 @@ const Globe: FunctionComponent<Props> = ({
return;
}

projection === GlobeProjection.Sphere
? viewer.scene.morphTo3D()
: viewer.scene.morphTo2D();
}, [viewer, projection]);
projectionState.projection === GlobeProjection.Sphere
? viewer.scene.morphTo3D(projectionState.morphTime)
: viewer.scene.morphTo2D(projectionState.morphTime);
}, [viewer, projectionState]);

// update position and distance when view changes
useEffect(() => {
Expand All @@ -181,7 +175,7 @@ const Globe: FunctionComponent<Props> = ({

const url = imageUrl;
const layers = viewer.scene.imageryLayers;
const oldLayer = layers.length > 1 && layers.get(1);

if (url) {
const imageProvider =
layerType === 'tiles'
Expand All @@ -206,14 +200,24 @@ const Globe: FunctionComponent<Props> = ({
// @ts-ignore
Cesium.TextureMagnificationFilter.NEAREST;

// remove and destroy old layer if exists
// remove and destroy old layers if they exist
// we do not clean it up in the useEffect clean function because we want
// to wait until the new layer is ready to prevent flickering
oldLayer && setTimeout(() => layers.remove(oldLayer, true), 100);
setTimeout(() => {
for (let i = 0; i < layers.length; i++) {
const layer = layers.get(i);
if (i !== 0 && layer !== newLayer) {
layers.remove(layer, true);
}
}
}, 100);
});
} else if (oldLayer) {
// remove old layer when no image should be shown anymore
layers.remove(oldLayer, true);
} else if (layers.length > 1) {
// remove old layers when no image should be shown anymore
for (let i = 1; i < layers.length; i++) {
const layer = layers.get(i);
layers.remove(layer, true);
}
}
}, [layerType, viewer, imageUrl]);

Expand All @@ -227,9 +231,11 @@ const Globe: FunctionComponent<Props> = ({
}, [viewer, flyTo]);

return (
<div className={styles.globe} onMouseEnter={() => onMouseEnter()} ref={ref}>
<DataSetInfo layer={layer} isMain={isMain} />
</div>
<div
className={styles.globe}
onMouseEnter={() => onMouseEnter()}
ref={ref}
/>
);
};

Expand Down
12 changes: 3 additions & 9 deletions src/scripts/components/globes/globes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,10 @@ const Globes: FunctionComponent = () => {
}
);
const dispatch = useDispatch();
const projection = useSelector(projectionSelector);
const projectionState = useSelector(projectionSelector);
const globalGlobeView = useSelector(globeViewSelector);
const storyLayerId = useSelector(storyLayerSelector);
const mainLayerId = match?.params.mainLayerId || storyLayerId;
const main = useSelector((state: State) =>
layerListItemSelector(state, mainLayerId)
);
const mainLayerDetails = useSelector((state: State) =>
layerDetailsSelector(state, mainLayerId)
);
Expand Down Expand Up @@ -76,12 +73,10 @@ const Globes: FunctionComponent = () => {
return (
<div className={styles.globes}>
<Globe
layer={main}
active={isMainActive}
isMain
layerType={mainLayerDetails?.type}
view={currentView}
projection={projection}
projectionState={projectionState}
imageUrl={mainImageUrl}
flyTo={flyTo}
onMouseEnter={() => setIsMainActive(true)}
Expand All @@ -91,11 +86,10 @@ const Globes: FunctionComponent = () => {

{compare && (
<Globe
layer={compare}
active={!isMainActive}
layerType={compareLayerDetails?.type}
view={currentView}
projection={projection}
projectionState={projectionState}
imageUrl={compareImageUrl}
flyTo={flyTo}
onMouseEnter={() => setIsMainActive(false)}
Expand Down
2 changes: 1 addition & 1 deletion src/scripts/components/projection-menu/projection-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const ProjectionMenu: FunctionComponent = () => {
const [isOpen, setIsOpen] = useState(false);
const onProjectionClick = (projection: GlobeProjection) => {
setIsOpen(false);
dispatch(setGlobeProjectionAction(projection));
dispatch(setGlobeProjectionAction(projection, 2));
};
const onButtonClickHandler = () => setIsOpen(!isOpen);

Expand Down
2 changes: 1 addition & 1 deletion src/scripts/components/story-video/story-video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const StoryVideo: FunctionComponent<Props> = ({videoId}) => (
<iframe
width="100%"
height="100%"
src={`https://www.youtube.com/embed/${videoId}`}
src={`https://www.youtube.com/embed/${videoId}?rel=0`}
frameBorder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen></iframe>
Expand Down
6 changes: 5 additions & 1 deletion src/scripts/components/story/story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ import StoryHeader from '../story-header/story-header';
import {getNavigationData} from '../../libs/get-navigation-data';
import Autoplay from '../autoplay/autoplay';
import setGlobeTimeAction from '../../actions/set-globe-time';
import setGlobeProjectionAction from '../../actions/set-globe-projection';

import {StoryMode} from '../../types/story-mode';
import {GlobeProjection} from '../../types/globe-projection';

import styles from './story.styl';

Expand All @@ -43,6 +45,7 @@ const getStoryId = (params: Params, mode: StoryMode) => {

const Story: FunctionComponent<Props> = ({mode}) => {
const params = useParams<Params>();
const sphereProjection = GlobeProjection.Sphere;
const storyId = getStoryId(params, mode);
const storyIds = params.storyIds;
const storyIndex = parseInt(params.storyNumber || '0', 10);
Expand All @@ -68,7 +71,8 @@ const Story: FunctionComponent<Props> = ({mode}) => {
// fetch story of active storyId
useEffect(() => {
storyId && dispatch(fetchStory(storyId));
}, [dispatch, storyId]);
dispatch(setGlobeProjectionAction(sphereProjection, 0));
}, [dispatch, storyId, sphereProjection]);

// fly to position given in a slide, if none given set to default
// set layer given by story slide
Expand Down
5 changes: 4 additions & 1 deletion src/scripts/config/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import {GlobeProjection} from '../types/globe-projection';

const globeState: GlobeState = {
time: 0,
projection: GlobeProjection.Sphere,
projectionState: {
projection: GlobeProjection.Sphere,
morphTime: 2
},
view: {
position: {
height: 25003000,
Expand Down
9 changes: 6 additions & 3 deletions src/scripts/libs/globe-url-parameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,16 @@ export function parseUrl(): GlobeState | null {
roll: values[5]
}
},
projection,
projectionState: {
projection: GlobeProjection.Sphere,
morphTime: 2
},
time: values[6]
};
}

export function getParamString(globeState: GlobeState): string | null {
const {view, projection, time} = globeState;
const {view, projectionState, time} = globeState;
const {position, orientation} = view;
const {longitude, latitude, height} = position;
const {heading, pitch, roll} = orientation;
Expand All @@ -72,5 +75,5 @@ export function getParamString(globeState: GlobeState): string | null {

const compactValues = values.map(num => num.toFixed(2));

return [projection[0], ...compactValues].join(char);
return [projectionState.projection[0], ...compactValues].join(char);
}
2 changes: 1 addition & 1 deletion src/scripts/reducers/globe/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import timeReducer from './time';

const globeReducer = combineReducers({
view: viewReducer,
projection: projectionReducer,
projectionState: projectionReducer,
time: timeReducer
});

Expand Down
13 changes: 8 additions & 5 deletions src/scripts/reducers/globe/projection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@ import {
import {parseUrl} from '../../libs/globe-url-parameter';
import config from '../../config/main';

import {GlobeProjection} from '../../types/globe-projection';
import {GlobeProjectionState} from '../../types/globe-projection-state';

// get initial state from url or fallback to default state in config
const globeState = parseUrl() || config.globe;
const initialState = globeState.projection;
const initialState = {
projection: globeState.projectionState.projection,
morphTime: 2
};

function projectionReducer(
state: GlobeProjection = initialState,
state: GlobeProjectionState = initialState,
action: SetGlobeProjectionAction
): GlobeProjection {
): GlobeProjectionState {
switch (action.type) {
case SET_GLOBE_PROJECTION:
return action.projection;
return {projection: action.projection, morphTime: action.morphTime};
default:
return state;
}
Expand Down
Loading

0 comments on commit c9fdf3f

Please sign in to comment.