Created
November 18, 2020 13:05
-
-
Save fostyfost/65daac0f89dbbe842a753efb9c5b2a5a to your computer and use it in GitHub Desktop.
Raf animate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import createStub from 'raf-stub'; | |
import { animate, AnimateUtilParams } from '../animate'; | |
describe('`animate` util tests', () => { | |
const params = {} as AnimateUtilParams; | |
const DEFAULT_DURATION = 300; | |
const FRAME_DURATION = 10; | |
const DEFAULT_FRAMES_COUNT = DEFAULT_DURATION / FRAME_DURATION + 1; | |
let stub; | |
let spyOnRaf; | |
beforeEach(() => { | |
stub = createStub(FRAME_DURATION); | |
// @ts-ignore | |
spyOnRaf = jest.spyOn(global, 'requestAnimationFrame'); | |
spyOnRaf.mockImplementation(stub.add); | |
params.actionCallback = jest.fn(); | |
params.onFinish = jest.fn(); | |
params.duration = DEFAULT_DURATION; | |
}); | |
afterEach(() => { | |
spyOnRaf.mockRestore(); | |
}); | |
it('returns request animation frame ID > 0', () => { | |
expect(animate(params) > 0).toBe(true); | |
}); | |
it(`runs \`actionCallback\` callback ${DEFAULT_FRAMES_COUNT} times by default`, () => { | |
animate(params); | |
stub.flush(); | |
// @ts-ignore | |
expect(params.actionCallback.mock.calls.length).toBe(params.duration / FRAME_DURATION + 1); | |
}); | |
it(`runs \`actionCallback\` callback ${1000 / FRAME_DURATION + 1} times if duration is 1000`, () => { | |
animate({ ...params, duration: 1000 }); | |
stub.flush(); | |
// @ts-ignore | |
expect(params.actionCallback.mock.calls.length).toBe(1000 / FRAME_DURATION + 1); | |
}); | |
it(`runs \`actionCallback\` callback 1 time if duration is 1`, () => { | |
animate({ ...params, duration: 1 }); | |
stub.flush(); | |
// @ts-ignore | |
expect(params.actionCallback.mock.calls.length).toBe(1); | |
}); | |
it('runs `onFinish` callback after animation', () => { | |
animate(params); | |
expect(params.onFinish).not.toBeCalled(); | |
stub.step(); | |
expect(params.onFinish).not.toBeCalled(); | |
stub.flush(); | |
// @ts-ignore | |
expect(params.onFinish.mock.calls.length).toBe(1); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import _noop from 'lodash/noop'; | |
export interface AnimateUtilParams { | |
actionCallback?: (timeFraction: number) => void; | |
onFinish?: () => void; | |
duration?: number; | |
} | |
export const animate = ({ actionCallback = _noop, onFinish = _noop, duration = 300 }: AnimateUtilParams): number => { | |
const start = performance.now(); | |
return requestAnimationFrame(function cb(time: number): void { | |
// `progress` изменяется от -N до 1 | |
let progress = (time - start) / duration; | |
if (progress > 1) { | |
progress = 1; | |
} | |
actionCallback(progress); | |
if (progress < 1) { | |
requestAnimationFrame(cb); | |
} else { | |
onFinish(); | |
} | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment