Skip to content

Commit

Permalink
[ts][pixi-v7] Allow to define a bounds providers for the Spine game o…
Browse files Browse the repository at this point in the history
…bject. See #2734.
  • Loading branch information
davidetan committed Jan 29, 2025
1 parent 9fb49c2 commit f8bcbb3
Show file tree
Hide file tree
Showing 6 changed files with 360 additions and 15 deletions.
2 changes: 2 additions & 0 deletions spine-ts/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ <h1>spine-ts Examples</h1>
<li><a href="/spine-pixi-v7/example/physics3.html">Physics III</a></li>
<li><a href="/spine-pixi-v7/example/physics4.html">Physics IV</a></li>
<li><a href="/spine-pixi-v7/example/slot-objects.html">Slot Objects</a></li>
<li><a href="/spine-pixi-v7/example/bounds.html">Bounds</a></li>
<li><a href="/spine-pixi-v7/example/bunnymark.html?count=500">Bunny Mark</a></li>
</ul>
<li>PixiJS v8</li>
Expand All @@ -79,6 +80,7 @@ <h1>spine-ts Examples</h1>
<li><a href="/spine-pixi-v8/example/physics3.html">Physics III</a></li>
<li><a href="/spine-pixi-v8/example/physics4.html">Physics IV</a></li>
<li><a href="/spine-pixi-v8/example/slot-objects.html">Slot Objects</a></li>
<li><a href="/spine-pixi-v8/example/bounds.html">Bounds</a></li>
<li><a href="/spine-pixi-v8/example/bunnymark.html?count=500&renderer=webgpu">Bunny Mark</a></li>
</ul>
<li>Phaser</li>
Expand Down
12 changes: 12 additions & 0 deletions spine-ts/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

122 changes: 122 additions & 0 deletions spine-ts/spine-pixi-v7/example/bounds.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<html>
<head>
<meta charset="UTF-8" />
<title>spine-pixi-v7</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/pixi.min.js"></script>
<script src="../dist/iife/spine-pixi-v7.js"></script>
<link rel="stylesheet" href="../../index.css">
</head>

<body>
<script>
(async function () {

var app = new PIXI.Application({
width: window.innerWidth,
height: window.innerHeight,
resolution: window.devicePixelRatio || 1,
autoDensity: true,
resizeTo: window,
backgroundColor: 0x2c3e50,
hello: true,
});
document.body.appendChild(app.view);

// Pre-load the skeleton data and atlas. You can also load .json skeleton data.
PIXI.Assets.add({alias: "spineboyData", src: "./assets/spineboy-pro.skel"});
PIXI.Assets.add({alias: "spineboyAtlas", src: "./assets/spineboy-pma.atlas"});
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);


// Create the spine display object
const spineboy1 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2 });

const spineboy2 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
boundsProvider: new spine.SetupPoseBoundsProvider(),
});

const spineboy3 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
boundsProvider: new spine.SkinsAndAnimationBoundsProvider("portal", undefined, undefined, false),
});

const spineboy4 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
boundsProvider: new spine.SkinsAndAnimationBoundsProvider("portal", undefined, undefined, true),
});

const spineboy5 = spine.Spine.from({skeleton: "spineboyData", atlas: "spineboyAtlas", scale: .2,
boundsProvider: new spine.AABBRectangleBoundsProvider(-100, -100, 100, 100),
});

const maxHeight = spineboy3.getBounds().height;
const scaleFactor = 1 / (maxHeight * 5 / window.innerHeight);
const scaledMaxHeight = maxHeight * scaleFactor;

const texts = [
"Default bounds: dynamic, recomputed when queried",
"Set up pose bound: fixed, based on setup pose",
"Skin and animations based bound: fixed, the max AABB rectangle containing the skeleton with the given skin and given animations (clipping is ignored)",
"Skin and animations based bound: same as above, but with clipping true. The bounds is smaller because clipped attachments' parts are not considered",
"AABB Rectangle bounds: fixed, manually provided bounds. The origin is in skeleton root and size are in skeleton space",
]

const pointerOn = [];

const elements = [spineboy1, spineboy2, spineboy3, spineboy4, spineboy5].map((spineboy, i) => {
// const elements = [spineboy1].map((spineboy, i) => {

spineboy.x = window.innerWidth / 2;
spineboy.y = window.innerHeight / 2 + spineboy.getBounds().height / 2;

const x = 300 * scaleFactor;

// spineboy placement
spineboy.scale.set(scaleFactor);
spineboy.state.setAnimation(0, "portal", true);
spineboy.x = x;
spineboy.y = 70 * scaleFactor + (window.innerHeight / 10 * (1 + 2*i));

app.stage.addChild(spineboy);

// yellow rectangle to show bounds
const graphics = new PIXI.Graphics();
app.stage.addChild(graphics);

// text
const basicText = new PIXI.Text(
texts[i],
{
fontSize: 20 * scaleFactor,
fill: "white",
wordWrap: true,
wordWrapWidth: 400 * scaleFactor,
}
);
basicText.x = x + scaledMaxHeight + 0 * scaleFactor;
basicText.y = scaledMaxHeight * (i + .5);
basicText.anchor.set(0, 0.5);
app.stage.addChild(basicText);

// pointer events
spineboy.eventMode = "static";
spineboy.cursor = "pointer";
spineboy.on("pointerenter", () => pointerOn[i] = true);
spineboy.on("pointerleave", () => pointerOn[i] = false);

return [spineboy, graphics];
})

app.ticker.add((delta) => {
elements.forEach(([spineboy, graphic], i) => {
const bound = spineboy.getBounds();
graphic.clear();
graphic.lineStyle(2, 0xfeeb77);
graphic.beginFill(0xff0000, pointerOn[i] ? .2 : 0);
graphic.drawRect(bound.x, bound.y, bound.width, bound.height);
graphic.endFill();
})
})

})();
</script>
</body>
</html>
3 changes: 2 additions & 1 deletion spine-ts/spine-pixi-v7/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@pixi/graphics": "^7.2.4",
"@pixi/text": "^7.2.4",
"@pixi/assets": "^7.2.4",
"@pixi/mesh": "^7.2.4"
"@pixi/mesh": "^7.2.4",
"@pixi/events": "^7.2.4"
}
}
Loading

0 comments on commit f8bcbb3

Please sign in to comment.