mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 23:34:53 +08:00
[ts][player] Per animation viewports.
This commit is contained in:
parent
88aaa7e70c
commit
db7d6b2cc2
9
spine-ts/build/spine-widget.d.ts
vendored
9
spine-ts/build/spine-widget.d.ts
vendored
@ -1708,6 +1708,10 @@ declare module spine {
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
padLeft: string;
|
||||
padRight: string;
|
||||
padTop: string;
|
||||
padBottom: string;
|
||||
};
|
||||
alpha: boolean;
|
||||
backgroundColor: string;
|
||||
@ -1746,6 +1750,9 @@ declare module spine {
|
||||
private paused;
|
||||
private playTime;
|
||||
private speed;
|
||||
private animationViewports;
|
||||
private currentViewport;
|
||||
private previousViewport;
|
||||
private selectedBones;
|
||||
constructor(parent: HTMLElement, config: SpinePlayerConfig);
|
||||
validateConfig(config: SpinePlayerConfig): SpinePlayerConfig;
|
||||
@ -1761,6 +1768,8 @@ declare module spine {
|
||||
setupInput(): void;
|
||||
private play();
|
||||
private pause();
|
||||
private setAnimation(animation);
|
||||
private calculateAnimationViewport(animationName);
|
||||
}
|
||||
}
|
||||
declare module spine {
|
||||
|
||||
@ -9539,6 +9539,9 @@ var spine;
|
||||
this.paused = true;
|
||||
this.playTime = 0;
|
||||
this.speed = 1;
|
||||
this.animationViewports = {};
|
||||
this.currentViewport = null;
|
||||
this.previousViewport = null;
|
||||
parent.appendChild(this.render());
|
||||
}
|
||||
SpinePlayer.prototype.validateConfig = function (config) {
|
||||
@ -9754,7 +9757,7 @@ var spine;
|
||||
row.classList.add("selected");
|
||||
_this.config.animation = animation.name;
|
||||
_this.playTime = 0;
|
||||
_this.animationState.setAnimation(0, _this.config.animation, true);
|
||||
_this.setAnimation(animation.name);
|
||||
};
|
||||
});
|
||||
animationsButton.classList.add("spine-player-button-icon-animations-selected");
|
||||
@ -9851,15 +9854,16 @@ var spine;
|
||||
this.animationState.apply(this.skeleton);
|
||||
}
|
||||
this.skeleton.updateWorldTransform();
|
||||
var viewportSize = this.scale(this.config.viewport.width, this.config.viewport.height, this.canvas.width, this.canvas.height);
|
||||
this.sceneRenderer.camera.zoom = this.config.viewport.width / viewportSize.x;
|
||||
this.sceneRenderer.camera.position.x = this.config.viewport.x + this.config.viewport.width / 2;
|
||||
this.sceneRenderer.camera.position.y = this.config.viewport.y + this.config.viewport.height / 2;
|
||||
var viewport = this.currentViewport;
|
||||
var viewportSize = this.scale(viewport.width, viewport.height, this.canvas.width, this.canvas.height);
|
||||
this.sceneRenderer.camera.zoom = viewport.width / viewportSize.x;
|
||||
this.sceneRenderer.camera.position.x = viewport.x + viewport.width / 2;
|
||||
this.sceneRenderer.camera.position.y = viewport.y + viewport.height / 2;
|
||||
this.sceneRenderer.begin();
|
||||
if (this.config.backgroundImage && this.config.backgroundImage.url) {
|
||||
var bgImage = this.assetManager.get(this.config.backgroundImage.url);
|
||||
if (!this.config.backgroundImage.x) {
|
||||
this.sceneRenderer.drawTexture(bgImage, this.config.viewport.x, this.config.viewport.y, this.config.viewport.width, this.config.viewport.height);
|
||||
this.sceneRenderer.drawTexture(bgImage, viewport.x, viewport.y, viewport.width, viewport.height);
|
||||
}
|
||||
else {
|
||||
this.sceneRenderer.drawTexture(bgImage, this.config.backgroundImage.x, this.config.backgroundImage.y, this.config.backgroundImage.width, this.config.backgroundImage.height);
|
||||
@ -9952,22 +9956,6 @@ var spine;
|
||||
this.skeleton.setSkinByName(this.config.skin);
|
||||
this.skeleton.setSlotsToSetupPose();
|
||||
}
|
||||
if (!this.config.viewport || !this.config.viewport.x || !this.config.viewport.y || !this.config.viewport.width || !this.config.viewport.height) {
|
||||
this.config.viewport = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0
|
||||
};
|
||||
this.skeleton.updateWorldTransform();
|
||||
var offset = new spine.Vector2();
|
||||
var size = new spine.Vector2();
|
||||
this.skeleton.getBounds(offset, size);
|
||||
this.config.viewport.x = offset.x + size.x / 2 - size.x / 2 * 1.2;
|
||||
this.config.viewport.y = offset.y + size.y / 2 - size.y / 2 * 1.2;
|
||||
this.config.viewport.width = size.x * 1.2;
|
||||
this.config.viewport.height = size.y * 1.2;
|
||||
}
|
||||
if (this.config.animations && this.config.animations.length > 0) {
|
||||
this.config.animations.forEach(function (animation) {
|
||||
if (!_this.skeleton.data.findAnimation(animation)) {
|
||||
@ -10000,6 +9988,18 @@ var spine;
|
||||
_this.playTime = time;
|
||||
};
|
||||
}
|
||||
if (!this.config.viewport || !this.config.viewport.x || !this.config.viewport.y || !this.config.viewport.width || !this.config.viewport.height) {
|
||||
this.config.viewport = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
padLeft: "0",
|
||||
padRight: "0",
|
||||
padTop: "0",
|
||||
padBottom: "0"
|
||||
};
|
||||
}
|
||||
this.setupInput();
|
||||
if (skeletonData.skins.length == 1)
|
||||
this.skinButton.classList.add("spine-player-hidden");
|
||||
@ -10101,7 +10101,7 @@ var spine;
|
||||
this.playButton.classList.add("spine-player-button-icon-pause");
|
||||
if (this.config.animation) {
|
||||
if (!this.animationState.getCurrent(0)) {
|
||||
this.animationState.setAnimation(0, this.config.animation, true);
|
||||
this.setAnimation(this.config.animation);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -10110,6 +10110,47 @@ var spine;
|
||||
this.playButton.classList.remove("spine-player-button-icon-pause");
|
||||
this.playButton.classList.add("spine-player-button-icon-play");
|
||||
};
|
||||
SpinePlayer.prototype.setAnimation = function (animation) {
|
||||
this.previousViewport = this.currentViewport;
|
||||
this.currentViewport = this.calculateAnimationViewport(animation);
|
||||
this.animationState.clearTracks();
|
||||
this.skeleton.setToSetupPose();
|
||||
this.animationState.setAnimation(0, this.config.animation, true);
|
||||
};
|
||||
SpinePlayer.prototype.calculateAnimationViewport = function (animationName) {
|
||||
var animation = this.skeleton.data.findAnimation(animationName);
|
||||
this.animationState.clearTracks();
|
||||
this.skeleton.setToSetupPose();
|
||||
this.animationState.setAnimationWith(0, animation, true);
|
||||
var steps = 100;
|
||||
var stepTime = animation.duration > 0 ? animation.duration / steps : 0;
|
||||
var minX = 100000000;
|
||||
var maxX = -100000000;
|
||||
var minY = 100000000;
|
||||
var maxY = -100000000;
|
||||
var offset = new spine.Vector2();
|
||||
var size = new spine.Vector2();
|
||||
for (var i = 0; i < steps; i++) {
|
||||
this.animationState.update(stepTime);
|
||||
this.animationState.apply(this.skeleton);
|
||||
this.skeleton.updateWorldTransform();
|
||||
this.skeleton.getBounds(offset, size);
|
||||
minX = Math.min(offset.x, minX);
|
||||
maxX = Math.max(offset.x + size.x, maxX);
|
||||
minY = Math.min(offset.y, minY);
|
||||
maxY = Math.max(offset.y + size.y, maxY);
|
||||
}
|
||||
offset.x = minX;
|
||||
offset.y = minY;
|
||||
size.x = maxX - minX;
|
||||
size.y = maxY - minY;
|
||||
return {
|
||||
x: offset.x + size.x / 2 - size.x / 2 * 1.2,
|
||||
y: offset.y + size.y / 2 - size.y / 2 * 1.2,
|
||||
width: size.x * 1.2,
|
||||
height: size.y * 1.2
|
||||
};
|
||||
};
|
||||
SpinePlayer.HOVER_COLOR_INNER = new spine.Color(0.478, 0, 0, 0.25);
|
||||
SpinePlayer.HOVER_COLOR_OUTER = new spine.Color(1, 1, 1, 1);
|
||||
SpinePlayer.NON_HOVER_COLOR_INNER = new spine.Color(0.478, 0, 0, 0.5);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -75,6 +75,10 @@
|
||||
y: number
|
||||
width: number
|
||||
height: number
|
||||
padLeft: string
|
||||
padRight: string
|
||||
padTop: string
|
||||
padBottom: string
|
||||
}
|
||||
|
||||
/* Optional: whether the canvas should be transparent. Default: false. */
|
||||
@ -256,6 +260,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
interface Viewport {
|
||||
x: number
|
||||
y: number
|
||||
width: number
|
||||
height: number
|
||||
}
|
||||
|
||||
export class SpinePlayer {
|
||||
static HOVER_COLOR_INNER = new spine.Color(0.478, 0, 0, 0.25);
|
||||
static HOVER_COLOR_OUTER = new spine.Color(1, 1, 1, 1);
|
||||
@ -283,6 +294,10 @@
|
||||
private playTime = 0;
|
||||
private speed = 1;
|
||||
|
||||
private animationViewports: Map<Viewport> = {}
|
||||
private currentViewport: Viewport = null;
|
||||
private previousViewport: Viewport = null;
|
||||
|
||||
private selectedBones: Bone[];
|
||||
|
||||
constructor(parent: HTMLElement, private config: SpinePlayerConfig) {
|
||||
@ -544,7 +559,7 @@
|
||||
row.classList.add("selected");
|
||||
this.config.animation = animation.name;
|
||||
this.playTime = 0;
|
||||
this.animationState.setAnimation(0, this.config.animation, true);
|
||||
this.setAnimation(animation.name);
|
||||
}
|
||||
});
|
||||
animationsButton.classList.add("spine-player-button-icon-animations-selected")
|
||||
@ -675,11 +690,12 @@
|
||||
|
||||
this.skeleton.updateWorldTransform();
|
||||
|
||||
let viewportSize = this.scale(this.config.viewport.width, this.config.viewport.height, this.canvas.width, this.canvas.height);
|
||||
let viewport = this.currentViewport;
|
||||
let viewportSize = this.scale(viewport.width, viewport.height, this.canvas.width, this.canvas.height);
|
||||
|
||||
this.sceneRenderer.camera.zoom = this.config.viewport.width / viewportSize.x;
|
||||
this.sceneRenderer.camera.position.x = this.config.viewport.x + this.config.viewport.width / 2;
|
||||
this.sceneRenderer.camera.position.y = this.config.viewport.y + this.config.viewport.height / 2;
|
||||
this.sceneRenderer.camera.zoom = viewport.width / viewportSize.x;
|
||||
this.sceneRenderer.camera.position.x = viewport.x + viewport.width / 2;
|
||||
this.sceneRenderer.camera.position.y = viewport.y + viewport.height / 2;
|
||||
|
||||
this.sceneRenderer.begin();
|
||||
|
||||
@ -687,7 +703,7 @@
|
||||
if (this.config.backgroundImage && this.config.backgroundImage.url) {
|
||||
let bgImage = this.assetManager.get(this.config.backgroundImage.url);
|
||||
if (!this.config.backgroundImage.x) {
|
||||
this.sceneRenderer.drawTexture(bgImage, this.config.viewport.x, this.config.viewport.y, this.config.viewport.width, this.config.viewport.height);
|
||||
this.sceneRenderer.drawTexture(bgImage, viewport.x, viewport.y, viewport.width, viewport.height);
|
||||
} else {
|
||||
this.sceneRenderer.drawTexture(bgImage, this.config.backgroundImage.x, this.config.backgroundImage.y, this.config.backgroundImage.width, this.config.backgroundImage.height);
|
||||
}
|
||||
@ -792,25 +808,6 @@
|
||||
this.skeleton.setSlotsToSetupPose();
|
||||
}
|
||||
|
||||
// Setup viewport after skin is set
|
||||
if (!this.config.viewport || !this.config.viewport.x || !this.config.viewport.y || !this.config.viewport.width || !this.config.viewport.height) {
|
||||
this.config.viewport = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0
|
||||
}
|
||||
|
||||
this.skeleton.updateWorldTransform();
|
||||
let offset = new spine.Vector2();
|
||||
let size = new spine.Vector2();
|
||||
this.skeleton.getBounds(offset, size);
|
||||
this.config.viewport.x = offset.x + size.x / 2 - size.x / 2 * 1.2;
|
||||
this.config.viewport.y = offset.y + size.y / 2 - size.y / 2 * 1.2;
|
||||
this.config.viewport.width = size.x * 1.2;
|
||||
this.config.viewport.height = size.y * 1.2;
|
||||
}
|
||||
|
||||
// Setup the animations after viewport, so default bounds don't get messed up.
|
||||
if (this.config.animations && this.config.animations.length > 0) {
|
||||
this.config.animations.forEach(animation => {
|
||||
@ -848,6 +845,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Setup viewport after skin is set
|
||||
if (!this.config.viewport || !this.config.viewport.x || !this.config.viewport.y || !this.config.viewport.width || !this.config.viewport.height) {
|
||||
this.config.viewport = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
padLeft: "0",
|
||||
padRight: "0",
|
||||
padTop: "0",
|
||||
padBottom: "0"
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the input processor and controllable bones
|
||||
this.setupInput();
|
||||
|
||||
@ -955,7 +966,7 @@
|
||||
|
||||
if (this.config.animation) {
|
||||
if (!this.animationState.getCurrent(0)) {
|
||||
this.animationState.setAnimation(0, this.config.animation, true);
|
||||
this.setAnimation(this.config.animation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -965,6 +976,54 @@
|
||||
this.playButton.classList.remove("spine-player-button-icon-pause");
|
||||
this.playButton.classList.add("spine-player-button-icon-play");
|
||||
}
|
||||
|
||||
private setAnimation (animation: string) {
|
||||
this.previousViewport = this.currentViewport;
|
||||
this.currentViewport = this.calculateAnimationViewport(animation);
|
||||
this.animationState.clearTracks();
|
||||
this.skeleton.setToSetupPose();
|
||||
this.animationState.setAnimation(0, this.config.animation, true);
|
||||
}
|
||||
|
||||
private calculateAnimationViewport (animationName: string): Viewport {
|
||||
let animation = this.skeleton.data.findAnimation(animationName);
|
||||
this.animationState.clearTracks();
|
||||
this.skeleton.setToSetupPose()
|
||||
this.animationState.setAnimationWith(0, animation, true);
|
||||
|
||||
let steps = 100;
|
||||
let stepTime = animation.duration > 0 ? animation.duration / steps : 0;
|
||||
let minX = 100000000;
|
||||
let maxX = -100000000;
|
||||
let minY = 100000000;
|
||||
let maxY = -100000000;
|
||||
let offset = new spine.Vector2();
|
||||
let size = new spine.Vector2();
|
||||
|
||||
for (var i = 0; i < steps; i++) {
|
||||
this.animationState.update(stepTime);
|
||||
this.animationState.apply(this.skeleton);
|
||||
this.skeleton.updateWorldTransform();
|
||||
this.skeleton.getBounds(offset, size);
|
||||
|
||||
minX = Math.min(offset.x, minX);
|
||||
maxX = Math.max(offset.x + size.x, maxX);
|
||||
minY = Math.min(offset.y, minY);
|
||||
maxY = Math.max(offset.y + size.y, maxY);
|
||||
}
|
||||
|
||||
offset.x = minX;
|
||||
offset.y = minY;
|
||||
size.x = maxX - minX;
|
||||
size.y = maxY - minY;
|
||||
|
||||
return {
|
||||
x: offset.x + size.x / 2 - size.x / 2 * 1.2,
|
||||
y: offset.y + size.y / 2 - size.y / 2 * 1.2,
|
||||
width: size.x * 1.2,
|
||||
height: size.y * 1.2
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function isContained(dom: HTMLElement, needle: HTMLElement): boolean {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user