Skip to content

Commit de6a183

Browse files
authored
Merge pull request #953 from plotly/animation-frame-events
Emit plotly_animatingframe event on animated frames
2 parents 920a333 + 627c8e1 commit de6a183

File tree

2 files changed

+56
-12
lines changed

2 files changed

+56
-12
lines changed

src/plot_api/plot_api.js

+36-12
Original file line numberDiff line numberDiff line change
@@ -2201,13 +2201,13 @@ Plotly.animate = function(gd, frameOrGroupNameOrFrameList, animationOpts) {
22012201
for(var i = 0; i < frameList.length; i++) {
22022202
var computedFrame;
22032203

2204-
if(frameList[i].name) {
2204+
if(frameList[i].type === 'byname') {
22052205
// If it's a named frame, compute it:
22062206
computedFrame = Plots.computeFrame(gd, frameList[i].name);
22072207
} else {
22082208
// Otherwise we must have been given a simple object, so treat
22092209
// the input itself as the computed frame.
2210-
computedFrame = frameList[i].frame;
2210+
computedFrame = frameList[i].data;
22112211
}
22122212

22132213
var frameOpts = getFrameOpts(i);
@@ -2274,6 +2274,15 @@ Plotly.animate = function(gd, frameOrGroupNameOrFrameList, animationOpts) {
22742274
var newFrame = trans._currentFrame = trans._frameQueue.shift();
22752275

22762276
if(newFrame) {
2277+
gd.emit('plotly_animatingframe', {
2278+
name: newFrame.name,
2279+
frame: newFrame.frame,
2280+
animation: {
2281+
frame: newFrame.frameOpts,
2282+
transition: newFrame.transitionOpts,
2283+
}
2284+
});
2285+
22772286
trans._lastFrameAt = Date.now();
22782287
trans._timeToNext = newFrame.frameOpts.duration;
22792288

@@ -2342,34 +2351,49 @@ Plotly.animate = function(gd, frameOrGroupNameOrFrameList, animationOpts) {
23422351
var isSingleFrame = !allFrames && !isFrameArray && Lib.isPlainObject(frameOrGroupNameOrFrameList);
23432352

23442353
if(isSingleFrame) {
2345-
frameList.push(setTransitionConfig({
2346-
frame: Lib.extendFlat({}, frameOrGroupNameOrFrameList)
2347-
}));
2354+
// In this case, a simple object has been passed to animate.
2355+
frameList.push({
2356+
type: 'object',
2357+
data: setTransitionConfig(Lib.extendFlat({}, frameOrGroupNameOrFrameList))
2358+
});
23482359
} else if(allFrames || typeof frameOrGroupNameOrFrameList === 'string') {
2360+
// In this case, null or undefined has been passed so that we want to
2361+
// animate *all* currently defined frames
23492362
for(i = 0; i < trans._frames.length; i++) {
23502363
frame = trans._frames[i];
23512364

23522365
if(allFrames || frame.group === frameOrGroupNameOrFrameList) {
2353-
frameList.push(setTransitionConfig({name: frame.name}));
2366+
frameList.push({
2367+
type: 'byname',
2368+
name: frame.name,
2369+
data: setTransitionConfig({name: frame.name})
2370+
});
23542371
}
23552372
}
23562373
} else if(isFrameArray) {
23572374
for(i = 0; i < frameOrGroupNameOrFrameList.length; i++) {
23582375
var frameOrName = frameOrGroupNameOrFrameList[i];
23592376
if(typeof frameOrName === 'string') {
2360-
frameList.push(setTransitionConfig({name: frameOrName}));
2377+
// In this case, there's an array and this frame is a string name:
2378+
frameList.push({
2379+
type: 'byname',
2380+
name: frameOrName,
2381+
data: setTransitionConfig({name: frameOrName})
2382+
});
23612383
} else {
2362-
frameList.push(setTransitionConfig({
2363-
frame: Lib.extendFlat({}, frameOrName)
2364-
}));
2384+
frameList.push({
2385+
type: 'object',
2386+
data: setTransitionConfig(Lib.extendFlat({}, frameOrName))
2387+
});
23652388
}
23662389
}
23672390
}
23682391

23692392
// Verify that all of these frames actually exist; return and reject if not:
23702393
for(i = 0; i < frameList.length; i++) {
2371-
if(frameList[i].name && !trans._frameHash[frameList[i].name]) {
2372-
Lib.warn('animate failure: frame not found: "' + frameList[i].name + '"');
2394+
frame = frameList[i];
2395+
if(frame.type === 'byname' && !trans._frameHash[frame.data.name]) {
2396+
Lib.warn('animate failure: frame not found: "' + frame.data.name + '"');
23732397
reject();
23742398
return;
23752399
}

test/jasmine/tests/animate_test.js

+20
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,26 @@ describe('Test animate API', function() {
406406
});
407407
});
408408

409+
describe('frame events', function() {
410+
it('emits an event when a frame is transitioned to', function(done) {
411+
var frames = [];
412+
gd.on('plotly_animatingframe', function(data) {
413+
frames.push(data.name);
414+
expect(data.frame).not.toBe(undefined);
415+
expect(data.animation.frame).not.toBe(undefined);
416+
expect(data.animation.transition).not.toBe(undefined);
417+
});
418+
419+
Plotly.animate(gd, ['frame0', 'frame1', {name: 'test'}, {data: []}], {
420+
transition: {duration: 1},
421+
frame: {duration: 1}
422+
}).then(function() {
423+
expect(frames).toEqual(['frame0', 'frame1', undefined, undefined]);
424+
}).catch(fail).then(done);
425+
426+
});
427+
});
428+
409429
describe('frame vs. transition timing', function() {
410430
it('limits the transition duration to <= frame duration', function(done) {
411431
Plotly.animate(gd, ['frame0'], {

0 commit comments

Comments
 (0)