diff --git a/index.php b/index.php index b901b98b5..c3067155e 100644 --- a/index.php +++ b/index.php @@ -1397,6 +1397,20 @@ function attr($attr, $file) { +
+ + + +
+ + + diff --git a/resources/js/HelioviewerWebClient.js b/resources/js/HelioviewerWebClient.js index 2f00529dc..8321bcd62 100644 --- a/resources/js/HelioviewerWebClient.js +++ b/resources/js/HelioviewerWebClient.js @@ -382,14 +382,35 @@ var HelioviewerWebClient = HelioviewerClient.extend( * initializes event-handlers */ _setupSettingsUI: function () { - var form, dateLatest, datePrevious, autorefresh, autoplay, duration, self = this; + let self = this; + + let form = $("#helioviewer-settings"); + let dateLatest = $("#settings-date-latest"); + let datePrevious = $("#settings-date-previous"); + let autorefresh = $("#settings-latest-image"); + let autoplay = $("#settings-movie-play-automatic"); + let duration = $("#settings-movie-duration"); + let zoom_type = $("#js-zoom-type"); + let zoom_focus = $("#js-zoom-focus"); + let zoom_label = $('#js-zoom-label') + zoom_label.qtip({ + show: { + delay: 0 + }, + content: { + text: zoom_label.attr('title') + }, + }); - form = $("#helioviewer-settings"); - dateLatest = $("#settings-date-latest"); - datePrevious = $("#settings-date-previous"); - autorefresh = $("#settings-latest-image"); - autoplay = $("#settings-movie-play-automatic"); - duration = $("#settings-movie-duration"); + let focus_label = $('#js-focus-label'); + focus_label.qtip({ + show: { + delay: 0 + }, + content: { + text: focus_label.attr('title') + }, + }) // Starting date if (Helioviewer.userSettings.get("options.date") === "latest") { @@ -417,6 +438,10 @@ var HelioviewerWebClient = HelioviewerClient.extend( // Default movie duration duration.val(Helioviewer.userSettings.get("options.movies.duration")); + // Zoom config + zoom_type.val(Helioviewer.userSettings.get('zoom.type')); + zoom_focus.val(Helioviewer.userSettings.get('zoom.focus')); + // Event-handlers dateLatest.change(function (e) { Helioviewer.userSettings.set("options.date", "latest"); @@ -439,7 +464,12 @@ var HelioviewerWebClient = HelioviewerClient.extend( duration.change(function () { Helioviewer.userSettings.set("options.movies.duration", parseInt(this.value, 10)); }); - + zoom_focus.change(function () { + Helioviewer.userSettings.set("zoom.focus", this.value); + }); + zoom_type.change(function () { + Helioviewer.userSettings.set("zoom.type", this.value); + }); }, /** diff --git a/resources/js/Utility/SettingsLoader.js b/resources/js/Utility/SettingsLoader.js index 0263d1e62..6a902bf18 100644 --- a/resources/js/Utility/SettingsLoader.js +++ b/resources/js/Utility/SettingsLoader.js @@ -205,6 +205,10 @@ var SettingsLoader = ( "celestialBodiesLabelsVisible" : {}, "celestialBodiesTrajectoriesVisible" : {} }, + zoom: { + type: 'continuous', + focus: 'center' + }, version: serverSettings.version }; } diff --git a/resources/js/Viewport/Helper/HelioviewerZoomer.js b/resources/js/Viewport/Helper/HelioviewerZoomer.js index 5fe26b397..b35a6f02c 100644 --- a/resources/js/Viewport/Helper/HelioviewerZoomer.js +++ b/resources/js/Viewport/Helper/HelioviewerZoomer.js @@ -27,6 +27,10 @@ const MAX_THRESHOLD = 1.5; this._maxImageScale = zoomLevels[0]; this._minImageScale = zoomLevels[zoomLevels.length - 1]; this._slider = new ZoomControls(this._maxImageScale, zoomLevels.length - 1, this._targetCenter.bind(this), this.jumpToZoomLevel.bind(this)); + this._step = { + lock: false, + lastVal: 0 + }; Helioviewer.userSettings.set('mobileZoomScale', 1); // Make sure the sun is centered when the user requests centering the viewport @@ -253,14 +257,26 @@ const MAX_THRESHOLD = 1.5; * Fired when 2 fingers touch the screen */ pinchStart(center) { - this.setAnchorForCenter(center); + if (Helioviewer.userSettings.get('zoom.focus') == 'center') { + // If setting is set to focus on the center of the screen, always do that. + this._targetCenter(); + } else { + // Focus on the target that was given by the pinch/cursor. + this.setAnchorForCenter(center); + } this._last_size = 0; + this._step.lastVal = 0; } /** * Fires as a user pinches/stretches */ pinchUpdate(size) { + // Don't do anything if the user has step zoom enabled. + if (Helioviewer.userSettings.get('zoom.type') == 'step') { + this._stepZoom(size) + return; + } let change = (size - this._last_size) / 200; this.setScale(this._scale + change); this._last_size = size; @@ -269,6 +285,29 @@ const MAX_THRESHOLD = 1.5; pinchEnd() { } + /** + * Handle step zooming if user has enabled it. + */ + _stepZoom(size) { + // Debounce the step zoom. A lot of step events can come in at once. + if (this._step.lock) { + return; + } + + if (size > this._step.lastVal) { + this._zoomHelioviewer(2, true); + } else if (size < this._step.lastVal) { + this._zoomHelioviewer(0.5, false); + } else { + // zoom didn't change, don't enable the scroll lock, just do nothing. + // this happens on some high resolution touchpads (mac) + return; + } + this._step.lastVal = size; + this._step.lock = true; + setTimeout(() => {this._step.lock = false;}, 500); + } + onUpdateViewport() { // Set anchor to center screen let center = { @@ -332,14 +371,28 @@ const MAX_THRESHOLD = 1.5; * Executed when the zoom in button is clicked. */ _smoothZoomIn() { - this._animateZoom(2, 0.2); + this._targetCenter(); + // Non step zoom will use zoom animation. + if (Helioviewer.userSettings.get('zoom.type') != 'step') { + this._animateZoom(2, 0.2); + } else { + // Step zoom just jumps forward + this._zoomHelioviewer(2, true); + } } /** * Executed when the zoom out button is clicked. */ _smoothZoomOut() { - this._animateZoom(0.5, 0.2); + this._targetCenter(); + // Non step zoom will use zoom animation. + if (Helioviewer.userSettings.get('zoom.type') != 'step') { + this._animateZoom(0.5, 0.2); + } else { + // step zoom will just jump out. + this._zoomHelioviewer(0.5, false); + } } /**