mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +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) {
|
||||
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 {
|
||||
let dataUri = this.rawDataUris[url];
|
||||
this.finish(url, 200, this.dataUriToString(dataUri));
|
||||
this.finish(url, 200, this.dataUriToString(rawDataUri));
|
||||
} catch (e) {
|
||||
this.finish(url, 400, JSON.stringify(e));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let request = new XMLHttpRequest();
|
||||
request.overrideMimeType("text/html");
|
||||
request.open("GET", url, true);
|
||||
request.open("GET", rawDataUri ? rawDataUri : url, true);
|
||||
let done = () => {
|
||||
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) {
|
||||
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 {
|
||||
let dataUri = this.rawDataUris[url];
|
||||
this.finish(url, 200, this.dataUriToUint8Array(dataUri));
|
||||
this.finish(url, 200, this.dataUriToUint8Array(rawDataUri));
|
||||
} catch (e) {
|
||||
this.finish(url, 400, JSON.stringify(e));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let request = new XMLHttpRequest();
|
||||
request.open("GET", url, true);
|
||||
request.open("GET", rawDataUri ? rawDataUri : url, true);
|
||||
request.responseType = "arraybuffer";
|
||||
let onerror = () => {
|
||||
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);
|
||||
}
|
||||
|
||||
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 CursorEventTypesInput = Exclude<CursorEventTypes, "enter" | "leave">;
|
||||
@ -167,6 +167,7 @@ export type CursorEventTypesInput = Exclude<CursorEventTypes, "enter" | "leave">
|
||||
interface WidgetAttributes {
|
||||
atlasPath?: string
|
||||
skeletonPath?: string
|
||||
rawData?: Record<string, string>
|
||||
jsonSkeletonKey?: string
|
||||
scale: number
|
||||
animation?: string
|
||||
@ -268,6 +269,12 @@ export class SpineWebComponentWidget extends HTMLElement implements Disposable,
|
||||
*/
|
||||
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.
|
||||
* 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 }> = {
|
||||
atlas: { propertyName: "atlasPath", type: "string" },
|
||||
skeleton: { propertyName: "skeletonPath", type: "string" },
|
||||
"raw-data": { propertyName: "rawData", type: "object" },
|
||||
"json-skeleton-key": { propertyName: "jsonSkeletonKey", type: "string" },
|
||||
scale: { propertyName: "scale", type: "number" },
|
||||
animation: { propertyName: "animation", type: "string", defaultValue: undefined },
|
||||
@ -972,12 +980,18 @@ export class SpineWebComponentWidget extends HTMLElement implements Disposable,
|
||||
private async loadSkeleton () {
|
||||
this.loading = true;
|
||||
|
||||
const { atlasPath, skeletonPath, scale, skeletonData: skeletonDataInput } = this;
|
||||
const { atlasPath, skeletonPath, scale, skeletonData: skeletonDataInput, rawData } = this;
|
||||
if (!atlasPath || !skeletonPath) {
|
||||
throw new Error(`Missing atlas path or skeleton path. Assets cannot be loaded: atlas: ${atlasPath}, skeleton: ${skeletonPath}`);
|
||||
}
|
||||
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
|
||||
// textures are loaeded depending on the 'pages' param:
|
||||
// - [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(",");
|
||||
}
|
||||
|
||||
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) {
|
||||
switch (type) {
|
||||
case "string":
|
||||
@ -2332,6 +2356,8 @@ function castValue (type: AttributeTypes, value: string | null, defaultValue?: a
|
||||
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":
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user