{"id":15287206,"url":"https://github.com/filidorwiese/spriteling","last_synced_at":"2025-04-13T05:08:20.607Z","repository":{"id":32455777,"uuid":"134289805","full_name":"filidorwiese/spriteling","owner":"filidorwiese","description":"Spriteling - Spritesheet Animation Engine","archived":false,"fork":false,"pushed_at":"2023-01-03T15:16:28.000Z","size":865,"stargazers_count":107,"open_issues_count":10,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-13T05:08:14.217Z","etag":null,"topics":["animation","javascript","spritesheet"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/filidorwiese.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-05-21T15:43:47.000Z","updated_at":"2024-04-30T01:25:14.000Z","dependencies_parsed_at":"2023-01-14T21:16:25.557Z","dependency_job_id":null,"html_url":"https://github.com/filidorwiese/spriteling","commit_stats":null,"previous_names":["filidorwiese/smitten"],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filidorwiese%2Fspriteling","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filidorwiese%2Fspriteling/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filidorwiese%2Fspriteling/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filidorwiese%2Fspriteling/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/filidorwiese","download_url":"https://codeload.github.com/filidorwiese/spriteling/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248665747,"owners_count":21142123,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animation","javascript","spritesheet"],"created_at":"2024-09-30T15:26:33.755Z","updated_at":"2025-04-13T05:08:20.592Z","avatar_url":"https://github.com/filidorwiese.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spriteling\n\nA scriptable spritesheet animation engine that works directly on DOM elements (no canvas). It's built as ES5 compatible JavaScript, has no external dependencies and a tiny footprint (~6KB minified/gzipped).\n\n### Install using node\n\n`npm install --save spriteling`\n\nThen either import, require or use directly as \u0026lt;script\u0026gt; tag:\n\n```js\nimport Spriteling from 'spriteling'\n\nconst Spriteling = require('spriteling')\n\n\u003cscript type=\"text/javascript\" src=\"spriteling.min.js\"\u003e\u003c/script\u003e\n```\n\n\n### Example 1: Basic looping animation\n\n\u003cimg src=\"https://raw.githubusercontent.com/filidorwiese/spriteling/master/examples/artwork/arcade-single.png\"\u003e\n\nCreate a DOM element on the page and give it an id. Pass it to a new instance of Spriteling, giving it some information about the spritesheet and where to put it on the page.\nFinally call .play() on it with some optional parameters.\n\n```html\n\u003cdiv id=\"sprite\"\u003e\u003c/div\u003e\n\u003cscript\u003e\n     const sprite = new Spriteling({\n        url: '/spritesheets/arcade.png',\n        top: 200,\n        left: 100,\n        cols: 3,\n        rows: 9\n    }, '#sprite')\n    \n    sprite.play({\n        run: -1,\n        delay: 100\n    })\n\u003c/script\u003e\n```\n\nYou can see it in action at [\"Arcade\" animation](https://fili.nl/spriteling-examples/looping-animation-arcade.html)\n\n### Example 2: Scripted animation \n\nLooping sure is nice! But when we have a non-linear animation to build, we need to have fine-grained control over the individual steps. Like the sequencing of the sprites and timing them correctly. Take this spritesheet of a reading character for example:\n\n\u003cimg src=\"https://raw.githubusercontent.com/filidorwiese/spriteling/master/examples/artwork/spritesheet-reading.png\" width=\"200\"\u003e\n\nFor this animation, simply looping the images won't do. We need to add an animation script to get the desired result: \n\n```html\n\u003cdiv id=\"sprite\"\u003e\u003c/div\u003e\n\u003cscript\u003e\n  const sprite = new Spriteling({\n    url: '/spritesheets/reading.png',\n    top: 200,\n    left: 100,\n    cols: 5,\n    rows: 3\n  }, '#sprite', true)\n\n  sprite.addScript('read', [\n    // read lines\n    {sprite: 1, delay: 1000},\n    {sprite: 2, delay: 800},\n    {sprite: 1},\n    {sprite: 3, delay: 400},\n    {sprite: 1},\n\n    // read lines\n    {sprite: 2, delay: 800},\n    {sprite: 1},\n    {sprite: 3, delay: 400},\n    {sprite: 1},\n\n    // read lines\n    {sprite: 2, delay: 400},\n    {sprite: 1},\n    {sprite: 3, delay: 800},\n    {sprite: 1},\n\n    // blink\n    {sprite: 4},\n    {sprite: 1},\n\n    // turn page\n    {sprite: 5},\n    {sprite: 6},\n    {sprite: 7},\n    {sprite: 8},\n    {sprite: 9},\n    {sprite: 10},\n    {sprite: 11},\n    {sprite: 12}\n  ])\n\n  sprite.play('read', {\n    run: -1,\n    delay: 200\n  })\n\u003c/script\u003e\n```\n\nYou can see it in action at [\"Reading\" demo](https://fili.nl/spriteling-examples/scripted-animation-reading.html). Another scripted animation can be seen at [\"Dog training\" demo](https://fili.nl/spriteling-examples/scripted-animation-ossy.html).\n\n### Example 3: Multiple instances\nSpriteling is not hardware-accelerated, there is no need for a clunky WebGL canvas element or CSS properties that need GPU support. In fact, under the hood there is nothing more then a background positioning trick doing the hard work, which is as fast as it can get. Even under stress it performs quite well, as you can see in the [\"Multiple instances\" demo](https://fili.nl/spriteling-examples/scripted-animation-multiple.html)\n\n### More advanced examples\nBut we shouldn't stop there! When adding positioning to the animation script, we can easily create a walking character. And the character truly comes alive when we add user interaction, like mouse events.\n\n\u003cimg src=\"https://raw.githubusercontent.com/filidorwiese/spriteling/master/examples/artwork/scared.gif\"\u003e\n\nFeel free to check out these \"Spriteling included\" websites:\n\n* Website [galaxy.fili.nl](https://galaxy.fili.nl)\n* Website [filidorwiese.nl](https://filidorwiese.nl)\n* Website [whois.wildlife.la](http://whois.wildlife.la)\n\nNow it's up to you. Please keep me posted on what you've created! \n\n# API\n\n## constructor(options, element, debug): Spriteling\n\nCreate a new Spriteling instance, example usage: \n```js\nconst sprite = new Spriteling({\n  url: '/spritesheets/walking-character.png',\n  top: 200,\n  left: 100,\n  cols: 5,\n  rows: 3\n}, '#sprite')\n```\n\n#### options: `SpriteSheetOptions`\n\nProperty | Type | Required | Default\u0026nbsp;value | Explanation\n:------------- |:------------- |:-------------:| :-------------:| :-------------\nurl | `string` | no | null | url to spritesheet, if not set the css background-image will be used\ncols | `number` | yes | null | Number of columns in the spritesheet\nrows | `number` | yes | null | Number of rows in the spritesheet\ncutOffFrames | `number` | no | 0 | Number of sprites not used in the spritesheet, for example the last sprite in a sheet might be blank\ntop bottom left right | `number` | no |  | Initial position of the placeholder element, will use current if not provided\nstartSprite | `number` | no | 1 | Sprite number to show when done loading\ndownsizeRatio | `number` | no | 1 | For HiDPI or Retina support, you can supply a higher resolution spritesheet (x2) and downsize it back to regular size with this property\nonLoaded | `function` | no | null | Callback function that will be called when loading has finished\n\n#### element: `HTMLElement | string` (optional)\nCan be a CSS selector or existing DOM element or null, in which case a new div element will be created\n\n#### debug: `boolean` (optional)\nCan be used to enable debug logging in console, useful when fine-tuning the animation scripts\n\n## .showSprite( sprite: `number`)\nStop the current animation and show the specified sprite\n\n```js\nspriteling.showSprite(4)\n```\n\n## .currentSprite(): `number`\nGet the current spriteNumber that is shown\n\n```js\nconst currentSprite = spriteling.currentSprite()\n```\n\n## .addScript(name: `string`, script: `Array\u003cFrame\u003e`)\nAdd a named animation sequence, for example:\n\n```js\nspriteling.addScript('walk', [\n    { sprite: 22, delay: 100 },\n    { sprite: 23, delay: 100, left: 10 },\n    { sprite: 24, delay: 150, left: 5 },\n    { sprite: 23, delay: 100, left: 10 }\n])\n```\n\n#### name: `string`\nCan be any string value\n\n#### script: `Array\u003cFrame\u003e`\nThe `script` parameter should be an array consisting of frame objects. These frame objects can have the following properties:\n\n\nProperty | Type | Required | Default\u0026nbsp;value | Explanation\n:------------- |:------------- |:-------------:| :-------------:| :-------------\nsprite | `number` | yes |  | Which sprite from spritesheet to show (counted from top-left to bottom-right)\ndelay | `number` | no | delay defined with .play() | Time in ms to wait after this frame has been rendered\ntop bottom left right | `number` | no | 0 | Move the position of the placeholder to any direction after frame has been rendered\n\n## .play(scriptName: `string`, options: `AnimationOptions`)\nResume/play current or given animation.\nMethod can be called in four ways:\n\n```js\nsprite.play() // resume current animation sequence (if not set - loops over all sprites once)\nsprite.play(scriptName) // play given animation script\nsprite.play(scriptName, { options }) // play given animation script with given options\nsprite.play({ options }) // play current animation with given options\n```\n\n#### scriptName: `string`\nloads a previously added animation with .addScript()\n\n#### options: `AnimationOptions`\n\nProperty | Type | Required | Default\u0026nbsp;value | Explanation\n:------------- |:-------------: |:-------------:| :-------------:| :-------------\nplay | `boolean` | no | true | Start playing the animation right away\nrun | `number` | no | -1 | The number of times the animation should run, -1 = infinite\ndelay | `number` | no | 50 | Default delay for all frames that don't have a delay set\ntempo | `number` | no | 1 | Timescale for all delays, double-speed = 2, half-speed = .5\nreversed | `boolean` | no | false | Direction of the animation head, true == backwards\nscript | `Array\u003cFrame\u003e` | no | all frames | New unnamed animation sequence\nonPlay() | `function` | no |  | Callback called when animator starts playing\nonStop() | `function` | no | null | Callback called when animator stops playing\nonFrame() | `function` | no | null | Callback called when the new frame is rendered\nonOutOfView() | `function` | no | null | Callback called when the placeholder is no longer in view. Could be used to stop the animation when it moved out of the document boundary.\n\nThe callbacks allow for interactions between sprites to take place. In the following example sprite1 will trigger play() on sprite2 after it's animation has been completed:\n\n```js\n\nconst sprite1 = Spriteling({\n  url: '/spritesheets/ping.png',\n  cols: 3,\n  rows: 9\n}, '#sprite1')\n\nconst sprite2 = Spriteling({\n  url: '/spritesheets/pong.png',\n  cols: 3,\n  rows: 9\n}, '#sprite2')\n\nsprite1.play({\n  run: 3,\n  script: [\n    { sprite:1 },\n    { sprite:2 },\n    { sprite:3, delay:350},\n    { sprite:4 }\n  ],\n  onStop: () =\u003e {\n    sprite2.play()\n  }\n})\n```\n\n## .isPlaying()\nGet the current play state\n\n```js\nconst isPlaying = spriteling.isPlaying()\n```\n\n## .setTempo( tempo: `number`)\nSet playback tempo, double-speed = 2, half-speed = .5 (default:1)\n\n```js\nspriteling.setTempo(2)\n```\n\n## .getTempo(): `number`\nGet playback tempo, double-speed = 2, half-speed = .5 (default:1)\n\n```js\nconst tempo = spriteling.getTempo()\n```\n\n## .next()\nStep the animation ahead one frame\n\n```js\nspriteling.next()\n```\n\n## .previous()\nStep the animation backwards one frame\n\n```js\nspriteling.previous()\n```\n\n## .goTo(frame: `number`): `boolean`\nJump to certain frame within current animation sequence. Returns true if succeeded.\n\n```js\nspriteling.goTo(10)\n```\n\n## .reverse()\nReverse direction of play\n\n```js\nspriteling.reverse()\n```\n\n## .isReversed()\nGet the current direction of play\n\n```js\nconst isReversed = spriteling.isReversed()\n```\n\n## .stop()\nStop the animation\n\n```js\nspriteling.stop()\n```\n\n## .reset()\nReset playhead to first frame\n\n```js\nspriteling.reset()\n```\n\n## .destroy()\nRemoves the element and kills the animation loop\n\n```js\nspriteling.destroy()\n```\n\n\n# Compatibility\n\nSpriteling should work on almost anything. From IE7 to phones and tablets. Let me know if you find it doesn't work on a particular device and I'll see if I can fix that.\n\n\n# License\nThe artwork in this repository has been created by [Arthur van 't Hoog](https://arthurvanthoog.nl) and is licensed under a [Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)](https://creativecommons.org/licenses/by-nc-nd/4.0/) license.\n\nMeaning you are free to:\n\n* Share — copy and redistribute the material in any medium or format\n\nUnder the following terms:\n\n* Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.\n* NonCommercial — You may not use the material for commercial purposes.\n* NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffilidorwiese%2Fspriteling","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffilidorwiese%2Fspriteling","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffilidorwiese%2Fspriteling/lists"}