Spine Web Player

The Spine web player lets you easily embed your Spine animations on your website.

The player has controls that allow a user to:

  • Pause/resume the currently playing animation
  • Scrub the timeline
  • Change the playback speed
  • Select an animation from a list of available animations
  • Select a skin from a list of available skins
  • Hide/show debug renderings of regions, meshes, bones, etc.
  • Drag skeleton bones

Note: The Spine Web Player uses WebGL for rendering. While WebGL is supported by all recent versions of popular desktop and mobile browsers, there may be compatibility issues with old browsers.

Exporting for the player

The Spine Web Player can display Spine skeletons exported from the Spine Editor in the JSON format.

Export

In addition to the exported .json file, the player also requires a texture atlas consisting of a .atlas file and one or more .png files. Please see the Spine User Guide on how to export skeletons to JSON and how to export a texture atlas for more details.

We will use the Spineboy project for all examples below, for which the export creates the following files:

Spineboy files

These files must be uploaded to a web server and accessible via URLs.

The .png files need to be accessible under the same path as the .altas file. For example, if the .atlas file is accessible via https://mysite.com/assets/spineboy.atlas, the .png file(s) must be accessible via https://mysite.com/assets/spineboy.png.

Embedding a player

Adding the player to your website consists of a few simple steps, detailed below.

Adding the player JavaScript & CSS files

The Spine Web Player consists of two files: spine-player.js and spine-player.css. The JS file contains the JavaScript code required for the player functionality, while CSS file defines the CSS for the player's UI.

The two files can be added to a web page like this:

<script src="http://esotericsoftware.com/files/spine-player/3.8/spine-player.js">
<link rel="stylesheet" href="http://esotericsoftware.com/files/spine-player/3.8/spine-player.css">

In the above example, the two files are loaded from the Esoteric Software server. The URLs contain a version number (3.8) which must match the Spine editor version you used to export your skeleton and atlas. Loading the files from the Esoteric Software server will ensure that your Spine players always use the latest JavaScript code and CSS.

You can find the sources for the Spine Web Player in our GitHub repository if you'd like to build the player from source.

Creating a container element

The player requires an element into which it should be loaded. The easiest way to do this is to create a div element with an id:

<div id="player-container" style="width: 640px; height: 480px;"></div>

Initializing the player

For the final step, the player needs to be initialized with a short JavaScript snippet:

<script>
new spine.SpinePlayer("player-container", {
      jsonUrl: "/files/spineboy/export/spineboy-pro.json",
      atlasUrl: "/files/spineboy/export/spineboy.atlas",
});
</script>

This creates a new SpinePlayer in the player-container element. The player loads the Skeleton .json from the relative URL /files/spineboy/export/spineboy-pro.json and the .atlas file from /files/spineboy/export/spineboy.atlas. This particular texture atlas has one page named spineboy.png, so that image is loaded relative to the .atlas file, from /files/spineboy/export/spineboy.png.

Putting it all together

The code area in the below player is editable! Use it to experiment with the configuration options explained in the next section.

With the above code, the player will choose default values for all its configurable properties: which animation to play, the background color, and many more. You can further customize the player's appearance and behavior through the configuration detailed below.

Configuration

The Spine Web Player offers a wide variety of configuration options to adapt it to your requirements.

JSON and atlas URL

We have already encountered the two mandatory configuration properties jsonUrl and atlasUrl in the example above. They specify from where the player should load the skeleton .json and .atlas files. You can specify relative or absolute URLs:

<script>
new spine.SpinePlayer("player-container", {
// Relative URLs
jsonUrl: "assets/spineboy.json",
atlasUrl: "assets/spineboy.atlas",
});

new spine.SpinePlayer("player-container", {
// Absolute URLs
jsonUrl: "https://esotericsoftware.com/files/examples/spineboy/export/spineboy-pro.json",
atlasUrl: "https://esotericsoftware.com/files/examples/spineboy/export/spineboy-pma.atlas"
});
</script>

When using absolute URLs to another domain, it is possible that web browsers won't be able to load the assets. This is usually due to not having CORS enabled on the server that hosts the assets.

Default animation

By default, the player will play the first animation found in the skeleton. The default animation can be set explicitly in the configuration instead:

<script>
new spine.SpinePlayer("player-container", {
...
animation: "walk" // Player will start with "walk" animation
});
</script>

Limiting the animations

The player allows a user to select the active animation. The set of animations that can be chosen can be limited via the animations property:

<script>
new spine.SpinePlayer("player-container", {
...
animations: ["walk", "run", "jump"] // The user can only select one of these three animations
});
</script>

The animation button will be hidden by the player if only one animation can be chosen, either because there is only one animation in the skeleton, or because the list of animations only contains one animation.

Default mix time

When a user switches between two animations, the player will mix the animations for 0.25 seconds by default, displaying a smooth transition. This mix time can be set via the defaultMix property:

<script>
new spine.SpinePlayer("player-container", {
...
defaultMix: 0.1 // Mix animation changes for 0.1 seconds
});
</script>

Default skin

By default, the player will use the default skin of the skeleton, which only has the attachment that are not in a skin in the Spine editor. The active skin can be set explicitly in the configuration via the skin property:

<script>
new spine.SpinePlayer("player-container", {
...
skin: "funky" // Start with the "funky" skin
});
</script>

Limiting the skins

The player allows a user to select the active skin. The set of skins that can be chosen can be limited via the skins property:

<script>
new spine.SpinePlayer("player-container", {
...
skins: ["default", "funky"] // The user can only select one of these two skins
});
</script>

The skin button will be hidden by the player if only one skin can be chosen, either because there is only one skin in the skeleton, or because the list of skins only contains one skin.

Premultiplied alpha

By default, the player loads images with premultiplied alpha enabled. To disable premultiplied alpha, the premultipliedAlpha configuration property must be set:

<script>
new spine.SpinePlayer("player-container", {
...
premultipliedAlpha: false // Disable premultiplied alpha rendering
});
</script>

We recommend using premultiplied alpha with all assets displayed by the Spine Web Player. It reduces artifacts and seams that may be visible when not using premultiplied alpha.

Hide controls

The player controls can be hidden via the showControls configuration property:

<script>
new spine.SpinePlayer("player-container", {
...
showControls: false // Hide the player controls
});
</script>

Debug visualizations

By default, the player does not show any debug visualizations like regions, mesh triangles, bones, etc. These can be enabled manually by the user via the player controls. The debug property can be used to specify which debug visualizations should be enabled by default:

<script>
new spine.SpinePlayer("player-container", {
...
debug: {
    bones: true,
    regions: true,
    meshes: true,
    bounds: true,
    paths: true,
    clipping: true,
    points: true,
    hulls: true
}
});
</script>

Of course, you can omit any visualizations you do not want to enable by default, or set their respective property to false.

Background color

The player background color can be set via the backgroundColor configuration property. The color must be specified as a hexadecimal RGBA color (#rrggbbaa).

<script>
new spine.SpinePlayer("player-container", {
...
backgroundColor: "#ff00ffff" // Magenta player background
});
</script>

The player can be expanded to fullscreen by the user. A separate background color for fullscreen mode can be set via the fullscreenBackgroundColor configuration property. If not specified, the fullscreen background color will be the same as the backgroundColor.

<script>
new spine.SpinePlayer("player-container", {
...
backgroundColor: "#ff00ffff" // Magenta player background
fullScreenBackgroundColor: "#00ff00ff" // Green player background in fullscreen mode
});
</script>

Background image

Instead of a plain background color, the player can also display a background image behind the skeleton. The image can be specified via the backgroundImage configuration property:

<script>
new spine.SpinePlayer("player-container", {
...
backgroundImage: { // Display a background image behind the skeleton
    url: "assets/background.png",
    x: 0,
    y: 0,
    width: 330,
    height: 330
}
});
</script>

The url is a relative or absolute URL to the background image. The x and y properties specify the position of the bottom left corner of the image in the skeleton's world coordinate space. The width and height properties specify the dimensions of the image.

Translucent player

By default, the player is opaque and will be drawn over any other HTML elements behind it. The alpha configuration property can be used in combination with the backgroundColor property to make the player translucent, allowing any HTML elements behind to be seen through the player.

<script>
new spine.SpinePlayer("player-container", {
...
alpha: true, // Enable player translucency
backgroundColor: "#00000000" // Background is fully transparent
});
</script>

Viewports

The player always tries to fill the container element it is embedded in. When an animation is chosen (or specified in the configuration), the player ensures the animation is fully visible inside the available player space.

Viewport

In the above image, the green rectangle represents the bounding box automatically calculated for Spineboy's run animation. It is padded by 10% on each side by default. The resulting viewport, indicated by the red rectangle, is then embedded in the available space of the player, retaining the viewport's aspect ratio.

This automatic viewport mechanism can be customized via the player configuration. If no viewport configuration is given, the player defaults to the automatic behavior described above.

You can set a global viewport, used for all animations, like this:

<script>
new spine.SpinePlayer("player-container", {
...
viewport: {
    x: 0,
    y: 0,
    width: 300,
    height: 300,
    padLeft: "5%",
    padRight: "5%",
    padTop: "5%",
    padBottom: "5%"
}
});
</script>

The x and y properties specify the position of the bottom left corner of the viewport in the skeleton's world coordinate space. The width and height properties specify the dimensions of the viewport. If any of these properties is omitted, the player ignores all other properties and resorts to the automatic behavior described above.

The padLeft, padRight, padTop, and padBottom properties specify the padding to be added to the respective sides of the viewport. In the example above, they are expressed as percentages. You can also specify absolute numbers in the skeleton's world coordinate space instead. If one of these properties is omitted, the player assumes a default value of 10%.

You can visualize the viewport as in the image above by specifying the debugRender property:

<script>
new spine.SpinePlayer("player-container", {
...
viewport: {
    ...
    debugRender: true // Show the viewport bounds
}
});
</script>

When the player switches between animations, it interpolates the viewports of the old and new animation for 0.2 seconds. This viewport transition time can be set via the transitionTime property:

<script>
new spine.SpinePlayer("player-container", {
...
viewport: {
    ...
    transitionTime: 1 // Transition between viewports for 1 second
}
});
</script>

It is sometimes helpful to specify a viewport for a specific animation. This can be done via the animations property:

<script>
new spine.SpinePlayer("player-container", {
...
viewport: {
    ...
    animations: {
       "walk": {
         x: 0,
         y: 0,
         width: 300,
         height: 300,
         padLeft: "5%",
         padRight: "5%",
         padTop: "5%",
         padBottom: "5%"
       },
       "run": {
         padTop: "20%",
       }
    }
}
});
</script>

In the above example, we specify a viewport for the walk and run animations. For the walk animation, we define the complete viewport bounds including padding. The global viewport (or the automatic behavior if no global viewport is given) will be completely overwritten for this animation.

For the run animation, we only specify the top padding. All other viewport values will be either derived from the global viewport, or from the automatic behavior.