custom-svga 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +252 -106
- package/dist/index.esm.js +1 -1
- package/dist/index.global.js +1 -1
- package/dist/svga.worker.cjs +21 -0
- package/dist/svga.worker.js +21 -0
- package/package.json +5 -1
- package/dist/ShapeRenderer-BbtJ_1XO.js +0 -1
- package/dist/ShapeRenderer-Cuwcq2MV.cjs +0 -1
package/dist/index.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var m=(n=>(n.INIT="init",n.VISIBILITY="visibility",n.SET_MOVIE="setMovie",n.SET_IMAGE="setImage",n.SET_DYNAMIC_TEXT="setDynamicText",n.DRAW_EXTERNAL_POSTER="drawExternalPoster",n.PLAY="play",n.STOP="stop",n.PAUSE="pause",n.STEP_TO_FRAME="stepToFrame",n.STEP_TO_PERCENTAGE="stepToPercentage",n.CLEAR="clear",n.CLEAR_DYNAMIC_OBJECTS="clearDynamicObjects",n.CLEAR_DYNAMIC_OBJECT="clearDynamicObject",n.DESTROY="destroy",n.PARSE="parse",n.PARSE_OFFSCREEN="parse_offscreen",n.RELEASE_CACHE="releaseCache",n))(m||{}),P=(n=>(n.SUCCESS="SUCCESS",n.ERROR="ERROR",n.EVENT="event",n))(P||{}),p=(n=>(n.READY="ready",n.ON_START="onStart",n.ON_STOP="onStop",n.ON_PAUSE="onPause",n.ON_PROCESS="onProcess",n.ON_LOOP_END="onLoopEnd",n.ON_REQUEST_MOVIE_DATA="onRequestMovieData",n))(p||{});let v=null,w=null;const b=new Map;let z=0,D={};function W(n){D={...D,...n}}const k=new Map;let x=null;function Y(n){x=n}function A(){if(!v){if(D.workerCreator)v=D.workerCreator();else if(D.workerUrl)v=new Worker(D.workerUrl);else{let n;try{typeof import.meta<"u"&&import.meta.url?n=new URL("./svga.worker.ts",import.meta.url):n="./svga.worker.ts"}catch{n="./svga.worker.ts"}v=new Worker(n,{type:"module"})}v.onmessage=n=>{const{type:e,id:t,name:s,args:a,taskId:i}=n.data;if(i!==void 0){x&&x(n.data);return}const r=b.get(t);r&&e===P.EVENT&&(s===p.ON_START&&r.onStart?r.onStart():s===p.ON_STOP&&r.onStop?r.onStop():s===p.ON_PAUSE&&r.onPause?r.onPause():s===p.ON_LOOP_END&&r.onLoopEnd?r.onLoopEnd():s===p.ON_PROCESS&&r.onProcess?r.onProcess(a[0]):s===p.ON_REQUEST_MOVIE_DATA&&r.resendMovieData())}}return v}class V{id;canvas;observerIsVisible=!0;worker;onStart;onPause;onStop;onLoopEnd;onProcess;_dynamicKeys=new Set;_config;_shapeRendererInstance=null;_movieData=null;constructor(e,t){this.canvas=e,this.id=`renderer_${z++}`,this._config=Object.assign({loop:0,useIntersectionObserver:!0,useSharedRAF:!0,invisibleBehavior:"pause"},t),b.set(this.id,this),this.worker=A();const s=e.transferControlToOffscreen();this.worker.postMessage({type:m.INIT,id:this.id,canvas:s,config:this._config},[s]),this._config.useIntersectionObserver!==!1&&(!w&&typeof IntersectionObserver<"u"&&(w=new IntersectionObserver(a=>{a.forEach(i=>{Array.from(b.values()).filter(r=>r.canvas===i.target).forEach(r=>{r.observerIsVisible=i.isIntersecting,r.worker.postMessage({type:m.VISIBILITY,id:r.id,visible:r.observerIsVisible})})})})),w&&w.observe(this.canvas))}async resendMovieData(){if(this._movieData){const e=this._movieData.movieDataId||"movie_direct_"+Math.random().toString(36).substring(2)+Date.now(),t={},s=[];if(typeof createImageBitmap<"u"&&this._movieData.images){for(const[i,r]of Object.entries(this._movieData.images))if(r instanceof ImageBitmap)try{const o=await createImageBitmap(r);t[i]=o,s.push(o)}catch(o){console.warn("[\u79BB\u5C4F\u6E32\u67D3\u5668] \u91CD\u65B0\u53D1\u9001\u52A8\u753B\u6570\u636E\u65F6\u514B\u9686\u4F4D\u56FE\u5931\u8D25\uFF1A",o)}}const a={...this._movieData,images:t,imageBytes:void 0};k.set(this.id,e),this.worker.postMessage({type:m.SET_MOVIE,id:this.id,movieData:a,movieDataId:e},s)}}async setMovie(e){this._movieData=e;const t=e.movieDataId||"movie_direct_"+Math.random().toString(36).substring(2)+Date.now();k.set(this.id,t),this.worker.postMessage({type:m.SET_MOVIE,id:this.id,movieData:null,movieDataId:t})}async setImage(e,t){if(this._dynamicKeys.add(t),typeof createImageBitmap<"u")try{const s=await createImageBitmap(e);this.worker.postMessage({type:m.SET_IMAGE,id:this.id,key:t,image:s},[s])}catch(s){console.warn("[\u79BB\u5C4F\u6E32\u67D3\u5668] \u8BBE\u7F6E\u52A8\u6001\u56FE\u7247\u65F6\u514B\u9686\u4F4D\u56FE\u5BF9\u8C61\u5931\u8D25\uFF1A",s)}}setDynamicText(e,t){this._dynamicKeys.add(t),this.worker.postMessage({type:m.SET_DYNAMIC_TEXT,id:this.id,key:t,text:e})}setShapeRenderer(e){this._shapeRendererInstance=e}async drawExternalPoster(e){try{const t=await(await fetch(e)).blob(),s=await createImageBitmap(t);this.worker.postMessage({type:m.DRAW_EXTERNAL_POSTER,id:this.id,image:s},[s])}catch(t){console.warn("[\u79BB\u5C4F\u6E32\u67D3\u5668] \u8F7D\u5165\u5E76\u751F\u6210\u9759\u6001\u6D77\u62A5\u6D77\u62A5\u5931\u8D25\uFF1A",t)}}play(e){this.worker.postMessage({type:m.PLAY,id:this.id,config:e})}stop(){this.worker.postMessage({type:m.STOP,id:this.id})}pause(){this.worker.postMessage({type:m.PAUSE,id:this.id})}stepToFrame(e,t=!1){this.worker.postMessage({type:m.STEP_TO_FRAME,id:this.id,frame:e,andPlay:t})}stepToPercentage(e,t){this.worker.postMessage({type:m.STEP_TO_PERCENTAGE,id:this.id,percentage:e,andPlay:t})}clear(){this.worker.postMessage({type:m.CLEAR,id:this.id})}clearDynamicObject(e){this._dynamicKeys.delete(e),this.worker.postMessage({type:m.CLEAR_DYNAMIC_OBJECT,id:this.id,key:e})}clearDynamicObjects(){this._dynamicKeys.clear(),this.worker.postMessage({type:m.CLEAR_DYNAMIC_OBJECTS,id:this.id})}getMemoryInfo(){if(!this._movieData)return{fileSize:0,imageMemory:0,dictionaryMemory:0,version:"",fps:0,frames:0,width:0,height:0,dynamicKeys:[],desc:"\u672A\u52A0\u8F7D\u4EFB\u4F55\u52A8\u6548"};let e=0;this._movieData.images&&Object.values(this._movieData.images).forEach(h=>{h&&h.width&&(e+=h.width*h.height*4)});const t=JSON.stringify({params:this._movieData.params,sprites:this._movieData.sprites}).length,s=this._movieData.fileSize||0,a=this._movieData.version||"",i=this._movieData.params.fps||20,r=this._movieData.params.frames||0,o=this._movieData.params.viewBoxWidth||0,u=this._movieData.params.viewBoxHeight||0,c=Array.from(this._dynamicKeys);return{fileSize:s,imageMemory:e,dictionaryMemory:t,version:a,fps:i,frames:r,width:o,height:u,dynamicKeys:c,desc:`\u6E90\u6587\u4EF6\u5927\u5C0F: ${(s/1024).toFixed(2)} KB | \u9884\u4F30\u663E\u5B58(\u4F4D\u56FE\u4E0E\u7ED3\u6784): ${((e+t)/1024/1024).toFixed(2)} MB`}}destroy(){w&&w.unobserve(this.canvas),k.delete(this.id),b.delete(this.id),this.worker.postMessage({type:m.DESTROY,id:this.id})}}class L{static async loadUrl(e){const t=await fetch(e);if(!t.ok)throw new Error(`\u65E0\u6CD5\u4ECE ${e} \u52A0\u8F7D SVGA \u6587\u4EF6: ${t.statusText}`);return await t.arrayBuffer()}static async loadFile(e){return new Promise((t,s)=>{const a=new FileReader;a.onload=()=>{a.result instanceof ArrayBuffer?t(a.result):s(new Error("\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6\u7684 ArrayBuffer \u6570\u636E"))},a.onerror=()=>s(a.error),a.readAsArrayBuffer(e)})}}let U=0;const M=new Map,f=new Map,K=20,I=new Map,F=new Map,S=new Map;function G(){if(f.size>K){const n=f.keys().next().value;n&&l.destroyCache(n)}}Y(n=>{const{taskId:e,type:t,data:s,error:a}=n,i=M.get(e);if(i){const{useImageBitmap:r}=i;if(t===P.SUCCESS)if(s&&s.images&&!r){const o=[],u=s.images,c={};Object.keys(u).forEach(h=>{const d=u[h];if(d instanceof Uint8Array&&d.length>0){const g=new Promise(y=>{let E="image/png";d[0]===255&&d[1]===216?E="image/jpeg":d[0]===71&&d[1]===73&&d[2]===70?E="image/gif":d[0]===82&&d[1]===73&&d[2]===70&&d[3]===70&&(E="image/webp");const T=new Blob([d],{type:E}),_=URL.createObjectURL(T),C=new Image;C.onload=()=>{c[h]=C,URL.revokeObjectURL(_),y()},C.onerror=()=>{c[h]=C,URL.revokeObjectURL(_),y()},C.src=_});o.push(g)}else c[h]=d}),o.length>0?Promise.all(o).then(()=>{Object.keys(u).forEach(h=>{u[h]=null}),s.images=c,i.resolve(s)}).catch(h=>{i.reject(h)}):(s.images=c,i.resolve(s))}else i.resolve(s);else i.reject(new Error(a||"\u89E3\u6790 SVGA \u6587\u4EF6\u5931\u8D25"));M.delete(e)}});class l{static getCachedVideoItem(e){return f.get(e)}static async loadUrl(e,t){const s=t?.cache!==!1;if(s&&f.has(e)){const i=f.get(e);return f.delete(e),f.set(e,i),i}if(I.has(e))return I.get(e);const a=(async()=>{try{const i=await L.loadUrl(e),r=await l.parseBuffer(i,{...t,movieDataId:e});return s&&(f.set(e,r),G()),r}catch(i){throw I.delete(e),i}finally{I.delete(e)}})();return I.set(e,a),a}static async loadFile(e,t){const s=await L.loadFile(e);return await l.parseBuffer(s,t)}static parseBuffer(e,t){const s=t?.useImageBitmap??!1,a=t?.cache!==!1,i=t?.movieDataId||"movie_direct_"+Math.random().toString(36).substring(2)+Date.now();return new Promise((r,o)=>{try{const u=A(),c=++U;M.set(c,{resolve:r,reject:o,useImageBitmap:s}),u.postMessage({type:m.PARSE,taskId:c,buffer:e,fileSize:e.byteLength,movieDataId:i,useImageBitmap:s,cache:a},[e])}catch(u){u instanceof Error?o(u):o(new Error("\u672A\u77E5\u9519\u8BEF"))}})}static async load(e,t){const s=t?.cache!==!1;if(s&&F.has(e)){const i=F.get(e);return F.delete(e),F.set(e,i),i}if(S.has(e))return S.get(e);const a=(async()=>{try{const i=await L.loadUrl(e),r=await l.parseBufferOffscreen(i,e,t);if(s&&(F.set(e,r),F.size>K)){const o=F.keys().next().value;o&&l.destroyOffscreenCache(o)}return r}catch(i){throw S.delete(e),i}finally{S.delete(e)}})();return S.set(e,a),a}static parseBufferOffscreen(e,t,s){const a=s?.cache!==!1;return new Promise((i,r)=>{try{const o=A(),u=++U;M.set(u,{resolve:i,reject:r}),o.postMessage({type:m.PARSE_OFFSCREEN,taskId:u,buffer:e,fileSize:e.byteLength,movieDataId:t,cache:a},[e])}catch(o){o instanceof Error?r(o):r(new Error("\u672A\u77E5\u9519\u8BEF"))}})}static destroyCache(e){const t=f.get(e);t&&t.images&&Object.keys(t.images).forEach(s=>{const a=t.images[s];a&&(typeof a.close=="function"?a.close():a instanceof HTMLImageElement&&(a.src="")),t.images[s]=null}),f.delete(e)}static clearCache(){Array.from(f.keys()).forEach(e=>{l.destroyCache(e)}),f.clear()}static destroyOffscreenCache(e,t=!0){F.delete(e);try{A().postMessage({type:m.RELEASE_CACHE,movieDataId:e,force:t})}catch(s){console.warn("[Parser] \u53D1\u9001\u624B\u52A8\u9500\u6BC1\u6D88\u606F\u5931\u8D25\uFF1A",s)}}static clearOffscreenCache(){F.clear();try{A().postMessage({type:m.RELEASE_CACHE,movieDataId:void 0,force:!0})}catch(e){console.warn("[Parser] \u53D1\u9001\u6E05\u7A7A\u6240\u6709\u79BB\u5C4F\u7F13\u5B58\u6D88\u606F\u5931\u8D25\uFF1A",e)}}static destroy(e){if(e==null){l.clearCache(),l.clearOffscreenCache();return}if(typeof e=="string"){l.destroyCache(e),l.destroyOffscreenCache(e);return}if(typeof e=="object"){const{url:t,mainThread:s,offscreen:a}=e,i=s!==void 0?s:a===void 0,r=a!==void 0?a:s===void 0;t?(i&&l.destroyCache(t),r&&l.destroyOffscreenCache(t)):(i&&l.clearCache(),r&&l.clearOffscreenCache())}}static setWorkerConfig(e){W(e)}}var H=Object.freeze({__proto__:null,Parser:l});const R=()=>typeof globalThis.requestAnimationFrame<"u"?globalThis.requestAnimationFrame.bind(globalThis):n=>setTimeout(()=>n(performance.now()),16.666666666666668),$=()=>typeof globalThis.cancelAnimationFrame<"u"?globalThis.cancelAnimationFrame.bind(globalThis):n=>clearTimeout(n);class B{static instance;sharedTasks=new Set;sharedRafId=0;standaloneTasks=new Map;static getInstance(){return B.instance||(B.instance=new B),B.instance}add(e,t=!0){if(t)this.sharedTasks.add(e),this.sharedTasks.size===1&&this.sharedRafId===0&&this.startShared();else if(!this.standaloneTasks.has(e)){const s=i=>{try{e(i)}catch(o){console.error("[SVGA \u5B9A\u65F6\u5668] \u72EC\u7ACB\u6E32\u67D3\u4EFB\u52A1\u6267\u884C\u5F02\u5E38\uFF1A",o)}const r=R()(s);this.standaloneTasks.set(e,r)},a=R()(s);this.standaloneTasks.set(e,a)}}remove(e){if(this.sharedTasks.has(e)&&(this.sharedTasks.delete(e),this.sharedTasks.size===0&&this.stopShared()),this.standaloneTasks.has(e)){const t=this.standaloneTasks.get(e);t&&$()(t),this.standaloneTasks.delete(e)}}startShared(){const e=t=>{this.sharedTasks.forEach(s=>{try{s(t)}catch(a){console.error("[SVGA \u5B9A\u65F6\u5668] \u5171\u4EAB\u6E32\u67D3\u4EFB\u52A1\u6267\u884C\u5F02\u5E38\uFF1A",a)}}),this.sharedTasks.size>0?this.sharedRafId=R()(e):this.sharedRafId=0};this.sharedRafId=R()(e)}stopShared(){this.sharedRafId!==0&&($()(this.sharedRafId),this.sharedRafId=0)}}const N=B.getInstance(),j=new WeakMap;let O=null;class J{canvas;ctx;observerIsVisible=!0;movieData=null;isPlaying=!1;currentFrame=0;runtimeFps=20;totalFrames=0;shapeRendererInstance=null;lastTime=0;config;currentLoop=0;onStart;onPause;onStop;onLoopEnd;onProcess;dynamicElements={};startFrame=0;endFrame=0;frameCache=new Map;constructor(e,t){if(this.canvas=e,this.config=Object.assign({loop:0,useIntersectionObserver:!0,useSharedRAF:!0,useOffscreenCanvas:!1,invisibleBehavior:"pause"},t),this.ctx=e.getContext("2d"),!this.ctx)throw new Error("\u83B7\u53D6 2D \u4E0A\u4E0B\u6587\u5931\u8D25");j.set(e,this),this.initObserver()}initObserver(){typeof IntersectionObserver<"u"&&this.config.useIntersectionObserver!==!1&&(this.observerIsVisible=!0,O||(O=new IntersectionObserver(e=>{e.forEach(t=>{const s=j.get(t.target);s&&(s.observerIsVisible=t.isIntersecting)})})),O.observe(this.canvas))}setMovie(e){this.frameCache.clear(),this.movieData=e,this.totalFrames=e.params.frames||1,this.canvas.width=e.params.viewBoxWidth||300,this.canvas.height=e.params.viewBoxHeight||300,this.startFrame=Math.max(0,this.config.startFrame??0),this.endFrame=Math.min(this.totalFrames-1,this.config.endFrame??this.totalFrames-1),this.endFrame<this.startFrame&&(this.endFrame=this.startFrame),this.currentFrame=this.config.direction==="backward"?this.endFrame:this.startFrame,this.currentLoop=0}setImage(e,t){this.frameCache.clear(),this.dynamicElements[t]||(this.dynamicElements[t]={}),this.dynamicElements[t].image=e}setDynamicText(e,t){this.frameCache.clear(),this.dynamicElements[t]||(this.dynamicElements[t]={}),this.dynamicElements[t].text=e}clearDynamicObject(e){this.frameCache.clear(),this.dynamicElements[e]&&delete this.dynamicElements[e]}clearDynamicObjects(){this.frameCache.clear(),this.dynamicElements={}}async drawExternalPoster(e){return new Promise(t=>{const s=new Image;s.crossOrigin="anonymous",s.onload=()=>{if(this.isPlaying||this.movieData){t();return}const a=this.canvas.getBoundingClientRect();if(a.width>0&&a.height>0){const u=window.devicePixelRatio||1;this.canvas.width=a.width*u,this.canvas.height=a.height*u}else this.canvas.width=s.width,this.canvas.height=s.height;this.clearCanvas();const i=Math.min(this.canvas.width/s.width,this.canvas.height/s.height),r=s.width*i,o=s.height*i;this.ctx.drawImage(s,(this.canvas.width-r)/2,(this.canvas.height-o)/2,r,o),t()},s.onerror=()=>t(),s.src=e})}stepToFrame(e,t=!1){e<0||e>=this.totalFrames||(this.currentFrame=e,this.drawFrame(this.currentFrame),t?this.play():this.stop())}stepToPercentage(e,t=!1){const s=Math.floor(e*this.totalFrames);this.stepToFrame(s<this.totalFrames?s:this.totalFrames-1,t)}setShapeRenderer(e){this.shapeRendererInstance=e}getMemoryInfo(){if(!this.movieData)return{fileSize:0,imageMemory:0,dictionaryMemory:0,version:"",fps:0,frames:0,width:0,height:0,dynamicKeys:[],desc:"\u672A\u52A0\u8F7D\u4EFB\u4F55\u52A8\u6548"};let e=0;this.movieData.images&&Object.values(this.movieData.images).forEach(h=>{h&&typeof h=="object"&&"width"in h&&"height"in h&&(e+=h.width*h.height*4)});const t=JSON.stringify({params:this.movieData.params,sprites:this.movieData.sprites}).length,s=this.movieData.fileSize||0,a=this.movieData.version||"",i=this.movieData.params.fps||20,r=this.movieData.params.frames||0,o=this.movieData.params.viewBoxWidth||0,u=this.movieData.params.viewBoxHeight||0,c=Object.keys(this.dynamicElements);return{fileSize:s,imageMemory:e,dictionaryMemory:t,version:a,fps:i,frames:r,width:o,height:u,dynamicKeys:c,desc:`\u6E90\u6587\u4EF6\u5927\u5C0F: ${(s/1024).toFixed(2)} KB | \u9884\u4F30\u663E\u5B58(\u4F4D\u56FE\u4E0E\u7ED3\u6784): ${((e+t)/1024/1024).toFixed(2)} MB`}}play(e){!this.movieData||this.isPlaying||(e&&(e.fps!==void 0&&(this.config.fps=e.fps),e.loop!==void 0&&(this.config.loop=e.loop,this.currentLoop=0),e.fillMode!==void 0&&(this.config.fillMode=e.fillMode),e.startFrame!==void 0&&(this.config.startFrame=e.startFrame),e.endFrame!==void 0&&(this.config.endFrame=e.endFrame),e.useIntersectionObserver!==void 0&&(this.config.useIntersectionObserver=e.useIntersectionObserver),e.invisibleBehavior!==void 0&&(this.config.invisibleBehavior=e.invisibleBehavior),e.useSharedRAF!==void 0&&(this.config.useSharedRAF=e.useSharedRAF),e.cacheFrames!==void 0&&(this.config.cacheFrames!==e.cacheFrames&&this.frameCache.clear(),this.config.cacheFrames=e.cacheFrames),e.direction!==void 0&&(this.config.direction=e.direction)),this.startFrame=Math.max(0,this.config.startFrame??0),this.endFrame=Math.min(this.totalFrames-1,this.config.endFrame??this.totalFrames-1),this.endFrame<this.startFrame&&(this.endFrame=this.startFrame),(this.currentFrame<this.startFrame||this.currentFrame>this.endFrame)&&(this.currentFrame=this.config.direction==="backward"?this.endFrame:this.startFrame),this.runtimeFps=this.config.fps||this.movieData.params.fps||20,this.isPlaying=!0,this.onStart?.(),this.lastTime=performance.now(),N.add(this.loop,this.config.useSharedRAF!==!1))}stop(){this.isPlaying&&(this.isPlaying=!1,this.onStop?.()),N.remove(this.loop)}pause(){this.isPlaying&&(this.isPlaying=!1,this.onPause?.()),N.remove(this.loop)}reset(){this.stop(),this.currentFrame=0,this.currentLoop=0,this.clearCanvas(),this.movieData&&this.drawFrame(0)}clear(){this.stop(),this.clearCanvas(),this.frameCache.clear(),this.movieData=null,this.currentFrame=0,this.currentLoop=0}destroy(){this.clear(),this.clearDynamicObjects(),this.frameCache.clear(),O&&O.unobserve(this.canvas),j.delete(this.canvas),this.canvas=null,this.ctx=null,this.shapeRendererInstance=null}loop=e=>{if(!this.isPlaying)return;const t=1e3/this.runtimeFps,s=e-this.lastTime;if(s>=t){this.lastTime=e-s%t;const a=!this.observerIsVisible,i=this.config.invisibleBehavior==="pause"||!this.config.invisibleBehavior;if(a&&i)return;if(a||this.drawFrame(this.currentFrame),this.onProcess?.(this.currentFrame),this.config.direction!=="backward"){if(this.currentFrame++,this.currentFrame>this.endFrame||this.currentFrame>=this.totalFrames){if(this.currentLoop++,this.onLoopEnd?.(),this.config.loop&&this.config.loop>0&&this.currentLoop>=this.config.loop){this.stop(),this.config.fillMode==="backwards"?this.stepToFrame(this.startFrame):this.config.fillMode==="clear"?this.clearCanvas():this.drawFrame(this.endFrame);return}this.currentFrame=this.startFrame}}else if(this.currentFrame--,this.currentFrame<this.startFrame){if(this.currentLoop++,this.onLoopEnd?.(),this.config.loop&&this.config.loop>0&&this.currentLoop>=this.config.loop){this.stop(),this.config.fillMode==="backwards"?this.stepToFrame(this.endFrame):this.config.fillMode==="clear"?this.clearCanvas():this.drawFrame(this.startFrame);return}this.currentFrame=this.endFrame}}};clearCanvas(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)}drawFrame(e){if(!this.movieData)return;if(this.config.cacheFrames&&this.frameCache.has(e)){const a=this.frameCache.get(e);this.clearCanvas(),this.ctx.drawImage(a,0,0);return}this.clearCanvas();const{sprites:t,images:s}=this.movieData;for(const a of t){const i=a.frames?.[e];if(!i||i.alpha===0)continue;if(this.ctx.save(),this.ctx.globalAlpha=i.alpha,i.transform){const{a:u,b:c,c:h,d,tx:g,ty:y}=i.transform;this.ctx.transform(u,c,h,d,g,y)}if(i.clipPath){const u=new Path2D(i.clipPath);this.ctx.clip(u)}let r=null;if(a.imageKey){const u=this.dynamicElements[a.imageKey];u&&u.image?r=u.image:s&&s[a.imageKey]&&(r=s[a.imageKey])}const o=i.layout;if(r){let u=0,c=0;"width"in r&&(u=r.width),"height"in r&&(c=r.height),o?this.ctx.drawImage(r,o.x||0,o.y||0,Math.max(o.width,0)||u,Math.max(o.height,0)||c):this.ctx.drawImage(r,0,0)}if(a.imageKey&&this.dynamicElements[a.imageKey]&&this.dynamicElements[a.imageKey].text){const u=this.dynamicElements[a.imageKey].text,c=u.size||"14px",h=u.family||"Arial",d=u.color||"#000000",g=u.offset||{x:0,y:0},y=typeof c=="number"?`${c}px ${h}`:`${c} ${h}`;this.ctx.font=y,this.ctx.fillStyle=d,this.ctx.textBaseline="middle",this.ctx.textAlign="center";let E=g.x,T=g.y;o&&(E+=o.x+o.width/2,T+=o.y+o.height/2),this.ctx.fillText(u.text,E,T)}i.shapes&&i.shapes.length>0&&this.shapeRendererInstance&&this.shapeRendererInstance.drawShapes(this.ctx,i.shapes),this.ctx.restore()}if(this.config.cacheFrames){const a=document.createElement("canvas");a.width=this.canvas.width,a.height=this.canvas.height,a.getContext("2d")?.drawImage(this.canvas,0,0),this.frameCache.set(e,a)}}}class X{renderer;constructor(e,t){let s;e instanceof HTMLDivElement?(s=document.createElement("canvas"),s.style.width="100%",s.style.height="100%",e.appendChild(s)):s=e,t?.useOffscreenCanvas&&typeof s.transferControlToOffscreen=="function"&&typeof Worker<"u"?this.renderer=new V(s,t):this.renderer=new J(s,t)}async setVideoItem(e){this.renderer.clear();const t=this.renderer instanceof V;if(t){if(e&&typeof e=="object"&&!e.isOffscreen&&(e.sprites||e.images))throw new Error("[SVGA \u64AD\u653E\u5668\u4E25\u91CD\u9519\u8BEF] \u5F53\u524D\u5DF2\u5F00\u542F Offscreen \u79BB\u5C4F\u6E32\u67D3\u4F18\u5316\uFF01\u5728\u79BB\u5C4F\u6E32\u67D3\u6A21\u5F0F\u4E0B\uFF0C\u4E25\u683C\u7981\u6B62\u5411\u64AD\u653E\u5668 setVideoItem \u4F20\u9012\u4E3B\u7EBF\u7A0B\u7684\u5B8C\u6574\u590D\u6742 MovieData \u6570\u636E\uFF08\u8FD9\u4F1A\u5BFC\u81F4\u4E3B\u7EBF\u7A0B\u4E8C\u6B21\u53CD\u5E8F\u5217\u5316\u4E0E\u591A\u4EFD\u56FE\u50CF\u7559\u5B58\uFF0C\u4F7F\u624B\u673A\u5185\u5B58\u6210\u500D\u66B4\u589E\uFF09\u3002\u8BF7\u6539\u7528\u4E3A\u79BB\u5C4F\u6A21\u5F0F\u4E13\u5C5E\u89E3\u8026\u8BBE\u8BA1\u7684\u52A0\u8F7D\u65B9\u6CD5\u3010Parser.load(url)\u3011\u83B7\u53D6\u4EC5\u542B ID \u7684\u8F7B\u91CF\u53E5\u67C4\uFF0C\u6216\u8005\u76F4\u63A5\u4F20\u5165 String \u7C7B\u578B\u7684 URL \u81EA\u9002\u5E94\u79BB\u5C4F\u6D41\u3002")}else if(e&&typeof e=="object"&&e.isOffscreen)throw new Error("[SVGA \u64AD\u653E\u5668\u4E25\u91CD\u9519\u8BEF] \u5F53\u524D\u4F7F\u7528\u7684\u662F\u4E3B\u7EBF\u7A0B\u4F20\u7EDF\u6E32\u67D3\u5668\uFF0C\u4F46\u5374\u4F20\u5165\u4E86\u5B50\u7EBF\u7A0B\u4E13\u7528\u7684\u79BB\u5C4F\u8F7B\u91CF\u5316\u5143\u6570\u636E\u53E5\u67C4 (isOffscreen: true)\uFF01\u8FD9\u5C06\u5BFC\u81F4\u4E3B\u7EBF\u7A0B\u6CA1\u6709\u4EFB\u4F55\u53EF\u4EE5\u7528\u4E8E\u7ED8\u5236\u548C\u53CD\u5E8F\u5217\u5316\u7684\u56FE\u50CF/\u7CBE\u7075\u5E8F\u5217\u6811\u4FE1\u606F\u3002\u5728\u666E\u901A\u6E32\u67D3\u6A21\u5F0F\u4E0B\uFF0C\u8BF7\u4F7F\u7528\u4E3B\u7EBF\u7A0B\u52A0\u8F7D\u65B9\u6CD5\u3010Parser.loadUrl(url)\u3011\u6216\u3010Parser.loadFile(file)\u3011\u3002");if(typeof e=="string")if(t){await this.renderer.setMovie({movieDataId:e});return}else{const{Parser:a}=await Promise.resolve().then(function(){return H}),i=a.getCachedVideoItem(e)||await a.loadUrl(e);i&&await this.renderer.setMovie(i);return}let s=!1;if(e&&e.sprites)for(const a of e.sprites){if(s)break;if(a.frames){for(const i of a.frames)if(i.shapes&&i.shapes.length>0){s=!0;break}}}if(s){const{ShapeRenderer:a}=await import("./ShapeRenderer-BbtJ_1XO.js");this.renderer.setShapeRenderer(a.getInstance())}await this.renderer.setMovie(e)}play(e){this.renderer.play(e)}playRange(e,t,s){this.renderer.play(Object.assign({startFrame:e,endFrame:t},s))}pause(){this.renderer.pause()}stop(){this.renderer.stop()}onStart(e){this.renderer.onStart=e}onPause(e){this.renderer.onPause=e}onStop(e){this.renderer.onStop=e}onLoopEnd(e){this.renderer.onLoopEnd=e}onProcess(e){this.renderer.onProcess=e}stepToFrame(e,t=!1){this.renderer.stepToFrame(e,t)}stepToPercentage(e,t=!1){this.renderer.stepToPercentage(e,t)}async setImage(e,t){if(typeof e=="string"){const s=new Image;s.crossOrigin="anonymous";const a=new Promise((i,r)=>{s.onload=()=>i(s),s.onerror=o=>r(o)});s.src=e;try{const i=await a;await this.renderer.setImage(i,t)}catch(i){console.warn(`[Player] \u52A8\u6001\u52A0\u8F7D\u56FE\u7247\u94FE\u63A5 ${e} \u5931\u8D25\uFF1A`,i)}}else await this.renderer.setImage(e,t)}setText(e,t){typeof e=="string"?this.renderer.setDynamicText({text:e},t):this.renderer.setDynamicText(e,t)}clearDynamicObject(e){this.renderer.clearDynamicObject(e)}clearDynamicObjects(){this.renderer.clearDynamicObjects()}async renderPoster(e){await this.renderer.drawExternalPoster(e)}getMemoryInfo(){return this.renderer.getMemoryInfo()}clear(){this.renderer.clear()}destroy(){this.renderer.destroy()}}export{l as Parser,X as Player};
|
|
1
|
+
const M=()=>typeof globalThis.requestAnimationFrame<"u"?globalThis.requestAnimationFrame.bind(globalThis):n=>setTimeout(()=>n(performance.now()),16.666666666666668),V=()=>typeof globalThis.cancelAnimationFrame<"u"?globalThis.cancelAnimationFrame.bind(globalThis):n=>clearTimeout(n);class A{static instance;sharedTasks=new Set;sharedRafId=0;standaloneTasks=new Map;static getInstance(){return A.instance||(A.instance=new A),A.instance}add(e,s=!0){if(s)this.sharedTasks.add(e),this.sharedTasks.size===1&&this.sharedRafId===0&&this.startShared();else if(!this.standaloneTasks.has(e)){const t=i=>{try{e(i)}catch(o){console.error("[SVGA \u5B9A\u65F6\u5668] \u72EC\u7ACB\u6E32\u67D3\u4EFB\u52A1\u6267\u884C\u5F02\u5E38\uFF1A",o)}const r=M()(t);this.standaloneTasks.set(e,r)},a=M()(t);this.standaloneTasks.set(e,a)}}remove(e){if(this.sharedTasks.has(e)&&(this.sharedTasks.delete(e),this.sharedTasks.size===0&&this.stopShared()),this.standaloneTasks.has(e)){const s=this.standaloneTasks.get(e);s&&V()(s),this.standaloneTasks.delete(e)}}startShared(){const e=s=>{this.sharedTasks.forEach(t=>{try{t(s)}catch(a){console.error("[SVGA \u5B9A\u65F6\u5668] \u5171\u4EAB\u6E32\u67D3\u4EFB\u52A1\u6267\u884C\u5F02\u5E38\uFF1A",a)}}),this.sharedTasks.size>0?this.sharedRafId=M()(e):this.sharedRafId=0};this.sharedRafId=M()(e)}stopShared(){this.sharedRafId!==0&&(V()(this.sharedRafId),this.sharedRafId=0)}}const x=A.getInstance(),L=new WeakMap;let O=null;class Y{canvas;ctx;observerIsVisible=!0;movieData=null;isPlaying=!1;currentFrame=0;runtimeFps=20;totalFrames=0;shapeRendererInstance=null;lastTime=0;config;currentLoop=0;onStart;onPause;onStop;onLoopEnd;onProcess;dynamicElements={};startFrame=0;endFrame=0;frameCache=new Map;constructor(e,s){if(this.canvas=e,this.config=Object.assign({loop:0,useIntersectionObserver:!0,useSharedRAF:!0,useOffscreenCanvas:!1,invisibleBehavior:"pause"},s),this.ctx=e.getContext("2d"),!this.ctx)throw new Error("\u83B7\u53D6 2D \u4E0A\u4E0B\u6587\u5931\u8D25");L.set(e,this),this.initObserver()}initObserver(){typeof IntersectionObserver<"u"&&this.config.useIntersectionObserver!==!1&&(this.observerIsVisible=!0,O||(O=new IntersectionObserver(e=>{e.forEach(s=>{const t=L.get(s.target);t&&(t.observerIsVisible=s.isIntersecting)})})),O.observe(this.canvas))}setMovie(e){this.frameCache.clear(),this.movieData=e,this.totalFrames=e.params.frames||1,this.canvas.width=e.params.viewBoxWidth||300,this.canvas.height=e.params.viewBoxHeight||300,this.startFrame=Math.max(0,this.config.startFrame??0),this.endFrame=Math.min(this.totalFrames-1,this.config.endFrame??this.totalFrames-1),this.endFrame<this.startFrame&&(this.endFrame=this.startFrame),this.currentFrame=this.config.direction==="backward"?this.endFrame:this.startFrame,this.currentLoop=0}setImage(e,s){this.frameCache.clear(),this.dynamicElements[s]||(this.dynamicElements[s]={}),this.dynamicElements[s].image=e}setDynamicText(e,s){this.frameCache.clear(),this.dynamicElements[s]||(this.dynamicElements[s]={}),this.dynamicElements[s].text=e}clearDynamicObject(e){this.frameCache.clear(),this.dynamicElements[e]&&delete this.dynamicElements[e]}clearDynamicObjects(){this.frameCache.clear(),this.dynamicElements={}}async drawExternalPoster(e){return new Promise(s=>{const t=new Image;t.crossOrigin="anonymous",t.onload=()=>{if(this.isPlaying||this.movieData){s();return}const a=this.canvas.getBoundingClientRect();if(a.width>0&&a.height>0){const u=window.devicePixelRatio||1;this.canvas.width=a.width*u,this.canvas.height=a.height*u}else this.canvas.width=t.width,this.canvas.height=t.height;this.clearCanvas();const i=Math.min(this.canvas.width/t.width,this.canvas.height/t.height),r=t.width*i,o=t.height*i;this.ctx.drawImage(t,(this.canvas.width-r)/2,(this.canvas.height-o)/2,r,o),s()},t.onerror=()=>s(),t.src=e})}stepToFrame(e,s=!1){e<0||e>=this.totalFrames||(this.currentFrame=e,this.drawFrame(this.currentFrame),s?this.play():this.stop())}stepToPercentage(e,s=!1){const t=Math.floor(e*this.totalFrames);this.stepToFrame(t<this.totalFrames?t:this.totalFrames-1,s)}setShapeRenderer(e){this.shapeRendererInstance=e}getMemoryInfo(){if(!this.movieData)return{fileSize:0,imageMemory:0,dictionaryMemory:0,version:"",fps:0,frames:0,width:0,height:0,dynamicKeys:[],desc:"\u672A\u52A0\u8F7D\u4EFB\u4F55\u52A8\u6548"};let e=0;this.movieData.images&&Object.values(this.movieData.images).forEach(c=>{c&&typeof c=="object"&&"width"in c&&"height"in c&&(e+=c.width*c.height*4)});const s=JSON.stringify({params:this.movieData.params,sprites:this.movieData.sprites}).length,t=this.movieData.fileSize||0,a=this.movieData.version||"",i=this.movieData.params.fps||20,r=this.movieData.params.frames||0,o=this.movieData.params.viewBoxWidth||0,u=this.movieData.params.viewBoxHeight||0,h=Object.keys(this.dynamicElements);return{fileSize:t,imageMemory:e,dictionaryMemory:s,version:a,fps:i,frames:r,width:o,height:u,dynamicKeys:h,desc:`\u6E90\u6587\u4EF6\u5927\u5C0F: ${(t/1024).toFixed(2)} KB | \u9884\u4F30\u663E\u5B58(\u4F4D\u56FE\u4E0E\u7ED3\u6784): ${((e+s)/1024/1024).toFixed(2)} MB`}}play(e){!this.movieData||this.isPlaying||(e&&(e.fps!==void 0&&(this.config.fps=e.fps),e.loop!==void 0&&(this.config.loop=e.loop,this.currentLoop=0),e.fillMode!==void 0&&(this.config.fillMode=e.fillMode),e.startFrame!==void 0&&(this.config.startFrame=e.startFrame),e.endFrame!==void 0&&(this.config.endFrame=e.endFrame),e.useIntersectionObserver!==void 0&&(this.config.useIntersectionObserver=e.useIntersectionObserver),e.invisibleBehavior!==void 0&&(this.config.invisibleBehavior=e.invisibleBehavior),e.useSharedRAF!==void 0&&(this.config.useSharedRAF=e.useSharedRAF),e.cacheFrames!==void 0&&(this.config.cacheFrames!==e.cacheFrames&&this.frameCache.clear(),this.config.cacheFrames=e.cacheFrames),e.direction!==void 0&&(this.config.direction=e.direction)),this.startFrame=Math.max(0,this.config.startFrame??0),this.endFrame=Math.min(this.totalFrames-1,this.config.endFrame??this.totalFrames-1),this.endFrame<this.startFrame&&(this.endFrame=this.startFrame),(this.currentFrame<this.startFrame||this.currentFrame>this.endFrame)&&(this.currentFrame=this.config.direction==="backward"?this.endFrame:this.startFrame),this.runtimeFps=this.config.fps||this.movieData.params.fps||20,this.isPlaying=!0,this.onStart?.(),this.lastTime=performance.now(),x.add(this.loop,this.config.useSharedRAF!==!1))}stop(){this.isPlaying&&(this.isPlaying=!1,this.onStop?.()),x.remove(this.loop)}pause(){this.isPlaying&&(this.isPlaying=!1,this.onPause?.()),x.remove(this.loop)}reset(){this.stop(),this.currentFrame=0,this.currentLoop=0,this.clearCanvas(),this.movieData&&this.drawFrame(0)}clear(){this.stop(),this.clearCanvas(),this.frameCache.clear(),this.movieData=null,this.currentFrame=0,this.currentLoop=0}destroy(){this.clear(),this.clearDynamicObjects(),this.frameCache.clear(),O&&O.unobserve(this.canvas),L.delete(this.canvas),this.canvas=null,this.ctx=null,this.shapeRendererInstance=null}loop=e=>{if(!this.isPlaying)return;const s=1e3/this.runtimeFps,t=e-this.lastTime;if(t>=s){this.lastTime=e-t%s;const a=!this.observerIsVisible,i=this.config.invisibleBehavior==="pause"||!this.config.invisibleBehavior;if(a&&i)return;if(a||this.drawFrame(this.currentFrame),this.onProcess?.(this.currentFrame),this.config.direction!=="backward"){if(this.currentFrame++,this.currentFrame>this.endFrame||this.currentFrame>=this.totalFrames){if(this.currentLoop++,this.onLoopEnd?.(),this.config.loop&&this.config.loop>0&&this.currentLoop>=this.config.loop){this.stop(),this.config.fillMode==="backwards"?this.stepToFrame(this.startFrame):this.config.fillMode==="clear"?this.clearCanvas():this.drawFrame(this.endFrame);return}this.currentFrame=this.startFrame}}else if(this.currentFrame--,this.currentFrame<this.startFrame){if(this.currentLoop++,this.onLoopEnd?.(),this.config.loop&&this.config.loop>0&&this.currentLoop>=this.config.loop){this.stop(),this.config.fillMode==="backwards"?this.stepToFrame(this.endFrame):this.config.fillMode==="clear"?this.clearCanvas():this.drawFrame(this.startFrame);return}this.currentFrame=this.endFrame}}};clearCanvas(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)}drawFrame(e){if(!this.movieData)return;if(this.config.cacheFrames&&this.frameCache.has(e)){const a=this.frameCache.get(e);this.clearCanvas(),this.ctx.drawImage(a,0,0);return}this.clearCanvas();const{sprites:s,images:t}=this.movieData;for(const a of s){const i=a.frames?.[e];if(!i||i.alpha===0)continue;if(this.ctx.save(),this.ctx.globalAlpha=i.alpha,i.transform){const{a:u,b:h,c,d:m,tx:y,ty:v}=i.transform;this.ctx.transform(u,h,c,m,y,v)}if(i.clipPath){const u=new Path2D(i.clipPath);this.ctx.clip(u)}let r=null;if(a.imageKey){const u=this.dynamicElements[a.imageKey];u&&u.image?r=u.image:t&&t[a.imageKey]&&(r=t[a.imageKey])}const o=i.layout;if(r){let u=0,h=0;"width"in r&&(u=r.width),"height"in r&&(h=r.height),o?this.ctx.drawImage(r,o.x||0,o.y||0,Math.max(o.width,0)||u,Math.max(o.height,0)||h):this.ctx.drawImage(r,0,0)}if(a.imageKey&&this.dynamicElements[a.imageKey]&&this.dynamicElements[a.imageKey].text){const u=this.dynamicElements[a.imageKey].text,h=u.size||"14px",c=u.family||"Arial",m=u.color||"#000000",y=u.offset||{x:0,y:0},v=typeof h=="number"?`${h}px ${c}`:`${h} ${c}`;this.ctx.font=v,this.ctx.fillStyle=m,this.ctx.textBaseline="middle",this.ctx.textAlign="center";let F=y.x,C=y.y;o&&(F+=o.x+o.width/2,C+=o.y+o.height/2),this.ctx.fillText(u.text,F,C)}i.shapes&&i.shapes.length>0&&this.shapeRendererInstance&&this.shapeRendererInstance.drawShapes(this.ctx,i.shapes),this.ctx.restore()}if(this.config.cacheFrames){const a=document.createElement("canvas");a.width=this.canvas.width,a.height=this.canvas.height,a.getContext("2d")?.drawImage(this.canvas,0,0),this.frameCache.set(e,a)}}}var l=(n=>(n.INIT="init",n.VISIBILITY="visibility",n.SET_MOVIE="setMovie",n.SET_IMAGE="setImage",n.SET_DYNAMIC_TEXT="setDynamicText",n.DRAW_EXTERNAL_POSTER="drawExternalPoster",n.PLAY="play",n.STOP="stop",n.PAUSE="pause",n.STEP_TO_FRAME="stepToFrame",n.STEP_TO_PERCENTAGE="stepToPercentage",n.CLEAR="clear",n.CLEAR_DYNAMIC_OBJECTS="clearDynamicObjects",n.CLEAR_DYNAMIC_OBJECT="clearDynamicObject",n.DESTROY="destroy",n.PARSE="parse",n.PARSE_OFFSCREEN="parse_offscreen",n.RELEASE_CACHE="releaseCache",n))(l||{}),k=(n=>(n.SUCCESS="SUCCESS",n.ERROR="ERROR",n.EVENT="event",n))(k||{}),w=(n=>(n.READY="ready",n.ON_START="onStart",n.ON_STOP="onStop",n.ON_PAUSE="onPause",n.ON_PROCESS="onProcess",n.ON_LOOP_END="onLoopEnd",n.ON_REQUEST_MOVIE_DATA="onRequestMovieData",n))(w||{});let E=null,B=null;const _=new Map;let G=0,p={};function K(n){p={...p,...n}}const j=new Map;let N=null;function H(n){N=n}function b(){if(!E){if(p.workerInstance)E=p.workerInstance;else if(p.workerCreator)E=p.workerCreator();else if(p.workerString){const n=new Blob([p.workerString],{type:"application/javascript"}),e=URL.createObjectURL(n);E=new Worker(e)}else if(p.workerUrl){const n=p.workerUrl;if(!n.startsWith(window.location.origin)&&/^(https?:)?\/\//.test(n)){const e=`importScripts(${JSON.stringify(n)});`,s=new Blob([e],{type:"application/javascript"}),t=URL.createObjectURL(s);E=new Worker(t)}else E=new Worker(n)}else{let n;try{if(typeof import.meta<"u"&&import.meta.url){const e=typeof import.meta<"u"&&import.meta.env,s=typeof globalThis<"u"?globalThis.process:void 0;(e?import.meta.env.DEV:typeof s<"u"&&s.env&&s.env.NODE_ENV!=="production")?n=new URL("./svga.worker.ts",import.meta.url):n=new URL("./svga.worker.js",import.meta.url)}else n="./svga.worker.js"}catch{n="./svga.worker.js"}E=new Worker(n,{type:"module"})}E.onmessage=n=>{const{type:e,id:s,name:t,args:a,taskId:i}=n.data;if(i!==void 0){N&&N(n.data);return}const r=_.get(s);r&&e===k.EVENT&&(t===w.ON_START&&r.onStart?r.onStart():t===w.ON_STOP&&r.onStop?r.onStop():t===w.ON_PAUSE&&r.onPause?r.onPause():t===w.ON_LOOP_END&&r.onLoopEnd?r.onLoopEnd():t===w.ON_PROCESS&&r.onProcess?r.onProcess(a[0]):t===w.ON_REQUEST_MOVIE_DATA&&r.resendMovieData())}}return E}class W{id;canvas;observerIsVisible=!0;worker;onStart;onPause;onStop;onLoopEnd;onProcess;_dynamicKeys=new Set;_config;_shapeRendererInstance=null;_movieData=null;constructor(e,s){this.canvas=e,this.id=`renderer_${G++}`,this._config=Object.assign({loop:0,useIntersectionObserver:!0,useSharedRAF:!0,invisibleBehavior:"pause"},s),_.set(this.id,this),this.worker=b();const t=e.transferControlToOffscreen();this.worker.postMessage({type:l.INIT,id:this.id,canvas:t,config:this._config},[t]),this._config.useIntersectionObserver!==!1&&(!B&&typeof IntersectionObserver<"u"&&(B=new IntersectionObserver(a=>{a.forEach(i=>{Array.from(_.values()).filter(r=>r.canvas===i.target).forEach(r=>{r.observerIsVisible=i.isIntersecting,r.worker.postMessage({type:l.VISIBILITY,id:r.id,visible:r.observerIsVisible})})})})),B&&B.observe(this.canvas))}async resendMovieData(){if(this._movieData){const e=this._movieData.movieDataId||"movie_direct_"+Math.random().toString(36).substring(2)+Date.now(),s={},t=[];if(typeof createImageBitmap<"u"&&this._movieData.images){for(const[i,r]of Object.entries(this._movieData.images))if(r instanceof ImageBitmap)try{const o=await createImageBitmap(r);s[i]=o,t.push(o)}catch(o){console.warn("[\u79BB\u5C4F\u6E32\u67D3\u5668] \u91CD\u65B0\u53D1\u9001\u52A8\u753B\u6570\u636E\u65F6\u514B\u9686\u4F4D\u56FE\u5931\u8D25\uFF1A",o)}}const a={...this._movieData,images:s,imageBytes:void 0};j.set(this.id,e),this.worker.postMessage({type:l.SET_MOVIE,id:this.id,movieData:a,movieDataId:e},t)}}async setMovie(e){this._movieData=e;const s=e.movieDataId||"movie_direct_"+Math.random().toString(36).substring(2)+Date.now();j.set(this.id,s),this.worker.postMessage({type:l.SET_MOVIE,id:this.id,movieData:null,movieDataId:s})}async setImage(e,s){if(this._dynamicKeys.add(s),typeof createImageBitmap<"u")try{const t=await createImageBitmap(e);this.worker.postMessage({type:l.SET_IMAGE,id:this.id,key:s,image:t},[t])}catch(t){console.warn("[\u79BB\u5C4F\u6E32\u67D3\u5668] \u8BBE\u7F6E\u52A8\u6001\u56FE\u7247\u65F6\u514B\u9686\u4F4D\u56FE\u5BF9\u8C61\u5931\u8D25\uFF1A",t)}}setDynamicText(e,s){this._dynamicKeys.add(s),this.worker.postMessage({type:l.SET_DYNAMIC_TEXT,id:this.id,key:s,text:e})}setShapeRenderer(e){this._shapeRendererInstance=e}async drawExternalPoster(e){try{const s=await(await fetch(e)).blob(),t=await createImageBitmap(s);this.worker.postMessage({type:l.DRAW_EXTERNAL_POSTER,id:this.id,image:t},[t])}catch(s){console.warn("[\u79BB\u5C4F\u6E32\u67D3\u5668] \u8F7D\u5165\u5E76\u751F\u6210\u9759\u6001\u6D77\u62A5\u6D77\u62A5\u5931\u8D25\uFF1A",s)}}play(e){this.worker.postMessage({type:l.PLAY,id:this.id,config:e})}stop(){this.worker.postMessage({type:l.STOP,id:this.id})}pause(){this.worker.postMessage({type:l.PAUSE,id:this.id})}stepToFrame(e,s=!1){this.worker.postMessage({type:l.STEP_TO_FRAME,id:this.id,frame:e,andPlay:s})}stepToPercentage(e,s){this.worker.postMessage({type:l.STEP_TO_PERCENTAGE,id:this.id,percentage:e,andPlay:s})}clear(){this.worker.postMessage({type:l.CLEAR,id:this.id})}clearDynamicObject(e){this._dynamicKeys.delete(e),this.worker.postMessage({type:l.CLEAR_DYNAMIC_OBJECT,id:this.id,key:e})}clearDynamicObjects(){this._dynamicKeys.clear(),this.worker.postMessage({type:l.CLEAR_DYNAMIC_OBJECTS,id:this.id})}getMemoryInfo(){if(!this._movieData)return{fileSize:0,imageMemory:0,dictionaryMemory:0,version:"",fps:0,frames:0,width:0,height:0,dynamicKeys:[],desc:"\u672A\u52A0\u8F7D\u4EFB\u4F55\u52A8\u6548"};let e=0;this._movieData.images&&Object.values(this._movieData.images).forEach(c=>{c&&c.width&&(e+=c.width*c.height*4)});const s=JSON.stringify({params:this._movieData.params,sprites:this._movieData.sprites}).length,t=this._movieData.fileSize||0,a=this._movieData.version||"",i=this._movieData.params.fps||20,r=this._movieData.params.frames||0,o=this._movieData.params.viewBoxWidth||0,u=this._movieData.params.viewBoxHeight||0,h=Array.from(this._dynamicKeys);return{fileSize:t,imageMemory:e,dictionaryMemory:s,version:a,fps:i,frames:r,width:o,height:u,dynamicKeys:h,desc:`\u6E90\u6587\u4EF6\u5927\u5C0F: ${(t/1024).toFixed(2)} KB | \u9884\u4F30\u663E\u5B58(\u4F4D\u56FE\u4E0E\u7ED3\u6784): ${((e+s)/1024/1024).toFixed(2)} MB`}}destroy(){B&&B.unobserve(this.canvas),j.delete(this.id),_.delete(this.id),this.worker.postMessage({type:l.DESTROY,id:this.id})}}class J{renderer;constructor(e,s){let t;e instanceof HTMLDivElement?(t=document.createElement("canvas"),t.style.width="100%",t.style.height="100%",e.appendChild(t)):t=e,s?.useOffscreenCanvas&&typeof t.transferControlToOffscreen=="function"&&typeof Worker<"u"?this.renderer=new W(t,s):this.renderer=new Y(t,s)}async setVideoItem(e){this.renderer.clear();const s=this.renderer instanceof W;if(s){if(e&&typeof e=="object"&&!e.isOffscreen&&(e.sprites||e.images))throw new Error("[SVGA \u64AD\u653E\u5668\u4E25\u91CD\u9519\u8BEF] \u5F53\u524D\u5DF2\u5F00\u542F Offscreen \u79BB\u5C4F\u6E32\u67D3\u4F18\u5316\uFF01\u5728\u79BB\u5C4F\u6E32\u67D3\u6A21\u5F0F\u4E0B\uFF0C\u4E25\u683C\u7981\u6B62\u5411\u64AD\u653E\u5668 setVideoItem \u4F20\u9012\u4E3B\u7EBF\u7A0B\u7684\u5B8C\u6574\u590D\u6742 MovieData \u6570\u636E\uFF08\u8FD9\u4F1A\u5BFC\u81F4\u4E3B\u7EBF\u7A0B\u4E8C\u6B21\u53CD\u5E8F\u5217\u5316\u4E0E\u591A\u4EFD\u56FE\u50CF\u7559\u5B58\uFF0C\u4F7F\u624B\u673A\u5185\u5B58\u6210\u500D\u66B4\u589E\uFF09\u3002\u8BF7\u6539\u7528\u4E3A\u79BB\u5C4F\u6A21\u5F0F\u4E13\u5C5E\u89E3\u8026\u8BBE\u8BA1\u7684\u52A0\u8F7D\u65B9\u6CD5\u3010Parser.load(url)\u3011\u83B7\u53D6\u4EC5\u542B ID \u7684\u8F7B\u91CF\u53E5\u67C4\uFF0C\u6216\u8005\u76F4\u63A5\u4F20\u5165 String \u7C7B\u578B\u7684 URL \u81EA\u9002\u5E94\u79BB\u5C4F\u6D41\u3002")}else if(e&&typeof e=="object"&&e.isOffscreen)throw new Error("[SVGA \u64AD\u653E\u5668\u4E25\u91CD\u9519\u8BEF] \u5F53\u524D\u4F7F\u7528\u7684\u662F\u4E3B\u7EBF\u7A0B\u4F20\u7EDF\u6E32\u67D3\u5668\uFF0C\u4F46\u5374\u4F20\u5165\u4E86\u5B50\u7EBF\u7A0B\u4E13\u7528\u7684\u79BB\u5C4F\u8F7B\u91CF\u5316\u5143\u6570\u636E\u53E5\u67C4 (isOffscreen: true)\uFF01\u8FD9\u5C06\u5BFC\u81F4\u4E3B\u7EBF\u7A0B\u6CA1\u6709\u4EFB\u4F55\u53EF\u4EE5\u7528\u4E8E\u7ED8\u5236\u548C\u53CD\u5E8F\u5217\u5316\u7684\u56FE\u50CF/\u7CBE\u7075\u5E8F\u5217\u6811\u4FE1\u606F\u3002\u5728\u666E\u901A\u6E32\u67D3\u6A21\u5F0F\u4E0B\uFF0C\u8BF7\u4F7F\u7528\u4E3B\u7EBF\u7A0B\u52A0\u8F7D\u65B9\u6CD5\u3010Parser.loadUrl(url)\u3011\u6216\u3010Parser.loadFile(file)\u3011\u3002");if(typeof e=="string")if(s){await this.renderer.setMovie({movieDataId:e});return}else{const{Parser:a}=await Promise.resolve().then(function(){return q}),i=a.getCachedVideoItem(e)||await a.loadUrl(e);i&&await this.renderer.setMovie(i);return}let t=!1;if(e&&e.sprites)for(const a of e.sprites){if(t)break;if(a.frames){for(const i of a.frames)if(i.shapes&&i.shapes.length>0){t=!0;break}}}if(t){const{ShapeRenderer:a}=await Promise.resolve().then(function(){return Q});this.renderer.setShapeRenderer(a.getInstance())}await this.renderer.setMovie(e)}play(e){this.renderer.play(e)}playRange(e,s,t){this.renderer.play(Object.assign({startFrame:e,endFrame:s},t))}pause(){this.renderer.pause()}stop(){this.renderer.stop()}onStart(e){this.renderer.onStart=e}onPause(e){this.renderer.onPause=e}onStop(e){this.renderer.onStop=e}onLoopEnd(e){this.renderer.onLoopEnd=e}onProcess(e){this.renderer.onProcess=e}stepToFrame(e,s=!1){this.renderer.stepToFrame(e,s)}stepToPercentage(e,s=!1){this.renderer.stepToPercentage(e,s)}async setImage(e,s){if(typeof e=="string"){const t=new Image;t.crossOrigin="anonymous";const a=new Promise((i,r)=>{t.onload=()=>i(t),t.onerror=o=>r(o)});t.src=e;try{const i=await a;await this.renderer.setImage(i,s)}catch(i){console.warn(`[Player] \u52A8\u6001\u52A0\u8F7D\u56FE\u7247\u94FE\u63A5 ${e} \u5931\u8D25\uFF1A`,i)}}else await this.renderer.setImage(e,s)}setText(e,s){typeof e=="string"?this.renderer.setDynamicText({text:e},s):this.renderer.setDynamicText(e,s)}clearDynamicObject(e){this.renderer.clearDynamicObject(e)}clearDynamicObjects(){this.renderer.clearDynamicObjects()}async renderPoster(e){await this.renderer.drawExternalPoster(e)}getMemoryInfo(){return this.renderer.getMemoryInfo()}clear(){this.renderer.clear()}destroy(){this.renderer.destroy()}}class U{static async loadUrl(e){const s=await fetch(e);if(!s.ok)throw new Error(`\u65E0\u6CD5\u4ECE ${e} \u52A0\u8F7D SVGA \u6587\u4EF6: ${s.statusText}`);return await s.arrayBuffer()}static async loadFile(e){return new Promise((s,t)=>{const a=new FileReader;a.onload=()=>{a.result instanceof ArrayBuffer?s(a.result):t(new Error("\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6\u7684 ArrayBuffer \u6570\u636E"))},a.onerror=()=>t(a.error),a.readAsArrayBuffer(e)})}}let $=0;const P=new Map,f=new Map,z=20,T=new Map,g=new Map,R=new Map;function X(){if(f.size>z){const n=f.keys().next().value;n&&d.destroyCache(n)}}H(n=>{const{taskId:e,type:s,data:t,error:a}=n,i=P.get(e);if(i){const{useImageBitmap:r}=i;if(s===k.SUCCESS)if(t&&t.images&&!r){const o=[],u=t.images,h={};Object.keys(u).forEach(c=>{const m=u[c];if(m instanceof Uint8Array&&m.length>0){const y=new Promise(v=>{let F="image/png";m[0]===255&&m[1]===216?F="image/jpeg":m[0]===71&&m[1]===73&&m[2]===70?F="image/gif":m[0]===82&&m[1]===73&&m[2]===70&&m[3]===70&&(F="image/webp");const C=new Blob([m],{type:F}),I=URL.createObjectURL(C),D=new Image;D.onload=()=>{h[c]=D,URL.revokeObjectURL(I),v()},D.onerror=()=>{h[c]=D,URL.revokeObjectURL(I),v()},D.src=I});o.push(y)}else h[c]=m}),o.length>0?Promise.all(o).then(()=>{Object.keys(u).forEach(c=>{u[c]=null}),t.images=h,i.resolve(t)}).catch(c=>{i.reject(c)}):(t.images=h,i.resolve(t))}else i.resolve(t);else i.reject(new Error(a||"\u89E3\u6790 SVGA \u6587\u4EF6\u5931\u8D25"));P.delete(e)}});class d{static getCachedVideoItem(e){return f.get(e)}static async loadUrl(e,s){const t=s?.cache!==!1;if(t&&f.has(e)){const i=f.get(e);return f.delete(e),f.set(e,i),i}if(T.has(e))return T.get(e);const a=(async()=>{try{const i=await U.loadUrl(e),r=await d.parseBuffer(i,{...s,movieDataId:e});return t&&(f.set(e,r),X()),r}catch(i){throw T.delete(e),i}finally{T.delete(e)}})();return T.set(e,a),a}static async loadFile(e,s){const t=await U.loadFile(e);return await d.parseBuffer(t,s)}static parseBuffer(e,s){const t=s?.useImageBitmap??!1,a=s?.cache!==!1,i=s?.movieDataId||"movie_direct_"+Math.random().toString(36).substring(2)+Date.now();return new Promise((r,o)=>{try{const u=b(),h=++$;P.set(h,{resolve:r,reject:o,useImageBitmap:t}),u.postMessage({type:l.PARSE,taskId:h,buffer:e,fileSize:e.byteLength,movieDataId:i,useImageBitmap:t,cache:a},[e])}catch(u){u instanceof Error?o(u):o(new Error("\u672A\u77E5\u9519\u8BEF"))}})}static async load(e,s){const t=s?.cache!==!1;if(t&&g.has(e)){const i=g.get(e);return g.delete(e),g.set(e,i),i}if(R.has(e))return R.get(e);const a=(async()=>{try{const i=await U.loadUrl(e),r=await d.parseBufferOffscreen(i,e,s);if(t&&(g.set(e,r),g.size>z)){const o=g.keys().next().value;o&&d.destroyOffscreenCache(o)}return r}catch(i){throw R.delete(e),i}finally{R.delete(e)}})();return R.set(e,a),a}static parseBufferOffscreen(e,s,t){const a=t?.cache!==!1;return new Promise((i,r)=>{try{const o=b(),u=++$;P.set(u,{resolve:i,reject:r}),o.postMessage({type:l.PARSE_OFFSCREEN,taskId:u,buffer:e,fileSize:e.byteLength,movieDataId:s,cache:a},[e])}catch(o){o instanceof Error?r(o):r(new Error("\u672A\u77E5\u9519\u8BEF"))}})}static destroyCache(e){const s=f.get(e);s&&s.images&&Object.keys(s.images).forEach(t=>{const a=s.images[t];a&&(typeof a.close=="function"?a.close():a instanceof HTMLImageElement&&(a.src="")),s.images[t]=null}),f.delete(e)}static clearCache(){Array.from(f.keys()).forEach(e=>{d.destroyCache(e)}),f.clear()}static destroyOffscreenCache(e,s=!0){g.delete(e);try{b().postMessage({type:l.RELEASE_CACHE,movieDataId:e,force:s})}catch(t){console.warn("[Parser] \u53D1\u9001\u624B\u52A8\u9500\u6BC1\u6D88\u606F\u5931\u8D25\uFF1A",t)}}static clearOffscreenCache(){g.clear();try{b().postMessage({type:l.RELEASE_CACHE,movieDataId:void 0,force:!0})}catch(e){console.warn("[Parser] \u53D1\u9001\u6E05\u7A7A\u6240\u6709\u79BB\u5C4F\u7F13\u5B58\u6D88\u606F\u5931\u8D25\uFF1A",e)}}static destroy(e){if(e==null){d.clearCache(),d.clearOffscreenCache();return}if(typeof e=="string"){d.destroyCache(e),d.destroyOffscreenCache(e);return}if(typeof e=="object"){const{url:s,mainThread:t,offscreen:a}=e,i=t!==void 0?t:a===void 0,r=a!==void 0?a:t===void 0;s?(i&&d.destroyCache(s),r&&d.destroyOffscreenCache(s)):(i&&d.clearCache(),r&&d.clearOffscreenCache())}}static setWorkerConfig(e){K(e)}}var q=Object.freeze({__proto__:null,Parser:d});class S{static instance;constructor(){}static getInstance(){return S.instance||(S.instance=new S),S.instance}drawShapes(e,s){for(const t of s){let a=null;if(t.type===0&&t.shape&&t.shape.d)a=new Path2D(t.shape.d);else if(t.type===1&&t.rect){const{x:i,y:r,width:o,height:u,cornerRadius:h}=t.rect;a=new Path2D,h>0?a.roundRect(i,r,o,u,h):a.rect(i,r,o,u)}else if(t.type===2&&t.ellipse){const{x:i,y:r,radiusX:o,radiusY:u}=t.ellipse;a=new Path2D,a.ellipse(i,r,o,u,0,0,2*Math.PI)}if(a&&t.styles){const{fill:i,stroke:r,strokeWidth:o,lineCap:u,lineJoin:h,miterLimit:c,lineDash:m}=t.styles;if(t.transform){e.save();const{a:y,b:v,c:F,d:C,tx:I,ty:D}=t.transform;e.transform(y,v,F,C,I,D)}i&&(e.fillStyle="rgba("+i.r*255+", "+i.g*255+", "+i.b*255+", "+i.a+")",e.fill(a)),r&&(e.strokeStyle="rgba("+r.r*255+", "+r.g*255+", "+r.b*255+", "+r.a+")",e.lineWidth=o||1,u&&(e.lineCap=u.toLowerCase()),h&&(e.lineJoin=h.toLowerCase()),c&&(e.miterLimit=c),m&&m.length>0?e.setLineDash(m):e.setLineDash([]),e.stroke(a)),t.transform&&e.restore()}}}}var Q=Object.freeze({__proto__:null,ShapeRenderer:S});export{d as Parser,J as Player,w as SVGA_EVENT_NAME,l as WORKER_ACTION,k as WORKER_RESPONSE_TYPE,K as setWorkerConfig};
|
package/dist/index.global.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var CustomSvga=function(e){"use strict";var t,s=typeof document<"u"?document.currentScript:null,a=((t=a||{}).INIT="init",t.VISIBILITY="visibility",t.SET_MOVIE="setMovie",t.SET_IMAGE="setImage",t.SET_DYNAMIC_TEXT="setDynamicText",t.DRAW_EXTERNAL_POSTER="drawExternalPoster",t.PLAY="play",t.STOP="stop",t.PAUSE="pause",t.STEP_TO_FRAME="stepToFrame",t.STEP_TO_PERCENTAGE="stepToPercentage",t.CLEAR="clear",t.CLEAR_DYNAMIC_OBJECTS="clearDynamicObjects",t.CLEAR_DYNAMIC_OBJECT="clearDynamicObject",t.DESTROY="destroy",t.PARSE="parse",t.PARSE_OFFSCREEN="parse_offscreen",t.RELEASE_CACHE="releaseCache",t),i=(e=>(e.SUCCESS="SUCCESS",e.ERROR="ERROR",e.EVENT="event",e))(i||{}),r=(e=>(e.READY="ready",e.ON_START="onStart",e.ON_STOP="onStop",e.ON_PAUSE="onPause",e.ON_PROCESS="onProcess",e.ON_LOOP_END="onLoopEnd",e.ON_REQUEST_MOVIE_DATA="onRequestMovieData",e))(r||{});let n=null,o=null;const c=new Map;let h=0,d={};const m=new Map;let l=null;function f(){if(!n){if(d.workerCreator)n=d.workerCreator();else if(d.workerUrl)n=new Worker(d.workerUrl);else{let e;try{e=typeof{url:s&&"SCRIPT"===s.tagName.toUpperCase()&&s.src||new URL("index.global.js",document.baseURI).href}<"u"&&(s&&"SCRIPT"===s.tagName.toUpperCase()&&s.src||new URL("index.global.js",document.baseURI).href)?new URL("./svga.worker.ts",s&&"SCRIPT"===s.tagName.toUpperCase()&&s.src||new URL("index.global.js",document.baseURI).href):"./svga.worker.ts"}catch{e="./svga.worker.ts"}n=new Worker(e,{type:"module"})}n.onmessage=e=>{const{type:t,id:s,name:a,args:n,taskId:o}=e.data;if(void 0!==o)return void(l&&l(e.data));const h=c.get(s);h&&t===i.EVENT&&(a===r.ON_START&&h.onStart?h.onStart():a===r.ON_STOP&&h.onStop?h.onStop():a===r.ON_PAUSE&&h.onPause?h.onPause():a===r.ON_LOOP_END&&h.onLoopEnd?h.onLoopEnd():a===r.ON_PROCESS&&h.onProcess?h.onProcess(n[0]):a===r.ON_REQUEST_MOVIE_DATA&&h.resendMovieData())}}return n}class p{id;canvas;observerIsVisible=!0;worker;onStart;onPause;onStop;onLoopEnd;onProcess;_dynamicKeys=new Set;_config;_shapeRendererInstance=null;_movieData=null;constructor(e,t){this.canvas=e,this.id="renderer_"+h++,this._config=Object.assign({loop:0,useIntersectionObserver:!0,useSharedRAF:!0,invisibleBehavior:"pause"},t),c.set(this.id,this),this.worker=f();const s=e.transferControlToOffscreen();this.worker.postMessage({type:a.INIT,id:this.id,canvas:s,config:this._config},[s]),!1!==this._config.useIntersectionObserver&&(!o&&typeof IntersectionObserver<"u"&&(o=new IntersectionObserver(e=>{e.forEach(e=>{Array.from(c.values()).filter(t=>t.canvas===e.target).forEach(t=>{t.observerIsVisible=e.isIntersecting,t.worker.postMessage({type:a.VISIBILITY,id:t.id,visible:t.observerIsVisible})})})})),o&&o.observe(this.canvas))}async resendMovieData(){if(this._movieData){const e=this._movieData.movieDataId||"movie_direct_"+Math.random().toString(36).substring(2)+Date.now(),t={},s=[];if(typeof createImageBitmap<"u"&&this._movieData.images)for(const[e,a]of Object.entries(this._movieData.images))if(a instanceof ImageBitmap)try{const i=await createImageBitmap(a);t[e]=i,s.push(i)}catch(e){console.warn("[离屏渲染器] 重新发送动画数据时克隆位图失败:",e)}const i={...this._movieData,images:t,imageBytes:void 0};m.set(this.id,e),this.worker.postMessage({type:a.SET_MOVIE,id:this.id,movieData:i,movieDataId:e},s)}}async setMovie(e){this._movieData=e;const t=e.movieDataId||"movie_direct_"+Math.random().toString(36).substring(2)+Date.now();m.set(this.id,t),this.worker.postMessage({type:a.SET_MOVIE,id:this.id,movieData:null,movieDataId:t})}async setImage(e,t){if(this._dynamicKeys.add(t),typeof createImageBitmap<"u")try{const s=await createImageBitmap(e);this.worker.postMessage({type:a.SET_IMAGE,id:this.id,key:t,image:s},[s])}catch(e){console.warn("[离屏渲染器] 设置动态图片时克隆位图对象失败:",e)}}setDynamicText(e,t){this._dynamicKeys.add(t),this.worker.postMessage({type:a.SET_DYNAMIC_TEXT,id:this.id,key:t,text:e})}setShapeRenderer(e){this._shapeRendererInstance=e}async drawExternalPoster(e){try{const t=await(await fetch(e)).blob(),s=await createImageBitmap(t);this.worker.postMessage({type:a.DRAW_EXTERNAL_POSTER,id:this.id,image:s},[s])}catch(e){console.warn("[离屏渲染器] 载入并生成静态海报海报失败:",e)}}play(e){this.worker.postMessage({type:a.PLAY,id:this.id,config:e})}stop(){this.worker.postMessage({type:a.STOP,id:this.id})}pause(){this.worker.postMessage({type:a.PAUSE,id:this.id})}stepToFrame(e,t=!1){this.worker.postMessage({type:a.STEP_TO_FRAME,id:this.id,frame:e,andPlay:t})}stepToPercentage(e,t){this.worker.postMessage({type:a.STEP_TO_PERCENTAGE,id:this.id,percentage:e,andPlay:t})}clear(){this.worker.postMessage({type:a.CLEAR,id:this.id})}clearDynamicObject(e){this._dynamicKeys.delete(e),this.worker.postMessage({type:a.CLEAR_DYNAMIC_OBJECT,id:this.id,key:e})}clearDynamicObjects(){this._dynamicKeys.clear(),this.worker.postMessage({type:a.CLEAR_DYNAMIC_OBJECTS,id:this.id})}getMemoryInfo(){if(!this._movieData)return{fileSize:0,imageMemory:0,dictionaryMemory:0,version:"",fps:0,frames:0,width:0,height:0,dynamicKeys:[],desc:"未加载任何动效"};let e=0;this._movieData.images&&Object.values(this._movieData.images).forEach(t=>{t&&t.width&&(e+=t.width*t.height*4)});const t=JSON.stringify({params:this._movieData.params,sprites:this._movieData.sprites}).length,s=this._movieData.fileSize||0,a=this._movieData.version||"",i=this._movieData.params.fps||20,r=this._movieData.params.frames||0,n=this._movieData.params.viewBoxWidth||0,o=this._movieData.params.viewBoxHeight||0,c=Array.from(this._dynamicKeys);return{fileSize:s,imageMemory:e,dictionaryMemory:t,version:a,fps:i,frames:r,width:n,height:o,dynamicKeys:c,desc:`源文件大小: ${(s/1024).toFixed(2)} KB | 预估显存(位图与结构): ${((e+t)/1024/1024).toFixed(2)} MB`}}destroy(){o&&o.unobserve(this.canvas),m.delete(this.id),c.delete(this.id),this.worker.postMessage({type:a.DESTROY,id:this.id})}}class g{static async loadUrl(e){const t=await fetch(e);if(!t.ok)throw new Error(`无法从 ${e} 加载 SVGA 文件: ${t.statusText}`);return await t.arrayBuffer()}static async loadFile(e){return new Promise((t,s)=>{const a=new FileReader;a.onload=()=>{a.result instanceof ArrayBuffer?t(a.result):s(new Error("无法读取文件的 ArrayBuffer 数据"))},a.onerror=()=>s(a.error),a.readAsArrayBuffer(e)})}}let y=0;const v=new Map,u=new Map,w=new Map,E=new Map,I=new Map;!function(e){l=e}(e=>{const{taskId:t,type:s,data:a,error:r}=e,n=v.get(t);if(n){const{useImageBitmap:e}=n;if(s===i.SUCCESS)if(a&&a.images&&!e){const e=[],t=a.images,s={};Object.keys(t).forEach(a=>{const i=t[a];if(i instanceof Uint8Array&&i.length>0){const t=new Promise(e=>{let t="image/png";255===i[0]&&216===i[1]?t="image/jpeg":71===i[0]&&73===i[1]&&70===i[2]?t="image/gif":82===i[0]&&73===i[1]&&70===i[2]&&70===i[3]&&(t="image/webp");const r=new Blob([i],{type:t}),n=URL.createObjectURL(r),o=new Image;o.onload=()=>{s[a]=o,URL.revokeObjectURL(n),e()},o.onerror=()=>{s[a]=o,URL.revokeObjectURL(n),e()},o.src=n});e.push(t)}else s[a]=i}),e.length>0?Promise.all(e).then(()=>{Object.keys(t).forEach(e=>{t[e]=null}),a.images=s,n.resolve(a)}).catch(e=>{n.reject(e)}):(a.images=s,n.resolve(a))}else n.resolve(a);else n.reject(new Error(r||"解析 SVGA 文件失败"));v.delete(t)}});class F{static getCachedVideoItem(e){return u.get(e)}static async loadUrl(e,t){const s=!1!==t?.cache;if(s&&u.has(e)){const t=u.get(e);return u.delete(e),u.set(e,t),t}if(w.has(e))return w.get(e);const a=(async()=>{try{const a=await g.loadUrl(e),i=await F.parseBuffer(a,{...t,movieDataId:e});return s&&(u.set(e,i),function(){if(u.size>20){const e=u.keys().next().value;e&&F.destroyCache(e)}}()),i}catch(t){throw w.delete(e),t}finally{w.delete(e)}})();return w.set(e,a),a}static async loadFile(e,t){const s=await g.loadFile(e);return await F.parseBuffer(s,t)}static parseBuffer(e,t){const s=t?.useImageBitmap??!1,i=!1!==t?.cache,r=t?.movieDataId||"movie_direct_"+Math.random().toString(36).substring(2)+Date.now();return new Promise((t,n)=>{try{const o=f(),c=++y;v.set(c,{resolve:t,reject:n,useImageBitmap:s}),o.postMessage({type:a.PARSE,taskId:c,buffer:e,fileSize:e.byteLength,movieDataId:r,useImageBitmap:s,cache:i},[e])}catch(e){e instanceof Error?n(e):n(new Error("未知错误"))}})}static async load(e,t){const s=!1!==t?.cache;if(s&&E.has(e)){const t=E.get(e);return E.delete(e),E.set(e,t),t}if(I.has(e))return I.get(e);const a=(async()=>{try{const a=await g.loadUrl(e),i=await F.parseBufferOffscreen(a,e,t);if(s&&(E.set(e,i),E.size>20)){const e=E.keys().next().value;e&&F.destroyOffscreenCache(e)}return i}catch(t){throw I.delete(e),t}finally{I.delete(e)}})();return I.set(e,a),a}static parseBufferOffscreen(e,t,s){const i=!1!==s?.cache;return new Promise((s,r)=>{try{const n=f(),o=++y;v.set(o,{resolve:s,reject:r}),n.postMessage({type:a.PARSE_OFFSCREEN,taskId:o,buffer:e,fileSize:e.byteLength,movieDataId:t,cache:i},[e])}catch(e){e instanceof Error?r(e):r(new Error("未知错误"))}})}static destroyCache(e){const t=u.get(e);t&&t.images&&Object.keys(t.images).forEach(e=>{const s=t.images[e];s&&("function"==typeof s.close?s.close():s instanceof HTMLImageElement&&(s.src="")),t.images[e]=null}),u.delete(e)}static clearCache(){Array.from(u.keys()).forEach(e=>{F.destroyCache(e)}),u.clear()}static destroyOffscreenCache(e,t=!0){E.delete(e);try{f().postMessage({type:a.RELEASE_CACHE,movieDataId:e,force:t})}catch(e){console.warn("[Parser] 发送手动销毁消息失败:",e)}}static clearOffscreenCache(){E.clear();try{f().postMessage({type:a.RELEASE_CACHE,movieDataId:void 0,force:!0})}catch(e){console.warn("[Parser] 发送清空所有离屏缓存消息失败:",e)}}static destroy(e){if(null==e)return F.clearCache(),void F.clearOffscreenCache();if("string"==typeof e)return F.destroyCache(e),void F.destroyOffscreenCache(e);if("object"==typeof e){const{url:t,mainThread:s,offscreen:a}=e,i=void 0!==s?s:void 0===a,r=void 0!==a?a:void 0===s;t?(i&&F.destroyCache(t),r&&F.destroyOffscreenCache(t)):(i&&F.clearCache(),r&&F.clearOffscreenCache())}}static setWorkerConfig(e){!function(e){d={...d,...e}}(e)}}var S=Object.freeze({__proto__:null,Parser:F});const b=()=>typeof globalThis.requestAnimationFrame<"u"?globalThis.requestAnimationFrame.bind(globalThis):e=>setTimeout(()=>e(performance.now()),16.666666666666668),T=()=>typeof globalThis.cancelAnimationFrame<"u"?globalThis.cancelAnimationFrame.bind(globalThis):e=>clearTimeout(e);class O{static instance;sharedTasks=new Set;sharedRafId=0;standaloneTasks=new Map;static getInstance(){return O.instance||(O.instance=new O),O.instance}add(e,t=!0){if(t)this.sharedTasks.add(e),1===this.sharedTasks.size&&0===this.sharedRafId&&this.startShared();else if(!this.standaloneTasks.has(e)){const t=s=>{try{e(s)}catch(e){console.error("[SVGA 定时器] 独立渲染任务执行异常:",e)}const a=b()(t);this.standaloneTasks.set(e,a)},s=b()(t);this.standaloneTasks.set(e,s)}}remove(e){if(this.sharedTasks.has(e)&&(this.sharedTasks.delete(e),0===this.sharedTasks.size&&this.stopShared()),this.standaloneTasks.has(e)){const t=this.standaloneTasks.get(e);t&&T()(t),this.standaloneTasks.delete(e)}}startShared(){const e=t=>{this.sharedTasks.forEach(e=>{try{e(t)}catch(e){console.error("[SVGA 定时器] 共享渲染任务执行异常:",e)}}),this.sharedTasks.size>0?this.sharedRafId=b()(e):this.sharedRafId=0};this.sharedRafId=b()(e)}stopShared(){0!==this.sharedRafId&&(T()(this.sharedRafId),this.sharedRafId=0)}}const D=O.getInstance(),_=new WeakMap;let C=null;class P{canvas;ctx;observerIsVisible=!0;movieData=null;isPlaying=!1;currentFrame=0;runtimeFps=20;totalFrames=0;shapeRendererInstance=null;lastTime=0;config;currentLoop=0;onStart;onPause;onStop;onLoopEnd;onProcess;dynamicElements={};startFrame=0;endFrame=0;frameCache=new Map;constructor(e,t){if(this.canvas=e,this.config=Object.assign({loop:0,useIntersectionObserver:!0,useSharedRAF:!0,useOffscreenCanvas:!1,invisibleBehavior:"pause"},t),this.ctx=e.getContext("2d"),!this.ctx)throw new Error("获取 2D 上下文失败");_.set(e,this),this.initObserver()}initObserver(){typeof IntersectionObserver<"u"&&!1!==this.config.useIntersectionObserver&&(this.observerIsVisible=!0,C||(C=new IntersectionObserver(e=>{e.forEach(e=>{const t=_.get(e.target);t&&(t.observerIsVisible=e.isIntersecting)})})),C.observe(this.canvas))}setMovie(e){this.frameCache.clear(),this.movieData=e,this.totalFrames=e.params.frames||1,this.canvas.width=e.params.viewBoxWidth||300,this.canvas.height=e.params.viewBoxHeight||300,this.startFrame=Math.max(0,this.config.startFrame??0),this.endFrame=Math.min(this.totalFrames-1,this.config.endFrame??this.totalFrames-1),this.endFrame<this.startFrame&&(this.endFrame=this.startFrame),this.currentFrame="backward"===this.config.direction?this.endFrame:this.startFrame,this.currentLoop=0}setImage(e,t){this.frameCache.clear(),this.dynamicElements[t]||(this.dynamicElements[t]={}),this.dynamicElements[t].image=e}setDynamicText(e,t){this.frameCache.clear(),this.dynamicElements[t]||(this.dynamicElements[t]={}),this.dynamicElements[t].text=e}clearDynamicObject(e){this.frameCache.clear(),this.dynamicElements[e]&&delete this.dynamicElements[e]}clearDynamicObjects(){this.frameCache.clear(),this.dynamicElements={}}async drawExternalPoster(e){return new Promise(t=>{const s=new Image;s.crossOrigin="anonymous",s.onload=()=>{if(this.isPlaying||this.movieData)return void t();const e=this.canvas.getBoundingClientRect();if(e.width>0&&e.height>0){const t=window.devicePixelRatio||1;this.canvas.width=e.width*t,this.canvas.height=e.height*t}else this.canvas.width=s.width,this.canvas.height=s.height;this.clearCanvas();const a=Math.min(this.canvas.width/s.width,this.canvas.height/s.height),i=s.width*a,r=s.height*a;this.ctx.drawImage(s,(this.canvas.width-i)/2,(this.canvas.height-r)/2,i,r),t()},s.onerror=()=>t(),s.src=e})}stepToFrame(e,t=!1){e<0||e>=this.totalFrames||(this.currentFrame=e,this.drawFrame(this.currentFrame),t?this.play():this.stop())}stepToPercentage(e,t=!1){const s=Math.floor(e*this.totalFrames);this.stepToFrame(s<this.totalFrames?s:this.totalFrames-1,t)}setShapeRenderer(e){this.shapeRendererInstance=e}getMemoryInfo(){if(!this.movieData)return{fileSize:0,imageMemory:0,dictionaryMemory:0,version:"",fps:0,frames:0,width:0,height:0,dynamicKeys:[],desc:"未加载任何动效"};let e=0;this.movieData.images&&Object.values(this.movieData.images).forEach(t=>{t&&"object"==typeof t&&"width"in t&&"height"in t&&(e+=t.width*t.height*4)});const t=JSON.stringify({params:this.movieData.params,sprites:this.movieData.sprites}).length,s=this.movieData.fileSize||0,a=this.movieData.version||"",i=this.movieData.params.fps||20,r=this.movieData.params.frames||0,n=this.movieData.params.viewBoxWidth||0,o=this.movieData.params.viewBoxHeight||0,c=Object.keys(this.dynamicElements);return{fileSize:s,imageMemory:e,dictionaryMemory:t,version:a,fps:i,frames:r,width:n,height:o,dynamicKeys:c,desc:`源文件大小: ${(s/1024).toFixed(2)} KB | 预估显存(位图与结构): ${((e+t)/1024/1024).toFixed(2)} MB`}}play(e){!this.movieData||this.isPlaying||(e&&(void 0!==e.fps&&(this.config.fps=e.fps),void 0!==e.loop&&(this.config.loop=e.loop,this.currentLoop=0),void 0!==e.fillMode&&(this.config.fillMode=e.fillMode),void 0!==e.startFrame&&(this.config.startFrame=e.startFrame),void 0!==e.endFrame&&(this.config.endFrame=e.endFrame),void 0!==e.useIntersectionObserver&&(this.config.useIntersectionObserver=e.useIntersectionObserver),void 0!==e.invisibleBehavior&&(this.config.invisibleBehavior=e.invisibleBehavior),void 0!==e.useSharedRAF&&(this.config.useSharedRAF=e.useSharedRAF),void 0!==e.cacheFrames&&(this.config.cacheFrames!==e.cacheFrames&&this.frameCache.clear(),this.config.cacheFrames=e.cacheFrames),void 0!==e.direction&&(this.config.direction=e.direction)),this.startFrame=Math.max(0,this.config.startFrame??0),this.endFrame=Math.min(this.totalFrames-1,this.config.endFrame??this.totalFrames-1),this.endFrame<this.startFrame&&(this.endFrame=this.startFrame),(this.currentFrame<this.startFrame||this.currentFrame>this.endFrame)&&(this.currentFrame="backward"===this.config.direction?this.endFrame:this.startFrame),this.runtimeFps=this.config.fps||this.movieData.params.fps||20,this.isPlaying=!0,this.onStart?.(),this.lastTime=performance.now(),D.add(this.loop,!1!==this.config.useSharedRAF))}stop(){this.isPlaying&&(this.isPlaying=!1,this.onStop?.()),D.remove(this.loop)}pause(){this.isPlaying&&(this.isPlaying=!1,this.onPause?.()),D.remove(this.loop)}reset(){this.stop(),this.currentFrame=0,this.currentLoop=0,this.clearCanvas(),this.movieData&&this.drawFrame(0)}clear(){this.stop(),this.clearCanvas(),this.frameCache.clear(),this.movieData=null,this.currentFrame=0,this.currentLoop=0}destroy(){this.clear(),this.clearDynamicObjects(),this.frameCache.clear(),C&&C.unobserve(this.canvas),_.delete(this.canvas),this.canvas=null,this.ctx=null,this.shapeRendererInstance=null}loop=e=>{if(!this.isPlaying)return;const t=1e3/this.runtimeFps,s=e-this.lastTime;if(s>=t){this.lastTime=e-s%t;const a=!this.observerIsVisible,i="pause"===this.config.invisibleBehavior||!this.config.invisibleBehavior;if(a&&i)return;if(a||this.drawFrame(this.currentFrame),this.onProcess?.(this.currentFrame),"backward"!==this.config.direction){if(this.currentFrame++,this.currentFrame>this.endFrame||this.currentFrame>=this.totalFrames){if(this.currentLoop++,this.onLoopEnd?.(),this.config.loop&&this.config.loop>0&&this.currentLoop>=this.config.loop)return this.stop(),void("backwards"===this.config.fillMode?this.stepToFrame(this.startFrame):"clear"===this.config.fillMode?this.clearCanvas():this.drawFrame(this.endFrame));this.currentFrame=this.startFrame}}else if(this.currentFrame--,this.currentFrame<this.startFrame){if(this.currentLoop++,this.onLoopEnd?.(),this.config.loop&&this.config.loop>0&&this.currentLoop>=this.config.loop)return this.stop(),void("backwards"===this.config.fillMode?this.stepToFrame(this.endFrame):"clear"===this.config.fillMode?this.clearCanvas():this.drawFrame(this.startFrame));this.currentFrame=this.endFrame}}};clearCanvas(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)}drawFrame(e){if(!this.movieData)return;if(this.config.cacheFrames&&this.frameCache.has(e)){const t=this.frameCache.get(e);return this.clearCanvas(),void this.ctx.drawImage(t,0,0)}this.clearCanvas();const{sprites:t,images:s}=this.movieData;for(const a of t){const t=a.frames?.[e];if(!t||0===t.alpha)continue;if(this.ctx.save(),this.ctx.globalAlpha=t.alpha,t.transform){const{a:e,b:s,c:a,d:i,tx:r,ty:n}=t.transform;this.ctx.transform(e,s,a,i,r,n)}if(t.clipPath){const e=new Path2D(t.clipPath);this.ctx.clip(e)}let i=null;if(a.imageKey){const e=this.dynamicElements[a.imageKey];e&&e.image?i=e.image:s&&s[a.imageKey]&&(i=s[a.imageKey])}const r=t.layout;if(i){let e=0,t=0;"width"in i&&(e=i.width),"height"in i&&(t=i.height),r?this.ctx.drawImage(i,r.x||0,r.y||0,Math.max(r.width,0)||e,Math.max(r.height,0)||t):this.ctx.drawImage(i,0,0)}if(a.imageKey&&this.dynamicElements[a.imageKey]&&this.dynamicElements[a.imageKey].text){const e=this.dynamicElements[a.imageKey].text,t=e.size||"14px",s=e.family||"Arial",i=e.color||"#000000",n=e.offset||{x:0,y:0},o="number"==typeof t?`${t}px ${s}`:`${t} ${s}`;this.ctx.font=o,this.ctx.fillStyle=i,this.ctx.textBaseline="middle",this.ctx.textAlign="center";let c=n.x,h=n.y;r&&(c+=r.x+r.width/2,h+=r.y+r.height/2),this.ctx.fillText(e.text,c,h)}t.shapes&&t.shapes.length>0&&this.shapeRendererInstance&&this.shapeRendererInstance.drawShapes(this.ctx,t.shapes),this.ctx.restore()}if(this.config.cacheFrames){const t=document.createElement("canvas");t.width=this.canvas.width,t.height=this.canvas.height,t.getContext("2d")?.drawImage(this.canvas,0,0),this.frameCache.set(e,t)}}}class R{static instance;constructor(){}static getInstance(){return R.instance||(R.instance=new R),R.instance}drawShapes(e,t){for(const s of t){let t=null;if(0===s.type&&s.shape&&s.shape.d)t=new Path2D(s.shape.d);else if(1===s.type&&s.rect){const{x:e,y:a,width:i,height:r,cornerRadius:n}=s.rect;t=new Path2D,n>0?t.roundRect(e,a,i,r,n):t.rect(e,a,i,r)}else if(2===s.type&&s.ellipse){const{x:e,y:a,radiusX:i,radiusY:r}=s.ellipse;t=new Path2D,t.ellipse(e,a,i,r,0,0,2*Math.PI)}if(t&&s.styles){const{fill:a,stroke:i,strokeWidth:r,lineCap:n,lineJoin:o,miterLimit:c,lineDash:h}=s.styles;if(s.transform){e.save();const{a:t,b:a,c:i,d:r,tx:n,ty:o}=s.transform;e.transform(t,a,i,r,n,o)}a&&(e.fillStyle="rgba("+255*a.r+", "+255*a.g+", "+255*a.b+", "+a.a+")",e.fill(t)),i&&(e.strokeStyle="rgba("+255*i.r+", "+255*i.g+", "+255*i.b+", "+i.a+")",e.lineWidth=r||1,n&&(e.lineCap=n.toLowerCase()),o&&(e.lineJoin=o.toLowerCase()),c&&(e.miterLimit=c),h&&h.length>0?e.setLineDash(h):e.setLineDash([]),e.stroke(t)),s.transform&&e.restore()}}}}var M=Object.freeze({__proto__:null,ShapeRenderer:R});return e.Parser=F,e.Player=class{renderer;constructor(e,t){let s;e instanceof HTMLDivElement?(s=document.createElement("canvas"),s.style.width="100%",s.style.height="100%",e.appendChild(s)):s=e,t?.useOffscreenCanvas&&"function"==typeof s.transferControlToOffscreen&&typeof Worker<"u"?this.renderer=new p(s,t):this.renderer=new P(s,t)}async setVideoItem(e){this.renderer.clear();const t=this.renderer instanceof p;if(t){if(e&&"object"==typeof e&&!e.isOffscreen&&(e.sprites||e.images))throw new Error("[SVGA 播放器严重错误] 当前已开启 Offscreen 离屏渲染优化!在离屏渲染模式下,严格禁止向播放器 setVideoItem 传递主线程的完整复杂 MovieData 数据(这会导致主线程二次反序列化与多份图像留存,使手机内存成倍暴增)。请改用为离屏模式专属解耦设计的加载方法【Parser.load(url)】获取仅含 ID 的轻量句柄,或者直接传入 String 类型的 URL 自适应离屏流。")}else if(e&&"object"==typeof e&&e.isOffscreen)throw new Error("[SVGA 播放器严重错误] 当前使用的是主线程传统渲染器,但却传入了子线程专用的离屏轻量化元数据句柄 (isOffscreen: true)!这将导致主线程没有任何可以用于绘制和反序列化的图像/精灵序列树信息。在普通渲染模式下,请使用主线程加载方法【Parser.loadUrl(url)】或【Parser.loadFile(file)】。");if("string"==typeof e){if(t)return void await this.renderer.setMovie({movieDataId:e});{const{Parser:t}=await Promise.resolve().then(function(){return S}),s=t.getCachedVideoItem(e)||await t.loadUrl(e);return void(s&&await this.renderer.setMovie(s))}}let s=!1;if(e&&e.sprites)for(const t of e.sprites){if(s)break;if(t.frames)for(const e of t.frames)if(e.shapes&&e.shapes.length>0){s=!0;break}}if(s){const{ShapeRenderer:e}=await Promise.resolve().then(function(){return M});this.renderer.setShapeRenderer(e.getInstance())}await this.renderer.setMovie(e)}play(e){this.renderer.play(e)}playRange(e,t,s){this.renderer.play(Object.assign({startFrame:e,endFrame:t},s))}pause(){this.renderer.pause()}stop(){this.renderer.stop()}onStart(e){this.renderer.onStart=e}onPause(e){this.renderer.onPause=e}onStop(e){this.renderer.onStop=e}onLoopEnd(e){this.renderer.onLoopEnd=e}onProcess(e){this.renderer.onProcess=e}stepToFrame(e,t=!1){this.renderer.stepToFrame(e,t)}stepToPercentage(e,t=!1){this.renderer.stepToPercentage(e,t)}async setImage(e,t){if("string"==typeof e){const s=new Image;s.crossOrigin="anonymous";const a=new Promise((e,t)=>{s.onload=()=>e(s),s.onerror=e=>t(e)});s.src=e;try{const e=await a;await this.renderer.setImage(e,t)}catch(t){console.warn(`[Player] 动态加载图片链接 ${e} 失败:`,t)}}else await this.renderer.setImage(e,t)}setText(e,t){"string"==typeof e?this.renderer.setDynamicText({text:e},t):this.renderer.setDynamicText(e,t)}clearDynamicObject(e){this.renderer.clearDynamicObject(e)}clearDynamicObjects(){this.renderer.clearDynamicObjects()}async renderPoster(e){await this.renderer.drawExternalPoster(e)}getMemoryInfo(){return this.renderer.getMemoryInfo()}clear(){this.renderer.clear()}destroy(){this.renderer.destroy()}},e}({});
|
|
1
|
+
var CustomSvga=function(e){"use strict";var t=typeof document<"u"?document.currentScript:null;const s=()=>typeof globalThis.requestAnimationFrame<"u"?globalThis.requestAnimationFrame.bind(globalThis):e=>setTimeout(()=>e(performance.now()),16.666666666666668),a=()=>typeof globalThis.cancelAnimationFrame<"u"?globalThis.cancelAnimationFrame.bind(globalThis):e=>clearTimeout(e);class i{static instance;sharedTasks=new Set;sharedRafId=0;standaloneTasks=new Map;static getInstance(){return i.instance||(i.instance=new i),i.instance}add(e,t=!0){if(t)this.sharedTasks.add(e),1===this.sharedTasks.size&&0===this.sharedRafId&&this.startShared();else if(!this.standaloneTasks.has(e)){const t=a=>{try{e(a)}catch(e){console.error("[SVGA 定时器] 独立渲染任务执行异常:",e)}const i=s()(t);this.standaloneTasks.set(e,i)},a=s()(t);this.standaloneTasks.set(e,a)}}remove(e){if(this.sharedTasks.has(e)&&(this.sharedTasks.delete(e),0===this.sharedTasks.size&&this.stopShared()),this.standaloneTasks.has(e)){const t=this.standaloneTasks.get(e);t&&a()(t),this.standaloneTasks.delete(e)}}startShared(){const e=t=>{this.sharedTasks.forEach(e=>{try{e(t)}catch(e){console.error("[SVGA 定时器] 共享渲染任务执行异常:",e)}}),this.sharedTasks.size>0?this.sharedRafId=s()(e):this.sharedRafId=0};this.sharedRafId=s()(e)}stopShared(){0!==this.sharedRafId&&(a()(this.sharedRafId),this.sharedRafId=0)}}const r=i.getInstance(),n=new WeakMap;let o=null;class c{canvas;ctx;observerIsVisible=!0;movieData=null;isPlaying=!1;currentFrame=0;runtimeFps=20;totalFrames=0;shapeRendererInstance=null;lastTime=0;config;currentLoop=0;onStart;onPause;onStop;onLoopEnd;onProcess;dynamicElements={};startFrame=0;endFrame=0;frameCache=new Map;constructor(e,t){if(this.canvas=e,this.config=Object.assign({loop:0,useIntersectionObserver:!0,useSharedRAF:!0,useOffscreenCanvas:!1,invisibleBehavior:"pause"},t),this.ctx=e.getContext("2d"),!this.ctx)throw new Error("获取 2D 上下文失败");n.set(e,this),this.initObserver()}initObserver(){typeof IntersectionObserver<"u"&&!1!==this.config.useIntersectionObserver&&(this.observerIsVisible=!0,o||(o=new IntersectionObserver(e=>{e.forEach(e=>{const t=n.get(e.target);t&&(t.observerIsVisible=e.isIntersecting)})})),o.observe(this.canvas))}setMovie(e){this.frameCache.clear(),this.movieData=e,this.totalFrames=e.params.frames||1,this.canvas.width=e.params.viewBoxWidth||300,this.canvas.height=e.params.viewBoxHeight||300,this.startFrame=Math.max(0,this.config.startFrame??0),this.endFrame=Math.min(this.totalFrames-1,this.config.endFrame??this.totalFrames-1),this.endFrame<this.startFrame&&(this.endFrame=this.startFrame),this.currentFrame="backward"===this.config.direction?this.endFrame:this.startFrame,this.currentLoop=0}setImage(e,t){this.frameCache.clear(),this.dynamicElements[t]||(this.dynamicElements[t]={}),this.dynamicElements[t].image=e}setDynamicText(e,t){this.frameCache.clear(),this.dynamicElements[t]||(this.dynamicElements[t]={}),this.dynamicElements[t].text=e}clearDynamicObject(e){this.frameCache.clear(),this.dynamicElements[e]&&delete this.dynamicElements[e]}clearDynamicObjects(){this.frameCache.clear(),this.dynamicElements={}}async drawExternalPoster(e){return new Promise(t=>{const s=new Image;s.crossOrigin="anonymous",s.onload=()=>{if(this.isPlaying||this.movieData)return void t();const e=this.canvas.getBoundingClientRect();if(e.width>0&&e.height>0){const t=window.devicePixelRatio||1;this.canvas.width=e.width*t,this.canvas.height=e.height*t}else this.canvas.width=s.width,this.canvas.height=s.height;this.clearCanvas();const a=Math.min(this.canvas.width/s.width,this.canvas.height/s.height),i=s.width*a,r=s.height*a;this.ctx.drawImage(s,(this.canvas.width-i)/2,(this.canvas.height-r)/2,i,r),t()},s.onerror=()=>t(),s.src=e})}stepToFrame(e,t=!1){e<0||e>=this.totalFrames||(this.currentFrame=e,this.drawFrame(this.currentFrame),t?this.play():this.stop())}stepToPercentage(e,t=!1){const s=Math.floor(e*this.totalFrames);this.stepToFrame(s<this.totalFrames?s:this.totalFrames-1,t)}setShapeRenderer(e){this.shapeRendererInstance=e}getMemoryInfo(){if(!this.movieData)return{fileSize:0,imageMemory:0,dictionaryMemory:0,version:"",fps:0,frames:0,width:0,height:0,dynamicKeys:[],desc:"未加载任何动效"};let e=0;this.movieData.images&&Object.values(this.movieData.images).forEach(t=>{t&&"object"==typeof t&&"width"in t&&"height"in t&&(e+=t.width*t.height*4)});const t=JSON.stringify({params:this.movieData.params,sprites:this.movieData.sprites}).length,s=this.movieData.fileSize||0,a=this.movieData.version||"",i=this.movieData.params.fps||20,r=this.movieData.params.frames||0,n=this.movieData.params.viewBoxWidth||0,o=this.movieData.params.viewBoxHeight||0,c=Object.keys(this.dynamicElements);return{fileSize:s,imageMemory:e,dictionaryMemory:t,version:a,fps:i,frames:r,width:n,height:o,dynamicKeys:c,desc:`源文件大小: ${(s/1024).toFixed(2)} KB | 预估显存(位图与结构): ${((e+t)/1024/1024).toFixed(2)} MB`}}play(e){!this.movieData||this.isPlaying||(e&&(void 0!==e.fps&&(this.config.fps=e.fps),void 0!==e.loop&&(this.config.loop=e.loop,this.currentLoop=0),void 0!==e.fillMode&&(this.config.fillMode=e.fillMode),void 0!==e.startFrame&&(this.config.startFrame=e.startFrame),void 0!==e.endFrame&&(this.config.endFrame=e.endFrame),void 0!==e.useIntersectionObserver&&(this.config.useIntersectionObserver=e.useIntersectionObserver),void 0!==e.invisibleBehavior&&(this.config.invisibleBehavior=e.invisibleBehavior),void 0!==e.useSharedRAF&&(this.config.useSharedRAF=e.useSharedRAF),void 0!==e.cacheFrames&&(this.config.cacheFrames!==e.cacheFrames&&this.frameCache.clear(),this.config.cacheFrames=e.cacheFrames),void 0!==e.direction&&(this.config.direction=e.direction)),this.startFrame=Math.max(0,this.config.startFrame??0),this.endFrame=Math.min(this.totalFrames-1,this.config.endFrame??this.totalFrames-1),this.endFrame<this.startFrame&&(this.endFrame=this.startFrame),(this.currentFrame<this.startFrame||this.currentFrame>this.endFrame)&&(this.currentFrame="backward"===this.config.direction?this.endFrame:this.startFrame),this.runtimeFps=this.config.fps||this.movieData.params.fps||20,this.isPlaying=!0,this.onStart?.(),this.lastTime=performance.now(),r.add(this.loop,!1!==this.config.useSharedRAF))}stop(){this.isPlaying&&(this.isPlaying=!1,this.onStop?.()),r.remove(this.loop)}pause(){this.isPlaying&&(this.isPlaying=!1,this.onPause?.()),r.remove(this.loop)}reset(){this.stop(),this.currentFrame=0,this.currentLoop=0,this.clearCanvas(),this.movieData&&this.drawFrame(0)}clear(){this.stop(),this.clearCanvas(),this.frameCache.clear(),this.movieData=null,this.currentFrame=0,this.currentLoop=0}destroy(){this.clear(),this.clearDynamicObjects(),this.frameCache.clear(),o&&o.unobserve(this.canvas),n.delete(this.canvas),this.canvas=null,this.ctx=null,this.shapeRendererInstance=null}loop=e=>{if(!this.isPlaying)return;const t=1e3/this.runtimeFps,s=e-this.lastTime;if(s>=t){this.lastTime=e-s%t;const a=!this.observerIsVisible,i="pause"===this.config.invisibleBehavior||!this.config.invisibleBehavior;if(a&&i)return;if(a||this.drawFrame(this.currentFrame),this.onProcess?.(this.currentFrame),"backward"!==this.config.direction){if(this.currentFrame++,this.currentFrame>this.endFrame||this.currentFrame>=this.totalFrames){if(this.currentLoop++,this.onLoopEnd?.(),this.config.loop&&this.config.loop>0&&this.currentLoop>=this.config.loop)return this.stop(),void("backwards"===this.config.fillMode?this.stepToFrame(this.startFrame):"clear"===this.config.fillMode?this.clearCanvas():this.drawFrame(this.endFrame));this.currentFrame=this.startFrame}}else if(this.currentFrame--,this.currentFrame<this.startFrame){if(this.currentLoop++,this.onLoopEnd?.(),this.config.loop&&this.config.loop>0&&this.currentLoop>=this.config.loop)return this.stop(),void("backwards"===this.config.fillMode?this.stepToFrame(this.endFrame):"clear"===this.config.fillMode?this.clearCanvas():this.drawFrame(this.startFrame));this.currentFrame=this.endFrame}}};clearCanvas(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)}drawFrame(e){if(!this.movieData)return;if(this.config.cacheFrames&&this.frameCache.has(e)){const t=this.frameCache.get(e);return this.clearCanvas(),void this.ctx.drawImage(t,0,0)}this.clearCanvas();const{sprites:t,images:s}=this.movieData;for(const a of t){const t=a.frames?.[e];if(!t||0===t.alpha)continue;if(this.ctx.save(),this.ctx.globalAlpha=t.alpha,t.transform){const{a:e,b:s,c:a,d:i,tx:r,ty:n}=t.transform;this.ctx.transform(e,s,a,i,r,n)}if(t.clipPath){const e=new Path2D(t.clipPath);this.ctx.clip(e)}let i=null;if(a.imageKey){const e=this.dynamicElements[a.imageKey];e&&e.image?i=e.image:s&&s[a.imageKey]&&(i=s[a.imageKey])}const r=t.layout;if(i){let e=0,t=0;"width"in i&&(e=i.width),"height"in i&&(t=i.height),r?this.ctx.drawImage(i,r.x||0,r.y||0,Math.max(r.width,0)||e,Math.max(r.height,0)||t):this.ctx.drawImage(i,0,0)}if(a.imageKey&&this.dynamicElements[a.imageKey]&&this.dynamicElements[a.imageKey].text){const e=this.dynamicElements[a.imageKey].text,t=e.size||"14px",s=e.family||"Arial",i=e.color||"#000000",n=e.offset||{x:0,y:0},o="number"==typeof t?`${t}px ${s}`:`${t} ${s}`;this.ctx.font=o,this.ctx.fillStyle=i,this.ctx.textBaseline="middle",this.ctx.textAlign="center";let c=n.x,h=n.y;r&&(c+=r.x+r.width/2,h+=r.y+r.height/2),this.ctx.fillText(e.text,c,h)}t.shapes&&t.shapes.length>0&&this.shapeRendererInstance&&this.shapeRendererInstance.drawShapes(this.ctx,t.shapes),this.ctx.restore()}if(this.config.cacheFrames){const t=document.createElement("canvas");t.width=this.canvas.width,t.height=this.canvas.height,t.getContext("2d")?.drawImage(this.canvas,0,0),this.frameCache.set(e,t)}}}var h,l=((h=l||{}).INIT="init",h.VISIBILITY="visibility",h.SET_MOVIE="setMovie",h.SET_IMAGE="setImage",h.SET_DYNAMIC_TEXT="setDynamicText",h.DRAW_EXTERNAL_POSTER="drawExternalPoster",h.PLAY="play",h.STOP="stop",h.PAUSE="pause",h.STEP_TO_FRAME="stepToFrame",h.STEP_TO_PERCENTAGE="stepToPercentage",h.CLEAR="clear",h.CLEAR_DYNAMIC_OBJECTS="clearDynamicObjects",h.CLEAR_DYNAMIC_OBJECT="clearDynamicObject",h.DESTROY="destroy",h.PARSE="parse",h.PARSE_OFFSCREEN="parse_offscreen",h.RELEASE_CACHE="releaseCache",h),d=(e=>(e.SUCCESS="SUCCESS",e.ERROR="ERROR",e.EVENT="event",e))(d||{}),m=(e=>(e.READY="ready",e.ON_START="onStart",e.ON_STOP="onStop",e.ON_PAUSE="onPause",e.ON_PROCESS="onProcess",e.ON_LOOP_END="onLoopEnd",e.ON_REQUEST_MOVIE_DATA="onRequestMovieData",e))(m||{});let f=null,p=null;const g=new Map;let y=0,v={};function u(e){v={...v,...e}}const w=new Map;let E=null;function I(){if(!f){if(v.workerInstance)f=v.workerInstance;else if(v.workerCreator)f=v.workerCreator();else if(v.workerString){const e=new Blob([v.workerString],{type:"application/javascript"}),t=URL.createObjectURL(e);f=new Worker(t)}else if(v.workerUrl){const e=v.workerUrl;if(!e.startsWith(window.location.origin)&&/^(https?:)?\/\//.test(e)){const t=`importScripts(${JSON.stringify(e)});`,s=new Blob([t],{type:"application/javascript"}),a=URL.createObjectURL(s);f=new Worker(a)}else f=new Worker(e)}else{let e;try{if(typeof{url:t&&"SCRIPT"===t.tagName.toUpperCase()&&t.src||new URL("index.global.js",document.baseURI).href}<"u"&&(t&&"SCRIPT"===t.tagName.toUpperCase()&&t.src||new URL("index.global.js",document.baseURI).href)){const s=typeof{url:t&&"SCRIPT"===t.tagName.toUpperCase()&&t.src||new URL("index.global.js",document.baseURI).href}<"u"&&void 0,a=typeof globalThis<"u"?globalThis.process:void 0;e=(s?(void 0).DEV:typeof a<"u"&&a.env&&"production"!==a.env.NODE_ENV)?new URL("./svga.worker.ts",t&&"SCRIPT"===t.tagName.toUpperCase()&&t.src||new URL("index.global.js",document.baseURI).href):new URL("./svga.worker.js",t&&"SCRIPT"===t.tagName.toUpperCase()&&t.src||new URL("index.global.js",document.baseURI).href)}else e="./svga.worker.js"}catch{e="./svga.worker.js"}f=new Worker(e,{type:"module"})}f.onmessage=e=>{const{type:t,id:s,name:a,args:i,taskId:r}=e.data;if(void 0!==r)return void(E&&E(e.data));const n=g.get(s);n&&t===d.EVENT&&(a===m.ON_START&&n.onStart?n.onStart():a===m.ON_STOP&&n.onStop?n.onStop():a===m.ON_PAUSE&&n.onPause?n.onPause():a===m.ON_LOOP_END&&n.onLoopEnd?n.onLoopEnd():a===m.ON_PROCESS&&n.onProcess?n.onProcess(i[0]):a===m.ON_REQUEST_MOVIE_DATA&&n.resendMovieData())}}return f}class S{id;canvas;observerIsVisible=!0;worker;onStart;onPause;onStop;onLoopEnd;onProcess;_dynamicKeys=new Set;_config;_shapeRendererInstance=null;_movieData=null;constructor(e,t){this.canvas=e,this.id="renderer_"+y++,this._config=Object.assign({loop:0,useIntersectionObserver:!0,useSharedRAF:!0,invisibleBehavior:"pause"},t),g.set(this.id,this),this.worker=I();const s=e.transferControlToOffscreen();this.worker.postMessage({type:l.INIT,id:this.id,canvas:s,config:this._config},[s]),!1!==this._config.useIntersectionObserver&&(!p&&typeof IntersectionObserver<"u"&&(p=new IntersectionObserver(e=>{e.forEach(e=>{Array.from(g.values()).filter(t=>t.canvas===e.target).forEach(t=>{t.observerIsVisible=e.isIntersecting,t.worker.postMessage({type:l.VISIBILITY,id:t.id,visible:t.observerIsVisible})})})})),p&&p.observe(this.canvas))}async resendMovieData(){if(this._movieData){const e=this._movieData.movieDataId||"movie_direct_"+Math.random().toString(36).substring(2)+Date.now(),t={},s=[];if(typeof createImageBitmap<"u"&&this._movieData.images)for(const[e,a]of Object.entries(this._movieData.images))if(a instanceof ImageBitmap)try{const i=await createImageBitmap(a);t[e]=i,s.push(i)}catch(e){console.warn("[离屏渲染器] 重新发送动画数据时克隆位图失败:",e)}const a={...this._movieData,images:t,imageBytes:void 0};w.set(this.id,e),this.worker.postMessage({type:l.SET_MOVIE,id:this.id,movieData:a,movieDataId:e},s)}}async setMovie(e){this._movieData=e;const t=e.movieDataId||"movie_direct_"+Math.random().toString(36).substring(2)+Date.now();w.set(this.id,t),this.worker.postMessage({type:l.SET_MOVIE,id:this.id,movieData:null,movieDataId:t})}async setImage(e,t){if(this._dynamicKeys.add(t),typeof createImageBitmap<"u")try{const s=await createImageBitmap(e);this.worker.postMessage({type:l.SET_IMAGE,id:this.id,key:t,image:s},[s])}catch(e){console.warn("[离屏渲染器] 设置动态图片时克隆位图对象失败:",e)}}setDynamicText(e,t){this._dynamicKeys.add(t),this.worker.postMessage({type:l.SET_DYNAMIC_TEXT,id:this.id,key:t,text:e})}setShapeRenderer(e){this._shapeRendererInstance=e}async drawExternalPoster(e){try{const t=await(await fetch(e)).blob(),s=await createImageBitmap(t);this.worker.postMessage({type:l.DRAW_EXTERNAL_POSTER,id:this.id,image:s},[s])}catch(e){console.warn("[离屏渲染器] 载入并生成静态海报海报失败:",e)}}play(e){this.worker.postMessage({type:l.PLAY,id:this.id,config:e})}stop(){this.worker.postMessage({type:l.STOP,id:this.id})}pause(){this.worker.postMessage({type:l.PAUSE,id:this.id})}stepToFrame(e,t=!1){this.worker.postMessage({type:l.STEP_TO_FRAME,id:this.id,frame:e,andPlay:t})}stepToPercentage(e,t){this.worker.postMessage({type:l.STEP_TO_PERCENTAGE,id:this.id,percentage:e,andPlay:t})}clear(){this.worker.postMessage({type:l.CLEAR,id:this.id})}clearDynamicObject(e){this._dynamicKeys.delete(e),this.worker.postMessage({type:l.CLEAR_DYNAMIC_OBJECT,id:this.id,key:e})}clearDynamicObjects(){this._dynamicKeys.clear(),this.worker.postMessage({type:l.CLEAR_DYNAMIC_OBJECTS,id:this.id})}getMemoryInfo(){if(!this._movieData)return{fileSize:0,imageMemory:0,dictionaryMemory:0,version:"",fps:0,frames:0,width:0,height:0,dynamicKeys:[],desc:"未加载任何动效"};let e=0;this._movieData.images&&Object.values(this._movieData.images).forEach(t=>{t&&t.width&&(e+=t.width*t.height*4)});const t=JSON.stringify({params:this._movieData.params,sprites:this._movieData.sprites}).length,s=this._movieData.fileSize||0,a=this._movieData.version||"",i=this._movieData.params.fps||20,r=this._movieData.params.frames||0,n=this._movieData.params.viewBoxWidth||0,o=this._movieData.params.viewBoxHeight||0,c=Array.from(this._dynamicKeys);return{fileSize:s,imageMemory:e,dictionaryMemory:t,version:a,fps:i,frames:r,width:n,height:o,dynamicKeys:c,desc:`源文件大小: ${(s/1024).toFixed(2)} KB | 预估显存(位图与结构): ${((e+t)/1024/1024).toFixed(2)} MB`}}destroy(){p&&p.unobserve(this.canvas),w.delete(this.id),g.delete(this.id),this.worker.postMessage({type:l.DESTROY,id:this.id})}}class b{static async loadUrl(e){const t=await fetch(e);if(!t.ok)throw new Error(`无法从 ${e} 加载 SVGA 文件: ${t.statusText}`);return await t.arrayBuffer()}static async loadFile(e){return new Promise((t,s)=>{const a=new FileReader;a.onload=()=>{a.result instanceof ArrayBuffer?t(a.result):s(new Error("无法读取文件的 ArrayBuffer 数据"))},a.onerror=()=>s(a.error),a.readAsArrayBuffer(e)})}}let F=0;const T=new Map,O=new Map,R=new Map,_=new Map,D=new Map;!function(e){E=e}(e=>{const{taskId:t,type:s,data:a,error:i}=e,r=T.get(t);if(r){const{useImageBitmap:e}=r;if(s===d.SUCCESS)if(a&&a.images&&!e){const e=[],t=a.images,s={};Object.keys(t).forEach(a=>{const i=t[a];if(i instanceof Uint8Array&&i.length>0){const t=new Promise(e=>{let t="image/png";255===i[0]&&216===i[1]?t="image/jpeg":71===i[0]&&73===i[1]&&70===i[2]?t="image/gif":82===i[0]&&73===i[1]&&70===i[2]&&70===i[3]&&(t="image/webp");const r=new Blob([i],{type:t}),n=URL.createObjectURL(r),o=new Image;o.onload=()=>{s[a]=o,URL.revokeObjectURL(n),e()},o.onerror=()=>{s[a]=o,URL.revokeObjectURL(n),e()},o.src=n});e.push(t)}else s[a]=i}),e.length>0?Promise.all(e).then(()=>{Object.keys(t).forEach(e=>{t[e]=null}),a.images=s,r.resolve(a)}).catch(e=>{r.reject(e)}):(a.images=s,r.resolve(a))}else r.resolve(a);else r.reject(new Error(i||"解析 SVGA 文件失败"));T.delete(t)}});class C{static getCachedVideoItem(e){return O.get(e)}static async loadUrl(e,t){const s=!1!==t?.cache;if(s&&O.has(e)){const t=O.get(e);return O.delete(e),O.set(e,t),t}if(R.has(e))return R.get(e);const a=(async()=>{try{const a=await b.loadUrl(e),i=await C.parseBuffer(a,{...t,movieDataId:e});return s&&(O.set(e,i),function(){if(O.size>20){const e=O.keys().next().value;e&&C.destroyCache(e)}}()),i}catch(t){throw R.delete(e),t}finally{R.delete(e)}})();return R.set(e,a),a}static async loadFile(e,t){const s=await b.loadFile(e);return await C.parseBuffer(s,t)}static parseBuffer(e,t){const s=t?.useImageBitmap??!1,a=!1!==t?.cache,i=t?.movieDataId||"movie_direct_"+Math.random().toString(36).substring(2)+Date.now();return new Promise((t,r)=>{try{const n=I(),o=++F;T.set(o,{resolve:t,reject:r,useImageBitmap:s}),n.postMessage({type:l.PARSE,taskId:o,buffer:e,fileSize:e.byteLength,movieDataId:i,useImageBitmap:s,cache:a},[e])}catch(e){e instanceof Error?r(e):r(new Error("未知错误"))}})}static async load(e,t){const s=!1!==t?.cache;if(s&&_.has(e)){const t=_.get(e);return _.delete(e),_.set(e,t),t}if(D.has(e))return D.get(e);const a=(async()=>{try{const a=await b.loadUrl(e),i=await C.parseBufferOffscreen(a,e,t);if(s&&(_.set(e,i),_.size>20)){const e=_.keys().next().value;e&&C.destroyOffscreenCache(e)}return i}catch(t){throw D.delete(e),t}finally{D.delete(e)}})();return D.set(e,a),a}static parseBufferOffscreen(e,t,s){const a=!1!==s?.cache;return new Promise((s,i)=>{try{const r=I(),n=++F;T.set(n,{resolve:s,reject:i}),r.postMessage({type:l.PARSE_OFFSCREEN,taskId:n,buffer:e,fileSize:e.byteLength,movieDataId:t,cache:a},[e])}catch(e){e instanceof Error?i(e):i(new Error("未知错误"))}})}static destroyCache(e){const t=O.get(e);t&&t.images&&Object.keys(t.images).forEach(e=>{const s=t.images[e];s&&("function"==typeof s.close?s.close():s instanceof HTMLImageElement&&(s.src="")),t.images[e]=null}),O.delete(e)}static clearCache(){Array.from(O.keys()).forEach(e=>{C.destroyCache(e)}),O.clear()}static destroyOffscreenCache(e,t=!0){_.delete(e);try{I().postMessage({type:l.RELEASE_CACHE,movieDataId:e,force:t})}catch(e){console.warn("[Parser] 发送手动销毁消息失败:",e)}}static clearOffscreenCache(){_.clear();try{I().postMessage({type:l.RELEASE_CACHE,movieDataId:void 0,force:!0})}catch(e){console.warn("[Parser] 发送清空所有离屏缓存消息失败:",e)}}static destroy(e){if(null==e)return C.clearCache(),void C.clearOffscreenCache();if("string"==typeof e)return C.destroyCache(e),void C.destroyOffscreenCache(e);if("object"==typeof e){const{url:t,mainThread:s,offscreen:a}=e,i=void 0!==s?s:void 0===a,r=void 0!==a?a:void 0===s;t?(i&&C.destroyCache(t),r&&C.destroyOffscreenCache(t)):(i&&C.clearCache(),r&&C.clearOffscreenCache())}}static setWorkerConfig(e){u(e)}}var P=Object.freeze({__proto__:null,Parser:C});class M{static instance;constructor(){}static getInstance(){return M.instance||(M.instance=new M),M.instance}drawShapes(e,t){for(const s of t){let t=null;if(0===s.type&&s.shape&&s.shape.d)t=new Path2D(s.shape.d);else if(1===s.type&&s.rect){const{x:e,y:a,width:i,height:r,cornerRadius:n}=s.rect;t=new Path2D,n>0?t.roundRect(e,a,i,r,n):t.rect(e,a,i,r)}else if(2===s.type&&s.ellipse){const{x:e,y:a,radiusX:i,radiusY:r}=s.ellipse;t=new Path2D,t.ellipse(e,a,i,r,0,0,2*Math.PI)}if(t&&s.styles){const{fill:a,stroke:i,strokeWidth:r,lineCap:n,lineJoin:o,miterLimit:c,lineDash:h}=s.styles;if(s.transform){e.save();const{a:t,b:a,c:i,d:r,tx:n,ty:o}=s.transform;e.transform(t,a,i,r,n,o)}a&&(e.fillStyle="rgba("+255*a.r+", "+255*a.g+", "+255*a.b+", "+a.a+")",e.fill(t)),i&&(e.strokeStyle="rgba("+255*i.r+", "+255*i.g+", "+255*i.b+", "+i.a+")",e.lineWidth=r||1,n&&(e.lineCap=n.toLowerCase()),o&&(e.lineJoin=o.toLowerCase()),c&&(e.miterLimit=c),h&&h.length>0?e.setLineDash(h):e.setLineDash([]),e.stroke(t)),s.transform&&e.restore()}}}}var k=Object.freeze({__proto__:null,ShapeRenderer:M});return e.Parser=C,e.Player=class{renderer;constructor(e,t){let s;e instanceof HTMLDivElement?(s=document.createElement("canvas"),s.style.width="100%",s.style.height="100%",e.appendChild(s)):s=e,t?.useOffscreenCanvas&&"function"==typeof s.transferControlToOffscreen&&typeof Worker<"u"?this.renderer=new S(s,t):this.renderer=new c(s,t)}async setVideoItem(e){this.renderer.clear();const t=this.renderer instanceof S;if(t){if(e&&"object"==typeof e&&!e.isOffscreen&&(e.sprites||e.images))throw new Error("[SVGA 播放器严重错误] 当前已开启 Offscreen 离屏渲染优化!在离屏渲染模式下,严格禁止向播放器 setVideoItem 传递主线程的完整复杂 MovieData 数据(这会导致主线程二次反序列化与多份图像留存,使手机内存成倍暴增)。请改用为离屏模式专属解耦设计的加载方法【Parser.load(url)】获取仅含 ID 的轻量句柄,或者直接传入 String 类型的 URL 自适应离屏流。")}else if(e&&"object"==typeof e&&e.isOffscreen)throw new Error("[SVGA 播放器严重错误] 当前使用的是主线程传统渲染器,但却传入了子线程专用的离屏轻量化元数据句柄 (isOffscreen: true)!这将导致主线程没有任何可以用于绘制和反序列化的图像/精灵序列树信息。在普通渲染模式下,请使用主线程加载方法【Parser.loadUrl(url)】或【Parser.loadFile(file)】。");if("string"==typeof e){if(t)return void await this.renderer.setMovie({movieDataId:e});{const{Parser:t}=await Promise.resolve().then(function(){return P}),s=t.getCachedVideoItem(e)||await t.loadUrl(e);return void(s&&await this.renderer.setMovie(s))}}let s=!1;if(e&&e.sprites)for(const t of e.sprites){if(s)break;if(t.frames)for(const e of t.frames)if(e.shapes&&e.shapes.length>0){s=!0;break}}if(s){const{ShapeRenderer:e}=await Promise.resolve().then(function(){return k});this.renderer.setShapeRenderer(e.getInstance())}await this.renderer.setMovie(e)}play(e){this.renderer.play(e)}playRange(e,t,s){this.renderer.play(Object.assign({startFrame:e,endFrame:t},s))}pause(){this.renderer.pause()}stop(){this.renderer.stop()}onStart(e){this.renderer.onStart=e}onPause(e){this.renderer.onPause=e}onStop(e){this.renderer.onStop=e}onLoopEnd(e){this.renderer.onLoopEnd=e}onProcess(e){this.renderer.onProcess=e}stepToFrame(e,t=!1){this.renderer.stepToFrame(e,t)}stepToPercentage(e,t=!1){this.renderer.stepToPercentage(e,t)}async setImage(e,t){if("string"==typeof e){const s=new Image;s.crossOrigin="anonymous";const a=new Promise((e,t)=>{s.onload=()=>e(s),s.onerror=e=>t(e)});s.src=e;try{const e=await a;await this.renderer.setImage(e,t)}catch(t){console.warn(`[Player] 动态加载图片链接 ${e} 失败:`,t)}}else await this.renderer.setImage(e,t)}setText(e,t){"string"==typeof e?this.renderer.setDynamicText({text:e},t):this.renderer.setDynamicText(e,t)}clearDynamicObject(e){this.renderer.clearDynamicObject(e)}clearDynamicObjects(){this.renderer.clearDynamicObjects()}async renderPoster(e){await this.renderer.drawExternalPoster(e)}getMemoryInfo(){return this.renderer.getMemoryInfo()}clear(){this.renderer.clear()}destroy(){this.renderer.destroy()}},e.SVGA_EVENT_NAME=m,e.WORKER_ACTION=l,e.WORKER_RESPONSE_TYPE=d,e.setWorkerConfig=u,e}({});
|