mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-11 01:28:44 +08:00
General refactor. spine-widget to spine-skeleton.
This commit is contained in:
parent
70cc7e45ca
commit
0abcaff7fe
@ -201,7 +201,7 @@
|
||||
<!-- SECTION 1 -->
|
||||
<div class="screen">
|
||||
<div class="top-section">
|
||||
<spine-widget
|
||||
<spine-skeleton
|
||||
identifier="list"
|
||||
|
||||
overlay-id="phone"
|
||||
@ -212,7 +212,7 @@
|
||||
|
||||
isinteractive
|
||||
|
||||
></spine-widget>
|
||||
></spine-skeleton>
|
||||
</div>
|
||||
|
||||
<div class="bottom-section">
|
||||
@ -268,7 +268,7 @@
|
||||
<div class="screen">
|
||||
<div class="top-section">
|
||||
|
||||
<spine-widget
|
||||
<spine-skeleton
|
||||
identifier="pan"
|
||||
|
||||
overlay-id="phone"
|
||||
@ -277,7 +277,7 @@
|
||||
skeleton="assets/food/pan-cooking-pro.json"
|
||||
animation="animation"
|
||||
|
||||
></spine-widget>
|
||||
></spine-skeleton>
|
||||
|
||||
</div>
|
||||
|
||||
@ -333,7 +333,7 @@
|
||||
<div class="screen">
|
||||
<div class="top-section">
|
||||
|
||||
<spine-widget
|
||||
<spine-skeleton
|
||||
identifier="delivery"
|
||||
|
||||
overlay-id="phone"
|
||||
@ -342,7 +342,7 @@
|
||||
skeleton="assets/food/meal-delivery-pro.json"
|
||||
animation="animation"
|
||||
|
||||
></spine-widget>
|
||||
></spine-skeleton>
|
||||
|
||||
</div>
|
||||
|
||||
@ -372,7 +372,7 @@
|
||||
<div class="screen">
|
||||
<div class="top-section">
|
||||
|
||||
<spine-widget
|
||||
<spine-skeleton
|
||||
identifier="ready"
|
||||
|
||||
overlay-id="phone"
|
||||
@ -382,7 +382,7 @@
|
||||
animation="base"
|
||||
|
||||
isinteractive
|
||||
></spine-widget>
|
||||
></spine-skeleton>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@ -37,20 +37,20 @@
|
||||
</div>
|
||||
|
||||
<div class="bottom" style="flex: 80%; background-color: rgb(24, 149, 89); display: flex; align-items: center; justify-content: center;">
|
||||
<spine-widget
|
||||
<spine-skeleton
|
||||
identifier="windmill-game"
|
||||
atlas="assets/windmill-ess.atlas"
|
||||
skeleton="assets/windmill-ess.json"
|
||||
animation="animation"
|
||||
isinteractive
|
||||
></spine-widget>
|
||||
<spine-widget
|
||||
></spine-skeleton>
|
||||
<spine-skeleton
|
||||
identifier="spineboy-game"
|
||||
atlas="assets/spineboy-pma.atlas"
|
||||
skeleton="assets/spineboy-pro.json"
|
||||
animation="hoverboard"
|
||||
fit="none"
|
||||
></spine-widget>
|
||||
></spine-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -41,13 +41,13 @@
|
||||
|
||||
<div class="container">
|
||||
<div class="left-column">
|
||||
<spine-widget
|
||||
<spine-skeleton
|
||||
identifier="boi"
|
||||
atlas="assets/spineboy-pma.atlas"
|
||||
skeleton="assets/spineboy-pro.skel"
|
||||
auto-calculate-bounds
|
||||
debug
|
||||
></spine-widget>
|
||||
></spine-skeleton>
|
||||
</div>
|
||||
<div class="right-column">
|
||||
<div id="lil"></div>
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
<div style="background-color: white; width: 250px; padding: 30px; text-align: center; border-radius: 10px; border: 3px solid black; box-shadow: 5px 5px rgb(0, 0, 0);">
|
||||
<div style="display: flex; justify-content: center;">
|
||||
<div style="width: 150px; height:150px; border-radius: 5%; border: 1px solid rgb(113, 113, 113); background-color: rgb(211, 211, 211); margin-bottom: 30px;">
|
||||
<spine-widget
|
||||
<spine-skeleton
|
||||
identifier="spineboy-login"
|
||||
atlas="assets/pwd/chibi-stickers-pro-pwd-test.atlas"
|
||||
skeleton="assets/pwd/chibi-stickers.json"
|
||||
@ -33,7 +33,7 @@
|
||||
animation="interactive/head/idle"
|
||||
clip
|
||||
isinteractive
|
||||
></spine-widget>
|
||||
></spine-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -51,14 +51,14 @@
|
||||
|
||||
<div style="height: 75px; cursor: pointer;">
|
||||
<div id="button-text" style="font-size: xx-large; cursor: pointer; user-select: none; display: none;"> LOGIN </div>
|
||||
<spine-widget
|
||||
<spine-skeleton
|
||||
identifier="button-login"
|
||||
atlas="assets/pwd/button.atlas"
|
||||
skeleton="assets/pwd/button.json"
|
||||
animation="idle"
|
||||
isinteractive
|
||||
fit="fill"
|
||||
></spine-widget>
|
||||
></spine-skeleton>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1023
spine-ts/spine-widget/src/SpineWebComponentOverlay.ts
Normal file
1023
spine-ts/spine-widget/src/SpineWebComponentOverlay.ts
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,4 @@
|
||||
export * from './SpineWebComponentWidget.js';
|
||||
export * from './SpineWebComponentSkeleton.js';
|
||||
export * from './SpineWebComponentOverlay.js';
|
||||
export * from "@esotericsoftware/spine-core";
|
||||
export * from "@esotericsoftware/spine-webgl";
|
||||
export * from "@esotericsoftware/spine-webgl";
|
||||
|
||||
189
spine-ts/spine-widget/src/wcUtils.ts
Normal file
189
spine-ts/spine-widget/src/wcUtils.ts
Normal file
@ -0,0 +1,189 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated July 28, 2023. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2023, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software or
|
||||
* otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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 THE
|
||||
* SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
import { AnimationsInfo, FitType, ModeType, OffScreenUpdateBehaviourType } from "./SpineWebComponentSkeleton";
|
||||
|
||||
const animatonTypeRegExp = /\[([^\]]+)\]/g;
|
||||
export type AttributeTypes = "string" | "number" | "boolean" | "array-number" | "array-string" | "object" | "fitType" | "modeType" | "offScreenUpdateBehaviourType" | "animationsInfo";
|
||||
|
||||
export function castValue (type: AttributeTypes, value: string | null, defaultValue?: any) {
|
||||
switch (type) {
|
||||
case "string":
|
||||
return castString(value, defaultValue);
|
||||
case "number":
|
||||
return castNumber(value, defaultValue);
|
||||
case "boolean":
|
||||
return castBoolean(value, defaultValue);
|
||||
case "array-number":
|
||||
return castArrayNumber(value, defaultValue);
|
||||
case "array-string":
|
||||
return castArrayString(value, defaultValue);
|
||||
case "object":
|
||||
return castObject(value, defaultValue);
|
||||
case "fitType":
|
||||
return isFitType(value) ? value : defaultValue;
|
||||
case "modeType":
|
||||
return isModeType(value) ? value : defaultValue;
|
||||
case "offScreenUpdateBehaviourType":
|
||||
return isOffScreenUpdateBehaviourType(value) ? value : defaultValue;
|
||||
case "animationsInfo":
|
||||
return castToAnimationsInfo(value) || defaultValue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function castBoolean (value: string | null, defaultValue = "") {
|
||||
return value === "true" || value === "" ? true : false;
|
||||
}
|
||||
|
||||
function castString (value: string | null, defaultValue = "") {
|
||||
return value === null ? defaultValue : value;
|
||||
}
|
||||
|
||||
function castNumber (value: string | null, defaultValue = 0) {
|
||||
if (value === null) return defaultValue;
|
||||
|
||||
const parsed = parseFloat(value);
|
||||
if (Number.isNaN(parsed)) return defaultValue;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
function castArrayNumber (value: string | null, defaultValue = undefined) {
|
||||
if (value === null) return defaultValue;
|
||||
return value.split(",").reduce((acc, pageIndex) => {
|
||||
const index = parseInt(pageIndex);
|
||||
if (!isNaN(index)) acc.push(index);
|
||||
return acc;
|
||||
}, [] as Array<number>);
|
||||
}
|
||||
|
||||
function castArrayString (value: string | null, defaultValue = undefined) {
|
||||
if (value === null) return defaultValue;
|
||||
return value.split(",");
|
||||
}
|
||||
|
||||
function castObject (value: string | null, defaultValue = undefined) {
|
||||
if (value === null) return null;
|
||||
return JSON.parse(value);
|
||||
}
|
||||
|
||||
|
||||
function castToAnimationsInfo (value: string | null): AnimationsInfo | undefined {
|
||||
if (value === null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const matches = value.match(animatonTypeRegExp);
|
||||
if (!matches) return undefined;
|
||||
|
||||
return matches.reduce((obj, group) => {
|
||||
const [trackIndexStringOrLoopDefinition, animationNameOrTrackIndexStringCycle, loop, delayString, mixDurationString] = group.slice(1, -1).split(',').map(v => v.trim());
|
||||
|
||||
if (trackIndexStringOrLoopDefinition === "loop") {
|
||||
if (!Number.isInteger(Number(animationNameOrTrackIndexStringCycle))) {
|
||||
throw new Error(`Track index of cycle in ${group} must be a positive integer number, instead it is ${animationNameOrTrackIndexStringCycle}. Original value: ${value}`);
|
||||
}
|
||||
const animationInfoObject = obj[animationNameOrTrackIndexStringCycle] ||= { animations: [] };
|
||||
animationInfoObject.cycle = true;
|
||||
return obj;
|
||||
}
|
||||
|
||||
const trackIndex = Number(trackIndexStringOrLoopDefinition);
|
||||
if (!Number.isInteger(trackIndex)) {
|
||||
throw new Error(`Track index in ${group} must be a positive integer number, instead it is ${trackIndexStringOrLoopDefinition}. Original value: ${value}`);
|
||||
}
|
||||
|
||||
let delay;
|
||||
if (delayString !== undefined) {
|
||||
delay = parseFloat(delayString);
|
||||
if (isNaN(delay)) {
|
||||
throw new Error(`Delay in ${group} must be a positive number, instead it is ${delayString}. Original value: ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
let mixDuration;
|
||||
if (mixDurationString !== undefined) {
|
||||
mixDuration = parseFloat(mixDurationString);
|
||||
if (isNaN(mixDuration)) {
|
||||
throw new Error(`mixDuration in ${group} must be a positive number, instead it is ${mixDurationString}. Original value: ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
const animationInfoObject = obj[trackIndexStringOrLoopDefinition] ||= { animations: [] };
|
||||
animationInfoObject.animations.push({
|
||||
animationName: animationNameOrTrackIndexStringCycle,
|
||||
loop: loop.trim().toLowerCase() === "true",
|
||||
delay,
|
||||
mixDuration,
|
||||
});
|
||||
return obj;
|
||||
}, {} as AnimationsInfo);
|
||||
}
|
||||
|
||||
function isFitType (value: string | null): value is FitType {
|
||||
return (
|
||||
value === "fill" ||
|
||||
value === "width" ||
|
||||
value === "height" ||
|
||||
value === "contain" ||
|
||||
value === "cover" ||
|
||||
value === "none" ||
|
||||
value === "scaleDown"
|
||||
);
|
||||
}
|
||||
|
||||
function isOffScreenUpdateBehaviourType (value: string | null): value is OffScreenUpdateBehaviourType {
|
||||
return (
|
||||
value === "pause" ||
|
||||
value === "update" ||
|
||||
value === "pose"
|
||||
);
|
||||
}
|
||||
|
||||
function isModeType (value: string | null): value is ModeType {
|
||||
return (
|
||||
value === "inside" ||
|
||||
value === "origin"
|
||||
);
|
||||
}
|
||||
const base64RegExp = /^(([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==))$/;
|
||||
export function isBase64 (str: string) {
|
||||
return base64RegExp.test(str);
|
||||
}
|
||||
|
||||
export interface Point {
|
||||
x: number,
|
||||
y: number,
|
||||
}
|
||||
|
||||
export interface Rectangle extends Point {
|
||||
width: number,
|
||||
height: number,
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user