UNPKG

aseprite-atlas

Version:

Aseprite sprite atlas parser and animator for browser and Node.js.

280 lines (268 loc) 9.67 kB
import {Animator} from './Animator' import {Aseprite} from '../types/Aseprite' describe('step()', () => { test('time < duration', () => { const cel = {position: {x: 0, y: 0}, duration: 1, slices: []} const animation = { size: {w: 0, h: 0}, cels: [cel, cel], duration: 2, direction: Aseprite.AnimationDirection.Forward } const animator = Animator.animate(0, 0.5, animation) expect(animator).toMatchObject({period: 0, exposure: 0.5}) }) test('time === duration', () => { const cel = {position: {x: 0, y: 0}, duration: 1, slices: []} const animation = { size: {w: 0, h: 0}, cels: [cel, cel], duration: 2, direction: Aseprite.AnimationDirection.Forward } const animator = Animator.animate(0, 1, animation) expect(animator).toMatchObject({period: 1, exposure: 0}) }) test('time > duration', () => { const cel = {position: {x: 0, y: 0}, duration: 1, slices: []} const animation = { size: {w: 0, h: 0}, cels: [cel, cel], duration: 2, direction: Aseprite.AnimationDirection.Forward } const animator = Animator.animate(0, 1.5, animation) expect(animator).toMatchObject({period: 1, exposure: 0.5}) }) }) describe('index', () => { test.each(Object.values(Aseprite.AnimationDirection))( '%# direction %p array start', direction => { const cel = {position: {x: 0, y: 0}, duration: 1, slices: []} const animation = { size: {w: 0, h: 0}, cels: [cel, cel], duration: 2, direction } const {period} = Animator.animate(0, 1, animation) const animator = Animator.index(period, animation.cels) expect(animator).toStrictEqual(1) } ) test.each(Object.values(Aseprite.AnimationDirection))( '%# direction %p array end', direction => { const cel = {position: {x: 0, y: 0}, duration: 1, slices: []} const animation = { size: {w: 0, h: 0}, cels: [cel, cel], duration: 2, direction } const {period} = Animator.animate(1, 1, animation) const animator = Animator.index(period, animation.cels) expect(animator).toStrictEqual(0) } ) test.each(< readonly [Aseprite.AnimationDirection, number, readonly number[]][] >[ [ Aseprite.AnimationDirection.Forward, 0, [1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0] ], [ Aseprite.AnimationDirection.Forward, Number.MAX_SAFE_INTEGER, [1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0] ], [ Aseprite.AnimationDirection.Reverse, Number.MIN_SAFE_INTEGER, [3, 2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 0] ], [ Aseprite.AnimationDirection.Reverse, 3, [2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 0, 3] ], [ Aseprite.AnimationDirection.PingPong, -2, [3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2] ], [ Aseprite.AnimationDirection.PingPong, 0, [1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2] ], [ Aseprite.AnimationDirection.PingPong, 3, [2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1] ] ])('%# direction %p bounds %p', (direction, period, expected) => { const cel = {position: {x: 0, y: 0}, duration: 1, slices: []} const animation = { size: {w: 0, h: 0}, cels: [cel, cel, cel, cel], duration: 4, direction } let exposure = 0 const playback = [] for (let i = 0; i < animation.cels.length * 5; ++i) { ;({period, exposure} = Animator.animate(period, exposure + 1, animation)) playback.push(Animator.index(period, animation.cels)) } expect(playback).toStrictEqual(expected) }) test.each(Object.values(Aseprite.AnimationDirection))( '%# duration met direction %p cycles', direction => { const cel = {position: {x: 0, y: 0}, duration: 1, slices: []} const animation = { size: {w: 0, h: 0}, cels: [cel, cel, cel, cel, cel], duration: 5, direction } let {period, exposure} = {period: 0, exposure: 0} const playback = [] for (let i = 0; i < animation.cels.length * 3; ++i) { ;({period, exposure} = Animator.animate( period, exposure + 1, animation )) playback.push(Animator.index(period, animation.cels)) } // prettier-ignore const expected = { [Aseprite.AnimationDirection.Forward]: [1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0], [Aseprite.AnimationDirection.Reverse]: [4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0], [Aseprite.AnimationDirection.PingPong]: [1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1] } expect(playback).toStrictEqual(expected[direction]) } ) test.each(Object.values(Aseprite.AnimationDirection))( '%# duration exceeded direction %p cycles', direction => { const cel = {position: {x: 0, y: 0}, duration: 1, slices: []} const animation = { size: {w: 0, h: 0}, cels: [cel, cel, cel, cel, cel], duration: 5, direction } let {period, exposure} = {period: 0, exposure: 0} const playback = [] for (let i = 0; i < animation.cels.length * 3; ++i) { ;({period, exposure} = Animator.animate( period, exposure + 6, animation )) playback.push(Animator.index(period, animation.cels)) } // prettier-ignore const expected = { [Aseprite.AnimationDirection.Forward]: [1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0], [Aseprite.AnimationDirection.Reverse]: [4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0], [Aseprite.AnimationDirection.PingPong]: [1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1] } expect(playback).toStrictEqual(expected[direction]) } ) test.each(Object.values(Aseprite.AnimationDirection))( '%# fractional duration met direction %p cycles', direction => { const cel = {position: {x: 0, y: 0}, duration: 1, slices: []} const animation = { size: {w: 0, h: 0}, cels: [cel, cel, cel, cel, cel], duration: 5, direction } let {period, exposure} = {period: 0, exposure: 0} const playback = [] for (let i = 0; i < animation.cels.length * 6; ++i) { ;({period, exposure} = Animator.animate( period, exposure + 0.5, animation )) playback.push(Animator.index(period, animation.cels)) } // prettier-ignore const expected = { [Aseprite.AnimationDirection.Forward]: [0, 1, 1, 2, 2, 3, 3, 4, 4, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 0], [Aseprite.AnimationDirection.Reverse]: [0, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 4, 4, 3, 3, 2, 2, 1, 1, 0], [Aseprite.AnimationDirection.PingPong]: [0, 1, 1, 2, 2, 3, 3, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 3, 3, 2, 2, 1] } expect(playback).toStrictEqual(expected[direction]) } ) test.each(Object.values(Aseprite.AnimationDirection))( '%# duration not met direction %p cycles', direction => { const cel = {position: {x: 0, y: 0}, duration: 1, slices: []} const animation = { size: {w: 0, h: 0}, cels: [cel, cel, cel, cel, cel], duration: 5, direction } let {period, exposure} = {period: 0, exposure: 0} const playback = [] for (let i = 0; i < animation.cels.length * 6; ++i) { ;({period, exposure} = Animator.animate( period, exposure + 0.9, animation )) playback.push(Animator.index(period, animation.cels)) } // prettier-ignore const expected = { [Aseprite.AnimationDirection.Forward]: [0, 1, 2, 3, 4, 0, 1, 2, 3, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 1], [Aseprite.AnimationDirection.Reverse]: [0, 4, 3, 2, 1, 0, 4, 3, 2, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 4], [Aseprite.AnimationDirection.PingPong]: [0, 1, 2, 3, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 2] } expect(playback).toStrictEqual(expected[direction]) } ) test.each(Object.values(Aseprite.AnimationDirection))( '%# fractional duration exceeded direction %p cycles', direction => { const cel = {position: {x: 0, y: 0}, duration: 1, slices: []} const animation = { size: {w: 0, h: 0}, cels: [cel, cel, cel, cel, cel], duration: 5, direction } let {period, exposure} = {period: 0, exposure: 0} const playback = [] for (let i = 0; i < animation.cels.length * 6; ++i) { ;({period, exposure} = Animator.animate( period, exposure + 5.5, animation )) playback.push(Animator.index(period, animation.cels)) } // prettier-ignore const expected = { [Aseprite.AnimationDirection.Forward]: [0, 1, 1, 2, 2, 3, 3, 4, 4, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 0], [Aseprite.AnimationDirection.Reverse]: [0, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 4, 4, 3, 3, 2, 2, 1, 1, 0], [Aseprite.AnimationDirection.PingPong]: [0, 1, 1, 2, 2, 3, 3, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 3, 3, 2, 2, 1] } expect(playback).toStrictEqual(expected[direction]) } ) })