mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
Add rawData attribute to pass s stringified JSON object for inline base64 assets.
This commit is contained in:
parent
23ece7f4da
commit
c4d419caf9
@ -411,18 +411,21 @@ export class Downloader {
|
|||||||
|
|
||||||
downloadText (url: string, success: (data: string) => void, error: (status: number, responseText: string) => void) {
|
downloadText (url: string, success: (data: string) => void, error: (status: number, responseText: string) => void) {
|
||||||
if (this.start(url, success, error)) return;
|
if (this.start(url, success, error)) return;
|
||||||
if (this.rawDataUris[url]) {
|
|
||||||
|
const rawDataUri = this.rawDataUris[url];
|
||||||
|
// we assume if a "." is included in a raw data uri, it is used to rewrite an asset URL
|
||||||
|
if (rawDataUri && !rawDataUri.includes(".")) {
|
||||||
try {
|
try {
|
||||||
let dataUri = this.rawDataUris[url];
|
this.finish(url, 200, this.dataUriToString(rawDataUri));
|
||||||
this.finish(url, 200, this.dataUriToString(dataUri));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.finish(url, 400, JSON.stringify(e));
|
this.finish(url, 400, JSON.stringify(e));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let request = new XMLHttpRequest();
|
let request = new XMLHttpRequest();
|
||||||
request.overrideMimeType("text/html");
|
request.overrideMimeType("text/html");
|
||||||
request.open("GET", url, true);
|
request.open("GET", rawDataUri ? rawDataUri : url, true);
|
||||||
let done = () => {
|
let done = () => {
|
||||||
this.finish(url, request.status, request.responseText);
|
this.finish(url, request.status, request.responseText);
|
||||||
};
|
};
|
||||||
@ -439,17 +442,20 @@ export class Downloader {
|
|||||||
|
|
||||||
downloadBinary (url: string, success: (data: Uint8Array) => void, error: (status: number, responseText: string) => void) {
|
downloadBinary (url: string, success: (data: Uint8Array) => void, error: (status: number, responseText: string) => void) {
|
||||||
if (this.start(url, success, error)) return;
|
if (this.start(url, success, error)) return;
|
||||||
if (this.rawDataUris[url]) {
|
|
||||||
|
const rawDataUri = this.rawDataUris[url];
|
||||||
|
// we assume if a "." is included in a raw data uri, it is used to rewrite an asset URL
|
||||||
|
if (rawDataUri && !rawDataUri.includes(".")) {
|
||||||
try {
|
try {
|
||||||
let dataUri = this.rawDataUris[url];
|
this.finish(url, 200, this.dataUriToUint8Array(rawDataUri));
|
||||||
this.finish(url, 200, this.dataUriToUint8Array(dataUri));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.finish(url, 400, JSON.stringify(e));
|
this.finish(url, 400, JSON.stringify(e));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let request = new XMLHttpRequest();
|
let request = new XMLHttpRequest();
|
||||||
request.open("GET", url, true);
|
request.open("GET", rawDataUri ? rawDataUri : url, true);
|
||||||
request.responseType = "arraybuffer";
|
request.responseType = "arraybuffer";
|
||||||
let onerror = () => {
|
let onerror = () => {
|
||||||
this.finish(url, request.status, request.response);
|
this.finish(url, request.status, request.response);
|
||||||
|
|||||||
@ -1021,7 +1021,56 @@
|
|||||||
/////////////////////
|
/////////////////////
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
/////////////////////
|
||||||
|
// start section //
|
||||||
|
/////////////////////
|
||||||
|
-->
|
||||||
|
|
||||||
|
<div class="section vertical-split">
|
||||||
|
|
||||||
|
<div class="split-top split">
|
||||||
|
<div class="split-left">
|
||||||
|
If you want to embed your assets within the page, you can inline them using their base64 version. Use a stringified json object containing as keys the assets name and as values their base64 version.
|
||||||
|
</div>
|
||||||
|
<div class="split-right">
|
||||||
|
<spine-widget
|
||||||
|
atlas="inline.atlas"
|
||||||
|
skeleton="inline.skel"
|
||||||
|
animation="animation"
|
||||||
|
raw-data='{
|
||||||
|
"inline.atlas":"aW5saW5lLnBuZwpzaXplOjE2LDE2CmZpbHRlcjpMaW5lYXIsTGluZWFyCnBtYTp0cnVlCmRvdApib3VuZHM6MCwwLDEsMQo=",
|
||||||
|
"inline.skel":"/B8S/IqaXgYHNC4yLjM5wkgAAMJIAABCyAAAQsgAAELIAAAAAQRkb3QCBXJvb3QAAAAAAAAAAAAAAAA/gAAAP4AAAAAAAAAAAAAAAAAAAAAABGRvdAAAAAAAAAAAAAAAAABCyAAAQsgAAAAAAAAAAAAAAAAAAAAAAQRkb3QB//////////8BAAAAAAABAAEBACWwfdcAAAAAP4AAAD+AAAA/gAAAP4AAAAAAAQphbmltYXRpb24BAQABAQMAAAAAAP////8/gAAA/wAA/wBAAAAA/////wAAAAAAAAAAAA==",
|
||||||
|
"inline.png":"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAANQTFRF////p8QbyAAAAApJREFUeJxjZAAAAAQAAiFkrWoAAAAASUVORK5CYII="
|
||||||
|
}'
|
||||||
|
></spine-widget>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="split-bottom">
|
||||||
|
<pre><code id="code-display">
|
||||||
|
<script>escapeHTMLandInject(`
|
||||||
|
<spine-widget
|
||||||
|
atlas="assets/inline.atlas"
|
||||||
|
skeleton="assets/inline.skel"
|
||||||
|
animation="animation"
|
||||||
|
raw-data='{
|
||||||
|
"assets/inline.atlas":"aW5saW5lLnBuZwpzaXplOjE2LDE2CmZpbHRlcjpMaW5lYXIsTGluZWFyCnBtYTp0cnVlCmRvdApib3VuZHM6MCwwLDEsMQo=",
|
||||||
|
"assets/inline.skel":"/B8S/IqaXgYHNC4yLjM5wkgAAMJIAABCyAAAQsgAAELIAAAAAQRkb3QCBXJvb3QAAAAAAAAAAAAAAAA/gAAAP4AAAAAAAAAAAAAAAAAAAAAABGRvdAAAAAAAAAAAAAAAAABCyAAAQsgAAAAAAAAAAAAAAAAAAAAAAQRkb3QB//////////8BAAAAAAABAAEBACWwfdcAAAAAP4AAAD+AAAA/gAAAP4AAAAAAAQphbmltYXRpb24BAQABAQMAAAAAAP////8/gAAA/wAA/wBAAAAA/////wAAAAAAAAAAAA==",
|
||||||
|
"assets/inline.png":"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAANQTFRF////p8QbyAAAAApJREFUeJxjZAAAAAQAAiFkrWoAAAAASUVORK5CYII="
|
||||||
|
}'
|
||||||
|
></spine-widget>`
|
||||||
|
);</script>
|
||||||
|
</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
/////////////////////
|
||||||
|
// end section //
|
||||||
|
/////////////////////
|
||||||
|
-->
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
/////////////////////
|
/////////////////////
|
||||||
|
|||||||
@ -158,7 +158,7 @@ function castToAnimationsInfo (value: string | null): AnimationsInfo | undefined
|
|||||||
}, {} as AnimationsInfo);
|
}, {} as AnimationsInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AttributeTypes = "string" | "number" | "boolean" | "array-number" | "array-string" | "fitType" | "modeType" | "offScreenUpdateBehaviourType" | "animationsInfo";
|
export type AttributeTypes = "string" | "number" | "boolean" | "array-number" | "array-string" | "object" | "fitType" | "modeType" | "offScreenUpdateBehaviourType" | "animationsInfo";
|
||||||
|
|
||||||
export type CursorEventTypes = "down" | "up" | "enter" | "leave" | "move" | "drag";
|
export type CursorEventTypes = "down" | "up" | "enter" | "leave" | "move" | "drag";
|
||||||
export type CursorEventTypesInput = Exclude<CursorEventTypes, "enter" | "leave">;
|
export type CursorEventTypesInput = Exclude<CursorEventTypes, "enter" | "leave">;
|
||||||
@ -167,6 +167,7 @@ export type CursorEventTypesInput = Exclude<CursorEventTypes, "enter" | "leave">
|
|||||||
interface WidgetAttributes {
|
interface WidgetAttributes {
|
||||||
atlasPath?: string
|
atlasPath?: string
|
||||||
skeletonPath?: string
|
skeletonPath?: string
|
||||||
|
rawData?: Record<string, string>
|
||||||
jsonSkeletonKey?: string
|
jsonSkeletonKey?: string
|
||||||
scale: number
|
scale: number
|
||||||
animation?: string
|
animation?: string
|
||||||
@ -268,6 +269,12 @@ export class SpineWebComponentWidget extends HTMLElement implements Disposable,
|
|||||||
*/
|
*/
|
||||||
public skeletonPath?: string;
|
public skeletonPath?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds the assets in base64 format.
|
||||||
|
* Connected to `raw-data` attribute.
|
||||||
|
*/
|
||||||
|
public rawData?: Record<string ,string>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the skeleton when the skeleton file is a JSON and contains multiple skeletons.
|
* The name of the skeleton when the skeleton file is a JSON and contains multiple skeletons.
|
||||||
* Connected to `json-skeleton-key` attribute.
|
* Connected to `json-skeleton-key` attribute.
|
||||||
@ -763,6 +770,7 @@ export class SpineWebComponentWidget extends HTMLElement implements Disposable,
|
|||||||
static attributesDescription: Record<string, { propertyName: keyof WidgetAttributes, type: AttributeTypes, defaultValue?: any }> = {
|
static attributesDescription: Record<string, { propertyName: keyof WidgetAttributes, type: AttributeTypes, defaultValue?: any }> = {
|
||||||
atlas: { propertyName: "atlasPath", type: "string" },
|
atlas: { propertyName: "atlasPath", type: "string" },
|
||||||
skeleton: { propertyName: "skeletonPath", type: "string" },
|
skeleton: { propertyName: "skeletonPath", type: "string" },
|
||||||
|
"raw-data": { propertyName: "rawData", type: "object" },
|
||||||
"json-skeleton-key": { propertyName: "jsonSkeletonKey", type: "string" },
|
"json-skeleton-key": { propertyName: "jsonSkeletonKey", type: "string" },
|
||||||
scale: { propertyName: "scale", type: "number" },
|
scale: { propertyName: "scale", type: "number" },
|
||||||
animation: { propertyName: "animation", type: "string", defaultValue: undefined },
|
animation: { propertyName: "animation", type: "string", defaultValue: undefined },
|
||||||
@ -972,12 +980,18 @@ export class SpineWebComponentWidget extends HTMLElement implements Disposable,
|
|||||||
private async loadSkeleton () {
|
private async loadSkeleton () {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
||||||
const { atlasPath, skeletonPath, scale, skeletonData: skeletonDataInput } = this;
|
const { atlasPath, skeletonPath, scale, skeletonData: skeletonDataInput, rawData } = this;
|
||||||
if (!atlasPath || !skeletonPath) {
|
if (!atlasPath || !skeletonPath) {
|
||||||
throw new Error(`Missing atlas path or skeleton path. Assets cannot be loaded: atlas: ${atlasPath}, skeleton: ${skeletonPath}`);
|
throw new Error(`Missing atlas path or skeleton path. Assets cannot be loaded: atlas: ${atlasPath}, skeleton: ${skeletonPath}`);
|
||||||
}
|
}
|
||||||
const isBinary = skeletonPath.endsWith(".skel");
|
const isBinary = skeletonPath.endsWith(".skel");
|
||||||
|
|
||||||
|
if (rawData) {
|
||||||
|
for (let [key, value] of Object.entries(rawData)) {
|
||||||
|
this.overlay.assetManager.setRawDataURI(key, isBase64(value) ? `data:application/octet-stream;base64,${value}` : value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// skeleton and atlas txt are loaded immeaditely
|
// skeleton and atlas txt are loaded immeaditely
|
||||||
// textures are loaeded depending on the 'pages' param:
|
// textures are loaeded depending on the 'pages' param:
|
||||||
// - [0,2]: only pages at index 0 and 2 are loaded
|
// - [0,2]: only pages at index 0 and 2 are loaded
|
||||||
@ -2320,6 +2334,16 @@ function castArrayString (value: string | null, defaultValue = undefined) {
|
|||||||
return value.split(",");
|
return value.split(",");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function castObject (value: string | null, defaultValue = undefined) {
|
||||||
|
if (value === null) return null;
|
||||||
|
return JSON.parse(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const base64RegExp = /^(([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==))$/;
|
||||||
|
function isBase64(str: string) {
|
||||||
|
return base64RegExp.test(str);
|
||||||
|
}
|
||||||
|
|
||||||
function castValue (type: AttributeTypes, value: string | null, defaultValue?: any) {
|
function castValue (type: AttributeTypes, value: string | null, defaultValue?: any) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "string":
|
case "string":
|
||||||
@ -2332,6 +2356,8 @@ function castValue (type: AttributeTypes, value: string | null, defaultValue?: a
|
|||||||
return castArrayNumber(value, defaultValue);
|
return castArrayNumber(value, defaultValue);
|
||||||
case "array-string":
|
case "array-string":
|
||||||
return castArrayString(value, defaultValue);
|
return castArrayString(value, defaultValue);
|
||||||
|
case "object":
|
||||||
|
return castObject(value, defaultValue);
|
||||||
case "fitType":
|
case "fitType":
|
||||||
return isFitType(value) ? value : defaultValue;
|
return isFitType(value) ? value : defaultValue;
|
||||||
case "modeType":
|
case "modeType":
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user