terriajs
Version:
Geospatial data visualization platform.
147 lines (130 loc) • 5.89 kB
JSX
;
const React = require('react');
const PropTypes = require('prop-types');
import createReactClass from 'create-react-class';
const defined = require('terriajs-cesium/Source/Core/defined');
const Ray = require('terriajs-cesium/Source/Core/Ray');
const IntersectionTests = require('terriajs-cesium/Source/Core/IntersectionTests');
const Ellipsoid = require('terriajs-cesium/Source/Core/Ellipsoid');
const Tween = require('terriajs-cesium/Source/ThirdParty/Tween');
const CesiumMath = require('terriajs-cesium/Source/Core/Math');
const Cartesian3 = require('terriajs-cesium/Source/Core/Cartesian3');
import Icon from "../../Icon.jsx";
import Styles from './zoom_control.scss';
// Map zoom control
const ZoomControl = createReactClass({
propTypes: {
terria: PropTypes.object
},
flyToPosition(scene, position, durationMilliseconds) {
const camera = scene.camera;
const startPosition = camera.position;
const endPosition = position;
// temp
durationMilliseconds = 200;
const controller = scene.screenSpaceCameraController;
controller.enableInputs = false;
scene.tweens.add({
duration: durationMilliseconds / 1000.0,
easingFunction: Tween.Easing.Sinusoidal.InOut,
startObject: {
time: 0.0
},
stopObject: {
time: 1.0
},
update(value) {
if (scene.isDestroyed()) {
return;
}
scene.camera.position.x = CesiumMath.lerp(startPosition.x, endPosition.x, value.time);
scene.camera.position.y = CesiumMath.lerp(startPosition.y, endPosition.y, value.time);
scene.camera.position.z = CesiumMath.lerp(startPosition.z, endPosition.z, value.time);
},
complete() {
if (controller.isDestroyed()) {
return;
}
controller.enableInputs = true;
},
cancel() {
if (controller.isDestroyed()) {
return;
}
controller.enableInputs = true;
}
});
},
getCameraFocus(scene) {
const ray = new Ray(scene.camera.positionWC, scene.camera.directionWC);
const intersections = IntersectionTests.rayEllipsoid(ray, Ellipsoid.WGS84);
if (defined(intersections)) {
return Ray.getPoint(ray, intersections.start);
}
// Camera direction is not pointing at the globe, so use the ellipsoid horizon point as
// the focal point.
return IntersectionTests.grazingAltitudeLocation(ray, Ellipsoid.WGS84);
},
zoomIn() {
const cartesian3Scratch = new Cartesian3();
this.props.terria.analytics.logEvent('navigation', 'click', 'zoomIn');
if (defined(this.props.terria.leaflet)) {
this.props.terria.leaflet.map.zoomIn(1);
}
if (defined(this.props.terria.cesium)) {
const scene = this.props.terria.cesium.scene;
const camera = scene.camera;
const focus = this.getCameraFocus(scene);
const direction = Cartesian3.subtract(focus, camera.position, cartesian3Scratch);
const movementVector = Cartesian3.multiplyByScalar(direction, 2.0 / 3.0, cartesian3Scratch);
const endPosition = Cartesian3.add(camera.position, movementVector, cartesian3Scratch);
this.flyToPosition(scene, endPosition);
}
this.props.terria.currentViewer.notifyRepaintRequired();
},
zoomOut() {
const cartesian3Scratch = new Cartesian3();
this.props.terria.analytics.logEvent('navigation', 'click', 'zoomOut');
if (defined(this.props.terria.leaflet)) {
this.props.terria.leaflet.map.zoomOut(1);
}
if (defined(this.props.terria.cesium)) {
const scene = this.props.terria.cesium.scene;
const camera = scene.camera;
const focus = this.getCameraFocus(scene);
const direction = Cartesian3.subtract(focus, camera.position, cartesian3Scratch);
const movementVector = Cartesian3.multiplyByScalar(direction, -2.0, cartesian3Scratch);
const endPosition = Cartesian3.add(camera.position, movementVector, cartesian3Scratch);
this.flyToPosition(scene, endPosition);
}
this.props.terria.currentViewer.notifyRepaintRequired();
},
zoomReset() {
this.props.terria.analytics.logEvent('navigation', 'click', 'reset');
this.props.terria.currentViewer.zoomTo(this.props.terria.homeView, 1.5);
},
render() {
return (
<div className={Styles.zoomControl}>
<ul className={Styles.list}>
<li>
<button type='button' onClick={this.zoomIn} className={Styles.increase} title='zoom in'>
<Icon glyph={Icon.GLYPHS.increase}/>
</button>
</li>
<li>
<button type='button' onClick={this.zoomReset} className={Styles.refresh} title='reset zoom'>
<Icon glyph={Icon.GLYPHS.refresh}/>
</button>
</li>
<li>
<button type='button' onClick={this.zoomOut} className={Styles.decrease} title='zoom out'>
<Icon glyph={Icon.GLYPHS.decrease}/>
</button>
</li>
</ul>
</div>
);
}
});
module.exports = ZoomControl;