Skip to content

Commit fe19e47

Browse files
committedOct 23, 2019
Store direct aspectratio edits and emit relayout
- combine two wheel listeners - use gl-plot3d aspect setter and getter
1 parent 4a649f0 commit fe19e47

File tree

6 files changed

+86
-50
lines changed

6 files changed

+86
-50
lines changed
 

‎package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
"gl-mat4": "^1.2.0",
8282
"gl-mesh3d": "^2.1.1",
8383
"gl-plot2d": "^1.4.2",
84-
"gl-plot3d": "git://github.com/gl-vis/gl-plot3d.git#4d41ca21b3c0a25db8776ce92261995323bb62e8",
84+
"gl-plot3d": "git://github.com/gl-vis/gl-plot3d.git#83e9c9406976e5ee92bf1f1851e4366e516c06f7",
8585
"gl-pointcloud2d": "^1.0.2",
8686
"gl-scatter3d": "^1.2.2",
8787
"gl-select-box": "^1.0.3",

‎src/plot_api/subroutines.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -578,8 +578,7 @@ exports.doCamera = function(gd) {
578578
var sceneLayout = fullLayout[sceneIds[i]];
579579
var scene = sceneLayout._scene;
580580

581-
var cameraData = sceneLayout.camera;
582-
scene.setCamera(cameraData);
581+
scene.setViewport(sceneLayout);
583582
}
584583
};
585584

‎src/plots/gl3d/scene.js

+70-39
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99

1010
'use strict';
1111

12-
var createCamera = require('gl-plot3d').createCamera;
13-
var createPlot = require('gl-plot3d').createScene;
14-
var mouseWheel = require('mouse-wheel');
12+
var glPlot3d = require('gl-plot3d');
13+
var createCamera = glPlot3d.createCamera;
14+
var createPlot = glPlot3d.createScene;
15+
1516
var getContext = require('webgl-context');
1617
var passiveSupported = require('has-passive-events');
1718

@@ -244,26 +245,7 @@ function tryCreatePlot(scene, cameraObject, pixelRatio, canvas, gl) {
244245
}
245246
}
246247

247-
if(failed < 2) {
248-
scene.wheelListener = mouseWheel(scene.glplot.canvas, function(dx, dy) {
249-
// TODO remove now that we can disable scroll via scrollZoom?
250-
if(scene.glplot.camera.keyBindingMode === false) return;
251-
if(!scene.glplot.camera.enableWheel) return;
252-
253-
if(scene.glplot.camera._ortho) {
254-
var s = (dx > dy) ? 1.1 : 1.0 / 1.1;
255-
256-
scene.fullSceneLayout.aspectratio.x = scene.glplot.aspect[0] *= s;
257-
scene.fullSceneLayout.aspectratio.y = scene.glplot.aspect[1] *= s;
258-
scene.fullSceneLayout.aspectratio.z = scene.glplot.aspect[2] *= s;
259-
260-
scene.glplot.redraw();
261-
}
262-
}, true);
263-
264-
return true;
265-
}
266-
return false;
248+
return failed < 2;
267249
}
268250

269251
function initializeGLPlot(scene, pixelRatio, canvas, gl) {
@@ -280,21 +262,45 @@ function initializeGLPlot(scene, pixelRatio, canvas, gl) {
280262

281263
var gd = scene.graphDiv;
282264

265+
var makeUpdate = function() {
266+
var update = {};
267+
268+
// camera updates
269+
update[scene.id + '.camera'] = getLayoutCamera(scene.camera);
270+
271+
// scene updates
272+
update[scene.id + '.aspectratio'] = scene.glplot.getAspectratio();
273+
274+
return update;
275+
};
276+
283277
var relayoutCallback = function(scene) {
284278
if(scene.fullSceneLayout.dragmode === false) return;
285279

286-
var update = {};
287-
update[scene.id + '.camera'] = getLayoutCamera(scene.camera);
288-
scene.saveCamera(gd.layout);
280+
var update = makeUpdate();
281+
scene.saveLayout(gd.layout);
289282
scene.graphDiv.emit('plotly_relayout', update);
290283
};
291284

292285
scene.glplot.canvas.addEventListener('mouseup', function() {
293286
relayoutCallback(scene);
294287
});
295288

296-
scene.glplot.canvas.addEventListener('wheel', function() {
289+
scene.glplot.canvas.addEventListener('wheel', function(e) {
297290
if(gd._context._scrollZoom.gl3d) {
291+
if(scene.glplot.camera._ortho) {
292+
var s = (e.deltaX > e.deltaY) ? 1.1 : 1.0 / 1.1;
293+
294+
var aspectratio = scene.fullSceneLayout.aspectratio;
295+
296+
aspectratio.x = scene.glplot.aspect[0] *= s;
297+
aspectratio.y = scene.glplot.aspect[1] *= s;
298+
aspectratio.z = scene.glplot.aspect[2] *= s;
299+
300+
scene.glplot.setAspectratio(aspectratio);
301+
scene.glplot.redraw();
302+
}
303+
298304
relayoutCallback(scene);
299305
}
300306
}, passiveSupported ? {passive: false} : false);
@@ -303,8 +309,7 @@ function initializeGLPlot(scene, pixelRatio, canvas, gl) {
303309
if(scene.fullSceneLayout.dragmode === false) return;
304310
if(scene.camera.mouseListener.buttons === 0) return;
305311

306-
var update = {};
307-
update[scene.id + '.camera'] = getLayoutCamera(scene.camera);
312+
var update = makeUpdate();
308313
scene.graphDiv.emit('plotly_relayouting', update);
309314
});
310315

@@ -516,7 +521,7 @@ proto.plot = function(sceneData, fullLayout, layout) {
516521
this.spikeOptions.merge(fullSceneLayout);
517522

518523
// Update camera and camera mode
519-
this.setCamera(fullSceneLayout.camera);
524+
this.setViewport(fullSceneLayout);
520525
this.updateFx(fullSceneLayout.dragmode, fullSceneLayout.hovermode);
521526
this.camera.enableWheel = this.graphDiv._context._scrollZoom.gl3d;
522527

@@ -740,8 +745,7 @@ proto.plot = function(sceneData, fullLayout, layout) {
740745
* Finally assign the computed aspecratio to the glplot module. This will have an effect
741746
* on the next render cycle.
742747
*/
743-
this.glplot.aspect = aspectRatio;
744-
748+
this.glplot.setAspectratio(fullSceneLayout.aspectratio);
745749

746750
// Update frame position for multi plots
747751
var domain = fullSceneLayout.domain || null;
@@ -771,9 +775,9 @@ proto.destroy = function() {
771775
this.glplot = null;
772776
};
773777

774-
// getOrbitCamera :: plotly_coords -> orbit_camera_coords
778+
// getCameraArrays :: plotly_coords -> orbit_camera_coords
775779
// inverse of getLayoutCamera
776-
function getOrbitCamera(camera) {
780+
function getCameraArrays(camera) {
777781
return [
778782
[camera.eye.x, camera.eye.y, camera.eye.z],
779783
[camera.center.x, camera.center.y, camera.center.z],
@@ -782,7 +786,7 @@ function getOrbitCamera(camera) {
782786
}
783787

784788
// getLayoutCamera :: orbit_camera_coords -> plotly_coords
785-
// inverse of getOrbitCamera
789+
// inverse of getCameraArrays
786790
function getLayoutCamera(camera) {
787791
return {
788792
up: {x: camera.up[0], y: camera.up[1], z: camera.up[2]},
@@ -798,9 +802,12 @@ proto.getCamera = function getCamera() {
798802
return getLayoutCamera(this.glplot.camera);
799803
};
800804

801-
// set camera position with a set of plotly coords
802-
proto.setCamera = function setCamera(cameraData) {
803-
this.glplot.camera.lookAt.apply(this, getOrbitCamera(cameraData));
805+
// set gl-plot3d camera position and scene aspects with a set of plotly coords
806+
proto.setViewport = function setViewport(sceneLayout) {
807+
var cameraData = sceneLayout.camera;
808+
809+
this.glplot.camera.lookAt.apply(this, getCameraArrays(cameraData));
810+
this.glplot.setAspectratio(sceneLayout.aspectratio);
804811

805812
var newOrtho = (cameraData.projection.type === 'orthographic');
806813
var oldOrtho = this.glplot.camera._ortho;
@@ -827,11 +834,17 @@ proto.setCamera = function setCamera(cameraData) {
827834
};
828835

829836
// save camera to user layout (i.e. gd.layout)
830-
proto.saveCamera = function saveCamera(layout) {
837+
proto.saveLayout = function saveLayout(layout) {
831838
var fullLayout = this.fullLayout;
839+
832840
var cameraData = this.getCamera();
833841
var cameraNestedProp = Lib.nestedProperty(layout, this.id + '.camera');
834842
var cameraDataLastSave = cameraNestedProp.get();
843+
844+
var aspectData = this.glplot.getAspectratio();
845+
var aspectNestedProp = Lib.nestedProperty(layout, this.id + '.camera');
846+
var aspectDataLastSave = aspectNestedProp.get();
847+
835848
var hasChanged = false;
836849

837850
function same(x, y, i, j) {
@@ -859,15 +872,33 @@ proto.saveCamera = function saveCamera(layout) {
859872
}
860873
}
861874

875+
if(!hasChanged) {
876+
if(aspectDataLastSave === undefined) {
877+
hasChanged = true;
878+
} else {
879+
if(
880+
aspectDataLastSave.x !== aspectData.x ||
881+
aspectDataLastSave.y !== aspectData.y ||
882+
aspectDataLastSave.z !== aspectData.z
883+
) {
884+
hasChanged = true;
885+
}
886+
}
887+
}
888+
862889
if(hasChanged) {
863890
var preGUI = {};
864891
preGUI[this.id + '.camera'] = cameraDataLastSave;
892+
preGUI[this.id + '.aspectratio'] = aspectDataLastSave;
865893
Registry.call('_storeDirectGUIEdit', layout, fullLayout._preGUI, preGUI);
866894

867895
cameraNestedProp.set(cameraData);
868896

869897
var cameraFullNP = Lib.nestedProperty(fullLayout, this.id + '.camera');
870898
cameraFullNP.set(cameraData);
899+
900+
var aspectFullNP = Lib.nestedProperty(fullLayout, this.id + '.aspectratio');
901+
aspectFullNP.set(aspectData);
871902
}
872903

873904
return hasChanged;

‎test/jasmine/tests/gl3d_plot_interact_test.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -1187,7 +1187,10 @@ describe('Test gl3d annotations', function() {
11871187
var camera = scene.getCamera();
11881188

11891189
camera.eye = {x: x, y: y, z: z};
1190-
scene.setCamera(camera);
1190+
scene.setViewport({
1191+
camera: camera,
1192+
aspectratio: gd._fullLayout.scene.aspectratio
1193+
});
11911194
// need a fairly long delay to let the camera update here
11921195
// 300 was not robust for me (AJ), 500 seems to be.
11931196
return delay(500)();

‎test/jasmine/tests/plot_api_react_test.js

+8-5
Original file line numberDiff line numberDiff line change
@@ -1968,11 +1968,14 @@ describe('Test Plotly.react + interactions under uirevision:', function() {
19681968
function _mouseup() {
19691969
var sceneLayout = gd._fullLayout.scene;
19701970
var cameraOld = sceneLayout.camera;
1971-
sceneLayout._scene.setCamera({
1972-
projection: {type: 'perspective'},
1973-
eye: {x: 2, y: 2, z: 2},
1974-
center: cameraOld.center,
1975-
up: cameraOld.up
1971+
sceneLayout._scene.setViewport({
1972+
camera: {
1973+
projection: {type: 'perspective'},
1974+
eye: {x: 2, y: 2, z: 2},
1975+
center: cameraOld.center,
1976+
up: cameraOld.up
1977+
},
1978+
aspectratio: gd._fullLayout.scene.aspectratio
19761979
});
19771980

19781981
var target = gd.querySelector('.svg-container .gl-container #scene canvas');

0 commit comments

Comments
 (0)
Please sign in to comment.