UNPKG

aseprite-atlas

Version:

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

403 lines (384 loc) 11.2 kB
import {Aseprite} from '../types/Aseprite' import {Parser} from './Parser' describe('parse()', () => { test('Parses Animations.', () => { const frameTags = [ {name: 'sceneryCloud', from: 0, to: 0, direction: 'forward'}, {name: 'palette-red', from: 1, to: 1, direction: 'forward'}, {name: 'sceneryConifer', from: 2, to: 2, direction: 'forward'}, {name: 'sceneryConifer-shadow', from: 3, to: 3, direction: 'forward'} ] const frames = { 'sceneryCloud 0': { frame: {x: 220, y: 18, w: 18, h: 18}, rotated: false, trimmed: false, spriteSourceSize: {x: 0, y: 0, w: 16, h: 16}, sourceSize: {w: 16, h: 16}, duration: 1 }, 'palette-red 1': { frame: {x: 90, y: 54, w: 18, h: 18}, rotated: false, trimmed: false, spriteSourceSize: {x: 0, y: 0, w: 16, h: 16}, sourceSize: {w: 16, h: 16}, duration: 65535 }, 'sceneryConifer 2': { frame: {x: 72, y: 54, w: 18, h: 18}, rotated: false, trimmed: false, spriteSourceSize: {x: 0, y: 0, w: 16, h: 16}, sourceSize: {w: 16, h: 16}, duration: 65535 }, 'sceneryConifer-shadow 3': { frame: {x: 54, y: 54, w: 18, h: 18}, rotated: false, trimmed: false, spriteSourceSize: {x: 0, y: 0, w: 16, h: 16}, sourceSize: {w: 16, h: 16}, duration: 65535 } } const slices = [ { name: 'sceneryCloud', color: '#0000ffff', keys: [{frame: 0, bounds: {x: 8, y: 12, w: 2, h: 3}}] }, { name: 'palette-red', color: '#0000ffff', keys: [{frame: 0, bounds: {x: 7, y: 11, w: 3, h: 4}}] }, { name: 'sceneryConifer', color: '#0000ffff', keys: [{frame: 0, bounds: {x: 7, y: 10, w: 3, h: 5}}] }, { name: 'sceneryConifer-shadow', color: '#0000ffff', keys: [{frame: 0, bounds: {x: 7, y: 9, w: 3, h: 6}}] } ] expect( Parser.parseAnimationRecord({ meta: <Aseprite.Meta>(<unknown>{frameTags, slices}), frames }) ).toStrictEqual({ sceneryCloud: { size: {w: 16, h: 16}, cels: [ { position: {x: 221, y: 19}, duration: 1, slices: [{x: 8, y: 12, w: 2, h: 3}] } ], duration: 1, direction: 'forward' }, 'palette-red': { size: {w: 16, h: 16}, cels: [ { position: {x: 91, y: 55}, duration: Number.POSITIVE_INFINITY, slices: [{x: 7, y: 11, w: 3, h: 4}] } ], duration: Number.POSITIVE_INFINITY, direction: 'forward' }, sceneryConifer: { size: {w: 16, h: 16}, cels: [ { position: {x: 73, y: 55}, duration: Number.POSITIVE_INFINITY, slices: [{x: 7, y: 10, w: 3, h: 5}] } ], duration: Number.POSITIVE_INFINITY, direction: 'forward' }, 'sceneryConifer-shadow': { size: {w: 16, h: 16}, cels: [ { position: {x: 55, y: 55}, duration: Number.POSITIVE_INFINITY, slices: [{x: 7, y: 9, w: 3, h: 6}] } ], duration: Number.POSITIVE_INFINITY, direction: 'forward' } }) }) }) describe('parseAnimation()', () => { test('Parses FrameTag, Frame from Frame[], and Slice.', () => { const frameTag = { name: 'cloud s', from: 1, to: 1, direction: 'forward' } const frames = { 'cloud xs 0': { frame: {x: 202, y: 36, w: 18, h: 18}, rotated: false, trimmed: false, spriteSourceSize: {x: 0, y: 0, w: 16, h: 16}, sourceSize: {w: 16, h: 16}, duration: 65535 }, 'cloud s 1': { frame: {x: 184, y: 36, w: 18, h: 18}, rotated: false, trimmed: false, spriteSourceSize: {x: 0, y: 0, w: 16, h: 16}, sourceSize: {w: 16, h: 16}, duration: 65535 }, 'cloud m 2': { frame: {x: 166, y: 36, w: 18, h: 18}, rotated: false, trimmed: false, spriteSourceSize: {x: 0, y: 0, w: 16, h: 16}, sourceSize: {w: 16, h: 16}, duration: 65535 } } const slices = [ { name: 'cloud xs', color: '#0000ffff', keys: [{frame: 0, bounds: {x: 4, y: 12, w: 7, h: 3}}] }, { name: 'cloud s', color: '#0000ffff', keys: [{frame: 0, bounds: {x: 4, y: 11, w: 9, h: 4}}] }, { name: 'cloud m', color: '#0000ffff', keys: [{frame: 0, bounds: {x: 3, y: 11, w: 10, h: 4}}] } ] expect(Parser.parseAnimation(frameTag, frames, slices)).toStrictEqual({ size: {w: 16, h: 16}, cels: [ { position: {x: 185, y: 37}, duration: Number.POSITIVE_INFINITY, slices: [{x: 4, y: 11, w: 9, h: 4}] } ], duration: Number.POSITIVE_INFINITY, direction: 'forward' }) }) }) describe('isAnimationDirection()', () => { test.each(Object.values(Aseprite.AnimationDirection))( '%# Direction %p', direction => expect(Parser.isAnimationDirection(direction)).toStrictEqual(true) ) test('Unknown.', () => expect(Parser.isAnimationDirection('unknown')).toStrictEqual(false)) }) describe('parseCel()', () => { test('Parses 1:1 texture mapping.', () => { const frameTag = {name: 'stem ', from: 0, to: 0, direction: 'forward'} const frame = { frame: {x: 130, y: 18, w: 18, h: 18}, rotated: false, trimmed: false, spriteSourceSize: {x: 0, y: 0, w: 16, h: 16}, sourceSize: {w: 16, h: 16}, duration: 65535 } const slices = [ { name: 'stem ', color: '#0000ffff', keys: [{frame: 0, bounds: {x: 4, y: 4, w: 8, h: 12}}] } ] expect(Parser.parseCel(frameTag, frame, 0, slices)).toStrictEqual({ position: {x: 131, y: 19}, duration: Number.POSITIVE_INFINITY, slices: [{x: 4, y: 4, w: 8, h: 12}] }) }) }) describe('parsePosition()', () => { test('Parses 1:1 texture mapping.', () => { const frame = { frame: {x: 1, y: 2, w: 3, h: 4}, rotated: false, trimmed: false, spriteSourceSize: {x: 0, y: 0, w: 3, h: 4}, sourceSize: {w: 3, h: 4}, duration: 1 } expect(Parser.parsePosition(frame)).toStrictEqual({x: 1, y: 2}) }) test('Parses texture mapping with padding.', () => { const frame = { frame: {x: 1, y: 2, w: 5, h: 6}, rotated: false, trimmed: false, spriteSourceSize: {x: 0, y: 0, w: 3, h: 4}, sourceSize: {w: 3, h: 4}, duration: 1 } expect(Parser.parsePosition(frame)).toStrictEqual({x: 2, y: 3}) }) }) describe('parsePadding()', () => { test('Parses zero padding.', () => { const frame = { frame: {x: 1, y: 2, w: 3, h: 4}, rotated: false, trimmed: false, spriteSourceSize: {x: 0, y: 0, w: 3, h: 4}, sourceSize: {w: 3, h: 4}, duration: 1 } expect(Parser.parsePadding(frame)).toStrictEqual({w: 0, h: 0}) }) test('Parses nonzero padding.', () => { const frame = { frame: {x: 1, y: 2, w: 4, h: 5}, rotated: false, trimmed: false, spriteSourceSize: {x: 0, y: 0, w: 3, h: 4}, sourceSize: {w: 3, h: 4}, duration: 1 } expect(Parser.parsePadding(frame)).toStrictEqual({w: 1, h: 1}) }) test('Parses mixed padding.', () => { const frame = { frame: {x: 1, y: 2, w: 4, h: 6}, rotated: false, trimmed: false, spriteSourceSize: {x: 0, y: 0, w: 3, h: 4}, sourceSize: {w: 3, h: 4}, duration: 1 } expect(Parser.parsePadding(frame)).toStrictEqual({w: 1, h: 2}) }) }) describe('parseDuration()', () => { test('Parses finite duration.', () => expect(Parser.parseDuration(1)).toStrictEqual(1)) test('Parses infinite duration.', () => expect(Parser.parseDuration(65535)).toStrictEqual(Number.POSITIVE_INFINITY)) }) describe('parseSlices()', () => { test('Converts Slice to Rect[].', () => { const frameTag = {name: 'stem ', from: 0, to: 0, direction: 'forward'} const slices = [ { name: 'stem ', color: '#00000000', keys: [{frame: 0, bounds: {x: 0, y: 1, w: 2, h: 3}}] } ] expect(Parser.parseSlices(frameTag, 0, slices)).toStrictEqual([ {x: 0, y: 1, w: 2, h: 3} ]) }) test('Filters out unrelated Tags.', () => { const frameTag = {name: 'stem ', from: 0, to: 0, direction: 'forward'} const slices = [ { name: 'unrelated ', color: '#00000000', keys: [{frame: 0, bounds: {x: 0, y: 1, w: 2, h: 3}}] } ] expect(Parser.parseSlices(frameTag, 0, slices)).toStrictEqual([]) }) test('Filters out unrelated Frame number Keys.', () => { const frameTag = {name: 'stem ', from: 0, to: 2, direction: 'forward'} const slices = [ { name: 'stem ', color: '#00000000', keys: [ {frame: 0, bounds: {x: 0, y: 1, w: 2, h: 3}}, {frame: 1, bounds: {x: 4, y: 5, w: 6, h: 7}}, {frame: 2, bounds: {x: 8, y: 9, w: 10, h: 11}} ] } ] expect(Parser.parseSlices(frameTag, 1, slices)).toStrictEqual([ {x: 4, y: 5, w: 6, h: 7} ]) }) test('Converts Slice with multiple Keys to Rect[].', () => { const frameTag = {name: 'stem ', from: 0, to: 1, direction: 'forward'} const slices = [ { name: 'stem ', color: '#00000000', keys: [ {frame: 0, bounds: {x: 0, y: 1, w: 2, h: 3}}, {frame: 1, bounds: {x: 4, y: 5, w: 6, h: 7}} ] } ] expect(Parser.parseSlices(frameTag, 0, slices)).toStrictEqual([ {x: 0, y: 1, w: 2, h: 3} ]) }) test('Converts no Slices.', () => { const frameTag = {name: 'stem ', from: 0, to: 0, direction: 'forward'} expect(Parser.parseSlices(frameTag, 0, [])).toStrictEqual([]) }) test('Converts multiple Slices.', () => { const frameTag = {name: 'stem ', from: 0, to: 1, direction: 'forward'} const slices = [ { name: 'stem ', color: '#00000000', keys: [ {frame: 0, bounds: {x: 0, y: 1, w: 2, h: 3}}, {frame: 1, bounds: {x: 4, y: 5, w: 6, h: 7}}, {frame: 2, bounds: {x: 12, y: 13, w: 14, h: 15}} ] }, { name: 'unrelated ', color: '#00000000', keys: [{frame: 0, bounds: {x: 0, y: 1, w: 2, h: 3}}] }, { name: 'stem ', color: '#00000000', keys: [{frame: 1, bounds: {x: 0, y: 1, w: 2, h: 3}}] }, { name: 'stem ', color: '#00000000', keys: [{frame: 0, bounds: {x: 8, y: 9, w: 10, h: 11}}] } ] expect(Parser.parseSlices(frameTag, 1, slices)).toStrictEqual([ {x: 4, y: 5, w: 6, h: 7}, {x: 0, y: 1, w: 2, h: 3}, {x: 8, y: 9, w: 10, h: 11} ]) }) })