Added basic animated camera movement

master
Robin Hawkes 2016-03-15 19:50:04 +00:00
rodzic 9882b8636d
commit 42bf0c4518
9 zmienionych plików z 2328 dodań i 210 usunięć

2253
dist/vizicities.js vendored

Plik diff jest za duży Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -41,43 +41,43 @@ var imageTileLayer = VIZI.imageTileLayer('http://{s}.basemaps.cartocdn.com/light
// }).addTo(world);
// Building and roads from Mapzen (polygons and linestrings)
var topoJSONTileLayer = VIZI.topoJSONTileLayer('https://vector.mapzen.com/osm/buildings,roads/{z}/{x}/{y}.topojson?api_key=vector-tiles-NT5Emiw', {
interactive: false,
style: function(feature) {
var height;
if (feature.properties.height) {
height = feature.properties.height;
} else {
height = 10 + Math.random() * 10;
}
return {
height: height,
lineColor: '#f7c616',
lineWidth: 1,
lineTransparent: true,
lineOpacity: 0.2,
lineBlending: THREE.AdditiveBlending,
lineRenderOrder: 2
};
},
filter: function(feature) {
// Don't show points
return feature.geometry.type !== 'Point';
},
// onEachFeature: function(feature, layer) {
// if (feature.geometry.type !== 'Polygon') {
// return;
// }
//
// // Make polygons clickable
// layer.on('click', function(layer, point2d, point3d, intersects) {
// console.log(layer, point2d, point3d, intersects);
// });
// },
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://whosonfirst.mapzen.com#License">Who\'s On First</a>.'
}).addTo(world);
// var topoJSONTileLayer = VIZI.topoJSONTileLayer('https://vector.mapzen.com/osm/buildings,roads/{z}/{x}/{y}.topojson?api_key=vector-tiles-NT5Emiw', {
// interactive: false,
// style: function(feature) {
// var height;
//
// if (feature.properties.height) {
// height = feature.properties.height;
// } else {
// height = 10 + Math.random() * 10;
// }
//
// return {
// height: height,
// lineColor: '#f7c616',
// lineWidth: 1,
// lineTransparent: true,
// lineOpacity: 0.2,
// lineBlending: THREE.AdditiveBlending,
// lineRenderOrder: 2
// };
// },
// filter: function(feature) {
// // Don't show points
// return feature.geometry.type !== 'Point';
// },
// // onEachFeature: function(feature, layer) {
// // if (feature.geometry.type !== 'Polygon') {
// // return;
// // }
// //
// // // Make polygons clickable
// // layer.on('click', function(layer, point2d, point3d, intersects) {
// // console.log(layer, point2d, point3d, intersects);
// // });
// // },
// attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://whosonfirst.mapzen.com#License">Who\'s On First</a>.'
// }).addTo(world);
// Just buildings from Mapzen (polygons)
// var topoJSONTileLayer = VIZI.topoJSONTileLayer('https://vector.mapzen.com/osm/buildings/{z}/{x}/{y}.topojson?api_key=vector-tiles-NT5Emiw', {
@ -104,30 +104,30 @@ var topoJSONTileLayer = VIZI.topoJSONTileLayer('https://vector.mapzen.com/osm/bu
// attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://whosonfirst.mapzen.com#License">Who\'s On First</a>.'
// }).addTo(world);
// // London Underground lines
// var geoJSONLayer = VIZI.geoJSONLayer('https://rawgit.com/robhawkes/4acb9d6a6a5f00a377e2/raw/30ae704a44e10f2e13fb7e956e80c3b22e8e7e81/tfl_lines.json', {
// output: true,
// interactive: true,
// style: function(feature) {
// var colour = feature.properties.lines[0].colour || '#ffffff';
//
// return {
// lineColor: colour,
// // lineHeight: 20,
// lineWidth: 3,
// // lineTransparent: true,
// // lineOpacity: 0.5,
// // lineBlending: THREE.AdditiveBlending,
// lineRenderOrder: 2
// };
// },
// onEachFeature: function(feature, layer) {
// layer.on('click', function(layer, point2d, point3d, intersects) {
// console.log(layer, point2d, point3d, intersects);
// });
// },
// attribution: '&copy; Transport for London.'
// }).addTo(world);
// London Underground lines
var geoJSONLayer = VIZI.geoJSONLayer('https://rawgit.com/robhawkes/4acb9d6a6a5f00a377e2/raw/30ae704a44e10f2e13fb7e956e80c3b22e8e7e81/tfl_lines.json', {
output: true,
interactive: true,
style: function(feature) {
var colour = feature.properties.lines[0].colour || '#ffffff';
return {
lineColor: colour,
lineHeight: 20,
lineWidth: 3,
lineTransparent: true,
lineOpacity: 0.5,
lineBlending: THREE.AdditiveBlending,
lineRenderOrder: 2
};
},
onEachFeature: function(feature, layer) {
layer.on('click', function(layer, point2d, point3d, intersects) {
console.log(layer, point2d, point3d, intersects);
});
},
attribution: '&copy; Transport for London.'
}).addTo(world);
// Set up render debug stats
var rendererStats = new THREEx.RendererStats();

Wyświetl plik

@ -79,6 +79,14 @@ function build() {
// Proxy the global proj4 variable to require('proj4')
'proj4': 'proj4'
},
resolve: {
alias: {
'TweenLite': __dirname + '/node_modules/gsap/src/uncompressed/TweenLite.js',
'TweenMax': __dirname + '/node_modules/gsap/src/uncompressed/TweenMax.js',
'TimelineLite': __dirname + '/node_modules/gsap/src/uncompressed/TimelineLite.js',
'TimelineMax': __dirname + '/node_modules/gsap/src/uncompressed/TimelineMax.js'
}
},
module: {
loaders: [
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }

Wyświetl plik

@ -82,6 +82,7 @@
"earcut": "^2.0.8",
"eventemitter3": "^1.1.1",
"geojson-merge": "^0.1.0",
"gsap": "^1.18.2",
"hammerjs": "^2.0.6",
"lodash.assign": "^4.0.2",
"lodash.throttle": "^4.0.0",

Wyświetl plik

@ -105,7 +105,7 @@ class World extends EventEmitter {
// Update controls
this._controls.forEach(controls => {
controls.update();
controls.update(delta);
});
this.emit('preUpdate', delta);

Wyświetl plik

@ -1,6 +1,10 @@
import EventEmitter from 'eventemitter3';
import THREE from 'three';
import OrbitControls from '../vendor/OrbitControls';
import TweenLite from 'TweenLite';
// Prevent animation from pausing when tab is inactive
TweenLite.lagSmoothing(0);
class Orbit extends EventEmitter {
constructor() {
@ -25,38 +29,127 @@ class Orbit extends EventEmitter {
}
// Moving the camera along the [x,y,z] axis based on a target position
_panTo(point, animate) {}
_panBy(pointDelta, animate) {}
panTo(point, animate) {}
panBy(pointDelta, animate) {}
// Zooming the camera in and out
_zoomTo(metres, animate) {}
_zoomBy(metresDelta, animate) {}
zoomTo(metres, animate) {}
zoomBy(metresDelta, animate) {}
// Force camera to look at something other than the target
_lookAt(point, animate) {}
lookAt(point, animate) {}
// Make camera look at the target
_lookAtTarget() {}
lookAtTarget() {}
// Tilt (up and down)
_tiltTo(angle, animate) {}
_tiltBy(angleDelta, animate) {}
tiltTo(angle, animate) {}
tiltBy(angleDelta, animate) {}
// Rotate (left and right)
_rotateTo(angle, animate) {}
_rotateBy(angleDelta, animate) {}
rotateTo(angle, animate) {}
rotateBy(angleDelta, animate) {}
// Fly to the given point, animating pan and tilt/rotation to final position
// with nice zoom out and in
//
// Calling flyTo a second time before the previous animation has completed
// will immediately start the new animation from wherever the previous one
// has got to
_flyTo(point, noZoom) {}
// TODO: Calling flyTo a second time before the previous animation has
// completed should immediately start the new animation from wherever the
// previous one has got to
//
// TODO: Long-distance pans should prevent the quadtree grid from trying to
// update by not firing the control update events every frame until the
// pan velocity calms down a bit
flyToPoint(point, duration, noZoom) {
// Animation time in seconds
var animationTime = duration || 3;
this._flyTarget = new THREE.Vector3(point.x, 0, point.y);
// Calculate delta from current position to fly target
var diff = new THREE.Vector3().subVectors(this._controls.target, this._flyTarget);
this._flyTween = new TweenLite(
{
x: 0,
z: 0,
prev: {
x: 0,
z: 0
}
},
animationTime,
{
x: diff.x,
z: diff.z,
onUpdate: function(tween) {
var controls = this._controls;
// Work out difference since last frame
var deltaX = tween.target.x - tween.target.prev.x;
var deltaZ = tween.target.z - tween.target.prev.z;
// Move some fraction toward the target point
controls.panLeft(deltaX, controls.object.matrix);
controls.panUp(deltaZ, controls.object.matrix);
tween.target.prev.x = tween.target.x;
tween.target.prev.z = tween.target.z;
// TODO: Get zoom to dolly in and out on pan
// controls.object.zoom += Math.sin(Math.PI / tween.target.zoom);
// controls.object.updateProjectionMatrix();
},
onComplete: function(tween) {
console.log(`Arrived at flyTarget`);
this._flyTarget = null;
},
onUpdateParams: ['{self}'],
onCompleteParams: ['{self}'],
callbackScope: this,
ease: Power1.easeInOut
}
);
}
flyToLatLon(latlon, duration, noZoom) {
var point = this._world.latLonToPoint(latlon);
this.flyToPoint(point, duration, noZoom);
}
// TODO: Make this animate over a user-defined period of time
//
// Perhaps use TweenMax for now and implement as a more lightweight solution
// later on once it all works
// _animateFlyTo(delta) {
// var controls = this._controls;
//
// // this._controls.panLeft(50, controls._controls.object.matrix);
// // this._controls.panUp(50, controls._controls.object.matrix);
// // this._controls.dollyIn(this._controls.getZoomScale());
// // this._controls.dollyOut(this._controls.getZoomScale());
//
// // Calculate delta from current position to fly target
// var diff = new THREE.Vector3().subVectors(this._controls.target, this._flyTarget);
//
// // 1000 units per second
// var speed = 1000 * (delta / 1000);
//
// // Remove fly target after arrival and snap to target
// if (diff.length() < 0.01) {
// console.log(`Arrived at flyTarget`);
// this._flyTarget = null;
// speed = 1;
// }
//
// // Move some fraction toward the target point
// controls.panLeft(diff.x * speed, controls.object.matrix);
// controls.panUp(diff.z * speed, controls.object.matrix);
// }
// Proxy to OrbitControls.update()
update() {
this._controls.update();
update(delta) {
this._controls.update(delta);
}
// Add controls to world instance and store world reference

Wyświetl plik

@ -1104,6 +1104,16 @@ var OrbitControls = function ( object, domElement ) {
window.addEventListener( 'keydown', onKeyDown, false );
// Expose controls methods for programmatic control
this.panLeft = panLeft;
this.panUp = panUp;
this.pan = pan;
this.dollyIn = dollyIn;
this.dollyOut = dollyOut;
this.getZoomScale = getZoomScale;
this.rotateLeft = rotateLeft;
this.rotateUp = rotateUp;
// force an update at start
this.update();