From 7e751cae91c2c08e2ba56912096eadd42f16e356 Mon Sep 17 00:00:00 2001 From: Eugene Maksymenko Date: Wed, 28 Sep 2022 12:21:38 +0300 Subject: [PATCH] Keep map scale by adopting field of view on view port resize --- src/BasicWorldWindowController.js | 2 +- src/WorldWindow.js | 18 +++++++++++++++--- src/geom/Camera.js | 23 +++++++++++++++++++++-- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/BasicWorldWindowController.js b/src/BasicWorldWindowController.js index 48b519a1ee..0590006bd6 100644 --- a/src/BasicWorldWindowController.js +++ b/src/BasicWorldWindowController.js @@ -457,7 +457,7 @@ define([ // Clamp tilt to between 0 and +90 to prevent the viewer from going upside down. lookAt.tilt = WWMath.clamp(lookAt.tilt, 0, 90); - // Normalize heading to between -180 and +180. + // Normalize roll to between -180 and +180. lookAt.roll = Angle.normalizedDegrees(lookAt.roll); // Apply 2D limits when the globe is 2D. diff --git a/src/WorldWindow.js b/src/WorldWindow.js index 6a4b37ffae..d6215c8326 100644 --- a/src/WorldWindow.js +++ b/src/WorldWindow.js @@ -175,7 +175,7 @@ define([ * @type {Rectangle} * @readonly */ - this.viewport = new Rectangle(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + this.viewport = new Rectangle(0, 0, 0, 0); /** * The globe displayed. @@ -811,13 +811,25 @@ define([ width = gl.canvas.clientWidth * this.pixelScale, height = gl.canvas.clientHeight * this.pixelScale; - if (gl.canvas.width != width || - gl.canvas.height != height) { + if (gl.canvas.width != width || gl.canvas.height != height + || this.viewport.width === 0 || this.viewport.height === 0) { // Make the canvas drawing buffer size match its screen size. gl.canvas.width = width; gl.canvas.height = height; + // Keep map scale by adopting field of view on view port resize + if (this.viewport.height !== 0) { + try { + this.camera.fieldOfView *= height / this.viewport.height; + } catch (ignore) { + // Keep original field of view in case new one does not fit requirements + } + } else if (width > height) { + // Apply initial field of view to the longest viewport side + this.camera.fieldOfView *= height / width; + } + // Set the WebGL viewport to match the canvas drawing buffer size. gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); this.viewport = new Rectangle(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); diff --git a/src/geom/Camera.js b/src/geom/Camera.js index a4dc60fc3a..7217c3122c 100644 --- a/src/geom/Camera.js +++ b/src/geom/Camera.js @@ -42,6 +42,7 @@ define([ /** * Camera tilt, in degrees. + * @type {Number} * @default 0 */ this.tilt = 0; @@ -53,13 +54,31 @@ define([ */ this.roll = 0; + // Intentionally not documented + this._fieldOfView = 45; + }; + + Object.defineProperties(Camera.prototype, { /** * Camera vertical field of view, in degrees * @type {Number} * @default 45 + * @throws {ArgumentError} If the specified field of view is out of range. */ - this.fieldOfView = 45; - }; + fieldOfView: { + get: function () { + return this._fieldOfView; + }, + set: function (value) { + if (value <= 0 || value => 180) { + throw new ArgumentError( + Logger.logMessage(Logger.LEVEL_SEVERE, "Camera", "setFieldOfView", "Invalid field of view") + ); + } + this._fieldOfView = value; + } + } + }); /** * Indicates whether the components of this object are equal to those of a specified object.