Skip to content

Commit

Permalink
feat: animation duration.offset
Browse files Browse the repository at this point in the history
  • Loading branch information
romelperez committed Dec 18, 2019
1 parent 9646fc9 commit 7c05e44
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 9 deletions.
Expand Up @@ -41,7 +41,8 @@ AnimationProvider.propTypes = {
enter: PropTypes.number,
exit: PropTypes.number,
stagger: PropTypes.number,
delay: PropTypes.number
delay: PropTypes.number,
offset: PropTypes.number
})
]),
children: PropTypes.any
Expand Down
3 changes: 2 additions & 1 deletion packages/animation/src/Energy/Energy.js
Expand Up @@ -25,7 +25,8 @@ class Component extends React.PureComponent {
PropTypes.shape({
enter: PropTypes.number,
exit: PropTypes.number,
delay: PropTypes.number
delay: PropTypes.number,
offset: PropTypes.number
})
]),
merge: PropTypes.bool,
Expand Down
86 changes: 86 additions & 0 deletions packages/animation/src/Stream/Stream.animation.test.js
Expand Up @@ -99,6 +99,52 @@ describe('staggering mode', () => {
expect(energy3.getFlow().entered).toBeTruthy();
});

test('Should enter animate staggering children nodes with duration offsets', () => {
let stream, energy1, energy2, energy3;
render(
<Stream ref={r => (stream = r)} duration={{ stagger: 50 }}>
<Energy ref={r => (energy1 = r)} duration={{ enter: 100 }} />
<Energy ref={r => (energy2 = r)} duration={{ enter: 100, offset: 100 }} />
<Energy ref={r => (energy3 = r)} duration={{ enter: 100 }} />
</Stream>
);

expect(stream.getFlow().exited).toBeTruthy();
expect(energy1.getFlow().exited).toBeTruthy();
expect(energy2.getFlow().exited).toBeTruthy();
expect(energy3.getFlow().exited).toBeTruthy();

jest.advanceTimersByTime(10);
expect(stream.getFlow().entering).toBeTruthy();
expect(energy1.getFlow().entering).toBeTruthy();
expect(energy2.getFlow().exited).toBeTruthy();
expect(energy3.getFlow().exited).toBeTruthy();

jest.advanceTimersByTime(150); // 160ms
expect(stream.getFlow().entering).toBeTruthy();
expect(energy1.getFlow().entered).toBeTruthy();
expect(energy2.getFlow().entering).toBeTruthy();
expect(energy3.getFlow().exited).toBeTruthy();

jest.advanceTimersByTime(50); // 210ms
expect(stream.getFlow().entering).toBeTruthy();
expect(energy1.getFlow().entered).toBeTruthy();
expect(energy2.getFlow().entering).toBeTruthy();
expect(energy3.getFlow().entering).toBeTruthy();

jest.advanceTimersByTime(50); // 260ms
expect(stream.getFlow().entering).toBeTruthy();
expect(energy1.getFlow().entered).toBeTruthy();
expect(energy2.getFlow().entered).toBeTruthy();
expect(energy3.getFlow().entering).toBeTruthy();

jest.advanceTimersByTime(50); // 310ms
expect(stream.getFlow().entered).toBeTruthy();
expect(energy1.getFlow().entered).toBeTruthy();
expect(energy2.getFlow().entered).toBeTruthy();
expect(energy3.getFlow().entered).toBeTruthy();
});

test('Should enter animate staggering children nodes with node delay and no effect of item delays', () => {
let stream, energy1, energy2, energy3;
render(
Expand Down Expand Up @@ -198,6 +244,46 @@ describe('serial mode', () => {
expect(energy2.getFlow().entered).toBeTruthy();
expect(energy3.getFlow().entered).toBeTruthy();
});

test('Should enter animate serial children nodes with duration offsets', () => {
let stream, energy1, energy2, energy3;
render(
<Stream ref={r => (stream = r)} serial>
<Energy ref={r => (energy1 = r)} duration={{ enter: 100 }} />
<Energy ref={r => (energy2 = r)} duration={{ enter: 100, offset: 100 }} />
<Energy ref={r => (energy3 = r)} duration={{ enter: 100 }} />
</Stream>
);

expect(stream.getFlow().exited).toBeTruthy();
expect(energy1.getFlow().exited).toBeTruthy();
expect(energy2.getFlow().exited).toBeTruthy();
expect(energy3.getFlow().exited).toBeTruthy();

jest.advanceTimersByTime(10);
expect(stream.getFlow().entering).toBeTruthy();
expect(energy1.getFlow().entering).toBeTruthy();
expect(energy2.getFlow().exited).toBeTruthy();
expect(energy3.getFlow().exited).toBeTruthy();

jest.advanceTimersByTime(200); // 210ms
expect(stream.getFlow().entering).toBeTruthy();
expect(energy1.getFlow().entered).toBeTruthy();
expect(energy2.getFlow().entering).toBeTruthy();
expect(energy3.getFlow().exited).toBeTruthy();

jest.advanceTimersByTime(100); // 310ms
expect(stream.getFlow().entering).toBeTruthy();
expect(energy1.getFlow().entered).toBeTruthy();
expect(energy2.getFlow().entered).toBeTruthy();
expect(energy3.getFlow().entering).toBeTruthy();

jest.advanceTimersByTime(100); // 410ms
expect(stream.getFlow().entered).toBeTruthy();
expect(energy1.getFlow().entered).toBeTruthy();
expect(energy2.getFlow().entered).toBeTruthy();
expect(energy3.getFlow().entered).toBeTruthy();
});
});

test('Should exit animate children at the same time', () => {
Expand Down
19 changes: 15 additions & 4 deletions packages/animation/src/Stream/Stream.js
Expand Up @@ -29,7 +29,8 @@ class Component extends React.PureComponent {
enter: PropTypes.number,
exit: PropTypes.number,
stagger: PropTypes.number,
delay: PropTypes.number
delay: PropTypes.number,
offset: PropTypes.number
})
]),
serial: PropTypes.bool,
Expand Down Expand Up @@ -116,18 +117,21 @@ class Component extends React.PureComponent {
if (this.props.serial) {
enter = this.subscribers.reduce((total, subscriber) => {
const subscriberDuration = subscriber.getDuration();
return total + subscriberDuration.delay + subscriberDuration.enter;
return total + subscriberDuration.offset + subscriberDuration.delay + subscriberDuration.enter;
}, 0);
}
// Staggering
else {
let accumulation = 0;

this.subscribers.forEach((subscriber, index) => {
const subscriberDuration = subscriber.getDuration();
accumulation += subscriberDuration.offset;
const staggerDuration = (duration.stagger * index);

enter = Math.max(
enter,
staggerDuration + subscriberDuration.delay + subscriberDuration.enter
staggerDuration + accumulation + subscriberDuration.delay + subscriberDuration.enter
);
});
}
Expand Down Expand Up @@ -209,6 +213,8 @@ class Component extends React.PureComponent {
let acummulation = 0;

this.subscribers.forEach((subscriber, index) => {
const itemDuration = subscriber.getDuration();
acummulation += itemDuration.offset;
const itemTime = duration.delay + acummulation;

this.scheduler.start(index, itemTime, () => subscriber.updateActivation(true));
Expand All @@ -220,8 +226,13 @@ class Component extends React.PureComponent {
enterChildrenInStaggering () {
const duration = this.getDuration();

let accumulation = 0;

this.subscribers.forEach((subscriber, index) => {
const itemTime = duration.delay + (duration.stagger * index);
const itemDuration = subscriber.getDuration();
accumulation += itemDuration.offset;
const itemTime = accumulation + duration.delay + (duration.stagger * index);

this.scheduler.start(index, itemTime, () => subscriber.updateActivation(true));
});
}
Expand Down
Expand Up @@ -2,7 +2,7 @@ function makeDurationManager (component) {
let customDuration;

function get () {
const defaultDuration = { enter: 200, exit: 200, stagger: 50, delay: 0 };
const defaultDuration = { enter: 200, exit: 200, stagger: 50, delay: 0, offset: 0 };

const providedDuration = component.props.animationContext.duration;

Expand Down
Expand Up @@ -3,10 +3,10 @@
import { makeDurationManager } from './makeDurationManager';

describe('get()', () => {
test('Should get 200ms for enter/exit, 0ms for delay, 50ms for stagger, by default', () => {
test('Should get 200ms for enter/exit, 0ms for delay, 50ms for stagger, 0ms for offset, by default', () => {
const component = { props: { animationContext: {} } };
const durationManager = makeDurationManager(component);
expect(durationManager.get()).toMatchObject({ enter: 200, exit: 200, delay: 0 });
expect(durationManager.get()).toMatchObject({ enter: 200, exit: 200, delay: 0, offset: 0 });
});

test('Should duration be extended by animation context', () => {
Expand Down

0 comments on commit 7c05e44

Please sign in to comment.