mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-01 21:29:07 +08:00
Merge branch '3.7-beta' into 3.7-beta-cpp
This commit is contained in:
commit
2e29006764
Binary file not shown.
@ -189,7 +189,7 @@ package spine {
|
|||||||
var pathLength : Number = lengths[curveCount];
|
var pathLength : Number = lengths[curveCount];
|
||||||
if (percentPosition) position *= pathLength;
|
if (percentPosition) position *= pathLength;
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (var i : int = 0; i < spacesCount; i++)
|
for (var i : int = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength;
|
spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
this._world.length = 8;
|
this._world.length = 8;
|
||||||
@ -305,7 +305,7 @@ package spine {
|
|||||||
else
|
else
|
||||||
position *= pathLength / path.lengths[curveCount - 1];
|
position *= pathLength / path.lengths[curveCount - 1];
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (i = 0; i < spacesCount; i++)
|
for (i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength;
|
spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -267,7 +267,7 @@ float* spPathConstraint_computeWorldPositions(spPathConstraint* self, spPathAtta
|
|||||||
pathLength = lengths[curveCount];
|
pathLength = lengths[curveCount];
|
||||||
if (percentPosition) position *= pathLength;
|
if (percentPosition) position *= pathLength;
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (i = 0; i < spacesCount; i++)
|
for (i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength;
|
spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
if (self->worldCount != 8) {
|
if (self->worldCount != 8) {
|
||||||
@ -397,7 +397,7 @@ float* spPathConstraint_computeWorldPositions(spPathConstraint* self, spPathAtta
|
|||||||
else
|
else
|
||||||
position *= pathLength / path->lengths[curveCount - 1];
|
position *= pathLength / path->lengths[curveCount - 1];
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (i = 0; i < spacesCount; i++)
|
for (i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength;
|
spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -288,7 +288,7 @@ PathConstraint::computeWorldPositions(PathAttachment &path, int spacesCount, boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (int i = 0; i < spacesCount; ++i) {
|
for (int i = 1; i < spacesCount; ++i) {
|
||||||
_spaces[i] *= pathLength;
|
_spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -417,7 +417,7 @@ PathConstraint::computeWorldPositions(PathAttachment &path, int spacesCount, boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (int i = 0; i < spacesCount; ++i) {
|
for (int i = 1; i < spacesCount; ++i) {
|
||||||
_spaces[i] *= pathLength;
|
_spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -252,7 +252,7 @@ function PathConstraint:computeWorldPositions (path, spacesCount, tangents, perc
|
|||||||
local pathLength = lengths[curveCount + 1];
|
local pathLength = lengths[curveCount + 1];
|
||||||
if percentPosition then position = position * pathLength end
|
if percentPosition then position = position * pathLength end
|
||||||
if percentSpacing then
|
if percentSpacing then
|
||||||
i = 0
|
i = 1
|
||||||
while i < spacesCount do
|
while i < spacesCount do
|
||||||
spaces[i + 1] = spaces[i + 1] * pathLength
|
spaces[i + 1] = spaces[i + 1] * pathLength
|
||||||
i = i + 1
|
i = i + 1
|
||||||
@ -395,7 +395,7 @@ function PathConstraint:computeWorldPositions (path, spacesCount, tangents, perc
|
|||||||
position = position * pathLength / path.lengths[curveCount];
|
position = position * pathLength / path.lengths[curveCount];
|
||||||
end
|
end
|
||||||
if percentSpacing then
|
if percentSpacing then
|
||||||
i = 0
|
i = 1
|
||||||
while i < spacesCount do
|
while i < spacesCount do
|
||||||
spaces[i + 1] = spaces[i + 1] * pathLength
|
spaces[i + 1] = spaces[i + 1] * pathLength
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -5,5 +5,5 @@ tsc -p tsconfig.core.json
|
|||||||
tsc -p tsconfig.webgl.json
|
tsc -p tsconfig.webgl.json
|
||||||
tsc -p tsconfig.canvas.json
|
tsc -p tsconfig.canvas.json
|
||||||
tsc -p tsconfig.threejs.json
|
tsc -p tsconfig.threejs.json
|
||||||
tsc -p tsconfig.widget.json
|
tsc -p tsconfig.player.json
|
||||||
ls build/*.js build/*.ts | awk '{print "unexpand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}' | sh
|
ls build/*.js build/*.ts | awk '{print "unexpand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}' | sh
|
||||||
|
|||||||
@ -3039,7 +3039,7 @@ var spine;
|
|||||||
if (percentPosition)
|
if (percentPosition)
|
||||||
position *= pathLength_1;
|
position *= pathLength_1;
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (var i = 0; i < spacesCount; i++)
|
for (var i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength_1;
|
spaces[i] *= pathLength_1;
|
||||||
}
|
}
|
||||||
world = spine.Utils.setArraySize(this.world, 8);
|
world = spine.Utils.setArraySize(this.world, 8);
|
||||||
@ -3148,7 +3148,7 @@ var spine;
|
|||||||
else
|
else
|
||||||
position *= pathLength / path.lengths[curveCount - 1];
|
position *= pathLength / path.lengths[curveCount - 1];
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (var i = 0; i < spacesCount; i++)
|
for (var i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength;
|
spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
var segments = this.segments;
|
var segments = this.segments;
|
||||||
|
|||||||
@ -3039,7 +3039,7 @@ var spine;
|
|||||||
if (percentPosition)
|
if (percentPosition)
|
||||||
position *= pathLength_1;
|
position *= pathLength_1;
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (var i = 0; i < spacesCount; i++)
|
for (var i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength_1;
|
spaces[i] *= pathLength_1;
|
||||||
}
|
}
|
||||||
world = spine.Utils.setArraySize(this.world, 8);
|
world = spine.Utils.setArraySize(this.world, 8);
|
||||||
@ -3148,7 +3148,7 @@ var spine;
|
|||||||
else
|
else
|
||||||
position *= pathLength / path.lengths[curveCount - 1];
|
position *= pathLength / path.lengths[curveCount - 1];
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (var i = 0; i < spacesCount; i++)
|
for (var i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength;
|
spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
var segments = this.segments;
|
var segments = this.segments;
|
||||||
|
|||||||
@ -3039,7 +3039,7 @@ var spine;
|
|||||||
if (percentPosition)
|
if (percentPosition)
|
||||||
position *= pathLength_1;
|
position *= pathLength_1;
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (var i = 0; i < spacesCount; i++)
|
for (var i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength_1;
|
spaces[i] *= pathLength_1;
|
||||||
}
|
}
|
||||||
world = spine.Utils.setArraySize(this.world, 8);
|
world = spine.Utils.setArraySize(this.world, 8);
|
||||||
@ -3148,7 +3148,7 @@ var spine;
|
|||||||
else
|
else
|
||||||
position *= pathLength / path.lengths[curveCount - 1];
|
position *= pathLength / path.lengths[curveCount - 1];
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (var i = 0; i < spacesCount; i++)
|
for (var i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength;
|
spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
var segments = this.segments;
|
var segments = this.segments;
|
||||||
|
|||||||
@ -3039,7 +3039,7 @@ var spine;
|
|||||||
if (percentPosition)
|
if (percentPosition)
|
||||||
position *= pathLength_1;
|
position *= pathLength_1;
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (var i = 0; i < spacesCount; i++)
|
for (var i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength_1;
|
spaces[i] *= pathLength_1;
|
||||||
}
|
}
|
||||||
world = spine.Utils.setArraySize(this.world, 8);
|
world = spine.Utils.setArraySize(this.world, 8);
|
||||||
@ -3148,7 +3148,7 @@ var spine;
|
|||||||
else
|
else
|
||||||
position *= pathLength / path.lengths[curveCount - 1];
|
position *= pathLength / path.lengths[curveCount - 1];
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (var i = 0; i < spacesCount; i++)
|
for (var i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength;
|
spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
var segments = this.segments;
|
var segments = this.segments;
|
||||||
|
|||||||
@ -3039,7 +3039,7 @@ var spine;
|
|||||||
if (percentPosition)
|
if (percentPosition)
|
||||||
position *= pathLength_1;
|
position *= pathLength_1;
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (var i = 0; i < spacesCount; i++)
|
for (var i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength_1;
|
spaces[i] *= pathLength_1;
|
||||||
}
|
}
|
||||||
world = spine.Utils.setArraySize(this.world, 8);
|
world = spine.Utils.setArraySize(this.world, 8);
|
||||||
@ -3148,7 +3148,7 @@ var spine;
|
|||||||
else
|
else
|
||||||
position *= pathLength / path.lengths[curveCount - 1];
|
position *= pathLength / path.lengths[curveCount - 1];
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (var i = 0; i < spacesCount; i++)
|
for (var i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength;
|
spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
var segments = this.segments;
|
var segments = this.segments;
|
||||||
|
|||||||
@ -3039,7 +3039,7 @@ var spine;
|
|||||||
if (percentPosition)
|
if (percentPosition)
|
||||||
position *= pathLength_1;
|
position *= pathLength_1;
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (var i = 0; i < spacesCount; i++)
|
for (var i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength_1;
|
spaces[i] *= pathLength_1;
|
||||||
}
|
}
|
||||||
world = spine.Utils.setArraySize(this.world, 8);
|
world = spine.Utils.setArraySize(this.world, 8);
|
||||||
@ -3148,7 +3148,7 @@ var spine;
|
|||||||
else
|
else
|
||||||
position *= pathLength / path.lengths[curveCount - 1];
|
position *= pathLength / path.lengths[curveCount - 1];
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (var i = 0; i < spacesCount; i++)
|
for (var i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength;
|
spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
var segments = this.segments;
|
var segments = this.segments;
|
||||||
|
|||||||
@ -178,7 +178,7 @@ module spine {
|
|||||||
let pathLength = lengths[curveCount];
|
let pathLength = lengths[curveCount];
|
||||||
if (percentPosition) position *= pathLength;
|
if (percentPosition) position *= pathLength;
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (let i = 0; i < spacesCount; i++)
|
for (let i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength;
|
spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
world = Utils.setArraySize(this.world, 8);
|
world = Utils.setArraySize(this.world, 8);
|
||||||
@ -289,7 +289,7 @@ module spine {
|
|||||||
else
|
else
|
||||||
position *= pathLength / path.lengths[curveCount - 1];
|
position *= pathLength / path.lengths[curveCount - 1];
|
||||||
if (percentSpacing) {
|
if (percentSpacing) {
|
||||||
for (let i = 0; i < spacesCount; i++)
|
for (let i = 1; i < spacesCount; i++)
|
||||||
spaces[i] *= pathLength;
|
spaces[i] *= pathLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 470 KiB After Width: | Height: | Size: 470 KiB |
|
Before Width: | Height: | Size: 257 KiB After Width: | Height: | Size: 257 KiB |
48
spine-ts/player/example/index.html
Normal file
48
spine-ts/player/example/index.html
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<script src="../../build/spine-player.js"></script>
|
||||||
|
<link rel="stylesheet" href="../css/spine-player.css">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: gray;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="container" style="width: 640px; height: 380px;"></div>
|
||||||
|
<div id="container-raptor" style="width: 640px; height: 380px;"></div>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
// Creates a new spine player. The debugRender option enables
|
||||||
|
// rendering of viewports and padding for debugging purposes.
|
||||||
|
new spine.SpinePlayer(document.getElementById("container"), {
|
||||||
|
jsonUrl: "assets/spineboy-pro.json",
|
||||||
|
atlasUrl: "assets/spineboy-pma.atlas",
|
||||||
|
animation: "run",
|
||||||
|
premultipliedAlpha: true,
|
||||||
|
backgroundColor: "#cccccc",
|
||||||
|
viewport: {
|
||||||
|
debugRender: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Creates a new spine player with a transparent background,
|
||||||
|
// so content from the website shines through. Hides the controls.
|
||||||
|
new spine.SpinePlayer(document.getElementById("container-raptor"), {
|
||||||
|
jsonUrl: "assets/raptor-pro.json",
|
||||||
|
atlasUrl: "assets/raptor-pma.atlas",
|
||||||
|
animation: "walk",
|
||||||
|
showControls: false,
|
||||||
|
premultipliedAlpha: true,
|
||||||
|
backgroundColor: "#00000000",
|
||||||
|
alpha: true
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -4,18 +4,18 @@
|
|||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
"preserveConstEnums": true,
|
"preserveConstEnums": true,
|
||||||
"outFile": "build/spine-widget.js",
|
"outFile": "build/spine-player.js",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"declaration": true
|
"declaration": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"core/src/**/*",
|
"core/src/**/*",
|
||||||
"webgl/src/**/*",
|
"webgl/src/**/*",
|
||||||
"widget/src/**/*"
|
"player/src/**/*"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"canvas",
|
"canvas",
|
||||||
"threejs",
|
"threejs",
|
||||||
"build"
|
"build"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -1,29 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<script src="../../build/spine-widget.js"></script>
|
|
||||||
<link rel="stylesheet" href="../css/spine-player.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
html, body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="player"></div>
|
|
||||||
</body>
|
|
||||||
<script>
|
|
||||||
window.addEventListener("message", function (event) {
|
|
||||||
new spine.SpinePlayer(document.getElementById("player"), event.data);
|
|
||||||
}, false);
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
iframe {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!--<iframe id="player" src="http://esotericsoftware.com/spine-player/3.7/iframe.html" width="600" height="480"></iframe>-->
|
|
||||||
<iframe id="player" src="http://localhost:8000/widget/example/iframe-local.html" width="600" height="480"></iframe>
|
|
||||||
</body>
|
|
||||||
<script>
|
|
||||||
var player = document.getElementById("player");
|
|
||||||
var playerConfig = {
|
|
||||||
atlasUrl: "http://esotericsoftware.com/files/examples/spineboy/export/spineboy-pma.atlas",
|
|
||||||
jsonUrl: "http://esotericsoftware.com/files/examples/spineboy/export/spineboy-pro.json",
|
|
||||||
premultipliedAlpha: true
|
|
||||||
};
|
|
||||||
player.addEventListener("load", function () {
|
|
||||||
player.contentWindow.postMessage(playerConfig, "*");
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</html>
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<script src="./spine-widget.js"></script>
|
|
||||||
<link rel="stylesheet" href="./spine-player.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
html, body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="player"></div>
|
|
||||||
</body>
|
|
||||||
<script>
|
|
||||||
window.addEventListener("message", function (event) {
|
|
||||||
new spine.SpinePlayer(document.getElementById("player"), event.data);
|
|
||||||
}, false);
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,130 +0,0 @@
|
|||||||
<html>
|
|
||||||
<script src="../../build/spine-widget.js"></script>
|
|
||||||
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
|
|
||||||
<body>
|
|
||||||
<center>
|
|
||||||
<!-- You can programmatically initialize a widget -->
|
|
||||||
<div id="spine-widget" style="margin-bottom: 20px; width: 640px; height: 480px;"></div>
|
|
||||||
<!-- You can also specify your own x/y and scale for the skeleton -->
|
|
||||||
<div style="margin-bottom: 20px; width: 100%; height: 150px;" class="spine-widget" data-json="assets/raptor-pro.json" data-atlas="assets/raptor-pma.atlas" data-animation="jump" data-fit-to-canvas="false" data-scale="0.1" data-x="200" data-y="10"></div>
|
|
||||||
<!-- Or make things real small -->
|
|
||||||
<div style="margin-bottom: 20px; width: 320px; height: 240px;" class="spine-widget" data-json="assets/raptor-pro.json" data-atlas="assets/raptor-pma.atlas" data-animation="walk" data-background-color="#cc0000"></div>
|
|
||||||
<!-- You can also specify the .JSON and .atlas files inline to reduce the number of requests made to the server -->
|
|
||||||
<div id="spine-widget-inline" style="margin-bottom: 20px; width: 640px; height: 480px;"></div>
|
|
||||||
</center>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<script id="atlas" type="text/plain">
|
|
||||||
spine-logo.png
|
|
||||||
size: 128,64
|
|
||||||
format: RGBA8888
|
|
||||||
filter: Linear,Linear
|
|
||||||
repeat: none
|
|
||||||
logo
|
|
||||||
rotate: false
|
|
||||||
xy: 2, 2
|
|
||||||
size: 104, 32
|
|
||||||
orig: 104, 32
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script id="atlasPage" type="text/plain">
|
|
||||||
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABACAYAAADS1n9/AAAFLElEQVR42u2bTWhVRxTH//myJtTmGT+SYEvTFGvTRBOTV8tLbXwL0e3bZCEiBtRuzUa6ElJX2QgKiqibiG4MfiSCiHaToohowQQEUShY/MCNNQUXLtSUs7gwDHPvzLx737svef8fDNHk3nnnnPnP3DNn7gMIIWTR0NKAlpPrcXKqB1Py80A7DvSvQH9DDRoYnSpgvBPjC3ks6O3DNnx4NYhXc1nM3dmMO5PdmDz4JQ4ur8VyRm0Jcbkbl00CCGsn1uMEo7aEuNSNSz4CmOnDDKNWBH19fQOjo6O/qU1+53p/Pp/fLq2jo6Mzqt9CoTDsY9fhr3HYRwAXunDBp/8wu8XOOHab0Pv0jXHJBn5qavqP+fn/FkxtZubPv2xGSgCD68WpoF+519Tns2f//Osa0NZlaH3zM964CmDXWuzyGfzApomJc5OB3bOzc38XGwsTEhPxOSzGEv9UhCCq1w0T5/UABIPqKoCRkZFfw5xVm6sIJOt/sgVPbIP/MIuHPrsD1W4ZBBe7JTaZTGal62ccO3b8tEssZBzKLgLVOJkB6jIoTkpAxGEfAaizXu6VPoJlVp8J8m/XYNbXoH54DYbPd+H805/w9P0Q3gcD/3Yr3p7ZgDOrGrDKd/lXbQmzW2LjMyHUma/2L/9X/dVXX19xxUZ1KuyD5fc2o9RAqjPKdJ9+rWswTTTXozlTj0yx95vslsE22a2KQAbTZXVV+5XPCrtWnTRx4hFLAHH60QMpDrmuPLZrS4lut4jWdUBty/XY2O/jwbXiry05TCUePg75BNK2YqgOxxVfkgKw2a3mRlEz2vfaJCejF/qyJs+9JAKZ5PIo5L5A7sYm3Li9Gbevb8T1iz/gohSI7vXj3sscXs5vxfz9AdyPkwO42K0+r202+w5oUpPRewto2gXoyUrSgdQdtgXzag+uumwBd7didyUIwPRosTWfeCQuAtO+15S1piWA6R5ML2YB+LZUagKy/JsKNyIOn0JQKQRw5BscsQ3+pzw+dTaisxIFoFf/olqxj+FEVwS9eGHLTEstAKkGvsjhRZQAxjowVurcpVgBLMqzAb0qlqTDIjKf7FtY9xnWnd2As68H8VotAF3biGs7WrCjHMmrqwDEH7Vf/Zxh0aA6HFWg0ANpc1itkMkjxteupjo0NdaiMeltYJK7ADWvSn1ZT0IAUU6YCkFRlUU1OLYiSTnrAEkKQC0EpVnsiizGSPDDZqsMlLpFjEoETVmvOG3qW88v4ma8ckaQXYFsYTUKlZIEmmodLkKXSVa2HUCwDMsgi3EiiODwIzgEcimRRm17pG+ZCcE5uL7flb/52l1Xg7p97dg38T0m7vbj7rtf8C7ICaQgJOcDlSAA/VGn1liCOAexlvgHk61sZwGuR7ZimO2ZrgdSBjzq/Nv2mIhiZwt2Ru0GfBLCUgvAtOLZWlkPg8L2/urKUGwhKOxFk6DAVKzNg80YjBLA9pVwrqKpuxGXEz61dO5TrZNro166kc+WvlNLFmWQ1WXJtxQZNZMkyMX2a6K2BrWzWcyaBv9KD67II6JSk2pTnFN/JSyNbDoubcvQduo7nHowgAe3enHr6Lc4OpTBEEh1CIBQAIQCIFUtgN7P0Ssvhz76EY/kq2GPt+Dx8xyeH/oKhzgiZUZ9vbxcZc+9bdhr2gnIN4k4IlVAVxO6Pm7DR10A+9uxn9GpEqQqKO8IyjeEb27CzT2t2MOoEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQpYG/wPiudlO23hTHQAAAABJRU5ErkJggg==
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script id="json" type="text/plain">
|
|
||||||
{
|
|
||||||
"skeleton": { "hash": "MYXtB/H4Z2fp6J+/XZiyN+f9Hfc", "spine": "3.5.49", "width": 104, "height": 32, "images": "" },
|
|
||||||
"bones": [
|
|
||||||
{ "name": "root" }
|
|
||||||
],
|
|
||||||
"slots": [
|
|
||||||
{ "name": "spine-logo", "bone": "root", "attachment": "logo" }
|
|
||||||
],
|
|
||||||
"skins": {
|
|
||||||
"default": {
|
|
||||||
"spine-logo": {
|
|
||||||
"logo": { "width": 104, "height": 32 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"animations": {
|
|
||||||
"animation": {
|
|
||||||
"bones": {
|
|
||||||
"root": {
|
|
||||||
"rotate": [
|
|
||||||
{ "time": 0, "angle": 0 },
|
|
||||||
{ "time": 0.8333, "angle": 39.96 },
|
|
||||||
{ "time": 1.6667, "angle": 0 }
|
|
||||||
],
|
|
||||||
"scale": [
|
|
||||||
{ "time": 0, "x": 1, "y": 1 },
|
|
||||||
{ "time": 0.8333, "x": 3, "y": 3 },
|
|
||||||
{ "time": 1.6667, "x": 1, "y": 1 }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function supportsWebGL() {
|
|
||||||
try {
|
|
||||||
var canvas = document.createElement("canvas");
|
|
||||||
var ctx = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
|
|
||||||
return ctx != null;
|
|
||||||
} catch(e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!supportsWebGL()) {
|
|
||||||
alert('WebGL is unavailable.');
|
|
||||||
}
|
|
||||||
|
|
||||||
spineWidget = new spine.SpineWidget("spine-widget", {
|
|
||||||
json: "assets/spineboy-pro.json",
|
|
||||||
atlas: "assets/spineboy-pma.atlas",
|
|
||||||
animation: "run",
|
|
||||||
backgroundColor: "#00000000",
|
|
||||||
debug: true,
|
|
||||||
success: function (widget) {
|
|
||||||
var animIndex = 0;
|
|
||||||
widget.canvas.onclick = function () {
|
|
||||||
animIndex++;
|
|
||||||
var animations = widget.skeleton.data.animations;
|
|
||||||
if (animIndex >= animations.length) animIndex = 0;
|
|
||||||
widget.setAnimation(animations[animIndex].name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
json = document.getElementById("json").innerHTML;
|
|
||||||
atlas = document.getElementById("atlas").innerHTML;
|
|
||||||
atlasPageContent = document.getElementById("atlasPage").innerHTML;
|
|
||||||
|
|
||||||
spineWidgetInline = new spine.SpineWidget("spine-widget-inline", {
|
|
||||||
jsonContent: json,
|
|
||||||
atlasContent: atlas,
|
|
||||||
atlasPages: ["spine-logo.png"],
|
|
||||||
atlasPagesContent: [atlasPageContent],
|
|
||||||
animation: "animation",
|
|
||||||
backgroundColor: "#00000000",
|
|
||||||
debug: true,
|
|
||||||
success: function (widget) {
|
|
||||||
var animIndex = 0;
|
|
||||||
widget.canvas.onclick = function () {
|
|
||||||
animIndex++;
|
|
||||||
let animations = widget.skeleton.data.animations;
|
|
||||||
if (animIndex >= animations.length) animIndex = 0;
|
|
||||||
widget.setAnimation(animations[animIndex].name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<script src="../../build/spine-widget.js"></script>
|
|
||||||
<link rel="stylesheet" href="../css/spine-player.css">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
background: gray;
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="container" style="width: 100%; height: 90vh;"></div>
|
|
||||||
</body>
|
|
||||||
<script>
|
|
||||||
new spine.SpinePlayer(document.getElementById("container"), {
|
|
||||||
jsonUrl: "assets/spineboy-pro.json",
|
|
||||||
atlasUrl: "assets/spineboy-pma.atlas",
|
|
||||||
premultipliedAlpha: true,
|
|
||||||
backgroundColor: "#cccccc",
|
|
||||||
viewport: {
|
|
||||||
debugRender: true,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
<html>
|
|
||||||
<script src="../../build/spine-widget.js"></script>
|
|
||||||
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
|
|
||||||
<body>
|
|
||||||
<center>
|
|
||||||
<!-- You can programmatically initialize a widget -->
|
|
||||||
<button id="reload">Reload</button>
|
|
||||||
</center>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
var numWidgets = 0;
|
|
||||||
var spineWidgets = []
|
|
||||||
|
|
||||||
function reload() {
|
|
||||||
// tear down old widgets if any
|
|
||||||
for (var i = 0; i < spineWidgets.length; i++) {
|
|
||||||
spineWidgets[i].pause();
|
|
||||||
var widgetDiv = document.getElementById("spine-widget-" + spineWidgets[i].id);
|
|
||||||
if (widgetDiv) widgetDiv.parentNode.removeChild(widgetDiv)
|
|
||||||
}
|
|
||||||
|
|
||||||
spineWidgets = []
|
|
||||||
|
|
||||||
for (var i = 0; i < 5; i++) {
|
|
||||||
var widgetDiv = document.createElement("div");
|
|
||||||
widgetDiv.id = "spine-widget-" + numWidgets;
|
|
||||||
widgetDiv.style = "margin-bottom: 20px; width: 640px; height: 480px;"
|
|
||||||
document.body.appendChild(widgetDiv)
|
|
||||||
|
|
||||||
spineWidget = new spine.SpineWidget("spine-widget-" + numWidgets, {
|
|
||||||
json: "assets/spineboy.json",
|
|
||||||
atlas: "assets/spineboy.atlas",
|
|
||||||
animation: "run",
|
|
||||||
backgroundColor: "#00000000",
|
|
||||||
debug: true,
|
|
||||||
success: function (widget) {
|
|
||||||
var animIndex = 0;
|
|
||||||
widget.canvas.onclick = function () {
|
|
||||||
animIndex++;
|
|
||||||
var animations = widget.skeleton.data.animations;
|
|
||||||
if (animIndex >= animations.length) animIndex = 0;
|
|
||||||
widget.setAnimation(animations[animIndex].name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
spineWidget.id = numWidgets++;
|
|
||||||
spineWidgets.push(spineWidget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var reloadButton = document.getElementById("reload");
|
|
||||||
reloadButton.onclick = reload;
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,366 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* Spine Runtimes Software License v2.5
|
|
||||||
*
|
|
||||||
* Copyright (c) 2013-2016, Esoteric Software
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
|
||||||
* non-transferable license to use, install, execute, and perform the Spine
|
|
||||||
* Runtimes software and derivative works solely for personal or internal
|
|
||||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
|
||||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
|
||||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
|
||||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
|
||||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
|
||||||
* or other intellectual property or proprietary rights notices on or in the
|
|
||||||
* Software, including any copy thereof. Redistributions in binary or source
|
|
||||||
* form must include this license and terms.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
||||||
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
|
||||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
||||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
module spine {
|
|
||||||
export class SpineWidget {
|
|
||||||
skeleton: Skeleton;
|
|
||||||
state: AnimationState;
|
|
||||||
context: spine.webgl.ManagedWebGLRenderingContext;
|
|
||||||
canvas: HTMLCanvasElement;
|
|
||||||
debugRenderer: spine.webgl.SkeletonDebugRenderer;
|
|
||||||
|
|
||||||
private config: SpineWidgetConfig;
|
|
||||||
private assetManager: spine.webgl.AssetManager;
|
|
||||||
private shader: spine.webgl.Shader;
|
|
||||||
private batcher: spine.webgl.PolygonBatcher;
|
|
||||||
private shapes: spine.webgl.ShapeRenderer;
|
|
||||||
private debugShader: spine.webgl.Shader;
|
|
||||||
private mvp = new spine.webgl.Matrix4();
|
|
||||||
private skeletonRenderer: spine.webgl.SkeletonRenderer;
|
|
||||||
private paused = false;
|
|
||||||
private lastFrameTime = Date.now() / 1000.0;
|
|
||||||
private backgroundColor = new Color();
|
|
||||||
private loaded = false;
|
|
||||||
private bounds = { offset: new Vector2(), size: new Vector2() };
|
|
||||||
|
|
||||||
|
|
||||||
constructor (element: HTMLElement | string, config: SpineWidgetConfig) {
|
|
||||||
if (!element) throw new Error("Please provide a DOM element, e.g. document.getElementById('myelement')");
|
|
||||||
if (!config) throw new Error("Please provide a configuration, specifying at least the json file, atlas file and animation name");
|
|
||||||
|
|
||||||
let elementId = element as string;
|
|
||||||
if (typeof(element) === "string") element = document.getElementById(element as string);
|
|
||||||
if (element == null) throw new Error(`Element ${elementId} does not exist`);
|
|
||||||
|
|
||||||
this.validateConfig(config);
|
|
||||||
|
|
||||||
let existingCanvas = <HTMLCanvasElement>element.children[0];
|
|
||||||
let canvas = this.canvas = existingCanvas || document.createElement("canvas");
|
|
||||||
canvas.style.width = "100%";
|
|
||||||
canvas.style.height = "100%";
|
|
||||||
if (!existingCanvas) {
|
|
||||||
(<HTMLElement> element).appendChild(canvas);
|
|
||||||
}
|
|
||||||
canvas.width = (<HTMLElement>element).clientWidth;
|
|
||||||
canvas.height = (<HTMLElement>element).clientHeight;
|
|
||||||
var webglConfig = { alpha: config.alpha };
|
|
||||||
this.context = new spine.webgl.ManagedWebGLRenderingContext(canvas, webglConfig);
|
|
||||||
|
|
||||||
this.shader = spine.webgl.Shader.newTwoColoredTextured(this.context);
|
|
||||||
this.batcher = new spine.webgl.PolygonBatcher(this.context);
|
|
||||||
this.mvp.ortho2d(0, 0, canvas.width - 1, canvas.height - 1);
|
|
||||||
this.skeletonRenderer = new spine.webgl.SkeletonRenderer(this.context);
|
|
||||||
this.debugShader = spine.webgl.Shader.newColored(this.context);
|
|
||||||
this.debugRenderer = new spine.webgl.SkeletonDebugRenderer(this.context);
|
|
||||||
this.shapes = new spine.webgl.ShapeRenderer(this.context);
|
|
||||||
|
|
||||||
let assets = this.assetManager = new spine.webgl.AssetManager(this.context, config.imagesPath ? config.imagesPath : "");
|
|
||||||
if (!config.atlasContent) {
|
|
||||||
assets.loadText(config.atlas);
|
|
||||||
}
|
|
||||||
if (!config.jsonContent) {
|
|
||||||
assets.loadText(config.json);
|
|
||||||
}
|
|
||||||
if (config.atlasPages == null) {
|
|
||||||
if (config.atlas) {
|
|
||||||
var atlasPage = config.atlas.replace(".atlas", ".png");
|
|
||||||
if (atlasPage.lastIndexOf(config.imagesPath) == 0) {
|
|
||||||
atlasPage = atlasPage.substr(config.imagesPath.length);
|
|
||||||
}
|
|
||||||
assets.loadTexture(atlasPage);
|
|
||||||
} else {
|
|
||||||
let firstLine = config.atlasContent.trim().split("\n")[0];
|
|
||||||
assets.loadTexture(firstLine);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (let i = 0; i < config.atlasPages.length; i++) {
|
|
||||||
if (config.atlasPagesContent && config.atlasPagesContent[i]) {
|
|
||||||
assets.loadTextureData(config.atlasPages[i], config.atlasPagesContent[i]);
|
|
||||||
} else {
|
|
||||||
assets.loadTexture(config.atlasPages[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
requestAnimationFrame(() => { this.load(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
private validateConfig (config: SpineWidgetConfig) {
|
|
||||||
if (!config.atlas && !config.atlasContent) throw new Error("Please specify config.atlas or config.atlasContent");
|
|
||||||
if (!config.json && !config.jsonContent) throw new Error("Please specify config.json or config.jsonContent");
|
|
||||||
if (!config.animation) throw new Error("Please specify config.animationName");
|
|
||||||
|
|
||||||
if (!config.scale) config.scale = 1.0;
|
|
||||||
if (!config.skin) config.skin = "default";
|
|
||||||
if (config.loop === undefined) config.loop = true;
|
|
||||||
if (!config.x) config.x = 0;
|
|
||||||
if (!config.y) config.y = 0;
|
|
||||||
if (config.fitToCanvas === undefined) config.fitToCanvas = true;
|
|
||||||
if (!config.backgroundColor) config.backgroundColor = "#555555";
|
|
||||||
if (!config.imagesPath) {
|
|
||||||
if (config.atlas) {
|
|
||||||
let index = config.atlas.lastIndexOf("/");
|
|
||||||
if (index != -1) {
|
|
||||||
config.imagesPath = config.atlas.substr(0, index) + "/";
|
|
||||||
} else {
|
|
||||||
config.imagesPath = "";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
config.imagesPath = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (config.json && config.json.lastIndexOf(config.imagesPath) == 0) {
|
|
||||||
config.json = config.json.substr(config.imagesPath.length);
|
|
||||||
}
|
|
||||||
if (config.atlas && config.atlas.lastIndexOf(config.imagesPath) == 0) {
|
|
||||||
config.atlas = config.atlas.substr(config.imagesPath.length);
|
|
||||||
}
|
|
||||||
if (!config.premultipliedAlpha === undefined) config.premultipliedAlpha = false;
|
|
||||||
if (!config.debug === undefined) config.debug = false;
|
|
||||||
if (!config.alpha === undefined) config.alpha = true;
|
|
||||||
this.backgroundColor.setFromString(config.backgroundColor);
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
private load () {
|
|
||||||
let assetManager = this.assetManager;
|
|
||||||
let imagesPath = this.config.imagesPath;
|
|
||||||
let config = this.config;
|
|
||||||
if (assetManager.isLoadingComplete()) {
|
|
||||||
if (assetManager.hasErrors()) {
|
|
||||||
if (config.error) config.error(this, "Failed to load assets: " + JSON.stringify(assetManager.getErrors()));
|
|
||||||
else throw new Error("Failed to load assets: " + JSON.stringify(assetManager.getErrors()));
|
|
||||||
}
|
|
||||||
|
|
||||||
let atlasContent = config.atlasContent === undefined ? this.assetManager.get(this.config.atlas) as string : config.atlasContent;
|
|
||||||
let atlas = new spine.TextureAtlas(atlasContent, (path: string) => {
|
|
||||||
let texture = assetManager.get(path) as spine.webgl.GLTexture;
|
|
||||||
return texture;
|
|
||||||
});
|
|
||||||
|
|
||||||
let atlasLoader = new spine.AtlasAttachmentLoader(atlas);
|
|
||||||
var skeletonJson = new spine.SkeletonJson(atlasLoader);
|
|
||||||
|
|
||||||
// Set the scale to apply during parsing, parse the file, and create a new skeleton.
|
|
||||||
skeletonJson.scale = config.scale;
|
|
||||||
let jsonContent = config.jsonContent === undefined ? assetManager.get(config.json) as string : config.jsonContent;
|
|
||||||
var skeletonData = skeletonJson.readSkeletonData(jsonContent);
|
|
||||||
var skeleton = this.skeleton = new spine.Skeleton(skeletonData);
|
|
||||||
var bounds = this.bounds;
|
|
||||||
skeleton.setSkinByName(config.skin);
|
|
||||||
skeleton.setToSetupPose();
|
|
||||||
skeleton.updateWorldTransform();
|
|
||||||
skeleton.getBounds(bounds.offset, bounds.size, []);
|
|
||||||
if (!config.fitToCanvas) {
|
|
||||||
skeleton.x = config.x;
|
|
||||||
skeleton.y = config.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
var animationState = this.state = new spine.AnimationState(new spine.AnimationStateData(skeleton.data));
|
|
||||||
animationState.setAnimation(0, config.animation, config.loop);
|
|
||||||
this.loaded = true;
|
|
||||||
if (config.success) config.success(this);
|
|
||||||
requestAnimationFrame(() => { this.render(); });
|
|
||||||
} else
|
|
||||||
requestAnimationFrame(() => { this.load(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
private render () {
|
|
||||||
var now = Date.now() / 1000;
|
|
||||||
var delta = now - this.lastFrameTime;
|
|
||||||
if (delta > 0.1) delta = 0;
|
|
||||||
this.lastFrameTime = now;
|
|
||||||
|
|
||||||
let gl = this.context.gl;
|
|
||||||
let color = this.backgroundColor;
|
|
||||||
this.resize();
|
|
||||||
gl.clearColor(color.r, color.g, color.b, color.a);
|
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
// Apply the animation state based on the delta time.
|
|
||||||
var state = this.state;
|
|
||||||
var skeleton = this.skeleton;
|
|
||||||
var premultipliedAlpha = this.config.premultipliedAlpha;
|
|
||||||
state.update(delta);
|
|
||||||
state.apply(skeleton);
|
|
||||||
skeleton.updateWorldTransform();
|
|
||||||
|
|
||||||
// Draw the skeleton
|
|
||||||
let shader = this.shader;
|
|
||||||
let batcher = this.batcher;
|
|
||||||
let skeletonRenderer = this.skeletonRenderer;
|
|
||||||
shader.bind();
|
|
||||||
shader.setUniformi(spine.webgl.Shader.SAMPLER, 0);
|
|
||||||
shader.setUniform4x4f(spine.webgl.Shader.MVP_MATRIX, this.mvp.values);
|
|
||||||
batcher.begin(shader);
|
|
||||||
skeletonRenderer.premultipliedAlpha = premultipliedAlpha;
|
|
||||||
skeletonRenderer.draw(batcher, skeleton);
|
|
||||||
batcher.end();
|
|
||||||
shader.unbind();
|
|
||||||
|
|
||||||
// Draw debug information if requested via config
|
|
||||||
if (this.config.debug) {
|
|
||||||
let shader = this.debugShader;
|
|
||||||
let shapes = this.shapes;
|
|
||||||
let renderer = this.debugRenderer;
|
|
||||||
shader.bind();
|
|
||||||
shader.setUniform4x4f(spine.webgl.Shader.MVP_MATRIX, this.mvp.values);
|
|
||||||
renderer.premultipliedAlpha = premultipliedAlpha;
|
|
||||||
shapes.begin(shader);
|
|
||||||
renderer.draw(shapes, skeleton);
|
|
||||||
shapes.end();
|
|
||||||
shader.unbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.paused) requestAnimationFrame(() => { this.render(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
private resize () {
|
|
||||||
let canvas = this.canvas;
|
|
||||||
let w = canvas.clientWidth;
|
|
||||||
let h = canvas.clientHeight;
|
|
||||||
let bounds = this.bounds;
|
|
||||||
|
|
||||||
var devicePixelRatio = window.devicePixelRatio || 1;
|
|
||||||
if (canvas.width != Math.floor(w * devicePixelRatio) || canvas.height != Math.floor(h * devicePixelRatio)) {
|
|
||||||
canvas.width = Math.floor(w * devicePixelRatio);
|
|
||||||
canvas.height = Math.floor(h * devicePixelRatio);
|
|
||||||
}
|
|
||||||
|
|
||||||
// magic
|
|
||||||
if (this.config.fitToCanvas) {
|
|
||||||
var centerX = bounds.offset.x + bounds.size.x / 2;
|
|
||||||
var centerY = bounds.offset.y + bounds.size.y / 2;
|
|
||||||
var scaleX = bounds.size.x / w;
|
|
||||||
var scaleY = bounds.size.y / h;
|
|
||||||
var scale = Math.max(scaleX, scaleY) * 1.2;
|
|
||||||
if (scale < 1) scale = 1;
|
|
||||||
var width = w * scale;
|
|
||||||
var height = h * scale;
|
|
||||||
this.skeleton.x = this.skeleton.y = 0;
|
|
||||||
this.mvp.ortho2d(centerX - width / 2, centerY - height / 2, width, height);
|
|
||||||
} else {
|
|
||||||
this.mvp.ortho2d(0, 0, w - 1, h - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.context.gl.viewport(0, 0, canvas.width, canvas.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
pause () {
|
|
||||||
this.paused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
play () {
|
|
||||||
this.paused = false;
|
|
||||||
requestAnimationFrame(() => { this.render(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
isPlaying () {
|
|
||||||
return !this.paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
setAnimation (animationName: string, animationStateListener: AnimationStateListener2 = null) {
|
|
||||||
if (!this.loaded) throw new Error("Widget isn't loaded yet");
|
|
||||||
this.skeleton.setToSetupPose();
|
|
||||||
let entry = this.state.setAnimation(0, animationName, this.config.loop);
|
|
||||||
entry.listener = animationStateListener
|
|
||||||
}
|
|
||||||
|
|
||||||
static loadWidgets() {
|
|
||||||
let widgets = document.getElementsByClassName("spine-widget");
|
|
||||||
for (var i = 0; i < widgets.length; i++) {
|
|
||||||
SpineWidget.loadWidget(<HTMLElement>widgets[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static loadWidget(widget: HTMLElement) {
|
|
||||||
let config = new SpineWidgetConfig();
|
|
||||||
config.atlas = widget.getAttribute("data-atlas");
|
|
||||||
config.json = widget.getAttribute("data-json");
|
|
||||||
config.animation = widget.getAttribute("data-animation");
|
|
||||||
if (widget.getAttribute("data-images-path")) config.imagesPath = widget.getAttribute("data-images-path");
|
|
||||||
if (widget.getAttribute("data-atlas-pages")) config.atlasPages = widget.getAttribute("data-atlas-pages").split(",");
|
|
||||||
if (widget.getAttribute("data-skin")) config.skin = widget.getAttribute("data-skin");
|
|
||||||
if (widget.getAttribute("data-loop")) config.loop = widget.getAttribute("data-loop") === "true";
|
|
||||||
if (widget.getAttribute("data-scale")) config.scale = parseFloat(widget.getAttribute("data-scale"));
|
|
||||||
if (widget.getAttribute("data-x")) config.x = parseFloat(widget.getAttribute("data-x"));
|
|
||||||
if (widget.getAttribute("data-y")) config.y = parseFloat(widget.getAttribute("data-y"));
|
|
||||||
if (widget.getAttribute("data-fit-to-canvas")) config.fitToCanvas = widget.getAttribute("data-fit-to-canvas") === "true";
|
|
||||||
if (widget.getAttribute("data-background-color")) config.backgroundColor = widget.getAttribute("data-background-color");
|
|
||||||
if (widget.getAttribute("data-premultiplied-alpha")) config.premultipliedAlpha = widget.getAttribute("data-premultiplied-alpha") === "true";
|
|
||||||
if (widget.getAttribute("data-debug")) config.debug = widget.getAttribute("data-debug") === "true";
|
|
||||||
if (widget.getAttribute("data-alpha")) config.alpha = widget.getAttribute("data-alpha") === "true";
|
|
||||||
|
|
||||||
new spine.SpineWidget(widget, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
static pageLoaded = false;
|
|
||||||
private static ready () {
|
|
||||||
if (SpineWidget.pageLoaded) return;
|
|
||||||
SpineWidget.pageLoaded = true;
|
|
||||||
SpineWidget.loadWidgets();
|
|
||||||
}
|
|
||||||
|
|
||||||
static setupDOMListener() {
|
|
||||||
if (document.addEventListener) {
|
|
||||||
document.addEventListener("DOMContentLoaded", SpineWidget.ready, false);
|
|
||||||
window.addEventListener("load", SpineWidget.ready, false);
|
|
||||||
} else {
|
|
||||||
(<any>document).attachEvent("onreadystatechange", function readyStateChange() {
|
|
||||||
if (document.readyState === "complete" ) SpineWidget.ready();
|
|
||||||
});
|
|
||||||
(<any>window).attachEvent("onload", SpineWidget.ready);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SpineWidgetConfig {
|
|
||||||
json: string;
|
|
||||||
jsonContent: any;
|
|
||||||
atlas: string;
|
|
||||||
atlasContent: string;
|
|
||||||
animation: string;
|
|
||||||
imagesPath: string;
|
|
||||||
atlasPages: string[];
|
|
||||||
atlasPagesContent: string[];
|
|
||||||
skin = "default";
|
|
||||||
loop = true;
|
|
||||||
scale = 1.0;
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
alpha = true;
|
|
||||||
fitToCanvas = true;
|
|
||||||
backgroundColor = "#555555";
|
|
||||||
premultipliedAlpha = false;
|
|
||||||
debug = false;
|
|
||||||
success: (widget: SpineWidget) => void;
|
|
||||||
error: (widget: SpineWidget, msg: string) => void;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spine.SpineWidget.setupDOMListener();
|
|
||||||
Loading…
x
Reference in New Issue
Block a user