| @@ -0,0 +1,43 @@ | |||
| /** | |||
| * @Author: Caven | |||
| * @Date: 2020-12-20 16:32:22 | |||
| */ | |||
| class Animation { | |||
| constructor(viewer) { | |||
| this._viewer = viewer | |||
| this._options = {} | |||
| } | |||
| _bindEvent() {} | |||
| _unbindEvent() {} | |||
| /** | |||
| * Start globe rotate | |||
| * @returns {Animation} | |||
| */ | |||
| start() { | |||
| if (this._options.duration) { | |||
| let timer = setTimeout(() => { | |||
| this._unbindEvent() | |||
| this._options.callback && | |||
| this._options.callback.call(this._options.context || this) | |||
| clearTimeout(timer) | |||
| }, Number(this._options.duration) * 1e3) | |||
| } | |||
| this._bindEvent() | |||
| return this | |||
| } | |||
| /** | |||
| * Stop globe rotate | |||
| * @returns {Animation} | |||
| */ | |||
| stop() { | |||
| this._unbindEvent() | |||
| return this | |||
| } | |||
| } | |||
| export default Animation | |||
| @@ -0,0 +1,16 @@ | |||
| /** | |||
| * @Author: Caven | |||
| * @Date: 2020-03-05 22:15:27 | |||
| */ | |||
| export { default as Animation } from './Animation' | |||
| /** | |||
| * types | |||
| */ | |||
| export { default as AroundView } from './type/AroundView' | |||
| export { default as AroundPoint } from './type/AroundPoint' | |||
| export { default as CircleScan } from './type/CircleScan' | |||
| export { default as Flying } from './type/Flying' | |||
| export { default as GlobeRotate } from './type/GlobeRotate' | |||
| export { default as RadarScan } from './type/RadarScan' | |||
| @@ -0,0 +1,72 @@ | |||
| /** | |||
| * @Author: Caven | |||
| * @Date: 2020-03-02 22:38:10 | |||
| */ | |||
| import { Transform } from '@dc-modules/transform' | |||
| import Parse from '@dc-modules/parse/Parse' | |||
| import Animation from '../Animation' | |||
| const { Cesium } = DC.Namespace | |||
| class AroundPoint extends Animation { | |||
| constructor(viewer, position, options = {}) { | |||
| super(viewer) | |||
| this._position = Parse.parsePosition(position) | |||
| this._options = options | |||
| this._heading = viewer.camera.heading | |||
| this._aroundAmount = 0.2 | |||
| this.type = 'around_point' | |||
| } | |||
| set position(position) { | |||
| this._position = Parse.parsePosition(position) | |||
| return this | |||
| } | |||
| set aroundAmount(aroundAmount) { | |||
| this._aroundAmount = aroundAmount | |||
| return this | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _bindEvent() { | |||
| this._viewer.clock.onTick.addEventListener(this._onAround, this) | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _unbindEvent() { | |||
| this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY) | |||
| this._viewer.clock.onTick.removeEventListener(this._onAround, this) | |||
| } | |||
| /** | |||
| * | |||
| * @param scene | |||
| * @param time | |||
| * @private | |||
| */ | |||
| _onAround(scene, time) { | |||
| this._heading += Cesium.Math.toRadians(this._aroundAmount) | |||
| if (this._heading >= Math.PI * 2 || this._heading <= -Math.PI * 2) { | |||
| this._heading = 0 | |||
| } | |||
| this._viewer.camera.lookAt( | |||
| Transform.transformWGS84ToCartesian(this._position), | |||
| new Cesium.HeadingPitchRange( | |||
| this._heading, | |||
| Cesium.Math.toRadians(this._options.pitch || 0), | |||
| this._options.range || 1000 | |||
| ) | |||
| ) | |||
| } | |||
| } | |||
| export default AroundPoint | |||
| @@ -0,0 +1,60 @@ | |||
| /** | |||
| * @Author: Caven | |||
| * @Date: 2020-03-02 23:14:20 | |||
| */ | |||
| import Animation from '../Animation' | |||
| const { Cesium } = DC.Namespace | |||
| class AroundView extends Animation { | |||
| constructor(viewer, options = {}) { | |||
| super(viewer) | |||
| this._options = options | |||
| this._heading = viewer.camera.heading | |||
| this._aroundAmount = 0.2 | |||
| this.type = 'around_view' | |||
| } | |||
| set aroundAmount(aroundAmount) { | |||
| this._aroundAmount = aroundAmount | |||
| return this | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _bindEvent() { | |||
| this._viewer.clock.onTick.addEventListener(this._onAround, this) | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _unbindEvent() { | |||
| this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY) | |||
| this._viewer.clock.onTick.removeEventListener(this._onAround, this) | |||
| } | |||
| /** | |||
| * | |||
| * @param scene | |||
| * @param time | |||
| * @private | |||
| */ | |||
| _onAround(scene, time) { | |||
| this._heading += Cesium.Math.toRadians(this._aroundAmount) | |||
| if (this._heading >= Math.PI * 2 || this._heading <= -Math.PI * 2) { | |||
| this._heading = 0 | |||
| } | |||
| this._viewer.scene.camera.setView({ | |||
| orientation: { | |||
| heading: this._heading | |||
| } | |||
| }) | |||
| } | |||
| } | |||
| export default AroundView | |||
| @@ -0,0 +1,81 @@ | |||
| /** | |||
| * @Author: Caven | |||
| * @Date: 2020-12-01 20:26:02 | |||
| */ | |||
| import Animation from '../Animation' | |||
| const CircleScanShader = require('@dc-modules/material/shader/circle/CircleScanShader.glsl') | |||
| const { Transform, Parse, Util } = DC | |||
| const { Cesium } = DC.Namespace | |||
| class CircleScan extends Animation { | |||
| constructor(viewer, position, radius, options = {}) { | |||
| super(viewer) | |||
| this._delegate = undefined | |||
| this._position = Parse.parsePosition(position) | |||
| this._radius = radius || 100 | |||
| this._color = options.color || Cesium.Color.RED | |||
| this._speed = options.speed || 2 | |||
| this.type = 'circle_scan' | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _mountContent() { | |||
| let center = Transform.transformWGS84ToCartesian(this._position) | |||
| let up = Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal( | |||
| center, | |||
| new Cesium.Cartesian3() | |||
| ) | |||
| let self = this | |||
| this._delegate = new Cesium.PostProcessStage({ | |||
| name: Util.uuid(), | |||
| fragmentShader: CircleScanShader, | |||
| uniforms: { | |||
| centerWC: function() { | |||
| return center | |||
| }, | |||
| normalWC: function() { | |||
| return up | |||
| }, | |||
| radius: function() { | |||
| return self._radius | |||
| }, | |||
| speed: function() { | |||
| return self._speed | |||
| }, | |||
| color: function() { | |||
| return self._color | |||
| } | |||
| } | |||
| }) | |||
| } | |||
| /** | |||
| * | |||
| * @returns {CircleScan} | |||
| */ | |||
| start() { | |||
| !this._delegate && this._mountContent() | |||
| this._delegate && this._viewer.scene.postProcessStages.add(this._delegate) | |||
| return this | |||
| } | |||
| /** | |||
| * | |||
| * @returns {CircleScan} | |||
| */ | |||
| stop() { | |||
| this._delegate && | |||
| this._viewer.scene.postProcessStages.remove(this._delegate) | |||
| this._delegate = undefined | |||
| return this | |||
| } | |||
| } | |||
| export default CircleScan | |||
| @@ -0,0 +1,117 @@ | |||
| /** | |||
| * @Author: Caven | |||
| * @Date: 2021-01-09 20:21:33 | |||
| */ | |||
| import { Transform } from '@dc-modules/transform' | |||
| import Parse from '@dc-modules/parse/Parse' | |||
| import Animation from '../Animation' | |||
| const { Cesium } = DC.Namespace | |||
| class Flying extends Animation { | |||
| constructor(viewer, options = {}) { | |||
| super(viewer) | |||
| this._options = options | |||
| this._positions = [] | |||
| this._durations = [3] | |||
| this._currentIndex = 0 | |||
| this._timer = undefined | |||
| } | |||
| set positions(positions) { | |||
| this._positions = Parse.parsePositions(positions) | |||
| return this | |||
| } | |||
| get positions() { | |||
| return this._positions | |||
| } | |||
| set durations(durations) { | |||
| this._durations = durations | |||
| return this | |||
| } | |||
| get durations() { | |||
| return this._durations | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _cameraFly() { | |||
| let self = this | |||
| let camera = this._viewer.camera | |||
| let position = this._positions[this._currentIndex] | |||
| let callback = () => { | |||
| let nextPosition = self._positions[self._currentIndex + 1] | |||
| if (nextPosition) { | |||
| self._currentIndex++ | |||
| if (self._currentIndex <= self._positions.length - 1) { | |||
| self._timer = setTimeout(() => { | |||
| self._cameraFly() | |||
| }, (self._options.dwellTime || 1) * 1e3) | |||
| } | |||
| } else if (!nextPosition && self._options.loop) { | |||
| self._currentIndex = 0 | |||
| self._timer = setTimeout(() => { | |||
| self._cameraFly() | |||
| }, (self._options.dwellTime || 1) * 1e3) | |||
| } | |||
| self._options.callback && self._options.callback(self._currentIndex) | |||
| } | |||
| if (position) { | |||
| camera.flyTo({ | |||
| destination: Transform.transformWGS84ToCartesian(position), | |||
| orientation: { | |||
| heading: Cesium.Math.toRadians(position.heading), | |||
| pitch: Cesium.Math.toRadians(position.pitch), | |||
| roll: Cesium.Math.toRadians(position.roll) | |||
| }, | |||
| complete: callback, | |||
| duration: | |||
| this._durations.length === 1 | |||
| ? this._durations[0] | |||
| : this._durations[this._currentIndex] | |||
| }) | |||
| } | |||
| } | |||
| /** | |||
| * | |||
| * @returns {Flying} | |||
| */ | |||
| start() { | |||
| if (this._positions && this._positions.length) { | |||
| this._currentIndex = 0 | |||
| this._cameraFly() | |||
| } | |||
| return this | |||
| } | |||
| /** | |||
| * | |||
| * @returns {Flying} | |||
| */ | |||
| pause() { | |||
| this._viewer.camera.cancelFlight() | |||
| this._timer && clearTimeout(this._timer) | |||
| return this | |||
| } | |||
| /** | |||
| * | |||
| * @returns {Flying} | |||
| */ | |||
| restore() { | |||
| if (this._positions && this._positions.length) { | |||
| this._cameraFly() | |||
| } | |||
| return this | |||
| } | |||
| } | |||
| export default Flying | |||
| @@ -0,0 +1,57 @@ | |||
| /** | |||
| * @Author: Caven | |||
| * @Date: 2020-01-30 20:47:25 | |||
| */ | |||
| import Animation from '../Animation' | |||
| const { Cesium } = DC.Namespace | |||
| class GlobeRotate extends Animation { | |||
| constructor(viewer, options = {}) { | |||
| super(viewer) | |||
| this._options = options | |||
| this.type = 'globe_rotate' | |||
| } | |||
| /** | |||
| * @param scene | |||
| * @param time | |||
| * @returns {boolean} | |||
| * @private | |||
| */ | |||
| _icrf(scene, time) { | |||
| if (scene.mode !== Cesium.SceneMode.SCENE3D) { | |||
| return true | |||
| } | |||
| let icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time) | |||
| if (icrfToFixed) { | |||
| let camera = this._viewer.camera | |||
| let offset = Cesium.Cartesian3.clone(camera.position) | |||
| let transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed) | |||
| camera.lookAtTransform(transform, offset) | |||
| } | |||
| } | |||
| /** | |||
| * Bind the Event | |||
| * @private | |||
| */ | |||
| _bindEvent() { | |||
| this._viewer.clock.multiplier = this._options.speed || 12 * 1000 | |||
| this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY) | |||
| this._viewer.scene.postUpdate.addEventListener(this._icrf, this) | |||
| } | |||
| /** | |||
| * Unbind the Event | |||
| * @private | |||
| */ | |||
| _unbindEvent() { | |||
| this._viewer.clock.multiplier = 1 | |||
| this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY) | |||
| this._viewer.scene.postUpdate.removeEventListener(this._icrf, this) | |||
| } | |||
| } | |||
| export default GlobeRotate | |||
| @@ -0,0 +1,96 @@ | |||
| /** | |||
| * @Author: Caven | |||
| * @Date: 2020-12-01 20:40:02 | |||
| */ | |||
| import { Util } from '@dc-modules/utils' | |||
| import { Transform } from '@dc-modules/transform' | |||
| import Parse from '@dc-modules/parse/Parse' | |||
| import Animation from '../Animation' | |||
| const { Cesium } = DC.Namespace | |||
| const RadarScanShader = require('@dc-modules/material/shader/radar/RadarScanShader.glsl') | |||
| class RadarScan extends Animation { | |||
| constructor(viewer, position, radius, options = {}) { | |||
| super(viewer) | |||
| this._position = Parse.parsePosition(position) | |||
| this._radius = radius || 100 | |||
| this._color = options.color || Cesium.Color.BLUE | |||
| this._speed = options.speed || 3 | |||
| this._delegate = undefined | |||
| this.type = 'radar_scan' | |||
| } | |||
| /** | |||
| * | |||
| * @private | |||
| */ | |||
| _mountContent() { | |||
| let center = Transform.transformWGS84ToCartesian(this._position) | |||
| let up = Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal( | |||
| center, | |||
| new Cesium.Cartesian3() | |||
| ) | |||
| let time = new Date().getTime() | |||
| let self = this | |||
| this._delegate = new Cesium.PostProcessStage({ | |||
| name: Util.uuid(), | |||
| fragmentShader: RadarScanShader, | |||
| uniforms: { | |||
| centerWC: function() { | |||
| return center | |||
| }, | |||
| planeNormalWC: function() { | |||
| return up | |||
| }, | |||
| lineNormalWC: function() { | |||
| let rotateQ = new Cesium.Quaternion() | |||
| let rotateM = new Cesium.Matrix3() | |||
| let east = Cesium.Cartesian3.cross( | |||
| Cesium.Cartesian3.UNIT_Z, | |||
| up, | |||
| new Cesium.Cartesian3() | |||
| ) | |||
| let now = new Date().getTime() | |||
| let angle = Cesium.Math.PI * 2 * ((now - time) / 1e4) * self._speed | |||
| Cesium.Quaternion.fromAxisAngle(up, angle, rotateQ) | |||
| Cesium.Matrix3.fromQuaternion(rotateQ, rotateM) | |||
| Cesium.Matrix3.multiplyByVector(rotateM, east, east) | |||
| Cesium.Cartesian3.normalize(east, east) | |||
| return east | |||
| }, | |||
| radius: function() { | |||
| return self._radius | |||
| }, | |||
| color: function() { | |||
| return self._color | |||
| } | |||
| } | |||
| }) | |||
| } | |||
| /** | |||
| * | |||
| * @returns {RadarScan} | |||
| */ | |||
| start() { | |||
| !this._delegate && this._mountContent() | |||
| this._delegate && this._viewer.scene.postProcessStages.add(this._delegate) | |||
| return this | |||
| } | |||
| /** | |||
| * | |||
| * @returns {RadarScan} | |||
| */ | |||
| stop() { | |||
| this._delegate && | |||
| this._viewer.scene.postProcessStages.remove(this._delegate) | |||
| this._delegate = undefined | |||
| return this | |||
| } | |||
| } | |||
| export default RadarScan | |||