Skip to content

Commit

Permalink
feature(PlanarControls): add max and min resolution parameters to lim…
Browse files Browse the repository at this point in the history
…it zoom
  • Loading branch information
mgermerie authored and gchoqueux committed Apr 1, 2021
1 parent e9ae835 commit ad17590
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/Controls/PlanarControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ const defaultOptions = {
maxPanSpeed: 15,
zoomTravelTime: 0.2, // must be a number
zoomFactor: 2,
maxResolution: 1 / Infinity,
minResolution: Infinity,
maxAltitude: 50000000,
groundLevel: 200,
autoTravelTimeMin: 1.5,
Expand Down Expand Up @@ -144,6 +146,10 @@ export const PLANAR_CONTROL_EVENT = {
* @param {number} [options.zoomTravelTime=0.2] Animation time when zooming.
* @param {number} [options.zoomFactor=2] The factor the scale is multiplied by when zooming
* in and divided by when zooming out. This factor can't be null.
* @param {number} [options.maxResolution=0] The smallest size in meters a pixel at the center of the
* view can represent.
* @param {number} [options.minResolution=Infinity] The biggest size in meters a pixel at the center of the
* view can represent.
* @param {number} [options.maxAltitude=12000] Maximum altitude reachable when panning or zooming out.
* @param {number} [options.groundLevel=200] Minimum altitude reachable when panning.
* @param {number} [options.autoTravelTimeMin=1.5] Minimum duration for animated travels with the `auto`
Expand Down Expand Up @@ -225,6 +231,10 @@ class PlanarControls extends THREE.EventDispatcher {
this.zoomInFactor = options.zoomFactor || defaultOptions.zoomFactor;
this.zoomOutFactor = 1 / (options.zoomFactor || defaultOptions.zoomFactor);

// the maximum and minimum size (in meters) a pixel at the center of the view can represent
this.maxResolution = options.maxResolution || defaultOptions.maxResolution;
this.minResolution = options.minResolution || defaultOptions.minResolution;

// approximate ground altitude value. Camera altitude is clamped above groundLevel
this.groundLevel = options.groundLevel || defaultOptions.groundLevel;

Expand Down Expand Up @@ -515,6 +525,12 @@ class PlanarControls extends THREE.EventDispatcher {
if (delta > 0 || (delta < 0 && this.maxAltitude > this.camera.position.z)) {
const zoomFactor = delta > 0 ? this.zoomInFactor : this.zoomOutFactor;

// do not zoom if the resolution after the zoom is outside resolution limits
const endResolution = this.view.getPixelsToMeters() / zoomFactor;
if (this.maxResolution > endResolution || endResolution > this.minResolution) {
return;
}

// change the camera field of view if the camera is orthographic
if (this.camera.isOrthographicCamera) {
// switch state to STATE.ZOOM
Expand Down
17 changes: 17 additions & 0 deletions test/unit/planarControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,23 @@ describe('Planar Controls', function () {
controlsOrtho.state = STATE.NONE;
});

it('resolution limits on zoom', function () {
const orthoScale = viewOrtho.getPixelsToMeters();
controlsOrtho.minResolution = orthoScale;
controlsOrtho.maxResolution = orthoScale;

// wheel in
wheelMouse(controlsOrtho, cameraOrtho, 10);
// camera has not moved
assert.ok(cameraOrtho.position.equals(cameraInitialPosition));
// zoom has not changed
assert.equal(cameraOrtho.zoom, cameraInitialZoom);
// reset controls
controlsOrtho.minResolution = Infinity;
controlsOrtho.maxResolution = 0;
controlsOrtho.state = STATE.NONE;
});

it('smart travel for a perspective camera', function () {
event.button = THREE.MOUSE.MIDDLE;

Expand Down

0 comments on commit ad17590

Please sign in to comment.