Spine Web Player
Spine Web Playerを使えば、Spineのアニメーションを簡単にWebサイトに埋め込むことができます。
プレーヤーには、以下のことを可能にするコントロールが備わっています:
- 再生中のアニメーションの一時停止/再開。
- タイムラインのスクラブ。
- 再生速度の変更。
- 利用可能なアニメーションのリストからの、アニメーションの選択。
- 利用可能なスキンのリストからの、スキンの選択。
- 領域、メッシュ、ボーンなどのデバッグレンダリングの表示/非表示。
- スケルトンのボーンのドラッグ。
また、プレーヤーのコントロールを無効にして、ユーザーの入力なしでアニメーションの表示だけに使用することもできます(サンプル)。
注意: Spine Web Playerは、レンダリングにWebGLを使用しています。WebGLは、一般的なデスクトップおよびモバイルブラウザの最近のバージョンではサポートされていますが、古いブラウザでは互換性に問題がある場合があります。
プレーヤー用の出力方法
Spine Web Playerは、SpineエディターからJSON
形式でエクスポートされたSpineのスケルトンを表示することができます。
エクスポートされた.json
ファイルに加えて、プレーヤーには.atlas
ファイルと1つまたは複数の.png
ファイルからなるテクスチャ アトラスが必要です。詳細については、SpineユーザーガイドのスケルトンをJSON
でエクスポートする方法とテクスチャアトラスをエクスポートする方法を参照してください。
以下の例では、Spineboyのプロジェクトを使用し、エクスポートにより以下のファイルが作成されています:
これらのファイルはウェブサーバーにアップロードして、URLでアクセスできるようにしなければなりません。
.png
ファイルは、.altas
ファイルと同じパスでアクセスできる必要があります。たとえば、.atlas
ファイルがhttps://mysite.com/assets/spineboy.atlas
からアクセスできる場合、(単一または複数の).png
ファイルはhttps://mysite.com/assets/spineboy.png
からアクセスできる必要があります。
プレーヤーの埋め込み
プレーヤーをウェブサイトに追加するには、以下の簡単なステップが必要です。
プレーヤーのJavaScriptおよびCSSファイルの追加
Spine Web Playerは、spine-player.js
とspine-player.css
の2つのファイルから構成されています。JSファイルにはプレーヤーの機能に必要なJavaScriptのコードが含まれ、CSSファイルにはプレーヤーのUIに必要なCSSが定義されています。
この2つのファイルは、次のようにしてWebページに追加することができます:
<link rel="stylesheet" href="https://unpkg.com/@esotericsoftware/spine-player@4.1.*/dist/spine-player.css">
上記の例では、これらの2つのファイルが高速なNPM CDN(content delivery network)、UNPKGからロードされています。各URLにはバージョン番号(4.0
)が含まれており、これはスケルトンとアトラスのエクスポートに使用したSpineエディターのバージョンと一致させる必要があります。上のようにファイルをロードすることで、Spineプレイヤーは常に最新のJavaScriptコードとCSSを使用することができます。
Use the .min.js
and .min.css
file extension for minified files on the UNPKG CDN:
<link rel="stylesheet" href="https://unpkg.com/@esotericsoftware/spine-player@4.1.*/dist/spine-player.min.css">
UNPKGを使用したくない場合は、UNPKGから直接ファイルをダウンロードするか、当社のGitHubリポジトリで提供されているソースからファイルをビルドして、自分でホストすることができます。また、NPMやYarnと一緒にSpine Web Playerを使用する方法についてもリポジトリ内のREADMEで説明されています。
コンテナ要素の作成
プレーヤーには、プレーヤーを読み込むための要素が必要です。最も簡単な方法は、id
を持つdiv
要素を作成することです:
プレーヤーの初期化
最後のステップとして、プレーヤーを初期化するために、以下の短いJavaScriptのスニペットが必要です:
new spine.SpinePlayer("player-container", {
skeleton: "/files/spineboy/export/spineboy-pro.json",
atlas: "/files/spineboy/export/spineboy.atlas",
});
</script>
これにより、player-container
要素に新しいSpinePlayer
が作成されます。このプレーヤーは、相対URLである/files/spineboy/export/spineboy-pro.json
から.json
ファイルを、/files/spineboy/export/spineboy.atlas
から.atlas
ファイルをロードします。この指定されたテクスチャアトラスにはspineboy.png
という名前のページが1つあるので、その画像は.atlas
ファイルに対して相対的に/files/spineboy/export/spineboy.png
から読み込まれます。
全てをまとめた結果
上のプレーヤーのコードは編集可能です。このコードを使って、次のセクションで説明する設定オプションを試してみてください。
上記のコードでは、再生するアニメーションや背景色など、設定可能なすべてのプロパティにデフォルト値が設定されます。プレーヤーの外観や動作は、後述する設定でさらにカスタマイズできます。
設定
Spine Web Playerは、ご希望に合わせて様々な設定が可能です。
JSON、バイナリ、アトラスのURLについて
上記の例では、2つの必須設定プロパティ skeleton
と atlas
に触れましたが、これらはプレーヤーがスケルトンの .json
またはバイナリ形式の .skel
と .atlas
ファイルをロードする場所を指定します。これには相対URLまたは絶対URLを指定できます:
new spine.SpinePlayer("player-container", {
// 相対URLの場合
skeleton: "assets/spineboy.json",
atlas: "assets/spineboy.atlas",
});
new spine.SpinePlayer("player-container", {
// 絶対URLの場合
skeleton: "https://esotericsoftware.com/files/examples/4.2/spineboy/export/spineboy-pro.skel",
atlas: "https://esotericsoftware.com/files/examples/4.2/spineboy/export/spineboy-pma.atlas"
});
</script>
別のドメインへの絶対URLを使用すると、Webブラウザがアセットを読み込めない可能性があります。これは通常、アセットをホストするサーバーでCORSが有効になっていないことが原因です。
データの埋め込み
URLからデータを読み込む代わりに、rawデータの .json/.skel
、.atlas
、および .png
ファイルをJavaScriptのソースに直接埋め込むこともできます。これを行うにはrawDataURIs
設定プロパティを使用してください:
skeleton: "raptor-pro.json",
atlas: "raptor-pma.atlas",
rawDataURIs: {
"raptor-pro.json": "data:application/json;base64,<base64 encoded raptor-pro.json>",
"raptor-pma.atlas": "data:application/octet-stream;base64,<base64 encoded raptor-pma.atlas>",
"raptor-pma.png": "data:image/png;base64,<base64 encoded raptor-pma.png>"
}
}
rawDataURIs
は、異なるパスまたは(CORSが有効な場合)異なるドメインのアトラス画像を使用するためにも使用できます。
デフォルトアニメーション
デフォルトでは、プレーヤーはそのスケルトンで最初に検知したアニメーションを再生します。デフォルトのアニメーションは、以下の構成プロパティで明示的に設定することができます:
new spine.SpinePlayer("player-container", {
...
animation: "walk" // プレーヤーは"walk"アニメーションからスタートします
});
</script>
アニメーションを制限する
プレーヤーでは、ユーザーがアクティブなアニメーションを選択することができます。選択可能なアニメーションのセットは、animations
プロパティで制限できます:
new spine.SpinePlayer("player-container", {
...
animations: ["walk", "run", "jump"] // ユーザーはこれらの3つのアニメーションのうちから1つだけを選べます
});
</script>
アニメーションボタンは、スケルトンにアニメーションが1つしかない場合や、animations
のリストにアニメーションが1つしかない場合など、選択できるアニメーションが1つしかない場合は、プレーヤーによって非表示になります。
デフォルトのミックスタイム
ユーザーが2つのアニメーションを切り替えたとき、デフォルトでは0.25
秒間、プレーヤーはアニメーションをミックスして、スムーズな切り替えを表示します。このミックスタイムはdefaultMix
プロパティで設定できます:
new spine.SpinePlayer("player-container", {
...
defaultMix: 0.1 // ミックスアニメーションは0.1秒間になります
});
</script>
デフォルトスキン
デフォルトでは、プレーヤーはスケルトンのデフォルトスキンを使用します。このスキンには、Spineエディターでスキンになっていないアタッチメントのみが含まれています。アクティブなスキンはskin
プロパティを介して明示的に設定できます:
new spine.SpinePlayer("player-container", {
...
skin: "funky" // "funky"スキンでスタートします
});
</script>
スキンを制限する
プレーヤーでは、ユーザーがアクティブなスキンを選択することができます。選択可能なスキンのセットは、skins
プロパティで制限することができます:
new spine.SpinePlayer("player-container", {
...
skins: ["default", "funky"] // ユーザーはこれらの2つのスキンのうちから1つだけを選べます
});
</script>
スキンボタンは、スケルトンにスキンが1つしかない場合や、skins
のリストにスキンが1つしかない場合など、スキンが1つしか選べない場合には、プレーヤーによって非表示になります。
乗算済みアルファ
デフォルトでは、プレーヤーは乗算済みアルファ(premultiplied alpha)を有効にして画像を読み込みます。乗算済みアルファを無効にするにはpremultipliedAlpha
構成プロパティを設定する必要があります:
new spine.SpinePlayer("player-container", {
...
premultipliedAlpha: false // 乗算済みアルファレンダリング無効
});
</script>
Spine Web Playerで表示されるすべてのアセットには、乗算済みアルファを使用することを推奨しています。その方が、乗算済みアルファを使用しない場合に見られるアーティファクト(画像の乱れ)や継ぎ目のような現象を減らすことができます。
コントロールの非表示
プレーヤーコントロールは、showControls
プロパティで隠すことができます。:
new spine.SpinePlayer("player-container", {
...
showControls: false // プレーヤーコントロール非表示
});
</script>
デバッグ表示
デフォルトでは、プレーヤーは領域、メッシュ三角形、ボーンなどのデバッグオプションを一切表示しません。これらは、プレーヤーコントロールを使って、ユーザーが手動で有効にすることができます。debug
プロパティを使用して、デフォルトで有効にするデバッグオプションを指定できます:
new spine.SpinePlayer("player-container", {
...
debug: {
bones: true,
regions: true,
meshes: true,
bounds: true,
paths: true,
clipping: true,
points: true,
hulls: true
}
});
</script>
もちろん、デフォルトで有効にしたくないオプションは省略することもできますし、それぞれのプロパティをfalse
に設定することもできます。
背景色
プレーヤーの背景色は、backgroundColor
プロパティで設定できます。色は16進数のRGBAカラー(#rrggbbaa
)で指定する必要があります。
new spine.SpinePlayer("player-container", {
...
backgroundColor: "#ff00ffff" // マゼンタ色のプレーヤー背景
});
</script>
プレーヤーは、ユーザーによってフルスクリーンに拡大することができます。フルスクリーンモード用の個別の背景色は、fullscreenBackgroundColor
プロパティで設定できます。指定されていない場合は、フルスクリーンの背景色はbackgroundColor
と同じになります。
new spine.SpinePlayer("player-container", {
...
backgroundColor: "#ff00ffff" // マゼンタ色のプレーヤー背景
fullScreenBackgroundColor: "#00ff00ff" // フルスクリーンモードではプレーヤー背景を緑に
});
</script>
背景画像
プレーヤーは、ベタ塗りの背景色の代わりに、スケルトンの背後に背景画像を表示することもできます。画像はbackgroundImage
プロパティで指定できます:
new spine.SpinePlayer("player-container", {
...
backgroundImage: { // スケルトンの背後に背景画像を表示
url: "assets/background.png",
x: 0,
y: 0,
width: 330,
height: 330
}
});
</script>
url
には、背景画像の相対または絶対URLを指定します。x
およびy
プロパティは、スケルトンのワールド座標空間における画像の左下隅の位置を指定します。width
および height
プロパティは、画像のサイズを指定します。
半透明のプレーヤー
デフォルトでは、プレーヤーは不透明で、背後にある他のHTML要素の上に描画されますが、alpha
プロパティをbackgroundColor
プロパティと組み合わせて使用すると、プレーヤーが半透明になり、背後のHTML要素が透けて見えるようになります。
new spine.SpinePlayer("player-container", {
...
alpha: true, // プレーヤーの半透明化を有効にする
backgroundColor: "#00000000" // 背景を完全な透明に
});
</script>
ビューポート
プレーヤーは、埋め込まれているコンテナ要素を常に埋めようとします。アニメーションが選択されている(または設定で指定されている)場合、プレーヤーは、利用可能なプレーヤースペース内でアニメーションが完全に表示されるようにします。
上の画像では、緑の長方形がSpineboyのrun
アニメーションのために自動的に計算されたバウンディングボックスを表しています。デフォルトでは、各辺に10%のパディングが施されています。赤い四角で示された結果のビューポートは、ビューポートのアスペクト比を維持したまま、プレーヤーの利用可能なスペースに埋め込まれます。
この自動ビューポート機構は、プレーヤーの設定でカスタマイズできます。ビューポート設定が指定されていない場合、プレーヤーは上述の自動動作をデフォルトとします。
すべてのアニメーションに使用されるグローバルビューポートを設定するには、次のようにします。:
new spine.SpinePlayer("player-container", {
...
viewport: {
x: 0,
y: 0,
width: 300,
height: 300,
padLeft: "5%",
padRight: "5%",
padTop: "5%",
padBottom: "5%"
}
});
</script>
x
およびy
プロパティは、スケルトンのワールド座標空間におけるビューポートの左下隅の位置を指定します。width
およびheight
プロパティは、ビューポートのサイズを指定します。これらのプロパティのいずれかが省略された場合、プレイヤーは他のすべてのプロパティを無視し、上述の自動動作に移行します。
padLeft
、padRight
、padTop
、padBottom
の各プロパティは、ビューポートの各辺に追加するパディングを指定します。上の例では、パーセンテージで表されています。代わりにスケルトンのワールド座標空間での絶対値を指定することもできます。これらのプロパティのいずれかが省略された場合、プレーヤーはデフォルト値の10%
を想定します。
debugRender
プロパティを指定することで、上の画像のようにビューポートを視覚化することができます :
new spine.SpinePlayer("player-container", {
...
viewport: {
...
debugRender: true // ビューポートの境界を表示
}
});
</script>
プレイヤーがアニメーションを切り替えるとき、新旧のアニメーションのビューポートを0.2
秒間補間します。このビューポートの切り替え時間はtransitionTime
プロパティで設定できます:
new spine.SpinePlayer("player-container", {
...
viewport: {
...
transitionTime: 1 // 1秒間のビューポート間トランジション
}
});
</script>
特定のアニメーション用にビューポートを指定すると便利な場合があります。これは、animations
プロパティで行うことができます:
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>
上の例では、walk
とrun
アニメーション用にビューポートを指定しています。walk
アニメーション用には、パディングを含む完全なビューポートの境界を定義しています。このアニメーションでは、グローバルビューポート(グローバルビューポートが指定されていない場合は自動動作)が完全に上書きされます。
run
アニメーション用には、上部のパディングのみを指定しています。他のすべてのビューポート値は、グローバルビューポートから取得するか、または自動動作から取得します。
高度な再生
プレーヤーには、function setAnimation(name: string, loop: boolean)
が用意されており、名前でアニメーションを設定し、ループするかどうかを指定することができます。このfunctionは、指定されたアニメーションに基づいて、ビューポートを調整します。
setAnimation
は、success
コールバックが呼び出されるまで呼び出すことができません。successコールバックは、アトラスとスケルトンのデータがロードされるとすぐに起こります。success
にはSpineプレーヤーのインスタンスが渡されます。error
コールバックも用意されており、アトラスやスケルトンデータがロードされなかった場合に呼び出されます。
new spine.SpinePlayer("player-container", {
...
success: function (player) {
player.setAnimation("run", true);
},
error: function (player, reason) {
alert(reason);
}
});
</script>
さらにコントロールしたい場合は、プレーヤーの SkeletonとAnimationStateに直接アクセスして、スケルトンにアタッチメントを設定したり、スケルトンのスキンを変更したり、アニメーションをキューに入れたり、複数のアニメーションを異なるトラックで一度に再生したり、その他様々なことができます。プレーヤーには、skeleton
とanimationState
プロパティが用意されています:
new spine.SpinePlayer("player-container", {
...
success: function (player) {
player.skeleton.setAttachment("weapon", "sword");
player.animationState.setAnimation(0, "jump");
player.animationState.addAnimation(0, "walk", true, 0);
}
});
</script>
これらのプロパティに直接アクセスする場合は、showControls: false
を使用して、ご自身のコードで設定された構成にコントロールが干渉しないようにすることをお勧めします。
デフォルトでは、ビューポートはデフォルトのアニメーションにおけるスケルトンのバウンドに基づいています。プレーヤーのsetAnimation
functionとは異なり、AnimationStateを変更しても、ビューポートは変化しません。