Skip to content

Commit

Permalink
0807 controllers (visgl#833)
Browse files Browse the repository at this point in the history
* Generic Viewports
  • Loading branch information
ibgreen authored Aug 11, 2017
1 parent a946dfc commit b26e655
Showing 22 changed files with 271 additions and 449 deletions.
6 changes: 2 additions & 4 deletions examples/plot/app.js
Original file line number Diff line number Diff line change
@@ -4,9 +4,7 @@ import {render} from 'react-dom';
import DeckGLOverlay from './deckgl-overlay.js';
import {OrbitController} from 'deck.gl/dist/controllers';

const equation = (x, y) => {
return Math.sin(x * x + y * y) * x / Math.PI;
};
const EQUATION = (x, y) => Math.sin(x * x + y * y) * x / Math.PI;

class Root extends Component {

@@ -69,7 +67,7 @@ class Root extends Component {
onViewportChange={this._onViewportChange} >
<DeckGLOverlay
viewport={OrbitController.getViewport(viewport)}
equation={equation}
equation={EQUATION}
resolution={200}
showAxis={true}
onHover={this._onHover} />
6 changes: 3 additions & 3 deletions examples/plot/package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"scripts": {
"start-local": "webpack-dev-server --env.local --progress --hot --port 3030 --open",
"start": "webpack-dev-server --progress --hot --port 3030 --open"
"start": "webpack-dev-server --progress --hot --open",
"start-local": "webpack-dev-server --env.local --progress --hot --open",
"start-es6": "webpack-dev-server --env.es6 --progress --hot --open"
},
"dependencies": {
"d3-scale": "^1.0.6",
"deck.gl": "^4.1.0",
"luma.gl": "^4.0.0",
"prop-types": "^15.5.8",
"react": "^15.4.1",
"react-dom": "^15.4.1"
},
4 changes: 2 additions & 2 deletions examples/without-map/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"scripts": {
"start-local": "webpack-dev-server --env.local --progress --hot --port 3000 --open",
"start": "webpack-dev-server --progress --hot --port 3000 --open"
"start": "webpack-dev-server --progress --hot --open",
"start-local": "webpack-dev-server --env.local --progress --hot --open"
},
"dependencies": {
"deck.gl": "^4.1.0",
11 changes: 9 additions & 2 deletions src/controls/events/event-manager.js
Original file line number Diff line number Diff line change
@@ -193,9 +193,16 @@ export default class EventManager {
// Calculate center relative to the root element
// TODO/xiaoji - avoid using getBoundingClientRect for perf?
const rect = element.getBoundingClientRect();

// Fix scale for map affected by a CSS transform.
// See https://stackoverflow.com/a/26893663/3528533
const scaleX = rect.width / element.offsetWidth;
const scaleY = rect.height / element.offsetHeight;

// Calculate center relative to the root element
const offsetCenter = {
x: center.x - rect.left - element.clientLeft,
y: center.y - rect.top - element.clientTop
x: (center.x - rect.left - element.clientLeft) / scaleX,
y: (center.y - rect.top - element.clientTop) / scaleY
};

handler(Object.assign({}, event, {
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import OrbitState from './orbit-state';
import assert from 'assert';

// EVENT HANDLING PARAMETERS
const ZOOM_ACCEL = 0.01;
@@ -30,24 +30,31 @@ const EVENT_TYPES = {
DOUBLE_TAP: ['doubletap']
};

export default class OrbitControls {
export default class GenericControls {
/**
* @classdesc
* A class that handles events and updates mercator style viewport parameters
*/
constructor() {
constructor(options) {
assert(options.StateClass);
this.StateClass = options.StateClass;

this._state = {
isDragging: false
};

this.handleEvent = this.handleEvent.bind(this);

this.setOptions(options);
}

/**
* Callback for events
* @param {hammer.Event} event
*/
handleEvent(event) {
this.orbitState = new OrbitState(Object.assign({}, this.orbitStateProps, this._state));
this.viewportState =
new this.StateClass(Object.assign({}, this.viewportStateProps, this._state));

switch (event.type) {
case 'panstart':
@@ -80,8 +87,11 @@ export default class OrbitControls {

isFunctionKeyPressed(event) {
const {srcEvent} = event;
return Boolean(srcEvent.metaKey || srcEvent.altKey ||
srcEvent.ctrlKey || srcEvent.shiftKey);
return Boolean(srcEvent.metaKey || srcEvent.altKey || srcEvent.ctrlKey || srcEvent.shiftKey);
}

isDragging() {
return this._state.isDragging;
}

setState(newState) {
@@ -93,24 +103,26 @@ export default class OrbitControls {

/* Callback util */
// formats map state and invokes callback function
updateViewport(newOrbitState, extraState = {}) {
const oldViewport = this.orbitState.getViewportProps();
const newViewport = newOrbitState.getViewportProps();
updateViewport(newViewportState, extraState = {}) {
const oldViewport = this.viewportState.getViewportProps();
const newViewport = newViewportState.getViewportProps();

if (this.onViewportChange &&
Object.keys(newViewport).some(key => oldViewport[key] !== newViewport[key])) {
// Viewport has changed
this.onViewportChange(newViewport);
}

this.setState(Object.assign({}, newOrbitState.getInteractiveState(), extraState));
this.setState(Object.assign({}, newViewportState.getInteractiveState(), extraState));
}

/**
* Extract interactivity options
*/
setOptions(options) {
const {
// TODO(deprecate): remove this when `onChangeViewport` gets deprecated
onChangeViewport,
onViewportChange,
onStateChange = this.onStateChange,
eventManager = this.eventManager,
@@ -120,20 +132,24 @@ export default class OrbitControls {
doubleClickZoom = true,
touchZoomRotate = true
} = options;
this.onViewportChange = onViewportChange;

// TODO(deprecate): remove this check when `onChangeViewport` gets deprecated
this.onViewportChange = onViewportChange || onChangeViewport;
this.onStateChange = onStateChange;
this.orbitStateProps = options;
this.viewportStateProps = options;

if (this.eventManager !== eventManager) {
// EventManager has changed
this.eventManager = eventManager;
this._events = {};
}

// Register/unregister events
this.toggleEvents(EVENT_TYPES.WHEEL, scrollZoom);
this.toggleEvents(EVENT_TYPES.PAN, dragPan || dragRotate);
this.toggleEvents(EVENT_TYPES.PINCH, touchZoomRotate);
this.toggleEvents(EVENT_TYPES.DOUBLE_TAP, doubleClickZoom);
const isInteractive = Boolean(this.onViewportChange);
this.toggleEvents(EVENT_TYPES.WHEEL, isInteractive && scrollZoom);
this.toggleEvents(EVENT_TYPES.PAN, isInteractive && (dragPan || dragRotate));
this.toggleEvents(EVENT_TYPES.PINCH, isInteractive && touchZoomRotate);
this.toggleEvents(EVENT_TYPES.DOUBLE_TAP, isInteractive && doubleClickZoom);

this.scrollZoom = scrollZoom;
this.dragPan = dragPan;
@@ -161,8 +177,8 @@ export default class OrbitControls {
// Default handler for the `panstart` event.
_onPanStart(event) {
const pos = this.getCenter(event);
const newOrbitState = this.orbitState.panStart({pos}).rotateStart({pos});
return this.updateViewport(newOrbitState, {isDragging: true});
const newViewportState = this.viewportState.panStart({pos}).rotateStart({pos});
return this.updateViewport(newViewportState, {isDragging: true});
}

// Default handler for the `panmove` event.
@@ -172,8 +188,8 @@ export default class OrbitControls {

// Default handler for the `panend` event.
_onPanEnd(event) {
const newOrbitState = this.orbitState.panEnd().rotateEnd();
return this.updateViewport(newOrbitState, {isDragging: false});
const newViewportState = this.viewportState.panEnd().rotateEnd();
return this.updateViewport(newViewportState, {isDragging: false});
}

// Default handler for panning to move.
@@ -183,8 +199,8 @@ export default class OrbitControls {
return false;
}
const pos = this.getCenter(event);
const newOrbitState = this.orbitState.pan({pos});
return this.updateViewport(newOrbitState);
const newViewportState = this.viewportState.pan({pos});
return this.updateViewport(newViewportState);
}

// Default handler for panning to rotate.
@@ -195,13 +211,13 @@ export default class OrbitControls {
}

const {deltaX, deltaY} = event;
const {width, height} = this.orbitState.getViewportProps();
const {width, height} = this.viewportState.getViewportProps();

const deltaScaleX = deltaX / width;
const deltaScaleY = deltaY / height;

const newOrbitState = this.orbitState.rotate({deltaScaleX, deltaScaleY});
return this.updateViewport(newOrbitState);
const newViewportState = this.viewportState.rotate({deltaScaleX, deltaScaleY});
return this.updateViewport(newViewportState);
}

// Default handler for the `wheel` event.
@@ -220,15 +236,15 @@ export default class OrbitControls {
scale = 1 / scale;
}

const newOrbitState = this.orbitState.zoom({pos, scale});
return this.updateViewport(newOrbitState);
const newViewportState = this.viewportState.zoom({pos, scale});
return this.updateViewport(newViewportState);
}

// Default handler for the `pinchstart` event.
_onPinchStart(event) {
const pos = this.getCenter(event);
const newOrbitState = this.orbitState.zoomStart({pos});
return this.updateViewport(newOrbitState, {isDragging: true});
const newViewportState = this.viewportState.zoomStart({pos});
return this.updateViewport(newViewportState, {isDragging: true});
}

// Default handler for the `pinch` event.
@@ -238,14 +254,14 @@ export default class OrbitControls {
}
const pos = this.getCenter(event);
const {scale} = event;
const newOrbitState = this.orbitState.zoom({pos, scale});
return this.updateViewport(newOrbitState);
const newViewportState = this.viewportState.zoom({pos, scale});
return this.updateViewport(newViewportState);
}

// Default handler for the `pinchend` event.
_onPinchEnd(event) {
const newOrbitState = this.orbitState.zoomEnd();
return this.updateViewport(newOrbitState, {isDragging: false});
const newViewportState = this.viewportState.zoomEnd();
return this.updateViewport(newViewportState, {isDragging: false});
}

// Default handler for the `doubletap` event.
@@ -256,7 +272,7 @@ export default class OrbitControls {
const pos = this.getCenter(event);
const isZoomOut = this.isFunctionKeyPressed(event);

const newOrbitState = this.orbitState.zoom({pos, scale: isZoomOut ? 0.5 : 2});
return this.updateViewport(newOrbitState);
const newViewportState = this.viewportState.zoom({pos, scale: isZoomOut ? 0.5 : 2});
return this.updateViewport(newViewportState);
}
}
3 changes: 3 additions & 0 deletions src/controls/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Deprecated exports, just to avoid breaking the 4.1 examples
export {default as MapController} from '../react/controllers/map-controller';
export {default as OrbitController} from '../react/controllers/orbit-controller';
Loading

0 comments on commit b26e655

Please sign in to comment.