Skip to content

Commit 03d19bc

Browse files
committed
Tweak images to handle animation a bit better
1 parent 63cd19b commit 03d19bc

File tree

2 files changed

+58
-18
lines changed

2 files changed

+58
-18
lines changed

src/components/images/draw.js

+24-18
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,21 @@ module.exports = function draw(gd) {
5555
function setImage(d) {
5656
var thisImage = d3.select(this);
5757

58+
if(this.img && this.img.src === d.source) {
59+
return;
60+
}
61+
5862
thisImage.attr('xmlns', xmlnsNamespaces.svg);
5963

6064
var imagePromise = new Promise(function(resolve) {
6165

6266
var img = new Image();
67+
this.img = img;
6368

6469
// If not set, a `tainted canvas` error is thrown
6570
img.setAttribute('crossOrigin', 'anonymous');
6671
img.onerror = errorHandler;
6772
img.onload = function() {
68-
6973
var canvas = document.createElement('canvas');
7074
canvas.width = this.width;
7175
canvas.height = this.height;
@@ -88,7 +92,7 @@ module.exports = function draw(gd) {
8892
thisImage.remove();
8993
resolve();
9094
}
91-
});
95+
}.bind(this));
9296

9397
gd._promises.push(imagePromise);
9498
}
@@ -146,29 +150,31 @@ module.exports = function draw(gd) {
146150
}
147151
}
148152

149-
150-
// Required for updating images
151-
function keyFunction(d, i) {
152-
return d.source + i;
153-
}
154-
155-
156153
var imagesBelow = fullLayout._imageLowerLayer.selectAll('image')
157-
.data(imageDataBelow, keyFunction),
154+
.data(imageDataBelow),
158155
imagesSubplot = fullLayout._imageSubplotLayer.selectAll('image')
159-
.data(imageDataSubplot, keyFunction),
156+
.data(imageDataSubplot),
160157
imagesAbove = fullLayout._imageUpperLayer.selectAll('image')
161-
.data(imageDataAbove, keyFunction);
158+
.data(imageDataAbove);
162159

163-
imagesBelow.enter().append('image').each(setImage);
164-
imagesSubplot.enter().append('image').each(setImage);
165-
imagesAbove.enter().append('image').each(setImage);
160+
imagesBelow.enter().append('image');
161+
imagesSubplot.enter().append('image');
162+
imagesAbove.enter().append('image');
166163

167164
imagesBelow.exit().remove();
168165
imagesSubplot.exit().remove();
169166
imagesAbove.exit().remove();
170167

171-
imagesBelow.each(applyAttributes);
172-
imagesSubplot.each(applyAttributes);
173-
imagesAbove.each(applyAttributes);
168+
imagesBelow.each(function(d) {
169+
setImage.bind(this)(d);
170+
applyAttributes.bind(this)(d);
171+
});
172+
imagesSubplot.each(function(d) {
173+
setImage.bind(this)(d);
174+
applyAttributes.bind(this)(d);
175+
});
176+
imagesAbove.each(function(d) {
177+
setImage.bind(this)(d);
178+
applyAttributes.bind(this)(d);
179+
});
174180
};

test/jasmine/tests/transition_test.js

+34
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,41 @@ function runTests(transitionDuration) {
9090
expect(p1[1]).not.toEqual(p2[1]);
9191

9292
}).catch(fail).then(done);
93+
});
94+
95+
it('transitions an image', function(done) {
96+
var whitepx = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
97+
var blackpx = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=';
98+
99+
function imageel() {
100+
return gd._fullLayout._imageUpperLayer.select('image').node();
101+
}
102+
function imagesrc() {
103+
return imageel().getAttribute('href');
104+
}
105+
var p1, p2, e1, e2;
106+
107+
Plotly.relayout(gd, {images: [{x: 0, y: 0, source: whitepx}]}).then(function() {
108+
p1 = imagesrc();
109+
e1 = imageel();
110+
111+
return Plots.transition(gd, null, {
112+
'images[0].source': blackpx,
113+
}, [],
114+
{redraw: true, duration: transitionDuration},
115+
{duration: transitionDuration, easing: 'cubic-in-out'}
116+
);
117+
}).then(function() {
118+
p2 = imagesrc();
119+
e2 = imageel();
120+
121+
// Test that the image src has changed:
122+
expect(p1).not.toEqual(p2);
93123

124+
// Test that the image element identity has not:
125+
expect(e1).toBe(e2);
126+
127+
}).catch(fail).then(done);
94128
});
95129

96130
it('transitions a transform', function(done) {

0 commit comments

Comments
 (0)