mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-25 22:23:42 +08:00
[ts][player] Added viewport.clip and ResizeMode.FitClip.
This commit is contained in:
parent
9710b0f08b
commit
9424018102
@ -103,6 +103,9 @@ export interface SpinePlayerConfig {
|
||||
width?: number
|
||||
height?: number
|
||||
|
||||
/* Optional: When true, drawing won't go outside the viewport. Default: false */
|
||||
clip?: boolean
|
||||
|
||||
/* Optional: Padding around the viewport size, given as a number or percentage (eg "25%"). Default: 10% */
|
||||
padLeft?: string | number
|
||||
padRight?: string | number
|
||||
@ -736,6 +739,7 @@ export class SpinePlayer implements Disposable {
|
||||
// Determine the base viewport.
|
||||
let globalViewport = this.config.viewport!;
|
||||
let viewport = this.currentViewport = {
|
||||
clip: globalViewport.clip,
|
||||
padLeft: globalViewport.padLeft !== void 0 ? globalViewport.padLeft : "10%",
|
||||
padRight: globalViewport.padRight !== void 0 ? globalViewport.padRight : "10%",
|
||||
padTop: globalViewport.padTop !== void 0 ? globalViewport.padTop : "10%",
|
||||
@ -758,6 +762,7 @@ export class SpinePlayer implements Disposable {
|
||||
viewport.width = userAnimViewport.width;
|
||||
viewport.height = userAnimViewport.height;
|
||||
}
|
||||
if (userAnimViewport.clip !== void 0) viewport.clip = userAnimViewport.clip;
|
||||
if (userAnimViewport.padLeft !== void 0) viewport.padLeft = userAnimViewport.padLeft;
|
||||
if (userAnimViewport.padRight !== void 0) viewport.padRight = userAnimViewport.padRight;
|
||||
if (userAnimViewport.padTop !== void 0) viewport.padTop = userAnimViewport.padTop;
|
||||
@ -827,10 +832,6 @@ export class SpinePlayer implements Disposable {
|
||||
let skeleton = this.skeleton!;
|
||||
let config = this.config!;
|
||||
if (skeleton) {
|
||||
// Resize the canvas.
|
||||
let renderer = this.sceneRenderer!;
|
||||
renderer.resize(ResizeMode.Expand);
|
||||
|
||||
let playDelta = this.paused ? 0 : delta * this.speed;
|
||||
if (config.frame) config.frame(this, playDelta);
|
||||
|
||||
@ -878,11 +879,15 @@ export class SpinePlayer implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
let renderer = this.sceneRenderer!;
|
||||
renderer.camera.zoom = this.canvas!.height / this.canvas!.width > viewport.height / viewport.width
|
||||
? viewport.width / this.canvas!.width : viewport.height / this.canvas!.height;
|
||||
renderer.camera.position.x = viewport.x + viewport.width / 2;
|
||||
renderer.camera.position.y = viewport.y + viewport.height / 2;
|
||||
|
||||
// Resize the canvas.
|
||||
renderer.resize(this.currentViewport.clip ? ResizeMode.FitClip : ResizeMode.Fit, viewport.width, viewport.height);
|
||||
|
||||
// Clear the screen.
|
||||
let gl = this.context!.gl;
|
||||
gl.clearColor(bg.r, bg.g, bg.b, bg.a);
|
||||
|
||||
@ -463,28 +463,34 @@ export class SceneRenderer implements Disposable {
|
||||
this.activeRenderer = null;
|
||||
}
|
||||
|
||||
resize (resizeMode: ResizeMode) {
|
||||
resize (resizeMode: ResizeMode, worldWidth?: number, worldHeight?: number) {
|
||||
let canvas = this.canvas;
|
||||
var dpr = window.devicePixelRatio || 1;
|
||||
var w = Math.round(canvas.clientWidth * dpr);
|
||||
var h = Math.round(canvas.clientHeight * dpr);
|
||||
|
||||
if (canvas.width != w || canvas.height != h) {
|
||||
canvas.width = w;
|
||||
canvas.height = h;
|
||||
}
|
||||
this.context.gl.viewport(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// Nothing to do for stretch, we simply apply the viewport size of the camera.
|
||||
if (resizeMode === ResizeMode.Expand)
|
||||
this.camera.setViewport(w, h);
|
||||
else if (resizeMode === ResizeMode.Fit) {
|
||||
let sourceWidth = canvas.width, sourceHeight = canvas.height;
|
||||
let targetWidth = this.camera.viewportWidth, targetHeight = this.camera.viewportHeight;
|
||||
let targetRatio = targetHeight / targetWidth;
|
||||
let sourceRatio = sourceHeight / sourceWidth;
|
||||
let scale = targetRatio < sourceRatio ? targetWidth / sourceWidth : targetHeight / sourceHeight;
|
||||
this.camera.setViewport(sourceWidth * scale, sourceHeight * scale);
|
||||
if (resizeMode === ResizeMode.FitClip) {
|
||||
let targetRatio = h / w, sourceRatio = worldHeight / worldWidth;
|
||||
let scale = targetRatio > sourceRatio ? w / worldWidth : h / worldHeight;
|
||||
worldWidth *= scale;
|
||||
worldHeight *= scale;
|
||||
this.camera.setViewport(worldWidth, worldHeight);
|
||||
this.context.gl.viewport((w - worldWidth) / 2, (h - worldHeight) / 2, worldWidth, worldHeight);
|
||||
} else {
|
||||
if (resizeMode === ResizeMode.Fit) {
|
||||
let targetWidth = this.camera.viewportWidth, targetHeight = this.camera.viewportHeight;
|
||||
let targetRatio = targetHeight / targetWidth, sourceRatio = h / w;
|
||||
let scale = targetRatio < sourceRatio ? targetWidth / w : targetHeight / h;
|
||||
this.camera.setViewport(w * scale, h * scale);
|
||||
} else if (resizeMode === ResizeMode.Expand)
|
||||
this.camera.setViewport(w, h);
|
||||
// Nothing to do for stretch, we simply apply the viewport size of the camera.
|
||||
|
||||
this.context.gl.viewport(0, 0, w, h);
|
||||
}
|
||||
this.camera.update();
|
||||
}
|
||||
@ -511,5 +517,6 @@ export class SceneRenderer implements Disposable {
|
||||
export enum ResizeMode {
|
||||
Stretch,
|
||||
Expand,
|
||||
Fit
|
||||
Fit,
|
||||
FitClip,
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user