Skip to content

Commit 53ba120

Browse files
authored
Merge pull request #1364 from plotly/relayout-scene-camera
Make relayout work for `scene.camera`
2 parents 32e4e09 + 5aea58c commit 53ba120

File tree

6 files changed

+233
-133
lines changed

6 files changed

+233
-133
lines changed

src/components/modebar/buttons.js

+10-7
Original file line numberDiff line numberDiff line change
@@ -306,20 +306,23 @@ function handleCamera3d(gd, ev) {
306306
var button = ev.currentTarget,
307307
attr = button.getAttribute('data-attr'),
308308
fullLayout = gd._fullLayout,
309-
sceneIds = Plots.getSubplotIds(fullLayout, 'gl3d');
309+
sceneIds = Plots.getSubplotIds(fullLayout, 'gl3d'),
310+
aobj = {};
310311

311312
for(var i = 0; i < sceneIds.length; i++) {
312313
var sceneId = sceneIds[i],
313-
fullSceneLayout = fullLayout[sceneId],
314-
scene = fullSceneLayout._scene;
314+
key = sceneId + '.camera',
315+
scene = fullLayout[sceneId]._scene;
315316

316-
if(attr === 'resetDefault') scene.setCameraToDefault();
317+
if(attr === 'resetDefault') {
318+
aobj[key] = null;
319+
}
317320
else if(attr === 'resetLastSave') {
318-
// This handler looks in the un-updated fullLayout.scene.camera object to reset the camera
319-
// to the last saved position.
320-
scene.setCamera(fullSceneLayout.camera);
321+
aobj[key] = Lib.extendDeep({}, scene.cameraInitial);
321322
}
322323
}
324+
325+
Plotly.relayout(gd, aobj);
323326
}
324327

325328
modeBarButtons.hoverClosest3d = {

src/plot_api/plot_api.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,7 @@ Plotly.relayout = function relayout(gd, astr, val) {
17241724
if(flags.dolayoutstyle) seq.push(subroutines.layoutStyles);
17251725
if(flags.doticks) seq.push(subroutines.doTicksRelayout);
17261726
if(flags.domodebar) seq.push(subroutines.doModeBar);
1727+
if(flags.docamera) seq.push(subroutines.doCamera);
17271728
}
17281729

17291730
Queue.add(gd,
@@ -1771,6 +1772,7 @@ function _relayout(gd, aobj) {
17711772
doplot: false,
17721773
docalc: false,
17731774
domodebar: false,
1775+
docamera: false,
17741776
layoutReplot: false
17751777
};
17761778

@@ -1967,7 +1969,10 @@ function _relayout(gd, aobj) {
19671969
var pp1 = String(p.parts[1] || '');
19681970
// check whether we can short-circuit a full redraw
19691971
// 3d or geo at this point just needs to redraw.
1970-
if(p.parts[0].indexOf('scene') === 0) flags.doplot = true;
1972+
if(p.parts[0].indexOf('scene') === 0) {
1973+
if(p.parts[1] === 'camera') flags.docamera = true;
1974+
else flags.doplot = true;
1975+
}
19711976
else if(p.parts[0].indexOf('geo') === 0) flags.doplot = true;
19721977
else if(p.parts[0].indexOf('ternary') === 0) flags.doplot = true;
19731978
else if(ai === 'paper_bgcolor') flags.doplot = true;
@@ -2119,6 +2124,7 @@ Plotly.update = function update(gd, traceUpdate, layoutUpdate, traces) {
21192124
if(relayoutFlags.dolayoutstyle) seq.push(subroutines.layoutStyles);
21202125
if(relayoutFlags.doticks) seq.push(subroutines.doTicksRelayout);
21212126
if(relayoutFlags.domodebar) seq.push(subroutines.doModeBar);
2127+
if(relayoutFlags.doCamera) seq.push(subroutines.doCamera);
21222128
}
21232129

21242130
Queue.add(gd,

src/plot_api/subroutines.js

+12
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,15 @@ exports.doModeBar = function(gd) {
314314

315315
return Plots.previousPromises(gd);
316316
};
317+
318+
exports.doCamera = function(gd) {
319+
var fullLayout = gd._fullLayout,
320+
sceneIds = Plots.getSubplotIds(fullLayout, 'gl3d');
321+
322+
for(var i = 0; i < sceneIds.length; i++) {
323+
var sceneLayout = fullLayout[sceneIds[i]],
324+
scene = sceneLayout._scene;
325+
326+
scene.setCamera(sceneLayout.camera);
327+
}
328+
};

src/plots/gl3d/index.js

+7-9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
var Scene = require('./scene');
1313
var Plots = require('../plots');
14+
var Lib = require('../../lib');
1415
var xmlnsNamespaces = require('../../constants/xmlns_namespaces');
1516

1617
var axesNames = ['xaxis', 'yaxis', 'zaxis'];
@@ -37,21 +38,13 @@ exports.plot = function plotGl3d(gd) {
3738
fullData = gd._fullData,
3839
sceneIds = Plots.getSubplotIds(fullLayout, 'gl3d');
3940

40-
fullLayout._paperdiv.style({
41-
width: fullLayout.width + 'px',
42-
height: fullLayout.height + 'px'
43-
});
44-
45-
gd._context.setBackground(gd, fullLayout.paper_bgcolor);
46-
4741
for(var i = 0; i < sceneIds.length; i++) {
4842
var sceneId = sceneIds[i],
4943
fullSceneData = Plots.getSubplotData(fullData, 'gl3d', sceneId),
5044
sceneLayout = fullLayout[sceneId],
5145
scene = sceneLayout._scene;
5246

53-
// If Scene is not instantiated, create one!
54-
if(scene === undefined) {
47+
if(!scene) {
5548
initAxes(gd, sceneLayout);
5649

5750
scene = new Scene({
@@ -68,6 +61,11 @@ exports.plot = function plotGl3d(gd) {
6861
sceneLayout._scene = scene;
6962
}
7063

64+
// save 'initial' camera settings for modebar button
65+
if(!scene.cameraInitial) {
66+
scene.cameraInitial = Lib.extendDeep({}, sceneLayout.camera);
67+
}
68+
7169
scene.plot(fullSceneData, fullLayout, gd.layout);
7270
}
7371
};

src/plots/gl3d/scene.js

+3-19
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ function computeTraceBounds(scene, trace, bounds) {
321321
}
322322

323323
proto.plot = function(sceneData, fullLayout, layout) {
324+
324325
// Save parameters
325326
this.plotArgs = [sceneData, fullLayout, layout];
326327

@@ -343,7 +344,8 @@ proto.plot = function(sceneData, fullLayout, layout) {
343344
this.axesOptions.merge(fullSceneLayout);
344345
this.spikeOptions.merge(fullSceneLayout);
345346

346-
// Update camera mode
347+
// Update camera and camera mode
348+
this.setCamera(fullSceneLayout.camera);
347349
this.updateFx(fullSceneLayout.dragmode, fullSceneLayout.hovermode);
348350

349351
// Update scene
@@ -564,18 +566,6 @@ proto.destroy = function() {
564566
this.glplot = null;
565567
};
566568

567-
568-
// for reset camera button in mode bar
569-
proto.setCameraToDefault = function setCameraToDefault() {
570-
// as in Gl3d.layoutAttributes
571-
572-
this.setCamera({
573-
eye: { x: 1.25, y: 1.25, z: 1.25 },
574-
center: { x: 0, y: 0, z: 0 },
575-
up: { x: 0, y: 0, z: 1 }
576-
});
577-
};
578-
579569
// getOrbitCamera :: plotly_coords -> orbit_camera_coords
580570
// inverse of getLayoutCamera
581571
function getOrbitCamera(camera) {
@@ -604,13 +594,7 @@ proto.getCamera = function getCamera() {
604594

605595
// set camera position with a set of plotly coords
606596
proto.setCamera = function setCamera(cameraData) {
607-
608-
var update = {};
609-
610-
update[this.id] = cameraData;
611-
612597
this.glplot.camera.lookAt.apply(this, getOrbitCamera(cameraData));
613-
this.graphDiv.emit('plotly_relayout', update);
614598
};
615599

616600
// save camera to user layout (i.e. gd.layout)

0 commit comments

Comments
 (0)