From 99a4538f1e8a0928fae1de0754f1bddd685e265d Mon Sep 17 00:00:00 2001 From: ienaga Date: Mon, 22 Jul 2024 18:02:29 +0900 Subject: [PATCH 001/343] =?UTF-8?q?#154=20Vite=E3=81=B8=E3=81=AE=E7=A7=BB?= =?UTF-8?q?=E8=A1=8C=E6=BA=96=E5=82=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.json | 18 +- .gitignore | 1 - .npmignore | 8 +- babel.config.js | 15 - jest.config.js | 13 - jest.setup.js | 481 ---- jsdoc.conf.js | 40 - next2d.js | 1 - package-lock.json | 3573 ++++++++++++++++++++++++ package.json | 49 +- packages/core/package.json | 14 +- packages/core/src/Player.ts | 14 +- packages/display/package.json | 10 +- packages/events/package.json | 10 +- packages/events/src/EventDispatcher.ts | 41 +- packages/filters/package.json | 10 +- packages/geom/package.json | 10 +- packages/interface/package.json | 10 +- packages/media/package.json | 10 +- packages/media/src/Video.ts | 67 +- packages/net/package.json | 10 +- packages/share/package.json | 14 +- packages/text/package.json | 10 +- packages/ui/package.json | 10 +- packages/util/package.json | 10 +- packages/util/src/Util.ts | 1 + packages/webgl/package.json | 10 +- src/index.js | 29 + tsconfig.json | 31 +- vite.config.ts | 34 + webpack.config.js | 131 - 31 files changed, 3788 insertions(+), 897 deletions(-) delete mode 100644 babel.config.js delete mode 100644 jest.config.js delete mode 100644 jest.setup.js delete mode 100644 jsdoc.conf.js delete mode 100644 next2d.js create mode 100644 package-lock.json create mode 100644 src/index.js create mode 100644 vite.config.ts delete mode 100644 webpack.config.js diff --git a/.eslintrc.json b/.eslintrc.json index e1cb6f11..cfae85aa 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,14 +1,27 @@ { "env": { - "es6": true + "browser": true, + "es2021": true }, "parserOptions": { "sourceType": "module", - "ecmaVersion": 2017 + "ecmaVersion": "latest" }, "extends": "plugin:@typescript-eslint/eslint-recommended", "parser": "@typescript-eslint/parser", + "plugins": ["unused-imports"], "rules": { + "no-unused-vars": "off", // or "@typescript-eslint/no-unused-vars": "off", + "unused-imports/no-unused-imports": "error", + "unused-imports/no-unused-vars": [ + "warn", + { + "vars": "all", + "varsIgnorePattern": "^_", + "args": "after-used", + "argsIgnorePattern": "^_" + } + ], "no-var": "error", "semi": ["error", "always", { "omitLastInOneLineBlock": true }], "block-spacing": "error", @@ -26,7 +39,6 @@ "arrow-spacing": "error", "no-undef": "off", "comma-dangle": "warn", - "no-unused-vars": ["error", { "vars": "local", "args": "all" }], "no-use-before-define": "error", "no-const-assign": "error", "space-before-blocks": "error", diff --git a/.gitignore b/.gitignore index 880317ba..ebc9334e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ json dist coverage *.html -package-lock.json .DS_Store .idea Thumbs.db \ No newline at end of file diff --git a/.npmignore b/.npmignore index 927fc5e6..e469565b 100644 --- a/.npmignore +++ b/.npmignore @@ -9,10 +9,6 @@ node_modules src DOCS.md DEVELOP.md -jest.config.js -jest.setup.js -webpack.config.js -babel.config.js -jsdoc.conf.js tsconfig.eslint.json -next2d.js \ No newline at end of file +next2d.js +vite.config.ts \ No newline at end of file diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index 72bf3f7d..00000000 --- a/babel.config.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - "presets": [ - [ - "@babel/preset-env", - { - "targets": { - "node": "current" - } - } - ] - ], - "plugins": [ - "@babel/plugin-transform-modules-commonjs" - ] -}; \ No newline at end of file diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 20f8ace7..00000000 --- a/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/** @type {import("ts-jest/dist/types").InitialOptionsTsJest} */ -module.exports = { - "preset": "ts-jest", - "setupFilesAfterEnv": ["./jest.setup.js"], - "transformIgnorePatterns": [ - "/node_modules/(?!(next2d|@next2d))" - ], - "transform": { - "\\.jsx?$": "babel-jest", - "^.+\\.(ts|tsx)$": "ts-jest" - }, - "testEnvironment": "node" -}; diff --git a/jest.setup.js b/jest.setup.js deleted file mode 100644 index cc1b9c09..00000000 --- a/jest.setup.js +++ /dev/null @@ -1,481 +0,0 @@ -globalThis.$windowEventMap = new Map(); -globalThis.window = { - "document": { - "getElementById": (id) => - { - return globalThis.$elements.has(id) - ? globalThis.$elements.get(id) - : null; - }, - "createElement": () => - { - const attribute = new Map(); - return { - "getAttribute": (name) => - { - return attribute.has(name) - ? attribute.get(name) - : null; - }, - "setAttribute": (name, value) => - { - attribute.set(name, value); - }, - "insertBefore": (element) => - { - if (element.id) { - globalThis.$elements.set(element.id, element); - } - }, - "getContext": () => - { - return { - "measureText": () => { - return { - "width": 0 - }; - } - }; - }, - "insertAdjacentHTML": () => - { - return undefined; - }, - "childNodes": [], - "children": [], - "style": {}, - "addEventListener": () => - { - return undefined; - } - }; - } - }, - "devicePixelRatio": 2, - "addEventListener": (type, callback) => - { - globalThis.$windowEventMap.set(type, callback); - }, - "next2d": { - "display": { - "MovieClip": class MovieClip - { - constructor() - { - this.name = ""; - this.namespace = "next2d.display.MovieClip"; - } - - _$sync () - { - return undefined; - } - - _$getChildren () - { - return undefined; - } - }, - "Loader": class Loader - { - constructor () - { - this.event = new Map(); - } - - get contentLoaderInfo () - { - return { - "addEventListener": (name, callback) => - { - this.event.set(name, callback); - } - }; - } - - loadImage () - { - this.event.get("complete")({ - "currentTarget": { - "content": { - "_$loaderInfo": { - "_$data": { - "symbols": new Map([["app", "app"]]) - } - }, - "text": "NoCode Tool image content" - } - } - }); - } - - load () - { - this.event.get("complete")({ - "currentTarget": { - "content": { - "_$loaderInfo": { - "_$data": { - "symbols": new Map([["app", "app"]]) - } - }, - "text": "NoCode Tool content" - } - } - }); - } - }, - "Shape": class Shape - { - get graphics () - { - return this; - } - - beginBitmapFill () - { - return this; - } - - beginFill () - { - return this; - } - - drawRect () - { - return this; - } - - endFill () - { - return this; - } - }, - "BitmapData": class BitmapData - { - draw (source, matrix, color_transform, canvas = {}, callback) - { - callback(canvas); - } - }, - "Sprite": class Sprite - { - addChild (display_object) - { - return display_object; - } - - get graphics () - { - return this; - } - - beginFill () - { - return this; - } - - drawRect () - { - return this; - } - - endFill () - { - return this; - } - } - }, - "player": { - "cacheStore": { - "removeCache": () => - { - return undefined; - }, - "setRemoveTimer": () => - { - return undefined; - } - }, - "base": "", - "broadcastEvents": new Map(), - "_$actions": [] - } - } -}; - -globalThis.next2d = { - "createRootMovieClip": function () - { - const object = { - "_$created": true, - "_$createWorkerInstance": () => - { - return undefined; - }, - "stage": { - "canvasWidth": 100, - "canvasHeight": 100, - "_$player": { - "_$matrix": [1,0,0,1,10,10] - } - }, - "addChild": (child) => - { - return child; - }, - "numChildren": 1, - "removeChild": (number) => - { - object.numChildren = number; - }, - "getChildAt": () => - { - return 0; - } - }; - - return object; - }, - "display": { - "MovieClip": class MovieClip - { - constructor() - { - this.name = ""; - this.namespace = "next2d.display.MovieClip"; - } - - _$sync () - { - return undefined; - } - - _$getChildren () - { - return undefined; - } - }, - "Loader": class Loader - { - constructor () - { - this.event = new Map(); - } - - get contentLoaderInfo () - { - return { - "addEventListener": (name, callback) => - { - this.event.set(name, callback); - } - }; - } - - loadImage () - { - this.event.get("complete")({ - "currentTarget": { - "content": { - "_$loaderInfo": { - "_$data": { - "symbols": new Map([["app", "app"]]) - } - }, - "text": "NoCode Tool image content" - } - } - }); - } - - load () - { - this.event.get("complete")({ - "currentTarget": { - "content": { - "_$loaderInfo": { - "_$data": { - "symbols": new Map([["app", "app"]]) - } - }, - "text": "NoCode Tool content" - } - } - }); - } - }, - "Shape": class Shape - { - get graphics () - { - return this; - } - - beginBitmapFill () - { - return this; - } - - beginFill () - { - return this; - } - - drawRect () - { - return this; - } - - endFill () - { - return this; - } - }, - "BitmapData": class BitmapData - { - draw (source, matrix, color_transform, canvas = {}, callback) - { - callback(canvas); - } - }, - "Sprite": class Sprite - { - addChild (display_object) - { - return display_object; - } - - get graphics () - { - return this; - } - - beginFill () - { - return this; - } - - drawRect () - { - return this; - } - - endFill () - { - return this; - } - } - }, - "geom": { - "Matrix": class Matrix - { - - } - }, - "events": { - "Event": class Event { - static get COMPLETE () - { - return "complete"; - } - static get REMOVED () - { - return "removed"; - } - }, - "IOErrorEvent": class IOErrorEvent - { - static get IO_ERROR () { - return "io_error"; - } - } - }, - "net": { - "URLRequest": class URLRequest - { - constructor() - { - this.method = "GET"; - this.requestHeaders = []; - this.data = null; - } - }, - "URLRequestHeader": class URLRequestHeader - { - constructor (name, value) - { - this.name = name; - this.value = value; - } - }, - "URLRequestMethod": { - "GET": "GET", - "PUT": "PUT", - "POST": "POST" - } - }, - "fw": { - "loaderInfo": new Map(), - "application": "app", - "cache": new Map([["cache", "cache"]]), - "config": { - "stage": { - "width": 240, - "height": 240, - "fps": 12, - "options": {} - } - }, - "context": "context", - "packages": new Map([["class", "class"]]), - "response": new Map([["response", "response"]]), - "variable": new Map([["variable", "variable"]]), - "query": new Map([["query", "query"]]) - } -}; - -globalThis.location = { - "pathname": "/" -}; - -globalThis.OffscreenCanvasRenderingContext2D = class OffscreenCanvasRenderingContext2D -{ - -}; - -globalThis.WebGLTexture = class WebGLTexture -{ - -}; - -globalThis.CanvasRenderingContext2D = class CanvasRenderingContext2D -{ - -}; - -globalThis.OffscreenCanvas = class OffscreenCanvas -{ - getContext () - { - return new OffscreenCanvasRenderingContext2D(); - } -}; - -globalThis.history = { - "pushState": () => - { - return undefined; - } -}; - -globalThis.cancelAnimationFrame = () => -{ - return undefined; -}; - -globalThis.requestAnimationFrame = (callback) => -{ - return callback(); -}; \ No newline at end of file diff --git a/jsdoc.conf.js b/jsdoc.conf.js deleted file mode 100644 index 02593082..00000000 --- a/jsdoc.conf.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -module.exports = { - "plugins": [ - "plugins/markdown" - ], - "markdown": { - "hardwrap": true - }, - "templates": { - "cleverLinks" : false, - "monospaceLinks": false, - "applicationName": "Next2D Framework", - "path": "../../../", - "openGraph": { - "title": "Player API Documentation", - "description": "Player API Documentation.", - "type": "website", - "image": "https://next2d.app/assets/img/ogp.png", - "url": "https://next2d.app/" - }, - "meta": { - "title": "Player API Documentation", - "description": "Next2D Player API Documentation.", - "keyword": "Next2D, WebGL, WebGL2, JavaScript, HTML5" - }, - "linenums": true, - "default" : { - "outputSourceFiles" : true - } - }, - "opts": { - "encoding": "utf8", - "recurse": true, - "private": false, - "lenient": true, - "destination": "../next2d/dist/docs/player/", - "template": "node_modules/@next2d/jsdoc-template" - } -}; diff --git a/next2d.js b/next2d.js deleted file mode 100644 index a23f953d..00000000 --- a/next2d.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{"use strict";let t=0;const e=()=>t++;let i=0,s=null;const r=(t=null)=>{s=t};let n="";const a=()=>n,h=t=>{n=t};let o=null;const l=()=>o,c=(t=null)=>{o=t};let _=1;const $=()=>_,u=window,d=u.document;class g{constructor(t="",e=""){this._$name=`${t}`,this._$value=`${e}`}static toString(){return"[class URLRequestHeader]"}static get namespace(){return"next2d.net.URLRequestHeader"}toString(){return"[object URLRequestHeader]"}get namespace(){return"next2d.net.URLRequestHeader"}get name(){return this._$name}get value(){return this._$value}}let f=1,p=0,m=!1;const x=(t=!0)=>{m=t},b=1/0,v=Math,T=Array,y=Map,E=Number,A=Float32Array,M=Int32Array,S=Int16Array,w=OffscreenCanvas,C=isNaN,I=requestAnimationFrame,F=cancelAnimationFrame,R=performance,B=setTimeout,L=clearTimeout,P=new A([1,0,0,1,0,0]),k=new A([1,1,1,1,0,0,0,0]),N=-32768,O=32767,D=v.PI/180,U=180/v.PI,V=[],G=[],z=[],X=[],q=[],Y=[],H=[],j=[],W=[],K=new w(1,1).getContext("2d"),Q=(t=0,e=0,i=0,s=0)=>{const r=W.pop()||{xMin:0,xMax:0,yMin:0,yMax:0};return r.xMin=t,r.xMax=e,r.yMin=i,r.yMax=s,r},J=t=>{W.push(t)},Z=(t=0,e=0,i=0,s=0)=>{const r=z.pop()||new A(4);return r[0]=t,r[1]=e,r[2]=i,r[3]=s,r},tt=t=>{z.push(t)},et=(t=0,e=0,i=0,s=0)=>{const r=G.pop()||new M(4);return r[0]=t,r[1]=e,r[2]=i,r[3]=s,r},it=(t=0,e=0,i=0,s=0,r=0,n=0)=>{const a=X.pop()||new A(6);return a[0]=t,a[1]=e,a[2]=i,a[3]=s,a[4]=r,a[5]=n,a},st=t=>{X.push(t)},rt=(t=1,e=1,i=1,s=1,r=0,n=0,a=0,h=0)=>{const o=q.pop()||new A(8);return o[0]=t,o[1]=e,o[2]=i,o[3]=s,o[4]=r,o[5]=n,o[6]=a,o[7]=h,o},nt=t=>{q.push(t)},at=(t=0,e=0,i=0,s=0,r=0,n=0,a=0,h=0,o=0)=>{const l=Y.pop()||new A(9);return l[0]=t,l[1]=e,l[2]=i,l[3]=s,l[4]=r,l[5]=n,l[6]=a,l[7]=h,l[8]=o,l},ht=(...t)=>{const e=H.pop()||[];return t.length&&e.push(...t),e},ot=(t=null)=>{t&&(t.length&&(t.length=0),H.push(t))},lt=t=>{t.size&&t.clear(),j.push(t)},ct=()=>j.pop()||new y,_t=t=>(t--,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t),$t=t=>{const e=-819.2*t[0]-819.2*t[2]+t[4],i=819.2*t[0]-819.2*t[2]+t[4],s=-819.2*t[0]+819.2*t[2]+t[4],r=-819.2*t[1]-819.2*t[3]+t[5],n=819.2*t[1]-819.2*t[3]+t[5];let a=s-e,h=-819.2*t[1]+819.2*t[3]+t[5]-r;const o=v.sqrt(a*a+h*h);o?(a/=o,h/=o):(a=0,h=0);const l=(i-e)*a+(n-r)*h;return Z(e+l*a,r+l*h,i,n)},ut=t=>{const e=1/(t[0]*t[4]-t[3]*t[1]),i=t[3]*t[7]-t[4]*t[6],s=t[1]*t[6]-t[0]*t[7];return at(t[4]*e,0-t[1]*e,0,0-t[3]*e,t[0]*e,0,i*e,s*e,1)},dt=(t,e,i,s=null)=>{const r=+t;return C(r)&&null!==s?s:v.min(v.max(e,C(r)?0:r),i)},gt=(t,e)=>it(t[0]*e[0]+t[2]*e[1],t[1]*e[0]+t[3]*e[1],t[0]*e[2]+t[2]*e[3],t[1]*e[2]+t[3]*e[3],t[0]*e[4]+t[2]*e[5]+t[4],t[1]*e[4]+t[3]*e[5]+t[5]),ft=(t,e)=>rt(t[0]*e[0],t[1]*e[1],t[2]*e[2],t[3]*e[3],t[0]*e[4]+t[4],t[1]*e[5]+t[5],t[2]*e[6]+t[6],t[3]*e[7]+t[7]),pt=(t,e)=>{const i=t.xMax*e[0]+t.yMax*e[2]+e[4],s=t.xMax*e[0]+t.yMin*e[2]+e[4],r=t.xMin*e[0]+t.yMax*e[2]+e[4],n=t.xMin*e[0]+t.yMin*e[2]+e[4],a=t.xMax*e[1]+t.yMax*e[3]+e[5],h=t.xMax*e[1]+t.yMin*e[3]+e[5],o=t.xMin*e[1]+t.yMax*e[3]+e[5],l=t.xMin*e[1]+t.yMin*e[3]+e[5],c=v.min(E.MAX_VALUE,i,s,r,n),_=v.max(0-E.MAX_VALUE,i,s,r,n),$=v.min(E.MAX_VALUE,a,h,o,l),u=v.max(0-E.MAX_VALUE,a,h,o,l);return Q(c,_,$,u)},mt=t=>{if(!K)return 0;K.fillStyle=t;const e=+`0x${K.fillStyle.slice(1)}`;return K.fillStyle="rgba(0, 0, 0, 1)",e},xt=t=>C(+t)?mt(`${t}`):+t,bt=t=>({A:t>>>24,R:(16711680&t)>>16,G:(65280&t)>>8,B:255&t}),vt=(t,e,i)=>(t>>16)*(i?e:1)/255,Tt=(t,e,i)=>(t>>8&255)*(i?e:1)/255,yt=(t,e,i)=>(255&t)*(i?e:1)/255,Et=(t,e=1)=>({R:(16711680&t)>>16,G:(65280&t)>>8,B:255&t,A:255*e}),At=(t,e,i=!1,s=!1)=>{let r="";return i&&(r="italic "),s&&(r+="bold "),`${r}${e}px '${t}','sans-serif'`},Mt=t=>{t.color&&nt(t.color),t.isLayer=!1,t.isUpdated=null,t.canApply=null,t.matrix=null,t.color=null,t.filters=null,t.blendMode="normal",t.sw=0,t.sh=0,V.push(t)};new Map([[1,"normal"],[2,"layer"],[3,"multiply"],[4,"screen"],[5,"lighten"],[6,"darken"],[7,"difference"],[8,"add"],[9,"subtract"],[10,"invert"],[11,"alpha"],[12,"erase"],[13,"overlay"],[14,"hardlight"]]);const St=new class{constructor(){this._$pool=[],this._$store=new Map,this._$timerMap=new Map,this._$context=null}set context(t){this._$context=t}reset(){for(const t of this._$store.values()){for(const e of t.values())this.destroy(e);lt(t)}this._$store.clear(),this._$context&&this._$context.frameBuffer.clearCache()}destroy(t=null){if(t&&"object"==typeof t)if(t instanceof WebGLTexture)I((()=>{this._$context&&this._$context.frameBuffer.releaseTexture(t)}));else{if("canvas"in t&&t instanceof CanvasRenderingContext2D){const e=t.canvas,i=e.width,s=e.height;t.clearRect(0,0,i+1,s+1),e.width=e.height=1,this._$pool.push(e)}this._$context&&"index"in t&&this._$context.frameBuffer.textureManager.releasePosition(t)}}getCanvas(){return this._$pool.pop()||document.createElement("canvas")}remove(t,e){if(!this._$store.has(t))return;const i=this._$store.get(t);i.has(e)&&(i.delete(e),i.size||(lt(i),this._$store.delete(t)))}stopTimer(t){t=`${t}`,this._$timerMap.has(t)&&(L(this._$timerMap.get(t)),this._$timerMap.delete(t))}removeCache(t){if(t=`${t}`,this._$store.has(t)){const e=this._$store.get(t);for(const t of e.values())this.destroy(t);e.clear(),lt(e),this._$store.delete(t)}this._$timerMap.delete(t)}setRemoveTimer(t){if(t=`${t}`,this.stopTimer(t),this._$store.has(t)){const e=B((()=>{this.removeCache(t)}),5e3);this._$timerMap.set(t,e)}}get(t){const e=`${t[0]}`,i=`${t[1]}`;if(this._$store.has(e)){this.stopTimer(e);const t=this._$store.get(e);if(t.has(i))return t.get(i)}return null}set(t,e=null){const i=`${t[0]}`,s=`${t[1]}`;this._$store.has(i)||this._$store.set(i,ct());const r=this._$store.get(i);if(null===e){if(!r.has(s))return;return this.destroy(r.get(s)),r.delete(s),void(r.size||(lt(r),this._$store.delete(i)))}r.set(s,e)}has(t){const e=`${t[0]}`;return!!this._$store.has(e)&&this._$store.get(e).has(`${t[1]}`)}generateKeys(t,e=null,i=null){let s="";e&&e.length&&(s+=`${e[0]}_${e[1]}`),i&&i.length&&(s+=0===i[7]?"":`_${i[7]}`);const r=ht();if(s){let t=0;const e=s.length;for(let i=0;i1&&n.sort((function(t,e){switch(!0){case t.priority>e.priority:return-1;case t.priority1&&r.sort((function(t,e){switch(!0){case t.priority>e.priority:return-1;case t.priority1&&n.sort((function(t,e){switch(!0){case t.priority>e.priority:return-1;case t.priority{if(e in t)return t[e];const i=l();return i&&e in i?i[e]:void 0}})}static toString(){return"[class MouseEvent]"}static get namespace(){return"next2d.events.MouseEvent"}toString(){return this.formatToString("MouseEvent","type","bubbles","cancelable","eventPhase","localX","localY","stageX","stageY","ctrlKey","altKey","shiftKey","buttonDown","delta","commandKey","controlKey","clickCount")}get namespace(){return"next2d.events.MouseEvent"}static get CLICK(){return"click"}static get DOUBLE_CLICK(){return"dblclick"}static get MOUSE_DOWN(){return"mouseDown"}static get MOUSE_MOVE(){return"mouseMove"}static get MOUSE_OUT(){return"mouseOut"}static get MOUSE_OVER(){return"mouseOver"}static get MOUSE_UP(){return"mouseUp"}static get MOUSE_WHEEL(){return"mouseWheel"}static get ROLL_OUT(){return"rollOut"}static get ROLL_OVER(){return"rollOver"}}class kt extends It{constructor(t,e=!1,i=!1,s=0,r=0){super(t,e,i),this._$bytesLoaded=0|s,this._$bytesTotal=0|r}static toString(){return"[class ProgressEvent]"}static get namespace(){return"next2d.events.ProgressEvent"}toString(){return this.formatToString("ProgressEvent","type","bubbles","cancelable","eventPhase","bytesLoaded","bytesTotal")}get namespace(){return"next2d.events.ProgressEvent"}static get PROGRESS(){return"progress"}get bytesLoaded(){return this._$bytesLoaded}get bytesTotal(){return this._$bytesTotal}}class Nt extends It{constructor(t,e=!1,i=!1,s=0,r=0){super(t,e,i),this._$bytesLoaded=0|s,this._$bytesTotal=0|r}static toString(){return"[class VideoEvent]"}static get namespace(){return"next2d.events.VideoEvent"}toString(){return this.formatToString("VideoEvent","type","bubbles","cancelable","eventPhase","bytesLoaded","bytesTotal")}get namespace(){return"next2d.events.VideoEvent"}static get PROGRESS(){return"progress"}static get PLAY(){return"play"}static get PLAY_START(){return"playStart"}static get PLAY_END(){return"playEnd"}static get PAUSE(){return"pause"}static get SEEK(){return"seek"}get bytesLoaded(){return this._$bytesLoaded}get bytesTotal(){return this._$bytesTotal}}class Ot{constructor(t=1,e=1,i=1,s=1,r=0,n=0,a=0,h=0){this._$colorTransform=rt(),this.redMultiplier=t,this.greenMultiplier=e,this.blueMultiplier=i,this.alphaMultiplier=s,this.redOffset=r,this.greenOffset=n,this.blueOffset=a,this.alphaOffset=h}static toString(){return"[class ColorTransform]"}static get namespace(){return"next2d.geom.ColorTransform"}toString(){return"(redMultiplier="+this._$colorTransform[0]+", greenMultiplier="+this._$colorTransform[1]+", blueMultiplier="+this._$colorTransform[2]+", alphaMultiplier="+this._$colorTransform[3]+", redOffset="+this._$colorTransform[4]+", greenOffset="+this._$colorTransform[5]+", blueOffset="+this._$colorTransform[6]+", alphaOffset="+this._$colorTransform[7]+")"}get namespace(){return"next2d.geom.ColorTransform"}get alphaMultiplier(){return this._$colorTransform[3]}set alphaMultiplier(t){this._$colorTransform[3]=dt(+t,0,1,0)}get alphaOffset(){return this._$colorTransform[7]}set alphaOffset(t){this._$colorTransform[7]=dt(0|t,-255,255,0)}get blueMultiplier(){return this._$colorTransform[2]}set blueMultiplier(t){this._$colorTransform[2]=dt(+t,0,1,0)}get blueOffset(){return this._$colorTransform[6]}set blueOffset(t){this._$colorTransform[6]=dt(0|t,-255,255,0)}get greenMultiplier(){return this._$colorTransform[1]}set greenMultiplier(t){this._$colorTransform[1]=dt(+t,0,1,0)}get greenOffset(){return this._$colorTransform[5]}set greenOffset(t){this._$colorTransform[5]=dt(0|t,-255,255,0)}get redMultiplier(){return this._$colorTransform[0]}set redMultiplier(t){this._$colorTransform[0]=dt(+t,0,1,0)}get redOffset(){return this._$colorTransform[4]}set redOffset(t){this._$colorTransform[4]=dt(0|t,-255,255,0)}concat(t){const e=ft(this._$colorTransform,t._$colorTransform);this.redMultiplier=e[0],this.greenMultiplier=e[1],this.blueMultiplier=e[2],this.alphaMultiplier=e[3],this.redOffset=e[4],this.greenOffset=e[5],this.blueOffset=e[6],this.alphaOffset=e[7],nt(e)}_$clone(){return dr(this._$colorTransform[0],this._$colorTransform[1],this._$colorTransform[2],this._$colorTransform[3],this._$colorTransform[4],this._$colorTransform[5],this._$colorTransform[6],this._$colorTransform[7])}}class Dt{constructor(t=0,e=0){this._$x=0,this._$y=0,this.x=t,this.y=e}static toString(){return"[class Point]"}static get namespace(){return"next2d.geom.Point"}toString(){return`(x=${this.x}, y=${this.y})`}get namespace(){return"next2d.geom.Point"}get length(){return v.sqrt(v.pow(this.x,2)+v.pow(this.y,2))}get x(){return this._$x}set x(t){this._$x=dt(+t,N,O,0)}get y(){return this._$y}set y(t){this._$y=dt(+t,N,O,0)}add(t){return new Dt(this.x+t.x,this.y+t.y)}clone(){return new Dt(this.x,this.y)}copyFrom(t){this._$x=t._$x,this._$y=t._$y}static distance(t,e){return v.sqrt(v.pow(t._$x-e._$x,2)+v.pow(t._$y-e._$y,2))}equals(t){return this._$x===t._$x&&this._$y===t._$y}static interpolate(t,e,i){return new Dt(t.x+(e.x-t.x)*(1-i),t.y+(e.y-t.y)*(1-i))}normalize(t){const e=this.length;this.x=this.x*t/e,this.y=this.y*t/e}offset(t,e){this.x+=t,this.y+=e}static polar(t,e){return new Dt(t*v.cos(e),t*v.sin(e))}setTo(t,e){this.x=t,this.y=e}subtract(t){return new Dt(this.x-t.x,this.y-t.y)}}class Ut{constructor(t=1,e=0,i=0,s=1,r=0,n=0){this._$matrix=it(1,0,0,1,0,0),this.a=t,this.b=e,this.c=i,this.d=s,this.tx=r,this.ty=n}static toString(){return"[class Matrix]"}static get namespace(){return"next2d.geom.Matrix"}toString(){return`(a=${this.a}, b=${this.b}, c=${this.c}, d=${this.d}, tx=${this.tx}, ty=${this.ty})`}get namespace(){return"next2d.geom.Matrix"}get a(){return this._$matrix[0]}set a(t){this._$matrix[0]=dt(+t,N,O,0)}get b(){return this._$matrix[1]}set b(t){this._$matrix[1]=dt(+t,N,O,0)}get c(){return this._$matrix[2]}set c(t){this._$matrix[2]=dt(+t,N,O,0)}get d(){return this._$matrix[3]}set d(t){this._$matrix[3]=dt(+t,N,O,0)}get tx(){return this._$matrix[4]}set tx(t){this._$matrix[4]=dt(+t,N,O,0)}get ty(){return this._$matrix[5]}set ty(t){this._$matrix[5]=dt(+t,N,O,0)}_$clone(){return this.clone()}clone(){return $r(this._$matrix[0],this._$matrix[1],this._$matrix[2],this._$matrix[3],this._$matrix[4],this._$matrix[5])}concat(t){const e=this._$matrix,i=t._$matrix;let s=e[0]*i[0],r=0,n=0,a=e[3]*i[3],h=e[4]*i[0]+i[4],o=e[5]*i[3]+i[5];(e[1]||e[2]||i[1]||i[2])&&(s+=e[1]*i[2],a+=e[2]*i[1],r+=e[0]*i[1]+e[1]*i[3],n+=e[2]*i[0]+e[3]*i[2],h+=e[5]*i[2],o+=e[4]*i[1]),this.a=s,this.b=r,this.c=n,this.d=a,this.tx=h,this.ty=o}copyFrom(t){this.a=t.a,this.b=t.b,this.c=t.c,this.d=t.d,this.tx=t.tx,this.ty=t.ty}createBox(t,e,i=0,s=0,r=0){this.identity(),this.rotate(i),this.scale(t,e),this.translate(s,r)}createGradientBox(t,e,i=0,s=0,r=0){if(this.a=t/1638.4,this.d=e/1638.4,i){const t=v.cos(i),e=v.sin(i);this.b=e*this.d,this.c=-e*this.a,this.a*=t,this.d*=t}else this.b=0,this.c=0;this.tx=s+t/2,this.ty=r+e/2}deltaTransformPoint(t){return new Dt(t.x*this._$matrix[0]+t.y*this._$matrix[2],t.x*this._$matrix[1]+t.y*this._$matrix[3])}identity(){this._$matrix[0]=1,this._$matrix[1]=0,this._$matrix[2]=0,this._$matrix[3]=1,this._$matrix[4]=0,this._$matrix[5]=0}invert(){const t=this._$matrix[0],e=this._$matrix[1],i=this._$matrix[2],s=this._$matrix[3],r=this._$matrix[4],n=this._$matrix[5];if(0===e&&0===i)this.a=1/t,this.b=0,this.c=0,this.d=1/s,this.tx=-this.a*r,this.ty=-this.d*n;else{const a=t*s-e*i;if(a){const h=1/a;this.a=s*h,this.b=-e*h,this.c=-i*h,this.d=t*h,this.tx=-(this.a*r+this.c*n),this.ty=-(this.b*r+this.d*n)}}}rotate(t){const e=this._$matrix[0],i=this._$matrix[1],s=this._$matrix[2],r=this._$matrix[3],n=this._$matrix[4],a=this._$matrix[5];this.a=e*v.cos(t)-i*v.sin(t),this.b=e*v.sin(t)+i*v.cos(t),this.c=s*v.cos(t)-r*v.sin(t),this.d=s*v.sin(t)+r*v.cos(t),this.tx=n*v.cos(t)-a*v.sin(t),this.ty=n*v.sin(t)+a*v.cos(t)}scale(t,e){this.a*=t,this.c*=t,this.tx*=t,this.b*=e,this.d*=e,this.ty*=e}setTo(t,e,i,s,r,n){this.a=t,this.b=e,this.c=i,this.d=s,this.tx=r,this.ty=n}transformPoint(t){return new Dt(t.x*this._$matrix[0]+t.y*this._$matrix[2]+this._$matrix[4],t.x*this._$matrix[1]+t.y*this._$matrix[3]+this._$matrix[5])}translate(t,e){this.tx+=t,this.ty+=e}}class Vt{constructor(t=0,e=0,i=0,s=0){this._$x=0,this._$y=0,this._$width=0,this._$height=0,this.setTo(t,e,i,s)}static toString(){return"[class Rectangle]"}static get namespace(){return"next2d.geom.Rectangle"}toString(){return`(x=${this.x}, y=${this.y}, w=${this.width}, h=${this.height})`}get namespace(){return"next2d.geom.Rectangle"}get bottom(){return this.y+this.height}set bottom(t){this.height=+t-this.y}get bottomRight(){return new Dt(this.right,this.bottom)}set bottomRight(t){this.right=t.x,this.bottom=t.y}get height(){return this._$height}set height(t){this._$height=dt(+t,N,O,0)}get left(){return this.x}set left(t){this.width=this.right-+t,this.x=t}get right(){return this.x+this.width}set right(t){this.width=+t-this.x}get size(){return new Dt(this.width,this.height)}set size(t){this.width=t.x,this.height=t.y}get top(){return this.y}set top(t){this.height=+(this.bottom-+t),this.y=t}get topLeft(){return new Dt(this.x,this.y)}set topLeft(t){this.left=t.x,this.top=t.y}get width(){return this._$width}set width(t){this._$width=dt(+t,N,O,0)}get x(){return this._$x}set x(t){this._$x=dt(+t,N,O,0)}get y(){return this._$y}set y(t){this._$y=dt(+t,N,O,0)}clone(){return new Vt(this.x,this.y,this.width,this.height)}contains(t,e){return this.x<=t&&this.y<=e&&this.right>t&&this.bottom>e}containsPoint(t){return this.x<=t.x&&this.y<=t.y&&this.right>t.x&&this.bottom>t.y}containsRect(t){return this.x<=t.x&&this.y<=t.y&&this.right>=t.right&&this.bottom>=t.bottom}copyFrom(t){this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height}equals(t){return this.x===t.x&&this.y===t.y&&this.width===t.width&&this.height===t.height}inflate(t,e){this.x=this.x-+t,this.width=this.width+2*+t,this.y=this.y-+e,this.height=this.height+2*+e}inflatePoint(t){this.x=this.x-t.x,this.width=this.width+2*t.x,this.y=this.y-t.y,this.height=this.height+2*t.y}intersection(t){const e=v.max(this.x,t.x),i=v.max(this.y,t.y),s=v.min(this.right,t.right)-e,r=v.min(this.bottom,t.bottom)-i;return s>0&&r>0?new Vt(e,i,s,r):new Vt(0,0,0,0)}intersects(t){const e=v.max(this.x,t.x),i=v.max(this.y,t.y),s=v.min(this.right,t.right),r=v.min(this.bottom,t.bottom);return s-e>0&&r-i>0}isEmpty(){return this.width<=0||this.height<=0}offset(t,e){this.x+=t,this.y+=e}offsetPoint(t){this.x+=t.x,this.y+=t.y}setEmpty(){this._$x=0,this._$y=0,this._$width=0,this._$height=0}setTo(t,e,i,s){this.x=t,this.y=e,this.width=i,this.height=s}union(t){return this.isEmpty()?t.clone():t.isEmpty()?this.clone():new Vt(v.min(this.x,t.x),v.min(this.y,t.y),v.max(this.right-t.left,t.right-this.left),v.max(this.bottom-t.top,t.bottom-this.top))}}class Gt{constructor(){this._$updated=!0}static toString(){return"[class BitmapFilter]"}static get namespace(){return"next2d.filters.BitmapFilter"}toString(){return"[object BitmapFilter]"}get namespace(){return"next2d.filters.BitmapFilter"}_$isUpdated(){return this._$updated}_$doChanged(){this._$updated=!0,x()}}class zt extends Gt{constructor(t=4,e=4,i=1){super(),this._$blurX=4,this._$blurY=4,this._$quality=1,this.blurX=t,this.blurY=e,this.quality=i}static toString(){return"[class BlurFilter]"}static get namespace(){return"next2d.filters.BlurFilter"}toString(){return"[object BlurFilter]"}get namespace(){return"next2d.filters.BlurFilter"}static get STEP(){return[.5,1.05,1.4,1.55,1.75,1.9,2,2.15,2.2,2.3,2.5,3,3,3.5,3.5]}get blurX(){return this._$blurX}set blurX(t){(t=dt(+t,0,255,0))!==this._$blurX&&(this._$blurX=t,this._$doChanged())}get blurY(){return this._$blurY}set blurY(t){(t=dt(+t,0,255,0))!==this._$blurY&&(this._$blurY=t,this._$doChanged())}get quality(){return this._$quality}set quality(t){(t=dt(0|t,0,15,1))!==this._$quality&&(this._$quality=t,this._$doChanged())}clone(){return new zt(this._$blurX,this._$blurY,this._$quality)}_$toArray(){return ht(1,this._$blurX,this._$blurY,this._$quality)}_$generateFilterRect(t,e=0,i=0){const s=Q(t.xMin,t.xMax,t.yMin,t.yMax);if(!this._$quality)return s;const r=zt.STEP[this._$quality-1];let n=0>=this._$blurX?1:this._$blurX*r,a=0>=this._$blurY?1:this._$blurY*r;return e?n*=e:n=v.round(n),i?a*=i:a=v.round(a),s.xMin-=n,s.xMax+=2*n,s.yMin-=a,s.yMax+=2*a,s}_$canApply(){return 0!==this._$blurX&&0!==this._$blurY}_$applyFilter(t,e,i=!0){this._$updated=!1;const s=t.frameBuffer,r=s.currentAttachment,n=s.getTextureFromCurrentAttachment();if(!this._$canApply())return i?n:s.createTextureFromCurrentAttachment();let a=v.sqrt(e[0]*e[0]+e[1]*e[1]),h=v.sqrt(e[2]*e[2]+e[3]*e[3]);a/=f,h/=f,a*=2,h*=2;const o=Q(0,n.width,0,n.height),l=this._$generateFilterRect(o,a,h);J(o);const c=0|v.ceil(l.xMax),_=0|v.ceil(l.yMax),$=v.ceil(v.abs(l.xMin)+.5*v.abs(c-l.xMax)),u=v.ceil(v.abs(l.yMin)+.5*v.abs(_-l.yMax));t._$offsetX=$+t._$offsetX,t._$offsetY=u+t._$offsetY;const d=this._$blurX*a,g=this._$blurY*h;let p=1,m=1;d>128?p=.0625:d>64?p=.125:d>32?p=.25:d>16&&(p=.5),g>128?m=.0625:g>64?m=.125:g>32?m=.25:g>16&&(m=.5);const x=d*p,b=g*m,T=v.ceil(c*p),y=v.ceil(_*m),E=s.createTextureAttachment(T,y),A=[E,s.createTextureAttachment(T,y)];let M=0;t._$bind(E),t.reset(),t.setTransform(p,0,0,m,0,0),t.drawImage(n,$,u,n.width,n.height),t.blend.toOneZero();let S=s.getTextureFromCurrentAttachment();for(let e=0;e0){M=(M+1)%2;const e=A[M];t._$bind(e),t._$applyBlurFilter(S,!0,x),S=s.getTextureFromCurrentAttachment()}if(this._$blurY>0){M=(M+1)%2;const e=A[M];t._$bind(e),t._$applyBlurFilter(S,!1,b),S=s.getTextureFromCurrentAttachment()}}if(t.blend.reset(),1!==p||1!==m){const e=s.createTextureAttachment(c,_);t._$bind(e),t.reset(),t.imageSmoothingEnabled=!0,t.setTransform(1/p,0,0,1/m,0,0),t.drawImage(S,0,0,T,y),S=s.getTextureFromCurrentAttachment(),t.reset(),t.setTransform(1,0,0,1,0,0),s.releaseAttachment(A[0],!0),s.releaseAttachment(A[1],!0),i?s.releaseAttachment(r,!0):s.releaseAttachment(e,!1)}else s.releaseAttachment(A[(M+1)%2],!0),i?s.releaseAttachment(r,!0):s.releaseAttachment(A[M],!1);return S}}class Xt extends Gt{constructor(t=4,e=45,i=16777215,s=1,r=0,n=1,a=4,h=4,o=1,l=1,c="inner",_=!1){super(),this._$blurFilter=new zt(a,h,l),this._$distance=4,this._$angle=45,this._$highlightColor=16777215,this._$highlightAlpha=1,this._$shadowColor=0,this._$shadowAlpha=1,this._$strength=1,this._$type="inner",this._$knockout=!1,this.distance=t,this.angle=e,this.highlightColor=i,this.highlightAlpha=s,this.shadowColor=r,this.shadowAlpha=n,this.strength=o,this.type=c,this.knockout=_}static toString(){return"[class BevelFilter]"}static get namespace(){return"next2d.filters.BevelFilter"}toString(){return"[object BevelFilter]"}get namespace(){return"next2d.filters.BevelFilter"}get angle(){return this._$angle}set angle(t){(t%=360)!==this._$angle&&(this._$angle=dt(t,-360,360,45),this._$doChanged())}get blurX(){return this._$blurFilter.blurX}set blurX(t){this._$blurFilter.blurX=t}get blurY(){return this._$blurFilter.blurY}set blurY(t){this._$blurFilter.blurY=t}get distance(){return this._$distance}set distance(t){(t=dt(+t,-255,255,4))!==this._$distance&&(this._$distance=t,this._$doChanged())}get highlightAlpha(){return this._$highlightAlpha}set highlightAlpha(t){(t=dt(+t,0,1,0))!==this._$highlightAlpha&&(this._$highlightAlpha=t,this._$doChanged())}get highlightColor(){return this._$highlightColor}set highlightColor(t){(t=dt(xt(t),0,16777215,16777215))!==this._$highlightColor&&(this._$highlightColor=t,this._$doChanged())}get knockout(){return this._$knockout}set knockout(t){t!==this._$knockout&&(this._$knockout=!!t,this._$doChanged())}get quality(){return this._$blurFilter.quality}set quality(t){this._$blurFilter.quality=t}get shadowAlpha(){return this._$shadowAlpha}set shadowAlpha(t){(t=dt(+t,0,1,0))!==this._$shadowAlpha&&(this._$shadowAlpha=t,this._$doChanged())}get shadowColor(){return this._$shadowColor}set shadowColor(t){(t=dt(xt(t),0,16777215,0))!==this._$shadowColor&&(this._$shadowColor=t,this._$doChanged())}get strength(){return this._$strength}set strength(t){(t=dt(0|t,0,255,0))!==this._$strength&&(this._$strength=t,this._$doChanged())}get type(){return this._$type}set type(t){(t=`${t}`)!==this._$type&&(this._$type=t,this._$doChanged())}clone(){return new Xt(this._$distance,this._$angle,this._$highlightColor,this._$highlightAlpha,this._$shadowColor,this._$shadowAlpha,this._$blurFilter.blurX,this._$blurFilter.blurY,this._$strength,this._$blurFilter.quality,this._$type,this._$knockout)}_$toArray(){return ht(0,this._$distance,this._$angle,this._$highlightColor,this._$highlightAlpha,this._$shadowColor,this._$shadowAlpha,this._$blurFilter.blurX,this._$blurFilter.blurY,this._$strength,this._$blurFilter.quality,this._$type,this._$knockout)}_$isUpdated(){return this._$updated||this._$blurFilter._$isUpdated()}_$generateFilterRect(t,e=0,i=0){let s=Q(t.xMin,t.xMax,t.yMin,t.yMax);if(!this._$canApply())return s;s=this._$blurFilter._$generateFilterRect(s,e,i);const r=this._$angle*D;let n=v.abs(v.cos(r)*this._$distance),a=v.abs(v.sin(r)*this._$distance);return e&&(n*=e),i&&(a*=i),s.xMin=v.min(s.xMin,n),n>0&&(s.xMax+=n),s.yMin=v.min(s.yMin,a),a>0&&(s.yMax+=a),s}_$canApply(){return this._$strength>0&&0!==this._$distance&&this._$blurFilter._$canApply()}_$applyFilter(t,e){this._$updated=!1;const i=t.frameBuffer,s=i.currentAttachment;if(!s)throw new Error("the current attachment is null.");t.setTransform(1,0,0,1,0,0);const r=i.getTextureFromCurrentAttachment();if(!this._$canApply())return r;const n=s.width,a=s.height,h=t._$offsetX,o=t._$offsetY;let l=v.sqrt(e[0]*e[0]+e[1]*e[1]),c=v.sqrt(e[2]*e[2]+e[3]*e[3]);l/=f,c/=f,l*=2,c*=2;const _=this._$angle*D,$=v.cos(_)*this._$distance*l,u=v.sin(_)*this._$distance*c,d=i.createTextureAttachment(n,a);t._$bind(d),t.reset(),t.drawImage(r,0,0,n,a),t.globalCompositeOperation="erase",t.drawImage(r,2*$,2*u,n,a);const g=this._$blurFilter._$applyFilter(t,e,!1),p=g.width,m=g.height,x=v.ceil(p+2*v.abs($)),b=v.ceil(m+2*v.abs(u)),T="inner"===this._$type,y=T?n:x,E=T?a:b,A=v.abs($),M=v.abs(u),S=(p-n)/2,w=(m-a)/2,C=T?0:A+S,I=T?0:M+w,F=T?-S-$:A-$,R=T?-w-u:M-u;return t._$bind(s),i.releaseAttachment(d,!0),t._$applyBitmapFilter(g,y,E,n,a,C,I,p,m,F,R,!1,this._$type,this._$knockout,this._$strength,null,null,null,vt(this._$highlightColor,this._$highlightAlpha,!0),Tt(this._$highlightColor,this._$highlightAlpha,!0),yt(this._$highlightColor,this._$highlightAlpha,!0),this._$highlightAlpha,vt(this._$shadowColor,this._$shadowAlpha,!0),Tt(this._$shadowColor,this._$shadowAlpha,!0),yt(this._$shadowColor,this._$shadowAlpha,!0),this._$shadowAlpha),t._$offsetX=h+C,t._$offsetY=o+I,i.releaseTexture(g),i.getTextureFromCurrentAttachment()}}class qt extends Gt{constructor(t=null){super(),this._$matrix=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0],this.matrix=t}static toString(){return"[class ColorMatrixFilter]"}static get namespace(){return"next2d.filters.ColorMatrixFilter"}toString(){return"[object ColorMatrixFilter]"}get namespace(){return"next2d.filters.ColorMatrixFilter"}get matrix(){return this._$matrix}set matrix(t){if(t&&T.isArray(t)&&20===t.length){for(let e=0;e<20;++e)if(t[e]!==this._$matrix[e]){this._$doChanged();break}this._$matrix=t}}clone(){return new qt(this._$matrix)}_$toArray(){return ht(2,this._$matrix)}_$generateFilterRect(t){return t}_$canApply(){return!0}_$applyFilter(t){this._$updated=!1;const e=t.frameBuffer,i=e.currentAttachment;t.setTransform(1,0,0,1,0,0);const s=e.getTextureFromCurrentAttachment(),r=s.width,n=s.height,a=e.createTextureAttachment(r,n);return t._$bind(a),t.reset(),t._$applyColorMatrixFilter(s,this._$matrix),e.releaseAttachment(i,!0),e.getTextureFromCurrentAttachment()}}class Yt extends Gt{constructor(t=0,e=0,i=null,s=1,r=0,n=!0,a=!0,h=0,o=0){super(),this._$matrixX=0,this._$matrixY=0,this._$matrix=null,this._$divisor=1,this._$bias=0,this._$preserveAlpha=!0,this._$clamp=!0,this._$color=0,this._$alpha=0,this.matrixX=t,this.matrixY=e,this.matrix=i,this.divisor=s,this.bias=r,this.preserveAlpha=n,this.clamp=a,this.color=h,this.alpha=o}static toString(){return"[class ConvolutionFilter]"}static get namespace(){return"next2d.filters.ConvolutionFilter"}toString(){return"[object ConvolutionFilter]"}get namespace(){return"next2d.filters.ConvolutionFilter"}get alpha(){return this._$alpha}set alpha(t){(t=dt(+t,0,1,0))!==this._$alpha&&(this._$alpha=t,this._$doChanged())}get bias(){return this._$bias}set bias(t){t!==this._$bias&&(this._$bias=0|t,this._$doChanged())}get clamp(){return this._$clamp}set clamp(t){t!==this._$clamp&&(this._$clamp=!!t,this._$doChanged())}get color(){return this._$color}set color(t){(t=dt(xt(t),0,16777215,0))!==this._$color&&(this._$color=t,this._$doChanged())}get divisor(){return this._$divisor}set divisor(t){t!==this._$divisor&&(this._$divisor=0|t,this._$doChanged())}get matrix(){return this._$matrix}set matrix(t){T.isArray(this._$matrix)&&ot(this._$matrix),this._$matrix=T.isArray(t)?t:null,this._$doChanged()}get matrixX(){return this._$matrixX}set matrixX(t){(t=0|dt(0|t,0,15,0))!==this._$matrixX&&(this._$matrixX=t,this._$doChanged())}get matrixY(){return this._$matrixY}set matrixY(t){(t=0|dt(0|t,0,15,0))!==this._$matrixY&&(this._$matrixY=t,this._$doChanged())}get preserveAlpha(){return this._$preserveAlpha}set preserveAlpha(t){t!==this._$preserveAlpha&&(this._$preserveAlpha=!!t,this._$doChanged())}clone(){return new Yt(this._$matrixX,this._$matrixY,this._$matrix?this._$matrix.slice():null,this._$divisor,this._$bias,this._$preserveAlpha,this._$clamp,this._$color,this._$alpha)}_$toArray(){return ht(3,this._$matrixX,this._$matrixY,this._$matrix,this._$divisor,this._$bias,this._$preserveAlpha,this._$clamp,this._$color,this._$alpha)}_$generateFilterRect(t){return t}_$canApply(){return null!==this._$matrix&&this._$matrixX*this._$matrixY===this._$matrix.length}_$applyFilter(t){this._$updated=!1;const e=t.frameBuffer,i=e.currentAttachment;t.setTransform(1,0,0,1,0,0);const s=e.getTextureFromCurrentAttachment();return this._$canApply()&&this._$matrix?(t._$applyConvolutionFilter(s,this._$matrixX,this._$matrixY,this._$matrix,this._$divisor,this._$bias,this._$preserveAlpha,this._$clamp,vt(this._$color,this._$alpha,!1),Tt(this._$color,this._$alpha,!1),yt(this._$color,this._$alpha,!1),this._$alpha),e.releaseAttachment(i,!0),e.getTextureFromCurrentAttachment()):s}}class Ht extends Gt{constructor(t=null,e=null,i=0,s=0,r=0,n=0,a="wrap",h=0,o=0){super(),this._$mapBitmap=null,this._$mapPoint=null,this._$componentX=0,this._$componentY=0,this._$scaleX=0,this._$scaleY=0,this._$mode="wrap",this._$color=0,this._$alpha=0,this.mapBitmap=t,this.mapPoint=e,this.componentX=i,this.componentY=s,this.scaleX=r,this.scaleY=n,this.mode=a,this.color=h,this.alpha=o}static toString(){return"[class DisplacementMapFilter]"}static get namespace(){return"next2d.filters.DisplacementMapFilter"}toString(){return"[object DisplacementMapFilter]"}get namespace(){return"next2d.filters.DisplacementMapFilter"}get alpha(){return this._$alpha}set alpha(t){(t=dt(+t,0,1,0))!==this._$alpha&&(this._$alpha=t,this._$doChanged())}get color(){return this._$color}set color(t){(t=dt(xt(t),0,16777215,0))!==this._$color&&(this._$color=t,this._$doChanged())}get componentX(){return this._$componentX}set componentX(t){t!==this._$componentX&&(this._$componentX=t,this._$doChanged())}get componentY(){return this._$componentY}set componentY(t){t!==this._$componentY&&(this._$componentY=t,this._$doChanged())}get mapBitmap(){return this._$mapBitmap}set mapBitmap(t){t!==this._$mapBitmap&&(this._$mapBitmap=t,this._$doChanged())}get mapPoint(){return this._$mapPoint}set mapPoint(t){t!==this._$mapPoint&&(this._$mapPoint=t,this._$doChanged())}get mode(){return this._$mode}set mode(t){t!==this._$mode&&(this._$mode=t,this._$doChanged())}get scaleX(){return this._$scaleX}set scaleX(t){(t=dt(+t,-65535,65535,0))!==this._$scaleX&&(this._$scaleX=t,this._$doChanged())}get scaleY(){return this._$scaleY}set scaleY(t){(t=dt(+t,-65535,65535,0))!==this._$scaleY&&(this._$scaleY=t,this._$doChanged())}clone(){return new Ht(this._$mapBitmap,this._$mapPoint,this._$componentX,this._$componentY,this._$scaleX,this._$scaleY,this._$mode,this._$color,this._$alpha)}_$toArray(){return ht(4,this._$mapBitmap,this._$mapPoint,this._$componentX,this._$componentY,this._$scaleX,this._$scaleY,this._$mode,this._$color,this._$alpha)}_$generateFilterRect(t){return t}_$canApply(){return null!==this._$mapBitmap&&this._$componentX>0&&this._$componentY>0&&0!==this._$scaleX&&0!==this._$scaleY}_$applyFilter(t,e){this._$updated=!1;const i=t.frameBuffer,s=i.currentAttachment;t.setTransform(1,0,0,1,0,0);const r=i.getTextureFromCurrentAttachment();if(!this._$canApply()||!s||!this._$mapBitmap)return r;const n=v.sqrt(e[0]*e[0]+e[1]*e[1]),a=v.sqrt(e[2]*e[2]+e[3]*e[3]);return t._$applyDisplacementMapFilter(r,this._$mapBitmap,r.width/n,r.height/a,this._$mapPoint,this._$componentX,this._$componentY,this._$scaleX,this._$scaleY,this._$mode,vt(this._$color,this._$alpha,!0),Tt(this._$color,this._$alpha,!0),yt(this._$color,this._$alpha,!0),this._$alpha),i.releaseAttachment(s,!0),i.getTextureFromCurrentAttachment()}}class jt extends Gt{constructor(t=4,e=45,i=0,s=1,r=4,n=4,a=1,h=1,o=!1,l=!1,c=!1){super(),this._$blurFilter=new zt(r,n,h),this._$distance=4,this._$angle=45,this._$color=0,this._$alpha=1,this._$strength=1,this._$inner=!1,this._$knockout=!1,this._$hideObject=!1,this.distance=t,this.angle=e,this.color=i,this.alpha=s,this.strength=a,this.inner=o,this.knockout=l,this.hideObject=c}static toString(){return"[class DropShadowFilter]"}static get namespace(){return"next2d.filters.DropShadowFilter"}toString(){return"[object DropShadowFilter]"}get namespace(){return"next2d.filters.DropShadowFilter"}get alpha(){return this._$alpha}set alpha(t){(t=dt(+t,0,1,0))!==this._$alpha&&(this._$alpha=t,this._$doChanged())}get angle(){return this._$angle}set angle(t){(t%=360)!==this._$angle&&(this._$angle=dt(t,-360,360,45),this._$doChanged())}get blurX(){return this._$blurFilter.blurX}set blurX(t){this._$blurFilter.blurX=t}get blurY(){return this._$blurFilter.blurY}set blurY(t){this._$blurFilter.blurY=t}get color(){return this._$color}set color(t){(t=dt(xt(t),0,16777215,0))!==this._$color&&(this._$color=t,this._$doChanged())}get distance(){return this._$distance}set distance(t){(t=dt(+t,-255,255,4))!==this._$distance&&(this._$distance=t,this._$doChanged())}get hideObject(){return this._$hideObject}set hideObject(t){t!==this._$hideObject&&(this._$hideObject=!!t,this._$doChanged())}get inner(){return this._$inner}set inner(t){t!==this._$inner&&(this._$inner=!!t,this._$doChanged())}get knockout(){return this._$knockout}set knockout(t){t!==this._$knockout&&(this._$knockout=!!t,this._$doChanged())}get quality(){return this._$blurFilter.quality}set quality(t){this._$blurFilter.quality=t}get strength(){return this._$strength}set strength(t){(t=dt(0|t,0,255,0))!==this._$strength&&(this._$strength=t,this._$doChanged())}clone(){return new jt(this._$distance,this._$angle,this._$color,this._$alpha,this._$blurFilter.blurX,this._$blurFilter.blurY,this._$strength,this._$blurFilter.quality,this._$inner,this._$knockout,this._$hideObject)}_$toArray(){return ht(5,this._$distance,this._$angle,this._$color,this._$alpha,this._$blurFilter.blurX,this._$blurFilter.blurY,this._$strength,this._$blurFilter.quality,this._$inner,this._$knockout,this._$hideObject)}_$isUpdated(){return this._$updated||this._$blurFilter._$isUpdated()}_$generateFilterRect(t,e=0,i=0){let s=Q(t.xMin,t.xMax,t.yMin,t.yMax);if(!this._$canApply())return s;s=this._$blurFilter._$generateFilterRect(s,e,i);const r=this._$angle*D;let n=v.cos(r)*this._$distance,a=v.sin(r)*this._$distance;return e&&(n*=e),i&&(a*=i),s.xMin=v.min(s.xMin,n),n>0&&(s.xMax+=n),s.yMin=v.min(s.yMin,a),a>0&&(s.yMax+=a),s}_$canApply(){return this._$alpha>0&&this._$strength>0&&this._$blurFilter._$canApply()}_$applyFilter(t,e){const i=t.frameBuffer,s=i.currentAttachment;if(!s)throw new Error("the current attachment is null.");if(t.setTransform(1,0,0,1,0,0),!this._$canApply())return i.getTextureFromCurrentAttachment();const r=s.width,n=s.height,a=t._$offsetX,h=t._$offsetY,o=this._$blurFilter._$applyFilter(t,e,!1),l=o.width,c=o.height,_=t._$offsetX,$=t._$offsetY,u=_-a,d=$-h;let g=v.sqrt(e[0]*e[0]+e[1]*e[1]),p=v.sqrt(e[2]*e[2]+e[3]*e[3]);g/=f,p/=f,g*=2,p*=2;const m=this._$angle*D,x=v.cos(m)*this._$distance*g,b=v.sin(m)*this._$distance*p,T=this._$inner?r:l+v.max(0,v.abs(x)-u),y=this._$inner?n:c+v.max(0,v.abs(b)-d),E=v.ceil(T),A=v.ceil(y),M=(E-T)/2,S=(A-y)/2,w=this._$inner?0:v.max(0,u-x)+M,C=this._$inner?0:v.max(0,d-b)+S,I=this._$inner?x-_:(x>0?v.max(0,x-u):0)+M,F=this._$inner?b-$:(b>0?v.max(0,b-d):0)+S;let R,B;return this._$inner?(R="inner",B=this._$knockout||this._$hideObject):!this._$knockout&&this._$hideObject?(R="full",B=!0):(R="outer",B=this._$knockout),t._$bind(s),t._$applyBitmapFilter(o,E,A,r,n,w,C,l,c,I,F,!0,R,B,this._$strength,null,null,null,vt(this._$color,this._$alpha,!0),Tt(this._$color,this._$alpha,!0),yt(this._$color,this._$alpha,!0),this._$alpha,0,0,0,0),t._$offsetX=a+w,t._$offsetY=h+C,i.releaseTexture(o),i.getTextureFromCurrentAttachment()}}class Wt extends Gt{constructor(t=0,e=1,i=4,s=4,r=1,n=1,a=!1,h=!1){super(),this._$blurFilter=new zt(i,s,n),this._$color=0,this._$alpha=1,this._$strength=1,this._$inner=!1,this._$knockout=!1,this.color=t,this.alpha=e,this.strength=r,this.inner=a,this.knockout=h}static toString(){return"[class GlowFilter]"}static get namespace(){return"next2d.filters.GlowFilter"}toString(){return"[object GlowFilter]"}get namespace(){return"next2d.filters.GlowFilter"}get alpha(){return this._$alpha}set alpha(t){(t=dt(+t,0,1,0))!==this._$alpha&&(this._$alpha=t,this._$doChanged())}get blurX(){return this._$blurFilter.blurX}set blurX(t){this._$blurFilter.blurX=t}get blurY(){return this._$blurFilter.blurY}set blurY(t){this._$blurFilter.blurY=t}get color(){return this._$color}set color(t){(t=dt(xt(t),0,16777215,4))!==this._$color&&(this._$color=t,this._$doChanged())}get inner(){return this._$inner}set inner(t){t!==this._$inner&&(this._$inner=!!t,this._$doChanged())}get knockout(){return this._$knockout}set knockout(t){t!==this._$knockout&&(this._$knockout=!!t,this._$doChanged())}get quality(){return this._$blurFilter.quality}set quality(t){this._$blurFilter.quality=t}get strength(){return this._$strength}set strength(t){(t=dt(0|t,0,255,0))!==this._$strength&&(this._$strength=t,this._$doChanged())}clone(){return new Wt(this._$color,this._$alpha,this._$blurFilter.blurX,this._$blurFilter.blurY,this._$strength,this._$blurFilter.quality,this._$inner,this._$knockout)}_$toArray(){return ht(6,this._$color,this._$alpha,this._$blurFilter.blurX,this._$blurFilter.blurY,this._$strength,this._$blurFilter.quality,this._$inner,this._$knockout)}_$isUpdated(){return this._$updated||this._$blurFilter._$isUpdated()}_$generateFilterRect(t,e=0,i=0){const s=Q(t.xMin,t.xMax,t.yMin,t.yMax);return this._$canApply()?this._$blurFilter._$generateFilterRect(s,e,i):s}_$canApply(){return this._$alpha>0&&this._$strength>0&&this._$blurFilter._$canApply()}_$applyFilter(t,e){const i=t.frameBuffer,s=i.currentAttachment;if(!s)throw new Error("the current attachment is null.");if(this._$updated=!1,t.setTransform(1,0,0,1,0,0),!this._$canApply())return i.getTextureFromCurrentAttachment();const r=s.width,n=s.height,a=t._$offsetX,h=t._$offsetY,o=this._$blurFilter._$applyFilter(t,e,!1),l=o.width,c=o.height,_=t._$offsetX,$=t._$offsetY,u=this._$inner?r:l,d=this._$inner?n:c,g=this._$inner?0:_-a,f=this._$inner?0:$-h,p=this._$inner?-_:0,m=this._$inner?-$:0,x=this._$inner?"inner":"outer";return t._$bind(s),t._$applyBitmapFilter(o,u,d,r,n,g,f,l,c,p,m,!0,x,this._$knockout,this._$strength,null,null,null,vt(this._$color,this._$alpha,!0),Tt(this._$color,this._$alpha,!0),yt(this._$color,this._$alpha,!0),this._$alpha,0,0,0,0),t._$offsetX=a+g,t._$offsetY=h+f,i.releaseTexture(o),i.getTextureFromCurrentAttachment()}}class Kt extends Gt{constructor(t=4,e=45,i=null,s=null,r=null,n=4,a=4,h=1,o=1,l="inner",c=!1){super(),this._$blurFilter=new zt(n,a,o),this._$distance=4,this._$angle=45,this._$colors=null,this._$alphas=null,this._$ratios=null,this._$strength=1,this._$type="inner",this._$knockout=!1,this.distance=t,this.angle=e,this.colors=i,this.alphas=s,this.ratios=r,this.strength=h,this.type=l,this.knockout=c}static toString(){return"[class GradientBevelFilter]"}static get namespace(){return"next2d.filters.GradientBevelFilter"}toString(){return"[object GradientBevelFilter]"}get namespace(){return"next2d.filters.GradientBevelFilter"}get alphas(){return this._$alphas}set alphas(t){if(t!==this._$alphas){if(this._$alphas=t,T.isArray(t)){for(let e=0;e0&&(s.xMax+=n),s.yMin=v.min(s.yMin,a),a>0&&(s.yMax+=a),s}_$canApply(){return this._$strength>0&&this._$distance>0&&null!==this._$alphas&&null!==this._$ratios&&null!==this._$colors&&this._$blurFilter._$canApply()}_$applyFilter(t,e){this._$updated=!1;const i=t.frameBuffer,s=i.currentAttachment;t.setTransform(1,0,0,1,0,0);const r=i.getTextureFromCurrentAttachment();if(!this._$canApply()||!s)return r;const n=s.width,a=s.height,h=t._$offsetX,o=t._$offsetY;let l=v.sqrt(e[0]*e[0]+e[1]*e[1]),c=v.sqrt(e[2]*e[2]+e[3]*e[3]);l/=f,c/=f,l*=2,c*=2;const _=+this._$angle*D,$=+v.cos(_)*this._$distance*l,u=+v.sin(_)*this._$distance*c,d=i.createTextureAttachment(n,a);t._$bind(d),t.reset(),t.drawImage(r,0,0,n,a),t.globalCompositeOperation="erase",t.drawImage(r,2*$,2*u,n,a);const g=this._$blurFilter._$applyFilter(t,e,!1),p=g.width,m=g.height,x=v.ceil(p+2*v.abs($)),b=v.ceil(m+2*v.abs(u)),T="inner"===this._$type,y=T?n:x,E=T?a:b,A=v.abs($),M=v.abs(u),S=(p-n)/2,w=(m-a)/2,C=T?0:A+S,I=T?0:M+w,F=T?-S-$:A-$,R=T?-w-u:M-u;return t._$bind(s),t._$applyBitmapFilter(g,y,E,n,a,C,I,p,m,F,R,!1,this._$type,this._$knockout,this._$strength,this._$ratios,this._$colors,this._$alphas,0,0,0,0,0,0,0,0),t._$offsetX=h+C,t._$offsetY=o+I,i.releaseAttachment(d,!0),i.getTextureFromCurrentAttachment()}}class Qt extends Gt{constructor(t=4,e=45,i=null,s=null,r=null,n=4,a=4,h=1,o=1,l="inner",c=!1){super(),this._$blurFilter=new zt(n,a,o),this._$distance=4,this._$angle=45,this._$colors=null,this._$alphas=null,this._$ratios=null,this._$strength=1,this._$type="inner",this._$knockout=!1,this.distance=t,this.angle=e,this.colors=i,this.alphas=s,this.ratios=r,this.strength=h,this.type=l,this.knockout=c}static toString(){return"[class GradientGlowFilter]"}static get namespace(){return"next2d.filters.GradientGlowFilter"}toString(){return"[object GradientGlowFilter]"}get namespace(){return"next2d.filters.GradientGlowFilter"}get alphas(){return this._$alphas}set alphas(t){if(t!==this._$alphas){if(this._$alphas=t,T.isArray(t)){for(let e=0;e0&&(s.xMax+=n),s.yMin=v.min(s.yMin,a),a>0&&(s.yMax+=a),s}_$canApply(){return this._$strength>0&&this._$distance>0&&null!==this._$alphas&&null!==this._$ratios&&null!==this._$colors&&this._$blurFilter._$canApply()}_$applyFilter(t,e){this._$updated=!1;const i=t.frameBuffer,s=i.currentAttachment;if(t.setTransform(1,0,0,1,0,0),!this._$canApply()||!s)return i.getTextureFromCurrentAttachment();const r=s.width,n=s.height,a=t._$offsetX,h=t._$offsetY,o=this._$blurFilter._$applyFilter(t,e,!1),l=o.width,c=o.height,_=t._$offsetX,$=t._$offsetY,u=_-a,d=$-h;let g=v.sqrt(e[0]*e[0]+e[1]*e[1]),p=v.sqrt(e[2]*e[2]+e[3]*e[3]);g/=f,p/=f,g*=2,p*=2;const m=+this._$angle*D,x=+v.cos(m)*this._$distance*g,b=+v.sin(m)*this._$distance*p,T="inner"===this.type,y=T?r:l+v.max(0,v.abs(x)-u),E=T?n:c+v.max(0,v.abs(b)-d),A=v.ceil(y),M=v.ceil(E),S=(A-y)/2,w=(M-E)/2,C=T?0:v.max(0,u-x)+S,I=T?0:v.max(0,d-b)+w,F=T?x-_:(x>0?v.max(0,x-u):0)+S,R=T?b-$:(b>0?v.max(0,b-d):0)+w;return t._$bind(s),t._$applyBitmapFilter(o,A,M,r,n,C,I,l,c,F,R,!0,this._$type,this._$knockout,this._$strength,this._$ratios,this._$colors,this._$alphas,0,0,0,0,0,0,0,0),t._$offsetX=a+C,t._$offsetY=h+I,i.releaseTexture(o),i.getTextureFromCurrentAttachment()}}class Jt{constructor(t){this._$displayObject=t,this._$matrix=null,this._$colorTransform=null,this._$blendMode=null,this._$filters=null}static toString(){return"[class Transform]"}static get namespace(){return"next2d.geom.Transform"}toString(){return"[object Transform]"}get namespace(){return"next2d.geom.Transform"}get colorTransform(){if(this._$colorTransform)return this._$colorTransform._$clone();const t=this._$displayObject,e=t._$placeObject||t._$getPlaceObject();if(e&&e.colorTransform){const t=e.colorTransform;return dr(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7])}return this._$transform(),this._$colorTransform||(this._$colorTransform=dr()),this._$colorTransform._$clone()}set colorTransform(t){this._$transform(null,t._$colorTransform)}get concatenatedColorTransform(){let t=this._$rawColorTransform(),e=this._$displayObject._$parent;for(;e;)t=ft(e._$transform._$rawColorTransform(),t),e=e._$parent;return dr(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7])}get matrix(){if(this._$matrix)return this._$matrix._$clone();const t=this._$displayObject,e=t._$placeObject||t._$getPlaceObject();if(e&&e.matrix){const t=e.matrix;return $r(t[0],t[1],t[2],t[3],t[4],t[5])}return this._$transform(),this._$matrix||(this._$matrix=$r()),this._$matrix._$clone()}set matrix(t){this._$transform(t._$matrix,null)}get concatenatedMatrix(){let t=this._$rawMatrix(),e=this._$displayObject._$parent;for(;e;)t=gt(e._$transform._$rawMatrix(),t),e=e._$parent;return $r(t[0],t[1],t[2],t[3],t[4],t[5])}pixelBounds(){if(!this._$displayObject)return new Vt(0,0,0,0);const t=this._$displayObject._$getBounds(null),e=new Vt(t.xMin,t.yMin,+v.abs(t.xMax-t.xMin),+v.abs(t.yMax-t.yMin));return J(t),e}_$rawMatrix(){if(null!==this._$matrix)return this._$matrix._$matrix;const t=this._$displayObject,e=t._$placeObject||t._$getPlaceObject();if(e&&e.matrix){if(T.isArray(e.matrix)){const t=e.matrix;e.matrix=it(t[0],t[1],t[2],t[3],t[4],t[5]),ot(t)}return e.matrix}return P}_$rawColorTransform(){if(null!==this._$colorTransform)return this._$colorTransform._$colorTransform;const t=this._$displayObject,e=t._$placeObject||t._$getPlaceObject();if(e&&e.colorTransform){if(T.isArray(e.colorTransform)){const t=e.colorTransform;e.colorTransform=rt(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7]),ot(t)}return e.colorTransform}return k}_$transform(t=null,e=null,i=null,s=""){const r=this._$displayObject,n=r._$placeObject||r._$getPlaceObject();this._$setMatrix(t,n),this._$setColorTransform(e,n),this._$setFilters(i,n),this._$setBlendMode(s,n)}_$setMatrix(t=null,e=null){if((t||e)&&(this._$displayObject._$doChanged(),x()),this._$matrix||(this._$matrix=$r(1,0,0,1,0,0),!t&&e&&e.matrix&&(t=e.matrix)),t){const e=this._$matrix._$matrix;e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5]}}_$setColorTransform(t=null,e=null){if((t||e)&&(this._$displayObject._$doChanged(),x()),this._$colorTransform||(this._$colorTransform=dr(1,1,1,1,0,0,0,0),!t&&e&&e.colorTransform&&(t=e.colorTransform)),t){const e=this._$colorTransform._$colorTransform;e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7]}}_$setFilters(t=null,e=null){if(T.isArray(t))return this._$filters&&ot(this._$filters),this._$filters=t.slice(0),this._$displayObject._$doChanged(),void x();if(!this._$filters)if(e){if(e.filters){this._$filters=e.filters.slice(0);for(let t=0;t-1){const e="_$getBounds"in this&&"function"==typeof this._$getBounds?this._$getBounds():Q(),i=this.rotation,s=i?pt(e,this._$transform._$rawMatrix()):e;i&&J(e);const r=v.abs(s.yMax-s.yMin);switch(J(s),r){case 0:case b:case-1/0:this.scaleY=0;break;default:this.scaleY=t/r}}}get loaderInfo(){return this._$loaderInfo}get mask(){return this._$mask}set mask(t){t!==this._$mask&&(this._$mask&&(Mr&&this._$mask.stage&&this._$mask._$removeWorkerInstance(),this._$mask._$isMask=!1,this._$mask=null),t&&(Mr&&"_$createWorkerInstance"in t&&"function"==typeof t._$createWorkerInstance&&t._$createWorkerInstance(),t._$isMask=!0,this._$mask=t),this._$doChanged())}get mouseX(){return l()?this.globalToLocal(_r()).x:0}get mouseY(){return l()?this.globalToLocal(_r()).y:0}get name(){return this._$name?this._$name:`instance${this._$instanceId}`}set name(t){this._$name=`${t}`;const e=this._$parent;if(e&&e._$names){e._$names.clear();const t=e._$getChildren();for(let i=0;it[0]?-1*e:e}set scaleX(t){if(t=dt(+t,N,O),!E.isInteger(t)){const e=t.toString(),i=e.indexOf("e");-1!==i&&(t=+e.slice(0,i)),t=+t.toFixed(4)}if(this._$scaleX===t)return;const e=this._$transform,i=null!==e._$matrix,s=i?e._$matrix:e.matrix;if(0===s.b||C(s.b))s.a=t;else{let e=v.atan2(s.b,s.a);e===-v.PI&&(e=0),s.b=t*v.sin(e),s.a=t*v.cos(e)}i?(this._$doChanged(),x()):(e.matrix=s,ur(s)),this._$scaleX=t}get scaleY(){if(null!==this._$scaleY)return this._$scaleY;const t=this._$transform._$rawMatrix();let e=v.sqrt(t[2]*t[2]+t[3]*t[3]);if(!E.isInteger(e)){const t=e.toString(),i=t.indexOf("e");-1!==i&&(e=+t.slice(0,i)),e=+e.toFixed(4)}return 0>t[3]?-1*e:e}set scaleY(t){if(t=dt(+t,N,O),!E.isInteger(t)){const e=t.toString(),i=e.indexOf("e");-1!==i&&(t=+e.slice(0,i)),t=+t.toFixed(4)}if(this._$scaleY===t)return;const e=this._$transform,i=null!==e._$matrix,s=i?e._$matrix:e.matrix;if(0===s.c||C(s.c))s.d=t;else{let e=v.atan2(-s.c,s.d);e===-v.PI&&(e=0),s.c=-t*v.sin(e),s.d=t*v.cos(e)}i?(this._$doChanged(),x()):(e.matrix=s,ur(s)),this._$scaleY=t}get stage(){if(this._$stage)return this._$stage;const t=this._$parent;return t?t._$stage:null}get transform(){return this._$transform}set transform(t){this._$transform=t}get visible(){return this._$visible}set visible(t){this._$visible!==t&&(this._$visible=!!t,this._$doChanged(),x())}get width(){const t="_$getBounds"in this&&"function"==typeof this._$getBounds?this._$getBounds():Q(),e=pt(t,this._$transform._$rawMatrix());J(t);const i=v.abs(e.xMax-e.xMin);switch(J(e),!0){case 0===i:case i===b:case i===-1/0:return 0;default:return+i.toFixed(2)}}set width(t){if(!C(t=+t)&&t>-1){const e="_$getBounds"in this&&"function"==typeof this._$getBounds?this._$getBounds():Q(),i=this.rotation,s=i?pt(e,this._$transform._$rawMatrix()):e;i&&J(e);const r=v.abs(s.xMax-s.xMin);switch(J(s),!0){case 0===r:case r===b:case r===-1/0:this.scaleX=0;break;default:this.scaleX=t/r}}}get x(){return this._$transform._$rawMatrix()[4]}set x(t){const e=this._$transform;if(e._$matrix)e._$matrix.tx=t,this._$doChanged(),x();else{const i=e.matrix;i.tx=t,e.matrix=i,ur(i)}}get y(){return this._$transform._$rawMatrix()[5]}set y(t){const e=this._$transform;if(e._$matrix)e._$matrix.ty=t,this._$doChanged(),x();else{const i=e.matrix;i.ty=t,e.matrix=i,ur(i)}}getBounds(t=null){const e="_$getBounds"in this&&"function"==typeof this._$getBounds?this._$getBounds():Q(),i=this._$transform.concatenatedMatrix,s=pt(e,i._$matrix);ur(i),J(e);const r=Q(s.xMin,s.xMax,s.yMin,s.yMax);J(s),t||(t=this);const n=t._$transform.concatenatedMatrix;n.invert();const a=pt(r,n._$matrix);J(r),ur(n);const h=a.xMin,o=a.yMin,l=a.xMax,c=a.yMax;return J(a),new Vt(h,o,v.abs(l-h),v.abs(c-o))}globalToLocal(t){const e=this._$transform.concatenatedMatrix;e.invert();const i=new Dt(t.x*e.a+t.y*e.c+e.tx,t.x*e.b+t.y*e.d+e.ty);return ur(e),i}hitTestObject(t){const e="_$getBounds"in this&&"function"==typeof this._$getBounds?this._$getBounds():Q(),i=this._$transform.concatenatedMatrix,s=pt(e,i._$matrix);ur(i),J(e);const r=t._$getBounds(null),n=t._$transform.concatenatedMatrix,a=pt(r,n._$matrix);ur(n),J(r);const h=v.max(s.xMin,a.xMin),o=v.max(s.yMin,a.yMin),l=v.min(s.xMax,a.xMax),c=v.min(s.yMax,a.yMax);return J(s),J(a),l-h>=0&&c-o>=0}hitTestPoint(t,e,i=!1){if(i){let i=P,s=this._$parent;for(;s;)i=gt(s._$transform._$rawMatrix(),i),s=s._$parent;rr.setTransform(1,0,0,1,0,0),rr.beginPath();let r=!1;return"_$hit"in this&&"function"==typeof this._$hit&&(r=this._$hit(rr,i,{x:t,y:e},!0)),i!==P&&st(i),r}const s="_$getBounds"in this&&"function"==typeof this._$getBounds?this._$getBounds():Q(),r=pt(s,this._$transform._$rawMatrix());J(s);const n=new Vt(r.xMin,r.yMin,r.xMax-r.xMin,r.yMax-r.yMin);J(r);const a=this._$parent?this._$parent.globalToLocal(new Dt(t,e)):new Dt(t,e);return n.containsPoint(a)}localToGlobal(t){const e=this._$transform.concatenatedMatrix,i=new Dt(t.x*e.a+t.y*e.c+e.tx,t.x*e.b+t.y*e.d+e.ty);return ur(e),i}getLocalVariable(t){return this._$variables?this._$variables.has(t)?this._$variables.get(t):void 0:null}setLocalVariable(t,e){this._$variables||(this._$variables=ct()),this._$variables.set(t,e)}hasLocalVariable(t){return!!this._$variables&&this._$variables.has(t)}deleteLocalVariable(t){this._$variables&&this._$variables.has(t)&&(this._$variables.delete(t),this._$variables.size||(lt(this._$variables),this._$variables=null))}getGlobalVariable(t){return Os.has(t)?Os.get(t):null}setGlobalVariable(t,e){Os.set(t,e)}hasGlobalVariable(t){return Os.has(t)}deleteGlobalVariable(t){Os.has(t)&&Os.delete(t)}clearGlobalVariable(){return Os.clear()}_$getPlaceObject(){if(!this._$placeObject){const t=this._$placeId;if(-1===t)return null;const e=this._$parent;if(!e||!e._$placeObjects)return null;const i=e._$placeMap;if(!i||!i.length)return null;const s=i["currentFrame"in e?e.currentFrame:1];if(!s)return null;const r=0|s[t],n=e._$placeObjects[r];return n?(this._$changePlace=r!==this._$currentPlaceId,this._$currentPlaceId=r,this._$placeObject=n,n):null}return this._$placeObject}_$baseBuild(t,e){const i=e._$loaderInfo;if(!i||!i._$data)throw new Error("the loaderInfo or data is nul.");return this._$parent=e,this._$root=e._$root,this._$stage=e._$stage,this._$loaderInfo=i,this._$characterId=0|t.characterId,this._$clipDepth=0|t.clipDepth,this._$startFrame=0|t.startFrame,this._$endFrame=0|t.endFrame,this._$name=t.name||"",i._$data.characters[t.characterId]}_$isUpdated(){return this._$updated}_$updateState(){this._$isNext=!0;const t=this._$parent;t&&t._$updateState()}_$doChanged(){this._$posted=!1,this._$isNext=!0,this._$updated=!0;const t=this._$parent;t&&(t._$updated||t._$doChanged())}_$drawFilter(t,e,i,s,r,n=null){const a=ht(this._$instanceId,"f");let h=St.get(a);const o=this._$isFilterUpdated(e,i,!0);if(h&&!o)return t.cachePosition=h,h;h&&St.set(a,null);const l=t.frameBuffer,c=n||t.getTextureFromRect(t.cachePosition),_=this._$applyFilter(t,i,c,e,s,r);l.textureManager.release(c);const $=this._$getLayerBounds(e);return h=l.createCachePosition(v.ceil(v.abs($.xMax-$.xMin)),v.ceil(v.abs($.yMax-$.yMin))),J($),h.filterState=!0,h.matrix=`${e[0]}_${e[1]}_${e[2]}_${e[3]}_0_0`,h.offsetX=_.offsetX,h.offsetY=_.offsetY,t.drawTextureFromRect(_,h),St.set(a,h),ot(a),h}_$getLayerBounds(t){const e="_$getBounds"in this&&"function"==typeof this._$getBounds?this._$getBounds():Q(),i=pt(e,t);J(e);const s=this._$filters||this.filters;if(!s.length)return i;let r=Q(0,v.abs(i.xMax-i.xMin),0,v.abs(i.yMax-i.yMin));J(i);let n=+v.sqrt(t[0]*t[0]+t[1]*t[1]),a=+v.sqrt(t[2]*t[2]+t[3]*t[3]);n/=f,a/=f,n*=2,a*=2;for(let t=0;t-1&&(t.depth=this._$placeId),this._$clipDepth&&(t.clipDepth=this._$clipDepth),this._$isMask&&(t.isMask=this._$isMask);const e=this._$mask;if(e){t.maskId=e._$instanceId;let i=P,s=e._$parent;for(;s;)i=gt(s._$transform._$rawMatrix(),i),s=s._$parent;t.maskMatrix=i}if(this._$visible){const e=this._$transform,i=e._$rawMatrix();1!==i[0]&&(t.a=i[0]),0!==i[1]&&(t.b=i[1]),0!==i[2]&&(t.c=i[2]),1!==i[3]&&(t.d=i[3]),0!==i[4]&&(t.tx=i[4]),0!==i[5]&&(t.ty=i[5]);const s=e._$rawColorTransform();1!==s[0]&&(t.f0=s[0]),1!==s[1]&&(t.f1=s[1]),1!==s[2]&&(t.f2=s[2]),1!==s[3]&&(t.f3=s[3]),0!==s[4]&&(t.f4=s[4]),0!==s[5]&&(t.f5=s[5]),0!==s[6]&&(t.f6=s[6]),0!==s[7]&&(t.f7=s[7]);const r=this._$filters||this.filters;if(r&&r.length){const e=ht();for(let t=0;tt._$names.size&&t._$names.has(e)?t._$names.get(e):t[e]})}get mouseChildren(){return this._$mouseChildren}set mouseChildren(t){this._$mouseChildren=!!t}get numChildren(){return this._$needsChildren?this._$getChildren().length:this._$children.length}addChild(t){return t._$parent&&t._$parent._$remove(t,!(t._$parent._$instanceId===this._$instanceId)),this._$getChildren().push(t),t._$name&&this._$names.set(t._$name,t),this._$addChild(t)}addChildAt(t,e){t._$parent&&t._$parent._$remove(t,!(t._$parent._$instanceId===this._$instanceId));const i=this._$getChildren(),s=i.length;if(0>e||e>s)throw new RangeError(`RangeError: addChildAt: index error: ${e}`);if(s&&s>e){i.splice(e,0,t);for(let t=0;tt||t>e.length)throw new RangeError(`RangeError: getChildAt: index error: ${t}`);return t in e?e[t]:null}getChildByName(t){if(!t)return null;const e=this._$getChildren();for(let i=0;it;--s)this._$remove(i[s])}}setChildIndex(t,e){const i=this.getChildIndex(t);if(i===e)return;const s=this._$getChildren();s.splice(i,1),s.splice(e,0,t),Mr&&this._$postChildrenIds(),this._$doChanged()}swapChildren(t,e){const i=this._$getChildren(),s=this.getChildIndex(t),r=this.getChildIndex(e);i[s]=e,i[r]=t,Mr&&this._$postChildrenIds(),this._$doChanged()}swapChildrenAt(t,e){this.swapChildren(this.getChildAt(t),this.getChildAt(e))}_$getBounds(t=null){let e=P;if(t){e=t;const i=this._$transform._$rawMatrix();1===i[0]&&0===i[1]&&0===i[2]&&1===i[3]&&0===i[4]&&0===i[5]||(e=gt(t,i))}const i=this._$needsChildren?this._$getChildren():this._$children;if(!i.length){const i=Q(e[4],-e[4],e[5],-e[5]);return t&&e!==t&&st(e),i}const s=E.MAX_VALUE;let r=s,n=-s,a=s,h=-s;for(let t=0;te){if(l._$isNext=!0,l._$placeObject=null,l._$filters=null,l._$blendMode=null,-1===l._$id){h.push(l),l._$name&&this._$names.set(l._$name,l);continue}const t=i[a];if(l._$id===t){l._$placeId=a,h.push(l),l._$name&&this._$names.set(l._$name,l),n.has(t)&&n.delete(t),r.set(t,!0),a++,s&&l._$postProperty();continue}n.set(l._$id,l)}else s&&l._$removeWorkerInstance(),St.setRemoveTimer(_),l._$loaderInfo&&l._$characterId&&St.setRemoveTimer(`${l._$loaderInfo._$id}@${l._$characterId}`),l._$graphics&&St.setRemoveTimer(l._$graphics._$uniqueKey),l.willTrigger(It.REMOVED)&&l.dispatchEvent(new It(It.REMOVED,!0)),l.willTrigger(It.REMOVED_FROM_STAGE)&&l.dispatchEvent(new It(It.REMOVED_FROM_STAGE,!0)),l._$added=!1,l._$addedStage=!1,l._$active=!1,l._$updated=!0,l._$filters=null,l._$blendMode=null,l._$isNext=!0,l._$placeObject=null,l._$created=!1,l._$posted=!1,l instanceof ee&&(l._$executeRemovedFromStage(),l._$removeParentAndStage())}if(i)for(let t=0;t-1;--e)t[e]._$prepareActions();this._$executeAddedEvent()}_$nextFrame(){let t=!1;const e=this._$getChildren();for(let i=e.length-1;i>-1;--i){const s=e[i];s._$isNext&&(t?s._$nextFrame():t=s._$nextFrame())}return this._$executeAddedEvent(),this._$isNext=t,!this._$posted&&Mr&&this._$postProperty(),this._$isNext}_$clip(t,e){let i=e;const s=this._$transform._$rawMatrix();1===s[0]&&0===s[1]&&0===s[2]&&1===s[3]&&0===s[4]&&0===s[5]||(i=gt(e,s));const r=this._$getChildren();for(let e=0;e0||"normal"!==a){const s=this._$getBounds(null),h=pt(s,i);J(s);const o=+h.xMax,l=+h.xMin,c=+h.yMax,_=+h.yMin;J(h);const $=v.ceil(v.abs(o-l)),u=v.ceil(v.abs(c-_));if(0>=$||0>=u)return Mt(r),i!==e&&st(i),null;let d=+v.sqrt(i[0]*i[0]+i[1]*i[1]);if(!E.isInteger(d)){const t=d.toString(),e=t.indexOf("e");-1!==e&&(d=+t.slice(0,e)),d=+d.toFixed(4)}let g=+v.sqrt(i[2]*i[2]+i[3]*i[3]);if(!E.isInteger(g)){const t=g.toString(),e=t.indexOf("e");-1!==e&&(g=+t.slice(0,e)),g=+g.toFixed(4)}r.canApply=this._$canApply(n);let f=Q(0,$,0,u);if(r.canApply&&n)for(let t=0;tp.width||_-f.yMin>p.height)return J(f),Mt(r),i!==e&&st(i),null;if(0>l+f.xMax||0>_+f.yMax)return J(f),Mt(r),i!==e&&st(i),null;let m=i[4]-l,x=i[5]-_;t._$startLayer(Q(l,o,_,c));const b=this._$isFilterUpdated(i,n,r.canApply),T=this._$getLayerBounds(i),y=v.ceil(v.abs(T.xMax-T.xMin)),A=v.ceil(v.abs(T.yMax-T.yMin));J(T);const M=y-f.xMax+f.xMin,S=A-f.yMax+f.yMin;m+=M,x+=S,r.sw=M,r.sh=S,b&&t._$saveAttachment(v.ceil($+M),v.ceil(u+S),!0),r.isLayer=!0,r.isUpdated=b,r.filters=n,r.blendMode=a,r.color=rt(),r.matrix=it(i[0],i[1],i[2],i[3],m,x),i!==e&&st(i),J(f)}return r}_$postDraw(t,e,i,s){t.drawInstacedArray();const r=ht(this._$instanceId,"f"),n=t.frameBuffer,a=s.matrix;let h=0,o=0,l=St.get(r);if(!l||s.isUpdated){l&&St.set(r,null),l=n.getTextureFromCurrentAttachment();const i=s.filters;let c=!1;if(i&&i.length){for(let s=0;s_||i._$clipDepth>0)&&(t.restore(),c&&t._$leaveClip(),_=0,c=!0),!c)continue;if(i._$clipDepth>0){_=i._$clipDepth,c=i._$shouldClip(o),c&&(t.save(),c=i._$startClip(t,o));continue}const r=i._$mask;if(r){let e;if(r._$updated=!1,this===r._$parent)e=o;else{e=P;let i=r._$parent;for(;i;)e=gt(i._$transform._$rawMatrix(),e),i=i._$parent;const s=$.scaleX,n=it(s,0,0,s,0,0);if(e=gt(n,e),st(n),t.isLayer){const i=t.getCurrentPosition();e[4]-=i.xMin,e[5]-=i.yMin}}if(!r._$shouldClip(e))continue;const i=r._$startClip(t,e);if(t.save(),!i){t.restore();continue}}i._$draw(t,o,l),i._$updated=!1,r&&(t.restore(),t._$leaveClip())}if(_&&(t.restore(),c&&t._$leaveClip()),h.isLayer)return this._$postDraw(t,e,s,h);h.matrix!==e&&st(h.matrix),s!==i&&nt(s),Mt(h)}_$mouseHit(t,e,i,s=!0){let r=e;const n=this._$transform._$rawMatrix();n!==P&&(r=gt(e,n));const a=this._$getChildren(),h=ht(),o=ht(),l=ct();let c=0,_=0;for(let t=0;tc&&(_=0,c=0),_&&l.set(e._$instanceId,_),o.push(e)))}const $=this._$mouseChildren&&s;let u=!1;const d=this._$root===this;for(;o.length;){const e=o.pop();if(e._$isMask)continue;if(d&&!(e instanceof te))continue;if(l.has(e._$instanceId)){const s=l.get(e._$instanceId);if(!s)continue;if(!h[s]._$hit(t,r,i,!0))continue}const s=e._$mask;if(s)if(this===s._$parent){if(!s._$hit(t,r,i,!0))continue}else{let e=P,r=s._$parent;for(;r;)e=gt(r._$transform._$rawMatrix(),e),r=r._$parent;if(!s._$hit(t,e,i,!0))continue}if(e._$mouseHit(t,r,i,$)||e._$hitArea&&e._$hitArea._$mouseHit(t,r,i,$)){if(e._$root===e)return!0;if(!$)return!0;if(u=!0,e instanceof te){if(!e.mouseEnabled&&!e._$hitObject)continue;return Zs||i.pointer||("_$text"in e&&"type"in e&&"input"===e.type&&(i.pointer="text"),"buttonMode"in e&&"useHandCursor"in e&&e.buttonMode&&e.useHandCursor&&(i.pointer="pointer")),i.hit||(i.hit=!e.mouseEnabled&&e._$hitObject?e._$hitObject:e),!0}}}return ot(h),ot(o),lt(l),r!==e&&st(r),u}_$hit(t,e,i,s=!1){let r=e;const n=this._$transform._$rawMatrix();n!==P&&(r=gt(e,n));const a=this._$getChildren();for(let e=a.length;e>-1;--e){const n=a[e];if(!n._$isMask&&n._$hit(t,r,i,s))return!0}return r!==e&&st(r),!1}_$createInstance(t){if(!this._$dictionary)throw new Error("the dictionary is null.");const e=this._$dictionary[t],i=this._$loaderInfo;if(!i||!i._$data)throw new Error("the loaderInfo or data is null.");const s=i._$data.characters[e.characterId],r=Ar(s.extends);return r._$build(e,this),r._$id=t,r}_$outCheck(t,e){let i=P,s=this._$parent;for(;s;)i=gt(s._$transform._$rawMatrix(),i),s=s._$parent;rr.setTransform(1,0,0,1,0,0),rr.beginPath();const r={x:t,y:e,pointer:"",hit:null};return this._$mouseHit(rr,i,r)}_$createWorkerInstance(){if(this._$created||!Mr)return;this._$created=!0,this._$posted=!0,this._$updated=!1;let t=0;const e=hr();e[t++]=this._$instanceId,e[t++]=this._$parent?this._$parent._$instanceId:-1,this._$registerProperty(e,2);const i=or();i.command="createDisplayObjectContainer",i.buffer=e;const s=ht(e.buffer);Mr.postMessage(i,s),lr(i),ot(s),this._$postChildrenIds()}_$postProperty(){if(!Mr)return;this._$postChildrenIds();const t=ht(),e=this._$createMessage();Mr.postMessage(e,t),ot(t),this._$posted=!0,this._$updated=!1}_$postChildrenIds(t=null){if(!Mr||!this._$created)return;let e=!1;if(!t){const i=this._$getChildren();t=ht();for(let e=0;eo||a>l)&&(h._$width=n,h._$height=a,h._$resizeCanvas(n,a,h.scaleX));const c=i?i._$colorTransform:k;let _=e?e._$matrix:P;if(e){const e=t._$transform.matrix;e.invert(),_=gt(_,e._$matrix),ur(e)}if(s||(s=St.getCanvas()),Mr){t._$stage||(t instanceof ee?wr&&wr(t):(t._$createWorkerInstance(),t._$postProperty())),s.width=n,s.height=a;const e=s.getContext("2d");if(!e)throw new Error("the context is null.");e.setTransform(1,0,0,1,0,0),e.clearRect(0,0,n,a);const i=t._$instanceId;Hs.set(i,{source:t,context:e,callback:r});const h=ht(),o={command:"bitmapDraw",sourceId:i,width:n,height:a};1===_[0]&&0===_[1]&&0===_[2]&&1===_[3]&&0===_[4]&&0===_[5]||(o.matrix=_.slice(),h.push(o.matrix.buffer)),1===c[0]&&1===c[1]&&1===c[2]&&1===c[3]&&0===c[4]&&0===c[5]&&0===c[6]&&0===c[7]||(o.colorTransform=c.slice(),h.push(o.colorTransform.buffer)),Mr.postMessage(o,h),ot(h)}else{const e=h.context;if(!e)throw new Error("the context is null.");e.reset(),e.setTransform(1,0,0,1,0,0),e._$setColor(0,0,0,0),e.clearRect(0,0,h._$width,h._$height),e.beginPath(),t._$draw(e,_,c),e.drawInstacedArray(),e.frameBuffer.transferToMainTexture(),s.width=n,s.height=a;const i=s.getContext("2d");if(!i)return;i.setTransform(1,0,0,1,0,0),i.clearRect(0,0,n,a),i.drawImage(h.canvas,0,0),r&&r(s)}e&&ur(e),i&&gr(i)}}class se extends Ft{constructor(t,e){super(),this._$name=`${t}`,this._$frame=0|e}static toString(){return"[class FrameLabel]"}static get namespace(){return"next2d.display.FrameLabel"}toString(){return"[object FrameLabel]"}get namespace(){return"next2d.display.FrameLabel"}get frame(){return this._$frame}get name(){return this._$name}}class re{constructor(t,e=null,i=!0,s=!1){this._$bitmapData=t,this._$matrix=e,this._$repeat=i,this._$smooth=s}clone(){return new re(this._$bitmapData.clone(),this._$matrix?this._$matrix.clone():null,this._$repeat,this._$smooth)}toArray(){return ht(this._$bitmapData,this._$matrix,this._$repeat,this._$smooth)}}class ne{constructor(t,e,i,s,r=null,n="pad",a="rgb",h=0){this._$type=t,this._$colors=e,this._$alphas=i,this._$ratios=s,this._$matrix=r,this._$spreadMethod=n,this._$interpolationMethod=a,this._$focalPointRatio=h,this._$colorStops=ht()}get colorStops(){if(!this._$colorStops.length){const t=v.min(v.min(this._$alphas.length,this._$colors.length),this._$ratios.length);for(let e=0;e7)switch(this._$recode||(this._$recode=ht()),this._$fills[2]===this._$fills[this._$fills.length-2]&&this._$fills[3]===this._$fills[this._$fills.length-1]||this._$fills.push(ae.LINE_TO,this._$fills[2],this._$fills[3]),this._$recode.push(...this._$fills),this._$fillType){case ae.FILL_STYLE:this._$recode.push(this._$fillType,this._$fillStyleR,this._$fillStyleG,this._$fillStyleB,this._$fillStyleA,ae.END_FILL);break;case ae.GRADIENT_FILL:this._$fillGradient&&this._$recode.push(this._$fillType,...this._$fillGradient.toArray());break;case ae.BITMAP_FILL:this._$fillBitmap&&this._$recode.push(this._$fillType,...this._$fillBitmap.toArray())}return this._$fills&&(ot(this._$fills),this._$fills=null),this._$fillType=0,this._$fillGradient=null,this._$fillBitmap=null,this._$fillStyleR=0,this._$fillStyleG=0,this._$fillStyleB=0,this._$fillStyleA=0,this._$doFill=!1,this._$restart(),this}endLine(){if(this._$doLine&&this._$lines)switch(this._$recode||(this._$recode=ht()),this._$recode.push(...this._$lines),ot(this._$lines),this._$lines=null,this._$lineType){case ae.STROKE_STYLE:this._$recode.push(this._$lineType,this._$lineWidth,this._$caps,this._$joints,this._$miterLimit,this._$lineStyleR,this._$lineStyleG,this._$lineStyleB,this._$lineStyleA,ae.END_STROKE);break;case ae.GRADIENT_STROKE:this._$lineGradient&&this._$recode.push(this._$lineType,this._$lineWidth,this._$caps,this._$joints,this._$miterLimit,...this._$lineGradient.toArray());break;case ae.BITMAP_STROKE:this._$fillBitmap&&this._$recode.push(this._$lineType,this._$lineWidth,this._$caps,this._$joints,this._$miterLimit,...this._$fillBitmap.toArray())}return this._$lineType=0,this._$lineWidth=0,this._$lineGradient=null,this._$lineStyleR=0,this._$lineStyleG=0,this._$lineStyleB=0,this._$lineStyleA=0,this._$caps="none",this._$joints="round",this._$miterLimit=0,this._$doLine=!1,this._$restart(),this}lineBitmapStyle(t,e=null,i=!0,s=!1){return this._$doLine&&this.endLine(),this._$lines||(this._$lines=ht()),this._$maxAlpha=1,this._$doLine=!0,this._$canDraw=!0,this._$lines.push(ae.BEGIN_PATH),this._$lineType=ae.BITMAP_STROKE,this._$fillBitmap=new re(t,e,i,s),this}lineGradientStyle(t,e,i,s,r=null,n="pad",a="rgb",h=0){if(!this._$doLine)return this;this._$lines||(this._$lines=ht());for(let t=0;t0&&a._$canApply(r);let T=Q(0,g,0,f);if(x&&r)for(let t=0;tA.width||d-T.yMin>A.height)return void J(T);if(0>$+T.xMax||0>d+T.yMax)return void J(T);J(T),""===this._$uniqueKey&&(!h&&a._$loaderInfo&&a._$characterId?this._$uniqueKey=`${a._$loaderInfo._$id}@${this._$bitmapId||a._$characterId}`:this._$uniqueKey=this._$createCacheKey());const M=cr();if("bitmap"===this._$mode)this._$cacheKeys.length||(this._$cacheKeys=St.generateKeys(this._$uniqueKey));else if(!this._$cacheKeys.length||this._$cacheParams[0]!==p||this._$cacheParams[1]!==m||this._$cacheParams[2]!==i[7]){const t=ht();t[0]=p,t[1]=m,this._$cacheKeys=St.generateKeys(this._$uniqueKey,t,i),ot(t),this._$cacheParams[0]=p,this._$cacheParams[1]=m,this._$cacheParams[2]=i[7]}if(t.cachePosition=St.get(this._$cacheKeys),!t.cachePosition){const s=y.currentAttachment;s&&s.mask&&t.stopStencil();let r=0,n=0;if("shape"===this._$mode){r=v.ceil(v.abs(l.xMax-l.xMin)*p),n=v.ceil(v.abs(l.yMax-l.yMin)*m);const e=t._$getTextureScale(r,n);e<1&&(r*=e,n*=e)}else r=v.ceil(v.abs(l.xMax-l.xMin)),n=v.ceil(v.abs(l.yMax-l.yMin));if(t.cachePosition=y.createCachePosition(r,n),t.bindRenderBuffer(t.cachePosition),t.reset(),"shape"===this._$mode?t.setTransform(p,0,0,m,-l.xMin*p,-l.yMin*m):t.setTransform(1,0,0,1,-l.xMin,-l.yMin),h){const i=M.scaleX,s=it(i,0,0,i,0,0),r=gt(s,o);st(s);const n=a._$parent._$transform.concatenatedMatrix._$matrix,h=it(n[0],n[1],n[2],n[3],n[4]*i-$,n[5]*i-d);st(n);const c=gt(h,r),_=c[4]-(e[4]-$),u=c[5]-(e[5]-d);st(c);const g=pt(l,r),f=+g.xMax,p=+g.xMin,m=+g.yMax,x=+g.yMin,b=v.ceil(v.abs(f-p)),T=v.ceil(v.abs(m-x));J(g);const y=a._$scale9Grid,E={x:y.x,y:y.y,w:y.width,h:y.height};t.grid.enable(p,x,b,T,l,E,i,r[0],r[1],r[2],r[3],r[4],r[5],h[0],h[1],h[2],h[3],h[4]-_,h[5]-u),st(r),st(h)}this._$doDraw(t,i,!1),h&&t.grid.disable(),y.transferTexture(t.cachePosition),St.set(this._$cacheKeys,t.cachePosition),t._$bind(s)}let S=0,w=0;if(x){const i=this._$createBitmapTexture(t,t.cachePosition,p,m,g,f),s=a._$drawFilter(t,e,r,g,f,i);s.offsetX&&(S=s.offsetX),s.offsetY&&(w=s.offsetY),t.cachePosition=s}if(x||"bitmap"!==this._$mode){const i=v.atan2(e[1],e[0]),s=v.atan2(-e[2],e[3]);if(x||!i&&!s)t.setTransform(1,0,0,1,$-S,d-w);else{const r=l.xMin*p,n=l.yMin*m,a=v.cos(i),h=v.sin(i),o=v.cos(s),c=v.sin(s);t.setTransform(a,h,-c,o,r*a-n*c+e[4],r*h+n*o+e[5])}}else t.setTransform(e[0],e[1],e[2],e[3],l.xMin*e[0]+l.yMin*e[2]+e[4],l.xMin*e[1]+l.yMin*e[3]+e[5]);t.cachePosition&&(t.globalAlpha=n,t.imageSmoothingEnabled="shape"===this._$mode,t.globalCompositeOperation=s,t.drawInstance($-S,d-w,_,u,i),t.cachePosition=null),J(l)}_$createBitmapTexture(t,e,i,s,r,n){if("bitmap"!==this._$mode)return null;t.drawInstacedArray();const a=t.frameBuffer,h=a.currentAttachment,o=a.createCacheAttachment(r,n);t._$bind(o),t.reset();const l=it(i,0,0,s,r/2,n/2),c=t.getTextureFromRect(e),_=it(1,0,0,1,-c.width/2,-c.height/2),$=gt(l,_);st(l),st(_),t.setTransform($[0],$[1],$[2],$[3],$[4],$[5]),t.drawImage(c,0,0,c.width,c.height);const u=a.getTextureFromCurrentAttachment();return t._$bind(h),a.releaseAttachment(o),a.textureManager.release(c),u}_$doDraw(t,e=null,i=!1){t.reset(),t.beginPath(),this._$runCommand(t,e,i)}_$hit(t,e,i,s=!1){return t.beginPath(),t.setTransform(e[0],e[1],e[2],e[3],e[4],e[5]),this._$runCommand(t,null,s,i)}_$getBounds(){const t=this._$displayObject;return t&&t._$bounds?Q(t._$bounds.xMin,t._$bounds.xMax,t._$bounds.yMin,t._$bounds.yMax):Q(this._$xMin,this._$xMax,this._$yMin,this._$yMax)}_$restart(){this._$displayObject&&(this._$displayObject._$posted=!1,this._$displayObject._$isUpdated()||(this._$displayObject._$doChanged(),x(),St.removeCache(this._$displayObject._$instanceId),this._$displayObject._$characterId&&St.removeCache(this._$displayObject._$characterId)))}_$setBounds(t=0,e=0){this._$setFillBounds(t,e),this._$doLine&&this._$setLineBounds(t,e)}_$setFillBounds(t=0,e=0){this._$xMin=v.min(this._$xMin,t),this._$xMax=v.max(this._$xMax,t),this._$yMin=v.min(this._$yMin,e),this._$yMax=v.max(this._$yMax,e)}_$setLineBounds(t=0,e=0){this._$xMin=v.min(this._$xMin,v.min(t,this._$pointerX)),this._$xMax=v.max(this._$xMax,v.max(t,this._$pointerX)),this._$yMin=v.min(this._$yMin,v.min(e,this._$pointerY)),this._$yMax=v.max(this._$yMax,v.max(e,this._$pointerY));const i=this._$lineWidth/2,s=.5*v.PI,r=v.atan2(e-this._$pointerY,t-this._$pointerX),n=v.atan2(this._$pointerY-e,this._$pointerX-t),a=r+s,h=r-s,o=n+s,l=n-s;let c=t+i,_=-i+t,$=this._$pointerX+i,u=-i+this._$pointerX,d=e+i,g=-i+e,f=this._$pointerY+i,p=-i+this._$pointerY;switch(this._$xMin=v.min(this._$xMin,v.min(c,v.min(_,v.min($,u)))),this._$xMax=v.max(this._$xMax,v.max(c,v.max(_,v.max($,u)))),this._$yMin=v.min(this._$yMin,v.min(d,v.min(g,v.min(f,p)))),this._$yMax=v.max(this._$yMax,v.max(d,v.max(g,v.max(f,p)))),v.abs(a)%s!=0&&(c=t+v.cos(a)*i),v.abs(h)%s!=0&&(_=t+v.cos(h)*i),v.abs(o)%s!=0&&($=this._$pointerX+v.cos(o)*i),v.abs(l)%s!=0&&(u=this._$pointerX+v.cos(l)*i),a&&v.abs(a)%v.PI!=0&&(d=e+v.sin(a)*i),h&&v.abs(h)%v.PI!=0&&(g=e+v.sin(h)*i),o&&v.abs(o)%v.PI!=0&&(f=this._$pointerY+v.sin(o)*i),l&&v.abs(l)%v.PI!=0&&(p=this._$pointerY+v.sin(l)*i),this._$xMin=v.min(this._$xMin,v.min(c,v.min(_,v.min($,u)))),this._$xMax=v.max(this._$xMax,v.max(c,v.max(_,v.max($,u)))),this._$yMin=v.min(this._$yMin,v.min(d,v.min(g,v.min(f,p)))),this._$yMax=v.max(this._$yMax,v.max(d,v.max(g,v.max(f,p)))),this._$caps){case"round":if(v.abs(r)%s!=0){const e=t+v.cos(r)*i;this._$xMin=v.min(this._$xMin,e),this._$xMax=v.max(this._$xMax,e)}if(r&&v.abs(r)%v.PI!=0){const t=e+v.sin(r)*i;this._$yMin=v.min(this._$yMin,t),this._$yMax=v.max(this._$yMax,t)}if(v.abs(n)%s!=0){const t=this._$pointerX+v.cos(n)*i;this._$xMin=v.min(this._$xMin,t),this._$xMax=v.max(this._$xMax,t)}if(n&&v.abs(n)%v.PI!=0){const t=this._$pointerY+v.sin(n)*i;this._$yMin=v.min(this._$yMin,t),this._$yMax=v.max(this._$yMax,t)}break;case"square":if(v.abs(r)%s!=0){const t=v.cos(r)*i,e=c+t,s=_+t;this._$xMin=v.min(this._$xMin,v.min(e,s)),this._$xMax=v.max(this._$xMax,v.max(e,s))}if(v.abs(n)%s!=0){const t=v.cos(n)*i,e=$+t,s=u+t;this._$xMin=v.min(this._$xMin,v.min(e,s)),this._$xMax=v.max(this._$xMax,v.max(e,s))}if(r&&v.abs(r)%v.PI!=0){const t=v.sin(r)*i,e=d+t,s=g+t;this._$yMin=v.min(this._$yMin,v.min(e,s)),this._$yMax=v.max(this._$yMax,v.max(e,s))}if(n&&v.abs(n)%v.PI!=0){const t=v.sin(n)*i,e=f+t,s=p+t;this._$yMin=v.min(this._$yMin,v.min(e,s)),this._$yMax=v.max(this._$yMax,v.max(e,s))}}}_$margePath(t){this._$doFill&&this._$fills&&this._$fills.push(...t),this._$doLine&&this._$lines&&this._$lines.push(...t),ot(t)}_$createCacheKey(){if(this._$doLine&&this.endLine(),this._$doFill&&this.endFill(),!this._$recode)return"";const t=this._$getRecodes();let e=0;for(let i=0;i{_=t})(dt(t,0,1,1));const e=$(),i=cr(),s=i._$sources;for(let t=0;t{this._$loadStart(t)},progress:t=>{this._$progress(t)},loadend:t=>{this._$loadEnd(t)}}})}_$loadStart(t){this._$bytesLoaded=t.loaded,this._$bytesTotal=t.total,this.willTrigger(It.OPEN)&&this.dispatchEvent(new It(It.OPEN)),this.willTrigger(kt.PROGRESS)&&this.dispatchEvent(new kt(kt.PROGRESS,!1,!1,t.loaded,t.total))}_$progress(t){this._$bytesLoaded=t.loaded,this._$bytesTotal=t.total,this.willTrigger(kt.PROGRESS)&&this.dispatchEvent(new kt(kt.PROGRESS,!1,!1,t.loaded,t.total))}_$loadEnd(t){this._$bytesLoaded=t.loaded,this._$bytesTotal=t.total,this.willTrigger(kt.PROGRESS)&&this.dispatchEvent(new kt(kt.PROGRESS,!1,!1,t.loaded,t.total));const e=t.target;if(!e)throw new Error("the Sound target is null.");199e.status?(this._$arrayBuffer=e.response,Ns?pr(this).then((t=>{(t.hasEventListener(It.INIT)||t.hasEventListener(It.COMPLETE))&&cr()._$loaders.push(t)})):Xs.push(this)):this.willTrigger(Lt.IO_ERROR)&&this.dispatchEvent(new Lt(Lt.IO_ERROR,!1,!1,e.statusText))}play(t=0){const e=this._$character?this._$character.audioBuffer:this._$audioBuffer;if(Ns&&e)this._$createBufferSource(t);else{const e=R.now(),i=()=>{if(null===(this._$character?this._$character.audioBuffer:this._$audioBuffer)||null===Ns)I(i);else{const i=(R.now()-e)/1e3;this._$createBufferSource(t,i)}};I(i)}}stop(){this._$stopFlag=!0;const t=this._$sources.length;if(t){const e=cr();if(Ns)for(let e=0;e{(t.hasEventListener(It.INIT)||t.hasEventListener(It.COMPLETE))&&cr()._$loaders.push(t)})):Xs.push(this)),this._$loopCount=0|t.loopCount,this._$volume=v.min(oe.volume,t.volume)}_$createBufferSource(t=0,e=0){if(!Ns)throw new Error("the Audio Context is null.");const i=Ns.createBufferSource();i.onended=t=>this._$endEventHandler(t),i.buffer=this._$character?this._$character.audioBuffer:this._$audioBuffer,i._$gainNode=Ns.createGain(),i._$gainNode.connect(Ns.destination);const s=v.min(oe.volume,this._$volume);i._$gainNode.gain.value=s,i._$volume=s,i.connect(i._$gainNode),i.start(0|t,e);const r=cr();-1===r._$sources.indexOf(this)&&r._$sources.push(this),this._$sources.push(i),this._$stopFlag=!1}_$endEventHandler(t){const e=t.target;if(this._$sources.splice(this._$sources.indexOf(e),1),!this._$stopFlag&&this._$loopCount>this._$currentCount)this._$createBufferSource(),this._$currentCount++;else{if(this._$currentCount=0,Ns&&(e._$gainNode&&(e._$gainNode.gain.value=0,e._$gainNode.disconnect(),e._$gainNode=null),e.onended=null,e.disconnect()),!this._$sources.length){const t=cr();t._$sources.splice(t._$sources.indexOf(this),1)}this.willTrigger(It.SOUND_COMPLETE)&&this.dispatchEvent(new It(It.SOUND_COMPLETE))}}}class ce{constructor(t=1,e=!1){this._$volume=1,this._$loop=!1,this.volume=t,this.loop=e}static toString(){return"[class SoundTransform]"}static get namespace(){return"next2d.media.SoundTransform"}toString(){return"[object SoundTransform]"}get namespace(){return"next2d.media.SoundTransform"}get loop(){return this._$loop}set loop(t){this._$loop=t}get volume(){return this._$volume}set volume(t){this._$volume=dt(+t,0,1,0)}}class _e extends Zt{constructor(t=0,e=0){super(),this._$smoothing=!0,this._$loop=!1,this._$autoPlay=!0,this._$bounds=Q(0,t,0,e),this._$bytesLoaded=0,this._$bytesTotal=0,this._$timerId=-1,this._$video=null,this._$stop=!0,this._$ready=!1,this._$volume=1,this._$context=null,this._$cacheKeys=ht(),this._$cacheParams=ht(0,0,0)}static toString(){return"[class Video]"}static get namespace(){return"next2d.media.Video"}toString(){return"[object Video]"}get namespace(){return"next2d.media.Video"}get bytesLoaded(){return this._$bytesLoaded}get bytesTotal(){return this._$bytesTotal}get currentTime(){return this._$video?this._$video.currentTime:0}get duration(){return this._$video?this._$video.duration:0}get loop(){return this._$loop}set loop(t){this._$loop=!!t}get autoPlay(){return this._$autoPlay}set autoPlay(t){this._$autoPlay=!!t}get smoothing(){return this._$smoothing}set smoothing(t){this._$smoothing=!!t}get src(){return this._$video?this._$video.src:""}set src(t){this._$video||(this._$video=this._$initializeVideo()),this._$video.src=t,this._$video.load()}get videoHeight(){return this._$video?this._$video.videoHeight:this._$bounds.yMax}get videoWidth(){return this._$video?this._$video.videoWidth:this._$bounds.xMax}get volume(){return this._$volume}set volume(t){this._$volume=dt(v.min(oe.volume,t),0,1,1),this._$video&&(this._$video.volume=this._$volume)}clear(){this._$video&&this._$video.pause(),this._$video=null,this._$bounds.xMax=0,this._$bounds.yMax=0,this._$doChanged()}pause(){if(this._$video&&!this._$stop){this._$stop=!0,this._$video.pause(),F(this._$timerId),this._$timerId=-1,this.hasEventListener(Nt.PAUSE)&&this.dispatchEvent(new Nt(Nt.PAUSE,!1,!1,this._$bytesLoaded,this._$bytesTotal));const t=cr();t._$videos.splice(t._$videos.indexOf(this),1)}}play(){this._$video&&this._$stop&&(this._$stop=!1,this._$video.volume=v.min(this._$volume,oe.volume),this._$video.play().then((()=>{this._$timerId=I((()=>{this._$update()})),this.hasEventListener(Nt.PLAY)&&this.dispatchEvent(new Nt(Nt.PLAY,!1,!1,this._$bytesLoaded,this._$bytesTotal));const t=cr();-1===t._$videos.indexOf(this)&&t._$videos.push(this),this._$ready=!0})))}seek(t){this._$video&&(this._$video.currentTime=t,this.hasEventListener(Nt.SEEK)&&this.dispatchEvent(new Nt(Nt.SEEK,!1,!1,this._$bytesLoaded,this._$bytesTotal)))}_$update(){const t=cr();if(!this.stage||!this._$video)return this._$video&&this._$video.pause(),F(this._$timerId),this._$timerId=-1,void t._$videos.splice(t._$videos.indexOf(this),1);Mr&&this._$postProperty(),this._$bytesLoaded=this._$video.currentTime,this._$video.currentTime&&(this.hasEventListener(Nt.PROGRESS)&&this.dispatchEvent(new Nt(Nt.PROGRESS,!1,!1,this._$bytesLoaded,this._$bytesTotal)),this._$doChanged()),this._$timerId=I((()=>{this._$update()}))}_$start(){if(!this._$video)return;this._$bounds.xMax=this._$video.videoWidth,this._$bounds.yMax=this._$video.videoHeight,this._$bytesTotal=this._$video.duration;const t=cr();this._$autoPlay&&(this._$stop=!1,this._$video.play().then((()=>{-1===t._$videos.indexOf(this)&&t._$videos.push(this),this.hasEventListener(Nt.PLAY_START)&&this.dispatchEvent(new Nt(Nt.PLAY_START,!1,!1,this._$bytesLoaded,this._$bytesTotal)),this._$timerId=I((()=>{this._$update()})),this._$ready=!0,this._$doChanged()}))),this._$createContext()}_$initializeVideo(){this._$cacheKeys.length=0;const t=d.createElement("video");return t.autoplay=!1,t.crossOrigin="anonymous",Ns||(t.muted=!0),Zs&&t.setAttribute("playsinline",""),t.addEventListener("canplaythrough",(()=>{this._$start()})),t.addEventListener("ended",(()=>{this._$loop?t.currentTime=0:(this.hasEventListener(Nt.PLAY_END)&&this.dispatchEvent(new Nt(Nt.PLAY_END,!1,!1,this._$bytesLoaded,this._$bytesTotal)),F(this._$timerId),this._$timerId=-1)})),t}_$createContext(){if(Mr){const t=new w(this._$bounds.xMax,this._$bounds.yMax);this._$context=t.getContext("2d")}}_$buildCharacter(t){t.buffer&&!t._$buffer&&(t._$buffer=new Uint8Array(t.buffer),t.buffer=null),this._$loop=t.loop,this._$autoPlay=t.autoPlay,this._$bounds.xMin=t.bounds.xMin,this._$bounds.yMin=t.bounds.yMin,this._$bounds.xMax=t.bounds.xMax,this._$bounds.yMax=t.bounds.yMax,this._$video||(this._$video=this._$initializeVideo()),this._$video.src=URL.createObjectURL(new Blob([t._$buffer],{type:"video/mp4"})),this._$video.volume=v.min(t.volume,oe.volume),this._$video.load(),Mr&&this._$stage&&this._$createWorkerInstance()}_$sync(t){this._$buildCharacter(t)}_$build(t,e){const i=this._$baseBuild(t,e);return this._$buildCharacter(i),i}_$clip(t,e){const i=this._$bounds.xMax,s=this._$bounds.yMax;if(!i||!s)return;let r=e;const n=this._$transform._$rawMatrix();1===n[0]&&0===n[1]&&0===n[2]&&1===n[3]&&0===n[4]&&0===n[5]||(r=gt(e,n)),t.reset(),t.setTransform(r[0],r[1],r[2],r[3],r[4],r[5]),t.beginPath(),t.moveTo(0,0),t.lineTo(i,0),t.lineTo(i,s),t.lineTo(0,s),t.lineTo(0,0),t.clip(),r!==e&&st(r)}_$draw(t,e,i){if(!this._$visible||!this._$video||!this._$ready)return;let s=i;const r=this._$transform._$rawColorTransform();1===r[0]&&1===r[1]&&1===r[2]&&1===r[3]&&0===r[4]&&0===r[5]&&0===r[6]&&0===r[7]||(s=ft(i,r));const n=dt(s[3]+s[7]/255,0,1,0);if(!n)return void(s!==i&&nt(s));let a=e;const h=this._$transform._$rawMatrix();1===h[0]&&0===h[1]&&0===h[2]&&1===h[3]&&0===h[4]&&0===h[5]||(a=gt(e,h));const o=pt(this._$bounds,a),l=+o.xMax,c=+o.xMin,_=+o.yMax,$=+o.yMin;J(o);const u=v.ceil(v.abs(l-c)),d=v.ceil(v.abs(_-$));switch(!0){case 0===u:case 0===d:case u===-1/0:case d===-1/0:case u===b:case d===b:return}let g=+v.sqrt(a[0]*a[0]+a[1]*a[1]);if(!E.isInteger(g)){const t=g.toString(),e=t.indexOf("e");-1!==e&&(g=+t.slice(0,e)),g=+g.toFixed(4)}let f=+v.sqrt(a[2]*a[2]+a[3]*a[3]);if(!E.isInteger(f)){const t=f.toString(),e=t.indexOf("e");-1!==e&&(f=+t.slice(0,e)),f=+f.toFixed(4)}const p=this._$filters||this.filters,m=p&&p.length>0&&this._$canApply(p);let x=Q(0,u,0,d);if(m)for(let t=0;ty.width||$-x.yMin>y.height)return void J(x);if(0>c+x.xMax||0>$+x.yMax)return void J(x);if(J(x),!this._$cacheKeys.length||this._$cacheParams[0]!==g||this._$cacheParams[1]!==f||this._$cacheParams[2]!==i[7]){const t=ht();t[0]=g,t[1]=f,this._$cacheKeys=St.generateKeys(this._$instanceId,t,i),ot(t),this._$cacheParams[0]=g,this._$cacheParams[1]=f,this._$cacheParams[2]=i[7]}const A=this._$blendMode||this.blendMode;if(t.cachePosition=St.get(this._$cacheKeys),!t.cachePosition){const e=v.ceil(v.abs(this._$bounds.xMax-this._$bounds.xMin)),i=v.ceil(v.abs(this._$bounds.yMax-this._$bounds.yMin)),s=T.createCachePosition(e,i);t.cachePosition=s,St.set(this._$cacheKeys,s)}const M=T.createTextureFromVideo(this._$video,this._$smoothing);let S=0,w=0;if(m){const e=T.currentAttachment,i=T.createCacheAttachment(u,d);t._$bind(i),t.reset();const s=it(g,0,0,f,u/2,d/2),r=it(1,0,0,1,-M.width/2,-M.height/2),n=gt(s,r);st(s),st(r),t.setTransform(n[0],n[1],n[2],n[3],n[4],n[5]),t.drawImage(M,0,0,M.width,M.height);const h=T.getTextureFromCurrentAttachment();t._$bind(e),T.releaseAttachment(i),t.drawTextureFromRect(M,t.cachePosition);const o=this._$drawFilter(t,a,p,u,d,h);o.offsetX&&(S=o.offsetX),o.offsetY&&(w=o.offsetY),t.cachePosition=o,t.setTransform(1,0,0,1,c-S,$-w)}else t.drawTextureFromRect(M,t.cachePosition),t.setTransform(a[0],a[1],a[2],a[3],a[4],a[5]);t.cachePosition&&(t.globalAlpha=n,t.imageSmoothingEnabled=!0,t.globalCompositeOperation=A,t.drawInstance(c-S,$-w,l,_,i),t.cachePosition=null),a!==e&&st(a),s!==i&&nt(s)}_$mouseHit(t,e,i){return!!this._$visible&&this._$hit(t,e,i)}_$hit(t,e,i){let s=e;const r=this._$transform._$rawMatrix();r!==P&&(s=gt(e,r));const n=this._$getBounds(null),a=pt(n,s),h=+a.xMax,o=+a.xMin,l=+a.yMax,c=+a.yMin;J(a),J(n);const _=v.ceil(v.abs(h-o)),$=v.ceil(v.abs(l-c));return t.setTransform(1,0,0,1,o,c),t.beginPath(),t.moveTo(0,0),t.lineTo(_,0),t.lineTo(_,$),t.lineTo(0,$),t.lineTo(0,0),s!==e&&st(s),t.isPointInPath(i.x,i.y)}_$getBounds(t=null){if(t){let e=t;const i=this._$transform._$rawMatrix();1===i[0]&&0===i[1]&&0===i[2]&&1===i[3]&&0===i[4]&&0===i[5]||(e=gt(t,i));const s=pt(this._$bounds,e);return e!==t&&st(e),s}return Q(this._$bounds.xMin,this._$bounds.xMax,this._$bounds.yMin,this._$bounds.yMax)}_$createWorkerInstance(){if(!Mr||this._$created)return;this._$created=!0;const t={command:"createVideo",buffer:new Float32Array,instanceId:this._$instanceId,parentId:this._$parent?this._$parent._$instanceId:-1,smoothing:this._$smoothing,xMin:this._$bounds.xMin,yMin:this._$bounds.yMin,xMax:this._$bounds.xMax,yMax:this._$bounds.yMax};this._$characterId>-1&&(t.characterId=this._$characterId),this._$loaderInfo&&(t.loaderInfoId=this._$loaderInfo._$id),this._$scale9Grid&&(t.grid={x:this._$scale9Grid.x,y:this._$scale9Grid.y,w:this._$scale9Grid.width,h:this._$scale9Grid.height}),Mr.postMessage(t)}_$postProperty(){if(!Mr)return;const t=this._$createMessage();t.smoothing=this._$smoothing;const e=ht(),i=this._$context;if(i&&this._$video){t.xMin=this._$bounds.xMin,t.yMin=this._$bounds.yMin,t.xMax=this._$bounds.xMax,t.yMax=this._$bounds.yMax,i.drawImage(this._$video,0,0);const s=i.canvas.transferToImageBitmap();t.imageBitmap=s,e.push(s)}Mr.postMessage(t,e),ot(e),this._$posted=!0,this._$updated=!1}}class $e extends ee{constructor(){super(),this._$buttonMode=!1,this._$hitArea=null,this._$soundTransform=null,this._$useHandCursor=!0}static toString(){return"[class Sprite]"}static get namespace(){return"next2d.display.Sprite"}toString(){return"[object Sprite]"}get namespace(){return"next2d.display.Sprite"}get buttonMode(){return this._$buttonMode}set buttonMode(t){this._$buttonMode=!!t}get dropTarget(){return Ds}get hitArea(){return this._$hitArea}set hitArea(t){this._$hitArea&&(this._$hitArea._$hitObject=null),this._$hitArea=t,t&&(t._$hitObject=this)}get soundTransform(){return this._$soundTransform||(this._$soundTransform=new ce),this._$soundTransform}set soundTransform(t){this._$soundTransform=t}get useHandCursor(){return this._$useHandCursor}set useHandCursor(t){this._$useHandCursor=t}startDrag(t=!1,e=null){let i=0,s=0;if(!t){const t=this._$dragMousePoint();i=this.x-t.x,s=this.y-t.y}Us(this),Vs.lock=t,Vs.position.x=i,Vs.position.y=s,Vs.bounds=e}stopDrag(){Us(null),Vs.lock=!1,Vs.position.x=0,Vs.position.y=0,Vs.bounds=null}_$sync(t){Mr&&this._$stage&&this._$createWorkerInstance(),this._$controller=t.controller,this._$dictionary=t.dictionary,this._$placeMap=t.placeMap,this._$placeObjects=t.placeObjects}_$build(t,e){const i=this._$baseBuild(t,e);return Mr&&this._$stage&&this._$createWorkerInstance(),this._$controller=i.controller,this._$dictionary=i.dictionary,this._$placeMap=i.placeMap,this._$placeObjects=i.placeObjects,i}_$dragMousePoint(){return this._$parent?this._$parent.globalToLocal(_r()):this.globalToLocal(_r())}}class ue extends $e{constructor(){super(),this._$stopFlag=!1,this._$canAction=!0,this._$canSound=!0,this._$actionProcess=!1,this._$actions=ct(),this._$frameCache=ct(),this._$labels=null,this._$sounds=ct(),this._$actionOffset=0,this._$actionLimit=0,this._$currentFrame=1,this._$totalFrames=1,this._$isPlaying=!1,this._$loopConfig=null,this._$tweenFrame=0}static toString(){return"[class MovieClip]"}static get namespace(){return"next2d.display.MovieClip"}toString(){return"[object MovieClip]"}get namespace(){return"next2d.display.MovieClip"}get currentFrame(){return this._$currentFrame}get currentFrameLabel(){if(!this._$labels)return null;const t=this._$currentFrame;return this._$labels.has(t)&&this._$labels.get(t)||null}get currentLabels(){return this._$labels&&this._$labels.size?T.from(this._$labels.values()):null}get isPlaying(){return this._$isPlaying}get totalFrames(){return this._$totalFrames}get loopConfig(){if(this._$loopConfig)return this._$loopConfig;const t=this._$placeObject||this._$getPlaceObject();return t&&t.loop?(this._$tweenFrame&&(this._$changePlace=this._$tweenFrame!==this._$parent._$currentFrame,this._$tweenFrame=0),t.loop.tweenFrame&&(this._$tweenFrame=t.loop.tweenFrame),t.loop):null}set loopConfig(t){this._$loopConfig=t,t&&(t.frame=this._$startFrame,this._$loopConfig=t,this._$currentFrame=this._$getLoopFrame(t))}gotoAndPlay(t){this.play(),this._$goToFrame(t)}gotoAndStop(t){this.stop(),this._$goToFrame(t)}nextFrame(){this.stop(),this._$totalFrames>this._$currentFrame&&this._$goToFrame(this._$currentFrame+1)}play(){this._$stopFlag=!1,this._$isPlaying=!0,this._$updateState()}prevFrame(){const t=this._$currentFrame-1;t&&(this.stop(),this._$goToFrame(t))}stop(){this._$stopFlag=!0,this._$isPlaying=!1}addFrameLabel(t){this._$labels||(this._$labels=ct()),this._$labels.set(t.frame,t)}addFrameScript(...t){for(let e=0;e=s&&this._$addAction(s,r),s===this._$currentFrame){const t=cr();if(t._$actionOffset=t._$actions.length,this._$canAction=!0,this._$setAction(),t._$actionOffset!==t._$actions.length){const e=t._$actions.splice(0,t._$actionOffset);t._$actions.push(...t._$actions,...e),t._$actionOffset=0}}}}_$getFrameForLabel(t){if(!this._$labels)return 0;for(const[e,i]of this._$labels)if(i.name===t)return e;return 0}_$addAction(t,e){if(t){this._$actions.has(t)||this._$actions.set(t,ht());const i=this._$actions.get(t);i&&i.push(e)}}_$setAction(){if(this._$executeAddedEvent(),this._$canAction){const t=this._$currentFrame;if(this._$labels&&this._$labels.has(t)){const e=this._$labels.get(t);e&&e.willTrigger(It.FRAME_LABEL)&&e.dispatchEvent(new It(It.FRAME_LABEL))}if(this._$actions.size&&this._$actions.has(t)){const t=cr();-1===t._$actions.indexOf(this)&&t._$actions.push(this)}}}_$goToFrame(t){let e=+t;if(C(e)&&(e=this._$getFrameForLabel(`${t}`)),e<1&&(e=1),e>this._$totalFrames)return this._$currentFrame=this._$totalFrames,this._$clearChildren(),this._$canAction=!1,void(this._$wait=!1);const i=cr();switch(!0){case e!==this._$currentFrame:{this._$wait=!1;const t=this._$currentFrame;this._$actionProcess&&(this._$frameCache.set("nextFrame",e),this._$frameCache.set("stopFlag",this._$stopFlag),this._$frameCache.set("isPlaying",this._$isPlaying)),this._$currentFrame=e,this._$clearChildren(),i._$actionOffset=i._$actions.length;const s=i._$actionOffset?i._$actions.indexOf(this):-1;if(this._$canAction=!0,this._$prepareActions(),i._$actionOffset&&i._$actionOffset!==i._$actions.length){const t=i._$actions.splice(0,i._$actionOffset);i._$actions.push(...i._$actions,...t),i._$actionOffset=0}if(!this._$actionProcess&&(s>-1||!i._$actionOffset))for(;i._$actions.length&&i._$actions.length!==s;){const t=i._$actions.pop();if(!t)continue;t._$canAction=!1,t._$actionOffset=0,t._$actionLimit=0,t._$actionProcess&&t._$frameCache.size&&(t._$currentFrame=t._$frameCache.get("nextFrame"),t._$clearChildren(),t._$stopFlag=t._$frameCache.get("stopFlag"),t._$isPlaying=t._$frameCache.get("isPlaying"),t._$frameCache.clear());const e=t._$currentFrame;if(!t._$actions.has(e))continue;const s=t._$actions.get(e);if(s)for(let e=0;e-1:{if(!this._$actionLimit)break;this._$wait=!1;const t=i._$actions.splice(this._$actionOffset,this._$actionLimit);for(;t.length;){const e=t.pop();if(!e)continue;e._$canAction=!1,e._$actionOffset=0,e._$actionLimit=0;const i=e._$currentFrame;if(!e._$actions.has(i))continue;const s=e._$actions.get(i);if(s)for(let t=0;t-1;--e)t[e]._$prepareActions();this._$setAction()}_$nextFrame(){let t=this._$needsChildren;switch(!0){case this._$wait:t=!0,this._$wait=!1;break;case this._$stopFlag:case 1===this._$totalFrames:break;default:{t=!0,this._$canAction=!0,this._$canSound=!0;const e=this.loopConfig;if(e){const i=e.end?e.end:this._$totalFrames;switch(e.type){case 0:this._$changePlace?this._$currentFrame=e.start:(++this._$currentFrame,this._$currentFrame>i&&(this._$currentFrame=e.start));break;case 1:this._$changePlace?this._$currentFrame=e.start:(++this._$currentFrame,this._$currentFrame>i&&(this._$currentFrame=i,t=!1,this._$canAction=!1,this._$canSound=!1));break;case 2:this._$changePlace?this._$currentFrame=e.start:(t=!1,this._$canAction=!1,this._$canSound=!1);break;case 3:this._$changePlace?this._$currentFrame=i:(--this._$currentFrame,e.start>this._$currentFrame&&(this._$currentFrame=e.start,t=!1,this._$canAction=!1,this._$canSound=!1));break;case 4:this._$changePlace?this._$currentFrame=i:(--this._$currentFrame,e.start>this._$currentFrame&&(this._$currentFrame=i))}}else++this._$currentFrame,this._$currentFrame>this._$totalFrames&&(this._$currentFrame=1);if(t&&this._$clearChildren(),this._$canSound&&this._$sounds.size&&this._$sounds.has(this._$currentFrame)){const t=cr();t._$sounds.has(this._$instanceId)||t._$sounds.set(this._$instanceId,this)}}}const e=this._$needsChildren?this._$getChildren():this._$children;for(let i=e.length-1;i>-1;--i){const s=e[i];s._$isNext&&(t?s._$nextFrame():t=s._$nextFrame())}return this._$setAction(),this._$isNext=t,!this._$posted&&Mr&&this._$postProperty(),this._$isNext}_$getLoopFrame(t){const e=this._$parent._$currentFrame-t.frame;let i=1;switch(t.type){case 0:{const s=t.end?t.end:this._$totalFrames;i=t.start;for(let r=0;rs&&(i=t.start)}break;case 1:{const s=t.end?t.end:this._$totalFrames;i=v.min(s,t.start+e)}break;case 2:i=t.start;break;case 3:i=t.end?t.end:this._$totalFrames,i=v.max(t.start,i-e);break;case 4:{const s=t.end?t.end:this._$totalFrames;i=s;for(let r=0;ri&&(i=s)}}return i}_$buildCharacter(t){if(t.sounds)for(let e=0;e{this._$loadstart(t)},progress:t=>{this._$progress(t)},loadend:t=>{this._$loadend(t)}}}))}loadJSON(t){if("zlib"===t.type){if(Pr())return void Ir.push(t);Lr(!0);const e=Rr(),i=new Uint8Array(t.buffer);e.onmessage=t=>{this._$unzipHandler(t)},e.postMessage(i,[i.buffer])}else this._$build(t)}_$loadend(t){const e=this._$loaderInfo;if(!e)return;e.bytesLoaded=t.loaded,e.bytesTotal=t.total,e.willTrigger(kt.PROGRESS)&&e.dispatchEvent(new kt(kt.PROGRESS,!1,!1,t.loaded,t.total));const i=t.target;if(e.willTrigger(Bt.HTTP_STATUS)){const t=Tr(i.getAllResponseHeaders());e.dispatchEvent(new Bt(Bt.HTTP_STATUS,!1,!1,i.status,i.responseURL,t))}199i.status?"json"===e.format?this.loadJSON(i.response):e.willTrigger(Lt.IO_ERROR)&&e.dispatchEvent(new Lt(Lt.IO_ERROR,!1,!1,"LoaderInfo format is `json`")):e.willTrigger(Lt.IO_ERROR)&&e.dispatchEvent(new Lt(Lt.IO_ERROR,!1,!1,i.statusText))}_$unzipHandler(t){if(this._$build(t.data),Ir.length){const t=Ir.pop();if(!t)return;const e=new Uint8Array(t.buffer),i=Rr();i.onmessage=t=>{this._$unzipHandler(t)},i.postMessage(e,[e.buffer])}else Lr(!1)}_$loadstart(t){const e=this._$loaderInfo;e&&(e.bytesLoaded=t.loaded,e.bytesTotal=t.total,e.willTrigger(It.OPEN)&&e.dispatchEvent(new It(It.OPEN)),e.willTrigger(kt.PROGRESS)&&e.dispatchEvent(new kt(kt.PROGRESS,!1,!1,t.loaded,t.total)))}_$progress(t){const e=this._$loaderInfo;e&&(e.bytesLoaded=t.loaded,e.bytesTotal=t.total,e.willTrigger(kt.PROGRESS)&&e.dispatchEvent(new kt(kt.PROGRESS,!1,!1,t.loaded,t.total)))}_$build(t){const e=this._$loaderInfo;if(!e)return;const i=ct();if(t.symbols.length)for(let e=0;e{const t=e.width,i=e.height,s=new ie(t,i);s.image=e,this.graphics.beginBitmapFill(s).drawRect(0,0,t,i),this.hasEventListener(It.LOAD)&&this.dispatchEvent(new It(It.LOAD))})),this._$src=e.src=t,this.graphics._$mode="bitmap"}_$buildCharacter(t,e){const i=this.graphics;if(!e._$data)throw new Error("the loaderInfo data is null.");if(t.recodes)switch(!0){case t.bitmapId>0:{const s=e._$data.characters[t.bitmapId];if(!s.buffer)throw new Error("the bitmap buffer is null.");const r=v.abs(s.bounds.xMax-s.bounds.xMin),n=v.abs(s.bounds.yMax-s.bounds.yMin),a=new ie(r,n);s._$buffer||(s._$buffer=new Uint8Array(s.buffer),ot(s.buffer),s.buffer=null),a.buffer=s._$buffer.slice(),i._$recode=ht(),r===t.bounds.xMax-t.bounds.xMin&&n===t.bounds.yMax-t.bounds.yMin&&(i._$bitmapId=t.bitmapId,i._$mode="bitmap");const h=t.recodes;if(h[h.length-1]===ae.END_FILL){const t=h.length-6;for(let e=0;e0&&i._$canDraw){i._$posted=!0;const e=or(),s=i._$getRecodes();e.command=`shapeRecodes@${this._$instanceId}`,e.buffer=s;const r=ht(s.buffer);Mr.postMessage(e,r),lr(e),ot(r),t[2]=i._$maxAlpha,t[3]=+i._$canDraw}const s=this._$getBounds();t[e++]=s.xMin,t[e++]=s.yMin,t[e++]=s.xMax,t[e++]=s.yMax,t[e++]=this._$characterId>-1?this._$characterId:-1,t[e++]=this._$loaderInfo?this._$loaderInfo._$id:-1,this._$registerProperty(t,10);const r=or();r.command="createShape",r.buffer=t;const n=ht(t.buffer);Mr.postMessage(r,n),lr(r),ot(n)}_$postProperty(){if(!this._$created||!Mr)return;const t=this._$createMessage(),e=this._$graphics;if(e&&!e._$posted){t.maxAlpha=e._$maxAlpha,t.canDraw=e._$canDraw;const i=e._$getRecodes();t.recodes=i;const s=ht(i.buffer),r=this._$getBounds();t.xMin=r.xMin,t.yMin=r.yMin,t.xMax=r.xMax,t.yMax=r.yMax,Mr.postMessage(t,s),ot(s)}else Mr.postMessage(t);this._$posted=!0,this._$updated=!1}}class fe extends ee{constructor(){super(),this._$player=null,this._$root=this,this._$stage=this,this._$invalidate=!0,this._$color=4294967295,this._$frameRate=60}static toString(){return"[class Stage]"}static get namespace(){return"next2d.display.Stage"}toString(){return"[object Stage]"}get namespace(){return"next2d.display.Stage"}get color(){return this._$color}set color(t){this._$color=dt(xt(t),0,16777215,16777215);const e=this._$player;if(e&&e.context){const t=bt(this._$color);e.context._$setColor(t.R/255,t.G/255,t.B/255,t.A/255)}}get frameRate(){return this._$frameRate}set frameRate(t){this._$frameRate=dt(+t,1,60,60),this._$player&&!this._$player._$stopFlag&&(this._$player.stop(),this._$player.play())}get player(){return this._$player}get canvasHeight(){return this._$player?this._$player._$height/f:0}get canvasWidth(){return this._$player?this._$player._$width/f:0}get currentStageHeight(){return this._$player?this._$player.height*this._$player._$scale:0}get currentStageWidth(){return this._$player?this._$player.width*this._$player._$scale:0}get stageHeight(){return this._$player?this._$player.height:0}get stageWidth(){return this._$player?this._$player.width:0}invalidate(){this._$invalidate=!0}_$addChild(t){return t._$stage=this,t._$root=t,this._$created=!0,super._$addChild(t)}}class pe{static toString(){return"[class Easing]"}static get namespace(){return"next2d.ui.Easing"}toString(){return"[object Easing]"}get namespace(){return"next2d.ui.Easing"}static linear(t,e,i,s){return t/s*i+e}static inQuad(t,e,i,s){return(t/=s)*t*i+e}static outQuad(t,e,i,s){return-(t/=s)*(t-2)*i+e}static inOutQuad(t,e,i,s){return(t/=s/2)<1?t*t*i/2+e:-((t-=1)*(t-2)-1)*i/2+e}static inCubic(t,e,i,s){return(t/=s)*t*t*i+e}static outCubic(t,e,i,s){return t/=s,(--t*t*t+1)*i+e}static inOutCubic(t,e,i,s){return(t/=s/2)<1?t*t*t*i/2+e:((t-=2)*t*t+2)*i/2+e}static inQuart(t,e,i,s){return(t/=s)*t*t*t*i+e}static outQuart(t,e,i,s){return t/=s,(--t*t*t*t-1)*-i+e}static inOutQuart(t,e,i,s){return(t/=s/2)<1?t*t*t*t*i/2+e:((t-=2)*t*t*t-2)*-i/2+e}static inQuint(t,e,i,s){return(t/=s)*t*t*t*t*i+e}static outQuint(t,e,i,s){return t/=s,(--t*t*t*t*t+1)*i+e}static inOutQuint(t,e,i,s){return(t/=s/2)<1?t*t*t*t*t*i/2+e:((t-=2)*t*t*t*t+2)*i/2+e}static inSine(t,e,i,s){return-i*v.cos(t/s*(v.PI/2))+i+e}static outSine(t,e,i,s){return i*v.sin(t/s*(v.PI/2))+e}static inOutSine(t,e,i,s){return-i/2*(v.cos(v.PI*t/s)-1)+e}static inExpo(t,e,i,s){return i*v.pow(2,10*(t/s-1))+e}static outExpo(t,e,i,s){return i*(1-v.pow(2,-10*t/s))+e}static inOutExpo(t,e,i,s){return(t/=s/2)<1?i/2*v.pow(2,10*(t-1))+e:i/2*(2-v.pow(2,-10*(t-1)))+e}static inCirc(t,e,i,s){return(1-v.sqrt(1-(t/=s)*t))*i+e}static outCirc(t,e,i,s){return t/=s,v.sqrt(1- --t*t)*i+e}static inOutCirc(t,e,i,s){return(t/=2*s)<1?(v.sqrt(1-t*t)-1)/-2*i+e:(v.sqrt(1-(t-=2)*t)+1)/2*i+e}static inBack(t,e,i,s){return(2.70158*(t/=s)*t*t-1.70158*t*t)*i+e}static outBack(t,e,i,s){return(1+2.70158*v.pow((t/=s)-1,3)+1.70158*v.pow(t-1,2))*i+e}static inOutBack(t,e,i,s){let r=1.70158;return(t/=s/2)<1?t*t*((1+(r*=1.525))*t-r)*i/2+e:((t-=2)*t*((1+(r*=1.525))*t+r)+2)*i/2+e}static inElastic(t,e,i,s){return 0==(t/=s)?e:1===t?i+e:-v.pow(2,(t*=10)-10)*v.sin((t-10.75)*(2*v.PI/3))*i+e}static outElastic(t,e,i,s){return 0==(t/=s)?e:1===t?i+e:(v.pow(2,-10*t)*v.sin((10*t-.75)*(2*v.PI/3))+1)*i+e}static inOutElastic(t,e,i,s){return 0==(t/=s)?e:1===t?i+e:t<.5?-v.pow(2,20*t-10)*v.sin((20*t-11.125)*(2*v.PI/4.5))/2*i+e:(v.pow(2,-20*t+10)*v.sin((20*t-11.125)*(2*v.PI/4.5))/2+1)*i+e}static outBounce(t,e,i,s){return(t/=s)<1/2.75?7.5625*t*t*i+e:t<2/2.75?(7.5625*(t-=1.5/2.75)*t+.75)*i+e:t<2.5/2.75?(7.5625*(t-=2.25/2.75)*t+.9375)*i+e:(7.5625*(t-=2.625/2.75)*t+.984375)*i+e}static inBounce(t,e,i,s){return i-pe.outBounce(s-t,0,i,s)+e}static inOutBounce(t,e,i,s){return t{this.initialize()}),1e3*this._$delay):this.initialize()}stop(){this._$timerId&&F(this._$timerId),this.hasEventListener(It.STOP)&&(this.dispatchEvent(new It(It.STOP)),this.removeAllEventListener(It.STOP)),this._$names=null,this._$forceStop=!0,this._$stopFlag=!0}_$update(){if(!this._$stopFlag){if(!this._$names)return this.stop();this._$currentTime=.001*(R.now()-this._$startTime),this._$updateProperty(this._$target,this._$from,this._$to,this._$names),this.hasEventListener(It.UPDATE)&&this.dispatchEvent(new It(It.UPDATE)),this._$currentTime>=this._$duration?(this.hasEventListener(It.COMPLETE)&&this.dispatchEvent(new It(It.COMPLETE)),this._$nextJob&&this._$nextJob.start()):this._$timerId=requestAnimationFrame((()=>{this._$update()}))}}_$updateProperty(t,e,i,s){for(let r=0;rthis._$currentTime?t[a]=this._$ease(this._$currentTime,o,i[a]-o,this._$duration):t[a]=i[a]}}}class xe{static toString(){return"[class Tween]"}static get namespace(){return"next2d.ui.Tween"}toString(){return"[object Tween]"}get namespace(){return"next2d.ui.Tween"}static add(t,e,i,s=0,r=1,n=null){return new me(t,e,i,s,r,n)}}class be{constructor(t=null,e=null,i=null,s=null,r=null,n=null,a=null,h=null,o=null,l=null){this._$font=t,this._$size=e,this._$color=null===i?null:dt(xt(i),0,16777215,0),this._$bold=s,this._$italic=r,this._$underline=n,this._$align=a,this._$leftMargin=h,this._$rightMargin=o,this._$leading=l,this._$letterSpacing=0}static toString(){return"[class TextFormat]"}static get namespace(){return"next2d.text.TextFormat"}toString(){return"[object TextFormat]"}get namespace(){return"next2d.text.TextFormat"}get align(){return this._$align}set align(t){this._$align=t}get bold(){return this._$bold}set bold(t){this._$bold=null!==t?!!t:null}get color(){return this._$color}set color(t){this._$color=t,t&&(this._$color=dt(xt(t),0,16777215,0))}get font(){return this._$font}set font(t){this._$font=null!==t?`${t}`:null}get italic(){return this._$italic}set italic(t){this._$italic=null!==t?!!t:null}get leading(){return this._$leading}set leading(t){this._$leading=t}get leftMargin(){return this._$leftMargin}set leftMargin(t){this._$leftMargin=t}get letterSpacing(){return this._$letterSpacing}set letterSpacing(t){this._$letterSpacing=t}get rightMargin(){return this._$rightMargin}set rightMargin(t){this._$rightMargin=t}get size(){return this._$size}set size(t){this._$size=t?0|t:null}get underline(){return this._$underline}set underline(t){this._$underline=null!==t?!!t:null}_$toStyleString(){let t="";if(this._$font&&(t+=`font-family: ${this._$font};`),this._$size&&(t+=`font-size: ${this._$size}px;`),this._$color){const e=Et(xt(this._$color));t+=`color: #${e.R.toString(16).padStart(2,"0")}${e.G.toString(16).padStart(2,"0")}${e.B.toString(16).padStart(2,"0")};`}return this._$bold&&(t+="font-weight: bold;"),this._$italic&&(t+="font-style: italic;"),this._$underline&&(t+="text-decoration: underline;"),this._$align&&(t+=`text-align: ${this._$align};`),this._$leftMargin&&(t+=`margin-left: ${this._$leftMargin}px;`),this._$rightMargin&&(t+=`margin-right: ${this._$rightMargin}px;`),this._$leading&&(t+=`margin-bottom: ${this._$leading}px;`),this._$letterSpacing&&(t+=`letter-spacing: ${this._$letterSpacing}px;`),t}_$isSame(t){return this._$font===t.font&&this._$size===t.size&&this._$color===t.color&&this._$bold===t.bold&&this._$italic===t.italic&&this._$underline===t.underline&&this._$align===t.align&&this._$leftMargin===t.leftMargin&&this._$rightMargin===t.rightMargin&&this._$leading===t.leading&&this._$letterSpacing===t.letterSpacing}_$clone(){const t=new be(this._$font,this._$size,this._$color,this._$bold,this._$italic,this._$underline,this._$align,this._$leftMargin,this._$rightMargin,this._$leading);return t._$letterSpacing=this._$letterSpacing,t}_$setDefault(){this._$align="left",this._$bold=!1,this._$color=0,this._$font="Times New Roman",this._$italic=!1,this._$leading=0,this._$leftMargin=0,this._$letterSpacing=0,this._$rightMargin=0,this._$size=12,this._$underline=!1}_$merge(t){null===this._$align&&(this._$align=t._$align),null===this._$bold&&(this._$bold=t._$bold),null===this._$color&&(this._$color=t._$color),null===this._$font&&(this._$font=t._$font),null===this._$italic&&(this._$italic=t._$italic),null===this._$leading&&(this._$leading=t._$leading),null===this._$leftMargin&&(this._$leftMargin=t._$leftMargin),null===this._$letterSpacing&&(this._$letterSpacing=t._$letterSpacing),null===this._$rightMargin&&(this._$rightMargin=t._$rightMargin),null===this._$size&&(this._$size=t._$size),null===this._$underline&&(this._$underline=t._$underline)}_$widthMargin(){let t=0;return this._$leftMargin&&(t+=this._$leftMargin),this._$rightMargin&&(t+=this._$rightMargin),t}_$generateFontStyle(){let t="";return this._$italic&&(t="italic "),this._$bold&&(t+="bold "),`${t}${this._$size}px '${this._$font}',sans-serif`}}const ve=new Uint16Array('ᵁ<Õıʊҝջאٵ۞ޢߖࠏ੊ઑඡ๭༉༦჊ረዡᐕᒝᓃᓟᔥ\0\0\0\0\0\0ᕫᛍᦍᰒᷝ὾⁠↰⊍⏀⏻⑂⠤⤒ⴈ⹈⿎〖㊺㘹㞬㣾㨨㩱㫠㬮ࠀEMabcfglmnoprstu\\bfms„‹•˜¦³¹ÈÏlig耻Æ䃆P耻&䀦cute耻Á䃁reve;䄂Āiyx}rc耻Â䃂;䐐r;쀀𝔄rave耻À䃀pha;䎑acr;䄀d;橓Āgp¡on;䄄f;쀀𝔸plyFunction;恡ing耻Å䃅Ācs¾Ãr;쀀𝒜ign;扔ilde耻Ã䃃ml耻Ä䃄ЀaceforsuåûþėĜĢħĪĀcrêòkslash;或Ŷöø;櫧ed;挆y;䐑ƀcrtąċĔause;戵noullis;愬a;䎒r;쀀𝔅pf;쀀𝔹eve;䋘còēmpeq;扎܀HOacdefhilorsuōőŖƀƞƢƵƷƺǜȕɳɸɾcy;䐧PY耻©䂩ƀcpyŝŢźute;䄆Ā;iŧŨ拒talDifferentialD;慅leys;愭ȀaeioƉƎƔƘron;䄌dil耻Ç䃇rc;䄈nint;戰ot;䄊ĀdnƧƭilla;䂸terDot;䂷òſi;䎧rcleȀDMPTLJNjǑǖot;抙inus;抖lus;投imes;抗oĀcsǢǸkwiseContourIntegral;戲eCurlyĀDQȃȏoubleQuote;思uote;怙ȀlnpuȞȨɇɕonĀ;eȥȦ户;橴ƀgitȯȶȺruent;扡nt;戯ourIntegral;戮ĀfrɌɎ;愂oduct;成nterClockwiseContourIntegral;戳oss;樯cr;쀀𝒞pĀ;Cʄʅ拓ap;才րDJSZacefiosʠʬʰʴʸˋ˗ˡ˦̳ҍĀ;oŹʥtrahd;椑cy;䐂cy;䐅cy;䐏ƀgrsʿ˄ˇger;怡r;憡hv;櫤Āayː˕ron;䄎;䐔lĀ;t˝˞戇a;䎔r;쀀𝔇Āaf˫̧Ācm˰̢riticalȀADGT̖̜̀̆cute;䂴oŴ̋̍;䋙bleAcute;䋝rave;䁠ilde;䋜ond;拄ferentialD;慆Ѱ̽\0\0\0͔͂\0Ѕf;쀀𝔻ƀ;DE͈͉͍䂨ot;惜qual;扐blèCDLRUVͣͲ΂ϏϢϸontourIntegraìȹoɴ͹\0\0ͻ»͉nArrow;懓Āeo·ΤftƀARTΐΖΡrrow;懐ightArrow;懔eåˊngĀLRΫτeftĀARγιrrow;柸ightArrow;柺ightArrow;柹ightĀATϘϞrrow;懒ee;抨pɁϩ\0\0ϯrrow;懑ownArrow;懕erticalBar;戥ǹABLRTaВЪаўѿͼrrowƀ;BUНОТ憓ar;椓pArrow;懵reve;䌑eft˒к\0ц\0ѐightVector;楐eeVector;楞ectorĀ;Bљњ憽ar;楖ightǔѧ\0ѱeeVector;楟ectorĀ;BѺѻ懁ar;楗eeĀ;A҆҇护rrow;憧ĀctҒҗr;쀀𝒟rok;䄐ࠀNTacdfglmopqstuxҽӀӄӋӞӢӧӮӵԡԯԶՒ՝ՠեG;䅊H耻Ð䃐cute耻É䃉ƀaiyӒӗӜron;䄚rc耻Ê䃊;䐭ot;䄖r;쀀𝔈rave耻È䃈ement;戈ĀapӺӾcr;䄒tyɓԆ\0\0ԒmallSquare;旻erySmallSquare;斫ĀgpԦԪon;䄘f;쀀𝔼silon;䎕uĀaiԼՉlĀ;TՂՃ橵ilde;扂librium;懌Āci՗՚r;愰m;橳a;䎗ml耻Ë䃋Āipժկsts;戃onentialE;慇ʀcfiosօֈ֍ֲ׌y;䐤r;쀀𝔉lledɓ֗\0\0֣mallSquare;旼erySmallSquare;斪Ͱֺ\0ֿ\0\0ׄf;쀀𝔽All;戀riertrf;愱cò׋؀JTabcdfgorstר׬ׯ׺؀ؒؖ؛؝أ٬ٲcy;䐃耻>䀾mmaĀ;d׷׸䎓;䏜reve;䄞ƀeiy؇،ؐdil;䄢rc;䄜;䐓ot;䄠r;쀀𝔊;拙pf;쀀𝔾eater̀EFGLSTصلَٖٛ٦qualĀ;Lؾؿ扥ess;招ullEqual;执reater;檢ess;扷lantEqual;橾ilde;扳cr;쀀𝒢;扫ЀAacfiosuڅڋږڛڞڪھۊRDcy;䐪Āctڐڔek;䋇;䁞irc;䄤r;愌lbertSpace;愋ǰگ\0ڲf;愍izontalLine;攀Āctۃۅòکrok;䄦mpńېۘownHumðįqual;扏܀EJOacdfgmnostuۺ۾܃܇܎ܚܞܡܨ݄ݸދޏޕcy;䐕lig;䄲cy;䐁cute耻Í䃍Āiyܓܘrc耻Î䃎;䐘ot;䄰r;愑rave耻Ì䃌ƀ;apܠܯܿĀcgܴܷr;䄪inaryI;慈lieóϝǴ݉\0ݢĀ;eݍݎ戬Āgrݓݘral;戫section;拂isibleĀCTݬݲomma;恣imes;恢ƀgptݿރވon;䄮f;쀀𝕀a;䎙cr;愐ilde;䄨ǫޚ\0ޞcy;䐆l耻Ï䃏ʀcfosuެ޷޼߂ߐĀiyޱ޵rc;䄴;䐙r;쀀𝔍pf;쀀𝕁ǣ߇\0ߌr;쀀𝒥rcy;䐈kcy;䐄΀HJacfosߤߨ߽߬߱ࠂࠈcy;䐥cy;䐌ppa;䎚Āey߶߻dil;䄶;䐚r;쀀𝔎pf;쀀𝕂cr;쀀𝒦րJTaceflmostࠥࠩࠬࡐࡣ঳সে্਷ੇcy;䐉耻<䀼ʀcmnpr࠷࠼ࡁࡄࡍute;䄹bda;䎛g;柪lacetrf;愒r;憞ƀaeyࡗ࡜ࡡron;䄽dil;䄻;䐛Āfsࡨ॰tԀACDFRTUVarࡾࢩࢱࣦ࣠ࣼयज़ΐ४Ānrࢃ࢏gleBracket;柨rowƀ;BR࢙࢚࢞憐ar;懤ightArrow;懆eiling;挈oǵࢷ\0ࣃbleBracket;柦nǔࣈ\0࣒eeVector;楡ectorĀ;Bࣛࣜ懃ar;楙loor;挊ightĀAV࣯ࣵrrow;憔ector;楎Āerँगeƀ;AVउऊऐ抣rrow;憤ector;楚iangleƀ;BEतथऩ抲ar;槏qual;抴pƀDTVषूौownVector;楑eeVector;楠ectorĀ;Bॖॗ憿ar;楘ectorĀ;B॥०憼ar;楒ightáΜs̀EFGLSTॾঋকঝঢভqualGreater;拚ullEqual;扦reater;扶ess;檡lantEqual;橽ilde;扲r;쀀𝔏Ā;eঽা拘ftarrow;懚idot;䄿ƀnpw৔ਖਛgȀLRlr৞৷ਂਐeftĀAR০৬rrow;柵ightArrow;柷ightArrow;柶eftĀarγਊightáοightáϊf;쀀𝕃erĀLRਢਬeftArrow;憙ightArrow;憘ƀchtਾੀੂòࡌ;憰rok;䅁;扪Ѐacefiosuਗ਼੝੠੷੼અઋ઎p;椅y;䐜Ādl੥੯iumSpace;恟lintrf;愳r;쀀𝔐nusPlus;戓pf;쀀𝕄cò੶;䎜ҀJacefostuણધભીଔଙඑ඗ඞcy;䐊cute;䅃ƀaey઴હાron;䅇dil;䅅;䐝ƀgswે૰଎ativeƀMTV૓૟૨ediumSpace;怋hiĀcn૦૘ë૙eryThiî૙tedĀGL૸ଆreaterGreateòٳessLesóੈLine;䀊r;쀀𝔑ȀBnptଢନଷ଺reak;恠BreakingSpace;䂠f;愕ڀ;CDEGHLNPRSTV୕ୖ୪୼஡௫ఄ౞಄ದ೘ൡඅ櫬Āou୛୤ngruent;扢pCap;扭oubleVerticalBar;戦ƀlqxஃஊ஛ement;戉ualĀ;Tஒஓ扠ilde;쀀≂̸ists;戄reater΀;EFGLSTஶஷ஽௉௓௘௥扯qual;扱ullEqual;쀀≧̸reater;쀀≫̸ess;批lantEqual;쀀⩾̸ilde;扵umpń௲௽ownHump;쀀≎̸qual;쀀≏̸eĀfsఊధtTriangleƀ;BEచఛడ拪ar;쀀⧏̸qual;括s̀;EGLSTవశ఼ౄోౘ扮qual;扰reater;扸ess;쀀≪̸lantEqual;쀀⩽̸ilde;扴estedĀGL౨౹reaterGreater;쀀⪢̸essLess;쀀⪡̸recedesƀ;ESಒಓಛ技qual;쀀⪯̸lantEqual;拠ĀeiಫಹverseElement;戌ghtTriangleƀ;BEೋೌ೒拫ar;쀀⧐̸qual;拭ĀquೝഌuareSuĀbp೨೹setĀ;E೰ೳ쀀⊏̸qual;拢ersetĀ;Eഃആ쀀⊐̸qual;拣ƀbcpഓതൎsetĀ;Eഛഞ쀀⊂⃒qual;抈ceedsȀ;ESTലള഻െ抁qual;쀀⪰̸lantEqual;拡ilde;쀀≿̸ersetĀ;E൘൛쀀⊃⃒qual;抉ildeȀ;EFT൮൯൵ൿ扁qual;扄ullEqual;扇ilde;扉erticalBar;戤cr;쀀𝒩ilde耻Ñ䃑;䎝܀Eacdfgmoprstuvලෂ෉෕ෛ෠෧෼ขภยา฿ไlig;䅒cute耻Ó䃓Āiy෎ීrc耻Ô䃔;䐞blac;䅐r;쀀𝔒rave耻Ò䃒ƀaei෮ෲ෶cr;䅌ga;䎩cron;䎟pf;쀀𝕆enCurlyĀDQฎบoubleQuote;怜uote;怘;橔Āclวฬr;쀀𝒪ash耻Ø䃘iŬื฼de耻Õ䃕es;樷ml耻Ö䃖erĀBP๋๠Āar๐๓r;怾acĀek๚๜;揞et;掴arenthesis;揜Ҁacfhilors๿ງຊຏຒດຝະ໼rtialD;戂y;䐟r;쀀𝔓i;䎦;䎠usMinus;䂱Āipຢອncareplanåڝf;愙Ȁ;eio຺ູ໠໤檻cedesȀ;EST່້໏໚扺qual;檯lantEqual;扼ilde;找me;怳Ādp໩໮uct;戏ortionĀ;aȥ໹l;戝Āci༁༆r;쀀𝒫;䎨ȀUfos༑༖༛༟OT耻"䀢r;쀀𝔔pf;愚cr;쀀𝒬؀BEacefhiorsu༾གྷཇའཱིྦྷྪྭ႖ႩႴႾarr;椐G耻®䂮ƀcnrཎནབute;䅔g;柫rĀ;tཛྷཝ憠l;椖ƀaeyཧཬཱron;䅘dil;䅖;䐠Ā;vླྀཹ愜erseĀEUྂྙĀlq྇ྎement;戋uilibrium;懋pEquilibrium;楯r»ཹo;䎡ghtЀACDFTUVa࿁࿫࿳ဢဨၛႇϘĀnr࿆࿒gleBracket;柩rowƀ;BL࿜࿝࿡憒ar;懥eftArrow;懄eiling;按oǵ࿹\0စbleBracket;柧nǔည\0နeeVector;楝ectorĀ;Bဝသ懂ar;楕loor;挋Āerိ၃eƀ;AVဵံြ抢rrow;憦ector;楛iangleƀ;BEၐၑၕ抳ar;槐qual;抵pƀDTVၣၮၸownVector;楏eeVector;楜ectorĀ;Bႂႃ憾ar;楔ectorĀ;B႑႒懀ar;楓Āpuႛ႞f;愝ndImplies;楰ightarrow;懛ĀchႹႼr;愛;憱leDelayed;槴ڀHOacfhimoqstuფჱჷჽᄙᄞᅑᅖᅡᅧᆵᆻᆿĀCcჩხHcy;䐩y;䐨FTcy;䐬cute;䅚ʀ;aeiyᄈᄉᄎᄓᄗ檼ron;䅠dil;䅞rc;䅜;䐡r;쀀𝔖ortȀDLRUᄪᄴᄾᅉownArrow»ОeftArrow»࢚ightArrow»࿝pArrow;憑gma;䎣allCircle;战pf;쀀𝕊ɲᅭ\0\0ᅰt;戚areȀ;ISUᅻᅼᆉᆯ斡ntersection;抓uĀbpᆏᆞsetĀ;Eᆗᆘ抏qual;抑ersetĀ;Eᆨᆩ抐qual;抒nion;抔cr;쀀𝒮ar;拆ȀbcmpᇈᇛሉላĀ;sᇍᇎ拐etĀ;Eᇍᇕqual;抆ĀchᇠህeedsȀ;ESTᇭᇮᇴᇿ扻qual;檰lantEqual;扽ilde;承Tháྌ;我ƀ;esሒሓሣ拑rsetĀ;Eሜም抃qual;抇et»ሓրHRSacfhiorsሾቄ቉ቕ቞ቱቶኟዂወዑORN耻Þ䃞ADE;愢ĀHc቎ቒcy;䐋y;䐦Ābuቚቜ;䀉;䎤ƀaeyብቪቯron;䅤dil;䅢;䐢r;쀀𝔗Āeiቻ኉Dzኀ\0ኇefore;戴a;䎘Ācn኎ኘkSpace;쀀  Space;怉ldeȀ;EFTካኬኲኼ戼qual;扃ullEqual;扅ilde;扈pf;쀀𝕋ipleDot;惛Āctዖዛr;쀀𝒯rok;䅦ૡዷጎጚጦ\0ጬጱ\0\0\0\0\0ጸጽ፷ᎅ\0᏿ᐄᐊᐐĀcrዻጁute耻Ú䃚rĀ;oጇገ憟cir;楉rǣጓ\0጖y;䐎ve;䅬Āiyጞጣrc耻Û䃛;䐣blac;䅰r;쀀𝔘rave耻Ù䃙acr;䅪Ādiፁ፩erĀBPፈ፝Āarፍፐr;䁟acĀekፗፙ;揟et;掵arenthesis;揝onĀ;P፰፱拃lus;抎Āgp፻፿on;䅲f;쀀𝕌ЀADETadps᎕ᎮᎸᏄϨᏒᏗᏳrrowƀ;BDᅐᎠᎤar;椒ownArrow;懅ownArrow;憕quilibrium;楮eeĀ;AᏋᏌ报rrow;憥ownáϳerĀLRᏞᏨeftArrow;憖ightArrow;憗iĀ;lᏹᏺ䏒on;䎥ing;䅮cr;쀀𝒰ilde;䅨ml耻Ü䃜ҀDbcdefosvᐧᐬᐰᐳᐾᒅᒊᒐᒖash;披ar;櫫y;䐒ashĀ;lᐻᐼ抩;櫦Āerᑃᑅ;拁ƀbtyᑌᑐᑺar;怖Ā;iᑏᑕcalȀBLSTᑡᑥᑪᑴar;戣ine;䁼eparator;杘ilde;所ThinSpace;怊r;쀀𝔙pf;쀀𝕍cr;쀀𝒱dash;抪ʀcefosᒧᒬᒱᒶᒼirc;䅴dge;拀r;쀀𝔚pf;쀀𝕎cr;쀀𝒲Ȁfiosᓋᓐᓒᓘr;쀀𝔛;䎞pf;쀀𝕏cr;쀀𝒳ҀAIUacfosuᓱᓵᓹᓽᔄᔏᔔᔚᔠcy;䐯cy;䐇cy;䐮cute耻Ý䃝Āiyᔉᔍrc;䅶;䐫r;쀀𝔜pf;쀀𝕐cr;쀀𝒴ml;䅸ЀHacdefosᔵᔹᔿᕋᕏᕝᕠᕤcy;䐖cute;䅹Āayᕄᕉron;䅽;䐗ot;䅻Dzᕔ\0ᕛoWidtè૙a;䎖r;愨pf;愤cr;쀀𝒵௡ᖃᖊᖐ\0ᖰᖶᖿ\0\0\0\0ᗆᗛᗫᙟ᙭\0ᚕ᚛ᚲᚹ\0ᚾcute耻á䃡reve;䄃̀;Ediuyᖜᖝᖡᖣᖨᖭ戾;쀀∾̳;房rc耻â䃢te肻´̆;䐰lig耻æ䃦Ā;r²ᖺ;쀀𝔞rave耻à䃠ĀepᗊᗖĀfpᗏᗔsym;愵èᗓha;䎱ĀapᗟcĀclᗤᗧr;䄁g;樿ɤᗰ\0\0ᘊʀ;adsvᗺᗻᗿᘁᘇ戧nd;橕;橜lope;橘;橚΀;elmrszᘘᘙᘛᘞᘿᙏᙙ戠;榤e»ᘙsdĀ;aᘥᘦ戡ѡᘰᘲᘴᘶᘸᘺᘼᘾ;榨;榩;榪;榫;榬;榭;榮;榯tĀ;vᙅᙆ戟bĀ;dᙌᙍ抾;榝Āptᙔᙗh;戢»¹arr;捼Āgpᙣᙧon;䄅f;쀀𝕒΀;Eaeiop዁ᙻᙽᚂᚄᚇᚊ;橰cir;橯;扊d;手s;䀧roxĀ;e዁ᚒñᚃing耻å䃥ƀctyᚡᚦᚨr;쀀𝒶;䀪mpĀ;e዁ᚯñʈilde耻ã䃣ml耻ä䃤Āciᛂᛈoninôɲnt;樑ࠀNabcdefiklnoprsu᛭ᛱᜰ᜼ᝃᝈ᝸᝽០៦ᠹᡐᜍ᤽᥈ᥰot;櫭Ācrᛶ᜞kȀcepsᜀᜅᜍᜓong;扌psilon;䏶rime;怵imĀ;e᜚᜛戽q;拍Ŷᜢᜦee;抽edĀ;gᜬᜭ挅e»ᜭrkĀ;t፜᜷brk;掶Āoyᜁᝁ;䐱quo;怞ʀcmprtᝓ᝛ᝡᝤᝨausĀ;eĊĉptyv;榰séᜌnoõēƀahwᝯ᝱ᝳ;䎲;愶een;扬r;쀀𝔟g΀costuvwឍឝឳេ៕៛៞ƀaiuបពរðݠrc;旯p»፱ƀdptឤឨឭot;樀lus;樁imes;樂ɱឹ\0\0ើcup;樆ar;昅riangleĀdu៍្own;施p;斳plus;樄eåᑄåᒭarow;植ƀako៭ᠦᠵĀcn៲ᠣkƀlst៺֫᠂ozenge;槫riangleȀ;dlr᠒᠓᠘᠝斴own;斾eft;旂ight;斸k;搣Ʊᠫ\0ᠳƲᠯ\0ᠱ;斒;斑4;斓ck;斈ĀeoᠾᡍĀ;qᡃᡆ쀀=⃥uiv;쀀≡⃥t;挐Ȁptwxᡙᡞᡧᡬf;쀀𝕓Ā;tᏋᡣom»Ꮜtie;拈؀DHUVbdhmptuvᢅᢖᢪᢻᣗᣛᣬ᣿ᤅᤊᤐᤡȀLRlrᢎᢐᢒᢔ;敗;敔;敖;敓ʀ;DUduᢡᢢᢤᢦᢨ敐;敦;敩;敤;敧ȀLRlrᢳᢵᢷᢹ;敝;敚;敜;教΀;HLRhlrᣊᣋᣍᣏᣑᣓᣕ救;敬;散;敠;敫;敢;敟ox;槉ȀLRlrᣤᣦᣨᣪ;敕;敒;攐;攌ʀ;DUduڽ᣷᣹᣻᣽;敥;敨;攬;攴inus;抟lus;択imes;抠ȀLRlrᤙᤛᤝ᤟;敛;敘;攘;攔΀;HLRhlrᤰᤱᤳᤵᤷ᤻᤹攂;敪;敡;敞;攼;攤;攜Āevģ᥂bar耻¦䂦Ȁceioᥑᥖᥚᥠr;쀀𝒷mi;恏mĀ;e᜚᜜lƀ;bhᥨᥩᥫ䁜;槅sub;柈Ŭᥴ᥾lĀ;e᥹᥺怢t»᥺pƀ;Eeįᦅᦇ;檮Ā;qۜۛೡᦧ\0᧨ᨑᨕᨲ\0ᨷᩐ\0\0᪴\0\0᫁\0\0ᬡᬮ᭍᭒\0᯽\0ᰌƀcpr᦭ᦲ᧝ute;䄇̀;abcdsᦿᧀᧄ᧊᧕᧙戩nd;橄rcup;橉Āau᧏᧒p;橋p;橇ot;橀;쀀∩︀Āeo᧢᧥t;恁îړȀaeiu᧰᧻ᨁᨅǰ᧵\0᧸s;橍on;䄍dil耻ç䃧rc;䄉psĀ;sᨌᨍ橌m;橐ot;䄋ƀdmnᨛᨠᨦil肻¸ƭptyv;榲t脀¢;eᨭᨮ䂢räƲr;쀀𝔠ƀceiᨽᩀᩍy;䑇ckĀ;mᩇᩈ朓ark»ᩈ;䏇r΀;Ecefms᩟᩠ᩢᩫ᪤᪪᪮旋;槃ƀ;elᩩᩪᩭ䋆q;扗eɡᩴ\0\0᪈rrowĀlr᩼᪁eft;憺ight;憻ʀRSacd᪒᪔᪖᪚᪟»ཇ;擈st;抛irc;抚ash;抝nint;樐id;櫯cir;槂ubsĀ;u᪻᪼晣it»᪼ˬ᫇᫔᫺\0ᬊonĀ;eᫍᫎ䀺Ā;qÇÆɭ᫙\0\0᫢aĀ;t᫞᫟䀬;䁀ƀ;fl᫨᫩᫫戁îᅠeĀmx᫱᫶ent»᫩eóɍǧ᫾\0ᬇĀ;dኻᬂot;橭nôɆƀfryᬐᬔᬗ;쀀𝕔oäɔ脀©;sŕᬝr;愗Āaoᬥᬩrr;憵ss;朗Ācuᬲᬷr;쀀𝒸Ābpᬼ᭄Ā;eᭁᭂ櫏;櫑Ā;eᭉᭊ櫐;櫒dot;拯΀delprvw᭠᭬᭷ᮂᮬᯔ᯹arrĀlr᭨᭪;椸;椵ɰ᭲\0\0᭵r;拞c;拟arrĀ;p᭿ᮀ憶;椽̀;bcdosᮏᮐᮖᮡᮥᮨ截rcap;橈Āauᮛᮞp;橆p;橊ot;抍r;橅;쀀∪︀Ȁalrv᮵ᮿᯞᯣrrĀ;mᮼᮽ憷;椼yƀevwᯇᯔᯘqɰᯎ\0\0ᯒreã᭳uã᭵ee;拎edge;拏en耻¤䂤earrowĀlrᯮ᯳eft»ᮀight»ᮽeäᯝĀciᰁᰇoninôǷnt;戱lcty;挭ঀAHabcdefhijlorstuwz᰸᰻᰿ᱝᱩᱵᲊᲞᲬᲷ᳻᳿ᴍᵻᶑᶫᶻ᷆᷍rò΁ar;楥Ȁglrs᱈ᱍ᱒᱔ger;怠eth;愸òᄳhĀ;vᱚᱛ怐»ऊūᱡᱧarow;椏aã̕Āayᱮᱳron;䄏;䐴ƀ;ao̲ᱼᲄĀgrʿᲁr;懊tseq;橷ƀglmᲑᲔᲘ耻°䂰ta;䎴ptyv;榱ĀirᲣᲨsht;楿;쀀𝔡arĀlrᲳᲵ»ࣜ»သʀaegsv᳂͸᳖᳜᳠mƀ;oș᳊᳔ndĀ;ș᳑uit;晦amma;䏝in;拲ƀ;io᳧᳨᳸䃷de脀÷;o᳧ᳰntimes;拇nø᳷cy;䑒cɯᴆ\0\0ᴊrn;挞op;挍ʀlptuwᴘᴝᴢᵉᵕlar;䀤f;쀀𝕕ʀ;emps̋ᴭᴷᴽᵂqĀ;d͒ᴳot;扑inus;戸lus;戔quare;抡blebarwedgåúnƀadhᄮᵝᵧownarrowóᲃarpoonĀlrᵲᵶefôᲴighôᲶŢᵿᶅkaro÷གɯᶊ\0\0ᶎrn;挟op;挌ƀcotᶘᶣᶦĀryᶝᶡ;쀀𝒹;䑕l;槶rok;䄑Ādrᶰᶴot;拱iĀ;fᶺ᠖斿Āah᷀᷃ròЩaòྦangle;榦Āci᷒ᷕy;䑟grarr;柿ऀDacdefglmnopqrstuxḁḉḙḸոḼṉṡṾấắẽỡἪἷὄ὎὚ĀDoḆᴴoôᲉĀcsḎḔute耻é䃩ter;橮ȀaioyḢḧḱḶron;䄛rĀ;cḭḮ扖耻ê䃪lon;払;䑍ot;䄗ĀDrṁṅot;扒;쀀𝔢ƀ;rsṐṑṗ檚ave耻è䃨Ā;dṜṝ檖ot;檘Ȁ;ilsṪṫṲṴ檙nters;揧;愓Ā;dṹṺ檕ot;檗ƀapsẅẉẗcr;䄓tyƀ;svẒẓẕ戅et»ẓpĀ1;ẝẤijạả;怄;怅怃ĀgsẪẬ;䅋p;怂ĀgpẴẸon;䄙f;쀀𝕖ƀalsỄỎỒrĀ;sỊị拕l;槣us;橱iƀ;lvỚớở䎵on»ớ;䏵ȀcsuvỪỳἋἣĀioữḱrc»Ḯɩỹ\0\0ỻíՈantĀglἂἆtr»ṝess»Ṻƀaeiἒ἖Ἒls;䀽st;扟vĀ;DȵἠD;橸parsl;槥ĀDaἯἳot;打rr;楱ƀcdiἾὁỸr;愯oô͒ĀahὉὋ;䎷耻ð䃰Āmrὓὗl耻ë䃫o;悬ƀcipὡὤὧl;䀡sôծĀeoὬὴctatioîՙnentialåչৡᾒ\0ᾞ\0ᾡᾧ\0\0ῆῌ\0ΐ\0ῦῪ \0 ⁚llingdotseñṄy;䑄male;晀ƀilrᾭᾳ῁lig;耀ffiɩᾹ\0\0᾽g;耀ffig;耀ffl;쀀𝔣lig;耀filig;쀀fjƀaltῙ῜ῡt;晭ig;耀flns;斱of;䆒ǰ΅\0ῳf;쀀𝕗ĀakֿῷĀ;vῼ´拔;櫙artint;樍Āao‌⁕Ācs‑⁒ႉ‸⁅⁈\0⁐β•‥‧‪‬\0‮耻½䂽;慓耻¼䂼;慕;慙;慛Ƴ‴\0‶;慔;慖ʴ‾⁁\0\0⁃耻¾䂾;慗;慜5;慘ƶ⁌\0⁎;慚;慝8;慞l;恄wn;挢cr;쀀𝒻ࢀEabcdefgijlnorstv₂₉₟₥₰₴⃰⃵⃺⃿℃ℒℸ̗ℾ⅒↞Ā;lٍ₇;檌ƀcmpₐₕ₝ute;䇵maĀ;dₜ᳚䎳;檆reve;䄟Āiy₪₮rc;䄝;䐳ot;䄡Ȁ;lqsؾق₽⃉ƀ;qsؾٌ⃄lanô٥Ȁ;cdl٥⃒⃥⃕c;檩otĀ;o⃜⃝檀Ā;l⃢⃣檂;檄Ā;e⃪⃭쀀⋛︀s;檔r;쀀𝔤Ā;gٳ؛mel;愷cy;䑓Ȁ;Eajٚℌℎℐ;檒;檥;檤ȀEaesℛℝ℩ℴ;扩pĀ;p℣ℤ檊rox»ℤĀ;q℮ℯ檈Ā;q℮ℛim;拧pf;쀀𝕘Āci⅃ⅆr;愊mƀ;el٫ⅎ⅐;檎;檐茀>;cdlqr׮ⅠⅪⅮⅳⅹĀciⅥⅧ;檧r;橺ot;拗Par;榕uest;橼ʀadelsↄⅪ←ٖ↛ǰ↉\0↎proø₞r;楸qĀlqؿ↖lesó₈ií٫Āen↣↭rtneqq;쀀≩︀Å↪ԀAabcefkosy⇄⇇⇱⇵⇺∘∝∯≨≽ròΠȀilmr⇐⇔⇗⇛rsðᒄf»․ilôکĀdr⇠⇤cy;䑊ƀ;cwࣴ⇫⇯ir;楈;憭ar;意irc;䄥ƀalr∁∎∓rtsĀ;u∉∊晥it»∊lip;怦con;抹r;쀀𝔥sĀew∣∩arow;椥arow;椦ʀamopr∺∾≃≞≣rr;懿tht;戻kĀlr≉≓eftarrow;憩ightarrow;憪f;쀀𝕙bar;怕ƀclt≯≴≸r;쀀𝒽asè⇴rok;䄧Ābp⊂⊇ull;恃hen»ᱛૡ⊣\0⊪\0⊸⋅⋎\0⋕⋳\0\0⋸⌢⍧⍢⍿\0⎆⎪⎴cute耻í䃭ƀ;iyݱ⊰⊵rc耻î䃮;䐸Ācx⊼⊿y;䐵cl耻¡䂡ĀfrΟ⋉;쀀𝔦rave耻ì䃬Ȁ;inoܾ⋝⋩⋮Āin⋢⋦nt;樌t;戭fin;槜ta;愩lig;䄳ƀaop⋾⌚⌝ƀcgt⌅⌈⌗r;䄫ƀelpܟ⌏⌓inåގarôܠh;䄱f;抷ed;䆵ʀ;cfotӴ⌬⌱⌽⍁are;愅inĀ;t⌸⌹戞ie;槝doô⌙ʀ;celpݗ⍌⍐⍛⍡al;抺Āgr⍕⍙eróᕣã⍍arhk;樗rod;樼Ȁcgpt⍯⍲⍶⍻y;䑑on;䄯f;쀀𝕚a;䎹uest耻¿䂿Āci⎊⎏r;쀀𝒾nʀ;EdsvӴ⎛⎝⎡ӳ;拹ot;拵Ā;v⎦⎧拴;拳Ā;iݷ⎮lde;䄩ǫ⎸\0⎼cy;䑖l耻ï䃯̀cfmosu⏌⏗⏜⏡⏧⏵Āiy⏑⏕rc;䄵;䐹r;쀀𝔧ath;䈷pf;쀀𝕛ǣ⏬\0⏱r;쀀𝒿rcy;䑘kcy;䑔Ѐacfghjos␋␖␢␧␭␱␵␻ppaĀ;v␓␔䎺;䏰Āey␛␠dil;䄷;䐺r;쀀𝔨reen;䄸cy;䑅cy;䑜pf;쀀𝕜cr;쀀𝓀஀ABEHabcdefghjlmnoprstuv⑰⒁⒆⒍⒑┎┽╚▀♎♞♥♹♽⚚⚲⛘❝❨➋⟀⠁⠒ƀart⑷⑺⑼rò৆òΕail;椛arr;椎Ā;gঔ⒋;檋ar;楢ॣ⒥\0⒪\0⒱\0\0\0\0\0⒵Ⓔ\0ⓆⓈⓍ\0⓹ute;䄺mptyv;榴raîࡌbda;䎻gƀ;dlࢎⓁⓃ;榑åࢎ;檅uo耻«䂫rЀ;bfhlpst࢙ⓞⓦⓩ⓫⓮⓱⓵Ā;f࢝ⓣs;椟s;椝ë≒p;憫l;椹im;楳l;憢ƀ;ae⓿─┄檫il;椙Ā;s┉┊檭;쀀⪭︀ƀabr┕┙┝rr;椌rk;杲Āak┢┬cĀek┨┪;䁻;䁛Āes┱┳;榋lĀdu┹┻;榏;榍Ȁaeuy╆╋╖╘ron;䄾Ādi═╔il;䄼ìࢰâ┩;䐻Ȁcqrs╣╦╭╽a;椶uoĀ;rนᝆĀdu╲╷har;楧shar;楋h;憲ʀ;fgqs▋▌উ◳◿扤tʀahlrt▘▤▷◂◨rrowĀ;t࢙□aé⓶arpoonĀdu▯▴own»њp»०eftarrows;懇ightƀahs◍◖◞rrowĀ;sࣴࢧarpoonó྘quigarro÷⇰hreetimes;拋ƀ;qs▋ও◺lanôবʀ;cdgsব☊☍☝☨c;檨otĀ;o☔☕橿Ā;r☚☛檁;檃Ā;e☢☥쀀⋚︀s;檓ʀadegs☳☹☽♉♋pproøⓆot;拖qĀgq♃♅ôউgtò⒌ôছiíলƀilr♕࣡♚sht;楼;쀀𝔩Ā;Eজ♣;檑š♩♶rĀdu▲♮Ā;l॥♳;楪lk;斄cy;䑙ʀ;achtੈ⚈⚋⚑⚖rò◁orneòᴈard;楫ri;旺Āio⚟⚤dot;䅀ustĀ;a⚬⚭掰che»⚭ȀEaes⚻⚽⛉⛔;扨pĀ;p⛃⛄檉rox»⛄Ā;q⛎⛏檇Ā;q⛎⚻im;拦Ѐabnoptwz⛩⛴⛷✚✯❁❇❐Ānr⛮⛱g;柬r;懽rëࣁgƀlmr⛿✍✔eftĀar০✇ightá৲apsto;柼ightá৽parrowĀlr✥✩efô⓭ight;憬ƀafl✶✹✽r;榅;쀀𝕝us;樭imes;樴š❋❏st;戗áፎƀ;ef❗❘᠀旊nge»❘arĀ;l❤❥䀨t;榓ʀachmt❳❶❼➅➇ròࢨorneòᶌarĀ;d྘➃;業;怎ri;抿̀achiqt➘➝ੀ➢➮➻quo;怹r;쀀𝓁mƀ;egল➪➬;檍;檏Ābu┪➳oĀ;rฟ➹;怚rok;䅂萀<;cdhilqrࠫ⟒☹⟜⟠⟥⟪⟰Āci⟗⟙;檦r;橹reå◲mes;拉arr;楶uest;橻ĀPi⟵⟹ar;榖ƀ;ef⠀भ᠛旃rĀdu⠇⠍shar;楊har;楦Āen⠗⠡rtneqq;쀀≨︀Å⠞܀Dacdefhilnopsu⡀⡅⢂⢎⢓⢠⢥⢨⣚⣢⣤ઃ⣳⤂Dot;戺Ȁclpr⡎⡒⡣⡽r耻¯䂯Āet⡗⡙;時Ā;e⡞⡟朠se»⡟Ā;sျ⡨toȀ;dluျ⡳⡷⡻owîҌefôएðᏑker;斮Āoy⢇⢌mma;権;䐼ash;怔asuredangle»ᘦr;쀀𝔪o;愧ƀcdn⢯⢴⣉ro耻µ䂵Ȁ;acdᑤ⢽⣀⣄sôᚧir;櫰ot肻·Ƶusƀ;bd⣒ᤃ⣓戒Ā;uᴼ⣘;横ţ⣞⣡p;櫛ò−ðઁĀdp⣩⣮els;抧f;쀀𝕞Āct⣸⣽r;쀀𝓂pos»ᖝƀ;lm⤉⤊⤍䎼timap;抸ఀGLRVabcdefghijlmoprstuvw⥂⥓⥾⦉⦘⧚⧩⨕⨚⩘⩝⪃⪕⪤⪨⬄⬇⭄⭿⮮ⰴⱧⱼ⳩Āgt⥇⥋;쀀⋙̸Ā;v⥐௏쀀≫⃒ƀelt⥚⥲⥶ftĀar⥡⥧rrow;懍ightarrow;懎;쀀⋘̸Ā;v⥻ే쀀≪⃒ightarrow;懏ĀDd⦎⦓ash;抯ash;抮ʀbcnpt⦣⦧⦬⦱⧌la»˞ute;䅄g;쀀∠⃒ʀ;Eiop඄⦼⧀⧅⧈;쀀⩰̸d;쀀≋̸s;䅉roø඄urĀ;a⧓⧔普lĀ;s⧓ସdz⧟\0⧣p肻 ଷmpĀ;e௹ఀʀaeouy⧴⧾⨃⨐⨓ǰ⧹\0⧻;橃on;䅈dil;䅆ngĀ;dൾ⨊ot;쀀⩭̸p;橂;䐽ash;怓΀;Aadqsxஒ⨩⨭⨻⩁⩅⩐rr;懗rĀhr⨳⨶k;椤Ā;oᏲᏰot;쀀≐̸uiöୣĀei⩊⩎ar;椨í஘istĀ;s஠டr;쀀𝔫ȀEest௅⩦⩹⩼ƀ;qs஼⩭௡ƀ;qs஼௅⩴lanô௢ií௪Ā;rஶ⪁»ஷƀAap⪊⪍⪑rò⥱rr;憮ar;櫲ƀ;svྍ⪜ྌĀ;d⪡⪢拼;拺cy;䑚΀AEadest⪷⪺⪾⫂⫅⫶⫹rò⥦;쀀≦̸rr;憚r;急Ȁ;fqs఻⫎⫣⫯tĀar⫔⫙rro÷⫁ightarro÷⪐ƀ;qs఻⪺⫪lanôౕĀ;sౕ⫴»శiíౝĀ;rవ⫾iĀ;eచథiäඐĀpt⬌⬑f;쀀𝕟膀¬;in⬙⬚⬶䂬nȀ;Edvஉ⬤⬨⬮;쀀⋹̸ot;쀀⋵̸ǡஉ⬳⬵;拷;拶iĀ;vಸ⬼ǡಸ⭁⭃;拾;拽ƀaor⭋⭣⭩rȀ;ast୻⭕⭚⭟lleì୻l;쀀⫽⃥;쀀∂̸lint;樔ƀ;ceಒ⭰⭳uåಥĀ;cಘ⭸Ā;eಒ⭽ñಘȀAait⮈⮋⮝⮧rò⦈rrƀ;cw⮔⮕⮙憛;쀀⤳̸;쀀↝̸ghtarrow»⮕riĀ;eೋೖ΀chimpqu⮽⯍⯙⬄୸⯤⯯Ȁ;cerല⯆ഷ⯉uå൅;쀀𝓃ortɭ⬅\0\0⯖ará⭖mĀ;e൮⯟Ā;q൴൳suĀbp⯫⯭å೸åഋƀbcp⯶ⰑⰙȀ;Ees⯿ⰀഢⰄ抄;쀀⫅̸etĀ;eഛⰋqĀ;qണⰀcĀ;eലⰗñസȀ;EesⰢⰣൟⰧ抅;쀀⫆̸etĀ;e൘ⰮqĀ;qൠⰣȀgilrⰽⰿⱅⱇìௗlde耻ñ䃱çృiangleĀlrⱒⱜeftĀ;eచⱚñదightĀ;eೋⱥñ೗Ā;mⱬⱭ䎽ƀ;esⱴⱵⱹ䀣ro;愖p;怇ҀDHadgilrsⲏⲔⲙⲞⲣⲰⲶⳓⳣash;抭arr;椄p;쀀≍⃒ash;抬ĀetⲨⲬ;쀀≥⃒;쀀>⃒nfin;槞ƀAetⲽⳁⳅrr;椂;쀀≤⃒Ā;rⳊⳍ쀀<⃒ie;쀀⊴⃒ĀAtⳘⳜrr;椃rie;쀀⊵⃒im;쀀∼⃒ƀAan⳰⳴ⴂrr;懖rĀhr⳺⳽k;椣Ā;oᏧᏥear;椧ቓ᪕\0\0\0\0\0\0\0\0\0\0\0\0\0ⴭ\0ⴸⵈⵠⵥ⵲ⶄᬇ\0\0ⶍⶫ\0ⷈⷎ\0ⷜ⸙⸫⸾⹃Ācsⴱ᪗ute耻ó䃳ĀiyⴼⵅrĀ;c᪞ⵂ耻ô䃴;䐾ʀabios᪠ⵒⵗLjⵚlac;䅑v;樸old;榼lig;䅓Ācr⵩⵭ir;榿;쀀𝔬ͯ⵹\0\0⵼\0ⶂn;䋛ave耻ò䃲;槁Ābmⶈ෴ar;榵Ȁacitⶕ⶘ⶥⶨrò᪀Āir⶝ⶠr;榾oss;榻nå๒;槀ƀaeiⶱⶵⶹcr;䅍ga;䏉ƀcdnⷀⷅǍron;䎿;榶pf;쀀𝕠ƀaelⷔ⷗ǒr;榷rp;榹΀;adiosvⷪⷫⷮ⸈⸍⸐⸖戨rò᪆Ȁ;efmⷷⷸ⸂⸅橝rĀ;oⷾⷿ愴f»ⷿ耻ª䂪耻º䂺gof;抶r;橖lope;橗;橛ƀclo⸟⸡⸧ò⸁ash耻ø䃸l;折iŬⸯ⸴de耻õ䃵esĀ;aǛ⸺s;樶ml耻ö䃶bar;挽ૡ⹞\0⹽\0⺀⺝\0⺢⺹\0\0⻋ຜ\0⼓\0\0⼫⾼\0⿈rȀ;astЃ⹧⹲຅脀¶;l⹭⹮䂶leìЃɩ⹸\0\0⹻m;櫳;櫽y;䐿rʀcimpt⺋⺏⺓ᡥ⺗nt;䀥od;䀮il;怰enk;怱r;쀀𝔭ƀimo⺨⺰⺴Ā;v⺭⺮䏆;䏕maô੶ne;明ƀ;tv⺿⻀⻈䏀chfork»´;䏖Āau⻏⻟nĀck⻕⻝kĀ;h⇴⻛;愎ö⇴sҀ;abcdemst⻳⻴ᤈ⻹⻽⼄⼆⼊⼎䀫cir;樣ir;樢Āouᵀ⼂;樥;橲n肻±ຝim;樦wo;樧ƀipu⼙⼠⼥ntint;樕f;쀀𝕡nd耻£䂣Ԁ;Eaceinosu່⼿⽁⽄⽇⾁⾉⾒⽾⾶;檳p;檷uå໙Ā;c໎⽌̀;acens່⽙⽟⽦⽨⽾pproø⽃urlyeñ໙ñ໎ƀaes⽯⽶⽺pprox;檹qq;檵im;拨iíໟmeĀ;s⾈ຮ怲ƀEas⽸⾐⽺ð⽵ƀdfp໬⾙⾯ƀals⾠⾥⾪lar;挮ine;挒urf;挓Ā;t໻⾴ï໻rel;抰Āci⿀⿅r;쀀𝓅;䏈ncsp;怈̀fiopsu⿚⋢⿟⿥⿫⿱r;쀀𝔮pf;쀀𝕢rime;恗cr;쀀𝓆ƀaeo⿸〉〓tĀei⿾々rnionóڰnt;樖stĀ;e【】䀿ñἙô༔઀ABHabcdefhilmnoprstux぀けさすムㄎㄫㅇㅢㅲㆎ㈆㈕㈤㈩㉘㉮㉲㊐㊰㊷ƀartぇおがròႳòϝail;検aròᱥar;楤΀cdenqrtとふへみわゔヌĀeuねぱ;쀀∽̱te;䅕iãᅮmptyv;榳gȀ;del࿑らるろ;榒;榥å࿑uo耻»䂻rր;abcfhlpstw࿜ガクシスゼゾダッデナp;極Ā;f࿠ゴs;椠;椳s;椞ë≝ð✮l;楅im;楴l;憣;憝Āaiパフil;椚oĀ;nホボ戶aló༞ƀabrョリヮrò៥rk;杳ĀakンヽcĀekヹ・;䁽;䁝Āes㄂㄄;榌lĀduㄊㄌ;榎;榐Ȁaeuyㄗㄜㄧㄩron;䅙Ādiㄡㄥil;䅗ì࿲âヺ;䑀Ȁclqsㄴㄷㄽㅄa;椷dhar;楩uoĀ;rȎȍh;憳ƀacgㅎㅟངlȀ;ipsླྀㅘㅛႜnåႻarôྩt;断ƀilrㅩဣㅮsht;楽;쀀𝔯ĀaoㅷㆆrĀduㅽㅿ»ѻĀ;l႑ㆄ;楬Ā;vㆋㆌ䏁;䏱ƀgns㆕ㇹㇼht̀ahlrstㆤㆰ㇂㇘㇤㇮rrowĀ;t࿜ㆭaéトarpoonĀduㆻㆿowîㅾp»႒eftĀah㇊㇐rrowó࿪arpoonóՑightarrows;應quigarro÷ニhreetimes;拌g;䋚ingdotseñἲƀahm㈍㈐㈓rò࿪aòՑ;怏oustĀ;a㈞㈟掱che»㈟mid;櫮Ȁabpt㈲㈽㉀㉒Ānr㈷㈺g;柭r;懾rëဃƀafl㉇㉊㉎r;榆;쀀𝕣us;樮imes;樵Āap㉝㉧rĀ;g㉣㉤䀩t;榔olint;樒arò㇣Ȁachq㉻㊀Ⴜ㊅quo;怺r;쀀𝓇Ābu・㊊oĀ;rȔȓƀhir㊗㊛㊠reåㇸmes;拊iȀ;efl㊪ၙᠡ㊫方tri;槎luhar;楨;愞ൡ㋕㋛㋟㌬㌸㍱\0㍺㎤\0\0㏬㏰\0㐨㑈㑚㒭㒱㓊㓱\0㘖\0\0㘳cute;䅛quï➺Ԁ;Eaceinpsyᇭ㋳㋵㋿㌂㌋㌏㌟㌦㌩;檴ǰ㋺\0㋼;檸on;䅡uåᇾĀ;dᇳ㌇il;䅟rc;䅝ƀEas㌖㌘㌛;檶p;檺im;择olint;樓iíሄ;䑁otƀ;be㌴ᵇ㌵担;橦΀Aacmstx㍆㍊㍗㍛㍞㍣㍭rr;懘rĀhr㍐㍒ë∨Ā;oਸ਼਴t耻§䂧i;䀻war;椩mĀin㍩ðnuóñt;朶rĀ;o㍶⁕쀀𝔰Ȁacoy㎂㎆㎑㎠rp;景Āhy㎋㎏cy;䑉;䑈rtɭ㎙\0\0㎜iäᑤaraì⹯耻­䂭Āgm㎨㎴maƀ;fv㎱㎲㎲䏃;䏂Ѐ;deglnprካ㏅㏉㏎㏖㏞㏡㏦ot;橪Ā;q኱ኰĀ;E㏓㏔檞;檠Ā;E㏛㏜檝;檟e;扆lus;樤arr;楲aròᄽȀaeit㏸㐈㐏㐗Āls㏽㐄lsetmé㍪hp;樳parsl;槤Ādlᑣ㐔e;挣Ā;e㐜㐝檪Ā;s㐢㐣檬;쀀⪬︀ƀflp㐮㐳㑂tcy;䑌Ā;b㐸㐹䀯Ā;a㐾㐿槄r;挿f;쀀𝕤aĀdr㑍ЂesĀ;u㑔㑕晠it»㑕ƀcsu㑠㑹㒟Āau㑥㑯pĀ;sᆈ㑫;쀀⊓︀pĀ;sᆴ㑵;쀀⊔︀uĀbp㑿㒏ƀ;esᆗᆜ㒆etĀ;eᆗ㒍ñᆝƀ;esᆨᆭ㒖etĀ;eᆨ㒝ñᆮƀ;afᅻ㒦ְrť㒫ֱ»ᅼaròᅈȀcemt㒹㒾㓂㓅r;쀀𝓈tmîñiì㐕aræᆾĀar㓎㓕rĀ;f㓔ឿ昆Āan㓚㓭ightĀep㓣㓪psiloîỠhé⺯s»⡒ʀbcmnp㓻㕞ሉ㖋㖎Ҁ;Edemnprs㔎㔏㔑㔕㔞㔣㔬㔱㔶抂;櫅ot;檽Ā;dᇚ㔚ot;櫃ult;櫁ĀEe㔨㔪;櫋;把lus;檿arr;楹ƀeiu㔽㕒㕕tƀ;en㔎㕅㕋qĀ;qᇚ㔏eqĀ;q㔫㔨m;櫇Ābp㕚㕜;櫕;櫓c̀;acensᇭ㕬㕲㕹㕻㌦pproø㋺urlyeñᇾñᇳƀaes㖂㖈㌛pproø㌚qñ㌗g;晪ڀ123;Edehlmnps㖩㖬㖯ሜ㖲㖴㗀㗉㗕㗚㗟㗨㗭耻¹䂹耻²䂲耻³䂳;櫆Āos㖹㖼t;檾ub;櫘Ā;dሢ㗅ot;櫄sĀou㗏㗒l;柉b;櫗arr;楻ult;櫂ĀEe㗤㗦;櫌;抋lus;櫀ƀeiu㗴㘉㘌tƀ;enሜ㗼㘂qĀ;qሢ㖲eqĀ;q㗧㗤m;櫈Ābp㘑㘓;櫔;櫖ƀAan㘜㘠㘭rr;懙rĀhr㘦㘨ë∮Ā;oਫ਩war;椪lig耻ß䃟௡㙑㙝㙠ዎ㙳㙹\0㙾㛂\0\0\0\0\0㛛㜃\0㜉㝬\0\0\0㞇ɲ㙖\0\0㙛get;挖;䏄rë๟ƀaey㙦㙫㙰ron;䅥dil;䅣;䑂lrec;挕r;쀀𝔱Ȁeiko㚆㚝㚵㚼Dz㚋\0㚑eĀ4fኄኁaƀ;sv㚘㚙㚛䎸ym;䏑Ācn㚢㚲kĀas㚨㚮pproø዁im»ኬsðኞĀas㚺㚮ð዁rn耻þ䃾Ǭ̟㛆⋧es膀×;bd㛏㛐㛘䃗Ā;aᤏ㛕r;樱;樰ƀeps㛡㛣㜀á⩍Ȁ;bcf҆㛬㛰㛴ot;挶ir;櫱Ā;o㛹㛼쀀𝕥rk;櫚á㍢rime;怴ƀaip㜏㜒㝤dåቈ΀adempst㜡㝍㝀㝑㝗㝜㝟ngleʀ;dlqr㜰㜱㜶㝀㝂斵own»ᶻeftĀ;e⠀㜾ñम;扜ightĀ;e㊪㝋ñၚot;旬inus;樺lus;樹b;槍ime;樻ezium;揢ƀcht㝲㝽㞁Āry㝷㝻;쀀𝓉;䑆cy;䑛rok;䅧Āio㞋㞎xô᝷headĀlr㞗㞠eftarro÷ࡏightarrow»ཝऀAHabcdfghlmoprstuw㟐㟓㟗㟤㟰㟼㠎㠜㠣㠴㡑㡝㡫㢩㣌㣒㣪㣶ròϭar;楣Ācr㟜㟢ute耻ú䃺òᅐrǣ㟪\0㟭y;䑞ve;䅭Āiy㟵㟺rc耻û䃻;䑃ƀabh㠃㠆㠋ròᎭlac;䅱aòᏃĀir㠓㠘sht;楾;쀀𝔲rave耻ù䃹š㠧㠱rĀlr㠬㠮»ॗ»ႃlk;斀Āct㠹㡍ɯ㠿\0\0㡊rnĀ;e㡅㡆挜r»㡆op;挏ri;旸Āal㡖㡚cr;䅫肻¨͉Āgp㡢㡦on;䅳f;쀀𝕦̀adhlsuᅋ㡸㡽፲㢑㢠ownáᎳarpoonĀlr㢈㢌efô㠭ighô㠯iƀ;hl㢙㢚㢜䏅»ᏺon»㢚parrows;懈ƀcit㢰㣄㣈ɯ㢶\0\0㣁rnĀ;e㢼㢽挝r»㢽op;挎ng;䅯ri;旹cr;쀀𝓊ƀdir㣙㣝㣢ot;拰lde;䅩iĀ;f㜰㣨»᠓Āam㣯㣲rò㢨l耻ü䃼angle;榧ހABDacdeflnoprsz㤜㤟㤩㤭㦵㦸㦽㧟㧤㧨㧳㧹㧽㨁㨠ròϷarĀ;v㤦㤧櫨;櫩asèϡĀnr㤲㤷grt;榜΀eknprst㓣㥆㥋㥒㥝㥤㦖appá␕othinçẖƀhir㓫⻈㥙opô⾵Ā;hᎷ㥢ïㆍĀiu㥩㥭gmá㎳Ābp㥲㦄setneqĀ;q㥽㦀쀀⊊︀;쀀⫋︀setneqĀ;q㦏㦒쀀⊋︀;쀀⫌︀Āhr㦛㦟etá㚜iangleĀlr㦪㦯eft»थight»ၑy;䐲ash»ံƀelr㧄㧒㧗ƀ;beⷪ㧋㧏ar;抻q;扚lip;拮Ābt㧜ᑨaòᑩr;쀀𝔳tré㦮suĀbp㧯㧱»ജ»൙pf;쀀𝕧roð໻tré㦴Ācu㨆㨋r;쀀𝓋Ābp㨐㨘nĀEe㦀㨖»㥾nĀEe㦒㨞»㦐igzag;榚΀cefoprs㨶㨻㩖㩛㩔㩡㩪irc;䅵Ādi㩀㩑Ābg㩅㩉ar;機eĀ;qᗺ㩏;扙erp;愘r;쀀𝔴pf;쀀𝕨Ā;eᑹ㩦atèᑹcr;쀀𝓌ૣណ㪇\0㪋\0㪐㪛\0\0㪝㪨㪫㪯\0\0㫃㫎\0㫘ៜ៟tré៑r;쀀𝔵ĀAa㪔㪗ròσrò৶;䎾ĀAa㪡㪤ròθrò৫að✓is;拻ƀdptឤ㪵㪾Āfl㪺ឩ;쀀𝕩imåឲĀAa㫇㫊ròώròਁĀcq㫒ីr;쀀𝓍Āpt៖㫜ré។Ѐacefiosu㫰㫽㬈㬌㬑㬕㬛㬡cĀuy㫶㫻te耻ý䃽;䑏Āiy㬂㬆rc;䅷;䑋n耻¥䂥r;쀀𝔶cy;䑗pf;쀀𝕪cr;쀀𝓎Ācm㬦㬩y;䑎l耻ÿ䃿Ԁacdefhiosw㭂㭈㭔㭘㭤㭩㭭㭴㭺㮀cute;䅺Āay㭍㭒ron;䅾;䐷ot;䅼Āet㭝㭡træᕟa;䎶r;쀀𝔷cy;䐶grarr;懝pf;쀀𝕫cr;쀀𝓏Ājn㮅㮇;怍j;怌'.split("").map((t=>t.charCodeAt(0)))),Te=new Uint16Array("Ȁaglq\tɭ\0\0p;䀦os;䀧t;䀾t;䀼uot;䀢".split("").map((t=>t.charCodeAt(0))));var ye;const Ee=new Map([[0,65533],[128,8364],[130,8218],[131,402],[132,8222],[133,8230],[134,8224],[135,8225],[136,710],[137,8240],[138,352],[139,8249],[140,338],[142,381],[145,8216],[146,8217],[147,8220],[148,8221],[149,8226],[150,8211],[151,8212],[152,732],[153,8482],[154,353],[155,8250],[156,339],[158,382],[159,376]]),Ae=null!==(ye=String.fromCodePoint)&&void 0!==ye?ye:function(t){let e="";return t>65535&&(t-=65536,e+=String.fromCharCode(t>>>10&1023|55296),t=56320|1023&t),e+=String.fromCharCode(t),e};var Me,Se,we,Ce,Ie,Fe,Re,Be;function Le(t){return t>=Me.ZERO&&t<=Me.NINE}!function(t){t[t.NUM=35]="NUM",t[t.SEMI=59]="SEMI",t[t.EQUALS=61]="EQUALS",t[t.ZERO=48]="ZERO",t[t.NINE=57]="NINE",t[t.LOWER_A=97]="LOWER_A",t[t.LOWER_F=102]="LOWER_F",t[t.LOWER_X=120]="LOWER_X",t[t.LOWER_Z=122]="LOWER_Z",t[t.UPPER_A=65]="UPPER_A",t[t.UPPER_F=70]="UPPER_F",t[t.UPPER_Z=90]="UPPER_Z"}(Me||(Me={})),function(t){t[t.VALUE_LENGTH=49152]="VALUE_LENGTH",t[t.BRANCH_LENGTH=16256]="BRANCH_LENGTH",t[t.JUMP_TABLE=127]="JUMP_TABLE"}(Se||(Se={})),function(t){t[t.EntityStart=0]="EntityStart",t[t.NumericStart=1]="NumericStart",t[t.NumericDecimal=2]="NumericDecimal",t[t.NumericHex=3]="NumericHex",t[t.NamedEntity=4]="NamedEntity"}(we||(we={})),(Ie=Ce||(Ce={}))[Ie.Legacy=0]="Legacy",Ie[Ie.Strict=1]="Strict",Ie[Ie.Attribute=2]="Attribute";class Pe{constructor(t,e,i){this.decodeTree=t,this.emitCodePoint=e,this.errors=i,this.state=we.EntityStart,this.consumed=1,this.result=0,this.treeIndex=0,this.excess=1,this.decodeMode=Ce.Strict}startEntity(t){this.decodeMode=t,this.state=we.EntityStart,this.result=0,this.treeIndex=0,this.excess=1,this.consumed=1}write(t,e){switch(this.state){case we.EntityStart:return t.charCodeAt(e)===Me.NUM?(this.state=we.NumericStart,this.consumed+=1,this.stateNumericStart(t,e+1)):(this.state=we.NamedEntity,this.stateNamedEntity(t,e));case we.NumericStart:return this.stateNumericStart(t,e);case we.NumericDecimal:return this.stateNumericDecimal(t,e);case we.NumericHex:return this.stateNumericHex(t,e);case we.NamedEntity:return this.stateNamedEntity(t,e)}}stateNumericStart(t,e){return e>=t.length?-1:(32|t.charCodeAt(e))===Me.LOWER_X?(this.state=we.NumericHex,this.consumed+=1,this.stateNumericHex(t,e+1)):(this.state=we.NumericDecimal,this.stateNumericDecimal(t,e))}addToNumericResult(t,e,i,s){if(e!==i){const r=i-e;this.result=this.result*Math.pow(s,r)+parseInt(t.substr(e,r),s),this.consumed+=r}}stateNumericHex(t,e){const i=e;for(;e=Me.UPPER_A&&s<=Me.UPPER_F||s>=Me.LOWER_A&&s<=Me.LOWER_F)))return this.addToNumericResult(t,i,e,16),this.emitNumericEntity(r,3);e+=1}var s;return this.addToNumericResult(t,i,e,16),-1}stateNumericDecimal(t,e){const i=e;for(;e=55296&&t<=57343||t>1114111?65533:null!==(e=Ee.get(t))&&void 0!==e?e:t}(this.result),this.consumed),this.errors&&(t!==Me.SEMI&&this.errors.missingSemicolonAfterCharacterReference(),this.errors.validateNumericCharacterReference(this.result)),this.consumed}stateNamedEntity(t,e){const{decodeTree:i}=this;let s=i[this.treeIndex],r=(s&Se.VALUE_LENGTH)>>14;for(;e=Me.UPPER_A&&t<=Me.UPPER_Z||t>=Me.LOWER_A&&t<=Me.LOWER_Z||Le(t)}(n)))?0:this.emitNotTerminatedNamedEntity();if(s=i[this.treeIndex],r=(s&Se.VALUE_LENGTH)>>14,0!==r){if(a===Me.SEMI)return this.emitNamedEntityData(this.treeIndex,r,this.consumed+this.excess);this.decodeMode!==Ce.Strict&&(this.result=this.treeIndex,this.consumed+=this.excess,this.excess=0)}}var n;return-1}emitNotTerminatedNamedEntity(){var t;const{result:e,decodeTree:i}=this,s=(i[e]&Se.VALUE_LENGTH)>>14;return this.emitNamedEntityData(e,s,this.consumed),null===(t=this.errors)||void 0===t||t.missingSemicolonAfterCharacterReference(),this.consumed}emitNamedEntityData(t,e,i){const{decodeTree:s}=this;return this.emitCodePoint(1===e?s[t]&~Se.VALUE_LENGTH:s[t+1],i),3===e&&this.emitCodePoint(s[t+2],i),i}end(){var t;switch(this.state){case we.NamedEntity:return 0===this.result||this.decodeMode===Ce.Attribute&&this.result!==this.treeIndex?0:this.emitNotTerminatedNamedEntity();case we.NumericDecimal:return this.emitNumericEntity(0,2);case we.NumericHex:return this.emitNumericEntity(0,3);case we.NumericStart:return null===(t=this.errors)||void 0===t||t.absenceOfDigitsInNumericCharacterReference(this.consumed),0;case we.EntityStart:return 0}}}function ke(t){let e="";const i=new Pe(t,(t=>e+=Ae(t)));return function(t,s){let r=0,n=0;for(;(n=t.indexOf("&",n))>=0;){e+=t.slice(r,n),i.startEntity(s);const a=i.write(t,n+1);if(a<0){r=n+i.end();break}r=n+a,n=0===a?r+1:r}const a=e+t.slice(r);return e="",a}}function Ne(t,e,i,s){const r=(e&Se.BRANCH_LENGTH)>>7,n=e&Se.JUMP_TABLE;if(0===r)return 0!==n&&s===n?i:-1;if(n){const e=s-n;return e<0||e>=r?-1:t[i+e]-1}let a=i,h=a+r-1;for(;a<=h;){const e=a+h>>>1,i=t[e];if(is))return t[e+r];h=e-1}}return-1}function Oe(t){return t===Fe.Space||t===Fe.NewLine||t===Fe.Tab||t===Fe.FormFeed||t===Fe.CarriageReturn}function De(t){return t===Fe.Slash||t===Fe.Gt||Oe(t)}ke(ve),ke(Te),function(t){t[t.Tab=9]="Tab",t[t.NewLine=10]="NewLine",t[t.FormFeed=12]="FormFeed",t[t.CarriageReturn=13]="CarriageReturn",t[t.Space=32]="Space",t[t.ExclamationMark=33]="ExclamationMark",t[t.Number=35]="Number",t[t.Amp=38]="Amp",t[t.SingleQuote=39]="SingleQuote",t[t.DoubleQuote=34]="DoubleQuote",t[t.Dash=45]="Dash",t[t.Slash=47]="Slash",t[t.Zero=48]="Zero",t[t.Nine=57]="Nine",t[t.Semi=59]="Semi",t[t.Lt=60]="Lt",t[t.Eq=61]="Eq",t[t.Gt=62]="Gt",t[t.Questionmark=63]="Questionmark",t[t.UpperA=65]="UpperA",t[t.LowerA=97]="LowerA",t[t.UpperF=70]="UpperF",t[t.LowerF=102]="LowerF",t[t.UpperZ=90]="UpperZ",t[t.LowerZ=122]="LowerZ",t[t.LowerX=120]="LowerX",t[t.OpeningSquareBracket=91]="OpeningSquareBracket"}(Fe||(Fe={})),function(t){t[t.Text=1]="Text",t[t.BeforeTagName=2]="BeforeTagName",t[t.InTagName=3]="InTagName",t[t.InSelfClosingTag=4]="InSelfClosingTag",t[t.BeforeClosingTagName=5]="BeforeClosingTagName",t[t.InClosingTagName=6]="InClosingTagName",t[t.AfterClosingTagName=7]="AfterClosingTagName",t[t.BeforeAttributeName=8]="BeforeAttributeName",t[t.InAttributeName=9]="InAttributeName",t[t.AfterAttributeName=10]="AfterAttributeName",t[t.BeforeAttributeValue=11]="BeforeAttributeValue",t[t.InAttributeValueDq=12]="InAttributeValueDq",t[t.InAttributeValueSq=13]="InAttributeValueSq",t[t.InAttributeValueNq=14]="InAttributeValueNq",t[t.BeforeDeclaration=15]="BeforeDeclaration",t[t.InDeclaration=16]="InDeclaration",t[t.InProcessingInstruction=17]="InProcessingInstruction",t[t.BeforeComment=18]="BeforeComment",t[t.CDATASequence=19]="CDATASequence",t[t.InSpecialComment=20]="InSpecialComment",t[t.InCommentLike=21]="InCommentLike",t[t.BeforeSpecialS=22]="BeforeSpecialS",t[t.BeforeSpecialT=23]="BeforeSpecialT",t[t.SpecialStartSequence=24]="SpecialStartSequence",t[t.InSpecialTag=25]="InSpecialTag",t[t.InEntity=26]="InEntity"}(Re||(Re={})),function(t){t[t.NoValue=0]="NoValue",t[t.Unquoted=1]="Unquoted",t[t.Single=2]="Single",t[t.Double=3]="Double"}(Be||(Be={}));const Ue={Cdata:new Uint8Array([67,68,65,84,65,91]),CdataEnd:new Uint8Array([93,93,62]),CommentEnd:new Uint8Array([45,45,62]),ScriptEnd:new Uint8Array([60,47,115,99,114,105,112,116]),StyleEnd:new Uint8Array([60,47,115,116,121,108,101]),TitleEnd:new Uint8Array([60,47,116,105,116,108,101]),TextareaEnd:new Uint8Array([60,47,116,101,120,116,97,114,101,97])};class Ve{constructor({xmlMode:t=!1,decodeEntities:e=!0},i){this.cbs=i,this.state=Re.Text,this.buffer="",this.sectionStart=0,this.index=0,this.entityStart=0,this.baseState=Re.Text,this.isSpecial=!1,this.running=!0,this.offset=0,this.currentSequence=void 0,this.sequenceIndex=0,this.xmlMode=t,this.decodeEntities=e,this.entityDecoder=new Pe(t?Te:ve,((t,e)=>this.emitCodePoint(t,e)))}reset(){this.state=Re.Text,this.buffer="",this.sectionStart=0,this.index=0,this.baseState=Re.Text,this.currentSequence=void 0,this.running=!0,this.offset=0}write(t){this.offset+=this.buffer.length,this.buffer=t,this.parse()}end(){this.running&&this.finish()}pause(){this.running=!1}resume(){this.running=!0,this.indexthis.sectionStart&&this.cbs.ontext(this.sectionStart,this.index),this.state=Re.BeforeTagName,this.sectionStart=this.index):this.decodeEntities&&t===Fe.Amp&&this.startEntity()}stateSpecialStartSequence(t){const e=this.sequenceIndex===this.currentSequence.length;if(e?De(t):(32|t)===this.currentSequence[this.sequenceIndex]){if(!e)return void this.sequenceIndex++}else this.isSpecial=!1;this.sequenceIndex=0,this.state=Re.InTagName,this.stateInTagName(t)}stateInSpecialTag(t){if(this.sequenceIndex===this.currentSequence.length){if(t===Fe.Gt||Oe(t)){const e=this.index-this.currentSequence.length;if(this.sectionStart=Fe.LowerA&&t<=Fe.LowerZ||t>=Fe.UpperA&&t<=Fe.UpperZ}(t)}startSpecial(t,e){this.isSpecial=!0,this.currentSequence=t,this.sequenceIndex=e,this.state=Re.SpecialStartSequence}stateBeforeTagName(t){if(t===Fe.ExclamationMark)this.state=Re.BeforeDeclaration,this.sectionStart=this.index+1;else if(t===Fe.Questionmark)this.state=Re.InProcessingInstruction,this.sectionStart=this.index+1;else if(this.isTagStartChar(t)){const e=32|t;this.sectionStart=this.index,this.xmlMode?this.state=Re.InTagName:e===Ue.ScriptEnd[2]?this.state=Re.BeforeSpecialS:e===Ue.TitleEnd[2]?this.state=Re.BeforeSpecialT:this.state=Re.InTagName}else t===Fe.Slash?this.state=Re.BeforeClosingTagName:(this.state=Re.Text,this.stateText(t))}stateInTagName(t){De(t)&&(this.cbs.onopentagname(this.sectionStart,this.index),this.sectionStart=-1,this.state=Re.BeforeAttributeName,this.stateBeforeAttributeName(t))}stateBeforeClosingTagName(t){Oe(t)||(t===Fe.Gt?this.state=Re.Text:(this.state=this.isTagStartChar(t)?Re.InClosingTagName:Re.InSpecialComment,this.sectionStart=this.index))}stateInClosingTagName(t){(t===Fe.Gt||Oe(t))&&(this.cbs.onclosetag(this.sectionStart,this.index),this.sectionStart=-1,this.state=Re.AfterClosingTagName,this.stateAfterClosingTagName(t))}stateAfterClosingTagName(t){(t===Fe.Gt||this.fastForwardTo(Fe.Gt))&&(this.state=Re.Text,this.sectionStart=this.index+1)}stateBeforeAttributeName(t){t===Fe.Gt?(this.cbs.onopentagend(this.index),this.isSpecial?(this.state=Re.InSpecialTag,this.sequenceIndex=0):this.state=Re.Text,this.sectionStart=this.index+1):t===Fe.Slash?this.state=Re.InSelfClosingTag:Oe(t)||(this.state=Re.InAttributeName,this.sectionStart=this.index)}stateInSelfClosingTag(t){t===Fe.Gt?(this.cbs.onselfclosingtag(this.index),this.state=Re.Text,this.sectionStart=this.index+1,this.isSpecial=!1):Oe(t)||(this.state=Re.BeforeAttributeName,this.stateBeforeAttributeName(t))}stateInAttributeName(t){(t===Fe.Eq||De(t))&&(this.cbs.onattribname(this.sectionStart,this.index),this.sectionStart=this.index,this.state=Re.AfterAttributeName,this.stateAfterAttributeName(t))}stateAfterAttributeName(t){t===Fe.Eq?this.state=Re.BeforeAttributeValue:t===Fe.Slash||t===Fe.Gt?(this.cbs.onattribend(Be.NoValue,this.sectionStart),this.sectionStart=-1,this.state=Re.BeforeAttributeName,this.stateBeforeAttributeName(t)):Oe(t)||(this.cbs.onattribend(Be.NoValue,this.sectionStart),this.state=Re.InAttributeName,this.sectionStart=this.index)}stateBeforeAttributeValue(t){t===Fe.DoubleQuote?(this.state=Re.InAttributeValueDq,this.sectionStart=this.index+1):t===Fe.SingleQuote?(this.state=Re.InAttributeValueSq,this.sectionStart=this.index+1):Oe(t)||(this.sectionStart=this.index,this.state=Re.InAttributeValueNq,this.stateInAttributeValueNoQuotes(t))}handleInAttributeValue(t,e){t===e||!this.decodeEntities&&this.fastForwardTo(e)?(this.cbs.onattribdata(this.sectionStart,this.index),this.sectionStart=-1,this.cbs.onattribend(e===Fe.DoubleQuote?Be.Double:Be.Single,this.index+1),this.state=Re.BeforeAttributeName):this.decodeEntities&&t===Fe.Amp&&this.startEntity()}stateInAttributeValueDoubleQuotes(t){this.handleInAttributeValue(t,Fe.DoubleQuote)}stateInAttributeValueSingleQuotes(t){this.handleInAttributeValue(t,Fe.SingleQuote)}stateInAttributeValueNoQuotes(t){Oe(t)||t===Fe.Gt?(this.cbs.onattribdata(this.sectionStart,this.index),this.sectionStart=-1,this.cbs.onattribend(Be.Unquoted,this.index),this.state=Re.BeforeAttributeName,this.stateBeforeAttributeName(t)):this.decodeEntities&&t===Fe.Amp&&this.startEntity()}stateBeforeDeclaration(t){t===Fe.OpeningSquareBracket?(this.state=Re.CDATASequence,this.sequenceIndex=0):this.state=t===Fe.Dash?Re.BeforeComment:Re.InDeclaration}stateInDeclaration(t){(t===Fe.Gt||this.fastForwardTo(Fe.Gt))&&(this.cbs.ondeclaration(this.sectionStart,this.index),this.state=Re.Text,this.sectionStart=this.index+1)}stateInProcessingInstruction(t){(t===Fe.Gt||this.fastForwardTo(Fe.Gt))&&(this.cbs.onprocessinginstruction(this.sectionStart,this.index),this.state=Re.Text,this.sectionStart=this.index+1)}stateBeforeComment(t){t===Fe.Dash?(this.state=Re.InCommentLike,this.currentSequence=Ue.CommentEnd,this.sequenceIndex=2,this.sectionStart=this.index+1):this.state=Re.InDeclaration}stateInSpecialComment(t){(t===Fe.Gt||this.fastForwardTo(Fe.Gt))&&(this.cbs.oncomment(this.sectionStart,this.index,0),this.state=Re.Text,this.sectionStart=this.index+1)}stateBeforeSpecialS(t){const e=32|t;e===Ue.ScriptEnd[3]?this.startSpecial(Ue.ScriptEnd,4):e===Ue.StyleEnd[3]?this.startSpecial(Ue.StyleEnd,4):(this.state=Re.InTagName,this.stateInTagName(t))}stateBeforeSpecialT(t){const e=32|t;e===Ue.TitleEnd[3]?this.startSpecial(Ue.TitleEnd,4):e===Ue.TextareaEnd[3]?this.startSpecial(Ue.TextareaEnd,4):(this.state=Re.InTagName,this.stateInTagName(t))}startEntity(){this.baseState=this.state,this.state=Re.InEntity,this.entityStart=this.index,this.entityDecoder.startEntity(this.xmlMode?Ce.Strict:this.baseState===Re.Text||this.baseState===Re.InSpecialTag?Ce.Legacy:Ce.Attribute)}stateInEntity(){const t=this.entityDecoder.write(this.buffer,this.index-this.offset);t>=0?(this.state=this.baseState,0===t&&(this.index=this.entityStart)):this.index=this.offset+this.buffer.length-1}cleanup(){this.running&&this.sectionStart!==this.index&&(this.state===Re.Text||this.state===Re.InSpecialTag&&0===this.sequenceIndex?(this.cbs.ontext(this.sectionStart,this.index),this.sectionStart=this.index):this.state!==Re.InAttributeValueDq&&this.state!==Re.InAttributeValueSq&&this.state!==Re.InAttributeValueNq||(this.cbs.onattribdata(this.sectionStart,this.index),this.sectionStart=this.index))}shouldContinue(){return this.index=t||(this.state===Re.InCommentLike?this.currentSequence===Ue.CdataEnd?this.cbs.oncdata(this.sectionStart,t,0):this.cbs.oncomment(this.sectionStart,t,0):this.state===Re.InTagName||this.state===Re.BeforeAttributeName||this.state===Re.BeforeAttributeValue||this.state===Re.AfterAttributeName||this.state===Re.InAttributeName||this.state===Re.InAttributeValueSq||this.state===Re.InAttributeValueDq||this.state===Re.InAttributeValueNq||this.state===Re.InClosingTagName||this.cbs.ontext(this.sectionStart,t))}emitCodePoint(t,e){this.baseState!==Re.Text&&this.baseState!==Re.InSpecialTag?(this.sectionStart0&&n.has(this.stack[0]);){const t=this.stack.shift();null===(i=(e=this.cbs).onclosetag)||void 0===i||i.call(e,t,!0)}this.isVoidElement(t)||(this.stack.unshift(t),this.htmlMode&&(We.has(t)?this.foreignContext.unshift(!0):Ke.has(t)&&this.foreignContext.unshift(!1))),null===(r=(s=this.cbs).onopentagname)||void 0===r||r.call(s,t),this.cbs.onopentag&&(this.attribs={})}endOpenTag(t){var e,i;this.startIndex=this.openTagStart,this.attribs&&(null===(i=(e=this.cbs).onopentag)||void 0===i||i.call(e,this.tagname,this.attribs,t),this.attribs=null),this.cbs.onclosetag&&this.isVoidElement(this.tagname)&&this.cbs.onclosetag(this.tagname,!0),this.tagname=""}onopentagend(t){this.endIndex=t,this.endOpenTag(!1),this.startIndex=t+1}onclosetag(t,e){var i,s,r,n,a,h,o,l;this.endIndex=e;let c=this.getSlice(t,e);if(this.lowerCaseTagNames&&(c=c.toLowerCase()),this.htmlMode&&(We.has(c)||Ke.has(c))&&this.foreignContext.shift(),this.isVoidElement(c))this.htmlMode&&"br"===c&&(null===(n=(r=this.cbs).onopentagname)||void 0===n||n.call(r,"br"),null===(h=(a=this.cbs).onopentag)||void 0===h||h.call(a,"br",{},!0),null===(l=(o=this.cbs).onclosetag)||void 0===l||l.call(o,"br",!1));else{const t=this.stack.indexOf(c);if(-1!==t)for(let e=0;e<=t;e++){const r=this.stack.shift();null===(s=(i=this.cbs).onclosetag)||void 0===s||s.call(i,r,e!==t)}else this.htmlMode&&"p"===c&&(this.emitOpenTag("p"),this.closeCurrentTag(!0))}this.startIndex=e+1}onselfclosingtag(t){this.endIndex=t,this.recognizeSelfClosing||this.foreignContext[0]?(this.closeCurrentTag(!1),this.startIndex=t+1):this.onopentagend(t)}closeCurrentTag(t){var e,i;const s=this.tagname;this.endOpenTag(t),this.stack[0]===s&&(null===(i=(e=this.cbs).onclosetag)||void 0===i||i.call(e,s,!t),this.stack.shift())}onattribname(t,e){this.startIndex=t;const i=this.getSlice(t,e);this.attribname=this.lowerCaseAttributeNames?i.toLowerCase():i}onattribdata(t,e){this.attribvalue+=this.getSlice(t,e)}onattribentity(t){this.attribvalue+=Ae(t)}onattribend(t,e){var i,s;this.endIndex=e,null===(s=(i=this.cbs).onattribute)||void 0===s||s.call(i,this.attribname,this.attribvalue,t===Be.Double?'"':t===Be.Single?"'":t===Be.NoValue?void 0:null),this.attribs&&!Object.prototype.hasOwnProperty.call(this.attribs,this.attribname)&&(this.attribs[this.attribname]=this.attribvalue),this.attribvalue=""}getInstructionName(t){const e=t.search(Qe);let i=e<0?t:t.substr(0,e);return this.lowerCaseTagNames&&(i=i.toLowerCase()),i}ondeclaration(t,e){this.endIndex=e;const i=this.getSlice(t,e);if(this.cbs.onprocessinginstruction){const t=this.getInstructionName(i);this.cbs.onprocessinginstruction(`!${t}`,`!${i}`)}this.startIndex=e+1}onprocessinginstruction(t,e){this.endIndex=e;const i=this.getSlice(t,e);if(this.cbs.onprocessinginstruction){const t=this.getInstructionName(i);this.cbs.onprocessinginstruction(`?${t}`,`?${i}`)}this.startIndex=e+1}oncomment(t,e,i){var s,r,n,a;this.endIndex=e,null===(r=(s=this.cbs).oncomment)||void 0===r||r.call(s,this.getSlice(t,e-i)),null===(a=(n=this.cbs).oncommentend)||void 0===a||a.call(n),this.startIndex=e+1}oncdata(t,e,i){var s,r,n,a,h,o,l,c,_,$;this.endIndex=e;const u=this.getSlice(t,e-i);!this.htmlMode||this.options.recognizeCDATA?(null===(r=(s=this.cbs).oncdatastart)||void 0===r||r.call(s),null===(a=(n=this.cbs).ontext)||void 0===a||a.call(n,u),null===(o=(h=this.cbs).oncdataend)||void 0===o||o.call(h)):(null===(c=(l=this.cbs).oncomment)||void 0===c||c.call(l,`[CDATA[${u}]]`),null===($=(_=this.cbs).oncommentend)||void 0===$||$.call(_)),this.startIndex=e+1}onend(){var t,e;if(this.cbs.onclosetag){this.endIndex=this.startIndex;for(let t=0;t=this.buffers[0].length;)this.shiftBuffer();let i=this.buffers[0].slice(t-this.bufferOffset,e-this.bufferOffset);for(;e-this.bufferOffset>this.buffers[0].length;)this.shiftBuffer(),i+=this.buffers[0].slice(0,e-this.bufferOffset);return i}shiftBuffer(){this.bufferOffset+=this.buffers[0].length,this.writeIndex--,this.buffers.shift()}write(t){var e,i;this.ended?null===(i=(e=this.cbs).onerror)||void 0===i||i.call(e,new Error(".write() after done!")):(this.buffers.push(t),this.tokenizer.running&&(this.tokenizer.write(t),this.writeIndex++))}end(t){var e,i;this.ended?null===(i=(e=this.cbs).onerror)||void 0===i||i.call(e,new Error(".end() after done!")):(t&&this.write(t),this.ended=!0,this.tokenizer.end())}pause(){this.tokenizer.pause()}resume(){for(this.tokenizer.resume();this.tokenizer.running&&this.writeIndex0?this.children[this.children.length-1]:null}get childNodes(){return this.children}set childNodes(t){this.children=t}}class hi extends ai{constructor(){super(...arguments),this.type=Ze.CDATA}get nodeType(){return 4}}class oi extends ai{constructor(){super(...arguments),this.type=Ze.Root}get nodeType(){return 9}}class li extends ai{constructor(t,e,i=[],s=("script"===t?Ze.Script:"style"===t?Ze.Style:Ze.Tag)){super(i),this.name=t,this.attribs=e,this.type=s}get nodeType(){return 1}get tagName(){return this.name}set tagName(t){this.name=t}get attributes(){return Object.keys(this.attribs).map((t=>{var e,i;return{name:t,value:this.attribs[t],namespace:null===(e=this["x-attribsNamespace"])||void 0===e?void 0:e[t],prefix:null===(i=this["x-attribsPrefix"])||void 0===i?void 0:i[t]}}))}}function ci(t,e=!1){let i;if(function(t){return t.type===Ze.Text}(t))i=new si(t.data);else if(function(t){return t.type===Ze.Comment}(t))i=new ri(t.data);else if(function(t){return(e=t).type===Ze.Tag||e.type===Ze.Script||e.type===Ze.Style;var e}(t)){const s=e?_i(t.children):[],r=new li(t.name,{...t.attribs},s);s.forEach((t=>t.parent=r)),null!=t.namespace&&(r.namespace=t.namespace),t["x-attribsNamespace"]&&(r["x-attribsNamespace"]={...t["x-attribsNamespace"]}),t["x-attribsPrefix"]&&(r["x-attribsPrefix"]={...t["x-attribsPrefix"]}),i=r}else if(function(t){return t.type===Ze.CDATA}(t)){const s=e?_i(t.children):[],r=new hi(s);s.forEach((t=>t.parent=r)),i=r}else if(function(t){return t.type===Ze.Root}(t)){const s=e?_i(t.children):[],r=new oi(s);s.forEach((t=>t.parent=r)),t["x-mode"]&&(r["x-mode"]=t["x-mode"]),i=r}else{if(!function(t){return t.type===Ze.Directive}(t))throw new Error(`Not implemented yet: ${t.type}`);{const e=new ni(t.name,t.data);null!=t["x-name"]&&(e["x-name"]=t["x-name"],e["x-publicId"]=t["x-publicId"],e["x-systemId"]=t["x-systemId"]),i=e}}return i.startIndex=t.startIndex,i.endIndex=t.endIndex,null!=t.sourceCodeLocation&&(i.sourceCodeLocation=t.sourceCodeLocation),i}function _i(t){const e=t.map((t=>ci(t,!0)));for(let t=1;t'"]/g,gi),fi(/["&\u00A0]/g,new Map([[34,"""],[38,"&"],[160," "]])),fi(/[&<>\u00A0]/g,new Map([[38,"&"],[60,"<"],[62,">"],[160," "]])),function(t){t[t.XML=0]="XML",t[t.HTML=1]="HTML"}(pi||(pi={})),function(t){t[t.UTF8=0]="UTF8",t[t.ASCII=1]="ASCII",t[t.Extensive=2]="Extensive",t[t.Attribute=3]="Attribute",t[t.Text=4]="Text"}(mi||(mi={})),new Map(["altGlyph","altGlyphDef","altGlyphItem","animateColor","animateMotion","animateTransform","clipPath","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","foreignObject","glyphRef","linearGradient","radialGradient","textPath"].map((t=>[t.toLowerCase(),t]))),new Map(["definitionURL","attributeName","attributeType","baseFrequency","baseProfile","calcMode","clipPathUnits","diffuseConstant","edgeMode","filterUnits","glyphRef","gradientTransform","gradientUnits","kernelMatrix","kernelUnitLength","keyPoints","keySplines","keyTimes","lengthAdjust","limitingConeAngle","markerHeight","markerUnits","markerWidth","maskContentUnits","maskUnits","numOctaves","pathLength","patternContentUnits","patternTransform","patternUnits","pointsAtX","pointsAtY","pointsAtZ","preserveAlpha","preserveAspectRatio","primitiveUnits","refX","refY","repeatCount","repeatDur","requiredExtensions","requiredFeatures","specularConstant","specularExponent","spreadMethod","startOffset","stdDeviation","stitchTiles","surfaceScale","systemLanguage","tableValues","targetX","targetY","textLength","viewBox","viewTarget","xChannelSelector","yChannelSelector","zoomAndPan"].map((t=>[t.toLowerCase(),t]))),new Set(["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"]),new Set(["area","base","basefont","br","col","command","embed","frame","hr","img","input","isindex","keygen","link","meta","param","source","track","wbr"]),new Set(["mi","mo","mn","ms","mtext","annotation-xml","foreignObject","desc","title"]),new Set(["svg","math"]),function(t){t[t.DISCONNECTED=1]="DISCONNECTED",t[t.PRECEDING=2]="PRECEDING",t[t.FOLLOWING=4]="FOLLOWING",t[t.CONTAINS=8]="CONTAINS",t[t.CONTAINED_BY=16]="CONTAINED_BY"}(xi||(xi={}));class bi{constructor(){this._$textWidth=-1,this._$textHeight=-1,this._$widthTable=[],this._$heightTable=[],this._$ascentTable=[],this._$textTable=[],this._$lineTable=[]}get textWidth(){if(-1===this._$textWidth){this._$textWidth=0;for(let t=0;t{let r=i.lineTable.length-1;const n=s.width-e._$widthMargin()-4;for(let a=0;an){Ti=_,r++,l.line=r;const t={mode:"wrap",text:"",x:0,y:0,w:0,h:0,line:r,textFormat:h._$clone()};let e=1,s=!0;const n=/[0-9a-zA-Z?!;:.,?!。、;:〜]/g;for(;;){const t=i.textTable.length-e;if(0>=t){s=!1,e=0;break}const r=i.textTable[t];if(!r){s=!1,e=0;break}if("text"!==r.mode){s=!1;break}if(" "===r.text){e--;break}if(!r.text.match(n)){e--;break}e++}if(i.widthTable[r]=0,i.heightTable[r]=0,i.ascentTable[r]=0,e>0&&s){const s=i.textTable.length-e;i.textTable.splice(s,0,t),i.lineTable.push(t);const n=r-1;i.widthTable[n]=0,i.heightTable[n]=0,i.ascentTable[n]=0;for(let t=0;t{const s=t.trim().split(";"),r=[];for(let t=0;t{for(let s=0;se.size&&(e.size=1));break;case"color":e.color=xt(r.value);break;case"letterSpacing":e.letterSpacing=+r.value;break;case"leading":e.leading=+r.value;break;case"leftMargin":e.leftMargin=+r.value;break;case"rightMargin":e.rightMargin=+r.value;break;case"underline":e.underline=!0;break;case"bold":e.bold=!0;break;case"italic":e.italic=!0}}},Mi=(t,e)=>{Ti=0;const i=t.lineTable.length;vi.font=e._$generateFontStyle();const s=vi.measureText(""),r={mode:"break",text:"",x:0,y:0,w:0,h:s.fontBoundingBoxAscent+s.fontBoundingBoxDescent,line:i,textFormat:e._$clone()};t.heightTable[i]=0,t.ascentTable[i]=0,t.widthTable[i]=0,t.lineTable.push(r),t.textTable.push(r)},Si=(t,e,i,s)=>{for(let r=0;r{const e=t.heightTable.length-1;for(let i=1;i0)continue;const e=t.lineTable[i];t.heightTable[i]=e.h=t.heightTable[i-1]}};class Ci extends te{constructor(){super(),this._$background=!1,this._$backgroundColor=16777215,this._$border=!1,this._$borderColor=0,this._$htmlText="",this._$multiline=!1,this._$text="",this._$wordWrap=!1,this._$scrollX=0,this._$scrollY=0,this._$maxChars=0,this._$stopIndex=-1,this._$compositionStartIndex=-1,this._$compositionEndIndex=-1;const t=new be;t._$setDefault(),this._$defaultTextFormat=t,this._$rawHtmlText="",this._$bounds={xMin:0,xMax:100,yMin:0,yMax:100},this._$originBounds={xMin:0,xMax:100,yMin:0,yMax:100},this._$restrict="",this._$isHTML=!1,this._$textData=null,this._$autoSize="none",this._$autoFontSize=!1,this._$focusVisible=!1,this._$timerId=-1,this._$focusIndex=-1,this._$selectIndex=-1,this._$scrollEnabled=!0,this._$xScrollShape=null,this._$yScrollShape=null,this._$type="static",this._$focus=!1,this._$copyText="",this._$thickness=0,this._$thicknessColor=0,this._$textFormats=null,this._$cacheKeys=ht(),this._$cacheParams=ht(0,0,0)}static toString(){return"[class TextField]"}static get namespace(){return"next2d.display.TextField"}toString(){return"[object TextField]"}get namespace(){return"next2d.display.TextField"}get autoFontSize(){return this._$autoFontSize}set autoFontSize(t){t!==this._$autoFontSize&&(this._$autoFontSize=t,this._$reload())}get autoSize(){return this._$autoSize}set autoSize(t){t!==this._$autoSize&&(this._$autoSize=t,this._$reload())}get background(){return this._$background}set background(t){t!==this._$background&&(this._$background=!!t,this._$reset())}get backgroundColor(){return this._$backgroundColor}set backgroundColor(t){(t=dt(xt(t),0,16777215,16777215))!==this._$backgroundColor&&(this._$backgroundColor=t,this._$reset())}get border(){return this._$border}set border(t){t!==this._$border&&(this._$border=!!t,this._$reset())}get borderColor(){return this._$borderColor}set borderColor(t){(t=dt(xt(t),0,16777215,0))!==this._$borderColor&&(this._$borderColor=t,this._$reset())}get stopIndex(){return this._$stopIndex}set stopIndex(t){if(t|=0,this._$stopIndex===t)return;this._$stopIndex=t;const e=this.getTextData();if(!e.textTable.length)return;let i=2,s=0;for(let r=0;r=t){s=r;break}"break"===n.mode&&(a=!0,this._$scrollX=0,i=2),a&&s++}const r=e.textTable[s].line;let n=0;for(let t=0;t<=r;++t)n+=e.heightTable[t];const a=this.height;let h=0;for(let t=r;t>-1;--t){const i=e.heightTable[t];if(aa){const t=(this.textHeight-a)/a;this._$scrollY=v.min((n-h)/t,a)}const o=this.width;let l=0;for(let t=s;t>0;--t){const i=e.textTable[t];if("text"===i.mode){if(oo){const t=(this.textWidth-o)/o;this._$scrollX=v.min((i-l)/t,o+.5)}this._$doChanged()}get defaultTextFormat(){return this._$defaultTextFormat._$clone()}set defaultTextFormat(t){t._$merge(this._$defaultTextFormat),this._$defaultTextFormat=t,this._$reset()}get focus(){return this._$focus}set focus(t){if(this._$focus===t)return;if("input"!==this._$type)return;this._$focus=!!t;const e=this._$focus?Rt.FOCUS_IN:Rt.FOCUS_OUT;this.willTrigger(e)&&this.dispatchEvent(new Rt(e)),tr.value="",this._$focus?tr.focus():(this._$focusIndex=-1,this._$selectIndex=-1,this._$focusVisible=!1,L(this._$timerId),tr.blur()),this._$doChanged(),x()}get htmlText(){if(this._$htmlText)return this._$htmlText;const t=this.getTextData();let e=t.textTable[0].textFormat,i="";continue}const n=r.textFormat;if(!e._$isSame(n)){i+="e){this._$doChanged(),this._$scrollX=t,this._$xScrollShape.width=e*e/this.textWidth;const i=this._$parent;if(i){this._$xScrollShape.hasLocalVariable("job")&&this._$xScrollShape.getLocalVariable("job").stop(),this._$xScrollShape.alpha=.9,this._$xScrollShape.x=this.x+1+(e-1-this._$xScrollShape.width)/(e-1)*(this._$scrollX-1),this._$xScrollShape.y=this.y+this.height-this._$xScrollShape.height-.5,i.addChildAt(this._$xScrollShape,i.getChildIndex(this)+1);const t=xe.add(this._$xScrollShape,{alpha:.9},{alpha:0},.5,.2,pe.outQuad);t.addEventListener(It.COMPLETE,(t=>{const e=t.target.target;e.deleteLocalVariable("job"),e.parent&&e.parent.removeChild(e)})),t.start(),this._$xScrollShape.setLocalVariable("job",t)}}this.willTrigger(It.SCROLL)&&this.dispatchEvent(new It(It.SCROLL,!0))}}get scrollY(){return this._$scrollY}set scrollY(t){if(this._$scrollEnabled&&"none"===this._$autoSize&&(this._$multiline||this._$wordWrap)&&!(this._$xScrollShape&&this._$xScrollShape.hasLocalVariable("job")||(t=dt(t,0,this.height,0),this._$scrollY===t))){const e=this.height;if(this._$yScrollShape&&this.textHeight>e){this._$doChanged(),this._$scrollY=t,this._$yScrollShape.height=e*e/this.textHeight;const i=this._$parent;if(i){this._$yScrollShape.hasLocalVariable("job")&&this._$yScrollShape.getLocalVariable("job").stop(),this._$yScrollShape.alpha=.9,this._$yScrollShape.x=this.x+this.width-this._$yScrollShape.width-.5,this._$yScrollShape.y=this.y+.5+(e-1-this._$yScrollShape.height)/(e-1)*(this._$scrollY-1),i.addChildAt(this._$yScrollShape,i.getChildIndex(this)+1);const t=xe.add(this._$yScrollShape,{alpha:.9},{alpha:0},.5,.2,pe.outQuad);t.addEventListener(It.COMPLETE,(t=>{const e=t.target.target;e.deleteLocalVariable("job"),e.parent&&e.parent.removeChild(e)})),t.start(),this._$yScrollShape.setLocalVariable("job",t)}}this.willTrigger(It.SCROLL)&&this.dispatchEvent(new It(It.SCROLL,!0))}}get text(){if(!this._$isHTML)return this._$text;if(this._$rawHtmlText)return this._$rawHtmlText;let t="";const e=this.getTextData();for(let i=1;i-1){const e=this._$getBounds(null),i=v.abs(e.xMin);this._$originBounds.xMax=t+i,this._$originBounds.xMin=i,this._$bounds.xMax=this._$originBounds.xMax,this._$bounds.xMin=this._$originBounds.xMin,super.width=t,this._$reload()}}get height(){return super.height}set height(t){if(!C(t=+t)&&t>-1){const e=this._$getBounds(null),i=v.abs(e.yMin);this._$originBounds.yMax=t+i,this._$bounds.yMax=this._$originBounds.yMax,this._$bounds.yMin=this._$originBounds.yMin,super.height=t,this._$reload()}}get x(){const t=this._$transform.matrix,e=this._$getBounds(null);return t._$matrix[4]+e.xMin}set x(t){const e=this._$getBounds(null);super.x=t-e.xMin}get y(){const t=this._$transform.matrix,e=this._$getBounds(null);return t._$matrix[5]+e.yMin}set y(t){const e=this._$getBounds(null);super.y=t-e.yMin}appendText(t){const e=this.text;this.text=e+`${t}`}getLineText(t){if(!this._$text&&!this._$htmlText)return"";t|=0;let e="";const i=this.getTextData();for(let s=0;st)break;r.line===t&&"text"===r.mode&&(e+=r.text)}return e}replaceText(t,e,i){if(e|=0,(t|=0)>-1&&e>-1&&e>=t){const s=this.text;t>=s.length?e>=s.length&&e>=t&&(this.text=s+`${i}`):this.text=s.slice(0,t)+`${i}`+s.slice(e,s.length)}}getTextData(t=0){return null!==this._$textData||(this._$isHTML?this._$textData=((t,e,i)=>{const s=new bi;if(!t)return s;const r=t.trim().replace(/\r?\n/g,"").replace(/\t/g,""),n=e._$clone();i.subFontSize&&i.subFontSize>0&&n.size&&(n.size-=i.subFontSize,1>n.size&&(n.size=1));const a=function(t,e){const i=new ui(void 0,e);return new Je(i,e).end(t),i.root}(r);return Mi(s,n),Si(a,n,s,i),wi(s),s})(this._$htmlText,this._$defaultTextFormat,{width:this.width,multiline:this._$multiline,wordWrap:this._$wordWrap,subFontSize:t,textFormats:this._$textFormats}):this._$textData=((t,e,i)=>{const s=new bi;if(!t)return s;const r=i.multiline?t.split("\n"):[t.replace("\n","")];for(let t=0;t0&&n.size&&(n.size-=i.subFontSize,1>n.size&&(n.size=1)),(0===t||i.wordWrap||i.multiline)&&Mi(s,n);const a=r[t];a&&(Ti=0,yi(a,n,s,i))}return wi(s),s})(this._$text,this._$defaultTextFormat,{width:this.width,multiline:this._$multiline,wordWrap:this._$wordWrap,subFontSize:t,textFormats:this._$textFormats})),this._$textData}selectAll(){const t=this.getTextData();t.textTable.length&&(this._$selectIndex=1,this._$focusIndex=t.textTable.length)}copy(){if(-1===this._$focusIndex||-1===this._$selectIndex)return;let t="";const e=v.min(this._$focusIndex,this._$selectIndex),i=v.max(this._$focusIndex,this._$selectIndex)+1,s=this.getTextData();for(let r=e;rs)break;i.line===s&&"text"===i.mode&&(r+=i.w)}let n=2;const a=s-1;for(let e=1;ea)return this._$focusIndex="text"===i.mode?e-1:e,this._$selectIndex=-1,L(this._$timerId),void this._$blinking();if(i.line===a&&"text"===i.mode&&(n+=i.w,n>r))return this._$focusIndex=e,this._$selectIndex=-1,L(this._$timerId),void this._$blinking()}}arrowDown(){if(-1===this._$focusIndex)return;const t=this.getTextData();if(!t.textTable.length)return;const e=t.textTable[this._$focusIndex],i="text"===e.mode?e.line:e.line-1;if(i===t.lineTable.length-1)return;let s=2;for(let e=1;ei)break;r.line===i&&"text"===r.mode&&(s+=r.w)}let r=2;const n=i+1;for(let e=1;en)return this._$focusIndex="text"===i.mode?e-1:e,this._$selectIndex=-1,L(this._$timerId),void this._$blinking();if(i.line===n&&"text"===i.mode&&(r+=i.w,r>s))return this._$focusIndex=e,this._$selectIndex=-1,L(this._$timerId),void this._$blinking()}this._$focusIndex=t.textTable.length,this._$selectIndex=-1,L(this._$timerId),this._$blinking()}arrowLeft(){this._$focusIndex&&(this.getTextData().textTable.length&&this._$focusIndex<2?this._$focusIndex=1:(this._$focusIndex--,this._$selectIndex=-1,L(this._$timerId),this._$blinking()))}arrowRight(){this.getTextData().textTable.length!==this._$focusIndex&&(this._$focusIndex++,this._$selectIndex=-1,L(this._$timerId),this._$blinking())}deleteText(){if(this._$compositionStartIndex>-1)return;let t=0,e=0;if(this._$selectIndex>-1)t=v.min(this._$focusIndex,this._$selectIndex),e=v.max(this._$focusIndex,this._$selectIndex)+1,this._$focusIndex=t;else{if(2>this._$focusIndex)return;this._$focusIndex--}const i=this.getTextData(),s=i.textTable[this._$focusIndex];s&&"wrap"===s.mode&&this._$focusIndex--;const r=ht();let n="";for(let s=1;ss))switch(a.mode){case"break":r.push(a.textFormat),n+="\n";break;case"text":r.push(a.textFormat),n+=a.text;break;default:continue}}if(i.textTable.length===this._$focusIndex&&(r.pop(),n=n.slice(0,-1)),this._$selectIndex=-1,n){const t=this.textWidth,e=this.textHeight;if(this._$textFormats=r,this.text=n,this._$scrollX>0){const e=this.textWidth,i=this.width;switch(!0){case i>e:this._$scrollY=0;break;case t!==e:this._$scrollY-=(t-e)/(e/i)}}if(this._$scrollY>0){const t=this.textHeight,i=this.height;switch(!0){case i>t:this._$scrollY=0;break;case e!==t:this._$scrollY-=(e-t)/(t/i)}}this._$textFormats=null,ot(r)}else this.text=null,this._$scrollX=0,this._$scrollY=0,this._$focusIndex=0}compositionStart(){this._$compositionStartIndex=this._$focusIndex}compositionUpdate(t){if(this._$compositionEndIndex>-1){const t=this._$compositionStartIndex;this._$focusIndex=this._$compositionStartIndex,this._$selectIndex=this._$compositionEndIndex-1,this._$compositionStartIndex=-1,this.deleteText(),this._$compositionStartIndex=t,this._$selectIndex=-1}let e=this.getTextData();const i=ht(),s=t.length;let r="";if(e.textTable.length){for(let n=1;nthis._$compositionStartIndex&&n++}}this._$compositionEndIndex=this._$focusIndex=n;const a=cr(),h=v.min(e.textTable.length-1,this._$compositionEndIndex),o=e.textTable[h];if(o){const t=o.line;let i=0;for(let s=0;s-1){const t=this.getTextData();for(let e=this._$compositionStartIndex;e-1)return;this._$selectIndex>-1&&this.deleteText();const e=this.getTextData(),i=ht();let s="";for(let r=1;ri&&this.textWidth+4>this.width;)this._$reset(),this.getTextData(i++);if(this.height&&this.textHeight)for(;t>i&&this.textHeight+4>this.height;)this._$reset(),this.getTextData(i++)}this._$resize()}_$blinking(){this._$focusVisible=!this._$focusVisible,this._$doChanged(),x(),this._$timerId=+B((()=>{this._$blinking()}),500),this._$timerId|=0}_$setIndex(t,e){if("input"!==this._$type)return;const i=this.getTextData();if(!i.textTable.length)return this._$focusIndex=0,this._$selectIndex=-1,void this.setBlinkingTimer();const s=this.width,r=this.height;let n=0;this._$scrollX>0&&(n+=this._$scrollX*(this.textWidth-s)/s);let h=0;this._$scrollY&&(h+=this._$scrollY*(this.textHeight-r)/r);const o=a(),l=this.globalToLocal(new Dt(t,e)),c=l.x+n,_=l.y+h;let $=2,u=2,d=u+i.heightTable[0];for(let t=1;t$&&_>u&&d>_&&s>c){const e=t;switch(o){case Cs:case Rs:this._$selectIndex!==e&&this._$focusIndex===e&&(this._$selectIndex=e,this._$focusIndex!==e&&(this._$focusVisible=!1,L(this._$timerId),this._$doChanged(),x()));break;default:(this._$focusIndex!==e||this._$selectIndex>-1)&&(this._$focusIndex=e,this._$selectIndex=-1,this.setBlinkingTimer())}return}$=2,u+=i.heightTable[e.line-1],d=u+i.heightTable[e.line];break;case"text":if(t===i.textTable.length-1&&c>$&&_>u&&d>_&&s>c){const t=i.textTable.length;switch(o){case Cs:case Rs:this._$selectIndex!==t&&(this._$selectIndex=t,this._$focusIndex!==t&&(this._$focusVisible=!1,L(this._$timerId),this._$doChanged(),x()));break;default:(this._$focusIndex!==t||this._$selectIndex>-1)&&(this._$focusIndex=t,this._$selectIndex=-1,this.setBlinkingTimer())}return}if(c>$&&_>u&&d>_&&$+e.w>c){let s=t;switch(o){case Cs:case Rs:this._$focusIndex>s?this._$focusIndex===s+1?$+e.w/2c&&(s=-1):$+e.w/2>c&&(s-=1),this._$selectIndex!==s&&(this._$selectIndex=s,this._$selectIndex>-1&&(this._$focusVisible=!1,L(this._$timerId)),this._$doChanged(),x());break;default:if($+e.w/2-1)&&(this._$focusIndex=s,this._$selectIndex=-1,this.setBlinkingTimer())}return}$+=e.w}}switch(o){case Cs:case Rs:this._$focusIndex=-1,this._$selectIndex=-1;break;default:this._$focusIndex=i.textTable.length,this._$selectIndex=-1,this.setBlinkingTimer()}}setBlinkingTimer(){this._$focusVisible=!1,this._$doChanged(),x(),L(this._$timerId),this._$timerId=+B((()=>{this._$blinking()}),500),this._$timerId|=0}_$resize(){if("none"!==this._$autoSize){const t=this._$defaultTextFormat,e=this.textWidth+4+t._$widthMargin();if(this._$wordWrap)this._$bounds.xMax=this._$originBounds.xMax,this._$bounds.xMin=this._$originBounds.xMin;else switch(this._$autoSize){case"left":case"center":this._$bounds.xMax=e+this._$bounds.xMin;break;case"right":this._$bounds.xMax=this._$originBounds.xMax-(this._$originBounds.xMax-this._$originBounds.xMin-(e-this._$originBounds.xMin))}this._$bounds.yMax=this.textHeight+this._$originBounds.yMin+4}else this._$scrollEnabled&&(this._$xScrollShape||(this._$xScrollShape=new ge,this._$xScrollShape.graphics.beginFill("#000",.3).drawRoundRect(0,0,3,3,3),this._$xScrollShape.scale9Grid=new Vt(1.5,1.5,.1,.1)),this._$yScrollShape||(this._$yScrollShape=new ge,this._$yScrollShape.graphics.beginFill("#000",.3).drawRoundRect(0,0,3,3,3),this._$yScrollShape.scale9Grid=new Vt(1.5,1.5,.1,.1)))}_$getAlignOffset(t,e){const i=this.getTextData().getLineWidth(t.line),s=t.textFormat,r=s.leftMargin||0;if(!this._$wordWrap&&i>e)return v.max(0,r);const n=s.rightMargin||0;return"center"===s.align||"center"===this._$autoSize?v.max(0,e/2-r-n-i/2-2):"right"===s.align||"right"===this._$autoSize?v.max(0,e-r-i-n-4):v.max(0,r)}_$getBounds(t=null){if(t){let e=t;const i=this._$transform._$rawMatrix();return 1===i[0]&&0===i[1]&&0===i[2]&&1===i[3]&&0===i[4]&&0===i[5]||(e=gt(t,i)),pt(this._$bounds,e)}return Q(this._$bounds.xMin,this._$bounds.xMax,this._$bounds.yMin,this._$bounds.yMax)}_$buildCharacter(t){const e=this._$defaultTextFormat;switch(e.font=t.font,e.size=0|t.size,e.align=t.align,e.color=0|t.color,e.leading=t.leading,e.letterSpacing=t.letterSpacing,e.leftMargin=t.leftMargin,e.rightMargin=t.rightMargin,t.fontType){case 1:e.bold=!0;break;case 2:e.italic=!0;break;case 3:e.bold=!0,e.italic=!0}switch(this._$type=t.inputType,this._$multiline=!!t.multiline,this._$wordWrap=!!t.wordWrap,this._$border=!!t.border,this._$scrollEnabled=!!t.scroll,this._$thickness=0|t.thickness,this._$thicknessColor=0|t.thicknessColor,this._$bounds.xMin=t.originBounds.xMin,this._$bounds.xMax=t.originBounds.xMax,this._$bounds.yMin=t.originBounds.yMin,this._$bounds.yMax=t.originBounds.yMax,this._$originBounds.xMin=t.originBounds.xMin,this._$originBounds.xMax=t.originBounds.xMax,this._$originBounds.yMin=t.originBounds.yMin,this._$originBounds.yMax=t.originBounds.yMax,t.autoSize){case 1:this.autoSize=t.align;break;case 2:this.autoFontSize=!0}this.text=t.text,Mr&&this._$stage&&this._$createWorkerInstance()}_$sync(t){this._$buildCharacter(t)}_$build(t,e){const i=this._$baseBuild(t,e);return this._$buildCharacter(i),i}_$clip(t,e){const i=this._$getBounds(),s=i.xMax,r=i.xMin,n=i.yMax,a=i.yMin;J(i);const h=v.ceil(v.abs(s-r)),o=v.ceil(v.abs(n-a));if(!h||!o)return;let l=e;const c=this._$transform._$rawMatrix();1===c[0]&&0===c[1]&&0===c[2]&&1===c[3]&&0===c[4]&&0===c[5]||(l=gt(e,c)),t.reset(),t.setTransform(e[0],e[1],e[2],e[3],e[4],e[5]),t.beginPath(),t.moveTo(0,0),t.lineTo(h,0),t.lineTo(h,o),t.lineTo(0,o),t.lineTo(0,0),t.clip(),l!==e&&st(l)}_$draw(t,e,i){if(!this._$visible)return;if(-1===this._$focusIndex&&!this._$background&&!this._$border&&!this.text)return;let s=i;const r=this._$transform._$rawColorTransform();1===r[0]&&1===r[1]&&1===r[2]&&1===r[3]&&0===r[4]&&0===r[5]&&0===r[6]&&0===r[7]||(s=ft(i,r));const n=dt(s[3]+s[7]/255,0,1);if(!n)return;let a=e;const h=this._$transform._$rawMatrix();1===h[0]&&0===h[1]&&0===h[2]&&1===h[3]&&0===h[4]&&0===h[5]||(a=gt(e,h));const o=this._$getBounds(null);o.xMin-=this._$thickness,o.xMax+=this._$thickness,o.yMin-=this._$thickness,o.yMax+=this._$thickness;const l=pt(o,a),c=+l.xMax,_=+l.xMin,$=+l.yMax,u=+l.yMin;J(l);const d=v.ceil(v.abs(c-_)),g=v.ceil(v.abs($-u));switch(!0){case 0===d:case 0===g:case d===-1/0:case g===-1/0:case d===b:case g===b:return}let f=+v.sqrt(a[0]*a[0]+a[1]*a[1]);if(!E.isInteger(f)){const t=f.toString(),e=t.indexOf("e");-1!==e&&(f=+t.slice(0,e)),f=+f.toFixed(4)}let p=+v.sqrt(a[2]*a[2]+a[3]*a[3]);if(!E.isInteger(p)){const t=p.toString(),e=t.indexOf("e");-1!==e&&(p=+t.slice(0,e)),p=+p.toFixed(4)}const m=this._$filters||this.filters,x=null!==m&&m.length>0&&this._$canApply(m);let T=Q(0,d,0,g);if(x&&m)for(let t=0;tA.width||u-T.yMin>A.height)return void J(T);if(0>_+T.xMax||0>u+T.yMax)return void J(T);if(J(T),this._$isUpdated()&&(St.removeCache(this._$instanceId),t.cachePosition=null,this._$cacheKeys.length=0),!this._$cacheKeys.length||this._$cacheParams[0]!==f||this._$cacheParams[1]!==p||this._$cacheParams[2]!==i[7]){const t=ht(f,p);this._$cacheKeys=St.generateKeys(this._$instanceId,t),ot(t),this._$cacheParams[0]=f,this._$cacheParams[1]=p,this._$cacheParams[2]=i[7]}const M=this._$blendMode||this.blendMode;if(t.cachePosition=St.get(this._$cacheKeys),!t.cachePosition){const e=v.min(1,v.max(f,p)),i=v.ceil(v.abs(o.xMax-o.xMin)*f),r=v.ceil(v.abs(o.yMax-o.yMin)*p),n=St.getCanvas();n.width=i+2*e,n.height=r+2*e;const a=n.getContext("2d");if(!a)throw new Error("the context is null.");if(this._$background||this._$border){if(a.beginPath(),a.moveTo(0,0),a.lineTo(i,0),a.lineTo(i,r),a.lineTo(0,r),a.lineTo(0,0),this._$background){const t=Et(this._$backgroundColor),e=v.max(0,v.min(255*t.A+s[7],255))/255;a.fillStyle=`rgba(${t.R},${t.G},${t.B},${e})`,a.fill()}if(this._$border){const t=Et(this._$borderColor),i=v.max(0,v.min(255*t.A+s[7],255))/255;a.lineWidth=e,a.strokeStyle=`rgba(${t.R},${t.G},${t.B},${i})`,a.stroke()}}a.save(),a.beginPath(),a.moveTo(2,2),a.lineTo(i-2,2),a.lineTo(i-2,r-2),a.lineTo(2,r-2),a.lineTo(2,2),a.clip();let h=2;if(this._$scrollX>0){const t=(this.textWidth-this.width)/this.width;h+=-this._$scrollX*t}let l=2;if(this._$scrollY>0){const t=(this.textHeight-this.height)/this.height;l+=-this._$scrollY*t}a.setTransform(f,0,0,p,h*f,l*p),a.beginPath(),this._$doDraw(a,s,i/f,e),a.restore();const c=y.createCachePosition(i,r),_=y.createTextureFromCanvas(a.canvas);t.drawTextureFromRect(_,c),t.cachePosition=c,St.set(this._$cacheKeys,c),St.destroy(a)}let S=!1,w=0,C=0;if(m&&m.length&&this._$canApply(m)){S=!0;const e=this._$drawFilter(t,a,m,d,g);e.offsetX&&(w=e.offsetX),e.offsetY&&(C=e.offsetY),t.cachePosition=e}const I=v.atan2(a[1],a[0]),F=v.atan2(-a[2],a[3]);if(S||!I&&!F)t.setTransform(1,0,0,1,_-w,u-C);else{const e=o.xMin*f,i=o.yMin*p,s=v.cos(I),r=v.sin(I),n=v.cos(F),h=v.sin(F);t.setTransform(s,r,-h,n,e*s-i*h+a[4],e*r+i*n+a[5])}t.cachePosition&&(t.globalAlpha=n,t.imageSmoothingEnabled=!0,t.globalCompositeOperation=M,t.drawInstance(_-w,u-C,c,$,i),t.cachePosition=null),J(o),a!==e&&st(a),s!==i&&nt(s)}_$doDraw(t,e,i,s){const r=this.getTextData();if(!r.textTable.length&&this._$focusIndex>-1&&this._$focusVisible){const i=this._$defaultTextFormat,s=Et(i.color||0),r=v.max(0,v.min(255*s.A+e[7],255))/255;return t.strokeStyle=`rgba(${s.R},${s.G},${s.B},${r})`,t.beginPath(),t.moveTo(0,0),t.lineTo(0,0+(i.size||12)),void t.stroke()}if(this._$selectIndex>-1&&this._$focusIndex>-1){const e=r.textTable.length-1;let s=0,n=0;this._$focusIndex<=this._$selectIndex?(s=v.min(this._$focusIndex,e),n=v.min(this._$selectIndex,e)):(s=v.min(this._$selectIndex,e),n=v.min(this._$focusIndex-1,e));const a=r.textTable[s],h=r.lineTable[a.line],o=this._$getAlignOffset(h,i);let l=0;if(s&&"text"===a.mode){let t=s;for(;t;){const e=r.textTable[--t];if("text"!==e.mode)break;l+=e.w}}t.fillStyle="#b4d7ff";let c=0;for(let e=s;e<=n;++e){const i=r.textTable[e];if("text"===i.mode&&(c+=i.w,e!==n))continue;let s=0;const a="text"===i.mode?i.line:i.line-1;for(let t=0;t0){const t=(this.textWidth-n)/n;a=this._$scrollX*t}const h=n+a,o=this.height;let l=0;if(this._$scrollY>0){const t=(this.textHeight-o)/o;l=this._$scrollY*t}const c=o+l;let _=0,$=0,u=0,d=0,g=!1,f=-1;for(let n=0;n-1&&f>this._$stopIndex))break;if(g&&"text"===o.mode)continue;const p=o.textFormat;if("none"===this._$autoSize){if($>c)break;if("text"===o.mode&&(a>_+o.w||_>h)){_+=o.w;continue}}const m=Et(p.color||0),x=v.max(0,v.min(255*m.A+e[7],255))/255;if(t.fillStyle=`rgba(${m.R},${m.G},${m.B},${x})`,this._$focusVisible&&this._$focusIndex===n){const e=_+u+.1;let i=o.line,s=o.y,n=r.ascentTable[i];"text"!==o.mode&&(s="break"===o.mode?o.h:r.ascentTable[i-1],i>0&&!r.ascentTable[i-1]?(i=o.line,n=r.ascentTable[i-1]):(i=o.line-1,n=r.ascentTable[i]));for(let t=0;t$+r.heightTable[b]){g=!0;continue}d=r.ascentTable[b],u=this._$getAlignOffset(o,i),g=!1;break;case"text":{t.beginPath(),t.font=At(p.font||"",p.size||0,!!p.italic,!!p.bold);const i=_+u,r=$+d;if(p.underline){const n=Et(p.color||0),a=v.max(0,v.min(255*n.A+e[7],255))/255;t.lineWidth=s,t.strokeStyle=`rgba(${n.R},${n.G},${n.B},${a})`,t.beginPath(),t.moveTo(i,r+2),t.lineTo(i+o.w,r+2),t.stroke()}this._$thickness&&t.strokeText(o.text,i,r),t.fillText(o.text,i,r),_+=o.w}}}if(this._$focusVisible&&this._$focusIndex>=r.textTable.length){const i=r.textTable[this._$focusIndex-1];if(i){const s=Et(i.textFormat.color||0),r=v.max(0,v.min(255*s.A+e[7],255))/255;t.strokeStyle=`rgba(${s.R},${s.G},${s.B},${r})`;const n=_+u+.1,a=$+d;t.beginPath(),"text"===i.mode?(t.moveTo(n,a-i.y),t.lineTo(n,a)):(t.moveTo(n,a+i.h),t.lineTo(n,a)),t.stroke()}}}_$mouseHit(t,e,i){return!!this._$visible&&this._$hit(t,e,i)}_$hit(t,e,i){let s=e;const r=this._$transform._$rawMatrix();1===r[0]&&0===r[1]&&0===r[2]&&1===r[3]&&0===r[4]&&0===r[5]||(s=gt(e,r));const n=this._$getBounds(null),a=pt(n,s),h=+a.xMax,o=+a.xMin,l=+a.yMax,c=+a.yMin;J(a),J(n);const _=v.ceil(v.abs(h-o)),$=v.ceil(v.abs(l-c));return t.setTransform(1,0,0,1,o,c),t.beginPath(),t.moveTo(0,0),t.lineTo(_,0),t.lineTo(_,$),t.lineTo(0,$),t.lineTo(0,0),s!==e&&st(s),t.isPointInPath(i.x,i.y)}_$createWorkerInstance(){if(this._$created||!Mr)return;this._$created=!0;const t=this._$getBounds(),e={command:"createTextField",buffer:new Float32Array,instanceId:this._$instanceId,parentId:this._$parent?this._$parent._$instanceId:-1,xMin:t.xMin,yMin:t.yMin,xMax:t.xMax,yMax:t.yMax,limitWidth:this.width,limitHeight:this.height,textHeight:this.textHeight,autoSize:this._$autoSize,wordWrap:this._$wordWrap,border:this._$border,background:this._$background,thickness:this._$thickness};this._$border&&(e.borderColor=this._$borderColor),this._$background&&(e.backgroundColor=this._$backgroundColor),this._$thickness&&(e.thicknessColor=this._$backgroundColor),this._$characterId>-1&&(e.characterId=this._$characterId),this._$loaderInfo&&(e.loaderInfoId=this._$loaderInfo._$id),this._$scale9Grid&&(e.grid={x:this._$scale9Grid.x,y:this._$scale9Grid.y,w:this._$scale9Grid.width,h:this._$scale9Grid.height}),Mr.postMessage(e)}_$postProperty(){if(!Mr)return;const t=this._$createMessage(),e=this._$getBounds(null);t.xMin=e.xMin,t.yMin=e.yMin,t.xMax=e.xMax,t.yMax=e.yMax,J(e),this._$isUpdated()&&(t.limitWidth=this.width,t.limitHeight=this.height,t.textHeight=this.textHeight,t.autoSize=this._$autoSize,t.wordWrap=this._$wordWrap,t.border=this._$border,this._$border&&(t.borderColor=this._$borderColor),t.background=this._$background,this._$background&&(t.backgroundColor=this._$backgroundColor),t.thickness=this._$thickness,this._$thickness&&(t.thicknessColor=this._$backgroundColor)),Mr.postMessage(t),this._$posted=!0,this._$updated=!1}}class Ii{constructor(){this._$rgb="rgb",this._$mode="pad",this._$type="linear",this._$focalPointRatio=0,this._$points=it(),this._$stops=ht()}dispose(){const t=this._$stops;for(let i=0;i{switch(!0){case t[0]>e[0]:return 1;case e[0]>t[0]:return-1;default:return 0}})),this._$stops}linear(t,e,i,s,r="rgb",n="pad"){return this._$type="linear",this._$points[0]=t,this._$points[1]=e,this._$points[2]=i,this._$points[3]=s,this._$rgb=r,this._$mode=n,this._$stops.length&&(this._$stops.length=0),this}radial(t,e,i,s,r,n,a="rgb",h="pad",o=0){return this._$type="radial",this._$points[0]=t,this._$points[1]=e,this._$points[2]=i,this._$points[3]=s,this._$points[4]=r,this._$points[5]=n,this._$rgb=a,this._$mode=h,this._$focalPointRatio=dt(o,-.975,.975,0),this._$stops.length&&(this._$stops.length=0),this}addColorStop(t,e){this._$stops.push(ht(t,e))}}class Fi{constructor(t,e,i){this._$texture=t,this._$repeat=e,this._$colorTransform=i}get texture(){return this._$texture}get repeat(){return this._$repeat}get colorTransform(){return this._$colorTransform}}class Ri{constructor(){this._$fillStyle=Z(1,1,1,1),this._$strokeStyle=Z(1,1,1,1),this._$lineWidth=1,this._$lineCap="round",this._$lineJoin="round",this._$miterLimit=5}get miterLimit(){return this._$miterLimit}set miterLimit(t){this._$miterLimit=t}get lineWidth(){return this._$lineWidth}set lineWidth(t){this._$lineWidth=t}get lineCap(){return this._$lineCap}set lineCap(t){this._$lineCap=t}get lineJoin(){return this._$lineJoin}set lineJoin(t){this._$lineJoin=t}get fillStyle(){return this._$fillStyle}set fillStyle(t){this._$fillStyle instanceof A&&tt(this._$fillStyle),this._$fillStyle=t}get strokeStyle(){return this._$strokeStyle}set strokeStyle(t){this._$strokeStyle instanceof A&&tt(this._$strokeStyle),this._$strokeStyle=t}clear(){this._$lineWidth=1,this._$lineCap="round",this._$lineJoin="round",this._$miterLimit=5,this._$clearFill(),this._$clearStroke()}_$clearFill(){if(this._$fillStyle instanceof Ii)return this._$fillStyle.dispose(),void(this._$fillStyle=Z(1,1,1,1));this._$fillStyle instanceof Fi?this._$fillStyle=Z(1,1,1,1):this._$fillStyle.fill(1)}_$clearStroke(){if(this._$strokeStyle instanceof Ii)return this._$strokeStyle.dispose(),void(this._$strokeStyle=Z(1,1,1,1));this._$strokeStyle instanceof Fi?this._$strokeStyle=Z(1,1,1,1):this._$strokeStyle.fill(1)}}let Bi=2048;class Li{constructor(t){t.pixelStorei(t.UNPACK_ALIGNMENT,1),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),this._$gl=t,this._$objectPool=[],this._$objectPoolArea=0,this._$activeTexture=-1,this._$boundTextures=[null,null,null],this._$maxWidth=0,this._$maxHeight=0,this._$atlasTextures=[],this._$atlasCacheMap=new Map,this._$positionObjectArray=[],this._$nodeObjectArray=[],this._$atlasNodes=new Map}createTextureAtlas(){const t=this._$gl.createTexture();t.width=Bi,t.height=Bi,this._$gl.activeTexture(this._$gl.TEXTURE3),this._$gl.bindTexture(this._$gl.TEXTURE_2D,t),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_WRAP_S,this._$gl.CLAMP_TO_EDGE),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_WRAP_T,this._$gl.CLAMP_TO_EDGE),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_MIN_FILTER,this._$gl.NEAREST),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_MAG_FILTER,this._$gl.NEAREST),this._$gl.texStorage2D(this._$gl.TEXTURE_2D,1,this._$gl.RGBA8,Bi,Bi),this._$gl.bindTexture(this._$gl.TEXTURE_2D,null),this._$activeTexture>-1&&this._$gl.activeTexture(this._$activeTexture);const e=this._$atlasTextures.length;this._$atlasNodes.set(e,[]),this._$atlasCacheMap.set(e,[]),this._$atlasTextures.push(t)}getAtlasTexture(t){return this._$atlasTextures[t]}getNode(t,e,i,s){const r=this._$nodeObjectArray.length?this._$nodeObjectArray.pop():{x:0,y:0,w:0,h:0};return r.x=t,r.y=e,r.w=i,r.h=s,r}createCachePosition(t,e){const i=this._$positionObjectArray.length?this._$positionObjectArray.pop():{index:0,x:0,y:0,w:0,h:0};i.x=i.y=0,i.w=t,i.h=e;for(const[s,r]of this._$atlasNodes){if(!r.length)return t>e?(Bi-t-1>0&&r.push(this.getNode(t+1,0,Bi-t-1,e)),Bi-e-1>0&&r.push(this.getNode(0,e+1,Bi,Bi-e-1))):(Bi-e-1>0&&r.push(this.getNode(0,e+1,t,Bi-e-1)),Bi-t-1>0&&r.push(this.getNode(t+1,0,Bi-t-1,Bi))),i.index=s,this._$atlasCacheMap.get(i.index).push(i),i;const n=r.length;for(let a=0;an.w||e>n.h))return i.index=s,i.x=n.x,i.y=n.y,this._$atlasCacheMap.get(i.index).push(i),n.w!==t||n.h!==e?t>e?(n.h-e-1>0&&r.push(this.getNode(n.x,n.y+e+1,n.w,n.h-e-1)),n.w-t-1>0?(n.x=n.x+t+1,n.w=n.w-t-1,n.h=e):(r.splice(a,1),this._$nodeObjectArray.push(n))):(n.w-t-1>0&&r.push(this.getNode(n.x+t+1,n.y,n.w-t-1,n.h)),n.h-e-1>0?(n.y=n.y+e+1,n.w=t,n.h=n.h-e-1):(r.splice(a,1),this._$nodeObjectArray.push(n))):(r.splice(a,1),this._$nodeObjectArray.push(n)),i}}const s=this._$atlasTextures.length;this.createTextureAtlas();const r=this._$atlasNodes.get(s);return t>e?(Bi-t-1>0&&r.push(this.getNode(t+1,0,Bi-t-1,e)),Bi-e-1>0&&r.push(this.getNode(0,e+1,Bi,Bi-e-1))):(Bi-e-1>0&&r.push(this.getNode(0,e+1,t,Bi-e-1)),Bi-t-1>0&&r.push(this.getNode(t+1,0,Bi-t-1,Bi))),i.index=s,this._$atlasCacheMap.get(i.index).push(i),i}releasePosition(t){var e;this._$atlasNodes.has(t.index)&&(null===(e=this._$atlasNodes.get(t.index))||void 0===e||e.unshift(this.getNode(t.x,t.y,t.w,t.h)),this._$positionObjectArray.push(t))}clearCache(){for(const t of this._$atlasCacheMap.values())t.length=0;for(const t of this._$atlasNodes.values())t.length=0}_$createTexture(t,e){const i=this._$gl.createTexture();return i.width=0,i.height=0,i.area=0,i.dirty=!0,i.smoothing=!0,this.bind0(i,!1),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_WRAP_S,this._$gl.CLAMP_TO_EDGE),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_WRAP_T,this._$gl.CLAMP_TO_EDGE),i.width=t,i.height=e,i.area=t*e,i.dirty=!1,this._$gl.texStorage2D(this._$gl.TEXTURE_2D,1,this._$gl.RGBA8,t,e),i}_$getTexture(t,e){for(let i=0;ithis._$maxWidth*this._$maxHeight*2)this._$gl.deleteTexture(t);else if(t.dirty=!0,this._$objectPool.push(t),this._$objectPoolArea+=t.area,this._$objectPool.length&&this._$objectPoolArea>this._$maxWidth*this._$maxHeight*10){const t=this._$objectPool.shift();this._$objectPoolArea-=t.area,this._$gl.deleteTexture(t)}}bind0(t,e=null){this._$bindTexture(2,this._$gl.TEXTURE2,null,null),this._$bindTexture(1,this._$gl.TEXTURE1,null,null),this._$bindTexture(0,this._$gl.TEXTURE0,t,e)}bind01(t,e,i=null){this._$bindTexture(2,this._$gl.TEXTURE2,null,null),this._$bindTexture(1,this._$gl.TEXTURE1,e,i),this._$bindTexture(0,this._$gl.TEXTURE0,t,i)}bind012(t,e,i,s=null){this._$bindTexture(2,this._$gl.TEXTURE2,i,s),this._$bindTexture(1,this._$gl.TEXTURE1,e,null),this._$bindTexture(0,this._$gl.TEXTURE0,t,null)}bind02(t,e,i=null){this._$bindTexture(2,this._$gl.TEXTURE2,e,i),this._$bindTexture(1,this._$gl.TEXTURE1,null,null),this._$bindTexture(0,this._$gl.TEXTURE0,t,null)}_$bindTexture(t,e,i=null,s=null){const r=i!==this._$boundTextures[t],n=null!==s&&null!==i&&s!==i.smoothing;if((r||n||e===this._$gl.TEXTURE0)&&e!==this._$activeTexture&&(this._$activeTexture=e,this._$gl.activeTexture(e)),r&&(this._$boundTextures[t]=i,this._$gl.bindTexture(this._$gl.TEXTURE_2D,i)),n){i&&(i.smoothing=!!s);const t=s?this._$gl.LINEAR:this._$gl.NEAREST;this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_MIN_FILTER,t),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_MAG_FILTER,t)}}}class Pi{constructor(t){this._$gl=t,this._$objectPool=ht(),this._$objectPoolArea=0,this._$maxWidth=0,this._$maxHeight=0}set maxWidth(t){this._$maxWidth=t}set maxHeight(t){this._$maxHeight=t}_$createStencilBuffer(){const t=this._$gl.createRenderbuffer();if(!t)throw new Error("the stencil buffer is null.");return t.width=0,t.height=0,t.area=0,t.dirty=!0,t}_$getStencilBuffer(t,e){const i=this._$objectPool.length;for(let s=0;s100){const t=this._$objectPool.shift();if(t)return this._$objectPoolArea-=t.area,t}return this._$createStencilBuffer()}create(t,e){const i=this._$getStencilBuffer(t,e);return i.width===t&&i.height===e||(i.width=t,i.height=e,i.area=t*e,i.dirty=!1,this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,i),this._$gl.renderbufferStorage(this._$gl.RENDERBUFFER,this._$gl.STENCIL_INDEX8,t,e)),i}release(t){if(t.area>this._$maxWidth*this._$maxHeight*2)this._$gl.deleteRenderbuffer(t);else if(t.dirty=!0,this._$objectPool.push(t),this._$objectPoolArea+=t.area,this._$objectPoolArea>this._$maxWidth*this._$maxHeight*10){const t=this._$objectPool.shift();t&&(this._$objectPoolArea-=t.area,this._$gl.deleteRenderbuffer(t))}}}class ki{constructor(t,e){this._$gl=t,this._$samples=e,this._$objectPool=ht()}set samples(t){this._$samples=t}_$createColorBuffer(){const t=this._$gl.createRenderbuffer();if(!t)throw new Error("the color buffer is null.");const e=this._$gl.createRenderbuffer();if(!e)throw new Error("the stencil buffer is null.");return t.stencil=e,t.samples=0,t.width=0,t.height=0,t.area=0,t.dirty=!0,t}_$getColorBuffer(t){if(!this._$objectPool.length)return this._$createColorBuffer();const e=this._$bsearch(t);if(e1;){const s=v.floor((i+e)/2);t<=this._$objectPool[s].area?i=s:e=s}return i}}class Ni{constructor(t,e){this._$gl=t,this._$objectPool=[],this._$frameBuffer=t.createFramebuffer(),t.bindFramebuffer(t.READ_FRAMEBUFFER,this._$frameBuffer),this._$frameBufferTexture=t.createFramebuffer(),this._$currentAttachment=null,this._$isBinding=!1,this._$textureManager=new Li(t),this._$stencilBufferPool=new Pi(t),this._$colorBufferPool=new ki(t,e),this._$isRenderBinding=!1,this._$colorBuffer=this._$gl.createRenderbuffer(),this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,this._$colorBuffer),this._$gl.renderbufferStorageMultisample(this._$gl.RENDERBUFFER,e,this._$gl.RGBA8,Bi,Bi),this._$stencilBuffer=this._$gl.createRenderbuffer(),this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,this._$stencilBuffer),this._$gl.renderbufferStorageMultisample(this._$gl.RENDERBUFFER,e,this._$gl.STENCIL_INDEX8,Bi,Bi)}bindRenderBuffer(){this._$isBinding||(this._$isBinding=!0,this._$gl.bindFramebuffer(this._$gl.FRAMEBUFFER,this._$frameBuffer)),this._$isRenderBinding||(this._$isRenderBinding=!0,this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,this._$colorBuffer),this._$gl.framebufferRenderbuffer(this._$gl.FRAMEBUFFER,this._$gl.COLOR_ATTACHMENT0,this._$gl.RENDERBUFFER,this._$colorBuffer),this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,this._$stencilBuffer),this._$gl.framebufferRenderbuffer(this._$gl.FRAMEBUFFER,this._$gl.STENCIL_ATTACHMENT,this._$gl.RENDERBUFFER,this._$stencilBuffer))}get currentAttachment(){return this._$currentAttachment}get textureManager(){return this._$textureManager}createCacheAttachment(t,e,i=!1,s=0){const r=this._$objectPool.pop()||{width:0,height:0,color:null,texture:null,msaa:!1,stencil:null,mask:!1,clipLevel:0,isActive:!1},n=this._$textureManager.create(t,e);return r.width=t,r.height=e,i?(r.color=this._$colorBufferPool.create(t,e,s),r.texture=n,r.msaa=!0,r.stencil=r.color.stencil):(r.color=n,r.texture=n,r.msaa=!1,r.stencil=this._$stencilBufferPool.create(t,e)),r.mask=!1,r.clipLevel=0,r.isActive=!0,r}clearCache(){this._$textureManager.clearCache()}setMaxSize(t,e){this._$stencilBufferPool._$maxWidth=t,this._$stencilBufferPool._$maxHeight=e,this._$textureManager._$maxWidth=t,this._$textureManager._$maxHeight=e}createTextureAttachment(t,e){const i=this._$objectPool.pop()||{width:0,height:0,color:null,texture:null,msaa:!1,stencil:null,mask:!1,clipLevel:0,isActive:!1},s=this._$textureManager.create(t,e);return i.width=t,i.height=e,i.color=s,i.texture=s,i.msaa=!1,i.stencil=null,i.mask=!1,i.clipLevel=0,i.isActive=!0,i}createTextureAttachmentFrom(t){const e=this._$objectPool.pop()||{width:0,height:0,color:null,texture:null,msaa:!1,stencil:null,mask:!1,clipLevel:0,isActive:!0};return e.width=t.width,e.height=t.height,e.color=t,e.texture=t,e.msaa=!1,e.stencil=null,e.mask=!1,e.clipLevel=0,e.isActive=!0,e}releaseAttachment(t=null,e=!1){t&&t.isActive&&(t.msaa?t.color instanceof WebGLRenderbuffer&&this._$colorBufferPool.release(t.color):t.stencil&&this._$stencilBufferPool.release(t.stencil),e&&t.texture&&this._$textureManager.release(t.texture),t.color=null,t.texture=null,t.stencil=null,t.isActive=!1,this._$objectPool.push(t))}bind(t){this._$currentAttachment=t,this._$isBinding||(this._$isBinding=!0,this._$gl.bindFramebuffer(this._$gl.FRAMEBUFFER,this._$frameBuffer)),t.msaa?t.color instanceof WebGLRenderbuffer&&(this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,t.color),this._$gl.framebufferRenderbuffer(this._$gl.FRAMEBUFFER,this._$gl.COLOR_ATTACHMENT0,this._$gl.RENDERBUFFER,t.color)):t.color instanceof WebGLTexture&&(t.color&&this._$textureManager.bind0(t.color),this._$gl.framebufferTexture2D(this._$gl.FRAMEBUFFER,this._$gl.COLOR_ATTACHMENT0,this._$gl.TEXTURE_2D,t.color,0)),this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,t.stencil),this._$gl.framebufferRenderbuffer(this._$gl.FRAMEBUFFER,this._$gl.STENCIL_ATTACHMENT,this._$gl.RENDERBUFFER,t.stencil),this._$isRenderBinding=!1}unbind(){this._$currentAttachment=null,this._$isBinding&&(this._$isBinding=!1,this._$gl.bindFramebuffer(this._$gl.FRAMEBUFFER,null))}transferToMainTexture(){if(!this._$currentAttachment)throw new Error("the current attachment is null.");const t=this._$currentAttachment.width,e=this._$currentAttachment.height,i=this._$currentAttachment.texture;if(!i)throw new Error("the texture is null.");this._$gl.bindFramebuffer(this._$gl.DRAW_FRAMEBUFFER,this._$frameBufferTexture),this._$textureManager.bind0(i),this._$gl.framebufferTexture2D(this._$gl.FRAMEBUFFER,this._$gl.COLOR_ATTACHMENT0,this._$gl.TEXTURE_2D,i,0),this._$gl.bindFramebuffer(this._$gl.DRAW_FRAMEBUFFER,null),this._$gl.blitFramebuffer(0,0,t,e,0,0,t,e,this._$gl.COLOR_BUFFER_BIT,this._$gl.NEAREST),this._$gl.bindFramebuffer(this._$gl.DRAW_FRAMEBUFFER,this._$frameBuffer)}createCachePosition(t,e){return this._$textureManager.createCachePosition(t,e)}transferTexture(t){this._$gl.disable(this._$gl.SCISSOR_TEST),this._$gl.bindFramebuffer(this._$gl.DRAW_FRAMEBUFFER,this._$frameBufferTexture);const e=this._$textureManager.getAtlasTexture(t.index);this._$textureManager.bind0(e),this._$gl.framebufferTexture2D(this._$gl.FRAMEBUFFER,this._$gl.COLOR_ATTACHMENT0,this._$gl.TEXTURE_2D,e,0);const i=v.max(0,t.x-1),s=v.max(0,t.y-1),r=v.min(Bi,t.x+t.w+1),n=v.min(Bi,t.y+t.h+1);this._$gl.blitFramebuffer(i,s,r,n,i,s,r,n,this._$gl.COLOR_BUFFER_BIT,this._$gl.NEAREST),this._$gl.bindFramebuffer(this._$gl.FRAMEBUFFER,this._$frameBuffer)}getTextureFromCurrentAttachment(){if(!this._$currentAttachment)throw new Error("the current attachment is null.");if(!this._$currentAttachment.msaa&&this._$currentAttachment.texture)return this._$currentAttachment.texture;const t=this._$currentAttachment.width,e=this._$currentAttachment.height,i=this._$currentAttachment.texture;if(!i)throw new Error("the texture is null.");return i.dirty=!1,this._$gl.bindFramebuffer(this._$gl.DRAW_FRAMEBUFFER,this._$frameBufferTexture),this._$textureManager.bind0(i),this._$gl.framebufferTexture2D(this._$gl.FRAMEBUFFER,this._$gl.COLOR_ATTACHMENT0,this._$gl.TEXTURE_2D,i,0),this._$gl.blitFramebuffer(0,0,t,e,0,0,t,e,this._$gl.COLOR_BUFFER_BIT,this._$gl.NEAREST),this._$gl.bindFramebuffer(this._$gl.FRAMEBUFFER,this._$frameBuffer),i}createTextureFromPixels(t,e,i=null,s=!1,r=!0){return this._$textureManager.create(t,e,i,s,r)}createTextureFromCanvas(t){return this._$textureManager.createFromCanvas(t)}createTextureFromImage(t,e=!1){return this._$textureManager.createFromImage(t,e)}createTextureFromVideo(t,e=!1){return this._$textureManager.createFromVideo(t,e)}createTextureFromCurrentAttachment(){if(!this._$currentAttachment)throw new Error("the current attachment is null.");const t=this._$currentAttachment.width,e=this._$currentAttachment.height,i=this._$textureManager.create(t,e);return this._$textureManager.bind0(i),this._$gl.copyTexSubImage2D(this._$gl.TEXTURE_2D,0,0,0,0,0,t,e),i}releaseTexture(t){this._$textureManager.release(t)}}class Oi{constructor(){this._$bezierConverterBuffer=new A(32)}cubicToQuad(t,e,i,s,r,n,a,h){this._$split2Cubic(t,e,i,s,r,n,a,h,0,16),this._$split2Cubic(this._$bezierConverterBuffer[0],this._$bezierConverterBuffer[1],this._$bezierConverterBuffer[2],this._$bezierConverterBuffer[3],this._$bezierConverterBuffer[4],this._$bezierConverterBuffer[5],this._$bezierConverterBuffer[6],this._$bezierConverterBuffer[7],0,8),this._$split2Cubic(this._$bezierConverterBuffer[16],this._$bezierConverterBuffer[17],this._$bezierConverterBuffer[18],this._$bezierConverterBuffer[19],this._$bezierConverterBuffer[20],this._$bezierConverterBuffer[21],this._$bezierConverterBuffer[22],this._$bezierConverterBuffer[23],16,24),this._$split2Quad(this._$bezierConverterBuffer[0],this._$bezierConverterBuffer[1],this._$bezierConverterBuffer[2],this._$bezierConverterBuffer[3],this._$bezierConverterBuffer[4],this._$bezierConverterBuffer[5],this._$bezierConverterBuffer[6],this._$bezierConverterBuffer[7],0),this._$split2Quad(this._$bezierConverterBuffer[8],this._$bezierConverterBuffer[9],this._$bezierConverterBuffer[10],this._$bezierConverterBuffer[11],this._$bezierConverterBuffer[12],this._$bezierConverterBuffer[13],this._$bezierConverterBuffer[14],this._$bezierConverterBuffer[15],8),this._$split2Quad(this._$bezierConverterBuffer[16],this._$bezierConverterBuffer[17],this._$bezierConverterBuffer[18],this._$bezierConverterBuffer[19],this._$bezierConverterBuffer[20],this._$bezierConverterBuffer[21],this._$bezierConverterBuffer[22],this._$bezierConverterBuffer[23],16),this._$split2Quad(this._$bezierConverterBuffer[24],this._$bezierConverterBuffer[25],this._$bezierConverterBuffer[26],this._$bezierConverterBuffer[27],this._$bezierConverterBuffer[28],this._$bezierConverterBuffer[29],this._$bezierConverterBuffer[30],this._$bezierConverterBuffer[31],24)}_$split2Cubic(t,e,i,s,r,n,a,h,o,l){const c=.125*(t+3*(i+r)+a),_=.125*(e+3*(s+n)+h),$=.125*(a+r-i-t),u=.125*(h+n-s-e);this._$bezierConverterBuffer[o]=t,this._$bezierConverterBuffer[o+1]=e,this._$bezierConverterBuffer[o+2]=.5*(t+i),this._$bezierConverterBuffer[o+3]=.5*(e+s),this._$bezierConverterBuffer[o+4]=c-$,this._$bezierConverterBuffer[o+5]=_-u,this._$bezierConverterBuffer[o+6]=c,this._$bezierConverterBuffer[o+7]=_,this._$bezierConverterBuffer[l]=c,this._$bezierConverterBuffer[l+1]=_,this._$bezierConverterBuffer[l+2]=c+$,this._$bezierConverterBuffer[l+3]=_+u,this._$bezierConverterBuffer[l+4]=.5*(r+a),this._$bezierConverterBuffer[l+5]=.5*(n+h),this._$bezierConverterBuffer[l+6]=a,this._$bezierConverterBuffer[l+7]=h}_$split2Quad(t,e,i,s,r,n,a,h,o){const l=.125*(t+3*(i+r)+a),c=.125*(e+3*(s+n)+h);this._$bezierConverterBuffer[o]=.25*t+.75*i,this._$bezierConverterBuffer[o+1]=.25*e+.75*s,this._$bezierConverterBuffer[o+2]=l,this._$bezierConverterBuffer[o+3]=c,this._$bezierConverterBuffer[o+4]=.75*r+.25*a,this._$bezierConverterBuffer[o+5]=.75*n+.25*h,this._$bezierConverterBuffer[o+6]=a,this._$bezierConverterBuffer[o+7]=h}}class Di{constructor(){this._$currentPath=ht(),this._$vertices=ht(),this._$bezierConverter=new Oi}get vertices(){return this._$pushCurrentPathToVertices(),this._$vertices}begin(){for(this._$currentPath.length=0;this._$vertices.length;)ot(this._$vertices.pop())}moveTo(t,e){this._$currentPath.length?this._$equalsToLastPoint(t,e)||(this._$pushCurrentPathToVertices(),this._$pushPointToCurrentPath(t,e,!1)):this._$pushPointToCurrentPath(t,e,!1)}lineTo(t,e){this._$currentPath.length||this.moveTo(0,0),this._$equalsToLastPoint(t,e)||this._$pushPointToCurrentPath(t,e,!1)}quadTo(t,e,i,s){this._$currentPath.length||this.moveTo(0,0),this._$equalsToLastPoint(i,s)||(this._$pushPointToCurrentPath(t,e,!0),this._$pushPointToCurrentPath(i,s,!1))}cubicTo(t,e,i,s,r,n){if(this._$currentPath.length||this.moveTo(0,0),this._$equalsToLastPoint(r,n))return;const a=+this._$currentPath[this._$currentPath.length-3],h=+this._$currentPath[this._$currentPath.length-2];this._$bezierConverter.cubicToQuad(a,h,t,e,i,s,r,n);const o=this._$bezierConverter._$bezierConverterBuffer;for(let t=0;t<32;)this.quadTo(o[t++],o[t++],o[t++],o[t++])}drawCircle(t,e,i){const s=i,r=.5522847498307936*i;this.cubicTo(t+s,e+r,t+r,e+s,t,e+s),this.cubicTo(t-r,e+s,t-s,e+r,t-s,e),this.cubicTo(t-s,e-r,t-r,e-s,t,e-s),this.cubicTo(t+r,e-s,t+s,e-r,t+s,e)}close(){if(this._$currentPath.length<=6)return;const t=+this._$currentPath[0],e=+this._$currentPath[1];this._$equalsToLastPoint(t,e)||this._$pushPointToCurrentPath(t,e,!1)}_$equalsToLastPoint(t,e){const i=+this._$currentPath[this._$currentPath.length-3],s=+this._$currentPath[this._$currentPath.length-2];return t===i&&e===s}_$pushPointToCurrentPath(t,e,i){this._$currentPath.push(t,e,i)}_$pushCurrentPathToVertices(){this._$currentPath.length<4?this._$currentPath.length=0:(this._$vertices.push(this._$currentPath),this._$currentPath=ht())}createRectVertices(t,e,i,s){return ht(ht(t,e,!1,t+i,e,!1,t+i,e+s,!1,t,e+s,!1))}}class Ui{constructor(){this.enabled=!1,this.parentMatrixA=1,this.parentMatrixB=0,this.parentMatrixC=0,this.parentMatrixD=0,this.parentMatrixE=1,this.parentMatrixF=0,this.parentMatrixG=0,this.parentMatrixH=0,this.parentMatrixI=1,this.ancestorMatrixA=1,this.ancestorMatrixB=0,this.ancestorMatrixC=0,this.ancestorMatrixD=0,this.ancestorMatrixE=1,this.ancestorMatrixF=0,this.ancestorMatrixG=0,this.ancestorMatrixH=0,this.ancestorMatrixI=1,this.parentViewportX=0,this.parentViewportY=0,this.parentViewportW=0,this.parentViewportH=0,this.minXST=1e-5,this.minYST=1e-5,this.minXPQ=1e-5,this.minYPQ=1e-5,this.maxXST=.99999,this.maxYST=.99999,this.maxXPQ=.99999,this.maxYPQ=.99999}enable(t,e,i,s,r,n,a,h,o,l,c,_,$,u,d,g,f,p,m){const x=r.xMax-r.xMin,b=r.yMax-r.yMin,T=n.w,y=n.h,E=v.abs(v.ceil(x*a)),A=v.abs(v.ceil(b*a)),M=T>0?(n.x-r.xMin)/x:1e-5,S=y>0?(n.y-r.yMin)/b:1e-5,w=T>0?(n.x+n.w-r.xMin)/x:.99999,C=y>0?(n.y+n.h-r.yMin)/b:.99999;let I=E*M/i,F=A*S/s,R=(i-E*(1-w))/i,B=(s-A*(1-C))/s;if(I>=R){const t=M/(M+(1-w));I=v.max(t-1e-5,0),R=v.min(t+1e-5,1)}if(F>=B){const t=S/(S+(1-C));F=v.max(t-1e-5,0),B=v.min(t+1e-5,1)}this.enabled=!0,this.parentMatrixA=h,this.parentMatrixB=o,this.parentMatrixD=l,this.parentMatrixE=c,this.parentMatrixG=_,this.parentMatrixH=$,this.ancestorMatrixA=u,this.ancestorMatrixB=d,this.ancestorMatrixD=g,this.ancestorMatrixE=f,this.ancestorMatrixG=p,this.ancestorMatrixH=m,this.parentViewportX=t,this.parentViewportY=e,this.parentViewportW=i,this.parentViewportH=s,this.minXST=M,this.minYST=S,this.minXPQ=I,this.minYPQ=F,this.maxXST=w,this.maxYST=C,this.maxXPQ=R,this.maxYPQ=B}disable(){this.enabled=!1}}class Vi{constructor(t,e){this._$gl=t,this._$array=[],this._$map=ct();const i=this._$gl.getProgramParameter(e,this._$gl.ACTIVE_UNIFORMS);for(let t=0;t0&&(t.assign--,t.method(t.array)))}}}class Gi{constructor(){this._$attributes=[],this._$count=0}get attributes(){return this._$attributes}get count(){return this._$count}set count(t){this._$count=t}clear(){this._$attributes.length=0,this._$count=0}}class zi{constructor(t,e,i,s){this._$gl=t,this._$context=e,this._$program=this._$createProgram(i,s),this._$uniform=new Vi(t,this._$program),this._$instance=null}get instance(){return this._$instance||(this._$instance=new Gi),this._$instance}get uniform(){return this._$uniform}_$createProgram(t,e){const i=this._$gl.createProgram();i.id=p++;const s=this._$gl.createShader(this._$gl.VERTEX_SHADER);this._$gl.shaderSource(s,t),this._$gl.compileShader(s);const r=this._$gl.createShader(this._$gl.FRAGMENT_SHADER);return this._$gl.shaderSource(r,e),this._$gl.compileShader(r),this._$gl.attachShader(i,s),this._$gl.attachShader(i,r),this._$gl.linkProgram(i),this._$gl.detachShader(i,s),this._$gl.detachShader(i,r),this._$gl.deleteShader(s),this._$gl.deleteShader(r),i}_$attachProgram(){const t=this._$context.shaderList;t.currentProgramId!==this._$program.id&&(t.currentProgramId=this._$program.id,this._$gl.useProgram(this._$program))}drawArraysInstanced(t){this._$attachProgram(),this._$context.vao.bindInstnceArray(t),this._$gl.drawArraysInstanced(this._$gl.TRIANGLE_STRIP,0,4,t.count)}_$drawImage(){this._$attachProgram(),this._$uniform.bindUniforms(),this._$context.vao.bindCommonVertexArray(),this._$gl.drawArrays(this._$gl.TRIANGLE_STRIP,0,4)}_$drawGradient(t,e){this._$attachProgram(),this._$uniform.bindUniforms(),this._$context.vao.bindGradientVertexArray(t,e),this._$gl.drawArrays(this._$gl.TRIANGLE_STRIP,0,4)}_$stroke(t){this._$attachProgram(),this._$context.blend.reset(),this._$uniform.bindUniforms(),this._$context.vao.bind(t),this._$gl.drawElements(this._$gl.TRIANGLES,t.indexCount,this._$gl.UNSIGNED_SHORT,0)}_$fill(t){this._$attachProgram(),this._$context.blend.reset(),this._$uniform.bindUniforms(),this._$context.vao.bind(t);const e=t.indexRanges,i=e[e.length-1];this._$gl.drawArrays(this._$gl.TRIANGLES,0,i.first+i.count)}_$containerClip(t,e,i){this._$attachProgram(),this._$context.blend.reset(),this._$uniform.bindUniforms(),this._$context.vao.bind(t),this._$gl.drawArrays(this._$gl.TRIANGLES,e,i)}_$drawPoints(t,e,i){this._$attachProgram(),this._$uniform.bindUniforms(),this._$context.vao.bind(t),this._$gl.drawArrays(this._$gl.POINTS,e,i)}}class Xi{static FUNCTION_GRID_OFF(){return"\n\nvec2 applyMatrix(in vec2 vertex) {\n mat3 matrix = mat3(\n u_highp[0].xyz,\n u_highp[1].xyz,\n u_highp[2].xyz\n );\n\n vec2 position = (matrix * vec3(vertex, 1.0)).xy;\n\n return position;\n}\n\n"}static FUNCTION_GRID_ON(t){return`\n\nvec2 applyMatrix(in vec2 vertex) {\n mat3 parent_matrix = mat3(\n u_highp[${t}].xyz,\n u_highp[${t+1}].xyz,\n u_highp[${t+2}].xyz\n );\n mat3 ancestor_matrix = mat3(\n u_highp[${t+3}].xyz,\n u_highp[${t+4}].xyz,\n u_highp[${t+5}].xyz\n );\n vec2 parent_offset = vec2(u_highp[${t+2}].w, u_highp[${t+3}].w);\n vec2 parent_size = vec2(u_highp[${t+4}].w, u_highp[${t+5}].w);\n vec4 grid_min = u_highp[${t+6}];\n vec4 grid_max = u_highp[${t+7}];\n\n vec2 position = (parent_matrix * vec3(vertex, 1.0)).xy;\n position = (position - parent_offset) / parent_size;\n\n vec4 ga = grid_min;\n vec4 gb = grid_max - grid_min;\n vec4 gc = vec4(1.0) - grid_max;\n\n vec2 pa = position;\n vec2 pb = position - grid_min.st;\n vec2 pc = position - grid_max.st;\n\n position = (ga.pq / ga.st) * min(pa, ga.st)\n + (gb.pq / gb.st) * clamp(pb, vec2(0.0), gb.st)\n + (gc.pq / gc.st) * max(vec2(0.0), pc);\n\n position = position * parent_size + parent_offset;\n position = (ancestor_matrix * vec3(position, 1.0)).xy;\n\n return position;\n}\n\n`}}class qi{static TEMPLATE(t,e,i,s){const r=e-1,n=i?this.VARYING_UV_ON():"",a=i?this.STATEMENT_UV_ON():"";return`#version 300 es\n\nlayout (location = 0) in vec2 a_vertex;\nlayout (location = 1) in vec2 a_option1;\nlayout (location = 2) in vec2 a_option2;\nlayout (location = 3) in float a_type;\n\nuniform vec4 u_highp[${t}];\n\n${n}\n\n${s?Xi.FUNCTION_GRID_ON(i?5:0):Xi.FUNCTION_GRID_OFF()}\n\nfloat crossVec2(in vec2 v1, in vec2 v2) {\n return v1.x * v2.y - v2.x * v1.y;\n}\n\nvec2 perpendicularVec2(in vec2 v1) {\n float face = u_highp[${r}][1];\n\n return face * vec2(v1.y, -v1.x);\n}\n\nvec2 calculateNormal(in vec2 direction) {\n vec2 normalized = normalize(direction);\n return perpendicularVec2(normalized);\n}\n\nvec2 calculateIntersection(in vec2 v1, in vec2 v2, in vec2 o1, in vec2 o2) {\n float t = crossVec2(o2 - o1, v2) / crossVec2(v1, v2);\n return (o1 + t * v1);\n}\n\nvec2 calculateAnchor(in vec2 position, in float convex, out vec2 v1, out vec2 v2, out vec2 o1, out vec2 o2) {\n float miter_limit = u_highp[${r}][2];\n\n vec2 a = applyMatrix(a_option1);\n vec2 b = applyMatrix(a_option2);\n\n v1 = convex * (position - a);\n v2 = convex * (b - position);\n o1 = calculateNormal(v1) + a;\n o2 = calculateNormal(v2) + position;\n\n vec2 anchor = calculateIntersection(v1, v2, o1, o2) - position;\n return normalize(anchor) * min(length(anchor), miter_limit);\n}\n\nvoid main() {\n vec2 viewport = vec2(u_highp[0].w, u_highp[1].w);\n float half_width = u_highp[${r}][0];\n\n vec2 position = applyMatrix(a_vertex);\n vec2 offset = vec2(0.0);\n vec2 v1, v2, o1, o2;\n\n if (a_type == 1.0 || a_type == 2.0) { // 線分\n offset = calculateNormal(a_option2 * (applyMatrix(a_option1) - position));\n } else if (a_type == 10.0) { // スクエア線端\n offset = normalize(position - applyMatrix(a_option1));\n offset += a_option2 * perpendicularVec2(offset);\n } else if (a_type == 21.0) { // マイター結合(線分Bの凸側)\n offset = calculateAnchor(position, 1.0, v1, v2, o1, o2);\n offset = calculateIntersection(v2, perpendicularVec2(offset), o2, position + offset) - position;\n } else if (a_type == 22.0) { // マイター結合(線分Aの凸側)\n offset = calculateAnchor(position, 1.0, v1, v2, o1, o2);\n offset = calculateIntersection(v1, perpendicularVec2(offset), o1, position + offset) - position;\n } else if (a_type == 23.0) { // マイター結合(線分Aの凹側)\n offset = calculateAnchor(position, -1.0, v1, v2, o1, o2);\n offset = calculateIntersection(v1, perpendicularVec2(offset), o1, position + offset) - position;\n } else if (a_type == 24.0) { // マイター結合(線分Bの凹側)\n offset = calculateAnchor(position, -1.0, v1, v2, o1, o2);\n offset = calculateIntersection(v2, perpendicularVec2(offset), o2, position + offset) - position;\n } else if (a_type >= 30.0) { // ラウンド結合\n float face = u_highp[${r}][1];\n float rad = face * (a_type - 30.0) * 0.3488888889; /* 0.3488888889 = PI / 9.0 */\n offset = mat2(cos(rad), sin(rad), -sin(rad), cos(rad)) * vec2(1.0, 0.0);\n }\n \n offset *= half_width;\n position += offset;\n ${a}\n\n position /= viewport;\n position = position * 2.0 - 1.0;\n gl_Position = vec4(position.x, -position.y, 0.0, 1.0);\n}\n\n`}static VARYING_UV_ON(){return"\nout vec2 v_uv;\n"}static STATEMENT_UV_ON(){return"\n mat3 uv_matrix = mat3(\n u_highp[0].xyz,\n u_highp[1].xyz,\n u_highp[2].xyz\n );\n mat3 inverse_matrix = mat3(\n u_highp[3].xyz,\n u_highp[4].xyz,\n vec3(u_highp[2].w, u_highp[3].w, u_highp[4].w)\n );\n\n v_uv = (uv_matrix * vec3(a_vertex, 1.0)).xy;\n v_uv += offset;\n v_uv = (inverse_matrix * vec3(v_uv, 1.0)).xy;\n"}}class Yi{static TEMPLATE(t,e,i,s){const r=i?this.ATTRIBUTE_BEZIER_ON():"",n=i?this.VARYING_BEZIER_ON():e?this.VARYING_UV_ON():"",a=i?this.STATEMENT_BEZIER_ON():e?this.STATEMENT_UV_ON():"";return`#version 300 es\n\nlayout (location = 0) in vec2 a_vertex;\n${r}\n\nuniform vec4 u_highp[${t}];\n\n${n}\n\n${s?Xi.FUNCTION_GRID_ON(e?5:0):Xi.FUNCTION_GRID_OFF()}\n\nvoid main() {\n vec2 viewport = vec2(u_highp[0].w, u_highp[1].w);\n\n ${a}\n\n vec2 pos = applyMatrix(a_vertex) / viewport;\n pos = pos * 2.0 - 1.0;\n gl_Position = vec4(pos.x, -pos.y, 0.0, 1.0);\n}\n\n`}static ATTRIBUTE_BEZIER_ON(){return"\nlayout (location = 1) in vec2 a_bezier;\n"}static VARYING_UV_ON(){return"\nout vec2 v_uv;\n"}static VARYING_BEZIER_ON(){return"\nout vec2 v_bezier;\n"}static STATEMENT_UV_ON(){return"\n mat3 uv_matrix = mat3(\n u_highp[0].xyz,\n u_highp[1].xyz,\n u_highp[2].xyz\n );\n mat3 inverse_matrix = mat3(\n u_highp[3].xyz,\n u_highp[4].xyz,\n vec3(u_highp[2].w, u_highp[3].w, u_highp[4].w)\n );\n\n v_uv = (inverse_matrix * uv_matrix * vec3(a_vertex, 1.0)).xy;\n"}static STATEMENT_BEZIER_ON(){return"\n v_bezier = a_bezier;\n"}}class Hi{static FUNCTION_IS_INSIDE(){return"\n\nfloat isInside(in vec2 uv) {\n return step(4.0, dot(step(vec4(0.0, uv.x, 0.0, uv.y), vec4(uv.x, 1.0, uv.y, 1.0)), vec4(1.0)));\n}\n\n"}static STATEMENT_INSTANCED_COLOR_TRANSFORM_ON(){return"\n src.rgb /= max(0.0001, src.a);\n src = clamp(src * mul + add, 0.0, 1.0);\n src.rgb *= src.a;\n"}static STATEMENT_COLOR_TRANSFORM_ON(t){return`\n vec4 mul = u_mediump[${t}];\n vec4 add = u_mediump[${t+1}];\n${Hi.STATEMENT_INSTANCED_COLOR_TRANSFORM_ON()}\n`}}class ji{static SOLID_COLOR(){return"#version 300 es\nprecision mediump float;\n\nuniform vec4 u_mediump;\n\nout vec4 o_color;\n\nvoid main() {\n o_color = vec4(u_mediump.rgb * u_mediump.a, u_mediump.a);\n}\n\n"}static BITMAP_CLIPPED(){return`#version 300 es\nprecision mediump float;\n\nuniform sampler2D u_texture;\nuniform vec4 u_mediump[3];\n\nin vec2 v_uv;\nout vec4 o_color;\n\nvoid main() {\n vec2 uv = vec2(v_uv.x, u_mediump[0].y - v_uv.y) / u_mediump[0].xy;\n\n vec4 src = texture(u_texture, uv);\n ${Hi.STATEMENT_COLOR_TRANSFORM_ON(1)}\n o_color = src;\n}`}static BITMAP_PATTERN(){return`#version 300 es\nprecision mediump float;\n\nuniform sampler2D u_texture;\nuniform vec4 u_mediump[3];\n\nin vec2 v_uv;\nout vec4 o_color;\n\nvoid main() {\n vec2 uv = fract(vec2(v_uv.x, -v_uv.y) / u_mediump[0].xy);\n \n vec4 src = texture(u_texture, uv);\n ${Hi.STATEMENT_COLOR_TRANSFORM_ON(1)}\n o_color = src;\n}`}static MASK(){return"#version 300 es\nprecision mediump float;\n\nin vec2 v_bezier;\nout vec4 o_color;\n\nvoid main() {\n vec2 px = dFdx(v_bezier);\n vec2 py = dFdy(v_bezier);\n\n vec2 f = (2.0 * v_bezier.x) * vec2(px.x, py.x) - vec2(px.y, py.y);\n float alpha = 0.5 - (v_bezier.x * v_bezier.x - v_bezier.y) / length(f);\n\n if (alpha > 0.0) {\n o_color = vec4(min(alpha, 1.0));\n } else {\n discard;\n } \n}\n\n"}}class Wi{constructor(t,e){this._$context=t,this._$gl=e,this._$collection=ct()}getSolidColorShapeShader(t,e){const i=`s${t?"y":"n"}${e?"y":"n"}`;if(this._$collection.has(i)){const t=this._$collection.get(i);if(t)return t}const s=(e?8:3)+(t?1:0),r=s;let n;n=t?qi.TEMPLATE(s,r,!1,e):Yi.TEMPLATE(s,!1,!1,e);const a=new zi(this._$gl,this._$context,n,ji.SOLID_COLOR());return this._$collection.set(i,a),a}getBitmapShapeShader(t,e,i){const s=`b${t?"y":"n"}${e?"y":"n"}${i?"y":"n"}`;if(this._$collection.has(s)){const t=this._$collection.get(s);if(t)return t}const r=(i?13:5)+(t?1:0),n=r;let a;a=t?qi.TEMPLATE(r,n,!0,i):Yi.TEMPLATE(r,!0,!1,i);const h=e?ji.BITMAP_PATTERN():ji.BITMAP_CLIPPED(),o=new zi(this._$gl,this._$context,a,h);return this._$collection.set(s,o),o}getMaskShapeShader(t,e){const i=`m${t?"y":"n"}${e?"y":"n"}`;if(this._$collection.has(i)){const t=this._$collection.get(i);if(t)return t}const s=(e?8:3)+(t?1:0),r=s;let n;n=t?qi.TEMPLATE(s,r,!1,e):Yi.TEMPLATE(s,!1,!0,e);const a=new zi(this._$gl,this._$context,n,ji.MASK());return this._$collection.set(i,a),a}setSolidColorShapeUniform(t,e,i,s,r,n,a,h,o,l,c,_){const $=t.highp;let u;n?($[0]=l.parentMatrixA,$[1]=l.parentMatrixB,$[2]=l.parentMatrixC,$[4]=l.parentMatrixD,$[5]=l.parentMatrixE,$[6]=l.parentMatrixF,$[8]=l.parentMatrixG,$[9]=l.parentMatrixH,$[10]=l.parentMatrixI,$[12]=l.ancestorMatrixA,$[13]=l.ancestorMatrixB,$[14]=l.ancestorMatrixC,$[16]=l.ancestorMatrixD,$[17]=l.ancestorMatrixE,$[18]=l.ancestorMatrixF,$[20]=l.ancestorMatrixG,$[21]=l.ancestorMatrixH,$[22]=l.ancestorMatrixI,$[3]=h,$[7]=o,$[11]=l.parentViewportX,$[15]=l.parentViewportY,$[19]=l.parentViewportW,$[23]=l.parentViewportH,$[24]=l.minXST,$[25]=l.minYST,$[26]=l.minXPQ,$[27]=l.minYPQ,$[28]=l.maxXST,$[29]=l.maxYST,$[30]=l.maxXPQ,$[31]=l.maxYPQ,u=32):($[0]=a[0],$[1]=a[1],$[2]=a[2],$[4]=a[3],$[5]=a[4],$[6]=a[5],$[8]=a[6],$[9]=a[7],$[10]=a[8],$[3]=h,$[7]=o,u=12),e&&($[u]=i,$[u+1]=s,$[u+2]=r);const d=t.mediump;d[0]=c[0],d[1]=c[1],d[2]=c[2],d[3]=c[3]*_}setBitmapShapeUniform(t,e,i,s,r,n,a,h,o,l,c,_,$,u,d,g,f,p,m,x,b){const v=t.highp;let T;v[0]=a[0],v[1]=a[1],v[2]=a[2],v[4]=a[3],v[5]=a[4],v[6]=a[5],v[8]=a[6],v[9]=a[7],v[10]=a[8],v[12]=h[0],v[13]=h[1],v[14]=h[2],v[16]=h[3],v[17]=h[4],v[18]=h[5],v[11]=h[6],v[15]=h[7],v[19]=h[8],v[3]=o,v[7]=l,T=20,n&&(v[T]=c.parentMatrixA,v[T+1]=c.parentMatrixB,v[T+2]=c.parentMatrixC,v[T+4]=c.parentMatrixD,v[T+5]=c.parentMatrixE,v[T+6]=c.parentMatrixF,v[T+8]=c.parentMatrixG,v[T+9]=c.parentMatrixH,v[T+10]=c.parentMatrixI,v[T+12]=c.ancestorMatrixA,v[T+13]=c.ancestorMatrixB,v[T+14]=c.ancestorMatrixC,v[T+16]=c.ancestorMatrixD,v[T+17]=c.ancestorMatrixE,v[T+18]=c.ancestorMatrixF,v[T+20]=c.ancestorMatrixG,v[T+21]=c.ancestorMatrixH,v[T+22]=c.ancestorMatrixI,v[T+11]=c.parentViewportX,v[T+15]=c.parentViewportY,v[T+19]=c.parentViewportW,v[T+23]=c.parentViewportH,v[T+24]=c.minXST,v[T+25]=c.minYST,v[T+26]=c.minXPQ,v[T+27]=c.minYPQ,v[T+28]=c.maxXST,v[T+29]=c.maxYST,v[T+30]=c.maxXPQ,v[T+31]=c.maxYPQ,T=52),e&&(v[T]=i,v[T+1]=s,v[T+2]=r);const y=t.mediump;y[0]=_,y[1]=$,y[4]=u,y[5]=d,y[6]=g,y[7]=f,y[8]=p,y[9]=m,y[10]=x,y[11]=b}setMaskShapeUniform(t,e,i,s,r,n,a,h,o,l,c,_,$,u=null){const d=t.highp;e&&u?(d[0]=u.parentMatrixA,d[1]=u.parentMatrixB,d[2]=u.parentMatrixC,d[4]=u.parentMatrixD,d[5]=u.parentMatrixE,d[6]=u.parentMatrixF,d[8]=u.parentMatrixG,d[9]=u.parentMatrixH,d[10]=u.parentMatrixI,d[12]=u.ancestorMatrixA,d[13]=u.ancestorMatrixB,d[14]=u.ancestorMatrixC,d[16]=u.ancestorMatrixD,d[17]=u.ancestorMatrixE,d[18]=u.ancestorMatrixF,d[20]=u.ancestorMatrixG,d[21]=u.ancestorMatrixH,d[22]=u.ancestorMatrixI,d[3]=_,d[7]=$,d[11]=u.parentViewportX,d[15]=u.parentViewportY,d[19]=u.parentViewportW,d[23]=u.parentViewportH,d[24]=u.minXST,d[25]=u.minYST,d[26]=u.minXPQ,d[27]=u.minYPQ,d[28]=u.maxXST,d[29]=u.maxYST,d[30]=u.maxXPQ,d[31]=u.maxYPQ):(d[0]=i,d[1]=s,d[2]=r,d[4]=n,d[5]=a,d[6]=h,d[8]=o,d[9]=l,d[10]=c,d[3]=_,d[7]=$)}setMaskShapeUniformIdentity(t,e,i){const s=t.highp;s[0]=1,s[1]=0,s[2]=0,s[4]=0,s[5]=1,s[6]=0,s[8]=0,s[9]=0,s[10]=1,s[3]=e,s[7]=i}}class Ki{static TEMPLATE(t,e,i,s,r){const n=i?this.STATEMENT_GRADIENT_TYPE_RADIAL(e,s):this.STATEMENT_GRADIENT_TYPE_LINEAR(e);let a;switch(r){case"reflect":a="1.0 - abs(fract(t * 0.5) * 2.0 - 1.0)";break;case"repeat":a="fract(t)";break;default:a="clamp(t, 0.0, 1.0)"}return`#version 300 es\nprecision highp float;\n\nuniform sampler2D u_texture;\nuniform vec4 u_highp[${t}];\n\nin vec2 v_uv;\nout vec4 o_color;\n\nvoid main() {\n vec2 p = v_uv;\n ${n}\n t = ${a};\n o_color = texture(u_texture, vec2(t, 0.5));\n}\n\n`}static STATEMENT_GRADIENT_TYPE_LINEAR(t){return`\n vec2 a = u_highp[${t}].xy;\n vec2 b = u_highp[${t}].zw;\n\n vec2 ab = b - a;\n vec2 ap = p - a;\n\n float t = dot(ab, ap) / dot(ab, ab);\n`}static STATEMENT_GRADIENT_TYPE_RADIAL(t,e){return`\n float radius = u_highp[${t}][0];\n\n vec2 coord = p / radius;\n ${e?this.STATEMENT_FOCAL_POINT_ON(t):this.STATEMENT_FOCAL_POINT_OFF()}\n`}static STATEMENT_FOCAL_POINT_OFF(){return"\n float t = length(coord);\n"}static STATEMENT_FOCAL_POINT_ON(t){return`\n vec2 focal = vec2(u_highp[${t}][1], 0.0);\n\n vec2 dir = normalize(coord - focal);\n\n float a = dot(dir, dir);\n float b = 2.0 * dot(dir, focal);\n float c = dot(focal, focal) - 1.0;\n float x = (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a);\n\n float t = distance(focal, coord) / distance(focal, focal + dir * x);\n`}}class Qi{constructor(t,e){this._$context=t,this._$gl=e,this._$collection=ct()}getGradientShapeShader(t,e,i,s,r){const n=this.createCollectionKey(t,e,i,s,r);if(this._$collection.has(n)){const t=this._$collection.get(n);if(t)return t}const a=(e?13:5)+(t?1:0)+1,h=a-1;let o;o=t?qi.TEMPLATE(a,h,!0,e):Yi.TEMPLATE(a,!0,!1,e);const l=new zi(this._$gl,this._$context,o,Ki.TEMPLATE(a,h,i,s,r));return this._$collection.set(n,l),l}createCollectionKey(t,e,i,s,r){const n=t?"y":"n",a=e?"y":"n",h=i?"y":"n",o=i&&s?"y":"n";let l=0;switch(r){case"reflect":l=1;break;case"repeat":l=2}return`${n}${a}${h}${o}${l}`}setGradientShapeUniform(t,e,i,s,r,n,a,h,o,l,c,_,$,u){const d=t.highp;d[0]=a[0],d[1]=a[1],d[2]=a[2],d[4]=a[3],d[5]=a[4],d[6]=a[5],d[8]=a[6],d[9]=a[7],d[10]=a[8],d[12]=h[0],d[13]=h[1],d[14]=h[2],d[16]=h[3],d[17]=h[4],d[18]=h[5],d[11]=h[6],d[15]=h[7],d[19]=h[8],d[3]=o,d[7]=l;let g=20;n&&(d[g]=c.parentMatrixA,d[g+1]=c.parentMatrixB,d[g+2]=c.parentMatrixC,d[g+4]=c.parentMatrixD,d[g+5]=c.parentMatrixE,d[g+6]=c.parentMatrixF,d[g+8]=c.parentMatrixG,d[g+9]=c.parentMatrixH,d[g+10]=c.parentMatrixI,d[g+12]=c.ancestorMatrixA,d[g+13]=c.ancestorMatrixB,d[g+14]=c.ancestorMatrixC,d[g+16]=c.ancestorMatrixD,d[g+17]=c.ancestorMatrixE,d[g+18]=c.ancestorMatrixF,d[g+20]=c.ancestorMatrixG,d[g+21]=c.ancestorMatrixH,d[g+22]=c.ancestorMatrixI,d[g+11]=c.parentViewportX,d[g+15]=c.parentViewportY,d[g+19]=c.parentViewportW,d[g+23]=c.parentViewportH,d[g+24]=c.minXST,d[g+25]=c.minYST,d[g+26]=c.minXPQ,d[g+27]=c.minYPQ,d[g+28]=c.maxXST,d[g+29]=c.maxYST,d[g+30]=c.maxXPQ,d[g+31]=c.maxYPQ,g=52),e&&(d[g]=i,d[g+1]=s,d[g+2]=r,g+=4),_?(d[g]=$[5],d[g+1]=u):(d[g]=$[0],d[g+1]=$[1],d[g+2]=$[2],d[g+3]=$[3])}}class Ji{static TEXTURE(){return"#version 300 es\n\nlayout (location = 0) in vec2 a_vertex;\n\nout vec2 v_coord;\n\nvoid main() {\n v_coord = a_vertex;\n\n vec2 position = a_vertex * 2.0 - 1.0;\n gl_Position = vec4(position, 0.0, 1.0);\n}\n\n"}static BLEND(){return"#version 300 es\n\nlayout (location = 0) in vec2 a_vertex;\n\nuniform vec4 u_highp[4];\n\nout vec2 v_coord;\n\nvoid main() {\n v_coord = a_vertex;\n\n vec2 offset = u_highp[0].xy;\n vec2 size = u_highp[0].zw;\n mat3 matrix = mat3(u_highp[1].xyz, u_highp[2].xyz, u_highp[3].xyz);\n vec2 viewport = vec2(u_highp[1].w, u_highp[2].w);\n\n vec2 position = vec2(a_vertex.x, 1.0 - a_vertex.y);\n position = position * size + offset;\n position = (matrix * vec3(position, 1.0)).xy;\n position /= viewport;\n\n position = position * 2.0 - 1.0;\n gl_Position = vec4(position.x, -position.y, 0.0, 1.0);\n}\n\n"}static INSTANCE_BLEND(){return"#version 300 es\n\nlayout (location = 0) in vec2 a_vertex;\n\nuniform vec4 u_highp[5];\n\nout vec2 v_src_coord;\nout vec2 v_dst_coord;\n\nvoid main() {\n vec4 rect = vec4(u_highp[0].x, u_highp[0].y, u_highp[0].z, u_highp[0].w);\n vec2 size = vec2(u_highp[4].x, u_highp[4].y);\n mat3 matrix = mat3(u_highp[1].xyz, u_highp[2].xyz, u_highp[3].xyz);\n vec2 viewport = vec2(u_highp[1].w, u_highp[2].w);\n\n v_src_coord = a_vertex * rect.zw + rect.xy;\n v_dst_coord = a_vertex;\n\n vec2 position = vec2(a_vertex.x, 1.0 - a_vertex.y);\n position = position * size;\n position = (matrix * vec3(position, 1.0)).xy;\n position /= viewport;\n\n position = position * 2.0 - 1.0;\n gl_Position = vec4(position.x, -position.y, 0.0, 1.0);\n}\n\n"}static INSTANCE(){return"#version 300 es\n\nlayout (location = 0) in vec2 a_vertex;\nlayout (location = 1) in vec4 a_rect;\nlayout (location = 2) in vec4 a_size;\nlayout (location = 3) in vec2 a_offset;\nlayout (location = 4) in vec4 a_matrix;\nlayout (location = 5) in vec4 a_mul;\nlayout (location = 6) in vec4 a_add;\n\nout vec2 v_coord;\nout vec4 mul;\nout vec4 add;\n\nvoid main() {\n v_coord = a_vertex * a_rect.zw + a_rect.xy;\n mul = a_mul;\n add = a_add;\n\n vec2 position = vec2(a_vertex.x, 1.0 - a_vertex.y);\n position = position * a_size.xy;\n mat3 matrix = mat3(a_matrix.x, a_matrix.y, 0.0, a_matrix.z, a_matrix.w, 0.0, a_offset.x, a_offset.y, 1.0);\n position = (matrix * vec3(position, 1.0)).xy;\n position /= a_size.zw;\n\n position = position * 2.0 - 1.0;\n gl_Position = vec4(position.x, -position.y, 0.0, 1.0);\n}\n\n"}static BLEND_CLIP(){return"#version 300 es\n\nlayout (location = 0) in vec2 a_vertex;\n\nuniform vec4 u_highp[4];\n\nout vec2 v_coord;\n\nvoid main() {\n v_coord = a_vertex;\n\n vec2 offset = u_highp[0].xy;\n vec2 size = u_highp[0].zw;\n mat3 inv_matrix = mat3(u_highp[1].xyz, u_highp[2].xyz, u_highp[3].xyz);\n vec2 viewport = vec2(u_highp[1].w, u_highp[2].w);\n\n vec2 position = vec2(a_vertex.x, 1.0 - a_vertex.y);\n position *= viewport;\n position = (inv_matrix * vec3(position, 1.0)).xy;\n position = (position - offset) / size;\n\n position = position * 2.0 - 1.0;\n gl_Position = vec4(position.x, -position.y, 0.0, 1.0);\n}\n\n"}}class Zi{static TEMPLATE(t,e,i){let s="";for(let t=1;t>16)/255,h[a++]=(e>>8&255)/255,h[a++]=(255&e)/255,h[a++]=s[t]}for(let t=r;tthis._$vertexBufferData.length){const t=new A(2*this._$vertexBufferData.length);t.set(this._$vertexBufferData),this._$vertexBufferData=t}}static _$expandIndexBufferIfNeeded(t){if(this._$indexBufferPos+t>this._$indexBufferData.length){const t=new S(2*this._$indexBufferData.length);t.set(this._$indexBufferData),this._$indexBufferData=t}}static _$generateLineSegment(t){const e=t.length-5;for(let i=0;it*s-i*e;class ds{constructor(t){this._$gl=t,this._$fillVertexArrayPool=[],this._$strokeVertexArrayPool=[],this._$boundVertexArray=null,this._$fillAttrib_vertex=0,this._$fillAttrib_bezier=1,this._$strokeAttrib_vertex=0,this._$strokeAttrib_option1=1,this._$strokeAttrib_option2=2,this._$strokeAttrib_type=3,this._$vertexBufferData=new Float32Array([0,0,0,1,1,0,1,1]),this._$attributeVertexBuffer=t.createBuffer(),this._$attributeBuffer=new Float32Array(22),this._$instanceVertexArray=this._$getCommonVertexArray(),this._$commonVertexArray=this._$getVertexArray(0,1)}_$getCommonVertexArray(){const t=this._$gl.createVertexArray();this.bind(t);const e=this._$gl.createBuffer();return this._$gl.bindBuffer(this._$gl.ARRAY_BUFFER,e),this._$gl.bufferData(this._$gl.ARRAY_BUFFER,new Float32Array([0,0,0,1,1,0,1,1]),this._$gl.STATIC_DRAW),this._$gl.enableVertexAttribArray(0),this._$gl.vertexAttribPointer(0,2,this._$gl.FLOAT,!1,0,0),this._$gl.bindBuffer(this._$gl.ARRAY_BUFFER,this._$attributeVertexBuffer),this._$gl.bufferData(this._$gl.ARRAY_BUFFER,this._$attributeBuffer.byteLength,this._$gl.DYNAMIC_DRAW),this._$gl.enableVertexAttribArray(1),this._$gl.vertexAttribPointer(1,4,this._$gl.FLOAT,!1,88,0),this._$gl.vertexAttribDivisor(1,1),this._$gl.enableVertexAttribArray(2),this._$gl.vertexAttribPointer(2,4,this._$gl.FLOAT,!1,88,16),this._$gl.vertexAttribDivisor(2,1),this._$gl.enableVertexAttribArray(3),this._$gl.vertexAttribPointer(3,2,this._$gl.FLOAT,!1,88,32),this._$gl.vertexAttribDivisor(3,1),this._$gl.enableVertexAttribArray(4),this._$gl.vertexAttribPointer(4,4,this._$gl.FLOAT,!1,88,40),this._$gl.vertexAttribDivisor(4,1),this._$gl.enableVertexAttribArray(5),this._$gl.vertexAttribPointer(5,4,this._$gl.FLOAT,!1,88,56),this._$gl.vertexAttribDivisor(5,1),this._$gl.enableVertexAttribArray(6),this._$gl.vertexAttribPointer(6,4,this._$gl.FLOAT,!1,88,72),this._$gl.vertexAttribDivisor(6,1),t}_$getVertexArray(t,e){const i=this._$gl.createVertexArray();this.bind(i);const s=this._$gl.createBuffer();return this._$gl.bindBuffer(this._$gl.ARRAY_BUFFER,s),this._$vertexBufferData[0]=t,this._$vertexBufferData[2]=t,this._$vertexBufferData[4]=e,this._$vertexBufferData[6]=e,this._$gl.bufferData(this._$gl.ARRAY_BUFFER,this._$vertexBufferData,this._$gl.STATIC_DRAW),this._$gl.enableVertexAttribArray(0),this._$gl.vertexAttribPointer(0,2,this._$gl.FLOAT,!1,0,0),i}_$getFillVertexArray(){if(this._$fillVertexArrayPool.length){const t=this._$fillVertexArrayPool.pop();if(t)return t}const t=this._$gl.createVertexArray();this.bind(t);const e=this._$gl.createBuffer();return t.vertexBuffer=e,t.vertexLength=0,this._$gl.bindBuffer(this._$gl.ARRAY_BUFFER,e),this._$gl.enableVertexAttribArray(0),this._$gl.enableVertexAttribArray(1),this._$gl.vertexAttribPointer(this._$fillAttrib_vertex,2,this._$gl.FLOAT,!1,16,0),this._$gl.vertexAttribPointer(this._$fillAttrib_bezier,2,this._$gl.FLOAT,!1,16,8),t}_$getStrokeVertexArray(){if(this._$strokeVertexArrayPool.length){const t=this._$strokeVertexArrayPool.pop();if(t)return t}const t=this._$gl.createVertexArray();this.bind(t);const e=this._$gl.createBuffer();t.vertexBuffer=e,t.vertexLength=0,this._$gl.bindBuffer(this._$gl.ARRAY_BUFFER,e);const i=this._$gl.createBuffer();return t.indexBuffer=i,t.indexLength=0,this._$gl.bindBuffer(this._$gl.ELEMENT_ARRAY_BUFFER,i),this._$gl.enableVertexAttribArray(0),this._$gl.enableVertexAttribArray(1),this._$gl.enableVertexAttribArray(2),this._$gl.enableVertexAttribArray(3),this._$gl.vertexAttribPointer(this._$strokeAttrib_vertex,2,this._$gl.FLOAT,!1,28,0),this._$gl.vertexAttribPointer(this._$strokeAttrib_option1,2,this._$gl.FLOAT,!1,28,8),this._$gl.vertexAttribPointer(this._$strokeAttrib_option2,2,this._$gl.FLOAT,!1,28,16),this._$gl.vertexAttribPointer(this._$strokeAttrib_type,1,this._$gl.FLOAT,!1,28,24),t}createFill(t){const e=$s.generate(t),i=e.vertexBufferData,s=this._$getFillVertexArray();return s.indexRanges=e.indexRanges,this.bind(s),this._$gl.bindBuffer(this._$gl.ARRAY_BUFFER,s.vertexBuffer),s.vertexLengththis._$attributeBuffer.length&&(this._$attributeBuffer=new Float32Array(t.attributes.length),this._$gl.bufferData(this._$gl.ARRAY_BUFFER,this._$attributeBuffer.byteLength,this._$gl.DYNAMIC_DRAW)),this._$attributeBuffer.set(t.attributes),this._$gl.bufferSubData(this._$gl.ARRAY_BUFFER,0,this._$attributeBuffer.subarray(0,t.attributes.length))}bindCommonVertexArray(){this.bind(this._$commonVertexArray)}bindGradientVertexArray(t,e){const i=this._$getVertexArray(t,e);this.bind(i)}}class gs{constructor(t,e){this._$context=t,this._$gl=e,this._$clips=[],this._$poolClip=[],this._$clipStatus=!1,this._$containerClip=!1,this._$currentClip=!1}get containerClip(){return this._$containerClip}set containerClip(t){this._$containerClip=t}_$onClear(t){t&&(this._$gl.enable(this._$gl.STENCIL_TEST),this._$currentClip=!0)}_$onBind(t){!t&&this._$currentClip?(this._$gl.disable(this._$gl.STENCIL_TEST),this._$currentClip=!1):t&&!this._$currentClip&&(this._$gl.enable(this._$gl.STENCIL_TEST),this._$currentClip=!0,this._$endClipDef())}_$onClearRect(){this._$gl.disable(this._$gl.STENCIL_TEST),this._$currentClip=!1}_$enterClip(){this._$currentClip||(this._$gl.enable(this._$gl.STENCIL_TEST),this._$currentClip=!0);const t=this._$context.frameBuffer.currentAttachment;if(!t)throw new Error("mask currentAttachment is null.");t.mask=!0,++t.clipLevel}_$beginClipDef(){const t=this._$context.frameBuffer.currentAttachment;if(!t)throw new Error("mask currentAttachment is null.");this._$gl.enable(this._$gl.SAMPLE_ALPHA_TO_COVERAGE),this._$gl.stencilFunc(this._$gl.ALWAYS,0,255),this._$gl.stencilOp(this._$gl.KEEP,this._$gl.INVERT,this._$gl.INVERT),this._$gl.stencilMask(1<7&&(this._$unionStencilMask(e,a,h),n=e)}n>e+1&&this._$unionStencilMask(e,a,h)}_$unionStencilMask(t,e,i){const s=this._$context.path.createRectVertices(0,0,e,i),r=this._$context.vao.createFill(s);ot(s.pop()),ot(s);const n=this._$context.shaderList.shapeShaderVariants,a=n.getMaskShapeShader(!1,!1),h=a.uniform;n.setMaskShapeUniformIdentity(h,e,i);const o=r.indexRanges[0];this._$gl.stencilFunc(this._$gl.LEQUAL,1<this._$maxTextureSize?this._$maxTextureSize/i:1}drawInstacedArray(){this._$blend.drawInstacedArray()}clearInstacedArray(){this._$blend.clearInstacedArray()}bindRenderBuffer(t){this._$frameBufferManager.bindRenderBuffer(),this._$gl.clearColor(0,0,0,0),this._$gl.clear(this._$gl.COLOR_BUFFER_BIT|this._$gl.STENCIL_BUFFER_BIT),this._$viewportWidth=t.w,this._$viewportHeight=t.h,this._$gl.viewport(t.x,t.y,t.w,t.h),this._$gl.enable(this._$gl.SCISSOR_TEST),this._$gl.scissor(t.x,t.y,t.w,t.h)}getTextureFromRect(t){const e=this._$frameBufferManager,i=e.textureManager.getAtlasTexture(t.index),s=e.currentAttachment,r=e.createTextureAttachment(t.w,t.h);this._$bind(r),this.save(),this.setTransform(1,0,0,1,0,0),this.reset(),this.drawImage(i,-t.x,-i.height+t.h+t.y,i.width,i.height),this.restore();const n=r.texture;return e.releaseAttachment(r),this._$bind(s),n}drawBitmap(t){const e=this._$shaderList.blendShaderVariants,i=e.getNormalBlendShader(!1);e.setNormalBlendUniform(i.uniform,0,0,t.width,t.height,this._$matrix,this._$viewportWidth,this._$viewportHeight,!1,1,1,1,1,0,0,0,0),this._$frameBufferManager.textureManager.bind0(t,this._$imageSmoothingEnabled),this._$blend.toOperation("normal"),i._$drawImage()}drawTextureFromRect(t,e){const i=this._$frameBufferManager,s=i.currentAttachment;this.bindRenderBuffer(e),i.transferTexture(e);const r=i.textureManager.getAtlasTexture(e.index),n=i.createTextureAttachmentFrom(r);this._$bind(n),this._$gl.enable(this._$gl.SCISSOR_TEST),this._$gl.scissor(e.x,e.y,e.w,e.h),this._$gl.clearColor(0,0,0,0),this._$gl.disable(this._$gl.SCISSOR_TEST),this.save(),this.setTransform(1,0,0,1,0,0),this.reset(),this.drawImage(t,e.x,r.height-e.h-e.y,t.width,t.height),this.restore(),i.releaseAttachment(n),this._$bind(s),i.textureManager.release(t)}stopStencil(){this._$mask._$onClearRect()}_$bind(t=null){if(!t)return;this._$frameBufferManager.bind(t);const e=t.color,i=t.stencil,s=t.width,r=t.height;this._$viewportWidth===s&&this._$viewportHeight===r||(this._$viewportWidth=s,this._$viewportHeight=r,this._$gl.viewport(0,0,s,r)),(e&&e.dirty||i&&i.dirty)&&(e&&(e.dirty=!1),i&&(i.dirty=!1),this._$gl.clearColor(0,0,0,0),this.clearRect(0,0,this._$viewportWidth,this._$viewportHeight),this._$gl.clearColor(this._$clearColorR,this._$clearColorG,this._$clearColorB,this._$clearColorA),this._$mask._$onClear(t.mask)),this._$mask._$onBind(t.mask)}setTransform(t,e,i,s,r,n){this._$matrix[0]=t,this._$matrix[1]=e,this._$matrix[3]=i,this._$matrix[4]=s,this._$matrix[6]=r,this._$matrix[7]=n}setMaxSize(t,e){this._$frameBufferManager.setMaxSize(t,e)}transform(t,e,i,s,r,n){const a=this._$matrix[0],h=this._$matrix[1],o=this._$matrix[3],l=this._$matrix[4],c=this._$matrix[6],_=this._$matrix[7];this._$matrix[0]=t*a+e*o,this._$matrix[1]=t*h+e*l,this._$matrix[3]=i*a+s*o,this._$matrix[4]=i*h+s*l,this._$matrix[6]=r*a+n*o+c,this._$matrix[7]=r*h+n*l+_}debug(t=0){const e=this._$frameBufferManager,i=e.textureManager.getAtlasTexture(t),s=e.currentAttachment,r=e.createTextureAttachmentFrom(i);this._$bind(r);const n=new Uint8Array(i.width*i.height*4);this._$gl.readPixels(0,0,i.width,i.height,this._$gl.RGBA,this._$gl.UNSIGNED_BYTE,n);const a=document.createElement("canvas");a.width=i.width,a.height=i.height;const h=a.getContext("2d"),o=new ImageData(i.width,i.height);for(let t=0;ts.length||e.push(s)}if(!e.length)return void ot(e);const i=this._$vao.createFill(e),s=this.fillStyle;let r,n,a,h=this._$matrix;const o=this._$grid.enabled;if(s instanceof Ii){const t=s.stops,e="linearRGB"===s.rgb;if(r=this._$gradientLUT.generateForShape(t,e),this._$frameBufferManager.textureManager.bind0(r,!0),this._$frameBufferManager.bindRenderBuffer(),n=this._$shaderList.gradientShapeShaderVariants,"linear"===s.type)a=n.getGradientShapeShader(!1,o,!1,!1,s.mode),n.setGradientShapeUniform(a.uniform,!1,0,0,0,o,h,ut(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,!1,s.points,0);else{h=this._$stack[this._$stack.length-1];const t=0!==s.focalPointRatio;a=n.getGradientShapeShader(!1,o,!0,t,s.mode),n.setGradientShapeUniform(a.uniform,!1,0,0,0,o,h,ut(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,!0,s.points,s.focalPointRatio)}}else if(s instanceof Fi){h=this._$stack[this._$stack.length-1];const t=s.colorTransform;r=s.texture,this._$frameBufferManager.textureManager.bind0(r,this._$imageSmoothingEnabled),n=this._$shaderList.shapeShaderVariants,a=n.getBitmapShapeShader(!1,s.repeat,o),t?n.setBitmapShapeUniform(a.uniform,!1,0,0,0,o,h,ut(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,r.width,r.height,t[0],t[1],t[2],this._$globalAlpha,t[4]/255,t[5]/255,t[6]/255,0):n.setBitmapShapeUniform(a.uniform,!1,0,0,0,o,h,ut(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,r.width,r.height,1,1,1,this._$globalAlpha,0,0,0,0)}else n=this._$shaderList.shapeShaderVariants,a=n.getSolidColorShapeShader(!1,this._$grid.enabled),n.setSolidColorShapeUniform(a.uniform,!1,0,0,0,o,h,this._$viewportWidth,this._$viewportHeight,this._$grid,s,this._$globalAlpha);const l=this._$shaderList.shapeShaderVariants,c=l.getMaskShapeShader(!1,o);l.setMaskShapeUniform(c.uniform,o,h[0],h[1],h[2],h[3],h[4],h[5],h[6],h[7],h[8],this._$viewportWidth,this._$viewportHeight,this._$grid),this._$gl.enable(this._$gl.STENCIL_TEST),this._$gl.stencilMask(255),this._$gl.enable(this._$gl.SAMPLE_ALPHA_TO_COVERAGE),this._$gl.stencilFunc(this._$gl.ALWAYS,0,255),this._$gl.stencilOp(this._$gl.KEEP,this._$gl.INVERT,this._$gl.INVERT),this._$gl.colorMask(!1,!1,!1,!1),c._$fill(i),this._$gl.disable(this._$gl.SAMPLE_ALPHA_TO_COVERAGE),this._$gl.stencilFunc(this._$gl.NOTEQUAL,0,255),this._$gl.stencilOp(this._$gl.KEEP,this._$gl.ZERO,this._$gl.ZERO),this._$gl.colorMask(!0,!0,!0,!0),a._$fill(i),this._$gl.disable(this._$gl.STENCIL_TEST),this.releaseFillVertexArray(i)}releaseFillVertexArray(t){this._$vao.releaseFill(t);const e=t.indexRanges;for(let t=0;tn.width||i>n.height||0>e&&0>=s+e||0>i&&0>=r+i||(this._$maskBounds.xMin=v.max(0,v.min(this._$maskBounds.xMin,e)),this._$maskBounds.yMin=v.max(0,v.min(this._$maskBounds.yMin,i)),this._$maskBounds.xMax=v.min(n.width,v.min(this._$maskBounds.xMax,s)),this._$maskBounds.yMax=v.min(n.height,v.min(this._$maskBounds.yMax,r)),0))}_$endClipDef(){this._$mask._$endClipDef()}_$leaveClip(){this.drawInstacedArray(),this._$mask._$leaveClip()}_$drawContainerClip(){this._$mask._$drawContainerClip()}closePath(){this._$path.close()}stroke(){const t=this._$path.vertices;if(!t.length)return;const e=ht();for(let i=0;is.length||e.push(s)}if(!e.length)return void ot(e);const i=this._$vao.createStroke(t,this.lineCap,this.lineJoin);let s=this._$matrix;const r=this.strokeStyle;let n=v.sign(s[0]*s[4]);n>0&&0!==s[1]&&0!==s[3]&&(n=-v.sign(s[1]*s[3]));let a,h,o=.5*this.lineWidth;this._$grid.enabled?(a=v.abs(this._$grid.ancestorMatrixA+this._$grid.ancestorMatrixD),h=v.abs(this._$grid.ancestorMatrixB+this._$grid.ancestorMatrixE)):(a=v.abs(s[0]+s[3]),h=v.abs(s[1]+s[4]));const l=v.min(a,h),c=v.max(a,h);o*=c*(1-.3*v.cos(.5*v.PI*(l/c))),o=v.max(1,o);const _=this._$grid.enabled;let $,u,d;if(r instanceof Ii){"radial"===r.type&&(s=this._$stack[this._$stack.length-1]);const t=r.stops,e="linearRGB"===r.rgb;if($=this._$gradientLUT.generateForShape(t,e),this._$frameBufferManager.textureManager.bind0($,!0),u=this._$shaderList.gradientShapeShaderVariants,"linear"===r.type)d=u.getGradientShapeShader(!0,_,!1,!1,r.mode),u.setGradientShapeUniform(d.uniform,!0,o,n,this.miterLimit,_,s,ut(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,!1,r.points,0);else{s=this._$stack[this._$stack.length-1];const t=0!==r.focalPointRatio;d=u.getGradientShapeShader(!0,_,!0,t,r.mode),u.setGradientShapeUniform(d.uniform,!0,o,n,this.miterLimit,_,s,ut(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,!0,r.points,r.focalPointRatio)}}else if(r instanceof Fi){s=this._$stack[this._$stack.length-1];const t=r.colorTransform;$=r.texture,this._$frameBufferManager.textureManager.bind0($),u=this._$shaderList.shapeShaderVariants,d=u.getBitmapShapeShader(!0,r.repeat,this._$grid.enabled),t?u.setBitmapShapeUniform(d.uniform,!0,o,n,this.miterLimit,_,s,ut(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,$.width,$.height,t[0],t[1],t[2],this._$globalAlpha,t[4]/255,t[5]/255,t[6]/255,0):u.setBitmapShapeUniform(d.uniform,!0,o,n,this.miterLimit,_,s,ut(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,$.width,$.height,1,1,1,this._$globalAlpha,0,0,0,0)}else u=this._$shaderList.shapeShaderVariants,d=u.getSolidColorShapeShader(!0,this._$grid.enabled),u.setSolidColorShapeUniform(d.uniform,!0,o,n,this.miterLimit,_,s,this._$viewportWidth,this._$viewportHeight,this._$grid,r,this._$globalAlpha);d._$stroke(i),this._$vao.releaseStroke(i)}arc(t,e,i){this._$path.drawCircle(t,e,i)}clip(){const t=this._$path.vertices;if(!t.length)return;const e=ht();for(let i=0;is.length||e.push(s)}if(!e.length)return void ot(e);const i=this._$vao.createFill(e),s=this._$shaderList.shapeShaderVariants,r=s.getMaskShapeShader(!1,!1),n=r.uniform;s.setMaskShapeUniform(n,!1,this._$matrix[0],this._$matrix[1],this._$matrix[2],this._$matrix[3],this._$matrix[4],this._$matrix[5],this._$matrix[6],this._$matrix[7],this._$matrix[8],this._$viewportWidth,this._$viewportHeight,null),this._$mask._$onClip(i,this._$matrix,this._$viewportWidth,this._$viewportHeight)||(r._$fill(i),this.beginPath())}save(){const t=this._$matrix;this._$stack.push(at(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])),this._$mask._$onSave()}restore(){var t;this._$stack.length&&(t=this._$matrix,Y.push(t),this._$matrix=this._$stack.pop()||at()),this._$mask._$onRestore()}createPattern(t,e,i){return new Fi(t,e,i)}createLinearGradient(t,e,i,s,r="rgb",n="pad"){return(new Ii).linear(t,e,i,s,r,n)}createRadialGradient(t,e,i,s,r,n,a="rgb",h="pad",o=0){return(new Ii).radial(t,e,i,s,r,n,a,h,o)}_$applyBlurFilter(t,e,i){const s=this._$frameBufferManager,r=s.currentAttachment;if(!r)throw new Error("the current attachment is null.");const n=r.width,a=r.height;s.textureManager.bind0(t,!0);const h=v.ceil(.5*i),o=1-(h-.5*i),l=1+i,c=this._$shaderList.filterShaderVariants,_=c.getBlurFilterShader(h);c.setBlurFilterUniform(_.uniform,n,a,e,o,l),_._$drawImage()}_$applyBitmapFilter(t,e,i,s,r,n,a,h,o,l,c,_,$,u,d,g=null,f=null,p=null,m=0,x=0,b=0,v=0,T=0,y=0,E=0,A=0){const M=this._$frameBufferManager,S="inner"===$,w=M.currentAttachment,C=M.getTextureFromCurrentAttachment();let I=null;const F=null!==g&&null!==f&&null!==p;let R;null!==g&&null!==f&&null!==p&&(I=this._$gradientLUT.generateForFilter(g,f,p)),S?F&&I?M.textureManager.bind02(t,I,!0):M.textureManager.bind0(t):(R=this._$frameBufferManager.createTextureAttachment(e,i),this._$bind(R),F&&I?M.textureManager.bind012(t,C,I,!0):M.textureManager.bind01(t,C));const B=!(S||"full"===$&&u),L=!(e===h&&i===o&&0===l&&0===c),P=!(1===d),k=this._$shaderList.filterShaderVariants,N=k.getBitmapFilterShader(B,L,_,$,u,P,F);k.setBitmapFilterUniform(N.uniform,e,i,s,r,n,a,h,o,l,c,_,d,m,x,b,v,T,y,E,A,B,L,P,F),S?u?this._$blend.toSourceIn():this._$blend.toSourceAtop():this._$blend.toOneZero(),N._$drawImage(),S||M.releaseAttachment(w,!0)}_$applyColorMatrixFilter(t,e){this._$frameBufferManager.textureManager.bind0(t,!0);const i=this._$shaderList.filterShaderVariants,s=i.getColorMatrixFilterShader();i.setColorMatrixFilterUniform(s.uniform,e),this._$blend.reset(),s._$drawImage()}_$applyConvolutionFilter(t,e,i,s,r,n,a,h,o,l,c,_){const $=t.width,u=t.height,d=this._$frameBufferManager.createTextureAttachment($,u);this._$bind(d),this._$frameBufferManager.textureManager.bind0(t,!0);const g=this._$shaderList.filterShaderVariants,f=g.getConvolutionFilterShader(e,i,a,h);g.setConvolutionFilterUniform(f.uniform,$,u,s,r,n,h,o,l,c,_),this._$blend.reset(),f._$drawImage()}_$applyDisplacementMapFilter(t,e,i,s,r,n,a,h,o,l,c,_,$,u){const d=t.width,g=t.height,f=this._$frameBufferManager.createTextureAttachment(d,g);this._$bind(f),r||(r={x:0,y:0});const p=this._$frameBufferManager.createTextureFromImage(e);this._$frameBufferManager.textureManager.bind01(t,p);const m=this._$shaderList.filterShaderVariants,x=m.getDisplacementMapFilterShader(n,a,l);m.setDisplacementMapFilterUniform(x.uniform,e.width,e.height,i,s,r.x,r.y,h,o,l,c,_,$,u),this._$blend.reset(),x._$drawImage(),this._$frameBufferManager.releaseTexture(p)}_$startLayer(t){this._$positions.push(t),this._$blends.push(this._$isLayer),this._$isLayer=!0}_$endLayer(){const t=this._$positions.pop();t&&J(t),this._$isLayer=!!this._$blends.pop()}_$saveAttachment(t,e,i=!1){this.drawInstacedArray();const s=this._$frameBufferManager;this._$attachmentArray.push(s.currentAttachment),this._$bind(s.createCacheAttachment(t,e,i))}_$restoreAttachment(t=!1){const e=this._$frameBufferManager;e.releaseAttachment(e.currentAttachment,t),this._$bind(this._$attachmentArray.pop())}getCurrentPosition(){return this._$positions[this._$positions.length-1]}textureScale(t,e){const i=v.max(t,e);return i>this._$maxTextureSize?this._$maxTextureSize/i:1}}class ms{constructor(){var t;t=window.devicePixelRatio,f=t,this._$stage=new fe,this._$stage._$player=this,this._$mode="loader",this._$actionOffset=0,this._$actions=ht(),this._$loaders=ht(),this._$sounds=ct(),this._$hitObject={x:0,y:0,pointer:"",hit:null},this._$rollOverObject=null,this._$mouseOverTarget=null,this._$ratio=f,this._$stopFlag=!0,this._$startTime=0,this._$fps=16,this._$loadStatus=0,this._$width=0,this._$height=0,this._$baseWidth=0,this._$baseHeight=0,this._$scale=1,this._$matrix=it(1,0,0,1,0,0),this._$tx=0,this._$ty=0,this._$state="up",this._$hitTestStart=!1,this._$stageX=-1,this._$stageY=-1,this._$deltaX=0,this._$deltaY=0,this._$broadcastEvents=ct(),this._$optionWidth=0,this._$optionHeight=0,this._$tagId="",this._$bgColor="transparent",this._$base="",this._$fullScreen=!1,this._$quality="high",this._$sources=ht(),this._$videos=ht(),this._$textField=null,this._$timerId=-1,this._$loadId=-1,this._$context=null,this._$attachment=null,this._$clickTarget=null,this._$actionProcess=!1,this._$canvas=d.createElement("canvas")}static get LOAD_START(){return 1}static get LOAD_END(){return 2}get cacheStore(){return St}get canvas(){return this._$canvas}get broadcastEvents(){return this._$broadcastEvents}get context(){return this._$context}set context(t){this._$context=t}get base(){return this._$base}set base(t){if(-1===t.indexOf("//")){const e=t.split("/");""!==e[0]&&"."!==e[0]||e.shift(),e.pop(),this._$base=`${location.origin}/`,e.length&&(this._$base+=`${e.join("/")}/`)}else if(-1===t.indexOf("?"))this._$base="/"===t.slice(-1)?t:`${t}/`;else{const e=t.split("?")[0];this._$base="/"===e.slice(-1)?e:`${e}/`}}get stage(){return this._$stage}get x(){return this._$tx}get y(){return this._$ty}get scaleX(){return this._$matrix[0]}get scaleY(){return this._$matrix[3]}get tx(){return this._$matrix[4]/this._$scale/f}get ty(){return this._$matrix[5]/this._$scale/f}get mode(){return this._$mode}set mode(t){this._$mode=t}get contentElementId(){return Ss}get width(){return this._$baseWidth}set width(t){this._$baseWidth=0|t}get height(){return this._$baseHeight}set height(t){this._$baseHeight=0|t}get bgColor(){return this._$bgColor}set bgColor(t){this._$bgColor=`${t}`}play(){if(this._$stopFlag){this._$stopFlag=!1,this._$timerId>-1&&F(this._$timerId),this._$startTime=R.now();const t=this._$stage._$frameRate;this._$fps=1e3/t|0,this._$timerId=I((t=>{this._$run(t)}))}}stop(){this._$timerId>-1&&F(this._$timerId),this._$stopFlag=!0,this._$timerId=-1,oe.stopAll(),St.reset(),Mr&&Mr.postMessage({command:"stop"})}removeCache(t){St.removeCache(t),Mr&&Mr.postMessage({command:"removeCache",id:t})}setOptions(t=null){t&&(this._$optionWidth=t.width||this._$optionWidth,this._$optionHeight=t.height||this._$optionHeight,this._$tagId=t.tagId||this._$tagId,this.base=t.base||this._$base,this._$bgColor=t.bgColor||this._$bgColor,this._$fullScreen=!!t.fullScreen)}_$loadWebAudio(t=null){t&&this._$canvas.removeEventListener(Bs,this._$loadWebAudio),Ns||mr()}_$updateLoadStatus(){if(this._$loadStatus===ms.LOAD_END)return this._$loadId>-1&&F(this._$loadId),this._$loadId=-1,void this._$loaded();this._$loadId=I((()=>{this._$updateLoadStatus()}))}_$loaded(){const t=d.getElementById(this.contentElementId);if(t){this._$setBackgroundColor(this._$bgColor),this._$deleteNode(),t.appendChild(this._$canvas),t.appendChild(tr),this._$stage._$prepareActions(),this._$broadcastEvents.has(It.FRAME_CONSTRUCTED)&&this._$dispatchEvent(new It(It.FRAME_CONSTRUCTED)),this._$doAction(),this._$broadcastEvents.has(It.EXIT_FRAME)&&this._$dispatchEvent(new It(It.EXIT_FRAME));const e=this._$loaders.length;for(let t=0;t`);const e=d.getElementById(t);if(!e)throw new Error("the content element is null.");const i=e.parentElement;if(i){this._$initStyle(e),this._$buildWait();const t=this._$optionWidth?this._$optionWidth:"BODY"===i.tagName?u.innerWidth:i.offsetWidth,s=this._$optionHeight?this._$optionHeight:"BODY"===i.tagName?u.innerHeight:i.offsetHeight;"loader"===this._$mode&&t&&s&&(this._$baseWidth=t,this._$baseHeight=s,this._$resize())}"loader"===this._$mode?(this._$loadStatus=ms.LOAD_START,this._$updateLoadStatus()):(this._$resize(),this._$loaded())}_$initStyle(t){const e=t.style;e.position="relative",e.top="0",e.left="0",e.backgroundColor="transparent",e.overflow="hidden",e.padding="0",e.margin="0",e.userSelect="none",e.outline="none";const i=this._$optionWidth,s=this._$optionHeight,r=t.parentElement;if(!r)throw new Error("the parentElement is null.");if("BODY"===r.tagName)return e.width=i?`${i}px`:`${window.innerWidth}px`,void(e.height=s?`${s}px`:`${window.innerHeight}px`);e.width=i?`${i}px`:`${r.offsetWidth}px`,e.height=s?`${s}px`:`${r.offsetHeight}px`}_$buildWait(){const t=d.getElementById(this.contentElementId);if(t){const e=`${this.contentElementId}_loading`;t.innerHTML=``;const i=d.createElement("div");i.id=e,t.appendChild(i)}}_$deleteNode(){const t=d.getElementById(this.contentElementId);if(t)for(;t.childNodes.length;)t.removeChild(t.childNodes[0])}_$initializeCanvas(){if(this._$canvas.width=1,this._$canvas.height=1,Mr){const t=this._$canvas.transferControlToOffscreen(),e=hr();let i=0;e[i++]=this._$stage._$instanceId,e[i++]=+Ws,e[i++]=f,e[i++]=this._$getSamples();const s=ht(t,e.buffer);Mr.postMessage({command:"initialize",canvas:t,buffer:e},s),ot(s)}else{const t=this._$canvas.getContext("webgl2",{stencil:!0,premultipliedAlpha:!0,antialias:!1,depth:!1,preserveDrawingBuffer:!0});t?(this._$context=new ps(t,this._$getSamples()),St.context=this._$context):alert("WebGL setting is off. Please turn the setting on.")}const t=()=>{if(this._$canvas.removeEventListener(Bs,t),this._$canvas.removeEventListener(Is,t),!Ns){mr();for(let t=0;t{c(t),h(ws),this._$hitTest()})),this._$canvas.addEventListener(Cs,(t=>{c(t),h(Cs),this._$hitTest()})),this._$canvas.addEventListener(Is,(t=>{c(t),h(Is),this._$hitTest()})),this._$canvas.addEventListener(Cs,(t=>{c(t),h(Cs),this._$hitTest()}),{passive:!1}),this._$canvas.addEventListener(Fs,(t=>{c(t),h(Fs),t.button||this._$hitTest()})),this._$canvas.addEventListener(Ps,(t=>{c(t),h(Ps),t.button||this._$hitTest()})),this._$canvas.addEventListener(ks,(t=>{c(t),h(ks),this._$hitTest(),c(null),this._$stageX=-1,this._$stageY=-1})),this._$canvas.addEventListener(Bs,(t=>{c(t),h(Bs),t.button||this._$hitTest()})),this._$canvas.addEventListener(Rs,(t=>{c(t),h(Rs),this._$hitTest()})),this._$canvas.addEventListener(Ls,(t=>{t.defaultPrevented||(c(t),h(Ls),this._$hitTest())}),{passive:!1});let e="";e+="position: absolute;",e+="top: 0;",e+="left: 0;",e+="-webkit-tap-highlight-color: rgba(0,0,0,0);",e+="backface-visibility: hidden;",e+="transform-origin: 0 0;",1!==f&&(e+=`transform: scale(${1/f});`),this._$canvas.setAttribute("style",e)}_$resize(){const t=d.getElementById(this.contentElementId);if(t){const e=t.parentElement;if(!e)throw new Error("the parentElement is null.");const i=this._$optionWidth?this._$optionWidth:"BODY"===e.tagName?u.innerWidth:e.offsetWidth?e.offsetWidth:parseFloat(e.style.width),s=this._$optionHeight?this._$optionHeight:"BODY"===e.tagName?u.innerHeight:e.offsetHeight?e.offsetHeight:parseFloat(e.style.height),r="BODY"===e.tagName?u.innerWidth:e.offsetWidth,n=v.min(i/this._$baseWidth,s/this._$baseHeight);let a=this._$fullScreen?i:this._$baseWidth*n|0,h=this._$fullScreen?s:this._$baseHeight*n|0;const o=t.style;if(o.width=`${a}px`,o.height=`${h}px`,o.top="0",o.left=this._$fullScreen?"0":r/2-a/2+"px",a*=f,h*=f,this._$width===a&&this._$height===h)return;this._$stage._$doChanged(),St.reset(),this._$scale=n,this._$width=a,this._$height=h;const l=this._$scale*this._$ratio;this._$matrix[0]=l,this._$matrix[3]=l,this._$fullScreen&&(this._$tx=(a-this._$baseWidth*n*f)/2,this._$ty=(h-this._$baseHeight*n*f)/2,this._$matrix[4]=this._$tx,this._$matrix[5]=this._$ty),this._$resizeCanvas(a,h,l,this._$tx,this._$ty),this._$ratio>1&&f>1&&(this._$canvas.style.transform=`scale(${1/this._$ratio})`),t.children.length>1&&t.children[1].dispatchEvent(new Event(`${Ss}_blur`))}}_$setBackgroundColor(t="transparent"){if(Mr){const e=hr();e[0]="transparent"===t?-1:xt(t);const i=or();i.command="setBackgroundColor",i.buffer=e;const s=ht(e.buffer);Mr.postMessage(i,s),lr(i),ot(s)}else{const e=this._$context;if(!e)return;if("transparent"===t)e._$setColor(0,0,0,0);else{const i=bt(xt(t));e._$setColor(i.R/255,i.G/255,i.B/255,1)}}}_$resizeCanvas(t,e,i,s=0,r=0){if(Mr){const n=hr();let a=0;n[a++]=t,n[a++]=e,n[a++]=i,n[a++]=s,n[a++]=r;const h=or(),o=ht(n.buffer);h.command="resize",h.buffer=n,Mr.postMessage(h,o),lr(h),ot(o)}else{const i=this._$context;if(!i)return;i.clearInstacedArray(),this._$canvas.width=t,this._$canvas.height=e,i._$gl.viewport(0,0,t,e);const s=i.frameBuffer;this._$attachment&&(s.unbind(),s.releaseAttachment(this._$attachment,!0)),this._$attachment=s.createCacheAttachment(t,e,!0),i.setMaxSize(t,e),i._$bind(this._$attachment)}}_$getSamples(){switch(this._$quality){case"high":return 4;case"medium":return 2;default:return 0}}_$dispatchEvent(t){if(this._$broadcastEvents.size&&this._$broadcastEvents.has(t.type)){const e=this._$broadcastEvents.get(t.type).slice(0);t.eventPhase=Ct.AT_TARGET;for(let i=0;ithis._$fps){if(this._$startTime=t-e%this._$fps,this._$action(),this._$sounds.size){for(const t of this._$sounds.values())t._$soundPlay();this._$sounds.clear()}this._$draw(),!Zs&&!this._$hitTestStart&&"up"===this._$state&&this._$stageX>-1&&this._$stageY>-1&&l()&&this._$pointerCheck()}else this._$videos.length&&!Mr&&this._$draw();this._$timerId=I((t=>{this._$run(t)}))}_$pointerCheck(){const t=this._$stageX,e=this._$stageY;this._$hitObject.x=t,this._$hitObject.y=e,this._$hitObject.pointer="",this._$hitObject.hit=null,rr.setTransform(1,0,0,1,0,0),rr.beginPath(),zs[4]=this._$tx/this._$scale/f,zs[5]=this._$ty/this._$scale/f,this._$stage._$mouseHit(rr,zs,this._$hitObject,!0);let i=null,s=null,r=!1,n=!1;if(this._$hitObject.hit){if(i=this._$hitObject.hit,this._$mouseOverTarget&&this._$mouseOverTarget!==i){const t=this._$mouseOverTarget;t.willTrigger(Pt.MOUSE_OUT)&&t.dispatchEvent(new Pt(Pt.MOUSE_OUT,!0,!1))}if(this._$rollOverObject!==i){let r=null;if(this._$rollOverObject)for(s=this._$rollOverObject,s.willTrigger(Pt.ROLL_OUT)&&s.dispatchEvent(new Pt(Pt.ROLL_OUT,!1,!1)),r=s._$parent;r&&r._$root!==r&&r!==i;){if(r._$mouseEnabled&&r._$outCheck(t,e)){let t=!1,e=i;for(;e&&e._$root!==e;){if(e===r){t=!0;break}e=e._$parent}if(!t&&r._$parent===i._$parent&&r._$index>i._$index&&(t=!0),t)break}r.willTrigger(Pt.ROLL_OUT)&&r.dispatchEvent(new Pt(Pt.ROLL_OUT,!1,!1)),r=r._$parent}for(s=i;s.willTrigger(Pt.ROLL_OVER)&&s.dispatchEvent(new Pt(Pt.ROLL_OVER,!1,!1)),s=s._$parent,s&&s!==r&&s.stage!==s;);}switch(this._$rollOverObject=i,!0){case null===this._$mouseOverTarget:case this._$mouseOverTarget!==i:i&&i.willTrigger(Pt.MOUSE_OVER)&&i.dispatchEvent(new Pt(Pt.MOUSE_OVER,!0,!1)),this._$mouseOverTarget=i}if("up"===this._$state&&(this._$clickTarget=null),!Zs&&"up"===this._$state)for(s=i;s&&s.root!==s;){if("_$text"in s&&"input"===s.type){r=!0;break}if("buttonMode"in s&&s.buttonMode){n=!0;break}s=s._$parent}}else{if(this._$mouseOverTarget&&(i=this._$mouseOverTarget,i.willTrigger(Pt.MOUSE_OUT)&&i.dispatchEvent(new Pt(Pt.MOUSE_OUT,!0,!1))),this._$rollOverObject)for(s=this._$rollOverObject;s&&s.root!==s;)s.willTrigger(Pt.ROLL_OUT)&&s.dispatchEvent(new Pt(Pt.ROLL_OUT,!1,!1)),s=s._$parent;this._$rollOverObject=null,this._$mouseOverTarget=null}switch(!0){case r:this._$canvas.style.cursor="text";break;case n:this._$canvas.style.cursor="pointer";break;case!Zs&&"up"===this._$state:this._$canvas.style.cursor="auto"}this._$actions.length>1&&this._$doAction()}_$action(){if(this._$stopFlag)return;let t=null;const e=this._$loaders.length;if(e){t=this._$loaders.slice(0),this._$loaders.length=0;for(let i=0;ie._$index&&(i=!0),i)break}t.willTrigger(Pt.ROLL_OUT)&&t.dispatchEvent(new Pt(Pt.ROLL_OUT,!1,!1)),t=t._$parent}for(i=e;i.willTrigger(Pt.ROLL_OVER)&&i.dispatchEvent(new Pt(Pt.ROLL_OVER,!1,!1)),i=i._$parent,i&&i!==t&&i.stage!==i;);}switch(this._$rollOverObject=e,!0){case null===this._$mouseOverTarget:case this._$mouseOverTarget!==e:e.willTrigger(Pt.MOUSE_OVER)&&e.dispatchEvent(new Pt(Pt.MOUSE_OVER,!0,!1)),this._$mouseOverTarget=e}"up"===this._$state?this._$clickTarget=null:this._$textField&&this._$textField._$setIndex(c-zs[4],_-zs[5]);break;case ws:case Fs:this._$textField&&e!==this._$textField&&(this._$textField.focus=!1,this._$textField=null),"_$text"in e&&(e.focus=!0,e._$setIndex(c-zs[4],_-zs[5]),this._$textField=e,tr.style.left=`${h}px`,tr.style.top=`${o}px`),e.willTrigger(Pt.MOUSE_DOWN)&&e.dispatchEvent(new Pt(Pt.MOUSE_DOWN,!0,!1)),this._$clickTarget=e;break;case Is:case Bs:e.willTrigger(Pt.MOUSE_UP)&&e.dispatchEvent(new Pt(Pt.MOUSE_UP,!0,!1)),this._$clickTarget===e&&e.willTrigger(Pt.CLICK)&&e.dispatchEvent(new Pt(Pt.CLICK,!0,!1)),this._$clickTarget=null;break;case Ls:e.willTrigger(Pt.MOUSE_WHEEL)&&e.dispatchEvent(new Pt(Pt.MOUSE_WHEEL)),e.scrollEnabled&&("deltaX"in t&&(e.scrollX+=t.deltaX/(e.textWidth/e.width)),"deltaY"in t&&(e.scrollY+=t.deltaY/(e.textHeight/e.height)));break;case Ps:e.willTrigger(Pt.DOUBLE_CLICK)&&e.dispatchEvent(new Pt(Pt.DOUBLE_CLICK))}if(!g&&!Zs&&"up"===this._$state)for(i=e;i&&i.root!==i;){if("_$text"in i){if("input"===i.type){$=!0;break}}else if(i._$buttonMode){p=!0;break}i=i._$parent}}switch(!0){case $:this._$canvas.style.cursor="text";break;case p:this._$canvas.style.cursor="pointer";break;case!Zs&&"up"===this._$state:this._$canvas.style.cursor="auto"}!this._$actionProcess&&this._$actions.length>1&&this._$doAction(),m&&(this._$stage._$prepareActions(),this._$actionProcess||this._$doAction()),this._$hitTestStart=!1}}const xs={Event:It,EventDispatcher:Ft,EventPhase:Ct,FocusEvent:Rt,HTTPStatusEvent:Bt,IOErrorEvent:Lt,MouseEvent:Pt,ProgressEvent:kt,VideoEvent:Nt};Object.entries(xs).forEach((([t,e])=>{Object.defineProperty(xs,t,{get:()=>e})}));const bs={DisplayObject:Zt,InteractiveObject:te,DisplayObjectContainer:ee,Sprite:$e,MovieClip:ue,BitmapData:ie,BlendMode:class{static toString(){return"[class BlendMode]"}static get namespace(){return"next2d.display.BlendMode"}toString(){return"[object BlendMode]"}get namespace(){return"next2d.display.BlendMode"}static get ADD(){return"add"}static get ALPHA(){return"alpha"}static get DARKEN(){return"darken"}static get DIFFERENCE(){return"difference"}static get ERASE(){return"erase"}static get HARDLIGHT(){return"hardlight"}static get INVERT(){return"invert"}static get LAYER(){return"layer"}static get LIGHTEN(){return"lighten"}static get MULTIPLY(){return"multiply"}static get NORMAL(){return"normal"}static get OVERLAY(){return"overlay"}static get SCREEN(){return"screen"}static get SUBTRACT(){return"subtract"}},FrameLabel:se,Graphics:ae,Loader:de,LoaderInfo:he,Shape:ge,Stage:fe,TextField:Ci};Object.entries(bs).forEach((([t,e])=>{Object.defineProperty(bs,t,{get:()=>e})}));const vs={BevelFilter:Xt,BlurFilter:zt,ColorMatrixFilter:qt,ConvolutionFilter:Yt,DisplacementMapFilter:Ht,DropShadowFilter:jt,GlowFilter:Wt,GradientBevelFilter:Kt,GradientGlowFilter:Qt};Object.entries(vs).forEach((([t,e])=>{Object.defineProperty(vs,t,{get:()=>e})}));const Ts={ColorTransform:Ot,Matrix:Ut,Point:Dt,Rectangle:Vt,Transform:Jt};Object.entries(Ts).forEach((([t,e])=>{Object.defineProperty(Ts,t,{get:()=>e})}));const ys={Sound:le,SoundMixer:oe,SoundTransform:ce,Video:_e};Object.entries(ys).forEach((([t,e])=>{Object.defineProperty(ys,t,{get:()=>e})}));const Es={URLRequest:wt,URLRequestHeader:g};Object.entries(Es).forEach((([t,e])=>{Object.defineProperty(Es,t,{get:()=>e})}));const As={TextFormat:be};Object.entries(As).forEach((([t,e])=>{Object.defineProperty(As,t,{get:()=>e})}));const Ms={Easing:pe,Job:me,Tween:xe};Object.entries(Ms).forEach((([t,e])=>{Object.defineProperty(Ms,t,{get:()=>e})}));const Ss="__next2d__",ws="touchstart",Cs="touchmove",Is="touchend",Fs="mousedown",Rs="mousemove",Bs="mouseup",Ls="wheel",Ps="dblclick",ks="mouseleave";let Ns=null;const Os=new Map;let Ds=null;const Us=t=>{Ds=t},Vs={lock:!1,position:{x:0,y:0},bounds:null},Gs=new Float32Array(256);new Float32Array(256);for(let t=0;t<256;++t)Gs[t]=v.pow(t/255,2.23333333),Gs[t]=t/255;const zs=new Float32Array([1,0,0,1,0,0]),Xs=[],qs=[],Ys=[],Hs=new Map;let js=!1,Ws=!1,Ks=!1,Qs=!1,Js=!1,Zs=!1;const tr=d.createElement("textarea");let er="";er+="position: fixed;",er+="top: 0;",er+="left: 0;",er+="font-size: 16px;",er+="border: 0;",er+="resize: none;",er+="opacity: 0;",er+="z-index: -1;",er+="pointer-events: none;",tr.setAttribute("style","position: fixed;top: 0;left: 0;font-size: 16px;border: 0;resize: none;opacity: 0;z-index: -1;pointer-events: none;"),tr.tabIndex=-1,tr.addEventListener("compositionstart",(()=>{const t=u.next2d.player._$textField;t&&t.compositionStart()})),tr.addEventListener("compositionupdate",(t=>{const e=u.next2d.player._$textField;e&&e.compositionUpdate(t.data)})),tr.addEventListener("compositionend",(()=>{const t=u.next2d.player._$textField;t&&t.compositionEnd()})),tr.addEventListener("input",(t=>{if(!t.data)return;const e=u.next2d.player._$textField;e&&e.insertText(t.data)})),tr.addEventListener("keydown",(t=>{const e=u.next2d.player._$textField;if(e)switch(t.key){case"Backspace":case"Delete":e.deleteText();break;case"Enter":e.insertText("\n");break;case"ArrowLeft":e.arrowLeft();break;case"ArrowRight":e.arrowRight();break;case"ArrowUp":e.arrowUp();break;case"ArrowDown":e.arrowDown();break;case"a":(t.metaKey||t.ctrlKey)&&(t.preventDefault(),e.selectAll());break;case"v":(t.metaKey||t.ctrlKey)&&(t.preventDefault(),e.paste());break;case"c":(t.metaKey||t.ctrlKey)&&(t.preventDefault(),e.copy())}}));const ir=d.createElement("canvas");ir.width=1,ir.height=1;const sr=ir.getContext("2d");if(!sr)throw new Error("the CanvasRenderingContext2D is null.");sr.globalAlpha=0,sr.imageSmoothingEnabled=!1;const rr=sr,nr=[],ar=[],hr=()=>nr.length?nr.pop():new Float32Array(64),or=()=>ar.length?ar.pop():{command:""},lr=t=>{t.buffer=null,ar.push(t),console.log("renderMessageArray: ",ar)},cr=()=>u.next2d.player,_r=()=>{const t=l();if(!t)return new Dt;const e=cr();let i=u.scrollX,s=u.scrollY;const r=d.getElementById(e.contentElementId);if(r){const t=r.getBoundingClientRect();i+=t.left,s+=t.top}let n=0,a=0;if("changedTouches"in t){const e=t.changedTouches[0];n=e.pageX,a=e.pageY}else"pageX"in t&&(n=t.pageX,a=t.pageY);const h=(n-i)/e._$scale-e.x/e._$scale/f,o=(a-s)/e._$scale-e.y/e._$scale/f;return new Dt(h,o)},$r=(t=1,e=0,i=0,s=1,r=0,n=0)=>{const a=qs.pop();return a?(a.setTo(t,e,i,s,r,n),a):new Ut(t,e,i,s,r,n)},ur=t=>{qs.push(t)},dr=(t=1,e=1,i=1,s=1,r=0,n=0,a=0,h=0)=>{const o=Ys.length?Ys.pop():null;return o?(o.redMultiplier=t,o.greenMultiplier=e,o.blueMultiplier=i,o.alphaMultiplier=s,o.redOffset=r,o.greenOffset=n,o.blueOffset=a,o.alphaOffset=h,o):new Ot(t,e,i,s,r,n,a,h)},gr=t=>{Ys.push(t)},fr=(t,e)=>{t._$character?t._$character.audioBuffer=e:t._$audioBuffer=e},pr=t=>{if(!Ns)throw new Error("the AudioContext is null.");let e=null;if(t._$character){const i=t._$character.buffer;i&&(e=new Uint8Array(i).buffer,ot(i),t._$character.buffer=null)}else e=t._$arrayBuffer;return e?Ns.decodeAudioData(e).then((e=>(fr(t,e),Promise.resolve(t)))).catch((()=>{if(!e)throw new Error;return((t,e)=>{if(!Ns)throw new Error("the Audio Context is null.");const i=new Uint8Array(e);let s=0;for(;s=i.indexOf(255,s),-1!==s&&224&~i[s+1];)++s;if(s>-1)return Ns.decodeAudioData(i.subarray(s).buffer).then((e=>(fr(t,e),Promise.resolve(t)))).catch((()=>{throw new Error("This voice data is not available.")}));throw new Error("This voice data is not available.")})(t,e)})):Promise.resolve(t)},mr=()=>{if(Ns||(Ns=new AudioContext,Ns.resume()),Ns){const t=ht();for(let e=0;e{Xs.length=0,cr()._$loaders.push(...t)}))}};let xr=-1;const br=()=>{const t=cr();if(t._$loadStatus===ms.LOAD_END){t._$resize();const e=t.stage;e.willTrigger(It.RESIZE)&&e.dispatchEvent(new It(It.RESIZE))}};u.addEventListener("resize",(()=>{L(xr),xr=B(br,300)}));const vr=t=>{let e=null;switch(t.method.toUpperCase()){case"GET":if(t.data){const e=t.url.split("?");e[1]=1===e.length?t.data.toString():`${e[1]}&${t.data.toString()}`,t.url=e.join("?")}break;case"PUT":case"POST":t.data&&(e=t.data.toString())}const i=new XMLHttpRequest;if(i.open(t.method,t.url,!0),i.responseType=t.format,i.withCredentials=t.withCredentials,t.event){const e=Object.keys(t.event);for(let s=0;s{const e=ht();if(t){const i=t.trim().split("\n"),s=i.length;for(let t=0;tyr.has(t)&&yr.get(t)||1,Ar=t=>{switch(t){case ue.namespace:return new ue;case ge.namespace:return new ge;case Ci.namespace:return new Ci;case $e.namespace:return new $e;case _e.namespace:return new _e}};let Mr=null,Sr=null,wr=null;const Cr=URL.createObjectURL(new Blob(['(()=>{"use strict";var r=Uint8Array,n=Uint16Array,e=Int32Array,a=new r([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),t=new r([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),i=new r([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),o=function(r,a){for(var t=new n(31),i=0;i<31;++i)t[i]=a+=1<>1|(21845&s)<<1;w=(61680&(w=(52428&w)>>2|(13107&w)<<2))>>4|(3855&w)<<4,d[s]=((65280&w)>>8|(255&w)<<8)>>1}var h=function(r,e,a){for(var t=r.length,i=0,o=new n(e);i>v]=c}else for(f=new n(t),i=0;i>15-r[i]);return f},y=new r(288);for(s=0;s<144;++s)y[s]=8;for(s=144;s<256;++s)y[s]=9;for(s=256;s<280;++s)y[s]=7;for(s=280;s<288;++s)y[s]=8;var b=new r(32);for(s=0;s<32;++s)b[s]=5;var g=h(y,9,1),p=h(b,5,1),m=function(r){for(var n=r[0],e=1;en&&(n=r[e]);return n},k=function(r,n,e){var a=n/8|0;return(r[a]|r[a+1]<<8)>>(7&n)&e},x=function(r,n){var e=n/8|0;return(r[e]|r[e+1]<<8|r[e+2]<<16)>>(7&n)},T=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],z=function(r,n,e){var a=new Error(n||T[r]);if(a.code=r,Error.captureStackTrace&&Error.captureStackTrace(a,z),!e)throw a;return a},E=function(n,e,o,f){var v=n.length,c=f?f.length:0;if(!v||e.f&&!e.l)return o||new r(0);var d=!o,s=d||2!=e.i,w=e.i;d&&(o=new r(3*v));var y,b=function(n){var e=o.length;if(n>e){var a=new r(Math.max(2*e,n));a.set(o),o=a}},T=e.f||0,E=e.p||0,M=e.b||0,S=e.l,U=e.d,A=e.m,C=e.n,q=8*v;do{if(!S){T=k(n,E,1);var D=k(n,E+1,3);if(E+=3,!D){var F=n[(y=E,(H=4+((y+7)/8|0))-4)]|n[H-3]<<8,I=H+F;if(I>v){w&&z(0);break}s&&b(M+F),o.set(n.subarray(H,I),M),e.b=M+=F,e.p=E=8*I,e.f=T;continue}if(1==D)S=g,U=p,A=9,C=5;else if(2==D){var O=k(n,E,31)+257,J=k(n,E+10,15)+4,L=O+k(n,E+5,31)+1;E+=14;for(var N=new r(L),P=new r(19),R=0;R>4)<16)N[R++]=H;else{var Q=0,V=0;for(16==H?(V=3+k(n,E,3),E+=2,Q=N[R-1]):17==H?(V=3+k(n,E,7),E+=3):18==H&&(V=11+k(n,E,127),E+=7);V--;)N[R++]=Q}}var W=N.subarray(0,O),X=N.subarray(O);A=m(W),C=m(X),S=h(W,A,1),U=h(X,C,1)}else z(1);if(E>q){w&&z(0);break}}s&&b(M+131072);for(var Y=(1<>4;if((E+=15&Q)>q){w&&z(0);break}if(Q||z(2),_<256)o[M++]=_;else{if(256==_){$=E,S=null;break}var rr=_-254;if(_>264){var nr=a[R=_-257];rr=k(n,E,(1<>4;if(er||z(3),E+=15&er,X=l[ar],ar>3&&(nr=t[ar],X+=x(n,E)&(1<q){w&&z(0);break}s&&b(M+131072);var tr=M+rr;if(Mn.length)&&(a=n.length),new r(n.subarray(e,a))}(o,0,M):o.subarray(0,M)},M=new r(0);function S(n,e){var a,t,i=function(r){31==r[0]&&139==r[1]&&8==r[2]||z(6,"invalid gzip data");var n=r[3],e=10;4&n&&(e+=2+(r[10]|r[11]<<8));for(var a=(n>>3&1)+(n>>4&1);a>0;a-=!r[e++]);return e+(2&n)}(n);return i+8>n.length&&z(6,"invalid gzip data"),E(n.subarray(i,-8),{i:2},e&&e.out||new r((t=(a=n).length,(a[t-4]|a[t-3]<<8|a[t-2]<<16|a[t-1]<<24)>>>0)),e&&e.dictionary)}function U(r,n){return E(r.subarray((e=r,a=n&&n.dictionary,(8!=(15&e[0])||e[0]>>4>7||(e[0]<<8|e[1])%31)&&z(6,"invalid zlib data"),(e[1]>>5&1)==+!a&&z(6,"invalid zlib data: "+(32&e[1]?"need":"unexpected")+" dictionary"),2+(e[1]>>3&4)),-4),{i:2},n&&n.out,n&&n.dictionary);var e,a}var A="undefined"!=typeof TextDecoder&&new TextDecoder;try{A.decode(M,{stream:!0})}catch(r){}"function"==typeof queueMicrotask?queueMicrotask:"function"==typeof setTimeout&&setTimeout;self.addEventListener("message",(r=>{return n=void 0,e=void 0,t=function*(){const n=31==(e=r.data)[0]&&139==e[1]&&8==e[2]?S(e,a):8!=(15&e[0])||e[0]>>4>7||(e[0]<<8|e[1])%31?function(r,n){return E(r,{i:2},n&&n.out,n&&n.dictionary)}(e,a):U(e,a);var e,a;let t="";for(let r=0;r(Fr||(Fr=new Worker(Cr)),Fr);let Br=!1;const Lr=t=>{Br=t},Pr=()=>Br,kr=()=>{if("OffscreenCanvas"in window){const t=new OffscreenCanvas(0,0).getContext("webgl2");Mr=null!==t?new Worker(URL.createObjectURL(new Blob(['(()=>{"use strict";let t=1,e=0,i=!1;const s=1/0,r=Math,n=Array,a=Map,h=Number,o=Float32Array,_=Int32Array,l=Int16Array,c=OffscreenCanvas,$=isNaN,u=requestAnimationFrame,d=setTimeout,g=clearTimeout,f=new o([1,0,0,1,0,0]),m=new o([1,1,1,1,0,0,0,0]),p=r.PI/180,x=(r.PI,[]),b=[],v=[],T=[],A=[],M=[],y=[],E=[],C=[],S=new c(1,1).getContext("2d"),F=(t=0,e=0,i=0,s=0)=>{const r=C.pop()||{xMin:0,xMax:0,yMin:0,yMax:0};return r.xMin=t,r.xMax=e,r.yMin=i,r.yMax=s,r},B=t=>{C.push(t)},w=(t=0,e=0,i=0,s=0)=>{const r=v.pop()||new o(4);return r[0]=t,r[1]=e,r[2]=i,r[3]=s,r},R=t=>{v.push(t)},I=(t=0,e=0,i=0,s=0)=>{const r=b.pop()||new _(4);return r[0]=t,r[1]=e,r[2]=i,r[3]=s,r},P=(t=0,e=0,i=0,s=0,r=0,n=0)=>{const a=T.pop()||new o(6);return a[0]=t,a[1]=e,a[2]=i,a[3]=s,a[4]=r,a[5]=n,a},N=t=>{T.push(t)},k=(t=1,e=1,i=1,s=1,r=0,n=0,a=0,h=0)=>{const _=A.pop()||new o(8);return _[0]=t,_[1]=e,_[2]=i,_[3]=s,_[4]=r,_[5]=n,_[6]=a,_[7]=h,_},L=t=>{A.push(t)},O=(t=0,e=0,i=0,s=0,r=0,n=0,a=0,h=0,_=0)=>{const l=M.pop()||new o(9);return l[0]=t,l[1]=e,l[2]=i,l[3]=s,l[4]=r,l[5]=n,l[6]=a,l[7]=h,l[8]=_,l},U=(...t)=>{const e=y.pop()||[];return t.length&&e.push(...t),e},D=(t=null)=>{t&&(t.length&&(t.length=0),y.push(t))},X=t=>{t.size&&t.clear(),E.push(t)},V=()=>E.pop()||new a,Y=t=>(t--,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t),z=t=>{const e=1/(t[0]*t[4]-t[3]*t[1]),i=t[3]*t[7]-t[4]*t[6],s=t[1]*t[6]-t[0]*t[7];return O(t[4]*e,0-t[1]*e,0,0-t[3]*e,t[0]*e,0,i*e,s*e,1)},G=(t,e,i,s=null)=>{const n=+t;return $(n)&&null!==s?s:r.min(r.max(e,$(n)?0:n),i)},H=(t,e)=>P(t[0]*e[0]+t[2]*e[1],t[1]*e[0]+t[3]*e[1],t[0]*e[2]+t[2]*e[3],t[1]*e[2]+t[3]*e[3],t[0]*e[4]+t[2]*e[5]+t[4],t[1]*e[4]+t[3]*e[5]+t[5]),W=(t,e)=>k(t[0]*e[0],t[1]*e[1],t[2]*e[2],t[3]*e[3],t[0]*e[4]+t[4],t[1]*e[5]+t[5],t[2]*e[6]+t[6],t[3]*e[7]+t[7]),q=(t,e)=>{const i=t.xMax*e[0]+t.yMax*e[2]+e[4],s=t.xMax*e[0]+t.yMin*e[2]+e[4],n=t.xMin*e[0]+t.yMax*e[2]+e[4],a=t.xMin*e[0]+t.yMin*e[2]+e[4],o=t.xMax*e[1]+t.yMax*e[3]+e[5],_=t.xMax*e[1]+t.yMin*e[3]+e[5],l=t.xMin*e[1]+t.yMax*e[3]+e[5],c=t.xMin*e[1]+t.yMin*e[3]+e[5],$=r.min(h.MAX_VALUE,i,s,n,a),u=r.max(0-h.MAX_VALUE,i,s,n,a),d=r.min(h.MAX_VALUE,o,_,l,c),g=r.max(0-h.MAX_VALUE,o,_,l,c);return F($,u,d,g)},j=t=>$(+t)?(t=>{if(!S)return 0;S.fillStyle=t;const e=+`0x${S.fillStyle.slice(1)}`;return S.fillStyle="rgba(0, 0, 0, 1)",e})(`${t}`):+t,K=(t,e,i)=>(t>>16)*(i?e:1)/255,Q=(t,e,i)=>(t>>8&255)*(i?e:1)/255,J=(t,e,i)=>(255&t)*(i?e:1)/255,Z=(t,e=1)=>({R:(16711680&t)>>16,G:(65280&t)>>8,B:255&t,A:255*e}),tt=(t,e,i=!1,s=!1)=>{let r="";return i&&(r="italic "),s&&(r+="bold "),`${r}${e}px \'${t}\',\'sans-serif\'`},et=t=>{t.color&&L(t.color),t.isLayer=!1,t.isUpdated=null,t.canApply=null,t.matrix=null,t.color=null,t.filters=null,t.blendMode="normal",t.sw=0,t.sh=0,x.push(t)},it=new Map([[1,"normal"],[2,"layer"],[3,"multiply"],[4,"screen"],[5,"lighten"],[6,"darken"],[7,"difference"],[8,"add"],[9,"subtract"],[10,"invert"],[11,"alpha"],[12,"erase"],[13,"overlay"],[14,"hardlight"]]),st=t=>it.has(t)&&it.get(t)||"normal",rt=new class{constructor(){this._$pool=[],this._$store=new Map,this._$timerMap=new Map,this._$context=null}set context(t){this._$context=t}reset(){for(const t of this._$store.values()){for(const e of t.values())this.destroy(e);X(t)}this._$store.clear(),this._$context&&this._$context.frameBuffer.clearCache()}destroy(t=null){if(t&&"object"==typeof t)if(t instanceof WebGLTexture)u((()=>{this._$context&&this._$context.frameBuffer.releaseTexture(t)}));else{if("canvas"in t&&t instanceof CanvasRenderingContext2D){const e=t.canvas,i=e.width,s=e.height;t.clearRect(0,0,i+1,s+1),e.width=e.height=1,this._$pool.push(e)}this._$context&&"index"in t&&this._$context.frameBuffer.textureManager.releasePosition(t)}}getCanvas(){return this._$pool.pop()||document.createElement("canvas")}remove(t,e){if(!this._$store.has(t))return;const i=this._$store.get(t);i.has(e)&&(i.delete(e),i.size||(X(i),this._$store.delete(t)))}stopTimer(t){t=`${t}`,this._$timerMap.has(t)&&(g(this._$timerMap.get(t)),this._$timerMap.delete(t))}removeCache(t){if(t=`${t}`,this._$store.has(t)){const e=this._$store.get(t);for(const t of e.values())this.destroy(t);e.clear(),X(e),this._$store.delete(t)}this._$timerMap.delete(t)}setRemoveTimer(t){if(t=`${t}`,this.stopTimer(t),this._$store.has(t)){const e=d((()=>{this.removeCache(t)}),5e3);this._$timerMap.set(t,e)}}get(t){const e=`${t[0]}`,i=`${t[1]}`;if(this._$store.has(e)){this.stopTimer(e);const t=this._$store.get(e);if(t.has(i))return t.get(i)}return null}set(t,e=null){const i=`${t[0]}`,s=`${t[1]}`;this._$store.has(i)||this._$store.set(i,V());const r=this._$store.get(i);if(null===e){if(!r.has(s))return;return this.destroy(r.get(s)),r.delete(s),void(r.size||(X(r),this._$store.delete(i)))}r.set(s,e)}has(t){const e=`${t[0]}`;return!!this._$store.has(e)&&this._$store.get(e).has(`${t[1]}`)}generateKeys(t,e=null,i=null){let s="";e&&e.length&&(s+=`${e[0]}_${e[1]}`),i&&i.length&&(s+=0===i[7]?"":`_${i[7]}`);const r=U();if(s){let t=0;const e=s.length;for(let i=0;i{i=t})()}}class at extends nt{constructor(t=4,e=4,i=1){super(),this._$blurX=4,this._$blurY=4,this._$quality=1,this.blurX=t,this.blurY=e,this.quality=i}static toString(){return"[class BlurFilter]"}static get namespace(){return"next2d.filters.BlurFilter"}toString(){return"[object BlurFilter]"}get namespace(){return"next2d.filters.BlurFilter"}static get STEP(){return[.5,1.05,1.4,1.55,1.75,1.9,2,2.15,2.2,2.3,2.5,3,3,3.5,3.5]}get blurX(){return this._$blurX}set blurX(t){(t=G(+t,0,255,0))!==this._$blurX&&(this._$blurX=t,this._$doChanged())}get blurY(){return this._$blurY}set blurY(t){(t=G(+t,0,255,0))!==this._$blurY&&(this._$blurY=t,this._$doChanged())}get quality(){return this._$quality}set quality(t){(t=G(0|t,0,15,1))!==this._$quality&&(this._$quality=t,this._$doChanged())}clone(){return new at(this._$blurX,this._$blurY,this._$quality)}_$toArray(){return U(1,this._$blurX,this._$blurY,this._$quality)}_$generateFilterRect(t,e=0,i=0){const s=F(t.xMin,t.xMax,t.yMin,t.yMax);if(!this._$quality)return s;const n=at.STEP[this._$quality-1];let a=0>=this._$blurX?1:this._$blurX*n,h=0>=this._$blurY?1:this._$blurY*n;return e?a*=e:a=r.round(a),i?h*=i:h=r.round(h),s.xMin-=a,s.xMax+=2*a,s.yMin-=h,s.yMax+=2*h,s}_$canApply(){return 0!==this._$blurX&&0!==this._$blurY}_$applyFilter(e,i,s=!0){this._$updated=!1;const n=e.frameBuffer,a=n.currentAttachment,h=n.getTextureFromCurrentAttachment();if(!this._$canApply())return s?h:n.createTextureFromCurrentAttachment();let o=r.sqrt(i[0]*i[0]+i[1]*i[1]),_=r.sqrt(i[2]*i[2]+i[3]*i[3]);o/=t,_/=t,o*=2,_*=2;const l=F(0,h.width,0,h.height),c=this._$generateFilterRect(l,o,_);B(l);const $=0|r.ceil(c.xMax),u=0|r.ceil(c.yMax),d=r.ceil(r.abs(c.xMin)+.5*r.abs($-c.xMax)),g=r.ceil(r.abs(c.yMin)+.5*r.abs(u-c.yMax));e._$offsetX=d+e._$offsetX,e._$offsetY=g+e._$offsetY;const f=this._$blurX*o,m=this._$blurY*_;let p=1,x=1;f>128?p=.0625:f>64?p=.125:f>32?p=.25:f>16&&(p=.5),m>128?x=.0625:m>64?x=.125:m>32?x=.25:m>16&&(x=.5);const b=f*p,v=m*x,T=r.ceil($*p),A=r.ceil(u*x),M=n.createTextureAttachment(T,A),y=[M,n.createTextureAttachment(T,A)];let E=0;e._$bind(M),e.reset(),e.setTransform(p,0,0,x,0,0),e.drawImage(h,d,g,h.width,h.height),e.blend.toOneZero();let C=n.getTextureFromCurrentAttachment();for(let t=0;t0){E=(E+1)%2;const t=y[E];e._$bind(t),e._$applyBlurFilter(C,!0,b),C=n.getTextureFromCurrentAttachment()}if(this._$blurY>0){E=(E+1)%2;const t=y[E];e._$bind(t),e._$applyBlurFilter(C,!1,v),C=n.getTextureFromCurrentAttachment()}}if(e.blend.reset(),1!==p||1!==x){const t=n.createTextureAttachment($,u);e._$bind(t),e.reset(),e.imageSmoothingEnabled=!0,e.setTransform(1/p,0,0,1/x,0,0),e.drawImage(C,0,0,T,A),C=n.getTextureFromCurrentAttachment(),e.reset(),e.setTransform(1,0,0,1,0,0),n.releaseAttachment(y[0],!0),n.releaseAttachment(y[1],!0),s?n.releaseAttachment(a,!0):n.releaseAttachment(t,!1)}else n.releaseAttachment(y[(E+1)%2],!0),s?n.releaseAttachment(a,!0):n.releaseAttachment(y[E],!1);return C}}class ht extends nt{constructor(t=4,e=45,i=16777215,s=1,r=0,n=1,a=4,h=4,o=1,_=1,l="inner",c=!1){super(),this._$blurFilter=new at(a,h,_),this._$distance=4,this._$angle=45,this._$highlightColor=16777215,this._$highlightAlpha=1,this._$shadowColor=0,this._$shadowAlpha=1,this._$strength=1,this._$type="inner",this._$knockout=!1,this.distance=t,this.angle=e,this.highlightColor=i,this.highlightAlpha=s,this.shadowColor=r,this.shadowAlpha=n,this.strength=o,this.type=l,this.knockout=c}static toString(){return"[class BevelFilter]"}static get namespace(){return"next2d.filters.BevelFilter"}toString(){return"[object BevelFilter]"}get namespace(){return"next2d.filters.BevelFilter"}get angle(){return this._$angle}set angle(t){(t%=360)!==this._$angle&&(this._$angle=G(t,-360,360,45),this._$doChanged())}get blurX(){return this._$blurFilter.blurX}set blurX(t){this._$blurFilter.blurX=t}get blurY(){return this._$blurFilter.blurY}set blurY(t){this._$blurFilter.blurY=t}get distance(){return this._$distance}set distance(t){(t=G(+t,-255,255,4))!==this._$distance&&(this._$distance=t,this._$doChanged())}get highlightAlpha(){return this._$highlightAlpha}set highlightAlpha(t){(t=G(+t,0,1,0))!==this._$highlightAlpha&&(this._$highlightAlpha=t,this._$doChanged())}get highlightColor(){return this._$highlightColor}set highlightColor(t){(t=G(j(t),0,16777215,16777215))!==this._$highlightColor&&(this._$highlightColor=t,this._$doChanged())}get knockout(){return this._$knockout}set knockout(t){t!==this._$knockout&&(this._$knockout=!!t,this._$doChanged())}get quality(){return this._$blurFilter.quality}set quality(t){this._$blurFilter.quality=t}get shadowAlpha(){return this._$shadowAlpha}set shadowAlpha(t){(t=G(+t,0,1,0))!==this._$shadowAlpha&&(this._$shadowAlpha=t,this._$doChanged())}get shadowColor(){return this._$shadowColor}set shadowColor(t){(t=G(j(t),0,16777215,0))!==this._$shadowColor&&(this._$shadowColor=t,this._$doChanged())}get strength(){return this._$strength}set strength(t){(t=G(0|t,0,255,0))!==this._$strength&&(this._$strength=t,this._$doChanged())}get type(){return this._$type}set type(t){(t=`${t}`)!==this._$type&&(this._$type=t,this._$doChanged())}clone(){return new ht(this._$distance,this._$angle,this._$highlightColor,this._$highlightAlpha,this._$shadowColor,this._$shadowAlpha,this._$blurFilter.blurX,this._$blurFilter.blurY,this._$strength,this._$blurFilter.quality,this._$type,this._$knockout)}_$toArray(){return U(0,this._$distance,this._$angle,this._$highlightColor,this._$highlightAlpha,this._$shadowColor,this._$shadowAlpha,this._$blurFilter.blurX,this._$blurFilter.blurY,this._$strength,this._$blurFilter.quality,this._$type,this._$knockout)}_$isUpdated(){return this._$updated||this._$blurFilter._$isUpdated()}_$generateFilterRect(t,e=0,i=0){let s=F(t.xMin,t.xMax,t.yMin,t.yMax);if(!this._$canApply())return s;s=this._$blurFilter._$generateFilterRect(s,e,i);const n=this._$angle*p;let a=r.abs(r.cos(n)*this._$distance),h=r.abs(r.sin(n)*this._$distance);return e&&(a*=e),i&&(h*=i),s.xMin=r.min(s.xMin,a),a>0&&(s.xMax+=a),s.yMin=r.min(s.yMin,h),h>0&&(s.yMax+=h),s}_$canApply(){return this._$strength>0&&0!==this._$distance&&this._$blurFilter._$canApply()}_$applyFilter(e,i){this._$updated=!1;const s=e.frameBuffer,n=s.currentAttachment;if(!n)throw new Error("the current attachment is null.");e.setTransform(1,0,0,1,0,0);const a=s.getTextureFromCurrentAttachment();if(!this._$canApply())return a;const h=n.width,o=n.height,_=e._$offsetX,l=e._$offsetY;let c=r.sqrt(i[0]*i[0]+i[1]*i[1]),$=r.sqrt(i[2]*i[2]+i[3]*i[3]);c/=t,$/=t,c*=2,$*=2;const u=this._$angle*p,d=r.cos(u)*this._$distance*c,g=r.sin(u)*this._$distance*$,f=s.createTextureAttachment(h,o);e._$bind(f),e.reset(),e.drawImage(a,0,0,h,o),e.globalCompositeOperation="erase",e.drawImage(a,2*d,2*g,h,o);const m=this._$blurFilter._$applyFilter(e,i,!1),x=m.width,b=m.height,v=r.ceil(x+2*r.abs(d)),T=r.ceil(b+2*r.abs(g)),A="inner"===this._$type,M=A?h:v,y=A?o:T,E=r.abs(d),C=r.abs(g),S=(x-h)/2,F=(b-o)/2,B=A?0:E+S,w=A?0:C+F,R=A?-S-d:E-d,I=A?-F-g:C-g;return e._$bind(n),s.releaseAttachment(f,!0),e._$applyBitmapFilter(m,M,y,h,o,B,w,x,b,R,I,!1,this._$type,this._$knockout,this._$strength,null,null,null,K(this._$highlightColor,this._$highlightAlpha,!0),Q(this._$highlightColor,this._$highlightAlpha,!0),J(this._$highlightColor,this._$highlightAlpha,!0),this._$highlightAlpha,K(this._$shadowColor,this._$shadowAlpha,!0),Q(this._$shadowColor,this._$shadowAlpha,!0),J(this._$shadowColor,this._$shadowAlpha,!0),this._$shadowAlpha),e._$offsetX=_+B,e._$offsetY=l+w,s.releaseTexture(m),s.getTextureFromCurrentAttachment()}}class ot extends nt{constructor(t=null){super(),this._$matrix=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0],this.matrix=t}static toString(){return"[class ColorMatrixFilter]"}static get namespace(){return"next2d.filters.ColorMatrixFilter"}toString(){return"[object ColorMatrixFilter]"}get namespace(){return"next2d.filters.ColorMatrixFilter"}get matrix(){return this._$matrix}set matrix(t){if(t&&n.isArray(t)&&20===t.length){for(let e=0;e<20;++e)if(t[e]!==this._$matrix[e]){this._$doChanged();break}this._$matrix=t}}clone(){return new ot(this._$matrix)}_$toArray(){return U(2,this._$matrix)}_$generateFilterRect(t){return t}_$canApply(){return!0}_$applyFilter(t){this._$updated=!1;const e=t.frameBuffer,i=e.currentAttachment;t.setTransform(1,0,0,1,0,0);const s=e.getTextureFromCurrentAttachment(),r=s.width,n=s.height,a=e.createTextureAttachment(r,n);return t._$bind(a),t.reset(),t._$applyColorMatrixFilter(s,this._$matrix),e.releaseAttachment(i,!0),e.getTextureFromCurrentAttachment()}}class _t extends nt{constructor(t=0,e=0,i=null,s=1,r=0,n=!0,a=!0,h=0,o=0){super(),this._$matrixX=0,this._$matrixY=0,this._$matrix=null,this._$divisor=1,this._$bias=0,this._$preserveAlpha=!0,this._$clamp=!0,this._$color=0,this._$alpha=0,this.matrixX=t,this.matrixY=e,this.matrix=i,this.divisor=s,this.bias=r,this.preserveAlpha=n,this.clamp=a,this.color=h,this.alpha=o}static toString(){return"[class ConvolutionFilter]"}static get namespace(){return"next2d.filters.ConvolutionFilter"}toString(){return"[object ConvolutionFilter]"}get namespace(){return"next2d.filters.ConvolutionFilter"}get alpha(){return this._$alpha}set alpha(t){(t=G(+t,0,1,0))!==this._$alpha&&(this._$alpha=t,this._$doChanged())}get bias(){return this._$bias}set bias(t){t!==this._$bias&&(this._$bias=0|t,this._$doChanged())}get clamp(){return this._$clamp}set clamp(t){t!==this._$clamp&&(this._$clamp=!!t,this._$doChanged())}get color(){return this._$color}set color(t){(t=G(j(t),0,16777215,0))!==this._$color&&(this._$color=t,this._$doChanged())}get divisor(){return this._$divisor}set divisor(t){t!==this._$divisor&&(this._$divisor=0|t,this._$doChanged())}get matrix(){return this._$matrix}set matrix(t){n.isArray(this._$matrix)&&D(this._$matrix),this._$matrix=n.isArray(t)?t:null,this._$doChanged()}get matrixX(){return this._$matrixX}set matrixX(t){(t=0|G(0|t,0,15,0))!==this._$matrixX&&(this._$matrixX=t,this._$doChanged())}get matrixY(){return this._$matrixY}set matrixY(t){(t=0|G(0|t,0,15,0))!==this._$matrixY&&(this._$matrixY=t,this._$doChanged())}get preserveAlpha(){return this._$preserveAlpha}set preserveAlpha(t){t!==this._$preserveAlpha&&(this._$preserveAlpha=!!t,this._$doChanged())}clone(){return new _t(this._$matrixX,this._$matrixY,this._$matrix?this._$matrix.slice():null,this._$divisor,this._$bias,this._$preserveAlpha,this._$clamp,this._$color,this._$alpha)}_$toArray(){return U(3,this._$matrixX,this._$matrixY,this._$matrix,this._$divisor,this._$bias,this._$preserveAlpha,this._$clamp,this._$color,this._$alpha)}_$generateFilterRect(t){return t}_$canApply(){return null!==this._$matrix&&this._$matrixX*this._$matrixY===this._$matrix.length}_$applyFilter(t){this._$updated=!1;const e=t.frameBuffer,i=e.currentAttachment;t.setTransform(1,0,0,1,0,0);const s=e.getTextureFromCurrentAttachment();return this._$canApply()&&this._$matrix?(t._$applyConvolutionFilter(s,this._$matrixX,this._$matrixY,this._$matrix,this._$divisor,this._$bias,this._$preserveAlpha,this._$clamp,K(this._$color,this._$alpha,!1),Q(this._$color,this._$alpha,!1),J(this._$color,this._$alpha,!1),this._$alpha),e.releaseAttachment(i,!0),e.getTextureFromCurrentAttachment()):s}}class lt extends nt{constructor(t=null,e=null,i=0,s=0,r=0,n=0,a="wrap",h=0,o=0){super(),this._$mapBitmap=null,this._$mapPoint=null,this._$componentX=0,this._$componentY=0,this._$scaleX=0,this._$scaleY=0,this._$mode="wrap",this._$color=0,this._$alpha=0,this.mapBitmap=t,this.mapPoint=e,this.componentX=i,this.componentY=s,this.scaleX=r,this.scaleY=n,this.mode=a,this.color=h,this.alpha=o}static toString(){return"[class DisplacementMapFilter]"}static get namespace(){return"next2d.filters.DisplacementMapFilter"}toString(){return"[object DisplacementMapFilter]"}get namespace(){return"next2d.filters.DisplacementMapFilter"}get alpha(){return this._$alpha}set alpha(t){(t=G(+t,0,1,0))!==this._$alpha&&(this._$alpha=t,this._$doChanged())}get color(){return this._$color}set color(t){(t=G(j(t),0,16777215,0))!==this._$color&&(this._$color=t,this._$doChanged())}get componentX(){return this._$componentX}set componentX(t){t!==this._$componentX&&(this._$componentX=t,this._$doChanged())}get componentY(){return this._$componentY}set componentY(t){t!==this._$componentY&&(this._$componentY=t,this._$doChanged())}get mapBitmap(){return this._$mapBitmap}set mapBitmap(t){t!==this._$mapBitmap&&(this._$mapBitmap=t,this._$doChanged())}get mapPoint(){return this._$mapPoint}set mapPoint(t){t!==this._$mapPoint&&(this._$mapPoint=t,this._$doChanged())}get mode(){return this._$mode}set mode(t){t!==this._$mode&&(this._$mode=t,this._$doChanged())}get scaleX(){return this._$scaleX}set scaleX(t){(t=G(+t,-65535,65535,0))!==this._$scaleX&&(this._$scaleX=t,this._$doChanged())}get scaleY(){return this._$scaleY}set scaleY(t){(t=G(+t,-65535,65535,0))!==this._$scaleY&&(this._$scaleY=t,this._$doChanged())}clone(){return new lt(this._$mapBitmap,this._$mapPoint,this._$componentX,this._$componentY,this._$scaleX,this._$scaleY,this._$mode,this._$color,this._$alpha)}_$toArray(){return U(4,this._$mapBitmap,this._$mapPoint,this._$componentX,this._$componentY,this._$scaleX,this._$scaleY,this._$mode,this._$color,this._$alpha)}_$generateFilterRect(t){return t}_$canApply(){return null!==this._$mapBitmap&&this._$componentX>0&&this._$componentY>0&&0!==this._$scaleX&&0!==this._$scaleY}_$applyFilter(t,e){this._$updated=!1;const i=t.frameBuffer,s=i.currentAttachment;t.setTransform(1,0,0,1,0,0);const n=i.getTextureFromCurrentAttachment();if(!this._$canApply()||!s||!this._$mapBitmap)return n;const a=r.sqrt(e[0]*e[0]+e[1]*e[1]),h=r.sqrt(e[2]*e[2]+e[3]*e[3]);return t._$applyDisplacementMapFilter(n,this._$mapBitmap,n.width/a,n.height/h,this._$mapPoint,this._$componentX,this._$componentY,this._$scaleX,this._$scaleY,this._$mode,K(this._$color,this._$alpha,!0),Q(this._$color,this._$alpha,!0),J(this._$color,this._$alpha,!0),this._$alpha),i.releaseAttachment(s,!0),i.getTextureFromCurrentAttachment()}}class ct extends nt{constructor(t=4,e=45,i=0,s=1,r=4,n=4,a=1,h=1,o=!1,_=!1,l=!1){super(),this._$blurFilter=new at(r,n,h),this._$distance=4,this._$angle=45,this._$color=0,this._$alpha=1,this._$strength=1,this._$inner=!1,this._$knockout=!1,this._$hideObject=!1,this.distance=t,this.angle=e,this.color=i,this.alpha=s,this.strength=a,this.inner=o,this.knockout=_,this.hideObject=l}static toString(){return"[class DropShadowFilter]"}static get namespace(){return"next2d.filters.DropShadowFilter"}toString(){return"[object DropShadowFilter]"}get namespace(){return"next2d.filters.DropShadowFilter"}get alpha(){return this._$alpha}set alpha(t){(t=G(+t,0,1,0))!==this._$alpha&&(this._$alpha=t,this._$doChanged())}get angle(){return this._$angle}set angle(t){(t%=360)!==this._$angle&&(this._$angle=G(t,-360,360,45),this._$doChanged())}get blurX(){return this._$blurFilter.blurX}set blurX(t){this._$blurFilter.blurX=t}get blurY(){return this._$blurFilter.blurY}set blurY(t){this._$blurFilter.blurY=t}get color(){return this._$color}set color(t){(t=G(j(t),0,16777215,0))!==this._$color&&(this._$color=t,this._$doChanged())}get distance(){return this._$distance}set distance(t){(t=G(+t,-255,255,4))!==this._$distance&&(this._$distance=t,this._$doChanged())}get hideObject(){return this._$hideObject}set hideObject(t){t!==this._$hideObject&&(this._$hideObject=!!t,this._$doChanged())}get inner(){return this._$inner}set inner(t){t!==this._$inner&&(this._$inner=!!t,this._$doChanged())}get knockout(){return this._$knockout}set knockout(t){t!==this._$knockout&&(this._$knockout=!!t,this._$doChanged())}get quality(){return this._$blurFilter.quality}set quality(t){this._$blurFilter.quality=t}get strength(){return this._$strength}set strength(t){(t=G(0|t,0,255,0))!==this._$strength&&(this._$strength=t,this._$doChanged())}clone(){return new ct(this._$distance,this._$angle,this._$color,this._$alpha,this._$blurFilter.blurX,this._$blurFilter.blurY,this._$strength,this._$blurFilter.quality,this._$inner,this._$knockout,this._$hideObject)}_$toArray(){return U(5,this._$distance,this._$angle,this._$color,this._$alpha,this._$blurFilter.blurX,this._$blurFilter.blurY,this._$strength,this._$blurFilter.quality,this._$inner,this._$knockout,this._$hideObject)}_$isUpdated(){return this._$updated||this._$blurFilter._$isUpdated()}_$generateFilterRect(t,e=0,i=0){let s=F(t.xMin,t.xMax,t.yMin,t.yMax);if(!this._$canApply())return s;s=this._$blurFilter._$generateFilterRect(s,e,i);const n=this._$angle*p;let a=r.cos(n)*this._$distance,h=r.sin(n)*this._$distance;return e&&(a*=e),i&&(h*=i),s.xMin=r.min(s.xMin,a),a>0&&(s.xMax+=a),s.yMin=r.min(s.yMin,h),h>0&&(s.yMax+=h),s}_$canApply(){return this._$alpha>0&&this._$strength>0&&this._$blurFilter._$canApply()}_$applyFilter(e,i){const s=e.frameBuffer,n=s.currentAttachment;if(!n)throw new Error("the current attachment is null.");if(e.setTransform(1,0,0,1,0,0),!this._$canApply())return s.getTextureFromCurrentAttachment();const a=n.width,h=n.height,o=e._$offsetX,_=e._$offsetY,l=this._$blurFilter._$applyFilter(e,i,!1),c=l.width,$=l.height,u=e._$offsetX,d=e._$offsetY,g=u-o,f=d-_;let m=r.sqrt(i[0]*i[0]+i[1]*i[1]),x=r.sqrt(i[2]*i[2]+i[3]*i[3]);m/=t,x/=t,m*=2,x*=2;const b=this._$angle*p,v=r.cos(b)*this._$distance*m,T=r.sin(b)*this._$distance*x,A=this._$inner?a:c+r.max(0,r.abs(v)-g),M=this._$inner?h:$+r.max(0,r.abs(T)-f),y=r.ceil(A),E=r.ceil(M),C=(y-A)/2,S=(E-M)/2,F=this._$inner?0:r.max(0,g-v)+C,B=this._$inner?0:r.max(0,f-T)+S,w=this._$inner?v-u:(v>0?r.max(0,v-g):0)+C,R=this._$inner?T-d:(T>0?r.max(0,T-f):0)+S;let I,P;return this._$inner?(I="inner",P=this._$knockout||this._$hideObject):!this._$knockout&&this._$hideObject?(I="full",P=!0):(I="outer",P=this._$knockout),e._$bind(n),e._$applyBitmapFilter(l,y,E,a,h,F,B,c,$,w,R,!0,I,P,this._$strength,null,null,null,K(this._$color,this._$alpha,!0),Q(this._$color,this._$alpha,!0),J(this._$color,this._$alpha,!0),this._$alpha,0,0,0,0),e._$offsetX=o+F,e._$offsetY=_+B,s.releaseTexture(l),s.getTextureFromCurrentAttachment()}}class $t extends nt{constructor(t=0,e=1,i=4,s=4,r=1,n=1,a=!1,h=!1){super(),this._$blurFilter=new at(i,s,n),this._$color=0,this._$alpha=1,this._$strength=1,this._$inner=!1,this._$knockout=!1,this.color=t,this.alpha=e,this.strength=r,this.inner=a,this.knockout=h}static toString(){return"[class GlowFilter]"}static get namespace(){return"next2d.filters.GlowFilter"}toString(){return"[object GlowFilter]"}get namespace(){return"next2d.filters.GlowFilter"}get alpha(){return this._$alpha}set alpha(t){(t=G(+t,0,1,0))!==this._$alpha&&(this._$alpha=t,this._$doChanged())}get blurX(){return this._$blurFilter.blurX}set blurX(t){this._$blurFilter.blurX=t}get blurY(){return this._$blurFilter.blurY}set blurY(t){this._$blurFilter.blurY=t}get color(){return this._$color}set color(t){(t=G(j(t),0,16777215,4))!==this._$color&&(this._$color=t,this._$doChanged())}get inner(){return this._$inner}set inner(t){t!==this._$inner&&(this._$inner=!!t,this._$doChanged())}get knockout(){return this._$knockout}set knockout(t){t!==this._$knockout&&(this._$knockout=!!t,this._$doChanged())}get quality(){return this._$blurFilter.quality}set quality(t){this._$blurFilter.quality=t}get strength(){return this._$strength}set strength(t){(t=G(0|t,0,255,0))!==this._$strength&&(this._$strength=t,this._$doChanged())}clone(){return new $t(this._$color,this._$alpha,this._$blurFilter.blurX,this._$blurFilter.blurY,this._$strength,this._$blurFilter.quality,this._$inner,this._$knockout)}_$toArray(){return U(6,this._$color,this._$alpha,this._$blurFilter.blurX,this._$blurFilter.blurY,this._$strength,this._$blurFilter.quality,this._$inner,this._$knockout)}_$isUpdated(){return this._$updated||this._$blurFilter._$isUpdated()}_$generateFilterRect(t,e=0,i=0){const s=F(t.xMin,t.xMax,t.yMin,t.yMax);return this._$canApply()?this._$blurFilter._$generateFilterRect(s,e,i):s}_$canApply(){return this._$alpha>0&&this._$strength>0&&this._$blurFilter._$canApply()}_$applyFilter(t,e){const i=t.frameBuffer,s=i.currentAttachment;if(!s)throw new Error("the current attachment is null.");if(this._$updated=!1,t.setTransform(1,0,0,1,0,0),!this._$canApply())return i.getTextureFromCurrentAttachment();const r=s.width,n=s.height,a=t._$offsetX,h=t._$offsetY,o=this._$blurFilter._$applyFilter(t,e,!1),_=o.width,l=o.height,c=t._$offsetX,$=t._$offsetY,u=this._$inner?r:_,d=this._$inner?n:l,g=this._$inner?0:c-a,f=this._$inner?0:$-h,m=this._$inner?-c:0,p=this._$inner?-$:0,x=this._$inner?"inner":"outer";return t._$bind(s),t._$applyBitmapFilter(o,u,d,r,n,g,f,_,l,m,p,!0,x,this._$knockout,this._$strength,null,null,null,K(this._$color,this._$alpha,!0),Q(this._$color,this._$alpha,!0),J(this._$color,this._$alpha,!0),this._$alpha,0,0,0,0),t._$offsetX=a+g,t._$offsetY=h+f,i.releaseTexture(o),i.getTextureFromCurrentAttachment()}}class ut extends nt{constructor(t=4,e=45,i=null,s=null,r=null,n=4,a=4,h=1,o=1,_="inner",l=!1){super(),this._$blurFilter=new at(n,a,o),this._$distance=4,this._$angle=45,this._$colors=null,this._$alphas=null,this._$ratios=null,this._$strength=1,this._$type="inner",this._$knockout=!1,this.distance=t,this.angle=e,this.colors=i,this.alphas=s,this.ratios=r,this.strength=h,this.type=_,this.knockout=l}static toString(){return"[class GradientBevelFilter]"}static get namespace(){return"next2d.filters.GradientBevelFilter"}toString(){return"[object GradientBevelFilter]"}get namespace(){return"next2d.filters.GradientBevelFilter"}get alphas(){return this._$alphas}set alphas(t){if(t!==this._$alphas){if(this._$alphas=t,n.isArray(t)){for(let e=0;e0&&(s.xMax+=a),s.yMin=r.min(s.yMin,h),h>0&&(s.yMax+=h),s}_$canApply(){return this._$strength>0&&this._$distance>0&&null!==this._$alphas&&null!==this._$ratios&&null!==this._$colors&&this._$blurFilter._$canApply()}_$applyFilter(e,i){this._$updated=!1;const s=e.frameBuffer,n=s.currentAttachment;e.setTransform(1,0,0,1,0,0);const a=s.getTextureFromCurrentAttachment();if(!this._$canApply()||!n)return a;const h=n.width,o=n.height,_=e._$offsetX,l=e._$offsetY;let c=r.sqrt(i[0]*i[0]+i[1]*i[1]),$=r.sqrt(i[2]*i[2]+i[3]*i[3]);c/=t,$/=t,c*=2,$*=2;const u=+this._$angle*p,d=+r.cos(u)*this._$distance*c,g=+r.sin(u)*this._$distance*$,f=s.createTextureAttachment(h,o);e._$bind(f),e.reset(),e.drawImage(a,0,0,h,o),e.globalCompositeOperation="erase",e.drawImage(a,2*d,2*g,h,o);const m=this._$blurFilter._$applyFilter(e,i,!1),x=m.width,b=m.height,v=r.ceil(x+2*r.abs(d)),T=r.ceil(b+2*r.abs(g)),A="inner"===this._$type,M=A?h:v,y=A?o:T,E=r.abs(d),C=r.abs(g),S=(x-h)/2,F=(b-o)/2,B=A?0:E+S,w=A?0:C+F,R=A?-S-d:E-d,I=A?-F-g:C-g;return e._$bind(n),e._$applyBitmapFilter(m,M,y,h,o,B,w,x,b,R,I,!1,this._$type,this._$knockout,this._$strength,this._$ratios,this._$colors,this._$alphas,0,0,0,0,0,0,0,0),e._$offsetX=_+B,e._$offsetY=l+w,s.releaseAttachment(f,!0),s.getTextureFromCurrentAttachment()}}class dt extends nt{constructor(t=4,e=45,i=null,s=null,r=null,n=4,a=4,h=1,o=1,_="inner",l=!1){super(),this._$blurFilter=new at(n,a,o),this._$distance=4,this._$angle=45,this._$colors=null,this._$alphas=null,this._$ratios=null,this._$strength=1,this._$type="inner",this._$knockout=!1,this.distance=t,this.angle=e,this.colors=i,this.alphas=s,this.ratios=r,this.strength=h,this.type=_,this.knockout=l}static toString(){return"[class GradientGlowFilter]"}static get namespace(){return"next2d.filters.GradientGlowFilter"}toString(){return"[object GradientGlowFilter]"}get namespace(){return"next2d.filters.GradientGlowFilter"}get alphas(){return this._$alphas}set alphas(t){if(t!==this._$alphas){if(this._$alphas=t,n.isArray(t)){for(let e=0;e0&&(s.xMax+=a),s.yMin=r.min(s.yMin,h),h>0&&(s.yMax+=h),s}_$canApply(){return this._$strength>0&&this._$distance>0&&null!==this._$alphas&&null!==this._$ratios&&null!==this._$colors&&this._$blurFilter._$canApply()}_$applyFilter(e,i){this._$updated=!1;const s=e.frameBuffer,n=s.currentAttachment;if(e.setTransform(1,0,0,1,0,0),!this._$canApply()||!n)return s.getTextureFromCurrentAttachment();const a=n.width,h=n.height,o=e._$offsetX,_=e._$offsetY,l=this._$blurFilter._$applyFilter(e,i,!1),c=l.width,$=l.height,u=e._$offsetX,d=e._$offsetY,g=u-o,f=d-_;let m=r.sqrt(i[0]*i[0]+i[1]*i[1]),x=r.sqrt(i[2]*i[2]+i[3]*i[3]);m/=t,x/=t,m*=2,x*=2;const b=+this._$angle*p,v=+r.cos(b)*this._$distance*m,T=+r.sin(b)*this._$distance*x,A="inner"===this.type,M=A?a:c+r.max(0,r.abs(v)-g),y=A?h:$+r.max(0,r.abs(T)-f),E=r.ceil(M),C=r.ceil(y),S=(E-M)/2,F=(C-y)/2,B=A?0:r.max(0,g-v)+S,w=A?0:r.max(0,f-T)+F,R=A?v-u:(v>0?r.max(0,v-g):0)+S,I=A?T-d:(T>0?r.max(0,T-f):0)+F;return e._$bind(n),e._$applyBitmapFilter(l,E,C,a,h,B,w,c,$,R,I,!0,this._$type,this._$knockout,this._$strength,this._$ratios,this._$colors,this._$alphas,0,0,0,0,0,0,0,0),e._$offsetX=o+B,e._$offsetY=_+w,s.releaseTexture(l),s.getTextureFromCurrentAttachment()}}class gt{constructor(){this._$instanceId=-1,this._$parentId=-1,this._$loaderInfoId=-1,this._$characterId=-1,this._$clipDepth=0,this._$depth=0,this._$isMask=!1,this._$updated=!0,this._$matrix=P(1,0,0,1,0,0),this._$colorTransform=k(1,1,1,1,0,0,0,0),this._$blendMode="normal",this._$filters=null,this._$visible=!0,this._$maskId=-1,this._$maskMatrix=null,this._$isMask=!1,this._$xMin=0,this._$yMin=0,this._$xMax=0,this._$yMax=0,this._$scale9Grid=null,this._$matrixBase=null}_$shouldClip(t){const e=this._$getBounds(t),i=r.abs(e.xMax-e.xMin),s=r.abs(e.yMax-e.yMin);return B(e),!(!i||!s)}_$getLayerBounds(e){const i=this._$getBounds(),s=q(i,e);B(i);const n=this._$filters;if(!n||!n.length)return s;let a=F(0,r.abs(s.xMax-s.xMin),0,r.abs(s.yMax-s.yMin));B(s);let h=+r.sqrt(e[0]*e[0]+e[1]*e[1]),o=+r.sqrt(e[2]*e[2]+e[3]*e[3]);h/=t,o/=t,h*=2,o*=2;for(let t=0;t-1){const t=le.instances;if(!t.has(this._$parentId))return;const e=t.get(this._$parentId);e._$updated||e._$doChanged()}}_$update(t){if(this._$doChanged(),this._$visible=t.visible,"depth"in t&&(this._$depth=t.depth),"isMask"in t&&(this._$isMask=t.isMask),"clipDepth"in t&&(this._$clipDepth=t.clipDepth),"maskId"in t&&(this._$maskId=t.maskId,this._$maskId>-1&&t.maskMatrix&&(this._$maskMatrix=t.maskMatrix)),this._$matrix[0]="a"in t?t.a:1,this._$matrix[1]="b"in t?t.b:0,this._$matrix[2]="c"in t?t.c:0,this._$matrix[3]="d"in t?t.d:1,this._$matrix[4]="tx"in t?t.tx:0,this._$matrix[5]="ty"in t?t.ty:0,this._$colorTransform[0]="f0"in t?t.f0:1,this._$colorTransform[1]="f1"in t?t.f1:1,this._$colorTransform[2]="f2"in t?t.f2:1,this._$colorTransform[3]="f3"in t?t.f3:1,this._$colorTransform[4]="f4"in t?t.f4:0,this._$colorTransform[5]="f5"in t?t.f5:0,this._$colorTransform[6]="f6"in t?t.f6:0,this._$colorTransform[7]="f7"in t?t.f7:0,this._$blendMode=t.blendMode||"normal",this._$filters=null,t.filters&&t.filters.length){this._$filters=U();for(let e=0;e-1&&this._$characterId&&rt.setRemoveTimer(`${this._$loaderInfoId}@${this._$characterId}`),t.instances.delete(this._$instanceId),this._$instanceId=-1,this._$parentId=-1,this._$loaderInfoId=-1,this._$characterId=-1,this._$blendMode="normal",this._$filters=null,this._$visible=!0,this._$maskId=-1,this._$isMask=!1,this._$depth=0,this._$clipDepth=0,this._$scale9Grid=null}_$isUpdated(){return this._$updated}_$isFilterUpdated(t,e=null,i=!1){if(this._$isUpdated())return!0;if(i&&e)for(let t=0;tc||s._$clipDepth>0)&&(t.restore(),l&&t._$leaveClip(),c=0,l=!0),!l)continue;if(s._$clipDepth>0){c=s._$clipDepth,l=s._$shouldClip(o),l&&(t.save(),l=s._$startClip(t,o));continue}const a=s._$maskId>-1&&$.has(s._$maskId)?$.get(s._$maskId):null;if(a){let e;if(a._$updated=!1,this._$instanceId===a._$parentId)e=o;else{e=f;let i=$.get(a._$parentId);for(;i||i._$instanceId!==i._$parentId;)e=H(i._$matrix,e),i=$.get(i._$parentId);const s=le.scaleX,r=P(s,0,0,s,0,0);if(e=H(r,e),N(r),t.isLayer){const i=t.getCurrentPosition();e[4]-=i.xMin,e[5]-=i.yMin}}if(!a._$shouldClip(e))continue;const i=a._$startClip(t,e);if(t.save(),!i){t.restore();continue}}s._$draw(t,o,_),s._$updated=!1,a&&(t.restore(),t._$leaveClip())}if(c&&(t.restore(),l&&t._$leaveClip()),h.isLayer)return this._$postDraw(t,e,s,h);h.matrix!==e&&N(h.matrix),s!==i&&L(s),et(h)}_$getLayerBounds(e){const i=this._$children;if(!i.length)return F(0,0,0,0);const s=h.MAX_VALUE;let n=s,a=-s,o=s,_=-s;const l=le.instances;for(let t=0;t0){const s=this._$getBounds(null),o=q(s,i);B(s);const _=+o.xMax,l=+o.xMin,c=+o.yMax,$=+o.yMin;B(o);const u=r.ceil(r.abs(_-l)),d=r.ceil(r.abs(c-$));if(0>=u||0>=d)return et(n),i!==e&&N(i),null;let g=+r.sqrt(i[0]*i[0]+i[1]*i[1]);if(!h.isInteger(g)){const t=g.toString(),e=t.indexOf("e");-1!==e&&(g=+t.slice(0,e)),g=+g.toFixed(4)}let f=+r.sqrt(i[2]*i[2]+i[3]*i[3]);if(!h.isInteger(f)){const t=f.toString(),e=t.indexOf("e");-1!==e&&(f=+t.slice(0,e)),f=+f.toFixed(4)}n.canApply=this._$canApply(this._$filters);let m=F(0,u,0,d);if(n.canApply&&this._$filters)for(let t=0;tp.width||$-m.yMin>p.height)return B(m),et(n),i!==e&&N(i),null;if(0>l+m.xMax||0>$+m.yMax)return B(m),et(n),i!==e&&N(i),null;let x=i[4]-l,b=i[5]-$;t._$startLayer(F(l,_,$,c));const v=this._$isFilterUpdated(i,this._$filters,n.canApply),T=this._$getLayerBounds(i),A=r.ceil(r.abs(T.xMax-T.xMin)),M=r.ceil(r.abs(T.yMax-T.yMin));B(T);const y=A-m.xMax+m.xMin,E=M-m.yMax+m.yMin;x+=y,b+=E,n.sw=y,n.sh=E,v&&t._$saveAttachment(r.ceil(u+y),r.ceil(d+E),!0),n.isLayer=!0,n.isUpdated=v,n.filters=this._$filters,n.blendMode=a,n.color=k(),n.matrix=P(i[0],i[1],i[2],i[3],x,b),i!==e&&N(i),B(m)}return n}_$postDraw(t,e,i,s){t.drawInstacedArray();const r=U(this._$instanceId,"f"),n=t.frameBuffer,a=s.matrix;let h=0,o=0,_=rt.get(r);if(!_||s.isUpdated){_&&rt.set(r,null),_=n.getTextureFromCurrentAttachment();const i=s.filters;let l=!1;if(i&&i.length){for(let s=0;s{switch(!0){case t[0]>e[0]:return 1;case e[0]>t[0]:return-1;default:return 0}})),this._$stops}linear(t,e,i,s,r="rgb",n="pad"){return this._$type="linear",this._$points[0]=t,this._$points[1]=e,this._$points[2]=i,this._$points[3]=s,this._$rgb=r,this._$mode=n,this._$stops.length&&(this._$stops.length=0),this}radial(t,e,i,s,r,n,a="rgb",h="pad",o=0){return this._$type="radial",this._$points[0]=t,this._$points[1]=e,this._$points[2]=i,this._$points[3]=s,this._$points[4]=r,this._$points[5]=n,this._$rgb=a,this._$mode=h,this._$focalPointRatio=G(o,-.975,.975,0),this._$stops.length&&(this._$stops.length=0),this}addColorStop(t,e){this._$stops.push(U(t,e))}}class pt{constructor(t,e,i){this._$texture=t,this._$repeat=e,this._$colorTransform=i}get texture(){return this._$texture}get repeat(){return this._$repeat}get colorTransform(){return this._$colorTransform}}class xt{constructor(){this._$fillStyle=w(1,1,1,1),this._$strokeStyle=w(1,1,1,1),this._$lineWidth=1,this._$lineCap="round",this._$lineJoin="round",this._$miterLimit=5}get miterLimit(){return this._$miterLimit}set miterLimit(t){this._$miterLimit=t}get lineWidth(){return this._$lineWidth}set lineWidth(t){this._$lineWidth=t}get lineCap(){return this._$lineCap}set lineCap(t){this._$lineCap=t}get lineJoin(){return this._$lineJoin}set lineJoin(t){this._$lineJoin=t}get fillStyle(){return this._$fillStyle}set fillStyle(t){this._$fillStyle instanceof o&&R(this._$fillStyle),this._$fillStyle=t}get strokeStyle(){return this._$strokeStyle}set strokeStyle(t){this._$strokeStyle instanceof o&&R(this._$strokeStyle),this._$strokeStyle=t}clear(){this._$lineWidth=1,this._$lineCap="round",this._$lineJoin="round",this._$miterLimit=5,this._$clearFill(),this._$clearStroke()}_$clearFill(){if(this._$fillStyle instanceof mt)return this._$fillStyle.dispose(),void(this._$fillStyle=w(1,1,1,1));this._$fillStyle instanceof pt?this._$fillStyle=w(1,1,1,1):this._$fillStyle.fill(1)}_$clearStroke(){if(this._$strokeStyle instanceof mt)return this._$strokeStyle.dispose(),void(this._$strokeStyle=w(1,1,1,1));this._$strokeStyle instanceof pt?this._$strokeStyle=w(1,1,1,1):this._$strokeStyle.fill(1)}}let bt=2048;class vt{constructor(t){t.pixelStorei(t.UNPACK_ALIGNMENT,1),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),this._$gl=t,this._$objectPool=[],this._$objectPoolArea=0,this._$activeTexture=-1,this._$boundTextures=[null,null,null],this._$maxWidth=0,this._$maxHeight=0,this._$atlasTextures=[],this._$atlasCacheMap=new Map,this._$positionObjectArray=[],this._$nodeObjectArray=[],this._$atlasNodes=new Map}createTextureAtlas(){const t=this._$gl.createTexture();t.width=bt,t.height=bt,this._$gl.activeTexture(this._$gl.TEXTURE3),this._$gl.bindTexture(this._$gl.TEXTURE_2D,t),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_WRAP_S,this._$gl.CLAMP_TO_EDGE),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_WRAP_T,this._$gl.CLAMP_TO_EDGE),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_MIN_FILTER,this._$gl.NEAREST),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_MAG_FILTER,this._$gl.NEAREST),this._$gl.texStorage2D(this._$gl.TEXTURE_2D,1,this._$gl.RGBA8,bt,bt),this._$gl.bindTexture(this._$gl.TEXTURE_2D,null),this._$activeTexture>-1&&this._$gl.activeTexture(this._$activeTexture);const e=this._$atlasTextures.length;this._$atlasNodes.set(e,[]),this._$atlasCacheMap.set(e,[]),this._$atlasTextures.push(t)}getAtlasTexture(t){return this._$atlasTextures[t]}getNode(t,e,i,s){const r=this._$nodeObjectArray.length?this._$nodeObjectArray.pop():{x:0,y:0,w:0,h:0};return r.x=t,r.y=e,r.w=i,r.h=s,r}createCachePosition(t,e){const i=this._$positionObjectArray.length?this._$positionObjectArray.pop():{index:0,x:0,y:0,w:0,h:0};i.x=i.y=0,i.w=t,i.h=e;for(const[s,r]of this._$atlasNodes){if(!r.length)return t>e?(bt-t-1>0&&r.push(this.getNode(t+1,0,bt-t-1,e)),bt-e-1>0&&r.push(this.getNode(0,e+1,bt,bt-e-1))):(bt-e-1>0&&r.push(this.getNode(0,e+1,t,bt-e-1)),bt-t-1>0&&r.push(this.getNode(t+1,0,bt-t-1,bt))),i.index=s,this._$atlasCacheMap.get(i.index).push(i),i;const n=r.length;for(let a=0;an.w||e>n.h))return i.index=s,i.x=n.x,i.y=n.y,this._$atlasCacheMap.get(i.index).push(i),n.w!==t||n.h!==e?t>e?(n.h-e-1>0&&r.push(this.getNode(n.x,n.y+e+1,n.w,n.h-e-1)),n.w-t-1>0?(n.x=n.x+t+1,n.w=n.w-t-1,n.h=e):(r.splice(a,1),this._$nodeObjectArray.push(n))):(n.w-t-1>0&&r.push(this.getNode(n.x+t+1,n.y,n.w-t-1,n.h)),n.h-e-1>0?(n.y=n.y+e+1,n.w=t,n.h=n.h-e-1):(r.splice(a,1),this._$nodeObjectArray.push(n))):(r.splice(a,1),this._$nodeObjectArray.push(n)),i}}const s=this._$atlasTextures.length;this.createTextureAtlas();const r=this._$atlasNodes.get(s);return t>e?(bt-t-1>0&&r.push(this.getNode(t+1,0,bt-t-1,e)),bt-e-1>0&&r.push(this.getNode(0,e+1,bt,bt-e-1))):(bt-e-1>0&&r.push(this.getNode(0,e+1,t,bt-e-1)),bt-t-1>0&&r.push(this.getNode(t+1,0,bt-t-1,bt))),i.index=s,this._$atlasCacheMap.get(i.index).push(i),i}releasePosition(t){var e;this._$atlasNodes.has(t.index)&&(null===(e=this._$atlasNodes.get(t.index))||void 0===e||e.unshift(this.getNode(t.x,t.y,t.w,t.h)),this._$positionObjectArray.push(t))}clearCache(){for(const t of this._$atlasCacheMap.values())t.length=0;for(const t of this._$atlasNodes.values())t.length=0}_$createTexture(t,e){const i=this._$gl.createTexture();return i.width=0,i.height=0,i.area=0,i.dirty=!0,i.smoothing=!0,this.bind0(i,!1),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_WRAP_S,this._$gl.CLAMP_TO_EDGE),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_WRAP_T,this._$gl.CLAMP_TO_EDGE),i.width=t,i.height=e,i.area=t*e,i.dirty=!1,this._$gl.texStorage2D(this._$gl.TEXTURE_2D,1,this._$gl.RGBA8,t,e),i}_$getTexture(t,e){for(let i=0;ithis._$maxWidth*this._$maxHeight*2)this._$gl.deleteTexture(t);else if(t.dirty=!0,this._$objectPool.push(t),this._$objectPoolArea+=t.area,this._$objectPool.length&&this._$objectPoolArea>this._$maxWidth*this._$maxHeight*10){const t=this._$objectPool.shift();this._$objectPoolArea-=t.area,this._$gl.deleteTexture(t)}}bind0(t,e=null){this._$bindTexture(2,this._$gl.TEXTURE2,null,null),this._$bindTexture(1,this._$gl.TEXTURE1,null,null),this._$bindTexture(0,this._$gl.TEXTURE0,t,e)}bind01(t,e,i=null){this._$bindTexture(2,this._$gl.TEXTURE2,null,null),this._$bindTexture(1,this._$gl.TEXTURE1,e,i),this._$bindTexture(0,this._$gl.TEXTURE0,t,i)}bind012(t,e,i,s=null){this._$bindTexture(2,this._$gl.TEXTURE2,i,s),this._$bindTexture(1,this._$gl.TEXTURE1,e,null),this._$bindTexture(0,this._$gl.TEXTURE0,t,null)}bind02(t,e,i=null){this._$bindTexture(2,this._$gl.TEXTURE2,e,i),this._$bindTexture(1,this._$gl.TEXTURE1,null,null),this._$bindTexture(0,this._$gl.TEXTURE0,t,null)}_$bindTexture(t,e,i=null,s=null){const r=i!==this._$boundTextures[t],n=null!==s&&null!==i&&s!==i.smoothing;if((r||n||e===this._$gl.TEXTURE0)&&e!==this._$activeTexture&&(this._$activeTexture=e,this._$gl.activeTexture(e)),r&&(this._$boundTextures[t]=i,this._$gl.bindTexture(this._$gl.TEXTURE_2D,i)),n){i&&(i.smoothing=!!s);const t=s?this._$gl.LINEAR:this._$gl.NEAREST;this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_MIN_FILTER,t),this._$gl.texParameteri(this._$gl.TEXTURE_2D,this._$gl.TEXTURE_MAG_FILTER,t)}}}class Tt{constructor(t){this._$gl=t,this._$objectPool=U(),this._$objectPoolArea=0,this._$maxWidth=0,this._$maxHeight=0}set maxWidth(t){this._$maxWidth=t}set maxHeight(t){this._$maxHeight=t}_$createStencilBuffer(){const t=this._$gl.createRenderbuffer();if(!t)throw new Error("the stencil buffer is null.");return t.width=0,t.height=0,t.area=0,t.dirty=!0,t}_$getStencilBuffer(t,e){const i=this._$objectPool.length;for(let s=0;s100){const t=this._$objectPool.shift();if(t)return this._$objectPoolArea-=t.area,t}return this._$createStencilBuffer()}create(t,e){const i=this._$getStencilBuffer(t,e);return i.width===t&&i.height===e||(i.width=t,i.height=e,i.area=t*e,i.dirty=!1,this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,i),this._$gl.renderbufferStorage(this._$gl.RENDERBUFFER,this._$gl.STENCIL_INDEX8,t,e)),i}release(t){if(t.area>this._$maxWidth*this._$maxHeight*2)this._$gl.deleteRenderbuffer(t);else if(t.dirty=!0,this._$objectPool.push(t),this._$objectPoolArea+=t.area,this._$objectPoolArea>this._$maxWidth*this._$maxHeight*10){const t=this._$objectPool.shift();t&&(this._$objectPoolArea-=t.area,this._$gl.deleteRenderbuffer(t))}}}class At{constructor(t,e){this._$gl=t,this._$samples=e,this._$objectPool=U()}set samples(t){this._$samples=t}_$createColorBuffer(){const t=this._$gl.createRenderbuffer();if(!t)throw new Error("the color buffer is null.");const e=this._$gl.createRenderbuffer();if(!e)throw new Error("the stencil buffer is null.");return t.stencil=e,t.samples=0,t.width=0,t.height=0,t.area=0,t.dirty=!0,t}_$getColorBuffer(t){if(!this._$objectPool.length)return this._$createColorBuffer();const e=this._$bsearch(t);if(e1;){const s=r.floor((i+e)/2);t<=this._$objectPool[s].area?i=s:e=s}return i}}class Mt{constructor(t,e){this._$gl=t,this._$objectPool=[],this._$frameBuffer=t.createFramebuffer(),t.bindFramebuffer(t.READ_FRAMEBUFFER,this._$frameBuffer),this._$frameBufferTexture=t.createFramebuffer(),this._$currentAttachment=null,this._$isBinding=!1,this._$textureManager=new vt(t),this._$stencilBufferPool=new Tt(t),this._$colorBufferPool=new At(t,e),this._$isRenderBinding=!1,this._$colorBuffer=this._$gl.createRenderbuffer(),this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,this._$colorBuffer),this._$gl.renderbufferStorageMultisample(this._$gl.RENDERBUFFER,e,this._$gl.RGBA8,bt,bt),this._$stencilBuffer=this._$gl.createRenderbuffer(),this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,this._$stencilBuffer),this._$gl.renderbufferStorageMultisample(this._$gl.RENDERBUFFER,e,this._$gl.STENCIL_INDEX8,bt,bt)}bindRenderBuffer(){this._$isBinding||(this._$isBinding=!0,this._$gl.bindFramebuffer(this._$gl.FRAMEBUFFER,this._$frameBuffer)),this._$isRenderBinding||(this._$isRenderBinding=!0,this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,this._$colorBuffer),this._$gl.framebufferRenderbuffer(this._$gl.FRAMEBUFFER,this._$gl.COLOR_ATTACHMENT0,this._$gl.RENDERBUFFER,this._$colorBuffer),this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,this._$stencilBuffer),this._$gl.framebufferRenderbuffer(this._$gl.FRAMEBUFFER,this._$gl.STENCIL_ATTACHMENT,this._$gl.RENDERBUFFER,this._$stencilBuffer))}get currentAttachment(){return this._$currentAttachment}get textureManager(){return this._$textureManager}createCacheAttachment(t,e,i=!1,s=0){const r=this._$objectPool.pop()||{width:0,height:0,color:null,texture:null,msaa:!1,stencil:null,mask:!1,clipLevel:0,isActive:!1},n=this._$textureManager.create(t,e);return r.width=t,r.height=e,i?(r.color=this._$colorBufferPool.create(t,e,s),r.texture=n,r.msaa=!0,r.stencil=r.color.stencil):(r.color=n,r.texture=n,r.msaa=!1,r.stencil=this._$stencilBufferPool.create(t,e)),r.mask=!1,r.clipLevel=0,r.isActive=!0,r}clearCache(){this._$textureManager.clearCache()}setMaxSize(t,e){this._$stencilBufferPool._$maxWidth=t,this._$stencilBufferPool._$maxHeight=e,this._$textureManager._$maxWidth=t,this._$textureManager._$maxHeight=e}createTextureAttachment(t,e){const i=this._$objectPool.pop()||{width:0,height:0,color:null,texture:null,msaa:!1,stencil:null,mask:!1,clipLevel:0,isActive:!1},s=this._$textureManager.create(t,e);return i.width=t,i.height=e,i.color=s,i.texture=s,i.msaa=!1,i.stencil=null,i.mask=!1,i.clipLevel=0,i.isActive=!0,i}createTextureAttachmentFrom(t){const e=this._$objectPool.pop()||{width:0,height:0,color:null,texture:null,msaa:!1,stencil:null,mask:!1,clipLevel:0,isActive:!0};return e.width=t.width,e.height=t.height,e.color=t,e.texture=t,e.msaa=!1,e.stencil=null,e.mask=!1,e.clipLevel=0,e.isActive=!0,e}releaseAttachment(t=null,e=!1){t&&t.isActive&&(t.msaa?t.color instanceof WebGLRenderbuffer&&this._$colorBufferPool.release(t.color):t.stencil&&this._$stencilBufferPool.release(t.stencil),e&&t.texture&&this._$textureManager.release(t.texture),t.color=null,t.texture=null,t.stencil=null,t.isActive=!1,this._$objectPool.push(t))}bind(t){this._$currentAttachment=t,this._$isBinding||(this._$isBinding=!0,this._$gl.bindFramebuffer(this._$gl.FRAMEBUFFER,this._$frameBuffer)),t.msaa?t.color instanceof WebGLRenderbuffer&&(this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,t.color),this._$gl.framebufferRenderbuffer(this._$gl.FRAMEBUFFER,this._$gl.COLOR_ATTACHMENT0,this._$gl.RENDERBUFFER,t.color)):t.color instanceof WebGLTexture&&(t.color&&this._$textureManager.bind0(t.color),this._$gl.framebufferTexture2D(this._$gl.FRAMEBUFFER,this._$gl.COLOR_ATTACHMENT0,this._$gl.TEXTURE_2D,t.color,0)),this._$gl.bindRenderbuffer(this._$gl.RENDERBUFFER,t.stencil),this._$gl.framebufferRenderbuffer(this._$gl.FRAMEBUFFER,this._$gl.STENCIL_ATTACHMENT,this._$gl.RENDERBUFFER,t.stencil),this._$isRenderBinding=!1}unbind(){this._$currentAttachment=null,this._$isBinding&&(this._$isBinding=!1,this._$gl.bindFramebuffer(this._$gl.FRAMEBUFFER,null))}transferToMainTexture(){if(!this._$currentAttachment)throw new Error("the current attachment is null.");const t=this._$currentAttachment.width,e=this._$currentAttachment.height,i=this._$currentAttachment.texture;if(!i)throw new Error("the texture is null.");this._$gl.bindFramebuffer(this._$gl.DRAW_FRAMEBUFFER,this._$frameBufferTexture),this._$textureManager.bind0(i),this._$gl.framebufferTexture2D(this._$gl.FRAMEBUFFER,this._$gl.COLOR_ATTACHMENT0,this._$gl.TEXTURE_2D,i,0),this._$gl.bindFramebuffer(this._$gl.DRAW_FRAMEBUFFER,null),this._$gl.blitFramebuffer(0,0,t,e,0,0,t,e,this._$gl.COLOR_BUFFER_BIT,this._$gl.NEAREST),this._$gl.bindFramebuffer(this._$gl.DRAW_FRAMEBUFFER,this._$frameBuffer)}createCachePosition(t,e){return this._$textureManager.createCachePosition(t,e)}transferTexture(t){this._$gl.disable(this._$gl.SCISSOR_TEST),this._$gl.bindFramebuffer(this._$gl.DRAW_FRAMEBUFFER,this._$frameBufferTexture);const e=this._$textureManager.getAtlasTexture(t.index);this._$textureManager.bind0(e),this._$gl.framebufferTexture2D(this._$gl.FRAMEBUFFER,this._$gl.COLOR_ATTACHMENT0,this._$gl.TEXTURE_2D,e,0);const i=r.max(0,t.x-1),s=r.max(0,t.y-1),n=r.min(bt,t.x+t.w+1),a=r.min(bt,t.y+t.h+1);this._$gl.blitFramebuffer(i,s,n,a,i,s,n,a,this._$gl.COLOR_BUFFER_BIT,this._$gl.NEAREST),this._$gl.bindFramebuffer(this._$gl.FRAMEBUFFER,this._$frameBuffer)}getTextureFromCurrentAttachment(){if(!this._$currentAttachment)throw new Error("the current attachment is null.");if(!this._$currentAttachment.msaa&&this._$currentAttachment.texture)return this._$currentAttachment.texture;const t=this._$currentAttachment.width,e=this._$currentAttachment.height,i=this._$currentAttachment.texture;if(!i)throw new Error("the texture is null.");return i.dirty=!1,this._$gl.bindFramebuffer(this._$gl.DRAW_FRAMEBUFFER,this._$frameBufferTexture),this._$textureManager.bind0(i),this._$gl.framebufferTexture2D(this._$gl.FRAMEBUFFER,this._$gl.COLOR_ATTACHMENT0,this._$gl.TEXTURE_2D,i,0),this._$gl.blitFramebuffer(0,0,t,e,0,0,t,e,this._$gl.COLOR_BUFFER_BIT,this._$gl.NEAREST),this._$gl.bindFramebuffer(this._$gl.FRAMEBUFFER,this._$frameBuffer),i}createTextureFromPixels(t,e,i=null,s=!1,r=!0){return this._$textureManager.create(t,e,i,s,r)}createTextureFromCanvas(t){return this._$textureManager.createFromCanvas(t)}createTextureFromImage(t,e=!1){return this._$textureManager.createFromImage(t,e)}createTextureFromVideo(t,e=!1){return this._$textureManager.createFromVideo(t,e)}createTextureFromCurrentAttachment(){if(!this._$currentAttachment)throw new Error("the current attachment is null.");const t=this._$currentAttachment.width,e=this._$currentAttachment.height,i=this._$textureManager.create(t,e);return this._$textureManager.bind0(i),this._$gl.copyTexSubImage2D(this._$gl.TEXTURE_2D,0,0,0,0,0,t,e),i}releaseTexture(t){this._$textureManager.release(t)}}class yt{constructor(){this._$bezierConverterBuffer=new o(32)}cubicToQuad(t,e,i,s,r,n,a,h){this._$split2Cubic(t,e,i,s,r,n,a,h,0,16),this._$split2Cubic(this._$bezierConverterBuffer[0],this._$bezierConverterBuffer[1],this._$bezierConverterBuffer[2],this._$bezierConverterBuffer[3],this._$bezierConverterBuffer[4],this._$bezierConverterBuffer[5],this._$bezierConverterBuffer[6],this._$bezierConverterBuffer[7],0,8),this._$split2Cubic(this._$bezierConverterBuffer[16],this._$bezierConverterBuffer[17],this._$bezierConverterBuffer[18],this._$bezierConverterBuffer[19],this._$bezierConverterBuffer[20],this._$bezierConverterBuffer[21],this._$bezierConverterBuffer[22],this._$bezierConverterBuffer[23],16,24),this._$split2Quad(this._$bezierConverterBuffer[0],this._$bezierConverterBuffer[1],this._$bezierConverterBuffer[2],this._$bezierConverterBuffer[3],this._$bezierConverterBuffer[4],this._$bezierConverterBuffer[5],this._$bezierConverterBuffer[6],this._$bezierConverterBuffer[7],0),this._$split2Quad(this._$bezierConverterBuffer[8],this._$bezierConverterBuffer[9],this._$bezierConverterBuffer[10],this._$bezierConverterBuffer[11],this._$bezierConverterBuffer[12],this._$bezierConverterBuffer[13],this._$bezierConverterBuffer[14],this._$bezierConverterBuffer[15],8),this._$split2Quad(this._$bezierConverterBuffer[16],this._$bezierConverterBuffer[17],this._$bezierConverterBuffer[18],this._$bezierConverterBuffer[19],this._$bezierConverterBuffer[20],this._$bezierConverterBuffer[21],this._$bezierConverterBuffer[22],this._$bezierConverterBuffer[23],16),this._$split2Quad(this._$bezierConverterBuffer[24],this._$bezierConverterBuffer[25],this._$bezierConverterBuffer[26],this._$bezierConverterBuffer[27],this._$bezierConverterBuffer[28],this._$bezierConverterBuffer[29],this._$bezierConverterBuffer[30],this._$bezierConverterBuffer[31],24)}_$split2Cubic(t,e,i,s,r,n,a,h,o,_){const l=.125*(t+3*(i+r)+a),c=.125*(e+3*(s+n)+h),$=.125*(a+r-i-t),u=.125*(h+n-s-e);this._$bezierConverterBuffer[o]=t,this._$bezierConverterBuffer[o+1]=e,this._$bezierConverterBuffer[o+2]=.5*(t+i),this._$bezierConverterBuffer[o+3]=.5*(e+s),this._$bezierConverterBuffer[o+4]=l-$,this._$bezierConverterBuffer[o+5]=c-u,this._$bezierConverterBuffer[o+6]=l,this._$bezierConverterBuffer[o+7]=c,this._$bezierConverterBuffer[_]=l,this._$bezierConverterBuffer[_+1]=c,this._$bezierConverterBuffer[_+2]=l+$,this._$bezierConverterBuffer[_+3]=c+u,this._$bezierConverterBuffer[_+4]=.5*(r+a),this._$bezierConverterBuffer[_+5]=.5*(n+h),this._$bezierConverterBuffer[_+6]=a,this._$bezierConverterBuffer[_+7]=h}_$split2Quad(t,e,i,s,r,n,a,h,o){const _=.125*(t+3*(i+r)+a),l=.125*(e+3*(s+n)+h);this._$bezierConverterBuffer[o]=.25*t+.75*i,this._$bezierConverterBuffer[o+1]=.25*e+.75*s,this._$bezierConverterBuffer[o+2]=_,this._$bezierConverterBuffer[o+3]=l,this._$bezierConverterBuffer[o+4]=.75*r+.25*a,this._$bezierConverterBuffer[o+5]=.75*n+.25*h,this._$bezierConverterBuffer[o+6]=a,this._$bezierConverterBuffer[o+7]=h}}class Et{constructor(){this._$currentPath=U(),this._$vertices=U(),this._$bezierConverter=new yt}get vertices(){return this._$pushCurrentPathToVertices(),this._$vertices}begin(){for(this._$currentPath.length=0;this._$vertices.length;)D(this._$vertices.pop())}moveTo(t,e){this._$currentPath.length?this._$equalsToLastPoint(t,e)||(this._$pushCurrentPathToVertices(),this._$pushPointToCurrentPath(t,e,!1)):this._$pushPointToCurrentPath(t,e,!1)}lineTo(t,e){this._$currentPath.length||this.moveTo(0,0),this._$equalsToLastPoint(t,e)||this._$pushPointToCurrentPath(t,e,!1)}quadTo(t,e,i,s){this._$currentPath.length||this.moveTo(0,0),this._$equalsToLastPoint(i,s)||(this._$pushPointToCurrentPath(t,e,!0),this._$pushPointToCurrentPath(i,s,!1))}cubicTo(t,e,i,s,r,n){if(this._$currentPath.length||this.moveTo(0,0),this._$equalsToLastPoint(r,n))return;const a=+this._$currentPath[this._$currentPath.length-3],h=+this._$currentPath[this._$currentPath.length-2];this._$bezierConverter.cubicToQuad(a,h,t,e,i,s,r,n);const o=this._$bezierConverter._$bezierConverterBuffer;for(let t=0;t<32;)this.quadTo(o[t++],o[t++],o[t++],o[t++])}drawCircle(t,e,i){const s=i,r=.5522847498307936*i;this.cubicTo(t+s,e+r,t+r,e+s,t,e+s),this.cubicTo(t-r,e+s,t-s,e+r,t-s,e),this.cubicTo(t-s,e-r,t-r,e-s,t,e-s),this.cubicTo(t+r,e-s,t+s,e-r,t+s,e)}close(){if(this._$currentPath.length<=6)return;const t=+this._$currentPath[0],e=+this._$currentPath[1];this._$equalsToLastPoint(t,e)||this._$pushPointToCurrentPath(t,e,!1)}_$equalsToLastPoint(t,e){const i=+this._$currentPath[this._$currentPath.length-3],s=+this._$currentPath[this._$currentPath.length-2];return t===i&&e===s}_$pushPointToCurrentPath(t,e,i){this._$currentPath.push(t,e,i)}_$pushCurrentPathToVertices(){this._$currentPath.length<4?this._$currentPath.length=0:(this._$vertices.push(this._$currentPath),this._$currentPath=U())}createRectVertices(t,e,i,s){return U(U(t,e,!1,t+i,e,!1,t+i,e+s,!1,t,e+s,!1))}}class Ct{constructor(){this.enabled=!1,this.parentMatrixA=1,this.parentMatrixB=0,this.parentMatrixC=0,this.parentMatrixD=0,this.parentMatrixE=1,this.parentMatrixF=0,this.parentMatrixG=0,this.parentMatrixH=0,this.parentMatrixI=1,this.ancestorMatrixA=1,this.ancestorMatrixB=0,this.ancestorMatrixC=0,this.ancestorMatrixD=0,this.ancestorMatrixE=1,this.ancestorMatrixF=0,this.ancestorMatrixG=0,this.ancestorMatrixH=0,this.ancestorMatrixI=1,this.parentViewportX=0,this.parentViewportY=0,this.parentViewportW=0,this.parentViewportH=0,this.minXST=1e-5,this.minYST=1e-5,this.minXPQ=1e-5,this.minYPQ=1e-5,this.maxXST=.99999,this.maxYST=.99999,this.maxXPQ=.99999,this.maxYPQ=.99999}enable(t,e,i,s,n,a,h,o,_,l,c,$,u,d,g,f,m,p,x){const b=n.xMax-n.xMin,v=n.yMax-n.yMin,T=a.w,A=a.h,M=r.abs(r.ceil(b*h)),y=r.abs(r.ceil(v*h)),E=T>0?(a.x-n.xMin)/b:1e-5,C=A>0?(a.y-n.yMin)/v:1e-5,S=T>0?(a.x+a.w-n.xMin)/b:.99999,F=A>0?(a.y+a.h-n.yMin)/v:.99999;let B=M*E/i,w=y*C/s,R=(i-M*(1-S))/i,I=(s-y*(1-F))/s;if(B>=R){const t=E/(E+(1-S));B=r.max(t-1e-5,0),R=r.min(t+1e-5,1)}if(w>=I){const t=C/(C+(1-F));w=r.max(t-1e-5,0),I=r.min(t+1e-5,1)}this.enabled=!0,this.parentMatrixA=o,this.parentMatrixB=_,this.parentMatrixD=l,this.parentMatrixE=c,this.parentMatrixG=$,this.parentMatrixH=u,this.ancestorMatrixA=d,this.ancestorMatrixB=g,this.ancestorMatrixD=f,this.ancestorMatrixE=m,this.ancestorMatrixG=p,this.ancestorMatrixH=x,this.parentViewportX=t,this.parentViewportY=e,this.parentViewportW=i,this.parentViewportH=s,this.minXST=E,this.minYST=C,this.minXPQ=B,this.minYPQ=w,this.maxXST=S,this.maxYST=F,this.maxXPQ=R,this.maxYPQ=I}disable(){this.enabled=!1}}class St{constructor(t,e){this._$gl=t,this._$array=[],this._$map=V();const i=this._$gl.getProgramParameter(e,this._$gl.ACTIVE_UNIFORMS);for(let t=0;t0&&(t.assign--,t.method(t.array)))}}}class Ft{constructor(){this._$attributes=[],this._$count=0}get attributes(){return this._$attributes}get count(){return this._$count}set count(t){this._$count=t}clear(){this._$attributes.length=0,this._$count=0}}class Bt{constructor(t,e,i,s){this._$gl=t,this._$context=e,this._$program=this._$createProgram(i,s),this._$uniform=new St(t,this._$program),this._$instance=null}get instance(){return this._$instance||(this._$instance=new Ft),this._$instance}get uniform(){return this._$uniform}_$createProgram(t,i){const s=this._$gl.createProgram();s.id=e++;const r=this._$gl.createShader(this._$gl.VERTEX_SHADER);this._$gl.shaderSource(r,t),this._$gl.compileShader(r);const n=this._$gl.createShader(this._$gl.FRAGMENT_SHADER);return this._$gl.shaderSource(n,i),this._$gl.compileShader(n),this._$gl.attachShader(s,r),this._$gl.attachShader(s,n),this._$gl.linkProgram(s),this._$gl.detachShader(s,r),this._$gl.detachShader(s,n),this._$gl.deleteShader(r),this._$gl.deleteShader(n),s}_$attachProgram(){const t=this._$context.shaderList;t.currentProgramId!==this._$program.id&&(t.currentProgramId=this._$program.id,this._$gl.useProgram(this._$program))}drawArraysInstanced(t){this._$attachProgram(),this._$context.vao.bindInstnceArray(t),this._$gl.drawArraysInstanced(this._$gl.TRIANGLE_STRIP,0,4,t.count)}_$drawImage(){this._$attachProgram(),this._$uniform.bindUniforms(),this._$context.vao.bindCommonVertexArray(),this._$gl.drawArrays(this._$gl.TRIANGLE_STRIP,0,4)}_$drawGradient(t,e){this._$attachProgram(),this._$uniform.bindUniforms(),this._$context.vao.bindGradientVertexArray(t,e),this._$gl.drawArrays(this._$gl.TRIANGLE_STRIP,0,4)}_$stroke(t){this._$attachProgram(),this._$context.blend.reset(),this._$uniform.bindUniforms(),this._$context.vao.bind(t),this._$gl.drawElements(this._$gl.TRIANGLES,t.indexCount,this._$gl.UNSIGNED_SHORT,0)}_$fill(t){this._$attachProgram(),this._$context.blend.reset(),this._$uniform.bindUniforms(),this._$context.vao.bind(t);const e=t.indexRanges,i=e[e.length-1];this._$gl.drawArrays(this._$gl.TRIANGLES,0,i.first+i.count)}_$containerClip(t,e,i){this._$attachProgram(),this._$context.blend.reset(),this._$uniform.bindUniforms(),this._$context.vao.bind(t),this._$gl.drawArrays(this._$gl.TRIANGLES,e,i)}_$drawPoints(t,e,i){this._$attachProgram(),this._$uniform.bindUniforms(),this._$context.vao.bind(t),this._$gl.drawArrays(this._$gl.POINTS,e,i)}}class wt{static FUNCTION_GRID_OFF(){return"\\n\\nvec2 applyMatrix(in vec2 vertex) {\\n mat3 matrix = mat3(\\n u_highp[0].xyz,\\n u_highp[1].xyz,\\n u_highp[2].xyz\\n );\\n\\n vec2 position = (matrix * vec3(vertex, 1.0)).xy;\\n\\n return position;\\n}\\n\\n"}static FUNCTION_GRID_ON(t){return`\\n\\nvec2 applyMatrix(in vec2 vertex) {\\n mat3 parent_matrix = mat3(\\n u_highp[${t}].xyz,\\n u_highp[${t+1}].xyz,\\n u_highp[${t+2}].xyz\\n );\\n mat3 ancestor_matrix = mat3(\\n u_highp[${t+3}].xyz,\\n u_highp[${t+4}].xyz,\\n u_highp[${t+5}].xyz\\n );\\n vec2 parent_offset = vec2(u_highp[${t+2}].w, u_highp[${t+3}].w);\\n vec2 parent_size = vec2(u_highp[${t+4}].w, u_highp[${t+5}].w);\\n vec4 grid_min = u_highp[${t+6}];\\n vec4 grid_max = u_highp[${t+7}];\\n\\n vec2 position = (parent_matrix * vec3(vertex, 1.0)).xy;\\n position = (position - parent_offset) / parent_size;\\n\\n vec4 ga = grid_min;\\n vec4 gb = grid_max - grid_min;\\n vec4 gc = vec4(1.0) - grid_max;\\n\\n vec2 pa = position;\\n vec2 pb = position - grid_min.st;\\n vec2 pc = position - grid_max.st;\\n\\n position = (ga.pq / ga.st) * min(pa, ga.st)\\n + (gb.pq / gb.st) * clamp(pb, vec2(0.0), gb.st)\\n + (gc.pq / gc.st) * max(vec2(0.0), pc);\\n\\n position = position * parent_size + parent_offset;\\n position = (ancestor_matrix * vec3(position, 1.0)).xy;\\n\\n return position;\\n}\\n\\n`}}class Rt{static TEMPLATE(t,e,i,s){const r=e-1,n=i?this.VARYING_UV_ON():"",a=i?this.STATEMENT_UV_ON():"";return`#version 300 es\\n\\nlayout (location = 0) in vec2 a_vertex;\\nlayout (location = 1) in vec2 a_option1;\\nlayout (location = 2) in vec2 a_option2;\\nlayout (location = 3) in float a_type;\\n\\nuniform vec4 u_highp[${t}];\\n\\n${n}\\n\\n${s?wt.FUNCTION_GRID_ON(i?5:0):wt.FUNCTION_GRID_OFF()}\\n\\nfloat crossVec2(in vec2 v1, in vec2 v2) {\\n return v1.x * v2.y - v2.x * v1.y;\\n}\\n\\nvec2 perpendicularVec2(in vec2 v1) {\\n float face = u_highp[${r}][1];\\n\\n return face * vec2(v1.y, -v1.x);\\n}\\n\\nvec2 calculateNormal(in vec2 direction) {\\n vec2 normalized = normalize(direction);\\n return perpendicularVec2(normalized);\\n}\\n\\nvec2 calculateIntersection(in vec2 v1, in vec2 v2, in vec2 o1, in vec2 o2) {\\n float t = crossVec2(o2 - o1, v2) / crossVec2(v1, v2);\\n return (o1 + t * v1);\\n}\\n\\nvec2 calculateAnchor(in vec2 position, in float convex, out vec2 v1, out vec2 v2, out vec2 o1, out vec2 o2) {\\n float miter_limit = u_highp[${r}][2];\\n\\n vec2 a = applyMatrix(a_option1);\\n vec2 b = applyMatrix(a_option2);\\n\\n v1 = convex * (position - a);\\n v2 = convex * (b - position);\\n o1 = calculateNormal(v1) + a;\\n o2 = calculateNormal(v2) + position;\\n\\n vec2 anchor = calculateIntersection(v1, v2, o1, o2) - position;\\n return normalize(anchor) * min(length(anchor), miter_limit);\\n}\\n\\nvoid main() {\\n vec2 viewport = vec2(u_highp[0].w, u_highp[1].w);\\n float half_width = u_highp[${r}][0];\\n\\n vec2 position = applyMatrix(a_vertex);\\n vec2 offset = vec2(0.0);\\n vec2 v1, v2, o1, o2;\\n\\n if (a_type == 1.0 || a_type == 2.0) { // 線分\\n offset = calculateNormal(a_option2 * (applyMatrix(a_option1) - position));\\n } else if (a_type == 10.0) { // スクエア線端\\n offset = normalize(position - applyMatrix(a_option1));\\n offset += a_option2 * perpendicularVec2(offset);\\n } else if (a_type == 21.0) { // マイター結合(線分Bの凸側)\\n offset = calculateAnchor(position, 1.0, v1, v2, o1, o2);\\n offset = calculateIntersection(v2, perpendicularVec2(offset), o2, position + offset) - position;\\n } else if (a_type == 22.0) { // マイター結合(線分Aの凸側)\\n offset = calculateAnchor(position, 1.0, v1, v2, o1, o2);\\n offset = calculateIntersection(v1, perpendicularVec2(offset), o1, position + offset) - position;\\n } else if (a_type == 23.0) { // マイター結合(線分Aの凹側)\\n offset = calculateAnchor(position, -1.0, v1, v2, o1, o2);\\n offset = calculateIntersection(v1, perpendicularVec2(offset), o1, position + offset) - position;\\n } else if (a_type == 24.0) { // マイター結合(線分Bの凹側)\\n offset = calculateAnchor(position, -1.0, v1, v2, o1, o2);\\n offset = calculateIntersection(v2, perpendicularVec2(offset), o2, position + offset) - position;\\n } else if (a_type >= 30.0) { // ラウンド結合\\n float face = u_highp[${r}][1];\\n float rad = face * (a_type - 30.0) * 0.3488888889; /* 0.3488888889 = PI / 9.0 */\\n offset = mat2(cos(rad), sin(rad), -sin(rad), cos(rad)) * vec2(1.0, 0.0);\\n }\\n \\n offset *= half_width;\\n position += offset;\\n ${a}\\n\\n position /= viewport;\\n position = position * 2.0 - 1.0;\\n gl_Position = vec4(position.x, -position.y, 0.0, 1.0);\\n}\\n\\n`}static VARYING_UV_ON(){return"\\nout vec2 v_uv;\\n"}static STATEMENT_UV_ON(){return"\\n mat3 uv_matrix = mat3(\\n u_highp[0].xyz,\\n u_highp[1].xyz,\\n u_highp[2].xyz\\n );\\n mat3 inverse_matrix = mat3(\\n u_highp[3].xyz,\\n u_highp[4].xyz,\\n vec3(u_highp[2].w, u_highp[3].w, u_highp[4].w)\\n );\\n\\n v_uv = (uv_matrix * vec3(a_vertex, 1.0)).xy;\\n v_uv += offset;\\n v_uv = (inverse_matrix * vec3(v_uv, 1.0)).xy;\\n"}}class It{static TEMPLATE(t,e,i,s){const r=i?this.ATTRIBUTE_BEZIER_ON():"",n=i?this.VARYING_BEZIER_ON():e?this.VARYING_UV_ON():"",a=i?this.STATEMENT_BEZIER_ON():e?this.STATEMENT_UV_ON():"";return`#version 300 es\\n\\nlayout (location = 0) in vec2 a_vertex;\\n${r}\\n\\nuniform vec4 u_highp[${t}];\\n\\n${n}\\n\\n${s?wt.FUNCTION_GRID_ON(e?5:0):wt.FUNCTION_GRID_OFF()}\\n\\nvoid main() {\\n vec2 viewport = vec2(u_highp[0].w, u_highp[1].w);\\n\\n ${a}\\n\\n vec2 pos = applyMatrix(a_vertex) / viewport;\\n pos = pos * 2.0 - 1.0;\\n gl_Position = vec4(pos.x, -pos.y, 0.0, 1.0);\\n}\\n\\n`}static ATTRIBUTE_BEZIER_ON(){return"\\nlayout (location = 1) in vec2 a_bezier;\\n"}static VARYING_UV_ON(){return"\\nout vec2 v_uv;\\n"}static VARYING_BEZIER_ON(){return"\\nout vec2 v_bezier;\\n"}static STATEMENT_UV_ON(){return"\\n mat3 uv_matrix = mat3(\\n u_highp[0].xyz,\\n u_highp[1].xyz,\\n u_highp[2].xyz\\n );\\n mat3 inverse_matrix = mat3(\\n u_highp[3].xyz,\\n u_highp[4].xyz,\\n vec3(u_highp[2].w, u_highp[3].w, u_highp[4].w)\\n );\\n\\n v_uv = (inverse_matrix * uv_matrix * vec3(a_vertex, 1.0)).xy;\\n"}static STATEMENT_BEZIER_ON(){return"\\n v_bezier = a_bezier;\\n"}}class Pt{static FUNCTION_IS_INSIDE(){return"\\n\\nfloat isInside(in vec2 uv) {\\n return step(4.0, dot(step(vec4(0.0, uv.x, 0.0, uv.y), vec4(uv.x, 1.0, uv.y, 1.0)), vec4(1.0)));\\n}\\n\\n"}static STATEMENT_INSTANCED_COLOR_TRANSFORM_ON(){return"\\n src.rgb /= max(0.0001, src.a);\\n src = clamp(src * mul + add, 0.0, 1.0);\\n src.rgb *= src.a;\\n"}static STATEMENT_COLOR_TRANSFORM_ON(t){return`\\n vec4 mul = u_mediump[${t}];\\n vec4 add = u_mediump[${t+1}];\\n${Pt.STATEMENT_INSTANCED_COLOR_TRANSFORM_ON()}\\n`}}class Nt{static SOLID_COLOR(){return"#version 300 es\\nprecision mediump float;\\n\\nuniform vec4 u_mediump;\\n\\nout vec4 o_color;\\n\\nvoid main() {\\n o_color = vec4(u_mediump.rgb * u_mediump.a, u_mediump.a);\\n}\\n\\n"}static BITMAP_CLIPPED(){return`#version 300 es\\nprecision mediump float;\\n\\nuniform sampler2D u_texture;\\nuniform vec4 u_mediump[3];\\n\\nin vec2 v_uv;\\nout vec4 o_color;\\n\\nvoid main() {\\n vec2 uv = vec2(v_uv.x, u_mediump[0].y - v_uv.y) / u_mediump[0].xy;\\n\\n vec4 src = texture(u_texture, uv);\\n ${Pt.STATEMENT_COLOR_TRANSFORM_ON(1)}\\n o_color = src;\\n}`}static BITMAP_PATTERN(){return`#version 300 es\\nprecision mediump float;\\n\\nuniform sampler2D u_texture;\\nuniform vec4 u_mediump[3];\\n\\nin vec2 v_uv;\\nout vec4 o_color;\\n\\nvoid main() {\\n vec2 uv = fract(vec2(v_uv.x, -v_uv.y) / u_mediump[0].xy);\\n \\n vec4 src = texture(u_texture, uv);\\n ${Pt.STATEMENT_COLOR_TRANSFORM_ON(1)}\\n o_color = src;\\n}`}static MASK(){return"#version 300 es\\nprecision mediump float;\\n\\nin vec2 v_bezier;\\nout vec4 o_color;\\n\\nvoid main() {\\n vec2 px = dFdx(v_bezier);\\n vec2 py = dFdy(v_bezier);\\n\\n vec2 f = (2.0 * v_bezier.x) * vec2(px.x, py.x) - vec2(px.y, py.y);\\n float alpha = 0.5 - (v_bezier.x * v_bezier.x - v_bezier.y) / length(f);\\n\\n if (alpha > 0.0) {\\n o_color = vec4(min(alpha, 1.0));\\n } else {\\n discard;\\n } \\n}\\n\\n"}}class kt{constructor(t,e){this._$context=t,this._$gl=e,this._$collection=V()}getSolidColorShapeShader(t,e){const i=`s${t?"y":"n"}${e?"y":"n"}`;if(this._$collection.has(i)){const t=this._$collection.get(i);if(t)return t}const s=(e?8:3)+(t?1:0),r=s;let n;n=t?Rt.TEMPLATE(s,r,!1,e):It.TEMPLATE(s,!1,!1,e);const a=new Bt(this._$gl,this._$context,n,Nt.SOLID_COLOR());return this._$collection.set(i,a),a}getBitmapShapeShader(t,e,i){const s=`b${t?"y":"n"}${e?"y":"n"}${i?"y":"n"}`;if(this._$collection.has(s)){const t=this._$collection.get(s);if(t)return t}const r=(i?13:5)+(t?1:0),n=r;let a;a=t?Rt.TEMPLATE(r,n,!0,i):It.TEMPLATE(r,!0,!1,i);const h=e?Nt.BITMAP_PATTERN():Nt.BITMAP_CLIPPED(),o=new Bt(this._$gl,this._$context,a,h);return this._$collection.set(s,o),o}getMaskShapeShader(t,e){const i=`m${t?"y":"n"}${e?"y":"n"}`;if(this._$collection.has(i)){const t=this._$collection.get(i);if(t)return t}const s=(e?8:3)+(t?1:0),r=s;let n;n=t?Rt.TEMPLATE(s,r,!1,e):It.TEMPLATE(s,!1,!0,e);const a=new Bt(this._$gl,this._$context,n,Nt.MASK());return this._$collection.set(i,a),a}setSolidColorShapeUniform(t,e,i,s,r,n,a,h,o,_,l,c){const $=t.highp;let u;n?($[0]=_.parentMatrixA,$[1]=_.parentMatrixB,$[2]=_.parentMatrixC,$[4]=_.parentMatrixD,$[5]=_.parentMatrixE,$[6]=_.parentMatrixF,$[8]=_.parentMatrixG,$[9]=_.parentMatrixH,$[10]=_.parentMatrixI,$[12]=_.ancestorMatrixA,$[13]=_.ancestorMatrixB,$[14]=_.ancestorMatrixC,$[16]=_.ancestorMatrixD,$[17]=_.ancestorMatrixE,$[18]=_.ancestorMatrixF,$[20]=_.ancestorMatrixG,$[21]=_.ancestorMatrixH,$[22]=_.ancestorMatrixI,$[3]=h,$[7]=o,$[11]=_.parentViewportX,$[15]=_.parentViewportY,$[19]=_.parentViewportW,$[23]=_.parentViewportH,$[24]=_.minXST,$[25]=_.minYST,$[26]=_.minXPQ,$[27]=_.minYPQ,$[28]=_.maxXST,$[29]=_.maxYST,$[30]=_.maxXPQ,$[31]=_.maxYPQ,u=32):($[0]=a[0],$[1]=a[1],$[2]=a[2],$[4]=a[3],$[5]=a[4],$[6]=a[5],$[8]=a[6],$[9]=a[7],$[10]=a[8],$[3]=h,$[7]=o,u=12),e&&($[u]=i,$[u+1]=s,$[u+2]=r);const d=t.mediump;d[0]=l[0],d[1]=l[1],d[2]=l[2],d[3]=l[3]*c}setBitmapShapeUniform(t,e,i,s,r,n,a,h,o,_,l,c,$,u,d,g,f,m,p,x,b){const v=t.highp;let T;v[0]=a[0],v[1]=a[1],v[2]=a[2],v[4]=a[3],v[5]=a[4],v[6]=a[5],v[8]=a[6],v[9]=a[7],v[10]=a[8],v[12]=h[0],v[13]=h[1],v[14]=h[2],v[16]=h[3],v[17]=h[4],v[18]=h[5],v[11]=h[6],v[15]=h[7],v[19]=h[8],v[3]=o,v[7]=_,T=20,n&&(v[T]=l.parentMatrixA,v[T+1]=l.parentMatrixB,v[T+2]=l.parentMatrixC,v[T+4]=l.parentMatrixD,v[T+5]=l.parentMatrixE,v[T+6]=l.parentMatrixF,v[T+8]=l.parentMatrixG,v[T+9]=l.parentMatrixH,v[T+10]=l.parentMatrixI,v[T+12]=l.ancestorMatrixA,v[T+13]=l.ancestorMatrixB,v[T+14]=l.ancestorMatrixC,v[T+16]=l.ancestorMatrixD,v[T+17]=l.ancestorMatrixE,v[T+18]=l.ancestorMatrixF,v[T+20]=l.ancestorMatrixG,v[T+21]=l.ancestorMatrixH,v[T+22]=l.ancestorMatrixI,v[T+11]=l.parentViewportX,v[T+15]=l.parentViewportY,v[T+19]=l.parentViewportW,v[T+23]=l.parentViewportH,v[T+24]=l.minXST,v[T+25]=l.minYST,v[T+26]=l.minXPQ,v[T+27]=l.minYPQ,v[T+28]=l.maxXST,v[T+29]=l.maxYST,v[T+30]=l.maxXPQ,v[T+31]=l.maxYPQ,T=52),e&&(v[T]=i,v[T+1]=s,v[T+2]=r);const A=t.mediump;A[0]=c,A[1]=$,A[4]=u,A[5]=d,A[6]=g,A[7]=f,A[8]=m,A[9]=p,A[10]=x,A[11]=b}setMaskShapeUniform(t,e,i,s,r,n,a,h,o,_,l,c,$,u=null){const d=t.highp;e&&u?(d[0]=u.parentMatrixA,d[1]=u.parentMatrixB,d[2]=u.parentMatrixC,d[4]=u.parentMatrixD,d[5]=u.parentMatrixE,d[6]=u.parentMatrixF,d[8]=u.parentMatrixG,d[9]=u.parentMatrixH,d[10]=u.parentMatrixI,d[12]=u.ancestorMatrixA,d[13]=u.ancestorMatrixB,d[14]=u.ancestorMatrixC,d[16]=u.ancestorMatrixD,d[17]=u.ancestorMatrixE,d[18]=u.ancestorMatrixF,d[20]=u.ancestorMatrixG,d[21]=u.ancestorMatrixH,d[22]=u.ancestorMatrixI,d[3]=c,d[7]=$,d[11]=u.parentViewportX,d[15]=u.parentViewportY,d[19]=u.parentViewportW,d[23]=u.parentViewportH,d[24]=u.minXST,d[25]=u.minYST,d[26]=u.minXPQ,d[27]=u.minYPQ,d[28]=u.maxXST,d[29]=u.maxYST,d[30]=u.maxXPQ,d[31]=u.maxYPQ):(d[0]=i,d[1]=s,d[2]=r,d[4]=n,d[5]=a,d[6]=h,d[8]=o,d[9]=_,d[10]=l,d[3]=c,d[7]=$)}setMaskShapeUniformIdentity(t,e,i){const s=t.highp;s[0]=1,s[1]=0,s[2]=0,s[4]=0,s[5]=1,s[6]=0,s[8]=0,s[9]=0,s[10]=1,s[3]=e,s[7]=i}}class Lt{static TEMPLATE(t,e,i,s,r){const n=i?this.STATEMENT_GRADIENT_TYPE_RADIAL(e,s):this.STATEMENT_GRADIENT_TYPE_LINEAR(e);let a;switch(r){case"reflect":a="1.0 - abs(fract(t * 0.5) * 2.0 - 1.0)";break;case"repeat":a="fract(t)";break;default:a="clamp(t, 0.0, 1.0)"}return`#version 300 es\\nprecision highp float;\\n\\nuniform sampler2D u_texture;\\nuniform vec4 u_highp[${t}];\\n\\nin vec2 v_uv;\\nout vec4 o_color;\\n\\nvoid main() {\\n vec2 p = v_uv;\\n ${n}\\n t = ${a};\\n o_color = texture(u_texture, vec2(t, 0.5));\\n}\\n\\n`}static STATEMENT_GRADIENT_TYPE_LINEAR(t){return`\\n vec2 a = u_highp[${t}].xy;\\n vec2 b = u_highp[${t}].zw;\\n\\n vec2 ab = b - a;\\n vec2 ap = p - a;\\n\\n float t = dot(ab, ap) / dot(ab, ab);\\n`}static STATEMENT_GRADIENT_TYPE_RADIAL(t,e){return`\\n float radius = u_highp[${t}][0];\\n\\n vec2 coord = p / radius;\\n ${e?this.STATEMENT_FOCAL_POINT_ON(t):this.STATEMENT_FOCAL_POINT_OFF()}\\n`}static STATEMENT_FOCAL_POINT_OFF(){return"\\n float t = length(coord);\\n"}static STATEMENT_FOCAL_POINT_ON(t){return`\\n vec2 focal = vec2(u_highp[${t}][1], 0.0);\\n\\n vec2 dir = normalize(coord - focal);\\n\\n float a = dot(dir, dir);\\n float b = 2.0 * dot(dir, focal);\\n float c = dot(focal, focal) - 1.0;\\n float x = (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a);\\n\\n float t = distance(focal, coord) / distance(focal, focal + dir * x);\\n`}}class Ot{constructor(t,e){this._$context=t,this._$gl=e,this._$collection=V()}getGradientShapeShader(t,e,i,s,r){const n=this.createCollectionKey(t,e,i,s,r);if(this._$collection.has(n)){const t=this._$collection.get(n);if(t)return t}const a=(e?13:5)+(t?1:0)+1,h=a-1;let o;o=t?Rt.TEMPLATE(a,h,!0,e):It.TEMPLATE(a,!0,!1,e);const _=new Bt(this._$gl,this._$context,o,Lt.TEMPLATE(a,h,i,s,r));return this._$collection.set(n,_),_}createCollectionKey(t,e,i,s,r){const n=t?"y":"n",a=e?"y":"n",h=i?"y":"n",o=i&&s?"y":"n";let _=0;switch(r){case"reflect":_=1;break;case"repeat":_=2}return`${n}${a}${h}${o}${_}`}setGradientShapeUniform(t,e,i,s,r,n,a,h,o,_,l,c,$,u){const d=t.highp;d[0]=a[0],d[1]=a[1],d[2]=a[2],d[4]=a[3],d[5]=a[4],d[6]=a[5],d[8]=a[6],d[9]=a[7],d[10]=a[8],d[12]=h[0],d[13]=h[1],d[14]=h[2],d[16]=h[3],d[17]=h[4],d[18]=h[5],d[11]=h[6],d[15]=h[7],d[19]=h[8],d[3]=o,d[7]=_;let g=20;n&&(d[g]=l.parentMatrixA,d[g+1]=l.parentMatrixB,d[g+2]=l.parentMatrixC,d[g+4]=l.parentMatrixD,d[g+5]=l.parentMatrixE,d[g+6]=l.parentMatrixF,d[g+8]=l.parentMatrixG,d[g+9]=l.parentMatrixH,d[g+10]=l.parentMatrixI,d[g+12]=l.ancestorMatrixA,d[g+13]=l.ancestorMatrixB,d[g+14]=l.ancestorMatrixC,d[g+16]=l.ancestorMatrixD,d[g+17]=l.ancestorMatrixE,d[g+18]=l.ancestorMatrixF,d[g+20]=l.ancestorMatrixG,d[g+21]=l.ancestorMatrixH,d[g+22]=l.ancestorMatrixI,d[g+11]=l.parentViewportX,d[g+15]=l.parentViewportY,d[g+19]=l.parentViewportW,d[g+23]=l.parentViewportH,d[g+24]=l.minXST,d[g+25]=l.minYST,d[g+26]=l.minXPQ,d[g+27]=l.minYPQ,d[g+28]=l.maxXST,d[g+29]=l.maxYST,d[g+30]=l.maxXPQ,d[g+31]=l.maxYPQ,g=52),e&&(d[g]=i,d[g+1]=s,d[g+2]=r,g+=4),c?(d[g]=$[5],d[g+1]=u):(d[g]=$[0],d[g+1]=$[1],d[g+2]=$[2],d[g+3]=$[3])}}class Ut{static TEXTURE(){return"#version 300 es\\n\\nlayout (location = 0) in vec2 a_vertex;\\n\\nout vec2 v_coord;\\n\\nvoid main() {\\n v_coord = a_vertex;\\n\\n vec2 position = a_vertex * 2.0 - 1.0;\\n gl_Position = vec4(position, 0.0, 1.0);\\n}\\n\\n"}static BLEND(){return"#version 300 es\\n\\nlayout (location = 0) in vec2 a_vertex;\\n\\nuniform vec4 u_highp[4];\\n\\nout vec2 v_coord;\\n\\nvoid main() {\\n v_coord = a_vertex;\\n\\n vec2 offset = u_highp[0].xy;\\n vec2 size = u_highp[0].zw;\\n mat3 matrix = mat3(u_highp[1].xyz, u_highp[2].xyz, u_highp[3].xyz);\\n vec2 viewport = vec2(u_highp[1].w, u_highp[2].w);\\n\\n vec2 position = vec2(a_vertex.x, 1.0 - a_vertex.y);\\n position = position * size + offset;\\n position = (matrix * vec3(position, 1.0)).xy;\\n position /= viewport;\\n\\n position = position * 2.0 - 1.0;\\n gl_Position = vec4(position.x, -position.y, 0.0, 1.0);\\n}\\n\\n"}static INSTANCE_BLEND(){return"#version 300 es\\n\\nlayout (location = 0) in vec2 a_vertex;\\n\\nuniform vec4 u_highp[5];\\n\\nout vec2 v_src_coord;\\nout vec2 v_dst_coord;\\n\\nvoid main() {\\n vec4 rect = vec4(u_highp[0].x, u_highp[0].y, u_highp[0].z, u_highp[0].w);\\n vec2 size = vec2(u_highp[4].x, u_highp[4].y);\\n mat3 matrix = mat3(u_highp[1].xyz, u_highp[2].xyz, u_highp[3].xyz);\\n vec2 viewport = vec2(u_highp[1].w, u_highp[2].w);\\n\\n v_src_coord = a_vertex * rect.zw + rect.xy;\\n v_dst_coord = a_vertex;\\n\\n vec2 position = vec2(a_vertex.x, 1.0 - a_vertex.y);\\n position = position * size;\\n position = (matrix * vec3(position, 1.0)).xy;\\n position /= viewport;\\n\\n position = position * 2.0 - 1.0;\\n gl_Position = vec4(position.x, -position.y, 0.0, 1.0);\\n}\\n\\n"}static INSTANCE(){return"#version 300 es\\n\\nlayout (location = 0) in vec2 a_vertex;\\nlayout (location = 1) in vec4 a_rect;\\nlayout (location = 2) in vec4 a_size;\\nlayout (location = 3) in vec2 a_offset;\\nlayout (location = 4) in vec4 a_matrix;\\nlayout (location = 5) in vec4 a_mul;\\nlayout (location = 6) in vec4 a_add;\\n\\nout vec2 v_coord;\\nout vec4 mul;\\nout vec4 add;\\n\\nvoid main() {\\n v_coord = a_vertex * a_rect.zw + a_rect.xy;\\n mul = a_mul;\\n add = a_add;\\n\\n vec2 position = vec2(a_vertex.x, 1.0 - a_vertex.y);\\n position = position * a_size.xy;\\n mat3 matrix = mat3(a_matrix.x, a_matrix.y, 0.0, a_matrix.z, a_matrix.w, 0.0, a_offset.x, a_offset.y, 1.0);\\n position = (matrix * vec3(position, 1.0)).xy;\\n position /= a_size.zw;\\n\\n position = position * 2.0 - 1.0;\\n gl_Position = vec4(position.x, -position.y, 0.0, 1.0);\\n}\\n\\n"}static BLEND_CLIP(){return"#version 300 es\\n\\nlayout (location = 0) in vec2 a_vertex;\\n\\nuniform vec4 u_highp[4];\\n\\nout vec2 v_coord;\\n\\nvoid main() {\\n v_coord = a_vertex;\\n\\n vec2 offset = u_highp[0].xy;\\n vec2 size = u_highp[0].zw;\\n mat3 inv_matrix = mat3(u_highp[1].xyz, u_highp[2].xyz, u_highp[3].xyz);\\n vec2 viewport = vec2(u_highp[1].w, u_highp[2].w);\\n\\n vec2 position = vec2(a_vertex.x, 1.0 - a_vertex.y);\\n position *= viewport;\\n position = (inv_matrix * vec3(position, 1.0)).xy;\\n position = (position - offset) / size;\\n\\n position = position * 2.0 - 1.0;\\n gl_Position = vec4(position.x, -position.y, 0.0, 1.0);\\n}\\n\\n"}}class Dt{static TEMPLATE(t,e,i){let s="";for(let t=1;t>16)/255,h[a++]=(e>>8&255)/255,h[a++]=(255&e)/255,h[a++]=s[t]}for(let t=r;tthis._$vertexBufferData.length){const t=new o(2*this._$vertexBufferData.length);t.set(this._$vertexBufferData),this._$vertexBufferData=t}}static _$expandIndexBufferIfNeeded(t){if(this._$indexBufferPos+t>this._$indexBufferData.length){const t=new l(2*this._$indexBufferData.length);t.set(this._$indexBufferData),this._$indexBufferData=t}}static _$generateLineSegment(t){const e=t.length-5;for(let i=0;it*s-i*e;class ee{constructor(t){this._$gl=t,this._$fillVertexArrayPool=[],this._$strokeVertexArrayPool=[],this._$boundVertexArray=null,this._$fillAttrib_vertex=0,this._$fillAttrib_bezier=1,this._$strokeAttrib_vertex=0,this._$strokeAttrib_option1=1,this._$strokeAttrib_option2=2,this._$strokeAttrib_type=3,this._$vertexBufferData=new Float32Array([0,0,0,1,1,0,1,1]),this._$attributeVertexBuffer=t.createBuffer(),this._$attributeBuffer=new Float32Array(22),this._$instanceVertexArray=this._$getCommonVertexArray(),this._$commonVertexArray=this._$getVertexArray(0,1)}_$getCommonVertexArray(){const t=this._$gl.createVertexArray();this.bind(t);const e=this._$gl.createBuffer();return this._$gl.bindBuffer(this._$gl.ARRAY_BUFFER,e),this._$gl.bufferData(this._$gl.ARRAY_BUFFER,new Float32Array([0,0,0,1,1,0,1,1]),this._$gl.STATIC_DRAW),this._$gl.enableVertexAttribArray(0),this._$gl.vertexAttribPointer(0,2,this._$gl.FLOAT,!1,0,0),this._$gl.bindBuffer(this._$gl.ARRAY_BUFFER,this._$attributeVertexBuffer),this._$gl.bufferData(this._$gl.ARRAY_BUFFER,this._$attributeBuffer.byteLength,this._$gl.DYNAMIC_DRAW),this._$gl.enableVertexAttribArray(1),this._$gl.vertexAttribPointer(1,4,this._$gl.FLOAT,!1,88,0),this._$gl.vertexAttribDivisor(1,1),this._$gl.enableVertexAttribArray(2),this._$gl.vertexAttribPointer(2,4,this._$gl.FLOAT,!1,88,16),this._$gl.vertexAttribDivisor(2,1),this._$gl.enableVertexAttribArray(3),this._$gl.vertexAttribPointer(3,2,this._$gl.FLOAT,!1,88,32),this._$gl.vertexAttribDivisor(3,1),this._$gl.enableVertexAttribArray(4),this._$gl.vertexAttribPointer(4,4,this._$gl.FLOAT,!1,88,40),this._$gl.vertexAttribDivisor(4,1),this._$gl.enableVertexAttribArray(5),this._$gl.vertexAttribPointer(5,4,this._$gl.FLOAT,!1,88,56),this._$gl.vertexAttribDivisor(5,1),this._$gl.enableVertexAttribArray(6),this._$gl.vertexAttribPointer(6,4,this._$gl.FLOAT,!1,88,72),this._$gl.vertexAttribDivisor(6,1),t}_$getVertexArray(t,e){const i=this._$gl.createVertexArray();this.bind(i);const s=this._$gl.createBuffer();return this._$gl.bindBuffer(this._$gl.ARRAY_BUFFER,s),this._$vertexBufferData[0]=t,this._$vertexBufferData[2]=t,this._$vertexBufferData[4]=e,this._$vertexBufferData[6]=e,this._$gl.bufferData(this._$gl.ARRAY_BUFFER,this._$vertexBufferData,this._$gl.STATIC_DRAW),this._$gl.enableVertexAttribArray(0),this._$gl.vertexAttribPointer(0,2,this._$gl.FLOAT,!1,0,0),i}_$getFillVertexArray(){if(this._$fillVertexArrayPool.length){const t=this._$fillVertexArrayPool.pop();if(t)return t}const t=this._$gl.createVertexArray();this.bind(t);const e=this._$gl.createBuffer();return t.vertexBuffer=e,t.vertexLength=0,this._$gl.bindBuffer(this._$gl.ARRAY_BUFFER,e),this._$gl.enableVertexAttribArray(0),this._$gl.enableVertexAttribArray(1),this._$gl.vertexAttribPointer(this._$fillAttrib_vertex,2,this._$gl.FLOAT,!1,16,0),this._$gl.vertexAttribPointer(this._$fillAttrib_bezier,2,this._$gl.FLOAT,!1,16,8),t}_$getStrokeVertexArray(){if(this._$strokeVertexArrayPool.length){const t=this._$strokeVertexArrayPool.pop();if(t)return t}const t=this._$gl.createVertexArray();this.bind(t);const e=this._$gl.createBuffer();t.vertexBuffer=e,t.vertexLength=0,this._$gl.bindBuffer(this._$gl.ARRAY_BUFFER,e);const i=this._$gl.createBuffer();return t.indexBuffer=i,t.indexLength=0,this._$gl.bindBuffer(this._$gl.ELEMENT_ARRAY_BUFFER,i),this._$gl.enableVertexAttribArray(0),this._$gl.enableVertexAttribArray(1),this._$gl.enableVertexAttribArray(2),this._$gl.enableVertexAttribArray(3),this._$gl.vertexAttribPointer(this._$strokeAttrib_vertex,2,this._$gl.FLOAT,!1,28,0),this._$gl.vertexAttribPointer(this._$strokeAttrib_option1,2,this._$gl.FLOAT,!1,28,8),this._$gl.vertexAttribPointer(this._$strokeAttrib_option2,2,this._$gl.FLOAT,!1,28,16),this._$gl.vertexAttribPointer(this._$strokeAttrib_type,1,this._$gl.FLOAT,!1,28,24),t}createFill(t){const e=Zt.generate(t),i=e.vertexBufferData,s=this._$getFillVertexArray();return s.indexRanges=e.indexRanges,this.bind(s),this._$gl.bindBuffer(this._$gl.ARRAY_BUFFER,s.vertexBuffer),s.vertexLengththis._$attributeBuffer.length&&(this._$attributeBuffer=new Float32Array(t.attributes.length),this._$gl.bufferData(this._$gl.ARRAY_BUFFER,this._$attributeBuffer.byteLength,this._$gl.DYNAMIC_DRAW)),this._$attributeBuffer.set(t.attributes),this._$gl.bufferSubData(this._$gl.ARRAY_BUFFER,0,this._$attributeBuffer.subarray(0,t.attributes.length))}bindCommonVertexArray(){this.bind(this._$commonVertexArray)}bindGradientVertexArray(t,e){const i=this._$getVertexArray(t,e);this.bind(i)}}class ie{constructor(t,e){this._$context=t,this._$gl=e,this._$clips=[],this._$poolClip=[],this._$clipStatus=!1,this._$containerClip=!1,this._$currentClip=!1}get containerClip(){return this._$containerClip}set containerClip(t){this._$containerClip=t}_$onClear(t){t&&(this._$gl.enable(this._$gl.STENCIL_TEST),this._$currentClip=!0)}_$onBind(t){!t&&this._$currentClip?(this._$gl.disable(this._$gl.STENCIL_TEST),this._$currentClip=!1):t&&!this._$currentClip&&(this._$gl.enable(this._$gl.STENCIL_TEST),this._$currentClip=!0,this._$endClipDef())}_$onClearRect(){this._$gl.disable(this._$gl.STENCIL_TEST),this._$currentClip=!1}_$enterClip(){this._$currentClip||(this._$gl.enable(this._$gl.STENCIL_TEST),this._$currentClip=!0);const t=this._$context.frameBuffer.currentAttachment;if(!t)throw new Error("mask currentAttachment is null.");t.mask=!0,++t.clipLevel}_$beginClipDef(){const t=this._$context.frameBuffer.currentAttachment;if(!t)throw new Error("mask currentAttachment is null.");this._$gl.enable(this._$gl.SAMPLE_ALPHA_TO_COVERAGE),this._$gl.stencilFunc(this._$gl.ALWAYS,0,255),this._$gl.stencilOp(this._$gl.KEEP,this._$gl.INVERT,this._$gl.INVERT),this._$gl.stencilMask(1<7&&(this._$unionStencilMask(e,a,h),n=e)}n>e+1&&this._$unionStencilMask(e,a,h)}_$unionStencilMask(t,e,i){const s=this._$context.path.createRectVertices(0,0,e,i),r=this._$context.vao.createFill(s);D(s.pop()),D(s);const n=this._$context.shaderList.shapeShaderVariants,a=n.getMaskShapeShader(!1,!1),h=a.uniform;n.setMaskShapeUniformIdentity(h,e,i);const o=r.indexRanges[0];this._$gl.stencilFunc(this._$gl.LEQUAL,1<this._$maxTextureSize?this._$maxTextureSize/i:1}drawInstacedArray(){this.blend.drawInstacedArray()}clearInstacedArray(){this.blend.clearInstacedArray()}bindRenderBuffer(t){this._$frameBufferManager.bindRenderBuffer(),this._$gl.clearColor(0,0,0,0),this._$gl.clear(this._$gl.COLOR_BUFFER_BIT|this._$gl.STENCIL_BUFFER_BIT),this._$viewportWidth=t.w,this._$viewportHeight=t.h,this._$gl.viewport(t.x,t.y,t.w,t.h),this._$gl.enable(this._$gl.SCISSOR_TEST),this._$gl.scissor(t.x,t.y,t.w,t.h)}getTextureFromRect(t){const e=this._$frameBufferManager,i=e.textureManager.getAtlasTexture(t.index),s=e.currentAttachment,r=e.createTextureAttachment(t.w,t.h);this._$bind(r),this.save(),this.setTransform(1,0,0,1,0,0),this.reset(),this.drawImage(i,-t.x,-i.height+t.h+t.y,i.width,i.height),this.restore();const n=r.texture;return e.releaseAttachment(r),this._$bind(s),n}drawBitmap(t){const e=this._$shaderList.blendShaderVariants,i=e.getNormalBlendShader(!1);e.setNormalBlendUniform(i.uniform,0,0,t.width,t.height,this._$matrix,this._$viewportWidth,this._$viewportHeight,!1,1,1,1,1,0,0,0,0),this._$frameBufferManager.textureManager.bind0(t,this._$imageSmoothingEnabled),this.blend.toOperation("normal"),i._$drawImage()}drawTextureFromRect(t,e){const i=this._$frameBufferManager,s=i.currentAttachment;this.bindRenderBuffer(e),i.transferTexture(e);const r=i.textureManager.getAtlasTexture(e.index),n=i.createTextureAttachmentFrom(r);this._$bind(n),this._$gl.enable(this._$gl.SCISSOR_TEST),this._$gl.scissor(e.x,e.y,e.w,e.h),this._$gl.clearColor(0,0,0,0),this._$gl.disable(this._$gl.SCISSOR_TEST),this.save(),this.setTransform(1,0,0,1,0,0),this.reset(),this.drawImage(t,e.x,r.height-e.h-e.y,t.width,t.height),this.restore(),i.releaseAttachment(n),this._$bind(s),i.textureManager.release(t)}stopStencil(){this._$mask._$onClearRect()}_$bind(t=null){if(!t)return;this._$frameBufferManager.bind(t);const e=t.color,i=t.stencil,s=t.width,r=t.height;this._$viewportWidth===s&&this._$viewportHeight===r||(this._$viewportWidth=s,this._$viewportHeight=r,this._$gl.viewport(0,0,s,r)),(e&&e.dirty||i&&i.dirty)&&(e&&(e.dirty=!1),i&&(i.dirty=!1),this._$gl.clearColor(0,0,0,0),this.clearRect(0,0,this._$viewportWidth,this._$viewportHeight),this._$gl.clearColor(this._$clearColorR,this._$clearColorG,this._$clearColorB,this._$clearColorA),this._$mask._$onClear(t.mask)),this._$mask._$onBind(t.mask)}setTransform(t,e,i,s,r,n){this._$matrix[0]=t,this._$matrix[1]=e,this._$matrix[3]=i,this._$matrix[4]=s,this._$matrix[6]=r,this._$matrix[7]=n}setMaxSize(t,e){this._$frameBufferManager.setMaxSize(t,e)}transform(t,e,i,s,r,n){const a=this._$matrix[0],h=this._$matrix[1],o=this._$matrix[3],_=this._$matrix[4],l=this._$matrix[6],c=this._$matrix[7];this._$matrix[0]=t*a+e*o,this._$matrix[1]=t*h+e*_,this._$matrix[3]=i*a+s*o,this._$matrix[4]=i*h+s*_,this._$matrix[6]=r*a+n*o+l,this._$matrix[7]=r*h+n*_+c}debug(t=0){const e=this._$frameBufferManager,i=e.textureManager.getAtlasTexture(t),s=e.currentAttachment,r=e.createTextureAttachmentFrom(i);this._$bind(r);const n=new Uint8Array(i.width*i.height*4);this._$gl.readPixels(0,0,i.width,i.height,this._$gl.RGBA,this._$gl.UNSIGNED_BYTE,n);const a=document.createElement("canvas");a.width=i.width,a.height=i.height;const h=a.getContext("2d"),o=new ImageData(i.width,i.height);for(let t=0;ts.length||e.push(s)}if(!e.length)return void D(e);const i=this._$vao.createFill(e),s=this.fillStyle;let r,n,a,h=this._$matrix;const o=this._$grid.enabled;if(s instanceof mt){const t=s.stops,e="linearRGB"===s.rgb;if(r=this._$gradientLUT.generateForShape(t,e),this._$frameBufferManager.textureManager.bind0(r,!0),this._$frameBufferManager.bindRenderBuffer(),n=this._$shaderList.gradientShapeShaderVariants,"linear"===s.type)a=n.getGradientShapeShader(!1,o,!1,!1,s.mode),n.setGradientShapeUniform(a.uniform,!1,0,0,0,o,h,z(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,!1,s.points,0);else{h=this._$stack[this._$stack.length-1];const t=0!==s.focalPointRatio;a=n.getGradientShapeShader(!1,o,!0,t,s.mode),n.setGradientShapeUniform(a.uniform,!1,0,0,0,o,h,z(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,!0,s.points,s.focalPointRatio)}}else if(s instanceof pt){h=this._$stack[this._$stack.length-1];const t=s.colorTransform;r=s.texture,this._$frameBufferManager.textureManager.bind0(r,this._$imageSmoothingEnabled),n=this._$shaderList.shapeShaderVariants,a=n.getBitmapShapeShader(!1,s.repeat,o),t?n.setBitmapShapeUniform(a.uniform,!1,0,0,0,o,h,z(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,r.width,r.height,t[0],t[1],t[2],this._$globalAlpha,t[4]/255,t[5]/255,t[6]/255,0):n.setBitmapShapeUniform(a.uniform,!1,0,0,0,o,h,z(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,r.width,r.height,1,1,1,this._$globalAlpha,0,0,0,0)}else n=this._$shaderList.shapeShaderVariants,a=n.getSolidColorShapeShader(!1,this._$grid.enabled),n.setSolidColorShapeUniform(a.uniform,!1,0,0,0,o,h,this._$viewportWidth,this._$viewportHeight,this._$grid,s,this._$globalAlpha);const _=this._$shaderList.shapeShaderVariants,l=_.getMaskShapeShader(!1,o);_.setMaskShapeUniform(l.uniform,o,h[0],h[1],h[2],h[3],h[4],h[5],h[6],h[7],h[8],this._$viewportWidth,this._$viewportHeight,this._$grid),this._$gl.enable(this._$gl.STENCIL_TEST),this._$gl.stencilMask(255),this._$gl.enable(this._$gl.SAMPLE_ALPHA_TO_COVERAGE),this._$gl.stencilFunc(this._$gl.ALWAYS,0,255),this._$gl.stencilOp(this._$gl.KEEP,this._$gl.INVERT,this._$gl.INVERT),this._$gl.colorMask(!1,!1,!1,!1),l._$fill(i),this._$gl.disable(this._$gl.SAMPLE_ALPHA_TO_COVERAGE),this._$gl.stencilFunc(this._$gl.NOTEQUAL,0,255),this._$gl.stencilOp(this._$gl.KEEP,this._$gl.ZERO,this._$gl.ZERO),this._$gl.colorMask(!0,!0,!0,!0),a._$fill(i),this._$gl.disable(this._$gl.STENCIL_TEST),this.releaseFillVertexArray(i)}releaseFillVertexArray(t){this._$vao.releaseFill(t);const e=t.indexRanges;for(let t=0;ta.width||i>a.height||0>e&&0>=s+e||0>i&&0>=n+i||(this._$maskBounds.xMin=r.max(0,r.min(this._$maskBounds.xMin,e)),this._$maskBounds.yMin=r.max(0,r.min(this._$maskBounds.yMin,i)),this._$maskBounds.xMax=r.min(a.width,r.min(this._$maskBounds.xMax,s)),this._$maskBounds.yMax=r.min(a.height,r.min(this._$maskBounds.yMax,n)),0))}_$endClipDef(){this._$mask._$endClipDef()}_$leaveClip(){this.drawInstacedArray(),this._$mask._$leaveClip()}_$drawContainerClip(){this._$mask._$drawContainerClip()}closePath(){this._$path.close()}stroke(){const t=this._$path.vertices;if(!t.length)return;const e=U();for(let i=0;is.length||e.push(s)}if(!e.length)return void D(e);const i=this._$vao.createStroke(t,this.lineCap,this.lineJoin);let s=this._$matrix;const n=this.strokeStyle;let a=r.sign(s[0]*s[4]);a>0&&0!==s[1]&&0!==s[3]&&(a=-r.sign(s[1]*s[3]));let h,o,_=.5*this.lineWidth;this._$grid.enabled?(h=r.abs(this._$grid.ancestorMatrixA+this._$grid.ancestorMatrixD),o=r.abs(this._$grid.ancestorMatrixB+this._$grid.ancestorMatrixE)):(h=r.abs(s[0]+s[3]),o=r.abs(s[1]+s[4]));const l=r.min(h,o),c=r.max(h,o);_*=c*(1-.3*r.cos(.5*r.PI*(l/c))),_=r.max(1,_);const $=this._$grid.enabled;let u,d,g;if(n instanceof mt){"radial"===n.type&&(s=this._$stack[this._$stack.length-1]);const t=n.stops,e="linearRGB"===n.rgb;if(u=this._$gradientLUT.generateForShape(t,e),this._$frameBufferManager.textureManager.bind0(u,!0),d=this._$shaderList.gradientShapeShaderVariants,"linear"===n.type)g=d.getGradientShapeShader(!0,$,!1,!1,n.mode),d.setGradientShapeUniform(g.uniform,!0,_,a,this.miterLimit,$,s,z(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,!1,n.points,0);else{s=this._$stack[this._$stack.length-1];const t=0!==n.focalPointRatio;g=d.getGradientShapeShader(!0,$,!0,t,n.mode),d.setGradientShapeUniform(g.uniform,!0,_,a,this.miterLimit,$,s,z(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,!0,n.points,n.focalPointRatio)}}else if(n instanceof pt){s=this._$stack[this._$stack.length-1];const t=n.colorTransform;u=n.texture,this._$frameBufferManager.textureManager.bind0(u),d=this._$shaderList.shapeShaderVariants,g=d.getBitmapShapeShader(!0,n.repeat,this._$grid.enabled),t?d.setBitmapShapeUniform(g.uniform,!0,_,a,this.miterLimit,$,s,z(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,u.width,u.height,t[0],t[1],t[2],this._$globalAlpha,t[4]/255,t[5]/255,t[6]/255,0):d.setBitmapShapeUniform(g.uniform,!0,_,a,this.miterLimit,$,s,z(this._$matrix),this._$viewportWidth,this._$viewportHeight,this._$grid,u.width,u.height,1,1,1,this._$globalAlpha,0,0,0,0)}else d=this._$shaderList.shapeShaderVariants,g=d.getSolidColorShapeShader(!0,this._$grid.enabled),d.setSolidColorShapeUniform(g.uniform,!0,_,a,this.miterLimit,$,s,this._$viewportWidth,this._$viewportHeight,this._$grid,n,this._$globalAlpha);g._$stroke(i),this._$vao.releaseStroke(i)}arc(t,e,i){this._$path.drawCircle(t,e,i)}clip(){const t=this._$path.vertices;if(!t.length)return;const e=U();for(let i=0;is.length||e.push(s)}if(!e.length)return void D(e);const i=this._$vao.createFill(e),s=this._$shaderList.shapeShaderVariants,r=s.getMaskShapeShader(!1,!1),n=r.uniform;s.setMaskShapeUniform(n,!1,this._$matrix[0],this._$matrix[1],this._$matrix[2],this._$matrix[3],this._$matrix[4],this._$matrix[5],this._$matrix[6],this._$matrix[7],this._$matrix[8],this._$viewportWidth,this._$viewportHeight,null),this._$mask._$onClip(i,this._$matrix,this._$viewportWidth,this._$viewportHeight)||(r._$fill(i),this.beginPath())}save(){const t=this._$matrix;this._$stack.push(O(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])),this._$mask._$onSave()}restore(){var t;this._$stack.length&&(t=this._$matrix,M.push(t),this._$matrix=this._$stack.pop()||O()),this._$mask._$onRestore()}createPattern(t,e,i){return new pt(t,e,i)}createLinearGradient(t,e,i,s,r="rgb",n="pad"){return(new mt).linear(t,e,i,s,r,n)}createRadialGradient(t,e,i,s,r,n,a="rgb",h="pad",o=0){return(new mt).radial(t,e,i,s,r,n,a,h,o)}_$applyBlurFilter(t,e,i){const s=this._$frameBufferManager,n=s.currentAttachment;if(!n)throw new Error("the current attachment is null.");const a=n.width,h=n.height;s.textureManager.bind0(t,!0);const o=r.ceil(.5*i),_=1-(o-.5*i),l=1+i,c=this._$shaderList.filterShaderVariants,$=c.getBlurFilterShader(o);c.setBlurFilterUniform($.uniform,a,h,e,_,l),$._$drawImage()}_$applyBitmapFilter(t,e,i,s,r,n,a,h,o,_,l,c,$,u,d,g=null,f=null,m=null,p=0,x=0,b=0,v=0,T=0,A=0,M=0,y=0){const E=this._$frameBufferManager,C="inner"===$,S=E.currentAttachment,F=E.getTextureFromCurrentAttachment();let B=null;const w=null!==g&&null!==f&&null!==m;let R;null!==g&&null!==f&&null!==m&&(B=this._$gradientLUT.generateForFilter(g,f,m)),C?w&&B?E.textureManager.bind02(t,B,!0):E.textureManager.bind0(t):(R=this._$frameBufferManager.createTextureAttachment(e,i),this._$bind(R),w&&B?E.textureManager.bind012(t,F,B,!0):E.textureManager.bind01(t,F));const I=!(C||"full"===$&&u),P=!(e===h&&i===o&&0===_&&0===l),N=!(1===d),k=this._$shaderList.filterShaderVariants,L=k.getBitmapFilterShader(I,P,c,$,u,N,w);k.setBitmapFilterUniform(L.uniform,e,i,s,r,n,a,h,o,_,l,c,d,p,x,b,v,T,A,M,y,I,P,N,w),C?u?this.blend.toSourceIn():this.blend.toSourceAtop():this.blend.toOneZero(),L._$drawImage(),C||E.releaseAttachment(S,!0)}_$applyColorMatrixFilter(t,e){this._$frameBufferManager.textureManager.bind0(t,!0);const i=this._$shaderList.filterShaderVariants,s=i.getColorMatrixFilterShader();i.setColorMatrixFilterUniform(s.uniform,e),this.blend.reset(),s._$drawImage()}_$applyConvolutionFilter(t,e,i,s,r,n,a,h,o,_,l,c){const $=t.width,u=t.height,d=this._$frameBufferManager.createTextureAttachment($,u);this._$bind(d),this._$frameBufferManager.textureManager.bind0(t,!0);const g=this._$shaderList.filterShaderVariants,f=g.getConvolutionFilterShader(e,i,a,h);g.setConvolutionFilterUniform(f.uniform,$,u,s,r,n,h,o,_,l,c),this.blend.reset(),f._$drawImage()}_$applyDisplacementMapFilter(t,e,i,s,r,n,a,h,o,_,l,c,$,u){const d=t.width,g=t.height,f=this._$frameBufferManager.createTextureAttachment(d,g);this._$bind(f),r||(r={x:0,y:0});const m=this._$frameBufferManager.createTextureFromImage(e);this._$frameBufferManager.textureManager.bind01(t,m);const p=this._$shaderList.filterShaderVariants,x=p.getDisplacementMapFilterShader(n,a,_);p.setDisplacementMapFilterUniform(x.uniform,e.width,e.height,i,s,r.x,r.y,h,o,_,l,c,$,u),this.blend.reset(),x._$drawImage(),this._$frameBufferManager.releaseTexture(m)}_$startLayer(t){this._$positions.push(t),this._$blends.push(this._$isLayer),this._$isLayer=!0}_$endLayer(){const t=this._$positions.pop();t&&B(t),this._$isLayer=!!this._$blends.pop()}_$saveAttachment(t,e,i=!1){this.drawInstacedArray();const s=this._$frameBufferManager;this._$attachmentArray.push(s.currentAttachment),this._$bind(s.createCacheAttachment(t,e,i))}_$restoreAttachment(t=!1){const e=this._$frameBufferManager;e.releaseAttachment(e.currentAttachment,t),this._$bind(this._$attachmentArray.pop())}getCurrentPosition(){return this._$positions[this._$positions.length-1]}textureScale(t,e){const i=r.max(t,e);return i>this._$maxTextureSize?this._$maxTextureSize/i:1}}class ne extends gt{constructor(){super(),this._$recodes=null,this._$maxAlpha=0,this._$canDraw=!1,this._$uniqueKey="",this._$cacheKeys=U(),this._$cacheParams=U(0,0,0),this._$bitmapId=0,this._$mode="shape"}_$clip(t,e){if(!this._$recodes)return;const i=this._$getBounds(),n=q(i,e);B(i);const a=r.ceil(r.abs(n.xMax-n.xMin)),h=r.ceil(r.abs(n.yMax-n.yMin));switch(B(n),!0){case 0===a:case 0===h:case a===-1/0:case h===-1/0:case a===s:case h===s:return}t.reset(),t.setTransform(e[0],e[1],e[2],e[3],e[4],e[5]),this._$runCommand(t,this._$recodes,null,!0),t.clip()}_$createCacheKey(){if(!this._$recodes)return"";let t=0;for(let e=0;e0&&this._$canApply(a);let T=F(0,m,0,p);if(v&&a)for(let t=0;tM.width||f-T.yMin>M.height)return void B(T);if(0>d+T.xMax||0>f+T.yMax)return void B(T);if(B(T),""===this._$uniqueKey&&(!l&&this._$loaderInfoId>-1&&this._$characterId>-1?this._$uniqueKey=`${this._$loaderInfoId}@${this._$characterId}`:this._$uniqueKey=this._$createCacheKey()),"bitmap"===this._$mode)this._$cacheKeys.length||(this._$cacheKeys=rt.generateKeys(this._$uniqueKey));else if(!this._$cacheKeys.length||this._$cacheParams[0]!==x||this._$cacheParams[1]!==b||this._$cacheParams[2]!==i[7]){const t=U();t[0]=x,t[1]=b,this._$cacheKeys=rt.generateKeys(this._$uniqueKey,t,i),D(t),this._$cacheParams[0]=x,this._$cacheParams[1]=b,this._$cacheParams[2]=i[7]}if(t.cachePosition=rt.get(this._$cacheKeys),!t.cachePosition){const s=A.currentAttachment;s&&s.mask&&t.stopStencil();let n=0,a=0;if("shape"===this._$mode){n=r.ceil(r.abs(c.xMax-c.xMin)*x),a=r.ceil(r.abs(c.yMax-c.yMin)*b);const e=t._$getTextureScale(n,a);e<1&&(n*=e,a*=e)}else n=r.ceil(r.abs(c.xMax-c.xMin)),a=r.ceil(r.abs(c.yMax-c.yMin));if(t.cachePosition=A.createCachePosition(n,a),t.bindRenderBuffer(t.cachePosition),t.reset(),"shape"===this._$mode?t.setTransform(x,0,0,b,-c.xMin*x,-c.yMin*b):t.setTransform(1,0,0,1,-c.xMin,-c.yMin),l){const i=le.scaleX,s=P(i,0,0,i,0,0),n=H(s,_);N(s);const a=this._$matrixBase,h=P(a[0],a[1],a[2],a[3],a[4]*i-d,a[5]*i-f),o=H(h,n),l=o[4]-(e[4]-d),$=o[5]-(e[5]-f);N(o);const u=q(c,n),g=+u.xMax,m=+u.xMin,p=+u.yMax,x=+u.yMin,b=r.ceil(r.abs(g-m)),v=r.ceil(r.abs(p-x));B(u),t.grid.enable(m,x,b,v,c,this._$scale9Grid,i,n[0],n[1],n[2],n[3],n[4],n[5],h[0],h[1],h[2],h[3],h[4]-l,h[5]-$),N(n),N(h)}this._$runCommand(t,this._$recodes,i,!1),l&&t.grid.disable(),A.transferTexture(t.cachePosition),rt.set(this._$cacheKeys,t.cachePosition),t._$bind(s)}let y=0,E=0;if(v&&a){const i=this._$createBitmapTexture(t,t.cachePosition,x,b,m,p),s=this._$drawFilter(t,e,a,m,p,i);s.offsetX&&(y=s.offsetX),s.offsetY&&(E=s.offsetY),t.cachePosition=s}if(v||"bitmap"!==this._$mode){const i=r.atan2(e[1],e[0]),s=r.atan2(-e[2],e[3]);if(v||!i&&!s)t.setTransform(1,0,0,1,d-y,f-E);else{const n=c.xMin*x,a=c.yMin*b,h=r.cos(i),o=r.sin(i),_=r.cos(s),l=r.sin(s);t.setTransform(h,o,-l,_,n*h-a*l+e[4],n*o+a*_+e[5])}}else t.setTransform(e[0],e[1],e[2],e[3],c.xMin*e[0]+c.yMin*e[2]+e[4],c.xMin*e[1]+c.yMin*e[3]+e[5]);t.cachePosition&&(t.globalAlpha=o,t.imageSmoothingEnabled="shape"===this._$mode,t.globalCompositeOperation=n,t.drawInstance(d-y,f-E,u,g,i),t.cachePosition=null),B(c)}setupStroke(t,e,i,s,r){switch(t.lineWidth=e,i){case 0:t.lineCap="none";break;case 1:t.lineCap="round";break;case 2:t.lineCap="square"}switch(s){case 0:t.lineJoin="bevel";break;case 1:t.lineJoin="miter";break;case 2:t.lineJoin="round"}t.miterLimit=r}createGradientStyle(t,e,i,s,n,a,h,o=null){let _,l="pad";switch(n){case 0:l="reflect";break;case 1:l="repeat"}if(0===e){const e=(t=>{const e=-819.2*t[0]-819.2*t[2]+t[4],i=819.2*t[0]-819.2*t[2]+t[4],s=-819.2*t[0]+819.2*t[2]+t[4],n=-819.2*t[1]-819.2*t[3]+t[5],a=819.2*t[1]-819.2*t[3]+t[5];let h=s-e,o=-819.2*t[1]+819.2*t[3]+t[5]-n;const _=r.sqrt(h*h+o*o);_?(h/=_,o/=_):(h=0,o=0);const l=(i-e)*h+(a-n)*o;return w(e+l*h,n+l*o,i,a)})(s);_=t.createLinearGradient(e[0],e[1],e[2],e[3],a?"rgb":"linearRGB",l)}else t.save(),t.transform(s[0],s[1],s[2],s[3],s[4],s[5]),_=t.createRadialGradient(0,0,0,0,0,819.2,a?"rgb":"linearRGB",l,h);for(let t=0;t-1&&this._$characterId>-1&&rt.removeCache(`${this._$loaderInfoId}@${this._$characterId}`))}}class ae extends ne{_$clip(t,e){let i=e;const n=this._$matrix;1===n[0]&&0===n[1]&&0===n[2]&&1===n[3]&&0===n[4]&&0===n[5]||(i=H(e,n));const a=this._$getBounds(),h=q(a,i);B(a);const o=r.ceil(r.abs(h.xMax-h.xMin)),_=r.ceil(r.abs(h.yMax-h.yMin));switch(B(h),!0){case 0===o:case 0===_:case o===-1/0:case _===-1/0:case o===s:case _===s:return}super._$clip(t,i),i!==e&&N(i)}_$draw(t,e,i){if(!this._$visible||!this._$maxAlpha||!this._$canDraw)return;let s=i;const r=this._$colorTransform;if(1===r[0]&&1===r[1]&&1===r[2]&&1===r[3]&&0===r[4]&&0===r[5]&&0===r[6]&&0===r[7]||(s=W(i,r)),!G(s[3]+s[7]/255,0,1,0))return void(s!==i&&L(s));let n=e;const a=this._$matrix;1===a[0]&&0===a[1]&&0===a[2]&&1===a[3]&&0===a[4]&&0===a[5]||(n=H(e,a)),super._$draw(t,n,s,this._$blendMode,this._$filters),n!==e&&N(n),s!==i&&L(s)}_$remove(){this._$xMin=0,this._$yMin=0,this._$xMax=0,this._$yMax=0,this._$recodes=null,super._$remove(),ce.push(this)}}class he extends gt{constructor(){super(),this._$background=!1,this._$backgroundColor=16777215,this._$border=!1,this._$borderColor=0,this._$wordWrap=!1,this._$textData=U(),this._$textAreaActive=!1,this._$thickness=0,this._$thicknessColor=0,this._$limitWidth=0,this._$limitHeight=0,this._$autoSize="none",this._$widthTable=U(),this._$heightTable=U(),this._$objectTable=U(),this._$textHeightTable=U(),this._$xMin=0,this._$yMin=0,this._$xMax=0,this._$yMax=0,this._$maxScrollV=null,this._$scrollV=1,this._$textHeight=0,this._$verticalAlign="top",this._$cacheKeys=U(),this._$cacheParams=U(0,0,0)}get width(){const t=q(this._$getBounds(null),this._$matrix),e=r.abs(t.xMax-t.xMin);switch(B(t),!0){case 0===e:case e===s:case e===-1/0:return 0;default:return e}}get height(){const t=q(this._$getBounds(null),this._$matrix),e=r.abs(t.yMax-t.yMin);switch(B(t),e){case 0:case s:case-1/0:return 0;default:return e}}get maxScrollV(){if(null===this._$maxScrollV){this._$maxScrollV=1;const t=this._$textHeightTable.length,e=this.height;if(e>this._$textHeight)return this._$maxScrollV;let i=0,s=0;for(;t>s&&(i+=this._$textHeightTable[s++],!(i>e));)this._$maxScrollV++}return this._$maxScrollV}_$clip(t,e){const i=this._$getBounds(),s=i.xMax,n=i.xMin,a=i.yMax,h=i.yMin;B(i);const o=r.ceil(r.abs(s-n)),_=r.ceil(r.abs(a-h));if(!o||!_)return;let l=e;const c=this._$matrix;1===c[0]&&0===c[1]&&0===c[2]&&1===c[3]&&0===c[4]&&0===c[5]||(l=H(e,c)),t.reset(),t.setTransform(e[0],e[1],e[2],e[3],e[4],e[5]),t.beginPath(),t.moveTo(0,0),t.lineTo(o,0),t.lineTo(o,_),t.lineTo(0,_),t.lineTo(0,0),t.clip(),l!==e&&N(l)}_$draw(t,e,i){if(!this._$visible||this._$textAreaActive)return;if(!this._$background&&!this._$border&&2>this._$textData.length)return;let n=i;const a=this._$colorTransform;1===a[0]&&1===a[1]&&1===a[2]&&1===a[3]&&0===a[4]&&0===a[5]&&0===a[6]&&0===a[7]||(n=W(i,a));const o=G(n[3]+n[7]/255,0,1);if(!o)return;let _=e;const l=this._$matrix;1===l[0]&&0===l[1]&&0===l[2]&&1===l[3]&&0===l[4]&&0===l[5]||(_=H(e,l));const c=this._$getBounds(null);c.xMin-=this._$thickness,c.xMax+=this._$thickness,c.yMin-=this._$thickness,c.yMax+=this._$thickness;const $=q(c,_),u=+$.xMax,d=+$.xMin,g=+$.yMax,f=+$.yMin;B($);const m=r.ceil(r.abs(u-d)),p=r.ceil(r.abs(g-f));switch(!0){case 0===m:case 0===p:case m===-1/0:case p===-1/0:case m===s:case p===s:return}let x=+r.sqrt(_[0]*_[0]+_[1]*_[1]);if(!h.isInteger(x)){const t=x.toString(),e=t.indexOf("e");-1!==e&&(x=+t.slice(0,e)),x=+x.toFixed(4)}let b=+r.sqrt(_[2]*_[2]+_[3]*_[3]);if(!h.isInteger(b)){const t=b.toString(),e=t.indexOf("e");-1!==e&&(b=+t.slice(0,e)),b=+b.toFixed(4)}const v=this._$filters,T=null!==v&&v.length>0&&this._$canApply(v);let A=F(0,m,0,p);if(T&&v)for(let t=0;ty.width||f-A.yMin>y.height)return void B(A);if(0>d+A.xMax||0>f+A.yMax)return void B(A);if(B(A),this._$isUpdated()&&(rt.removeCache(this._$instanceId),t.cachePosition=null,this._$cacheKeys.length=0),!this._$cacheKeys.length||this._$cacheParams[0]!==x||this._$cacheParams[1]!==b||this._$cacheParams[2]!==i[7]){const t=U(x,b);this._$cacheKeys=rt.generateKeys(this._$instanceId,t),D(t),this._$cacheParams[0]=x,this._$cacheParams[1]=b,this._$cacheParams[2]=i[7]}if(t.cachePosition=rt.get(this._$cacheKeys),!t.cachePosition){const s=r.min(1,r.max(x,b)),a=r.ceil(r.abs(c.xMax-c.xMin)*x),h=r.ceil(r.abs(c.yMax-c.yMin)*b);n[3]=1;const o=new OffscreenCanvas(a+2*s,h+2*s).getContext("2d");if(!o)return;if(this._$background||this._$border){if(o.beginPath(),o.moveTo(0,0),o.lineTo(a,0),o.lineTo(a,h),o.lineTo(0,h),o.lineTo(0,0),this._$background){const t=Z(this._$backgroundColor),e=r.max(0,r.min(255*t.A*i[3]+i[7],255))/255;o.fillStyle=`rgba(${t.R},${t.G},${t.B},${e})`,o.fill()}if(this._$border){const t=Z(this._$borderColor),e=r.max(0,r.min(255*t.A*i[3]+i[7],255))/255;o.lineWidth=s,o.strokeStyle=`rgba(${t.R},${t.G},${t.B},${e})`,o.stroke()}}o.save(),o.beginPath(),o.moveTo(2,2),o.lineTo(a-2,2),o.lineTo(a-2,h-2),o.lineTo(2,h-2),o.lineTo(2,2),o.clip(),o.beginPath(),o.setTransform(x,0,0,b,0,0),this._$doDraw(o,e,i,a/x),o.restore();const _=M.createCachePosition(m,p),l=M.createTextureFromCanvas(o.canvas);t.drawTextureFromRect(l,_),t.cachePosition=_,rt.set(this._$cacheKeys,_)}let E=!1,C=0,S=0;if(v&&v.length&&this._$canApply(v)){E=!0;const e=this._$drawFilter(t,_,v,m,p);e.offsetX&&(C=e.offsetX),e.offsetY&&(S=e.offsetY),t.cachePosition=e}const w=r.atan2(_[1],_[0]),R=r.atan2(-_[2],_[3]);if(E||!w&&!R)t.setTransform(1,0,0,1,d-C,f-S);else{const e=c.xMin*x,i=c.yMin*b,s=r.cos(w),n=r.sin(w),a=r.cos(R),h=r.sin(R);t.setTransform(s,n,-h,a,e*s-i*h+_[4],e*n+i*a+_[5])}t.cachePosition&&(t.globalAlpha=o,t.imageSmoothingEnabled=!0,t.globalCompositeOperation=this._$blendMode,t.drawInstance(d-C,f-S,u,g,i),t.cachePosition=null),B(c),_!==e&&N(_),n!==i&&L(n)}_$doDraw(t,e,i,s){const n=this.width,a=this.height;let h=0,o=0,_=0,l=0;if("top"!==this._$verticalAlign&&this.height>this._$textHeight)switch(this._$verticalAlign){case"middle":l=(this.height-this._$textHeight+2)/2;break;case"bottom":l=this.height-this._$textHeight+2}const c=this._$textData.length;for(let $=0;$a||u>n))continue;const d=c.textFormat,g=Z(c.textFormat._$color),f=r.max(0,r.min(255*g.A*i[3]+i[7],255))/255;if(t.fillStyle=`rgba(${g.R},${g.G},${g.B},${f})`,this._$thickness){const e=Z(this._$thicknessColor),s=r.max(0,r.min(255*e.A*i[3]+i[7],255))/255;t.lineWidth=this._$thickness,t.strokeStyle=`rgba(${e.R},${e.G},${e.B},${s})`}const m=c.yIndex;switch(c.mode){case"break":case"wrap":if(_++,this._$scrollV>_)continue;if(o+=this._$textHeightTable[m],h=this._$getAlignOffset(this._$objectTable[m],s),d._$underline){const s=c.textFormat._$size/12,n=Z(d._$color),a=r.max(0,r.min(255*n.A*i[3]+i[7],255))/255;t.lineWidth=r.max(1,1/r.min(e[0],e[3])),t.strokeStyle=`rgba(${n.R},${n.G},${n.B},${a})`,t.beginPath(),t.moveTo(h,l+o-s),t.lineTo(h+this._$widthTable[m],l+o-s),t.stroke()}break;case"text":{if(this._$scrollV>_)continue;let e=o-this._$heightTable[0];_e||(e+=c.textFormat._$size/12*2),t.beginPath(),t.textBaseline="top",t.font=tt(d._$font,d._$size,d._$italic,d._$bold),this._$thickness&&t.strokeText(c.text,u,l+e),t.fillText(c.text,u,l+e)}break;case"image":if(!c.loaded)continue;t.beginPath(),t.drawImage(c.image,c.hspace,l+c.y,c.width,c.height)}}}_$getAlignOffset(t,e){const i=this._$widthTable[t.yIndex],s=t.textFormat,n=s._$blockIndent+s._$leftMargin>0?s._$blockIndent+s._$leftMargin:0;switch(!0){case!this._$wordWrap&&i>e:return r.max(0,n);case"center"===s._$align:case"center"===this._$autoSize:return r.max(0,e/2-n-s._$rightMargin-i/2);case"right"===s._$align:case"right"===this._$autoSize:return r.max(0,e-n-i-s._$rightMargin-2);default:return r.max(0,n+2)}}_$remove(){this._$xMin=0,this._$yMin=0,this._$xMax=0,this._$yMax=0,this._$textData.length=0,this._$widthTable.length=0,this._$heightTable.length=0,this._$objectTable.length=0,this._$textHeightTable.length=0,this._$textAreaActive=!1,super._$remove(),$e.push(this)}_$updateProperty(t){this._$textAreaActive=!!t.textAreaActive,this._$textData.length=0,this._$widthTable.length=0,this._$heightTable.length=0,this._$objectTable.length=0,this._$textHeightTable.length=0,this._$textData.push(...t.textData),this._$widthTable.push(...t.widthTable),this._$heightTable.push(...t.heightTable),this._$objectTable.push(...t.objectTable),this._$textHeightTable.push(...t.textHeightTable),this._$wordWrap=t.wordWrap,this._$limitWidth=t.limitWidth,this._$limitHeight=t.limitHeight,this._$autoSize=t.autoSize,this._$scrollV=t.scrollV,this._$textHeight=t.textHeight,this._$verticalAlign=t.verticalAlign,this._$border=t.border,this._$border&&(this._$borderColor=t.borderColor),this._$background=t.background,this._$background&&(this._$backgroundColor=t.backgroundColor),"thickness"in t&&(this._$thickness=t.thickness,this._$thicknessColor=t.thicknessColor)}_$update(t){super._$update(t),this._$textAreaActive=!!t.textAreaActive,this._$xMin=t.xMin,this._$yMin=t.yMin,this._$xMax=t.xMax,this._$yMax=t.yMax,t.textData&&this._$updateProperty(t)}}class oe extends gt{constructor(){super(),this._$imageBitmap=null,this._$context=null,this._$smoothing=!0,this._$cacheKeys=U(),this._$cacheParams=U(0,0,0)}_$clip(t,e){const i=this._$xMax,s=this._$yMax;if(!i||!s)return;let r=e;const n=this._$matrix;1===n[0]&&0===n[1]&&0===n[2]&&1===n[3]&&0===n[4]&&0===n[5]||(r=H(e,n)),t.reset(),t.setTransform(r[0],r[1],r[2],r[3],r[4],r[5]),t.beginPath(),t.moveTo(0,0),t.lineTo(i,0),t.lineTo(i,s),t.lineTo(0,s),t.lineTo(0,0),t.clip(),r!==e&&N(r)}_$draw(t,e,i){if(!this._$visible||!this._$imageBitmap||!this._$context)return;let n=i;const a=this._$colorTransform;1===a[0]&&1===a[1]&&1===a[2]&&1===a[3]&&0===a[4]&&0===a[5]&&0===a[6]&&0===a[7]||(n=W(i,a));const o=G(n[3]+n[7]/255,0,1,0);if(!o)return void(n!==i&&L(n));let _=e;const l=this._$matrix;1===l[0]&&0===l[1]&&0===l[2]&&1===l[3]&&0===l[4]&&0===l[5]||(_=H(e,l));const c=this._$getBounds();B(c);const $=q(c,_),u=+$.xMax,d=+$.xMin,g=+$.yMax,f=+$.yMin;B($);const m=r.ceil(r.abs(u-d)),p=r.ceil(r.abs(g-f));switch(!0){case 0===m:case 0===p:case m===-1/0:case p===-1/0:case m===s:case p===s:return}let x=+r.sqrt(_[0]*_[0]+_[1]*_[1]);if(!h.isInteger(x)){const t=x.toString(),e=t.indexOf("e");-1!==e&&(x=+t.slice(0,e)),x=+x.toFixed(4)}let b=+r.sqrt(_[2]*_[2]+_[3]*_[3]);if(!h.isInteger(b)){const t=b.toString(),e=t.indexOf("e");-1!==e&&(b=+t.slice(0,e)),b=+b.toFixed(4)}const v=this._$filters,T=null!==v&&v.length>0&&this._$canApply(v);let A=F(0,m,0,p);if(T&&v)for(let t=0;ty.width||f-A.yMin>y.height)return void B(A);if(0>d+A.xMax||0>f+A.yMax)return void B(A);if(B(A),!this._$cacheKeys.length||this._$cacheParams[0]!==x||this._$cacheParams[1]!==b||this._$cacheParams[2]!==i[7]){const t=U();t[0]=x,t[1]=b,this._$cacheKeys=rt.generateKeys(this._$instanceId,t,i),D(t),this._$cacheParams[0]=x,this._$cacheParams[1]=b,this._$cacheParams[2]=i[7]}if(t.cachePosition=rt.get(this._$cacheKeys),!t.cachePosition){const e=r.ceil(r.abs(this._$xMax-this._$xMin)),i=r.ceil(r.abs(this._$yMax-this._$yMin)),s=M.createCachePosition(e,i);t.cachePosition=s,rt.set(this._$cacheKeys,s)}this._$context.drawImage(this._$imageBitmap,0,0);const E=M.textureManager._$createFromElement(this._$imageBitmap.width,this._$imageBitmap.height,this._$context.canvas,this._$smoothing);let C=0,S=0;if(T&&v){const e=M.currentAttachment,i=M.createCacheAttachment(m,p);t._$bind(i),t.reset();const s=P(x,0,0,b,m/2,p/2),r=P(1,0,0,1,-E.width/2,-E.height/2),n=H(s,r);N(s),N(r),t.setTransform(n[0],n[1],n[2],n[3],n[4],n[5]),t.drawImage(E,0,0,E.width,E.height);const a=M.getTextureFromCurrentAttachment();t._$bind(e),M.releaseAttachment(i),t.drawTextureFromRect(E,t.cachePosition);const h=this._$drawFilter(t,_,v,m,p,a);h.offsetX&&(C=h.offsetX),h.offsetY&&(S=h.offsetY),t.cachePosition=h,t.setTransform(1,0,0,1,d-C,f-S)}else t.drawTextureFromRect(E,t.cachePosition),t.setTransform(_[0],_[1],_[2],_[3],_[4],_[5]);t.cachePosition&&(t.globalAlpha=o,t.imageSmoothingEnabled=!0,t.globalCompositeOperation=this._$blendMode,t.drawInstance(d-C,f-S,u,g,i),t.cachePosition=null),_!==e&&N(_),n!==i&&L(n)}_$remove(){this._$xMin=0,this._$yMin=0,this._$xMax=0,this._$yMax=0,this._$context=null,this._$imageBitmap=null,this._$smoothing=!0,super._$remove(),de.push(this)}_$updateProperty(t){if(this._$xMin=t.xMin,this._$yMin=t.yMin,this._$xMax=t.xMax,this._$yMax=t.yMax,this._$imageBitmap=t.imageBitmap,this._$smoothing=t.smoothing,!this._$context&&this._$imageBitmap){const t=new c(this._$imageBitmap.width,this._$imageBitmap.height);this._$context=t.getContext("2d")}}_$update(t){super._$update(t),this._$updateProperty(t)}}let _e=!1;const le=new class{constructor(){this._$instances=new Map,this._$matrix=P(1,0,0,1,0,0),this._$width=0,this._$height=0,this._$stage=new ft,this._$canvas=null,this._$context=null,this._$attachment=null}get instances(){return this._$instances}get context(){return this._$context}get scaleX(){return this._$matrix[0]}stop(){rt.reset()}_$initialize(e,i){let s=0;var r,n;this._$setStage(e[s++]),n=1===e[s++],_e=n,r=e[s++],t=r,this._$canvas=i;const a=i.getContext("webgl2",{stencil:!0,premultipliedAlpha:!0,antialias:!1,depth:!1,preserveDrawingBuffer:!0});if(a){const t=new re(a,e[s++]);this._$context=t,rt.context=t}}_$setBackgroundColor(t){if(!this._$context)return;const e=t[0];if(-1===e)this._$context._$setColor(0,0,0,0);else{const t={A:(i=e)>>>24,R:(16711680&i)>>16,G:(65280&i)>>8,B:255&i};this._$context._$setColor(t.R/255,t.G/255,t.B/255,1)}var i}_$bitmapDraw(t,e,i,s){const r=this._$context;if(!r)return;r._$bind(this._$attachment),r.reset(),r.setTransform(1,0,0,1,0,0),r.clearRect(0,0,this._$width,this._$height),r.beginPath(),t._$draw(r,e,i),r.frameBuffer.transferToMainTexture();const n=s.getContext("2d");n&&this._$canvas&&n.drawImage(this._$canvas,0,0)}_$draw(){if(!this._$width||!this._$height)return;const t=this._$context;t&&(t.reset(),t.setTransform(1,0,0,1,0,0),t.clearRect(0,0,this._$width,this._$height),t.beginPath(),this._$stage._$draw(t,this._$matrix,m),this._$stage._$updated=!1,t.drawInstacedArray(),t.frameBuffer.transferToMainTexture())}_$resize(t){let e=0;const i=t[e++],s=t[e++];if(this._$width=i,this._$height=s,!this._$canvas)return;if(this._$canvas.width===i&&this._$canvas.height===s)return;const r=this._$context;if(!r)return;const n=t[e++];this._$matrix[0]=n,this._$matrix[3]=n,this._$matrix[4]=t[e++],this._$matrix[5]=t[e++],this._$stage._$updated=!0,rt.reset(),r.clearInstacedArray(),this._$canvas.width=i,this._$canvas.height=s,r._$gl.viewport(0,0,i,s);const a=r.frameBuffer;this._$attachment&&(a.unbind(),a.releaseAttachment(this._$attachment,!0)),this._$attachment=a.createCacheAttachment(i,s,!0),r.setMaxSize(i,s),r._$bind(this._$attachment)}_$setStage(t){this._$stage._$instanceId=t,this._$instances.set(t,this._$stage)}_$updateStage(){this._$stage._$updated=!0}_$createDisplayObjectContainer(t){const e=ge();let i=0;e._$instanceId=t[i++],e._$parentId=t[i++],this._$setProperty(e,t,2),this._$instances.set(e._$instanceId,e)}_$setProperty(t,e,i){t._$visible=1===e[i++],t._$depth=e[i++],t._$clipDepth=e[i++],t._$isMask=1===e[i++],1===e[i++]?(t._$maskId=e[i++],t._$maskMatrix||(t._$maskMatrix=P()),t._$maskMatrix[0]=e[i++],t._$maskMatrix[1]=e[i++],t._$maskMatrix[2]=e[i++],t._$maskMatrix[3]=e[i++],t._$maskMatrix[4]=e[i++],t._$maskMatrix[5]=e[i++]):(t._$maskId=-1,t._$maskMatrix&&(N(t._$maskMatrix),t._$maskMatrix=null),i+=7),t._$visible?(t._$matrix[0]=e[i++],t._$matrix[1]=e[i++],t._$matrix[2]=e[i++],t._$matrix[3]=e[i++],t._$matrix[4]=e[i++],t._$matrix[5]=e[i++],t._$colorTransform[0]=e[i++],t._$colorTransform[1]=e[i++],t._$colorTransform[2]=e[i++],t._$colorTransform[3]=e[i++],t._$colorTransform[4]=e[i++],t._$colorTransform[5]=e[i++],t._$colorTransform[6]=e[i++],t._$colorTransform[7]=e[i++]):(i+=6,i+=8),t._$blendMode=st(e[i++]),e[i++]?t._$scale9Grid={x:e[i++],y:e[i++],w:e[i++],h:e[i++]}:t._$scale9Grid=null,t._$blendMode=st(e[i++]),e[i++]?t._$scale9Grid={x:e[i++],y:e[i++],w:e[i++],h:e[i++]}:t._$scale9Grid=null}_$registerShapeRecodes(t,e){this._$instances.has(t)||this._$instances.set(t,pe()),this._$instances.get(t)._$recodes=e}_$createShape(t){let e=0;const i=t[e++];this._$instances.has(i)||this._$instances.set(i,pe());const s=this._$instances.get(i);s._$instanceId=i,s._$parentId=t[e++],s._$maxAlpha=t[e++],s._$canDraw=1===t[e++],s._$xMin=t[e++],s._$yMin=t[e++],s._$xMax=t[e++],s._$yMax=t[e++],s._$characterId=t[e++],s._$loaderInfoId=t[e++],this._$setProperty(s,t,10)}_$createVideo(t){const e=me();t.characterId&&(e._$characterId=t.characterId),"loaderInfoId"in t&&(e._$loaderInfoId=t.loaderInfoId||0),e._$updateProperty(t),this._$instances.set(e._$instanceId,e)}_$createTextField(t){const e=fe();e._$xMin=t.xMin||0,e._$yMin=t.yMin||0,e._$xMax=t.xMax||0,e._$yMax=t.yMax||0,t.characterId&&(e._$characterId=t.characterId),"loaderInfoId"in t&&(e._$loaderInfoId=t.loaderInfoId||0),e._$updateProperty(t),this._$instances.set(e._$instanceId,e)}},ce=[],$e=[],ue=[],de=[],ge=()=>ue.pop()||new ft,fe=()=>$e.pop()||new he,me=()=>de.pop()||new oe,pe=()=>ce.pop()||new ae;const xe=new class{constructor(){this.state="deactivate",this.queue=[],this._$options=[]}execute(){this.state="active";let t=!0;for(;this.queue.length;){const e=this.queue.shift();if(console.log(e),e){switch(t=!0,e.command){case"draw":le._$draw();break;case"setProperty":if(!le.instances.has(e.instanceId))continue;break;case"setChildren":{t=!1;const i=e.buffer,s=le.instances;if(!s.has(i[0]))continue;const r=s.get(i[0]);r._$doChanged(),r._$children=i.subarray(1)}break;case"remove":{const t=le.instances;if(!t.has(e.instanceId))continue;t.get(e.instanceId)._$remove(),t.delete(e.instanceId)}break;case"createShape":le._$createShape(e.buffer);break;case"createDisplayObjectContainer":le._$createDisplayObjectContainer(e.buffer);break;case"createTextField":le._$createTextField(e);break;case"createVideo":le._$createVideo(e);break;case"resize":le._$resize(e.buffer);break;case"initialize":le._$initialize(e.buffer,e.canvas);break;case"setBackgroundColor":le._$setBackgroundColor(e.buffer);break;case"stop":le.stop();break;case"removeCache":rt.removeCache(e.id);break;case"bitmapDraw":{const t=le.instances;if(!t.has(e.sourceId))continue;const i=t.get(e.sourceId),s=new c(e.width,e.height);le._$bitmapDraw(i,e.matrix||f,e.colorTransform||m,s);const r=s.transferToImageBitmap();globalThis.postMessage({command:"bitmapDraw",sourceId:e.sourceId,imageBitmap:r},[r])}break;default:if(e.command.indexOf("shapeRecodes")>-1){t=!1;const i=+e.command.split("@")[1];le._$registerShapeRecodes(i,e.buffer)}}e.buffer&&t&&(this._$options.length=0)}}this.state="deactivate"}};self.addEventListener("message",(t=>{return e=void 0,i=void 0,r=function*(){xe.queue.push(t.data),"deactivate"===xe.state&&xe.execute()},new((s=void 0)||(s=Promise))((function(t,n){function a(t){try{o(r.next(t))}catch(t){n(t)}}function h(t){try{o(r.throw(t))}catch(t){n(t)}}function o(e){var i;e.done?t(e.value):(i=e.value,i instanceof s?i:new s((function(t){t(i)}))).then(a,h)}o((r=r.apply(e,i||[])).next())}));var e,i,s,r}))})();'],{type:"text/javascript"}))):null,Mr=null,Mr&&(wr=t=>{t._$createWorkerInstance(),t._$postProperty();const e=t._$needsChildren?t._$getChildren():t._$children,i=ht();for(let t=0;t{t._$removeWorkerInstance();const e=t._$needsChildren?t._$getChildren():t._$children;for(let t=0;t{const e=navigator.userAgentData;if(e)e.getHighEntropyValues(["platform","mobile"]).then((e=>{const i=e.brands;for(let t=0;t-1,Js=e.indexOf("iPhone")>-1||e.indexOf("iPod")>-1,js=e.indexOf("Chrome")>-1,Ks=e.indexOf("Firefox")>-1,Ws=-1===e.indexOf("Chrome")&&e.indexOf("Safari")>-1,Zs=Qs||Js,t()}}))};"next2d"in window||(console.log("%c Next2D Player %c 1.18.12 %c https://next2d.app","color: #fff; background: #5f5f5f","color: #fff; background: #4bc729",""),window.next2d=new class{constructor(t){this._$promises=t,this._$player=new ms,this.display=bs,this.events=xs,this.filters=vs,this.geom=Ts,this.media=ys,this.net=Es,this.text=As,this.ui=Ms}get player(){return this._$player}load(t,e){Promise.all(this._$promises).then((()=>{if(ot(this._$promises),"develop"===t){const e=location.search.slice(1).split("&")[0];if(!e)return;t=`${location.origin}/${e}`}if(!t)return;"/"===t.charAt(1)&&(t=t.slice(1)),e&&"base"in e||!(t.indexOf("//")>-1)||(this._$player.base=t),this._$player.setOptions(e),this._$player._$initialize();const i=new de;i.contentLoaderInfo.addEventListener(Lt.IO_ERROR,(t=>{t.target&&t.target.removeEventListener(Lt.IO_ERROR,t.listener),alert("Error: "+t.text)})),i.contentLoaderInfo.addEventListener(It.COMPLETE,(t=>{const e=t.target,i=this._$player;if(e.removeEventListener(It.COMPLETE,t.listener),e._$data){const t=e._$data.stage;i.bgColor=t.bgColor,i._$setBackgroundColor(t.bgColor),i.stage.addChild(e.content),i.width=t.width,i.height=t.height,i.stage._$frameRate=dt(+t.fps,1,60,60)}i._$resize()})),i.load(new wt(t))}))}createRootMovieClip(){return t=this,e=arguments,s=function*(t=240,e=240,i=24,s=null){yield Promise.all(this._$promises),ot(this._$promises);const r=this._$player;r.width=0|t,r.height=0|e,r.mode="create",r.stage._$frameRate=0|i,r.setOptions(s),r._$initialize();const n=r.stage.addChild(new $e);return r._$loadStatus=ms.LOAD_END,r.play(),n},new((i=void 0)||(i=Promise))((function(r,n){function a(t){try{o(s.next(t))}catch(t){n(t)}}function h(t){try{o(s.throw(t))}catch(t){n(t)}}function o(t){var e;t.done?r(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(a,h)}o((s=s.apply(t,e||[])).next())}));var t,e,i,s}}([new Promise((t=>{if("loading"===document.readyState){const e=()=>{window.removeEventListener("DOMContentLoaded",e),kr().then((()=>{cr()._$initializeCanvas(),t()}))};window.addEventListener("DOMContentLoaded",e)}else kr().then((()=>{cr()._$initializeCanvas(),t()}))}))]))})(); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..c907a483 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3573 @@ +{ + "name": "@next2d/player", + "version": "1.18.13", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@next2d/player", + "version": "1.18.13", + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "htmlparser2": "^9.1.0" + }, + "devDependencies": { + "@types/node": "^20.14.11", + "@typescript-eslint/eslint-plugin": "^7.16.1", + "@typescript-eslint/parser": "^7.16.1", + "@vitest/web-worker": "^2.0.3", + "eslint": "^8.52.0", + "eslint-plugin-unused-imports": "^3.2.0", + "fflate": "^0.8.2", + "typescript": "^5.5.3", + "vite": "^5.3.4", + "vitest": "^2.0.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Next2D" + }, + "peerDependencies": { + "@next2d/core": "file:packages/core", + "@next2d/display": "file:packages/display", + "@next2d/events": "file:packages/events", + "@next2d/filters": "file:packages/filters", + "@next2d/geom": "file:packages/geom", + "@next2d/interface": "file:packages/interface", + "@next2d/media": "file:packages/media", + "@next2d/net": "file:packages/net", + "@next2d/share": "file:packages/share", + "@next2d/text": "file:packages/text", + "@next2d/ui": "file:packages/ui", + "@next2d/util": "file:packages/util", + "@next2d/webgl": "file:packages/webgl" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@next2d/core": { + "resolved": "packages/core", + "link": true + }, + "node_modules/@next2d/display": { + "resolved": "packages/display", + "link": true + }, + "node_modules/@next2d/events": { + "resolved": "packages/events", + "link": true + }, + "node_modules/@next2d/filters": { + "resolved": "packages/filters", + "link": true + }, + "node_modules/@next2d/geom": { + "resolved": "packages/geom", + "link": true + }, + "node_modules/@next2d/interface": { + "resolved": "packages/interface", + "link": true + }, + "node_modules/@next2d/media": { + "resolved": "packages/media", + "link": true + }, + "node_modules/@next2d/net": { + "resolved": "packages/net", + "link": true + }, + "node_modules/@next2d/share": { + "resolved": "packages/share", + "link": true + }, + "node_modules/@next2d/text": { + "resolved": "packages/text", + "link": true + }, + "node_modules/@next2d/ui": { + "resolved": "packages/ui", + "link": true + }, + "node_modules/@next2d/util": { + "resolved": "packages/util", + "link": true + }, + "node_modules/@next2d/webgl": { + "resolved": "packages/webgl", + "link": true + }, + "node_modules/@next2d/webpack-worker-loader-plugin": { + "resolved": "packages/webpack-worker-loader-plugin", + "link": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", + "integrity": "sha512-JlPfZ/C7yn5S5p0yKk7uhHTTnFlvTgLetl2VxqE518QgyM7C9bSfFTYvB/Q/ftkq0RIPY4ySxTz+/wKJ/dXC0w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.0.tgz", + "integrity": "sha512-RDxUSY8D1tWYfn00DDi5myxKgOk6RvWPxhmWexcICt/MEC6yEMr4HNCu1sXXYLw8iAsg0D44NuU+qNq7zVWCrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.0.tgz", + "integrity": "sha512-emvKHL4B15x6nlNTBMtIaC9tLPRpeA5jMvRLXVbl/W9Ie7HhkrE7KQjvgS9uxgatL1HmHWDXk5TTS4IaNJxbAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.0.tgz", + "integrity": "sha512-fO28cWA1dC57qCd+D0rfLC4VPbh6EOJXrreBmFLWPGI9dpMlER2YwSPZzSGfq11XgcEpPukPTfEVFtw2q2nYJg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.0.tgz", + "integrity": "sha512-2Rn36Ubxdv32NUcfm0wB1tgKqkQuft00PtM23VqLuCUR4N5jcNWDoV5iBC9jeGdgS38WK66ElncprqgMUOyomw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.0.tgz", + "integrity": "sha512-gJuzIVdq/X1ZA2bHeCGCISe0VWqCoNT8BvkQ+BfsixXwTOndhtLUpOg0A1Fcx/+eA6ei6rMBzlOz4JzmiDw7JQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.0.tgz", + "integrity": "sha512-0EkX2HYPkSADo9cfeGFoQ7R0/wTKb7q6DdwI4Yn/ULFE1wuRRCHybxpl2goQrx4c/yzK3I8OlgtBu4xvted0ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.0.tgz", + "integrity": "sha512-GlIQRj9px52ISomIOEUq/IojLZqzkvRpdP3cLgIE1wUWaiU5Takwlzpz002q0Nxxr1y2ZgxC2obWxjr13lvxNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.0.tgz", + "integrity": "sha512-N6cFJzssruDLUOKfEKeovCKiHcdwVYOT1Hs6dovDQ61+Y9n3Ek4zXvtghPPelt6U0AH4aDGnDLb83uiJMkWYzQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.0.tgz", + "integrity": "sha512-2DnD3mkS2uuam/alF+I7M84koGwvn3ZVD7uG+LEWpyzo/bq8+kKnus2EVCkcvh6PlNB8QPNFOz6fWd5N8o1CYg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.0.tgz", + "integrity": "sha512-D6pkaF7OpE7lzlTOFCB2m3Ngzu2ykw40Nka9WmKGUOTS3xcIieHe82slQlNq69sVB04ch73thKYIWz/Ian8DUA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.0.tgz", + "integrity": "sha512-HBndjQLP8OsdJNSxpNIN0einbDmRFg9+UQeZV1eiYupIRuZsDEoeGU43NQsS34Pp166DtwQOnpcbV/zQxM+rWA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.0.tgz", + "integrity": "sha512-HxfbvfCKJe/RMYJJn0a12eiOI9OOtAUF4G6ozrFUK95BNyoJaSiBjIOHjZskTUffUrB84IPKkFG9H9nEvJGW6A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.0.tgz", + "integrity": "sha512-HxDMKIhmcguGTiP5TsLNolwBUK3nGGUEoV/BO9ldUBoMLBssvh4J0X8pf11i1fTV7WShWItB1bKAKjX4RQeYmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.0.tgz", + "integrity": "sha512-xItlIAZZaiG/u0wooGzRsx11rokP4qyc/79LkAOdznGRAbOFc+SfEdfUOszG1odsHNgwippUJavag/+W/Etc6Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.0.tgz", + "integrity": "sha512-xNo5fV5ycvCCKqiZcpB65VMR11NJB+StnxHz20jdqRAktfdfzhgjTiJ2doTDQE/7dqGaV5I7ZGqKpgph6lCIag==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", + "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/type-utils": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", + "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", + "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@vitest/expect": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.3.tgz", + "integrity": "sha512-X6AepoOYePM0lDNUPsGXTxgXZAl3EXd0GYe/MZyVE4HzkUqyUVC6S3PrY5mClDJ6/7/7vALLMV3+xD/Ko60Hqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.0.3", + "@vitest/utils": "2.0.3", + "chai": "^5.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.3.tgz", + "integrity": "sha512-URM4GLsB2xD37nnTyvf6kfObFafxmycCL8un3OC9gaCs5cti2u+5rJdIflZ2fUJUen4NbvF6jCufwViAFLvz1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.3.tgz", + "integrity": "sha512-EmSP4mcjYhAcuBWwqgpjR3FYVeiA4ROzRunqKltWjBfLNs1tnMLtF+qtgd5ClTwkDP6/DGlKJTNa6WxNK0bNYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.0.3", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.3.tgz", + "integrity": "sha512-6OyA6v65Oe3tTzoSuRPcU6kh9m+mPL1vQ2jDlPdn9IQoUxl8rXhBnfICNOC+vwxWY684Vt5UPgtcA2aPFBb6wg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.0.3", + "magic-string": "^0.30.10", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.3.tgz", + "integrity": "sha512-sfqyAw/ypOXlaj4S+w8689qKM1OyPOqnonqOc9T91DsoHbfN5mU7FdifWWv3MtQFf0lEUstEwR9L/q/M390C+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.3.tgz", + "integrity": "sha512-c/UdELMuHitQbbc/EVctlBaxoYAwQPQdSNwv7z/vHyBKy2edYZaFgptE27BRueZB7eW8po+cllotMNTDpL3HWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.0.3", + "estree-walker": "^3.0.3", + "loupe": "^3.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/web-worker": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@vitest/web-worker/-/web-worker-2.0.3.tgz", + "integrity": "sha512-r6upd0uSya0W1PhYPyytuLyxcVxTfwTP4IovhDYL1TM/MHtIfRdhVGVVnjdhQlmZXEF7t8p6LUyBpMETApDgDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.5" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "2.0.3" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-unused-imports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.2.0.tgz", + "integrity": "sha512-6uXyn6xdINEpxE1MtDjxQsyXB37lfyO2yKGVVgtD7WEWQGORSOZjgrD6hBhvGv4/SO+TOlS+UnC6JppRqbuwGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-rule-composer": "^0.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "6 - 7", + "eslint": "8" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + } + } + }, + "node_modules/eslint-rule-composer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", + "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true, + "license": "MIT" + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", + "integrity": "sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.19.0", + "@rollup/rollup-android-arm64": "4.19.0", + "@rollup/rollup-darwin-arm64": "4.19.0", + "@rollup/rollup-darwin-x64": "4.19.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", + "@rollup/rollup-linux-arm-musleabihf": "4.19.0", + "@rollup/rollup-linux-arm64-gnu": "4.19.0", + "@rollup/rollup-linux-arm64-musl": "4.19.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", + "@rollup/rollup-linux-riscv64-gnu": "4.19.0", + "@rollup/rollup-linux-s390x-gnu": "4.19.0", + "@rollup/rollup-linux-x64-gnu": "4.19.0", + "@rollup/rollup-linux-x64-musl": "4.19.0", + "@rollup/rollup-win32-arm64-msvc": "4.19.0", + "@rollup/rollup-win32-ia32-msvc": "4.19.0", + "@rollup/rollup-win32-x64-msvc": "4.19.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", + "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.0.tgz", + "integrity": "sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz", + "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", + "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.39", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.3.tgz", + "integrity": "sha512-14jzwMx7XTcMB+9BhGQyoEAmSl0eOr3nrnn+Z12WNERtOvLN+d2scbRUvyni05rT3997Bg+rZb47NyP4IQPKXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.5", + "pathe": "^1.1.2", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.3.tgz", + "integrity": "sha512-o3HRvU93q6qZK4rI2JrhKyZMMuxg/JRt30E6qeQs6ueaiz5hr1cPj+Sk2kATgQzMMqsa2DiNI0TIK++1ULx8Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@vitest/expect": "2.0.3", + "@vitest/pretty-format": "^2.0.3", + "@vitest/runner": "2.0.3", + "@vitest/snapshot": "2.0.3", + "@vitest/spy": "2.0.3", + "@vitest/utils": "2.0.3", + "chai": "^5.1.1", + "debug": "^4.3.5", + "execa": "^8.0.1", + "magic-string": "^0.30.10", + "pathe": "^1.1.2", + "std-env": "^3.7.0", + "tinybench": "^2.8.0", + "tinypool": "^1.0.0", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.0.3", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.0.3", + "@vitest/ui": "2.0.3", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/core": { + "name": "@next2d/core", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/core": "file:../core", + "@next2d/display": "file:../display", + "@next2d/events": "file:../events", + "@next2d/geom": "file:../geom", + "@next2d/interface": "file:../interface", + "@next2d/media": "file:../media", + "@next2d/net": "file:../net", + "@next2d/share": "file:../share", + "@next2d/text": "file:../text", + "@next2d/util": "file:../util", + "@next2d/webgl": "file:../webgl" + } + }, + "packages/display": { + "name": "@next2d/display", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/core": "file:../core", + "@next2d/events": "file:../events", + "@next2d/geom": "file:../geom", + "@next2d/interface": "file:../interface", + "@next2d/media": "file:../media", + "@next2d/net": "file:../net", + "@next2d/share": "file:../share", + "@next2d/text": "file:../text", + "@next2d/ui": "file:../ui", + "@next2d/util": "file:../util", + "@next2d/webgl": "file:../webgl" + } + }, + "packages/events": { + "name": "@next2d/events", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/core": "file:../core", + "@next2d/display": "file:../display", + "@next2d/interface": "file:../interface", + "@next2d/net": "file:../net", + "@next2d/share": "file:../share", + "@next2d/util": "file:../util" + } + }, + "packages/filters": { + "name": "@next2d/filters", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/share": "file:../share", + "@next2d/webgl": "file:../webgl" + } + }, + "packages/geom": { + "name": "@next2d/geom", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/core": "file:../core", + "@next2d/display": "file:../display", + "@next2d/filters": "file:../filters", + "@next2d/interface": "file:../interface", + "@next2d/share": "file:../share", + "@next2d/util": "file:../util" + } + }, + "packages/interface": { + "name": "@next2d/interface", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/display": "file:../display", + "@next2d/geom": "file:../geom", + "@next2d/net": "file:../net" + } + }, + "packages/media": { + "name": "@next2d/media", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/core": "file:../core", + "@next2d/display": "file:../display", + "@next2d/events": "file:../events", + "@next2d/geom": "file:../geom", + "@next2d/interface": "file:../interface", + "@next2d/net": "file:../net", + "@next2d/share": "file:../share", + "@next2d/util": "file:../util", + "@next2d/webgl": "file:../webgl" + } + }, + "packages/net": { + "name": "@next2d/net", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/core": "file:../core", + "@next2d/interface": "file:../interface", + "@next2d/share": "file:../share", + "@next2d/util": "file:../util" + } + }, + "packages/share": { + "name": "@next2d/share", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/webgl": "file:../webgl" + } + }, + "packages/text": { + "name": "@next2d/text", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/share": "file:../share" + } + }, + "packages/ui": { + "name": "@next2d/ui", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/events": "file:../events", + "@next2d/share": "file:../share" + } + }, + "packages/util": { + "name": "@next2d/util", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/core": "file:../core", + "@next2d/display": "file:../display", + "@next2d/events": "file:../events", + "@next2d/geom": "file:../geom", + "@next2d/interface": "file:../interface", + "@next2d/media": "file:../media", + "@next2d/net": "file:../net", + "@next2d/text": "file:../text" + } + }, + "packages/webgl": { + "name": "@next2d/webgl", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/share": "file:../share" + } + }, + "packages/webpack-worker-loader-plugin": { + "name": "@next2d/webpack-worker-loader-plugin", + "license": "MIT" + } + } +} diff --git a/package.json b/package.json index 872919eb..4c3e7d5a 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,22 @@ { "name": "@next2d/player", - "version": "1.18.12", + "version": "1.18.13", "description": "Experience the fast and beautiful anti-aliased rendering of WebGL. You can create rich, interactive graphics, cross-platform applications and games without worrying about browser or device compatibility.", "author": "Toshiyuki Ienaga (https://github.com/ienaga/)", "license": "MIT", "homepage": "https://next2d.app", "bugs": "https://github.com/Next2D/Player/issues", - "main": "index.js", - "bundle": "dist/next2d.min.js", - "types": "index.d.ts", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist" + ], + "exports": { + ".": { + "import": "./src/index.js", + "require": "./src/index.js" + } + }, "keywords": [ "Next2D", "Next2D Player" @@ -21,12 +29,12 @@ "packages/*" ], "scripts": { - "start": "tsc && node ./scripts/build.js && webpack serve", + "start": "vite --host", "lint": "eslint src/**/*.ts packages/**/*.ts worker/**/*.ts", - "publish:dist": "tsc && node ./scripts/publish.js", + "test": "vitest", "clean": "node ./scripts/clean.js", - "build": "tsc && node ./scripts/build.js && webpack --mode production", - "test": "jest" + "build": "tsc && node ./scripts/build.js", + "publish:dist": "tsc && node ./scripts/publish.js" }, "funding": { "type": "github", @@ -36,24 +44,16 @@ "htmlparser2": "^9.1.0" }, "devDependencies": { - "@babel/core": "^7.24.8", - "@babel/plugin-transform-modules-commonjs": "^7.24.8", - "@babel/preset-env": "^7.24.8", - "@types/jest": "^29.5.12", - "@typescript-eslint/eslint-plugin": "^7.16.0", - "@typescript-eslint/parser": "^7.16.0", + "@types/node": "^20.14.11", + "@typescript-eslint/eslint-plugin": "^7.16.1", + "@typescript-eslint/parser": "^7.16.1", + "@vitest/web-worker": "^2.0.3", "eslint": "^8.52.0", - "eslint-webpack-plugin": "^4.2.0", + "eslint-plugin-unused-imports": "^3.2.0", "fflate": "^0.8.2", - "jest": "^29.7.0", - "jsdoc": "^4.0.3", - "ts-jest": "^29.2.2", - "ts-loader": "^9.5.1", - "ts-node": "^10.9.2", "typescript": "^5.5.3", - "webpack": "^5.93.0", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^5.0.4" + "vite": "^5.3.4", + "vitest": "^2.0.3" }, "peerDependencies": { "@next2d/core": "file:packages/core", @@ -68,7 +68,6 @@ "@next2d/text": "file:packages/text", "@next2d/ui": "file:packages/ui", "@next2d/util": "file:packages/util", - "@next2d/webgl": "file:packages/webgl", - "@next2d/webpack-worker-loader-plugin": "file:packages/webpack-worker-loader-plugin" + "@next2d/webgl": "file:packages/webgl" } } diff --git a/packages/core/package.json b/packages/core/package.json index f6041019..0b0be264 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -6,21 +6,15 @@ "license": "MIT", "homepage": "https://next2d.app", "bugs": "https://github.com/Next2D/Player/issues", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", + "main": "dist/index.js", + "types": "dist/index.d.ts", "files": [ "dist" ], "exports": { ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } + "import": "./src/index.js", + "require": "./src/index.js" } }, "keywords": [ diff --git a/packages/core/src/Player.ts b/packages/core/src/Player.ts index 916ce7bc..9a80e9c8 100644 --- a/packages/core/src/Player.ts +++ b/packages/core/src/Player.ts @@ -1172,7 +1172,7 @@ export class Player // @ts-ignore this._$canvas.addEventListener($MOUSE_UP, loadWebAudio); - // touch event + // @ts-ignore this._$canvas.addEventListener($TOUCH_START, (event: TouchEvent) => { $setEvent(event); @@ -1182,6 +1182,7 @@ export class Player this._$hitTest(); }); + // @ts-ignore this._$canvas.addEventListener($TOUCH_MOVE, (event: TouchEvent) => { $setEvent(event); @@ -1189,6 +1190,7 @@ export class Player this._$hitTest(); }); + // @ts-ignore this._$canvas.addEventListener($TOUCH_END, (event: TouchEvent) => { $setEvent(event); @@ -1196,7 +1198,7 @@ export class Player this._$hitTest(); }); - // mouse wheel + // @ts-ignore this._$canvas.addEventListener($TOUCH_MOVE, (event: TouchEvent) => { $setEvent(event); @@ -1205,7 +1207,7 @@ export class Player this._$hitTest(); }, { "passive": false }); - // mouse event + // @ts-ignore this._$canvas.addEventListener($MOUSE_DOWN, (event: MouseEvent) => { $setEvent(event); @@ -1216,6 +1218,7 @@ export class Player } }); + // @ts-ignore this._$canvas.addEventListener($DOUBLE_CLICK, (event: MouseEvent) => { $setEvent(event); @@ -1226,6 +1229,7 @@ export class Player } }); + // @ts-ignore this._$canvas.addEventListener($MOUSE_LEAVE, (event: MouseEvent) => { $setEvent(event); @@ -1238,6 +1242,7 @@ export class Player this._$stageY = -1; }); + // @ts-ignore this._$canvas.addEventListener($MOUSE_UP, (event: MouseEvent) => { $setEvent(event); @@ -1248,6 +1253,7 @@ export class Player } }); + // @ts-ignore this._$canvas.addEventListener($MOUSE_MOVE, (event: MouseEvent) => { $setEvent(event); @@ -1256,7 +1262,7 @@ export class Player this._$hitTest(); }); - // mouse wheel + // @ts-ignore this._$canvas.addEventListener($MOUSE_WHEEL, (event: MouseEvent) => { if (!event.defaultPrevented) { diff --git a/packages/display/package.json b/packages/display/package.json index 23b99b43..d21842b7 100644 --- a/packages/display/package.json +++ b/packages/display/package.json @@ -13,14 +13,8 @@ ], "exports": { ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } + "import": "./src/index.js", + "require": "./src/index.js" } }, "keywords": [ diff --git a/packages/events/package.json b/packages/events/package.json index cb1551fb..0091c87d 100644 --- a/packages/events/package.json +++ b/packages/events/package.json @@ -13,14 +13,8 @@ ], "exports": { ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } + "import": "./src/index.js", + "require": "./src/index.js" } }, "keywords": [ diff --git a/packages/events/src/EventDispatcher.ts b/packages/events/src/EventDispatcher.ts index 75ec3724..3e087e3f 100644 --- a/packages/events/src/EventDispatcher.ts +++ b/packages/events/src/EventDispatcher.ts @@ -15,25 +15,15 @@ import { } from "@next2d/share"; /** - * EventDispatcher クラスは、イベントを送出するすべてのクラスの基本クラスです。 - * - * The EventDispatcher class is the base class for all classes that dispatch events. - * - * @example Example usage of EventDispatcher. - * // new ColorTransform - * const {EventDispatcher} = next2d.events; - * const eventDispatcher = new EventDispatcher(); - * eventDispatcher.addEventListener(Event.ENTER_FRAME, function (event) - * { - * // more... - * }); + * @description EventDispatcher クラスは、イベントを送出するすべてのクラスの基本クラスです。 + * The EventDispatcher class is the base class for all classes that dispatch events. * * @class * @memberOf next2d.events */ export class EventDispatcher { - public _$events: Map|null; + public _$events: Map | null; /** * @constructor @@ -64,11 +54,11 @@ export class EventDispatcher } /** - * @description 指定されたクラスの空間名を返します。 - * Returns the space name of the specified class. + * @description クラスの空間名を返します。 + * Returns the space name of the class. * * @member {string} - * @default next2d.events.EventDispatcher + * @default "next2d.events.EventDispatcher" * @const * @static */ @@ -78,9 +68,10 @@ export class EventDispatcher } /** - * @description 指定されたオブジェクトのストリングを返します。 - * Returns the string representation of the specified object. + * @description オブジェクトのストリングを返します。 + * Returns the string representation of the object. * + * @default "[object EventDispatcher]" * @return {string} * @method * @public @@ -91,11 +82,11 @@ export class EventDispatcher } /** - * @description 指定されたオブジェクトの空間名を返します。 - * Returns the space name of the specified object. + * @description オブジェクトの空間名を返します。 + * Returns the space name of the object. * * @member {string} - * @default next2d.events.EventDispatcher + * @default "next2d.events.EventDispatcher" * @const * @public */ @@ -112,8 +103,8 @@ export class EventDispatcher * * @param {string} type * @param {function} listener - * @param {boolean} [use_capture=false] - * @param {number} [priority=0] + * @param {boolean} [use_capture = false] + * @param {number} [priority = 0] * @return {void} * @method * @public @@ -244,7 +235,7 @@ export class EventDispatcher * @method * @public */ - dispatchEvent (event: Event) + dispatchEvent (event: Event): boolean { switch (event.type) { @@ -848,7 +839,7 @@ export class EventDispatcher * @method * @public */ - willTrigger (type :string): boolean + willTrigger (type: string): boolean { if (this.hasEventListener(type)) { return true; diff --git a/packages/filters/package.json b/packages/filters/package.json index b04f1282..2da7a1d0 100644 --- a/packages/filters/package.json +++ b/packages/filters/package.json @@ -13,14 +13,8 @@ ], "exports": { ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } + "import": "./src/index.js", + "require": "./src/index.js" } }, "keywords": [ diff --git a/packages/geom/package.json b/packages/geom/package.json index 31c09f82..0ef8066b 100644 --- a/packages/geom/package.json +++ b/packages/geom/package.json @@ -13,14 +13,8 @@ ], "exports": { ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } + "import": "./src/index.js", + "require": "./src/index.js" } }, "keywords": [ diff --git a/packages/interface/package.json b/packages/interface/package.json index 209d12ef..7d262b70 100644 --- a/packages/interface/package.json +++ b/packages/interface/package.json @@ -13,14 +13,8 @@ ], "exports": { ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } + "import": "./src/index.js", + "require": "./src/index.js" } }, "keywords": [ diff --git a/packages/media/package.json b/packages/media/package.json index d58fe311..b7e3b56c 100644 --- a/packages/media/package.json +++ b/packages/media/package.json @@ -13,14 +13,8 @@ ], "exports": { ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } + "import": "./src/index.js", + "require": "./src/index.js" } }, "keywords": [ diff --git a/packages/media/src/Video.ts b/packages/media/src/Video.ts index 7f7d4161..e753e6fe 100644 --- a/packages/media/src/Video.ts +++ b/packages/media/src/Video.ts @@ -513,8 +513,6 @@ export class Video extends DisplayObject if (player._$videos.indexOf(this) === -1) { player._$videos.push(this); } - - this._$ready = true; }); } } @@ -531,7 +529,7 @@ export class Video extends DisplayObject seek (offset: number): void { if (this._$video) { - this._$video.currentTime = offset; + this._$video.currentTime = $Math.min(this._$video.duration, offset); if (this.hasEventListener(VideoEvent.SEEK)) { this.dispatchEvent(new VideoEvent( @@ -591,11 +589,11 @@ export class Video extends DisplayObject } /** - * @return {void} + * @return {Promise} * @method * @private */ - _$start () + async _$start (): Promise { if (!this._$video) { return ; @@ -605,35 +603,36 @@ export class Video extends DisplayObject this._$bounds.yMax = this._$video.videoHeight; this._$bytesTotal = this._$video.duration; - const player = $currentPlayer(); + // init play and stop, reset + if (!this._$ready) { + await this._$video.play(); + this._$video.pause(); + this._$video.currentTime = 0; + this._$ready = true; + } + if (this._$autoPlay) { this._$stop = false; - this - ._$video - .play() - .then(() => - { - if (player._$videos.indexOf(this) === -1) { - player._$videos.push(this); - } - if (this.hasEventListener(VideoEvent.PLAY_START)) { - this.dispatchEvent(new VideoEvent( - VideoEvent.PLAY_START, false, false, - this._$bytesLoaded, this._$bytesTotal - )); - } + const player = $currentPlayer(); + if (player._$videos.indexOf(this) === -1) { + player._$videos.push(this); + } - this._$timerId = $requestAnimationFrame(() => - { - this._$update(); - }); + if (this.hasEventListener(VideoEvent.PLAY_START)) { + this.dispatchEvent(new VideoEvent( + VideoEvent.PLAY_START, false, false, + this._$bytesLoaded, this._$bytesTotal + )); + } - this._$ready = true; + this._$timerId = $requestAnimationFrame(() => + { + this._$update(); + }); - this._$doChanged(); - }); + this._$doChanged(); } this._$createContext(); @@ -662,9 +661,9 @@ export class Video extends DisplayObject video.setAttribute("playsinline", ""); } - video.addEventListener("canplaythrough", () => + video.addEventListener("canplaythrough", async (): Promise => { - this._$start(); + await this._$start(); }); video.addEventListener("ended", () => @@ -864,10 +863,10 @@ export class Video extends DisplayObject // default bounds const bounds: BoundsImpl = $boundsMatrix(this._$bounds, multiMatrix); - const xMax = +bounds.xMax; - const xMin = +bounds.xMin; - const yMax = +bounds.yMax; - const yMin = +bounds.yMin; + const xMax = +bounds.xMax; + const xMin = +bounds.xMin; + const yMax = +bounds.yMax; + const yMin = +bounds.yMin; $poolBoundsObject(bounds); const width: number = $Math.ceil($Math.abs(xMax - xMin)); @@ -1198,7 +1197,7 @@ export class Video extends DisplayObject const message: PropertyVideoMessageImpl = { "command": "createVideo", - "buffer": new Float32Array(), + "buffer": new Float32Array(0), "instanceId": this._$instanceId, "parentId": this._$parent ? this._$parent._$instanceId : -1, "smoothing": this._$smoothing, diff --git a/packages/net/package.json b/packages/net/package.json index f8f6c5eb..f27c595f 100644 --- a/packages/net/package.json +++ b/packages/net/package.json @@ -13,14 +13,8 @@ ], "exports": { ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } + "import": "./src/index.js", + "require": "./src/index.js" } }, "keywords": [ diff --git a/packages/share/package.json b/packages/share/package.json index 5bca16ca..248be15f 100644 --- a/packages/share/package.json +++ b/packages/share/package.json @@ -6,21 +6,15 @@ "license": "MIT", "homepage": "https://next2d.app", "bugs": "https://github.com/Next2D/Player/issues", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", + "main": "dist/index.js", + "types": "dist/index.d.ts", "files": [ "dist" ], "exports": { ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } + "import": "./src/index.js", + "require": "./src/index.js" } }, "keywords": [ diff --git a/packages/text/package.json b/packages/text/package.json index 2cbb6261..2334fe9f 100644 --- a/packages/text/package.json +++ b/packages/text/package.json @@ -13,14 +13,8 @@ ], "exports": { ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } + "import": "./src/index.js", + "require": "./src/index.js" } }, "keywords": [ diff --git a/packages/ui/package.json b/packages/ui/package.json index a7ff7c29..35b879f5 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -13,14 +13,8 @@ ], "exports": { ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } + "import": "./src/index.js", + "require": "./src/index.js" } }, "keywords": [ diff --git a/packages/util/package.json b/packages/util/package.json index a091ff5e..b589b961 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -13,14 +13,8 @@ ], "exports": { ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } + "import": "./src/index.js", + "require": "./src/index.js" } }, "keywords": [ diff --git a/packages/util/src/Util.ts b/packages/util/src/Util.ts index b8c37a02..e6fd77c2 100644 --- a/packages/util/src/Util.ts +++ b/packages/util/src/Util.ts @@ -351,6 +351,7 @@ $textArea.addEventListener("compositionend", (): void => } }); +// @ts-ignore $textArea.addEventListener("input", (event: InputEvent): void => { if (!event.data) { diff --git a/packages/webgl/package.json b/packages/webgl/package.json index e43c2ed7..d25f75cb 100644 --- a/packages/webgl/package.json +++ b/packages/webgl/package.json @@ -13,14 +13,8 @@ ], "exports": { ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } + "import": "./src/index.js", + "require": "./src/index.js" } }, "keywords": [ diff --git a/src/index.js b/src/index.js new file mode 100644 index 00000000..aa35fc0c --- /dev/null +++ b/src/index.js @@ -0,0 +1,29 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("@next2d/util"); +var core_1 = require("@next2d/core"); +if (!("next2d" in window)) { + console.log("%c Next2D Player %c 1.18.12 %c https://next2d.app", "color: #fff; background: #5f5f5f", "color: #fff; background: #4bc729", ""); + window.next2d = new core_1.Next2D([new Promise(function (resolve) { + if (document.readyState === "loading") { + var initialize_1 = function () { + window.removeEventListener("DOMContentLoaded", initialize_1); + (0, util_1.$initialize)() + .then(function () { + (0, util_1.$currentPlayer)() + ._$initializeCanvas(); + resolve(); + }); + }; + window.addEventListener("DOMContentLoaded", initialize_1); + } + else { + (0, util_1.$initialize)() + .then(function () { + (0, util_1.$currentPlayer)() + ._$initializeCanvas(); + resolve(); + }); + } + })]); +} diff --git a/tsconfig.json b/tsconfig.json index 9bc4c58c..f8fbb82b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,25 +1,36 @@ { "compilerOptions": { - "strict": true, + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "Bundler", "resolveJsonModule": true, "strictFunctionTypes": false, "esModuleInterop": true, - "skipLibCheck": true, "declaration": true, - "target": "es6", - "module": "es6", - "lib": [ - "es6", - "dom" - ], - "moduleResolution": "node", + "isolatedModules": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "baseUrl": ".", "outDir": "./dist", "paths": { "@next2d/*": [ "packages/*/src" ] - } + }, + + "types": [ + "vitest/globals" + ] }, "include": [ "src/index.ts", diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 00000000..aab2f27f --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,34 @@ +/// +/// + +import { defineConfig } from "vite"; +import path from "path"; + +export default defineConfig({ + "server": { + "open": "index.html" + }, + "build": { + "outDir": "docs", + "target": "esnext", + "modulePreload": { + "polyfill": false + }, + "rollupOptions": { //ファイル出力設定 + "output": { + "entryFileNames": "next2d.js" + } + } + }, + "resolve": { + "alias": { + "@": path.resolve(process.cwd(), "./src/js") + } + }, + "test": { + "globals": true, + "environment": "jsdom", + "setupFiles": ["@vitest/web-worker"], + "include": ["src/**/*.test.ts"] + } +}); \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 1b96f37f..00000000 --- a/webpack.config.js +++ /dev/null @@ -1,131 +0,0 @@ -const path = require("path"); -const ESLintPlugin = require("eslint-webpack-plugin"); -const WebpackWorkerLoaderPlugin = require("@next2d/webpack-worker-loader-plugin"); - -const unzip_worker = { - "mode": "production", - "entry": path.resolve(__dirname, "worker/unzip/src/index.ts"), - "output": { - "filename": "UnzipWorker.min.js", - "path": path.resolve(__dirname, "worker/unzip") - }, - "cache": { - "type": "filesystem", - "buildDependencies": { - "config": [__filename] - } - }, - "plugins": [ - new ESLintPlugin({ - "extensions": [".ts"], - "exclude": "node_modules" - }) - ], - "module": { - "rules": [ - { - "test": /\.ts$/, - "loader": "ts-loader", - "options": { - "configFile": path.resolve(__dirname, "worker/unzip/tsconfig.json") - } - } - ] - }, - "performance": { - "hints": false - } -}; - -const render_worker = { - "mode": "production", - "entry": path.resolve(__dirname, "worker/renderer/src/index.ts"), - "output": { - "filename": "RendererWorker.min.js", - "path": path.resolve(__dirname, "worker/renderer") - }, - "cache": { - "type": "filesystem", - "buildDependencies": { - "config": [__filename] - } - }, - "plugins": [ - new ESLintPlugin({ - "extensions": [".ts"], - "exclude": "node_modules" - }) - ], - "resolve": { - "alias": { - "@": path.resolve(__dirname, "worker/renderer") - }, - "extensions": [".ts", ".js"] - }, - "module": { - "rules": [ - { - "test": /\.ts$/, - "loader": "ts-loader", - "options": { - "configFile": path.resolve(__dirname, "worker/renderer/tsconfig.json") - } - } - ] - }, - "performance": { - "hints": false - } -}; - -const player = { - "mode": "development", - "entry": path.resolve(__dirname, "src/index.ts"), - "output": { - "filename": "next2d.js", - "path": __dirname - }, - "cache": { - "type": "filesystem", - "buildDependencies": { - "config": [__filename] - } - }, - "plugins": [ - new ESLintPlugin({ - "extensions": [".ts"], - "exclude": "node_modules" - }), - new WebpackWorkerLoaderPlugin() - ], - "resolve": { - "alias": { - "@": path.resolve(__dirname, "src") - }, - "extensions": [".ts", ".js"] - }, - "module": { - "rules": [ - { - "test": /\.ts$/, - "loader": "ts-loader", - "options": { - "configFile": path.resolve(__dirname, "src/tsconfig.json") - } - } - ] - }, - "devServer": { - "static": [ - { "directory": __dirname } - ], - "historyApiFallback": true, - "compress": false, - "open": true - }, - "performance": { - "hints": false - } -}; - -module.exports = [unzip_worker, render_worker, player]; \ No newline at end of file From 037e8273968c8b2dff4b984ccfcd6ffc1a49c89b Mon Sep 17 00:00:00 2001 From: ienaga Date: Mon, 22 Jul 2024 18:54:58 +0900 Subject: [PATCH 002/343] =?UTF-8?q?#154=20vitest=E3=81=AE=E5=B0=8E?= =?UTF-8?q?=E5=85=A5=E6=BA=96=E5=82=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintignore | 3 +- .npmignore | 2 - DEVELOP.md | 7 +- package-lock.json | 963 +++++++++++++++++- package.json | 2 + .../src/interface/EventDispatcherImpl.ts | 3 + packages/geom/src/Point.ts | 100 +- packages/geom/src/Point/Point_length.test.ts | 17 + .../geom/src/Point/Point_toString.test.ts | 27 + packages/geom/src/Rectangle.ts | 168 ++- vite.config.ts | 3 +- 11 files changed, 1091 insertions(+), 204 deletions(-) create mode 100644 packages/events/src/interface/EventDispatcherImpl.ts create mode 100644 packages/geom/src/Point/Point_length.test.ts create mode 100644 packages/geom/src/Point/Point_toString.test.ts diff --git a/.eslintignore b/.eslintignore index aa12f36d..f295a90b 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,5 +2,4 @@ dist json @types -.github -__tests__ \ No newline at end of file +.github \ No newline at end of file diff --git a/.npmignore b/.npmignore index e469565b..43d0ed7a 100644 --- a/.npmignore +++ b/.npmignore @@ -3,12 +3,10 @@ .gitattributes .gitignore .github -__tests__ json node_modules src DOCS.md DEVELOP.md -tsconfig.eslint.json next2d.js vite.config.ts \ No newline at end of file diff --git a/DEVELOP.md b/DEVELOP.md index a48c09f4..c962c2b7 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -3,7 +3,7 @@ ## Version Middleware required for development and supported versions ``` -node >= v17.x +node >= v20.x ``` ## Initial Settings @@ -28,10 +28,5 @@ npm test npm run lint ``` -## Export minify -``` -npm run build -``` - ## License This project is licensed under the [MIT License](https://opensource.org/licenses/MIT) - see the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c907a483..67108d11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "htmlparser2": "^9.1.0" }, "devDependencies": { + "@types/jest": "^29.5.12", "@types/node": "^20.14.11", "@typescript-eslint/eslint-plugin": "^7.16.1", "@typescript-eslint/parser": "^7.16.1", @@ -22,6 +23,7 @@ "eslint": "^8.52.0", "eslint-plugin-unused-imports": "^3.2.0", "fflate": "^0.8.2", + "jsdom": "^24.1.1", "typescript": "^5.5.3", "vite": "^5.3.4", "vitest": "^2.0.3" @@ -60,6 +62,124 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -597,6 +717,50 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -968,6 +1132,13 @@ "win32" ] }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -975,6 +1146,44 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, "node_modules/@types/node": { "version": "20.14.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", @@ -985,6 +1194,30 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.16.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", @@ -1186,14 +1419,14 @@ "license": "ISC" }, "node_modules/@vitest/expect": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.3.tgz", - "integrity": "sha512-X6AepoOYePM0lDNUPsGXTxgXZAl3EXd0GYe/MZyVE4HzkUqyUVC6S3PrY5mClDJ6/7/7vALLMV3+xD/Ko60Hqg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.4.tgz", + "integrity": "sha512-39jr5EguIoanChvBqe34I8m1hJFI4+jxvdOpD7gslZrVQBKhh8H9eD7J/LJX4zakrw23W+dITQTDqdt43xVcJw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "2.0.3", - "@vitest/utils": "2.0.3", + "@vitest/spy": "2.0.4", + "@vitest/utils": "2.0.4", "chai": "^5.1.1", "tinyrainbow": "^1.2.0" }, @@ -1202,9 +1435,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.3.tgz", - "integrity": "sha512-URM4GLsB2xD37nnTyvf6kfObFafxmycCL8un3OC9gaCs5cti2u+5rJdIflZ2fUJUen4NbvF6jCufwViAFLvz1g==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.4.tgz", + "integrity": "sha512-RYZl31STbNGqf4l2eQM1nvKPXE0NhC6Eq0suTTePc4mtMQ1Fn8qZmjV4emZdEdG2NOWGKSCrHZjmTqDCDoeFBw==", "dev": true, "license": "MIT", "dependencies": { @@ -1215,13 +1448,13 @@ } }, "node_modules/@vitest/runner": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.3.tgz", - "integrity": "sha512-EmSP4mcjYhAcuBWwqgpjR3FYVeiA4ROzRunqKltWjBfLNs1tnMLtF+qtgd5ClTwkDP6/DGlKJTNa6WxNK0bNYQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.4.tgz", + "integrity": "sha512-Gk+9Su/2H2zNfNdeJR124gZckd5st4YoSuhF1Rebi37qTXKnqYyFCd9KP4vl2cQHbtuVKjfEKrNJxHHCW8thbQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "2.0.3", + "@vitest/utils": "2.0.4", "pathe": "^1.1.2" }, "funding": { @@ -1229,13 +1462,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.3.tgz", - "integrity": "sha512-6OyA6v65Oe3tTzoSuRPcU6kh9m+mPL1vQ2jDlPdn9IQoUxl8rXhBnfICNOC+vwxWY684Vt5UPgtcA2aPFBb6wg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.4.tgz", + "integrity": "sha512-or6Mzoz/pD7xTvuJMFYEtso1vJo1S5u6zBTinfl+7smGUhqybn6VjzCDMhmTyVOFWwkCMuNjmNNxnyXPgKDoPw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.0.3", + "@vitest/pretty-format": "2.0.4", "magic-string": "^0.30.10", "pathe": "^1.1.2" }, @@ -1244,9 +1477,9 @@ } }, "node_modules/@vitest/spy": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.3.tgz", - "integrity": "sha512-sfqyAw/ypOXlaj4S+w8689qKM1OyPOqnonqOc9T91DsoHbfN5mU7FdifWWv3MtQFf0lEUstEwR9L/q/M390C+A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.4.tgz", + "integrity": "sha512-uTXU56TNoYrTohb+6CseP8IqNwlNdtPwEO0AWl+5j7NelS6x0xZZtP0bDWaLvOfUbaYwhhWp1guzXUxkC7mW7Q==", "dev": true, "license": "MIT", "dependencies": { @@ -1257,13 +1490,13 @@ } }, "node_modules/@vitest/utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.3.tgz", - "integrity": "sha512-c/UdELMuHitQbbc/EVctlBaxoYAwQPQdSNwv7z/vHyBKy2edYZaFgptE27BRueZB7eW8po+cllotMNTDpL3HWg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.4.tgz", + "integrity": "sha512-Zc75QuuoJhOBnlo99ZVUkJIuq4Oj0zAkrQ2VzCqNCx6wAwViHEh5Fnp4fiJTE9rA+sAoXRf00Z9xGgfEzV6fzQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.0.3", + "@vitest/pretty-format": "2.0.4", "estree-walker": "^3.0.3", "loupe": "^3.1.1", "tinyrainbow": "^1.2.0" @@ -1273,9 +1506,9 @@ } }, "node_modules/@vitest/web-worker": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@vitest/web-worker/-/web-worker-2.0.3.tgz", - "integrity": "sha512-r6upd0uSya0W1PhYPyytuLyxcVxTfwTP4IovhDYL1TM/MHtIfRdhVGVVnjdhQlmZXEF7t8p6LUyBpMETApDgDg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/web-worker/-/web-worker-2.0.4.tgz", + "integrity": "sha512-szSNjgmymobgimyIWNDymEwHSRM4MczyhtP+yrKR61vXTqvKWEiu5jiHBnjqMdHLeN3McHOdO5wHK7rLKPYDAg==", "dev": true, "license": "MIT", "dependencies": { @@ -1285,7 +1518,7 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": "2.0.3" + "vitest": "2.0.4" } }, "node_modules/acorn": { @@ -1311,6 +1544,19 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1381,6 +1627,13 @@ "node": ">=12" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1475,6 +1728,22 @@ "node": ">= 16" } }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1495,6 +1764,19 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1517,6 +1799,40 @@ "node": ">= 8" } }, + "node_modules/cssstyle": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", + "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "rrweb-cssom": "^0.6.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cssstyle/node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/debug": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", @@ -1535,6 +1851,13 @@ } } }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true, + "license": "MIT" + }, "node_modules/deep-eql": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", @@ -1552,6 +1875,26 @@ "dev": true, "license": "MIT" }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1937,6 +2280,23 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2070,6 +2430,21 @@ "dev": true, "license": "ISC" }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2211,6 +2586,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -2228,6 +2610,19 @@ "node": ">=8" } }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/htmlparser2": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", @@ -2247,6 +2642,34 @@ "entities": "^4.5.0" } }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/human-signals": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", @@ -2257,6 +2680,19 @@ "node": ">=16.17.0" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -2356,6 +2792,13 @@ "node": ">=8" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, "node_modules/is-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", @@ -2376,6 +2819,94 @@ "dev": true, "license": "ISC" }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -2389,6 +2920,47 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdom": { + "version": "24.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.1.tgz", + "integrity": "sha512-5O1wWV99Jhq4DV7rCLIoZ/UIhyQeDR7wHVyZAHAshbrvZsLs+Xzz7gtwnlJTJDjleiTKh54F4dXrX70vJQTyJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssstyle": "^4.0.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.12", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.4", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -2508,6 +3080,29 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mimic-fn": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", @@ -2599,6 +3194,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/nwsapi": { + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", + "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", + "dev": true, + "license": "MIT" + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2688,6 +3290,19 @@ "node": ">=6" } }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2804,6 +3419,41 @@ "node": ">= 0.8.0" } }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true, + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -2814,6 +3464,13 @@ "node": ">=6" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true, + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -2835,6 +3492,20 @@ ], "license": "MIT" }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -2909,6 +3580,13 @@ "fsevents": "~2.3.2" } }, + "node_modules/rrweb-cssom": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", + "dev": true, + "license": "MIT" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -2933,6 +3611,26 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -3009,6 +3707,29 @@ "node": ">=0.10.0" } }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -3075,6 +3796,13 @@ "node": ">=8" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -3132,6 +3860,35 @@ "node": ">=8.0" } }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -3192,6 +3949,16 @@ "dev": true, "license": "MIT" }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3202,6 +3969,17 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/vite": { "version": "5.3.4", "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", @@ -3259,9 +4037,9 @@ } }, "node_modules/vite-node": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.3.tgz", - "integrity": "sha512-14jzwMx7XTcMB+9BhGQyoEAmSl0eOr3nrnn+Z12WNERtOvLN+d2scbRUvyni05rT3997Bg+rZb47NyP4IQPKXg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.4.tgz", + "integrity": "sha512-ZpJVkxcakYtig5iakNeL7N3trufe3M6vGuzYAr4GsbCTwobDeyPJpE4cjDhhPluv8OvQCFzu2LWp6GkoKRITXA==", "dev": true, "license": "MIT", "dependencies": { @@ -3282,19 +4060,19 @@ } }, "node_modules/vitest": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.3.tgz", - "integrity": "sha512-o3HRvU93q6qZK4rI2JrhKyZMMuxg/JRt30E6qeQs6ueaiz5hr1cPj+Sk2kATgQzMMqsa2DiNI0TIK++1ULx8Jw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.4.tgz", + "integrity": "sha512-luNLDpfsnxw5QSW4bISPe6tkxVvv5wn2BBs/PuDRkhXZ319doZyLOBr1sjfB5yCEpTiU7xCAdViM8TNVGPwoog==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.3.0", - "@vitest/expect": "2.0.3", - "@vitest/pretty-format": "^2.0.3", - "@vitest/runner": "2.0.3", - "@vitest/snapshot": "2.0.3", - "@vitest/spy": "2.0.3", - "@vitest/utils": "2.0.3", + "@vitest/expect": "2.0.4", + "@vitest/pretty-format": "^2.0.4", + "@vitest/runner": "2.0.4", + "@vitest/snapshot": "2.0.4", + "@vitest/spy": "2.0.4", + "@vitest/utils": "2.0.4", "chai": "^5.1.1", "debug": "^4.3.5", "execa": "^8.0.1", @@ -3305,8 +4083,8 @@ "tinypool": "^1.0.0", "tinyrainbow": "^1.2.0", "vite": "^5.0.0", - "vite-node": "2.0.3", - "why-is-node-running": "^2.2.2" + "vite-node": "2.0.4", + "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" @@ -3320,8 +4098,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.0.3", - "@vitest/ui": "2.0.3", + "@vitest/browser": "2.0.4", + "@vitest/ui": "2.0.4", "happy-dom": "*", "jsdom": "*" }, @@ -3346,6 +4124,66 @@ } } }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3396,6 +4234,45 @@ "dev": true, "license": "ISC" }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 4c3e7d5a..85d70ab5 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "htmlparser2": "^9.1.0" }, "devDependencies": { + "@types/jest": "^29.5.12", "@types/node": "^20.14.11", "@typescript-eslint/eslint-plugin": "^7.16.1", "@typescript-eslint/parser": "^7.16.1", @@ -51,6 +52,7 @@ "eslint": "^8.52.0", "eslint-plugin-unused-imports": "^3.2.0", "fflate": "^0.8.2", + "jsdom": "^24.1.1", "typescript": "^5.5.3", "vite": "^5.3.4", "vitest": "^2.0.3" diff --git a/packages/events/src/interface/EventDispatcherImpl.ts b/packages/events/src/interface/EventDispatcherImpl.ts new file mode 100644 index 00000000..8674f35f --- /dev/null +++ b/packages/events/src/interface/EventDispatcherImpl.ts @@ -0,0 +1,3 @@ +import { EventDispatcher } from "../EventDispatcher"; + +export type EventDispatcherImpl = T; diff --git a/packages/geom/src/Point.ts b/packages/geom/src/Point.ts index 1692125a..96d2e603 100644 --- a/packages/geom/src/Point.ts +++ b/packages/geom/src/Point.ts @@ -1,21 +1,8 @@ -import { - $Math, - $clamp, - $SHORT_INT_MIN, - $SHORT_INT_MAX -} from "@next2d/share"; - /** - * Point オブジェクトは 2 次元の座標系の位置を表します。 - * x は水平方向の軸を表し、y は垂直方向の軸を表します。 - * - * The Point object represents a location in a two-dimensional coordinate system, - * where x represents the horizontal axis and y represents the vertical axis. - * - * @example Example usage of Point. - * // new Point - * const {Point} = next2d.geom; - * const point = new Point(); + * @description Point オブジェクトは 2 次元の座標系の位置を表します。 + * x は水平方向の軸を表し、y は垂直方向の軸を表します。 + * The Point object represents a location in a two-dimensional coordinate system, + * where x represents the horizontal axis and y represents the vertical axis. * * @class * @memberOf next2d.geom @@ -26,9 +13,8 @@ export class Point private _$y: number; /** - * @param {number} [x=0] - * @param {number} [y=0] - * + * @param {number} [x = 0] + * @param {number} [y = 0] * @constructor * @public */ @@ -39,18 +25,14 @@ export class Point * @default 0 * @private */ - this._$x = 0; + this._$x = x; /** * @type {number} * @default 0 * @private */ - this._$y = 0; - - // setup - this.x = x; - this.y = y; + this._$y = y; } /** @@ -58,7 +40,7 @@ export class Point * Returns the string representation of the specified class. * * @return {string} - * @default [class Point] + * @default "[class Point]" * @method * @static */ @@ -72,7 +54,7 @@ export class Point * Returns the space name of the specified class. * * @member {string} - * @default next2d.geom.Point + * @default "next2d.geom.Point" * @const * @static */ @@ -91,7 +73,7 @@ export class Point */ toString (): string { - return `(x=${this.x}, y=${this.y})`; + return `(x=${this._$x}, y=${this._$y})`; } /** @@ -119,7 +101,7 @@ export class Point */ get length (): number { - return $Math.sqrt($Math.pow(this.x, 2) + $Math.pow(this.y, 2)); + return Math.sqrt(Math.pow(this._$x, 2) + Math.pow(this._$y, 2)); } /** @@ -136,7 +118,7 @@ export class Point } set x (x: number) { - this._$x = $clamp(+x, $SHORT_INT_MIN, $SHORT_INT_MAX, 0); + this._$x = x; } /** @@ -153,7 +135,7 @@ export class Point } set y (y: number) { - this._$y = $clamp(+y, $SHORT_INT_MIN, $SHORT_INT_MAX, 0); + this._$y = y; } /** @@ -161,14 +143,14 @@ export class Point * Adds the coordinates of another point * to the coordinates of this point to create a new point. * - * @param {Point} v + * @param {Point} point * @returns {Point} * @method * @public */ - add (v: Point): Point + add (point: Point): Point { - return new Point(this.x + v.x, this.y + v.y); + return new Point(this._$x + point.x, this._$y + point.y); } /** @@ -181,7 +163,7 @@ export class Point */ clone (): Point { - return new Point(this.x, this.y); + return new Point(this._$x, this._$y); } /** @@ -190,14 +172,14 @@ export class Point * Copies all of the point data from * the source Point object into the calling Point object. * - * @param {Point} source_point + * @param {Point} point * @returns void * @public */ - copyFrom (source_point: Point): void + copyFrom (point: Point): void { - this._$x = source_point._$x; - this._$y = source_point._$y; + this._$x = point.x; + this._$y = point.y; } /** @@ -212,9 +194,9 @@ export class Point */ static distance (point1: Point, point2: Point): number { - return $Math.sqrt( - $Math.pow(point1._$x - point2._$x, 2) - + $Math.pow(point1._$y - point2._$y, 2) + return Math.sqrt( + Math.pow(point1._$x - point2._$x, 2) + + Math.pow(point1._$y - point2._$y, 2) ); } @@ -262,8 +244,8 @@ export class Point normalize (thickness: number): void { const length = this.length; - this.x = this.x * thickness / length; - this.y = this.y * thickness / length; + this._$x = this._$x * thickness / length; + this._$y = this._$y * thickness / length; } /** @@ -276,41 +258,41 @@ export class Point * @method * @public */ - offset (dx: number, dy: number) + offset (dx: number, dy: number): void { - this.x += dx; - this.y += dy; + this._$x += dx; + this._$y += dy; } /** * @description 極座標ペアを直交点座標に変換します。 * Converts a pair of polar coordinates to a Cartesian point coordinate. * - * @param {number} len + * @param {number} length * @param {number} angle * @return {Point} * @method * @static */ - static polar (len: number, angle: number): Point + static polar (length: number, angle: number): Point { - return new Point(len * $Math.cos(angle), len * $Math.sin(angle)); + return new Point(length * Math.cos(angle), length * Math.sin(angle)); } /** * @description Point のメンバーを指定の値に設定します。 * Sets the members of Point to the specified values * - * @param {number} xa - * @param {number} ya + * @param {number} x + * @param {number} y * @return {void} * @method * @public */ - setTo (xa: number, ya: number): void + setTo (x: number, y: number): void { - this.x = xa; - this.y = ya; + this._$x = x; + this._$y = y; } /** @@ -318,13 +300,13 @@ export class Point * Subtracts the coordinates of another point * from the coordinates of this point to create a new point. * - * @param {Point} v + * @param {Point} point * @return {Point} * @method * @public */ - subtract (v: Point): Point + subtract (point: Point): Point { - return new Point(this.x - v.x, this.y - v.y); + return new Point(this._$x - point.x, this._$y - point.y); } } diff --git a/packages/geom/src/Point/Point_length.test.ts b/packages/geom/src/Point/Point_length.test.ts new file mode 100644 index 00000000..84ff3951 --- /dev/null +++ b/packages/geom/src/Point/Point_length.test.ts @@ -0,0 +1,17 @@ +import { Point } from "../Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js length test", () => +{ + it("default test case1", () => + { + const point = new Point(); + expect(point.length).toBe(0); + }); + + it("default test case2", () => + { + const point = new Point(10, 30); + expect(point.length).toBe(31.622776601683793); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Point/Point_toString.test.ts b/packages/geom/src/Point/Point_toString.test.ts new file mode 100644 index 00000000..89687eb1 --- /dev/null +++ b/packages/geom/src/Point/Point_toString.test.ts @@ -0,0 +1,27 @@ +import { Point } from "../Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js toString test", () => +{ + it("toString test1 success", () => + { + const point = new Point(); + expect(point.toString()).toBe("(x=0, y=0)"); + }); + + it("toString test2 success", () => + { + const point = new Point(1, 2); + expect(point.toString()).toBe("(x=1, y=2)"); + }); +}); + +describe("Point.js static toString test", () => +{ + + it("static toString test", () => + { + expect(Point.toString()).toBe("[class Point]"); + }); + +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle.ts b/packages/geom/src/Rectangle.ts index d21eb15a..e5ce111d 100644 --- a/packages/geom/src/Rectangle.ts +++ b/packages/geom/src/Rectangle.ts @@ -1,31 +1,20 @@ import { Point } from "./Point"; -import { - $Math, - $clamp, - $SHORT_INT_MIN, - $SHORT_INT_MAX -} from "@next2d/share"; /** - * Rectangle オブジェクトは、その位置(左上隅のポイント (x, y) で示される)、および幅と高さで定義される領域です。 - * Rectangle クラスの x、y、width、および height の各プロパティは、互いに独立しているため、 - * あるプロパティの値を変更しても、他のプロパティに影響はありません。 - * ただし、right プロパティと bottom プロパティはこれら 4 つのプロパティと不可分に関連しています。 - * 例えば、right プロパティの値を変更すると width プロパティの値も変更されます。 - * bottom プロパティの値を変更すると、height プロパティの値も変更されます。 + * @description Rectangle オブジェクトは、その位置(左上隅のポイント (x, y) で示される)、および幅と高さで定義される領域です。 + * Rectangle クラスの x、y、width、および height の各プロパティは、互いに独立しているため、 + * あるプロパティの値を変更しても、他のプロパティに影響はありません。 + * ただし、right プロパティと bottom プロパティはこれら 4 つのプロパティと不可分に関連しています。 + * 例えば、right プロパティの値を変更すると width プロパティの値も変更されます。 + * bottom プロパティの値を変更すると、height プロパティの値も変更されます。 * - * A Rectangle object is an area defined by its position, - * as indicated by its top-left corner point (x, y) and by its width and its height. - * The x, y, width, and height properties of the Rectangle class are independent of each other; - * changing the value of one property has no effect on the others. However, - * the right and bottom properties are integrally related to those four properties. - * For example, if you change the value of the right property, the value of the width property changes; - * if you change the bottom property, the value of the height property changes. - * - * @example Example usage of Rectangle. - * // new Rectangle - * const {Rectangle} = next2d.geom; - * const rectangle = new Rectangle(0, 0, 100, 100); + * A Rectangle object is an area defined by its position, + * as indicated by its top-left corner point (x, y) and by its width and its height. + * The x, y, width, and height properties of the Rectangle class are independent of each other; + * changing the value of one property has no effect on the others. However, + * the right and bottom properties are integrally related to those four properties. + * For example, if you change the value of the right property, the value of the width property changes; + * if you change the bottom property, the value of the height property changes. * * @class * @memberOf next2d.geom @@ -55,31 +44,28 @@ export class Rectangle * @default 0 * @private */ - this._$x = 0; + this._$x = x; /** * @type {number} * @default 0 * @private */ - this._$y = 0; + this._$y = y; /** * @type {number} * @default 0 * @private */ - this._$width = 0; + this._$width = width; /** * @type {number} * @default 0 * @private */ - this._$height = 0; - - // init - this.setTo(x, y, width, height); + this._$height = height; } /** @@ -87,7 +73,7 @@ export class Rectangle * Returns the string representation of the specified class. * * @return {string} - * @default [class Rectangle] + * @default "[class Rectangle]" * @method * @static */ @@ -101,7 +87,7 @@ export class Rectangle * Returns the space name of the specified class. * * @member {string} - * @default next2d.geom.Rectangle + * @default "next2d.geom.Rectangle" * @const * @static */ @@ -128,7 +114,7 @@ export class Rectangle * Returns the space name of the specified object. * * @member {string} - * @default next2d.geom.Rectangle + * @default "next2d.geom.Rectangle" * @const * @public */ @@ -146,11 +132,11 @@ export class Rectangle */ get bottom (): number { - return this.y + this.height; + return this._$y + this._$height; } set bottom (bottom: number) { - this.height = +bottom - this.y; + this._$height = bottom - this._$y; } /** @@ -185,7 +171,7 @@ export class Rectangle } set height (height: number) { - this._$height = $clamp(+height, $SHORT_INT_MIN, $SHORT_INT_MAX, 0); + this._$height = height; } /** @@ -197,12 +183,12 @@ export class Rectangle */ get left (): number { - return this.x; + return this._$x; } set left (left: number) { - this.width = this.right - +left; - this.x = left; + this._$width = this.right - left; + this._$x = left; } /** @@ -214,11 +200,11 @@ export class Rectangle */ get right (): number { - return this.x + this.width; + return this._$x + this.width; } set right (right: number) { - this.width = +right - this.x; + this._$width = right - this._$x; } /** @@ -232,12 +218,12 @@ export class Rectangle */ get size (): Point { - return new Point(this.width, this.height); + return new Point(this._$width, this._$height); } set size (point: Point) { - this.width = point.x; - this.height = point.y; + this._$width = point.x; + this._$height = point.y; } /** @@ -249,12 +235,12 @@ export class Rectangle */ get top (): number { - return this.y; + return this._$y; } set top (top: number) { - this.height = +(this.bottom - +top); - this.y = top; + this._$height = this.bottom - top; + this._$y = top; } /** @@ -268,7 +254,7 @@ export class Rectangle */ get topLeft (): Point { - return new Point(this.x, this.y); + return new Point(this._$x, this._$y); } set topLeft (point: Point) { @@ -289,7 +275,7 @@ export class Rectangle } set width (width: number) { - this._$width = $clamp(+width, $SHORT_INT_MIN, $SHORT_INT_MAX, 0); + this._$width = width; } /** @@ -305,7 +291,7 @@ export class Rectangle } set x (x: number) { - this._$x = $clamp(+x, $SHORT_INT_MIN, $SHORT_INT_MAX, 0); + this._$x = x; } /** @@ -321,7 +307,7 @@ export class Rectangle } set y (y: number) { - this._$y = $clamp(+y, $SHORT_INT_MIN, $SHORT_INT_MAX, 0); + this._$y = y; } /** @@ -336,7 +322,7 @@ export class Rectangle */ clone (): Rectangle { - return new Rectangle(this.x, this.y, this.width, this.height); + return new Rectangle(this._$x, this._$y, this._$width, this._$height); } /** @@ -352,7 +338,7 @@ export class Rectangle */ contains (x: number, y: number): boolean { - return this.x <= x && this.y <= y && this.right > x && this.bottom > y; + return this._$x <= x && this._$y <= y && this.right > x && this.bottom > y; } /** @@ -367,7 +353,7 @@ export class Rectangle */ containsPoint (point: Point): boolean { - return this.x <= point.x && this.y <= point.y && + return this._$x <= point.x && this._$y <= point.y && this.right > point.x && this.bottom > point.y; } @@ -383,7 +369,7 @@ export class Rectangle */ containsRect (rect: Rectangle): boolean { - return this.x <= rect.x && this.y <= rect.y && + return this._$x <= rect.x && this._$y <= rect.y && this.right >= rect.right && this.bottom >= rect.bottom; } @@ -400,10 +386,10 @@ export class Rectangle */ copyFrom (source_rect: Rectangle): void { - this.x = source_rect.x; - this.y = source_rect.y; - this.width = source_rect.width; - this.height = source_rect.height; + this._$x = source_rect.x; + this._$y = source_rect.y; + this._$width = source_rect.width; + this._$height = source_rect.height; } /** @@ -419,8 +405,8 @@ export class Rectangle */ equals (to_compare: Rectangle): boolean { - return this.x === to_compare.x && this.y === to_compare.y && - this.width === to_compare.width && this.height === to_compare.height; + return this._$x === to_compare.x && this._$y === to_compare.y && + this._$width === to_compare.width && this._$height === to_compare.height; } /** @@ -435,11 +421,11 @@ export class Rectangle */ inflate (dx: number, dy: number): void { - this.x = this.x - +dx; - this.width = this.width + 2 * +dx; + this._$x = this._$x - dx; + this._$width = this._$width + 2 * dx; - this.y = this.y - +dy; - this.height = this.height + 2 * +dy; + this._$y = this._$y - dy; + this._$height = this._$height + 2 * dy; } /** @@ -453,11 +439,11 @@ export class Rectangle */ inflatePoint (point: Point): void { - this.x = this.x - point.x; - this.width = this.width + 2 * point.x; + this._$x = this._$x - point.x; + this._$width = this._$width + 2 * point.x; - this.y = this.y - point.y; - this.height = this.height + 2 * point.y; + this._$y = this._$y - point.y; + this._$height = this._$height + 2 * point.y; } /** @@ -473,10 +459,10 @@ export class Rectangle */ intersection (to_intersect: Rectangle): Rectangle { - const sx = $Math.max(this.x, to_intersect.x); - const sy = $Math.max(this.y, to_intersect.y); - const ex = $Math.min(this.right, to_intersect.right); - const ey = $Math.min(this.bottom, to_intersect.bottom); + const sx = Math.max(this._$x, to_intersect.x); + const sy = Math.max(this._$y, to_intersect.y); + const ex = Math.min(this.right, to_intersect.right); + const ey = Math.min(this.bottom, to_intersect.bottom); const w = ex - sx; const h = ey - sy; @@ -496,10 +482,10 @@ export class Rectangle */ intersects (to_intersect: Rectangle): boolean { - const sx = $Math.max(this.x, to_intersect.x); - const sy = $Math.max(this.y, to_intersect.y); - const ex = $Math.min(this.right, to_intersect.right); - const ey = $Math.min(this.bottom, to_intersect.bottom); + const sx = Math.max(this._$x, to_intersect.x); + const sy = Math.max(this._$y, to_intersect.y); + const ex = Math.min(this.right, to_intersect.right); + const ey = Math.min(this.bottom, to_intersect.bottom); return ex - sx > 0 && ey - sy > 0; } @@ -513,7 +499,7 @@ export class Rectangle */ isEmpty (): boolean { - return this.width <= 0 || this.height <= 0; + return this._$width <= 0 || this._$height <= 0; } /** @@ -529,8 +515,8 @@ export class Rectangle */ offset (dx: number ,dy: number): void { - this.x += dx; - this.y += dy; + this._$x += dx; + this._$y += dy; } /** @@ -544,8 +530,8 @@ export class Rectangle */ offsetPoint (point: Point): void { - this.x += point.x; - this.y += point.y; + this._$x += point.x; + this._$y += point.y; } /** @@ -578,10 +564,10 @@ export class Rectangle */ setTo (x: number, y: number, width: number, height: number): void { - this.x = x; - this.y = y; - this.width = width; - this.height = height; + this._$x = x; + this._$y = y; + this._$width = width; + this._$height = height; } /** @@ -606,10 +592,10 @@ export class Rectangle } return new Rectangle( - $Math.min(this.x, to_union.x), - $Math.min(this.y, to_union.y), - $Math.max(this.right - to_union.left, to_union.right - this.left), - $Math.max(this.bottom - to_union.top, to_union.bottom - this.top) + Math.min(this._$x, to_union.x), + Math.min(this._$y, to_union.y), + Math.max(this.right - to_union.left, to_union.right - this.left), + Math.max(this.bottom - to_union.top, to_union.bottom - this.top) ); } } diff --git a/vite.config.ts b/vite.config.ts index aab2f27f..3b6650e7 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,5 +1,6 @@ /// /// +/// import { defineConfig } from "vite"; import path from "path"; @@ -29,6 +30,6 @@ export default defineConfig({ "globals": true, "environment": "jsdom", "setupFiles": ["@vitest/web-worker"], - "include": ["src/**/*.test.ts"] + "include": ["packages/**/*.test.ts"] } }); \ No newline at end of file From 469a6939a275b78a01cd9894c061c694d0046f64 Mon Sep 17 00:00:00 2001 From: ienaga Date: Mon, 22 Jul 2024 21:57:27 +0900 Subject: [PATCH 003/343] =?UTF-8?q?#154=20feat:=20Point=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E3=82=92=E7=A7=BB=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/integration.yml | 4 - .gitignore | 1 + __tests__/next2d/geom/PointTest.ts | 1456 ----------------- package.json | 1 + packages/geom/package.json | 8 - packages/geom/src/Point.test.ts | 56 + packages/geom/src/Point.ts | 55 +- packages/geom/src/Point/Point_length.test.ts | 17 - .../geom/src/Point/Point_toString.test.ts | 27 - .../src/Point/service/PointAddService.test.ts | 54 + .../geom/src/Point/service/PointAddService.ts | 16 + .../Point/service/PointCloneService.test.ts | 26 + .../src/Point/service/PointCloneService.ts | 15 + .../service/PointCopyFromService.test.ts | 52 + .../src/Point/service/PointCopyFromService.ts | 17 + .../service/PointDistanceService.test.ts | 117 ++ .../src/Point/service/PointDistanceService.ts | 19 + .../Point/service/PointEqualsService.test.ts | 62 + .../src/Point/service/PointEqualsService.ts | 16 + .../service/PointInterpolateService.test.ts | 183 +++ .../Point/service/PointInterpolateService.ts | 20 + .../service/PointNormalizeService.test.ts | 48 + .../Point/service/PointNormalizeService.ts | 17 + .../Point/service/PointOffsetService.test.ts | 42 + .../src/Point/service/PointOffsetService.ts | 18 + .../Point/service/PointPolarService.test.ts | 192 +++ .../src/Point/service/PointPolarService.ts | 16 + .../Point/service/PointSetToService.test.ts | 21 + .../src/Point/service/PointSetToService.ts | 18 + .../service/PointSubtractService.test.ts | 23 + .../src/Point/service/PointSubtractService.ts | 16 + vite.config.ts | 2 +- 32 files changed, 1096 insertions(+), 1539 deletions(-) delete mode 100644 __tests__/next2d/geom/PointTest.ts create mode 100644 packages/geom/src/Point.test.ts delete mode 100644 packages/geom/src/Point/Point_length.test.ts delete mode 100644 packages/geom/src/Point/Point_toString.test.ts create mode 100644 packages/geom/src/Point/service/PointAddService.test.ts create mode 100644 packages/geom/src/Point/service/PointAddService.ts create mode 100644 packages/geom/src/Point/service/PointCloneService.test.ts create mode 100644 packages/geom/src/Point/service/PointCloneService.ts create mode 100644 packages/geom/src/Point/service/PointCopyFromService.test.ts create mode 100644 packages/geom/src/Point/service/PointCopyFromService.ts create mode 100644 packages/geom/src/Point/service/PointDistanceService.test.ts create mode 100644 packages/geom/src/Point/service/PointDistanceService.ts create mode 100644 packages/geom/src/Point/service/PointEqualsService.test.ts create mode 100644 packages/geom/src/Point/service/PointEqualsService.ts create mode 100644 packages/geom/src/Point/service/PointInterpolateService.test.ts create mode 100644 packages/geom/src/Point/service/PointInterpolateService.ts create mode 100644 packages/geom/src/Point/service/PointNormalizeService.test.ts create mode 100644 packages/geom/src/Point/service/PointNormalizeService.ts create mode 100644 packages/geom/src/Point/service/PointOffsetService.test.ts create mode 100644 packages/geom/src/Point/service/PointOffsetService.ts create mode 100644 packages/geom/src/Point/service/PointPolarService.test.ts create mode 100644 packages/geom/src/Point/service/PointPolarService.ts create mode 100644 packages/geom/src/Point/service/PointSetToService.test.ts create mode 100644 packages/geom/src/Point/service/PointSetToService.ts create mode 100644 packages/geom/src/Point/service/PointSubtractService.test.ts create mode 100644 packages/geom/src/Point/service/PointSubtractService.ts diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 19aa8db6..c4c34cc7 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -17,8 +17,6 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 - run: npm install - - run: npm run clean - - run: npm run build - run: npm run test windows-browser-test: @@ -27,6 +25,4 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 - run: npm install - - run: npm run clean - - run: npm run build - run: npm run test diff --git a/.gitignore b/.gitignore index ebc9334e..d52f50f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ node_modules json dist +build coverage *.html .DS_Store diff --git a/__tests__/next2d/geom/PointTest.ts b/__tests__/next2d/geom/PointTest.ts deleted file mode 100644 index 27289183..00000000 --- a/__tests__/next2d/geom/PointTest.ts +++ /dev/null @@ -1,1456 +0,0 @@ -import { Point } from "../../../packages/geom/src/Point"; -import { - $SHORT_INT_MAX, - $SHORT_INT_MIN -} from "../../../packages/share/src/RenderUtil"; - -describe("Point.js toString test", () => -{ - it("toString test1 success", () => - { - const object = new Point(); - expect(object.toString()).toBe("(x=0, y=0)"); - }); - - it("toString test2 success", () => - { - const object = new Point(1, 2); - expect(object.toString()).toBe("(x=1, y=2)"); - }); -}); - -describe("Point.js static toString test", () => -{ - - it("static toString test", () => - { - expect(Point.toString()).toBe("[class Point]"); - }); - -}); - -describe("Point.js namespace test", () => -{ - - it("namespace test public", () => - { - const object = new Point(); - expect(object.namespace).toBe("next2d.geom.Point"); - }); - - it("namespace test static", () => - { - expect(Point.namespace).toBe("next2d.geom.Point"); - }); - -}); - -describe("Point.js property valid test and clone test", () => -{ - - it("valid and clone test", function () { - - // @ts-ignore - let p1 = new Point("a", "b"); - // @ts-ignore - p1.x = "a"; - // @ts-ignore - p1.y = "b"; - - // clone - let p2 = p1.clone(); - p2.x = 10; - p2.y = 20; - - // origin - expect(p1.x).toBe(0); - expect(p1.y).toBe(0); - - // clone - expect(p2.x).toBe(10); - expect(p2.y).toBe(20); - expect(p2.length).toBe(22.360679774997898); - expect(p2.toString()).toBe("(x=10, y=20)"); - }); - -}); - -describe("Point.js add test", () => -{ - - it("add test1", () => - { - let p1 = new Point(10, 10); - let p2 = new Point(20, 20); - - let p3 = p1.add(p1); - let p4 = p2.add(p2); - let p5 = p1.add(p2); - let p6 = p2.add(p1); - - expect(p3.toString()).toBe("(x=20, y=20)"); - expect(p4.toString()).toBe("(x=40, y=40)"); - expect(p5.toString()).toBe("(x=30, y=30)"); - expect(p6.toString()).toBe("(x=30, y=30)"); - }); - - it("add test2", () => - { - let p1 = new Point(-10, -10); - let p2 = new Point(20, -20); - - let p3 = p1.add(p1); - let p4 = p2.add(p2); - let p5 = p1.add(p2); - let p6 = p2.add(p1); - - expect(p3.toString()).toBe("(x=-20, y=-20)"); - expect(p4.toString()).toBe("(x=40, y=-40)"); - expect(p5.toString()).toBe("(x=10, y=-30)"); - expect(p6.toString()).toBe("(x=10, y=-30)"); - }); - - it("add test3", () => - { - // @ts-ignore - let p1 = new Point("a", 10); - let p2 = new Point(20, 0); - - let p3 = p1.add(p1); - let p4 = p2.add(p2); - let p5 = p1.add(p2); - let p6 = p2.add(p1); - - expect(p3.toString()).toBe("(x=0, y=20)"); - expect(p4.toString()).toBe("(x=40, y=0)"); - expect(p5.toString()).toBe("(x=20, y=10)"); - expect(p6.toString()).toBe("(x=20, y=10)"); - }); - -}); - -describe("Point.js copyFrom test", () => -{ - - it("copyFrom test1", () => - { - let p1 = new Point(10, 10); - let p2 = new Point(20, 20); - - p1.copyFrom(p2); - p1.x = 10; - - expect(p1.toString()).toBe("(x=10, y=20)"); - expect(p2.toString()).toBe("(x=20, y=20)"); - }); - - it("copyFrom test2", () => - { - let p1 = new Point(-10, -10); - let p2 = new Point(20, -20); - - p1.copyFrom(p2); - - expect(p1.toString()).toBe("(x=20, y=-20)"); - expect(p2.toString()).toBe("(x=20, y=-20)"); - }); - - it("copyFrom test3", () => - { - // @ts-ignore - let p1 = new Point("a", 10); - let p2 = new Point(20, 0); - - p1.copyFrom(p2); - - expect(p1.toString()).toBe("(x=20, y=0)"); - expect(p2.toString()).toBe("(x=20, y=0)"); - }); - - it("copyFrom test4", () => - { - let p1 = new Point(10, 10); - // @ts-ignore - let p2 = new Point("a", 20); - - p1.copyFrom(p2); - - expect(p1.toString()).toBe("(x=0, y=20)"); - expect(p2.toString()).toBe("(x=0, y=20)"); - }); - -}); - -describe("Point.js distance test", () => -{ - - it("distance test1", () => - { - let p1 = new Point(10, 10); - let p2 = new Point(20, 20); - let d = Point.distance(p1, p2); - expect(d).toBe(14.142135623730951); - }); - - it("distance test2", () => - { - let p1 = new Point(-10, 10); - let p2 = new Point(20, 20); - let d = Point.distance(p1, p2); - expect(d).toBe(31.622776601683793); - }); - - it("distance test3", () => - { - let p1 = new Point(10, -10); - let p2 = new Point(20, 20); - let d = Point.distance(p1, p2); - expect(d).toBe(31.622776601683793); - }); - - it("distance test4", () => - { - let p1 = new Point(10, 10); - let p2 = new Point(-20, 20); - let d = Point.distance(p1, p2); - expect(d).toBe(31.622776601683793); - }); - - it("distance test5", () => - { - let p1 = new Point(10, 10); - let p2 = new Point(20, -20); - let d = Point.distance(p1, p2); - expect(d).toBe(31.622776601683793); - }); - - it("distance test6", () => - { - let p1 = new Point(10, -10); - let p2 = new Point(20, -20); - let d = Point.distance(p1, p2); - expect(d).toBe(14.142135623730951); - }); - - it("distance test7", () => - { - let p1 = new Point(-10, 10); - let p2 = new Point(-20, 20); - let d = Point.distance(p1, p2); - expect(d).toBe(14.142135623730951); - }); - - it("distance test8", () => - { - let p1 = new Point(-10, -10); - let p2 = new Point(20, 20); - let d = Point.distance(p1, p2); - expect(d).toBe(42.42640687119285); - }); - - it("distance test9", () => - { - let p1 = new Point(10, 10); - let p2 = new Point(-20, -20); - let d = Point.distance(p1, p2); - expect(d).toBe(42.42640687119285); - }); - - it("distance test10", () => - { - let p1 = new Point(-10, 10); - let p2 = new Point(20, -20); - let d = Point.distance(p1, p2); - expect(d).toBe(42.42640687119285); - }); - - it("distance test11", () => - { - let p1 = new Point(10, -10); - let p2 = new Point(-20, 20); - let d = Point.distance(p1, p2); - expect(d).toBe(42.42640687119285); - }); - - it("distance test12", () => - { - let p1 = new Point(-10, -10); - let p2 = new Point(-20, 20); - let d = Point.distance(p1, p2); - expect(d).toBe(31.622776601683793); - }); - - it("distance test13", () => - { - let p1 = new Point(10, -10); - let p2 = new Point(-20, -20); - let d = Point.distance(p1, p2); - expect(d).toBe(31.622776601683793); - }); - - it("distance test14", () => - { - let p1 = new Point(-10, 10); - let p2 = new Point(-20, -20); - let d = Point.distance(p1, p2); - expect(d).toBe(31.622776601683793); - }); - - it("distance test15", () => - { - let p1 = new Point(-10, -10); - let p2 = new Point(20, -20); - let d = Point.distance(p1, p2); - expect(d).toBe(31.622776601683793); - }); - - it("distance test16", () => - { - let p1 = new Point(-10, -10); - let p2 = new Point(-20, -20); - let d = Point.distance(p1, p2); - expect(d).toBe(14.142135623730951); - }); - - it("distance test1", () => - { - // @ts-ignore - let p1 = new Point("a", 10); - let p2 = new Point(20, 20); - let d = Point.distance(p1, p2); - expect(d).toBe(22.360679774997898); - }); - - it("distance test1", () => - { - // @ts-ignore - let p1 = new Point(10, "a"); - let p2 = new Point(20, 20); - let d = Point.distance(p1, p2); - expect(d).toBe(22.360679774997898); - }); - - it("distance test1", () => - { - let p1 = new Point(10, 10); - // @ts-ignore - let p2 = new Point("a", 20); - let d = Point.distance(p1, p2); - expect(d).toBe(14.142135623730951); - }); - - it("distance test1", () => - { - let p1 = new Point(10, 10); - // @ts-ignore - let p2 = new Point(20, "a"); - let d = Point.distance(p1, p2); - expect(d).toBe(14.142135623730951); - }); - -}); - -describe("Point.js equals test", () => -{ - - it("equals test1", () => - { - let p1 = new Point(10, 10); - let p2 = new Point(10, 10); - let p3 = new Point(10, 20); - let p4 = new Point(20, 10); - let p5 = new Point(20, 20); - - expect(p1.equals(p2)).toBe(true); - expect(p1.equals(p3)).toBe(false); - expect(p1.equals(p4)).toBe(false); - expect(p1.equals(p5)).toBe(false); - }); - - it("equals test2", () => - { - let p1 = new Point(-10, -10); - let p2 = new Point(-10, -10); - let p3 = new Point(-10, -20); - let p4 = new Point(-20, -10); - let p5 = new Point(-20, -20); - - expect(p1.equals(p2)).toBe(true); - expect(p1.equals(p3)).toBe(false); - expect(p1.equals(p4)).toBe(false); - expect(p1.equals(p5)).toBe(false); - }); - - it("equals test3", () => - { - let p1 = new Point(1, 10); - let p2 = new Point(1, 10); - // @ts-ignore - let p3 = new Point(true, 10); - // @ts-ignore - let p4 = new Point(false, 10); - // @ts-ignore - let p5 = new Point(1, false); - - expect(p1.equals(p2)).toBe(true); - expect(p1.equals(p3)).toBe(true); - expect(p1.equals(p4)).toBe(false); - expect(p1.equals(p5)).toBe(false); - }); - - it("equals test4", () => - { - // @ts-ignore - let p1 = new Point(true, 10); - let p2 = new Point(1, 10); - // @ts-ignore - let p3 = new Point(true, 10); - // @ts-ignore - let p4 = new Point(false, 10); - // @ts-ignore - let p5 = new Point(1, false); - - expect(p1.equals(p2)).toBe(true); - expect(p1.equals(p3)).toBe(true); - expect(p1.equals(p4)).toBe(false); - expect(p1.equals(p5)).toBe(false); - }); - - it("equals valid test1", () => - { - // @ts-ignore - let p1 = new Point("a", 10); - let p2 = new Point(10, 10); - - expect(p1.equals(p2)).toBe(false); - }); - - it("equals valid test2", () => - { - // @ts-ignore - let p1 = new Point("a", 10); - // @ts-ignore - let p2 = new Point("a", 10); - - expect(p1.equals(p2)).toBe(true); - }); - - it("equals valid test3", () => - { - // @ts-ignore - let p1 = new Point("a", "a"); - // @ts-ignore - let p2 = new Point("a", "a"); - - expect(p1.equals(p2)).toBe(true); - }); - -}); - -describe("Point.js interpolate test", () => -{ - - it("interpolate test1", () => - { - let p1 = new Point(0, 0); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=3, y=4)"); - }); - - it("interpolate test2", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=7.5, y=9)"); - }); - - it("interpolate test3", () => - { - let p1 = new Point(-9, 10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=-1.5, y=9)"); - }); - - it("interpolate test4", () => - { - let p1 = new Point(9, -10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=7.5, y=-1)"); - }); - - it("interpolate test5", () => - { - let p1 = new Point(-9, -10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=-1.5, y=-1)"); - }); - - it("interpolate test6", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(-6, 8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=1.5, y=9)"); - }); - - it("interpolate test7", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(6, -8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=7.5, y=1)"); - }); - - it("interpolate test8", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(-6, -8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=1.5, y=1)"); - }); - - it("interpolate test9", () => - { - let p1 = new Point(-9, 10); - let p2 = new Point(-6, 8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=-7.5, y=9)"); - }); - - it("interpolate test10", () => - { - let p1 = new Point(9, -10); - let p2 = new Point(6, -8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=7.5, y=-9)"); - }); - - it("interpolate test11", () => - { - let p1 = new Point(-9, -10); - let p2 = new Point(-6, -8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=-7.5, y=-9)"); - }); - - it("interpolate test12", () => - { - // @ts-ignore - let p1 = new Point("a", 10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=3, y=9)"); - }); - - it("interpolate test13", () => - { - // @ts-ignore - let p1 = new Point(9, "a"); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=7.5, y=4)"); - }); - - it("interpolate test14", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, -0.5); - expect(p3.toString()).toBe("(x=4.5, y=7)"); - }); - - it("interpolate test15", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(6, 8); - // @ts-ignore - let p3 = Point.interpolate(p1, p2, "a"); - expect(p3.toString()).toBe("(x=0, y=0)"); - }); - - it("interpolate test16", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(9, 8); - let p3 = Point.interpolate(p1, p2, 0.5); - expect(p3.toString()).toBe("(x=9, y=9)"); - }); - - it("interpolate test17", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, 1); - expect(p3.toString()).toBe("(x=9, y=10)"); - }); - - it("interpolate test18", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, 0); - expect(p3.toString()).toBe("(x=6, y=8)"); - }); - - it("interpolate test19", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, 1.5); - expect(p3.toString()).toBe("(x=10.5, y=11)"); - }); - - it("interpolate test20", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, 0.2); - expect(p3.toString()).toBe("(x=6.6, y=8.4)"); - }); - - it("interpolate test21", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, -0.2); - expect(p3.toString()).toBe("(x=5.4, y=7.6)"); - }); - - it("interpolate test22", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, 1.2); - expect(p3.toString()).toBe("(x=9.6, y=10.4)"); - }); - - it("interpolate test23", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, -1.2); - expect(p3.toString()).toBe("(x=2.3999999999999995, y=5.6)"); - }); - - it("interpolate test24", () => - { - let p1 = new Point(9, 10); - let p2 = new Point(6, 8); - let p3 = Point.interpolate(p1, p2, -1); - expect(p3.toString()).toBe("(x=3, y=6)"); - }); - - it("interpolate test25", () => - { - let p1 = new Point(6, 8); - let p2 = new Point(9, 10); - let p3 = Point.interpolate(p1, p2, -1); - expect(p3.toString()).toBe("(x=12, y=12)"); - }); - -}); - -describe("Point.js normalize test", () => -{ - - it("normalize test1", () => - { - let p = new Point(6, 8); - p.normalize(2.5); - expect(p.toString()).toBe("(x=1.5, y=2)"); - }); - - it("normalize test2", () => - { - let p = new Point(6, 8); - p.normalize(0); - expect(p.toString()).toBe("(x=0, y=0)"); - }); - - it("normalize test3", () => - { - let p = new Point(6, 8); - p.normalize(-2.5); - expect(p.toString()).toBe("(x=-1.5, y=-2)"); - }); - - it("normalize test4", () => - { - let p = new Point(-6, 8); - p.normalize(2.5); - expect(p.toString()).toBe("(x=-1.5, y=2)"); - }); - - it("normalize test5", () => - { - let p = new Point(6, -8); - p.normalize(2.5); - expect(p.toString()).toBe("(x=1.5, y=-2)"); - }); - - it("normalize test6", () => - { - let p = new Point(-6, -8); - p.normalize(2.5); - expect(p.toString()).toBe("(x=-1.5, y=-2)"); - }); - - it("normalize test7", () => - { - // @ts-ignore - let p = new Point("a", 8); - p.normalize(2.5); - expect(p.toString()).toBe("(x=0, y=2.5)"); - }); - - it("normalize test8", () => - { - // @ts-ignore - let p = new Point(6, "a"); - p.normalize(2.5); - expect(p.toString()).toBe("(x=2.5, y=0)"); - }); - - it("normalize test9", () => - { - let p = new Point(6, 8); - // @ts-ignore - p.normalize("a"); - expect(p.toString()).toBe("(x=0, y=0)"); - }); - - it("normalize test10", () => - { - // @ts-ignore - let p = new Point("a", 8); - // @ts-ignore - p.normalize("a"); - expect(p.toString()).toBe("(x=0, y=0)"); - }); - - it("normalize test11", () => - { - // @ts-ignore - let p = new Point(6, "a"); - // @ts-ignore - p.normalize("a"); - expect(p.toString()).toBe("(x=0, y=0)"); - }); -}); - -describe("Point.js offset test", () => -{ - - it("offset test1", () => - { - let p = new Point(10, 20); - p.offset(30, 40); - expect(p.toString()).toBe("(x=40, y=60)"); - }); - - it("offset test2", () => - { - let p = new Point(10, 20); - p.offset(-30, 40); - expect(p.toString()).toBe("(x=-20, y=60)"); - }); - - it("offset test3", () => - { - let p = new Point(10, 20); - p.offset(30, -40); - expect(p.toString()).toBe("(x=40, y=-20)"); - }); - - it("offset test4", () => - { - let p = new Point(-10, 20); - p.offset(30, 40); - expect(p.toString()).toBe("(x=20, y=60)"); - }); - - it("offset test5", () => - { - let p = new Point(10, -20); - p.offset(30, 40); - expect(p.toString()).toBe("(x=40, y=20)"); - }); - - it("offset test6", () => - { - // @ts-ignore - let p = new Point("a", -20); - p.offset(30, 40); - expect(p.toString()).toBe("(x=30, y=20)"); - }); - - it("offset test7", () => - { - let p = new Point(10, -20); - // @ts-ignore - p.offset("a", 40); - expect(p.toString()).toBe("(x=0, y=20)"); - }); - - it("offset test8", () => - { - // @ts-ignore - let p = new Point(10, "a"); - // @ts-ignore - p.offset("a", 40); - expect(p.toString()).toBe("(x=0, y=40)"); - }); -}); - -describe("Point.js polar test", () => -{ - - it("polar test1", () => - { - let angle = Math.PI * 2 * (30 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=3.464101615137755, y=1.9999999999999998)" - ); - }); - - it("polar test2", () => - { - let angle = Math.PI * 2 * (45 / 360); // 30 degrees - let p = Point.polar(4, angle); - - expect(p.x | 0).toBe(2); - expect(p.y | 0).toBe(2); - - }); - - it("polar test3", () => - { - let angle = Math.PI * 2 * (90 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=2.4492935982947064e-16, y=4)" - ); - }); - - it("polar test4", () => - { - let angle = Math.PI * 2 * (135 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=-2.82842712474619, y=2.8284271247461903)" - ); - }); - - it("polar test5", () => - { - let angle = Math.PI * 2 * (180 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=-4, y=4.898587196589413e-16)" - ); - }); - - it("polar test6", () => - { - let angle = Math.PI * 2 * (225 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=-2.8284271247461907, y=-2.82842712474619)" - ); - }); - - it("polar test7", () => - { - let angle = Math.PI * 2 * (270 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=-7.347880794884119e-16, y=-4)" - ); - }); - - it("polar test8", () => - { - let angle = Math.PI * 2 * (315 / 360); // 30 degrees - let p = Point.polar(4, angle); - if (p.x > 2.8284271247461894) { - expect(p.x).toBe(2.82842712474619); - } else { - expect(p.x).toBe(2.8284271247461894); - } - expect(p.y).toBe(-2.8284271247461907); - }); - - it("polar test9", () => - { - let angle = Math.PI * 2 * (360 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=4, y=-9.797174393178826e-16)" - ); - }); - - it("polar test10", () => - { - let angle = Math.PI * 2 * (-30 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=3.464101615137755, y=-1.9999999999999998)" - ); - }); - - it("polar test11", () => - { - let angle = Math.PI * 2 * (-45 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.x | 0).toBe(2); - expect(p.y | 0).toBe(-2); - }); - - it("polar test12", () => - { - let angle = Math.PI * 2 * (-90 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=2.4492935982947064e-16, y=-4)" - ); - }); - - it("polar test13", () => - { - let angle = Math.PI * 2 * (-135 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=-2.82842712474619, y=-2.8284271247461903)" - ); - }); - - it("polar test14", () => - { - let angle = Math.PI * 2 * (-180 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=-4, y=-4.898587196589413e-16)" - ); - }); - - it("polar test15", () => - { - let angle = Math.PI * 2 * (-225 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=-2.8284271247461907, y=2.82842712474619)" - ); - }); - - it("polar test16", () => - { - let angle = Math.PI * 2 * (-270 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=-7.347880794884119e-16, y=4)" - ); - }); - - it("polar test17", () => - { - let angle = Math.PI * 2 * (-315 / 360); // 30 degrees - let p = Point.polar(4, angle); - if (p.x > 2.8284271247461894) { - expect(p.x).toBe(2.82842712474619); - } else { - expect(p.x).toBe(2.8284271247461894); - } - expect(p.y).toBe(2.8284271247461907); - }); - - it("polar test18", () => - { - let angle = Math.PI * 2 * (-360 / 360); // 30 degrees - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=4, y=9.797174393178826e-16)" - ); - }); - - it("polar test19", () => - { - let angle = Math.PI * 2 * (30 / 360); // 30 degrees - let p = Point.polar(0, angle); - expect(p.toString()).toBe( - "(x=0, y=0)" - ); - }); - - it("polar test20", () => - { - let angle = Math.PI * 2 * (30 / 360); // 30 degrees - let p = Point.polar(-4, angle); - expect(p.toString()).toBe( - "(x=-3.464101615137755, y=-1.9999999999999998)" - ); - }); - - it("polar test21", () => - { - let angle = "a"; // 30 degrees - // @ts-ignore - let p = Point.polar(4, angle); - expect(p.toString()).toBe( - "(x=0, y=0)" - ); - }); - - it("polar test22", () => - { - let angle = Math.PI * 2 * (30 / 360); // 30 degrees - // @ts-ignore - let p = Point.polar("a", angle); - expect(p.toString()).toBe( - "(x=0, y=0)" - ); - }); - - it("polar test23", () => - { - let angle = "a"; // 30 degrees - // @ts-ignore - let p = Point.polar("a", angle); - expect(p.toString()).toBe( - "(x=0, y=0)" - ); - }); -}); - -describe("Point.js setTo test", () => -{ - - it("setTo test1", () => - { - let p = new Point(10, 20); - p.setTo(30, 40); - expect(p.toString()).toBe("(x=30, y=40)"); - }); - - it("setTo test2", () => - { - // @ts-ignore - let p = new Point("a", 20); - p.setTo(30, 40); - expect(p.toString()).toBe("(x=30, y=40)"); - }); - - it("setTo test3", () => - { - let p = new Point(10, 20); - // @ts-ignore - p.setTo("a", 40); - expect(p.toString()).toBe("(x=0, y=40)"); - }); - - it("setTo test4", () => - { - let p = new Point(10, 20); - p.setTo(0, 40); - expect(p.toString()).toBe("(x=0, y=40)"); - }); - -}); - -describe("Point.js subtract test", () => -{ - - it("subtract test1", () => - { - let p1 = new Point(6, 8); - let p2 = new Point(1.5, 2); - let p3 = p1.subtract(p2); - expect(p3.toString()).toBe("(x=4.5, y=6)"); - }); - - it("subtract test2", () => - { - let p1 = new Point(6, 8); - let p2 = new Point(-1, 2); - let p3 = p1.subtract(p2); - expect(p3.toString()).toBe("(x=7, y=6)"); - }); - - it("subtract test3", () => - { - let p1 = new Point(6, 8); - // @ts-ignore - let p2 = new Point("a", 2); - let p3 = p1.subtract(p2); - expect(p3.toString()).toBe("(x=6, y=6)"); - }); - - it("subtract test4", () => - { - let p1 = new Point(6, 8); - // @ts-ignore - let p2 = new Point(1, "a"); - let p3 = p1.subtract(p2); - expect(p3.toString()).toBe("(x=5, y=8)"); - }); - - it("subtract test5", () => - { - let p1 = new Point(6, 8); - // @ts-ignore - let p2 = new Point("a", "a"); - let p3 = p1.subtract(p2); - expect(p3.toString()).toBe("(x=6, y=8)"); - }); -}); - -//properties -describe("Point.js x test", () => -{ - - it("default test case1", () => - { - let p = new Point(); - expect(p.x).toBe(0); - }); - - it("default test case2", () => - { - let p = new Point(); - // @ts-ignore - p.x = null; - expect(p.x).toBe(0); - }); - - it("default test case3", () => - { - let p = new Point(); - // @ts-ignore - p.x = undefined; - expect(p.x).toBe(0); - }); - - it("default test case4", () => - { - let p = new Point(); - // @ts-ignore - p.x = true; - expect(p.x).toBe(1); - }); - - it("default test case5", () => - { - let p = new Point(); - // @ts-ignore - p.x = ""; - expect(p.x).toBe(0); - }); - - it("default test case6", () => - { - let p = new Point(); - // @ts-ignore - p.x = "abc"; - expect(p.x).toBe(0); - }); - - it("default test case7", () => - { - let p = new Point(); - p.x = 0; - expect(p.x).toBe(0); - }); - - it("default test case8", () => - { - let p = new Point(); - p.x = 1; - expect(p.x).toBe(1); - }); - - it("default test case9", () => - { - let p = new Point(); - p.x = 500; - expect(p.x).toBe(500); - }); - - it("default test case10", () => - { - let p = new Point(); - p.x = 50000000000000000; - expect(p.x).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let p = new Point(); - p.x = -1; - expect(p.x).toBe(-1); - }); - - it("default test case12", () => - { - let p = new Point(); - p.x = -500; - expect(p.x).toBe(-500); - }); - - it("default test case13", () => - { - let p = new Point(); - p.x = -50000000000000000; - expect(p.x).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let p = new Point(); - // @ts-ignore - p.x = { "a":0 }; - expect(p.x).toBe(0); - }); - - it("default test case15", () => - { - let p = new Point(); - // @ts-ignore - p.x = function a() {}; - expect(p.x).toBe(0); - }); - - it("default test case16", () => - { - let p = new Point(); - // @ts-ignore - p.x = [1]; - expect(p.x).toBe(1); - }); - - it("default test case17", () => - { - let p = new Point(); - // @ts-ignore - p.x = [1,2]; - expect(p.x).toBe(0); - }); - - it("default test case18", () => - { - let p = new Point(); - // @ts-ignore - p.x = {}; - expect(p.x).toBe(0); - }); - - it("default test case19", () => - { - let p = new Point(); - // @ts-ignore - p.x = { "toString":function () { return 1 } }; - expect(p.x).toBe(1); - }); - - it("default test case20", () => - { - let p = new Point(); - // @ts-ignore - p.x = { "toString":function () { return "1" } }; - expect(p.x).toBe(1); - }); - - it("default test case21", () => - { - let p = new Point(); - // @ts-ignore - p.x = { "toString":function () { return "1a" } }; - expect(p.x).toBe(0); - }); - -}); - -describe("Point.js y test", () => -{ - - it("default test case1", () => - { - let p = new Point(); - expect(p.y).toBe(0); - }); - - it("default test case2", () => - { - let p = new Point(); - // @ts-ignore - p.y = null; - expect(p.y).toBe(0); - }); - - it("default test case3", () => - { - let p = new Point(); - // @ts-ignore - p.y = undefined; - expect(p.y).toBe(0); - }); - - it("default test case4", () => - { - let p = new Point(); - // @ts-ignore - p.y = true; - expect(p.y).toBe(1); - }); - - it("default test case5", () => - { - let p = new Point(); - // @ts-ignore - p.y = ""; - expect(p.y).toBe(0); - }); - - it("default test case6", () => - { - let p = new Point(); - // @ts-ignore - p.y = "abc"; - expect(p.y).toBe(0); - }); - - it("default test case7", () => - { - let p = new Point(); - p.y = 0; - expect(p.y).toBe(0); - }); - - it("default test case8", () => - { - let p = new Point(); - p.y = 1; - expect(p.y).toBe(1); - }); - - it("default test case9", () => - { - let p = new Point(); - p.y = 500; - expect(p.y).toBe(500); - }); - - it("default test case10", () => - { - let p = new Point(); - p.y = 50000000000000000; - expect(p.y).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let p = new Point(); - p.y = -1; - expect(p.y).toBe(-1); - }); - - it("default test case12", () => - { - let p = new Point(); - p.y = -500; - expect(p.y).toBe(-500); - }); - - it("default test case13", () => - { - let p = new Point(); - p.y = -50000000000000000; - expect(p.y).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let p = new Point(); - // @ts-ignore - p.y = { "a":0 }; - expect(p.y).toBe(0); - }); - - it("default test case15", () => - { - let p = new Point(); - // @ts-ignore - p.y = function a() {}; - expect(p.y).toBe(0); - }); - - it("default test case16", () => - { - let p = new Point(); - // @ts-ignore - p.y = [1]; - expect(p.y).toBe(1); - }); - - it("default test case17", () => - { - let p = new Point(); - // @ts-ignore - p.y = [1,2]; - expect(p.y).toBe(0); - }); - - it("default test case18", () => - { - let p = new Point(); - // @ts-ignore - p.y = {}; - expect(p.y).toBe(0); - }); - - it("default test case19", () => - { - let p = new Point(); - // @ts-ignore - p.y = { "toString":function () { return 1 } }; - expect(p.y).toBe(1); - }); - - it("default test case20", () => - { - let p = new Point(); - // @ts-ignore - p.y = { "toString":function () { return "1" } }; - expect(p.y).toBe(1); - }); - - it("default test case21", () => - { - let p = new Point(); - // @ts-ignore - p.y = { "toString":function () { return "1a" } }; - expect(p.y).toBe(0); - }); - -}); - -describe("Point.js length test", () => -{ - - it("default test case1", () => - { - let p = new Point(); - expect(p.length).toBe(0); - }); - - it("default test case2", () => - { - let p = new Point(10, 30); - expect(p.length).toBe(31.622776601683793); - }); - -}); \ No newline at end of file diff --git a/package.json b/package.json index 85d70ab5..d880111d 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "test": "vitest", "clean": "node ./scripts/clean.js", "build": "tsc && node ./scripts/build.js", + "build:vite": "vite build", "publish:dist": "tsc && node ./scripts/publish.js" }, "funding": { diff --git a/packages/geom/package.json b/packages/geom/package.json index 0ef8066b..5315254f 100644 --- a/packages/geom/package.json +++ b/packages/geom/package.json @@ -24,13 +24,5 @@ "repository": { "type": "git", "url": "git+https://github.com/Next2D/Player.git" - }, - "peerDependencies": { - "@next2d/interface": "file:../interface", - "@next2d/display": "file:../display", - "@next2d/core": "file:../core", - "@next2d/util": "file:../util", - "@next2d/filters": "file:../filters", - "@next2d/share": "file:../share" } } diff --git a/packages/geom/src/Point.test.ts b/packages/geom/src/Point.test.ts new file mode 100644 index 00000000..77a240de --- /dev/null +++ b/packages/geom/src/Point.test.ts @@ -0,0 +1,56 @@ +import { Point } from "./Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js toString test", () => +{ + it("toString test1 success", () => + { + const point = new Point(); + expect(point.toString()).toBe("(x=0, y=0)"); + }); + + it("toString test2 success", () => + { + const point = new Point(1, 2); + expect(point.toString()).toBe("(x=1, y=2)"); + }); +}); + +describe("Point.js static toString test", () => +{ + + it("static toString test", () => + { + expect(Point.toString()).toBe("[class Point]"); + }); + +}); + +describe("Point.js namespace test", () => +{ + it("namespace test public", () => + { + const point = new Point(); + expect(point.namespace).toBe("next2d.geom.Point"); + }); + + it("namespace test static", () => + { + expect(Point.namespace).toBe("next2d.geom.Point"); + }); +}); + +describe("Point.js length test", () => +{ + it("default test case1", () => + { + const point = new Point(); + expect(point.length).toBe(0); + }); + + it("default test case2", () => + { + const point = new Point(10, 30); + expect(point.length).toBe(31.622776601683793); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Point.ts b/packages/geom/src/Point.ts index 96d2e603..504eadaa 100644 --- a/packages/geom/src/Point.ts +++ b/packages/geom/src/Point.ts @@ -1,3 +1,15 @@ +import { execute as pointAddService } from "./Point/service/PointAddService"; +import { execute as pointCloneService } from "./Point/service/PointCloneService"; +import { execute as pointCopyFromService } from "./Point/service/PointCopyFromService"; +import { execute as pointDistanceService } from "./Point/service/PointDistanceService"; +import { execute as pointEqualsService } from "./Point/service/PointEqualsService"; +import { execute as pointInterpolateService } from "./Point/service/PointInterpolateService"; +import { execute as pointNormalizeService } from "./Point/service/PointNormalizeService"; +import { execute as pointOffsetService } from "./Point/service/PointOffsetService"; +import { execute as pointPolarService } from "./Point/service/PointPolarService"; +import { execute as pointSetToService } from "./Point/service/PointSetToService"; +import { execute as pointSubtractService } from "./Point/service/PointSubtractService"; + /** * @description Point オブジェクトは 2 次元の座標系の位置を表します。 * x は水平方向の軸を表し、y は垂直方向の軸を表します。 @@ -150,7 +162,7 @@ export class Point */ add (point: Point): Point { - return new Point(this._$x + point.x, this._$y + point.y); + return pointAddService(this, point); } /** @@ -163,7 +175,7 @@ export class Point */ clone (): Point { - return new Point(this._$x, this._$y); + return pointCloneService(this); } /** @@ -174,12 +186,12 @@ export class Point * * @param {Point} point * @returns void + * @method * @public */ copyFrom (point: Point): void { - this._$x = point.x; - this._$y = point.y; + pointCopyFromService(this, point); } /** @@ -194,24 +206,21 @@ export class Point */ static distance (point1: Point, point2: Point): number { - return Math.sqrt( - Math.pow(point1._$x - point2._$x, 2) - + Math.pow(point1._$y - point2._$y, 2) - ); + return pointDistanceService(point1, point2); } /** * @description 2 つのポイントが等しいかどうかを判別します。 * Determines whether two points are equal. * - * @param {Point} to_compare + * @param {Point} point * @return {boolean} * @method * @public */ - equals (to_compare: Point): boolean + equals (point: Point): boolean { - return this._$x === to_compare._$x && this._$y === to_compare._$y; + return pointEqualsService(this, point); } /** @@ -222,14 +231,12 @@ export class Point * @param {Point} point2 * @param {number} f * @return {Point} + * @method * @static */ static interpolate (point1: Point, point2: Point, f: number): Point { - return new Point( - point1.x + (point2.x - point1.x) * (1 - f), - point1.y + (point2.y - point1.y) * (1 - f) - ); + return pointInterpolateService(point1, point2, f); } /** @@ -243,9 +250,7 @@ export class Point */ normalize (thickness: number): void { - const length = this.length; - this._$x = this._$x * thickness / length; - this._$y = this._$y * thickness / length; + pointNormalizeService(this, thickness); } /** @@ -254,14 +259,13 @@ export class Point * * @param {number} dx * @param {number} dy - * @return {Point} + * @return {void} * @method * @public */ offset (dx: number, dy: number): void { - this._$x += dx; - this._$y += dy; + pointOffsetService(this, dx, dy); } /** @@ -276,7 +280,7 @@ export class Point */ static polar (length: number, angle: number): Point { - return new Point(length * Math.cos(angle), length * Math.sin(angle)); + return pointPolarService(length, angle); } /** @@ -291,8 +295,7 @@ export class Point */ setTo (x: number, y: number): void { - this._$x = x; - this._$y = y; + pointSetToService(this, x, y); } /** @@ -307,6 +310,6 @@ export class Point */ subtract (point: Point): Point { - return new Point(this._$x - point.x, this._$y - point.y); + return pointSubtractService(this, point); } -} +} \ No newline at end of file diff --git a/packages/geom/src/Point/Point_length.test.ts b/packages/geom/src/Point/Point_length.test.ts deleted file mode 100644 index 84ff3951..00000000 --- a/packages/geom/src/Point/Point_length.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Point } from "../Point"; -import { describe, expect, it } from "vitest"; - -describe("Point.js length test", () => -{ - it("default test case1", () => - { - const point = new Point(); - expect(point.length).toBe(0); - }); - - it("default test case2", () => - { - const point = new Point(10, 30); - expect(point.length).toBe(31.622776601683793); - }); -}); \ No newline at end of file diff --git a/packages/geom/src/Point/Point_toString.test.ts b/packages/geom/src/Point/Point_toString.test.ts deleted file mode 100644 index 89687eb1..00000000 --- a/packages/geom/src/Point/Point_toString.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Point } from "../Point"; -import { describe, expect, it } from "vitest"; - -describe("Point.js toString test", () => -{ - it("toString test1 success", () => - { - const point = new Point(); - expect(point.toString()).toBe("(x=0, y=0)"); - }); - - it("toString test2 success", () => - { - const point = new Point(1, 2); - expect(point.toString()).toBe("(x=1, y=2)"); - }); -}); - -describe("Point.js static toString test", () => -{ - - it("static toString test", () => - { - expect(Point.toString()).toBe("[class Point]"); - }); - -}); \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointAddService.test.ts b/packages/geom/src/Point/service/PointAddService.test.ts new file mode 100644 index 00000000..b552b395 --- /dev/null +++ b/packages/geom/src/Point/service/PointAddService.test.ts @@ -0,0 +1,54 @@ +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js add test", () => +{ + it("add test case1", () => + { + const p1 = new Point(10, 10); + const p2 = new Point(20, 20); + + const p3 = p1.add(p1); + const p4 = p2.add(p2); + const p5 = p1.add(p2); + const p6 = p2.add(p1); + + expect(p3.toString()).toBe("(x=20, y=20)"); + expect(p4.toString()).toBe("(x=40, y=40)"); + expect(p5.toString()).toBe("(x=30, y=30)"); + expect(p6.toString()).toBe("(x=30, y=30)"); + }); + + it("add test case2", () => + { + const p1 = new Point(-10, -10); + const p2 = new Point(20, -20); + + const p3 = p1.add(p1); + const p4 = p2.add(p2); + const p5 = p1.add(p2); + const p6 = p2.add(p1); + + expect(p3.toString()).toBe("(x=-20, y=-20)"); + expect(p4.toString()).toBe("(x=40, y=-40)"); + expect(p5.toString()).toBe("(x=10, y=-30)"); + expect(p6.toString()).toBe("(x=10, y=-30)"); + }); + + it("add test case3", () => + { + const p1 = new Point(0, 10); + const p2 = new Point(20, 0); + + const p3 = p1.add(p1); + const p4 = p2.add(p2); + const p5 = p1.add(p2); + const p6 = p2.add(p1); + + expect(p3.toString()).toBe("(x=0, y=20)"); + expect(p4.toString()).toBe("(x=40, y=0)"); + expect(p5.toString()).toBe("(x=20, y=10)"); + expect(p6.toString()).toBe("(x=20, y=10)"); + }); + +}); \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointAddService.ts b/packages/geom/src/Point/service/PointAddService.ts new file mode 100644 index 00000000..41b15449 --- /dev/null +++ b/packages/geom/src/Point/service/PointAddService.ts @@ -0,0 +1,16 @@ +import { Point } from "../../Point"; + +/** + * @description 2つの座標を加算します。 + * Adds two points. + * + * @param {Point} src + * @param {Point} dst + * @return {Point} + * @method + * @public + */ +export const execute = (src: Point, dst: Point): Point => +{ + return new Point(src.x + dst.x, src.y + dst.y); +}; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointCloneService.test.ts b/packages/geom/src/Point/service/PointCloneService.test.ts new file mode 100644 index 00000000..58bdb173 --- /dev/null +++ b/packages/geom/src/Point/service/PointCloneService.test.ts @@ -0,0 +1,26 @@ +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js property valid test and clone test", () => +{ + it("clone test", function () { + + // origin + const point1 = new Point(0, 0); + + // clone + const point2 = point1.clone(); + point2.x = 10; + point2.y = 20; + + // origin + expect(point1.x).toBe(0); + expect(point1.y).toBe(0); + + // clone + expect(point2.x).toBe(10); + expect(point2.y).toBe(20); + expect(point2.length).toBe(22.360679774997898); + expect(point2.toString()).toBe("(x=10, y=20)"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointCloneService.ts b/packages/geom/src/Point/service/PointCloneService.ts new file mode 100644 index 00000000..10ef34ef --- /dev/null +++ b/packages/geom/src/Point/service/PointCloneService.ts @@ -0,0 +1,15 @@ +import { Point } from "../../Point"; + +/** + * @description 座標を複製します。 + * Duplicates the coordinates. + * + * @param {Point} src + * @return {Point} + * @method + * @public + */ +export const execute = (src: Point): Point => +{ + return new Point(src.x, src.y); +}; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointCopyFromService.test.ts b/packages/geom/src/Point/service/PointCopyFromService.test.ts new file mode 100644 index 00000000..482ab24d --- /dev/null +++ b/packages/geom/src/Point/service/PointCopyFromService.test.ts @@ -0,0 +1,52 @@ +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js copyFrom test", () => +{ + + it("copyFrom test case1", () => + { + const p1 = new Point(10, 10); + const p2 = new Point(20, 20); + + p1.copyFrom(p2); + p1.x = 10; + + expect(p1.toString()).toBe("(x=10, y=20)"); + expect(p2.toString()).toBe("(x=20, y=20)"); + }); + + it("copyFrom test case2", () => + { + const p1 = new Point(-10, -10); + const p2 = new Point(20, -20); + + p1.copyFrom(p2); + + expect(p1.toString()).toBe("(x=20, y=-20)"); + expect(p2.toString()).toBe("(x=20, y=-20)"); + }); + + it("copyFrom test case3", () => + { + const p1 = new Point(0, 10); + const p2 = new Point(20, 0); + + p1.copyFrom(p2); + + expect(p1.toString()).toBe("(x=20, y=0)"); + expect(p2.toString()).toBe("(x=20, y=0)"); + }); + + it("copyFrom test case4", () => + { + const p1 = new Point(10, 10); + const p2 = new Point(0, 20); + + p1.copyFrom(p2); + + expect(p1.toString()).toBe("(x=0, y=20)"); + expect(p2.toString()).toBe("(x=0, y=20)"); + }); + +}); \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointCopyFromService.ts b/packages/geom/src/Point/service/PointCopyFromService.ts new file mode 100644 index 00000000..eed86113 --- /dev/null +++ b/packages/geom/src/Point/service/PointCopyFromService.ts @@ -0,0 +1,17 @@ +import type { Point } from "../../Point"; + +/** + * @description 指定されたポイントの値をコピーします。 + * Copies the value of the specified point. + * + * @param {Point} src + * @param {Point} dst + * @return {void} + * @method + * @public + */ +export const execute = (src: Point, dst: Point): void => +{ + src.x = dst.x; + src.y = dst.y; +}; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointDistanceService.test.ts b/packages/geom/src/Point/service/PointDistanceService.test.ts new file mode 100644 index 00000000..e801d441 --- /dev/null +++ b/packages/geom/src/Point/service/PointDistanceService.test.ts @@ -0,0 +1,117 @@ +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js distance test", () => +{ + it("distance test case1", () => + { + const p1 = new Point(10, 10); + const p2 = new Point(20, 20); + expect(Point.distance(p1, p2)).toBe(14.142135623730951); + }); + + it("distance test case2", () => + { + const p1 = new Point(-10, 10); + const p2 = new Point(20, 20); + expect(Point.distance(p1, p2)).toBe(31.622776601683793); + }); + + it("distance test case3", () => + { + const p1 = new Point(10, -10); + const p2 = new Point(20, 20); + expect(Point.distance(p1, p2)).toBe(31.622776601683793); + }); + + it("distance test case4", () => + { + const p1 = new Point(10, 10); + const p2 = new Point(-20, 20); + expect(Point.distance(p1, p2)).toBe(31.622776601683793); + }); + + it("distance test case5", () => + { + const p1 = new Point(10, 10); + const p2 = new Point(20, -20); + expect(Point.distance(p1, p2)).toBe(31.622776601683793); + }); + + it("distance test case6", () => + { + const p1 = new Point(10, -10); + const p2 = new Point(20, -20); + expect(Point.distance(p1, p2)).toBe(14.142135623730951); + }); + + it("distance test case7", () => + { + const p1 = new Point(-10, 10); + const p2 = new Point(-20, 20); + expect(Point.distance(p1, p2)).toBe(14.142135623730951); + }); + + it("distance test case8", () => + { + const p1 = new Point(-10, -10); + const p2 = new Point(20, 20); + expect(Point.distance(p1, p2)).toBe(42.42640687119285); + }); + + it("distance test case9", () => + { + const p1 = new Point(10, 10); + const p2 = new Point(-20, -20); + expect(Point.distance(p1, p2)).toBe(42.42640687119285); + }); + + it("distance test case10", () => + { + const p1 = new Point(-10, 10); + const p2 = new Point(20, -20); + expect(Point.distance(p1, p2)).toBe(42.42640687119285); + }); + + it("distance test case11", () => + { + const p1 = new Point(10, -10); + const p2 = new Point(-20, 20); + expect(Point.distance(p1, p2)).toBe(42.42640687119285); + }); + + it("distance test case12", () => + { + const p1 = new Point(-10, -10); + const p2 = new Point(-20, 20); + expect(Point.distance(p1, p2)).toBe(31.622776601683793); + }); + + it("distance test case13", () => + { + const p1 = new Point(10, -10); + const p2 = new Point(-20, -20); + expect(Point.distance(p1, p2)).toBe(31.622776601683793); + }); + + it("distance test case14", () => + { + const p1 = new Point(-10, 10); + const p2 = new Point(-20, -20); + expect(Point.distance(p1, p2)).toBe(31.622776601683793); + }); + + it("distance test case15", () => + { + const p1 = new Point(-10, -10); + const p2 = new Point(20, -20); + expect(Point.distance(p1, p2)).toBe(31.622776601683793); + }); + + it("distance test case16", () => + { + const p1 = new Point(-10, -10); + const p2 = new Point(-20, -20); + expect(Point.distance(p1, p2)).toBe(14.142135623730951); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointDistanceService.ts b/packages/geom/src/Point/service/PointDistanceService.ts new file mode 100644 index 00000000..6c818bb1 --- /dev/null +++ b/packages/geom/src/Point/service/PointDistanceService.ts @@ -0,0 +1,19 @@ +import type { Point } from "../../Point"; + +/** + * @description 2点間の距離を返します。 + * Returns the distance between two points. + * + * @param {Point} point1 + * @param {Point} point2 + * @return {number} + * @method + * @public + */ +export const execute = (point1: Point, point2: Point): number => +{ + return Math.sqrt( + Math.pow(point1.x - point2.x, 2) + + Math.pow(point1.y - point2.y, 2) + ); +}; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointEqualsService.test.ts b/packages/geom/src/Point/service/PointEqualsService.test.ts new file mode 100644 index 00000000..a2675abc --- /dev/null +++ b/packages/geom/src/Point/service/PointEqualsService.test.ts @@ -0,0 +1,62 @@ +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js equals test", () => +{ + + it("equals test case1", () => + { + const p1 = new Point(10, 10); + const p2 = new Point(10, 10); + const p3 = new Point(10, 20); + const p4 = new Point(20, 10); + const p5 = new Point(20, 20); + + expect(p1.equals(p2)).toBe(true); + expect(p1.equals(p3)).toBe(false); + expect(p1.equals(p4)).toBe(false); + expect(p1.equals(p5)).toBe(false); + }); + + it("equals test case2", () => + { + const p1 = new Point(-10, -10); + const p2 = new Point(-10, -10); + const p3 = new Point(-10, -20); + const p4 = new Point(-20, -10); + const p5 = new Point(-20, -20); + + expect(p1.equals(p2)).toBe(true); + expect(p1.equals(p3)).toBe(false); + expect(p1.equals(p4)).toBe(false); + expect(p1.equals(p5)).toBe(false); + }); + + it("equals test case3", () => + { + const p1 = new Point(1, 10); + const p2 = new Point(1, 10); + const p3 = new Point(1, 10); + const p4 = new Point(0, 10); + const p5 = new Point(1, 1); + + expect(p1.equals(p2)).toBe(true); + expect(p1.equals(p3)).toBe(true); + expect(p1.equals(p4)).toBe(false); + expect(p1.equals(p5)).toBe(false); + }); + + it("equals test case4", () => + { + const p1 = new Point(1, 10); + const p2 = new Point(1, 10); + const p3 = new Point(1, 10); + const p4 = new Point(0, 10); + const p5 = new Point(1, 0); + + expect(p1.equals(p2)).toBe(true); + expect(p1.equals(p3)).toBe(true); + expect(p1.equals(p4)).toBe(false); + expect(p1.equals(p5)).toBe(false); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointEqualsService.ts b/packages/geom/src/Point/service/PointEqualsService.ts new file mode 100644 index 00000000..caf2bbc5 --- /dev/null +++ b/packages/geom/src/Point/service/PointEqualsService.ts @@ -0,0 +1,16 @@ +import type { Point } from "../../Point"; + +/** + * @description 2点が等しいかどうかを返します。 + * Returns whether two points are equal. + * + * @param {Point} src + * @param {Point} dst + * @return {boolean} + * @method + * @public + */ +export const execute = (src: Point, dst: Point): boolean => +{ + return src.x === dst.x && src.y === dst.y; +}; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointInterpolateService.test.ts b/packages/geom/src/Point/service/PointInterpolateService.test.ts new file mode 100644 index 00000000..9b3840d1 --- /dev/null +++ b/packages/geom/src/Point/service/PointInterpolateService.test.ts @@ -0,0 +1,183 @@ +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js interpolate test", () => +{ + + it("interpolate test case1", () => + { + const p1 = new Point(0, 0); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, 0.5); + expect(p3.toString()).toBe("(x=3, y=4)"); + }); + + it("interpolate test2 case", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, 0.5); + expect(p3.toString()).toBe("(x=7.5, y=9)"); + }); + + it("interpolate test case3", () => + { + const p1 = new Point(-9, 10); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, 0.5); + expect(p3.toString()).toBe("(x=-1.5, y=9)"); + }); + + it("interpolate test case4", () => + { + const p1 = new Point(9, -10); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, 0.5); + expect(p3.toString()).toBe("(x=7.5, y=-1)"); + }); + + it("interpolate test case5", () => + { + const p1 = new Point(-9, -10); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, 0.5); + expect(p3.toString()).toBe("(x=-1.5, y=-1)"); + }); + + it("interpolate test case6", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(-6, 8); + const p3 = Point.interpolate(p1, p2, 0.5); + expect(p3.toString()).toBe("(x=1.5, y=9)"); + }); + + it("interpolate test case7", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(6, -8); + const p3 = Point.interpolate(p1, p2, 0.5); + expect(p3.toString()).toBe("(x=7.5, y=1)"); + }); + + it("interpolate test case8", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(-6, -8); + const p3 = Point.interpolate(p1, p2, 0.5); + expect(p3.toString()).toBe("(x=1.5, y=1)"); + }); + + it("interpolate test case9", () => + { + const p1 = new Point(-9, 10); + const p2 = new Point(-6, 8); + const p3 = Point.interpolate(p1, p2, 0.5); + expect(p3.toString()).toBe("(x=-7.5, y=9)"); + }); + + it("interpolate test case10", () => + { + const p1 = new Point(9, -10); + const p2 = new Point(6, -8); + const p3 = Point.interpolate(p1, p2, 0.5); + expect(p3.toString()).toBe("(x=7.5, y=-9)"); + }); + + it("interpolate test case11", () => + { + const p1 = new Point(-9, -10); + const p2 = new Point(-6, -8); + const p3 = Point.interpolate(p1, p2, 0.5); + expect(p3.toString()).toBe("(x=-7.5, y=-9)"); + }); + + it("interpolate test case12", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, -0.5); + expect(p3.toString()).toBe("(x=4.5, y=7)"); + }); + + it("interpolate test case13", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(9, 8); + const p3 = Point.interpolate(p1, p2, 0.5); + expect(p3.toString()).toBe("(x=9, y=9)"); + }); + + it("interpolate test case14", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, 1); + expect(p3.toString()).toBe("(x=9, y=10)"); + }); + + it("interpolate test case15", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, 0); + expect(p3.toString()).toBe("(x=6, y=8)"); + }); + + it("interpolate test case16", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, 1.5); + expect(p3.toString()).toBe("(x=10.5, y=11)"); + }); + + it("interpolate test case17", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, 0.2); + expect(p3.toString()).toBe("(x=6.6, y=8.4)"); + }); + + it("interpolate test case18", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, -0.2); + expect(p3.toString()).toBe("(x=5.4, y=7.6)"); + }); + + it("interpolate test case19", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, 1.2); + expect(p3.toString()).toBe("(x=9.6, y=10.4)"); + }); + + it("interpolate test case20", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, -1.2); + expect(p3.toString()).toBe("(x=2.3999999999999995, y=5.6)"); + }); + + it("interpolate test case21", () => + { + const p1 = new Point(9, 10); + const p2 = new Point(6, 8); + const p3 = Point.interpolate(p1, p2, -1); + expect(p3.toString()).toBe("(x=3, y=6)"); + }); + + it("interpolate test case22", () => + { + const p1 = new Point(6, 8); + const p2 = new Point(9, 10); + const p3 = Point.interpolate(p1, p2, -1); + expect(p3.toString()).toBe("(x=12, y=12)"); + }); + +}); \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointInterpolateService.ts b/packages/geom/src/Point/service/PointInterpolateService.ts new file mode 100644 index 00000000..739223a6 --- /dev/null +++ b/packages/geom/src/Point/service/PointInterpolateService.ts @@ -0,0 +1,20 @@ +import { Point } from "../../Point"; + +/** + * @description 2点間の補間を返します。 + * Returns the interpolation between two points. + * + * @param {Point} point1 + * @param {Point} point2 + * @param {number} f + * @return {Point} + * @method + * @public + */ +export const execute = (point1: Point, point2: Point, f: number): Point => +{ + return new Point( + point1.x + (point2.x - point1.x) * (1 - f), + point1.y + (point2.y - point1.y) * (1 - f) + ); +}; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointNormalizeService.test.ts b/packages/geom/src/Point/service/PointNormalizeService.test.ts new file mode 100644 index 00000000..055ffd28 --- /dev/null +++ b/packages/geom/src/Point/service/PointNormalizeService.test.ts @@ -0,0 +1,48 @@ +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js normalize test", () => +{ + + it("normalize test case1", () => + { + const point = new Point(6, 8); + point.normalize(2.5); + expect(point.toString()).toBe("(x=1.5, y=2)"); + }); + + it("normalize test case2", () => + { + const point = new Point(6, 8); + point.normalize(0); + expect(point.toString()).toBe("(x=0, y=0)"); + }); + + it("normalize test case3", () => + { + const point = new Point(6, 8); + point.normalize(-2.5); + expect(point.toString()).toBe("(x=-1.5, y=-2)"); + }); + + it("normalize test case4", () => + { + const point = new Point(-6, 8); + point.normalize(2.5); + expect(point.toString()).toBe("(x=-1.5, y=2)"); + }); + + it("normalize test case5", () => + { + const point = new Point(6, -8); + point.normalize(2.5); + expect(point.toString()).toBe("(x=1.5, y=-2)"); + }); + + it("normalize test case6", () => + { + const point = new Point(-6, -8); + point.normalize(2.5); + expect(point.toString()).toBe("(x=-1.5, y=-2)"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointNormalizeService.ts b/packages/geom/src/Point/service/PointNormalizeService.ts new file mode 100644 index 00000000..05757cd3 --- /dev/null +++ b/packages/geom/src/Point/service/PointNormalizeService.ts @@ -0,0 +1,17 @@ +import type { Point } from "../../Point"; + +/** + * @description (0,0) と現在のポイント間の線のセグメントを設定された長さに拡大 / 縮小します。 + * Expands / contracts the line segment between (0,0) and the current point to the specified length. + * + * @param {number} thickness + * @return {void} + * @method + * @public + */ +export const execute = (src: Point, thickness: number): void => +{ + const value = thickness / src.length; + src.x *= value; + src.y *= value; +}; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointOffsetService.test.ts b/packages/geom/src/Point/service/PointOffsetService.test.ts new file mode 100644 index 00000000..ff60dfa2 --- /dev/null +++ b/packages/geom/src/Point/service/PointOffsetService.test.ts @@ -0,0 +1,42 @@ +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js offset test", () => +{ + + it("offset test case1", () => + { + const point = new Point(10, 20); + point.offset(30, 40); + expect(point.toString()).toBe("(x=40, y=60)"); + }); + + it("offset test case2", () => + { + const point = new Point(10, 20); + point.offset(-30, 40); + expect(point.toString()).toBe("(x=-20, y=60)"); + }); + + it("offset test case3", () => + { + const point = new Point(10, 20); + point.offset(30, -40); + expect(point.toString()).toBe("(x=40, y=-20)"); + }); + + it("offset test case4", () => + { + const point = new Point(-10, 20); + point.offset(30, 40); + expect(point.toString()).toBe("(x=20, y=60)"); + }); + + it("offset test case5", () => + { + const point = new Point(10, -20); + point.offset(30, 40); + expect(point.toString()).toBe("(x=40, y=20)"); + }); + +}); \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointOffsetService.ts b/packages/geom/src/Point/service/PointOffsetService.ts new file mode 100644 index 00000000..beb33dec --- /dev/null +++ b/packages/geom/src/Point/service/PointOffsetService.ts @@ -0,0 +1,18 @@ +import type { Point } from "../../Point"; + +/** + * @description 2点間の補間を返します。 + * Returns the interpolation between two points. + * + * @param {Point} src + * @param {number} dx + * @param {number} dy + * @return {Point} + * @method + * @public + */ +export const execute = (src: Point, dx: number, dy: number): void => +{ + src.x += dx; + src.y += dy; +}; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointPolarService.test.ts b/packages/geom/src/Point/service/PointPolarService.test.ts new file mode 100644 index 00000000..6d4736ed --- /dev/null +++ b/packages/geom/src/Point/service/PointPolarService.test.ts @@ -0,0 +1,192 @@ +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js polar test case", () => +{ + + it("polar test case1", () => + { + const angle = Math.PI * 2 * (30 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=3.464101615137755, y=1.9999999999999998)" + ); + }); + + it("polar test case2", () => + { + const angle = Math.PI * 2 * (45 / 360); // 30 degrees + const point = Point.polar(4, angle); + + expect(point.x | 0).toBe(2); + expect(point.y | 0).toBe(2); + + }); + + it("polar test case3", () => + { + const angle = Math.PI * 2 * (90 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=2.4492935982947064e-16, y=4)" + ); + }); + + it("polar test case4", () => + { + const angle = Math.PI * 2 * (135 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=-2.82842712474619, y=2.8284271247461903)" + ); + }); + + it("polar test case5", () => + { + const angle = Math.PI * 2 * (180 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=-4, y=4.898587196589413e-16)" + ); + }); + + it("polar test case6", () => + { + const angle = Math.PI * 2 * (225 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=-2.8284271247461907, y=-2.82842712474619)" + ); + }); + + it("polar test case7", () => + { + const angle = Math.PI * 2 * (270 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=-7.347880794884119e-16, y=-4)" + ); + }); + + it("polar test case8", () => + { + const angle = Math.PI * 2 * (315 / 360); // 30 degrees + const point = Point.polar(4, angle); + if (point.x > 2.8284271247461894) { + expect(point.x).toBe(2.82842712474619); + } else { + expect(point.x).toBe(2.8284271247461894); + } + expect(point.y).toBe(-2.8284271247461907); + }); + + it("polar test case9", () => + { + const angle = Math.PI * 2 * (360 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=4, y=-9.797174393178826e-16)" + ); + }); + + it("polar test case10", () => + { + const angle = Math.PI * 2 * (-30 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=3.464101615137755, y=-1.9999999999999998)" + ); + }); + + it("polar test case11", () => + { + const angle = Math.PI * 2 * (-45 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.x | 0).toBe(2); + expect(point.y | 0).toBe(-2); + }); + + it("polar test case12", () => + { + const angle = Math.PI * 2 * (-90 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=2.4492935982947064e-16, y=-4)" + ); + }); + + it("polar test case13", () => + { + const angle = Math.PI * 2 * (-135 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=-2.82842712474619, y=-2.8284271247461903)" + ); + }); + + it("polar test case14", () => + { + const angle = Math.PI * 2 * (-180 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=-4, y=-4.898587196589413e-16)" + ); + }); + + it("polar test case15", () => + { + const angle = Math.PI * 2 * (-225 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=-2.8284271247461907, y=2.82842712474619)" + ); + }); + + it("polar test case16", () => + { + const angle = Math.PI * 2 * (-270 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=-7.347880794884119e-16, y=4)" + ); + }); + + it("polar test case17", () => + { + const angle = Math.PI * 2 * (-315 / 360); // 30 degrees + const point = Point.polar(4, angle); + if (point.x > 2.8284271247461894) { + expect(point.x).toBe(2.82842712474619); + } else { + expect(point.x).toBe(2.8284271247461894); + } + expect(point.y).toBe(2.8284271247461907); + }); + + it("polar test case18", () => + { + const angle = Math.PI * 2 * (-360 / 360); // 30 degrees + const point = Point.polar(4, angle); + expect(point.toString()).toBe( + "(x=4, y=9.797174393178826e-16)" + ); + }); + + it("polar test case19", () => + { + const angle = Math.PI * 2 * (30 / 360); // 30 degrees + const point = Point.polar(0, angle); + expect(point.toString()).toBe( + "(x=0, y=0)" + ); + }); + + it("polar test case20", () => + { + const angle = Math.PI * 2 * (30 / 360); // 30 degrees + const point = Point.polar(-4, angle); + expect(point.toString()).toBe( + "(x=-3.464101615137755, y=-1.9999999999999998)" + ); + }); +}); diff --git a/packages/geom/src/Point/service/PointPolarService.ts b/packages/geom/src/Point/service/PointPolarService.ts new file mode 100644 index 00000000..cdb184ec --- /dev/null +++ b/packages/geom/src/Point/service/PointPolarService.ts @@ -0,0 +1,16 @@ +import { Point } from "../../Point"; + +/** + * @description 指定された長さと角度からポイントを返します。 + * Returns a point from the specified length and angle. + * + * @param {number} length + * @param {number} angle + * @return {Point} + * @method + * @public + */ +export const execute = (length: number, angle: number): Point => +{ + return new Point(length * Math.cos(angle), length * Math.sin(angle)); +}; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointSetToService.test.ts b/packages/geom/src/Point/service/PointSetToService.test.ts new file mode 100644 index 00000000..fe57e6dd --- /dev/null +++ b/packages/geom/src/Point/service/PointSetToService.test.ts @@ -0,0 +1,21 @@ +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js setTo test", () => +{ + + it("setTo test case1", () => + { + const point = new Point(10, 20); + point.setTo(30, 40); + expect(point.toString()).toBe("(x=30, y=40)"); + }); + + it("setTo test case2", () => + { + const p = new Point(10, 20); + p.setTo(0, 40); + expect(p.toString()).toBe("(x=0, y=40)"); + }); + +}); \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointSetToService.ts b/packages/geom/src/Point/service/PointSetToService.ts new file mode 100644 index 00000000..7c3261b5 --- /dev/null +++ b/packages/geom/src/Point/service/PointSetToService.ts @@ -0,0 +1,18 @@ +import type { Point } from "../../Point"; + +/** + * @description 指定されたポイントの座標を設定します。 + * Sets the coordinates of the specified point. + * + * @param {Point} src + * @param {number} x + * @param {number} y + * @return {void} + * @method + * @public + */ +export const execute = (src: Point, x: number, y: number): void => +{ + src.x = x; + src.y = y; +}; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointSubtractService.test.ts b/packages/geom/src/Point/service/PointSubtractService.test.ts new file mode 100644 index 00000000..cc29d11a --- /dev/null +++ b/packages/geom/src/Point/service/PointSubtractService.test.ts @@ -0,0 +1,23 @@ +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Point.js subtract test", () => +{ + + it("subtract test case1", () => + { + const p1 = new Point(6, 8); + const p2 = new Point(1.5, 2); + const p3 = p1.subtract(p2); + expect(p3.toString()).toBe("(x=4.5, y=6)"); + }); + + it("subtract test case2", () => + { + const p1 = new Point(6, 8); + const p2 = new Point(-1, 2); + const p3 = p1.subtract(p2); + expect(p3.toString()).toBe("(x=7, y=6)"); + }); + +}); \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointSubtractService.ts b/packages/geom/src/Point/service/PointSubtractService.ts new file mode 100644 index 00000000..6be1dc23 --- /dev/null +++ b/packages/geom/src/Point/service/PointSubtractService.ts @@ -0,0 +1,16 @@ +import { Point } from "../../Point"; + +/** + * @description 指定の座標を減算して、新しいポイントを作成 + * Subtracts the specified coordinates to create a new point. + * + * @param {Point} src + * @param {Point} dst + * @return {Point} + * @method + * @public + */ +export const execute = (src: Point, dst: Point): Point => +{ + return new Point(src.x - dst.x, src.y - dst.y); +}; \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index 3b6650e7..bfb3b8b5 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -10,7 +10,7 @@ export default defineConfig({ "open": "index.html" }, "build": { - "outDir": "docs", + "outDir": "build", "target": "esnext", "modulePreload": { "polyfill": false From 6c32d6423d314569723d1ea93950bc2b4bf841e4 Mon Sep 17 00:00:00 2001 From: ienaga Date: Mon, 22 Jul 2024 22:07:03 +0900 Subject: [PATCH 004/343] =?UTF-8?q?#154=20Lint=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/media/src/Video.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/media/src/Video.ts b/packages/media/src/Video.ts index e753e6fe..e95e7af8 100644 --- a/packages/media/src/Video.ts +++ b/packages/media/src/Video.ts @@ -607,8 +607,8 @@ export class Video extends DisplayObject if (!this._$ready) { await this._$video.play(); this._$video.pause(); - this._$video.currentTime = 0; - this._$ready = true; + this._$video.currentTime = 0; + this._$ready = true; } if (this._$autoPlay) { From 4e5b4780cd7ec381123d46e8fc92b4f80b95298b Mon Sep 17 00:00:00 2001 From: ienaga Date: Mon, 22 Jul 2024 23:50:12 +0900 Subject: [PATCH 005/343] =?UTF-8?q?#154=20feat:=20Rectangle=E3=82=92?= =?UTF-8?q?=E7=A7=BB=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/next2d/geom/RectangleTest.ts | 2530 ----------------- packages/geom/src/Rectangle.test.ts | 224 ++ packages/geom/src/Rectangle.ts | 122 +- .../service/RectangleCloneService.test.ts | 15 + .../service/RectangleCloneService.ts | 15 + .../RectangleContainsPointService.test.ts | 46 + .../service/RectangleContainsPointService.ts | 20 + .../RectangleContainsRectService.test.ts | 35 + .../service/RectangleContainsRectService.ts | 19 + .../service/RectangleContainsService.test.ts | 41 + .../service/RectangleContainsService.ts | 17 + .../service/RectangleCopyFromService.test.ts | 20 + .../service/RectangleCopyFromService.ts | 19 + .../service/RectangleEqualsService.test.ts | 16 + .../service/RectangleEqualsService.ts | 19 + .../RectangleInflatePointService.test.ts | 33 + .../service/RectangleInflatePointService.ts | 20 + .../service/RectangleInflateService.test.ts | 27 + .../service/RectangleInflateService.ts | 20 + .../RectangleIntersectionService.test.ts | 77 + .../service/RectangleIntersectionService.ts | 25 + .../RectangleIntersectsService.test.ts | 38 + .../service/RectangleIntersectsService.ts | 20 + .../service/RectangleIsEmptyService.test.ts | 25 + .../service/RectangleIsEmptyService.ts | 15 + .../RectangleOffsetPointService.test.ts | 19 + .../service/RectangleOffsetPointService.ts | 18 + .../service/RectangleOffsetService.test.ts | 17 + .../service/RectangleOffsetService.ts | 18 + .../service/RectangleSetEmptyService.test.ts | 17 + .../service/RectangleSetEmptyService.ts | 15 + .../service/RectangleSetToService.test.ts | 17 + .../service/RectangleSetToService.ts | 27 + .../service/RectangleUnionService.test.ts | 87 + .../service/RectangleUnionService.ts | 29 + packages/webpack-worker-loader-plugin/LICENSE | 21 - .../webpack-worker-loader-plugin/index.js | 152 - .../webpack-worker-loader-plugin/package.json | 23 - 38 files changed, 1116 insertions(+), 2802 deletions(-) delete mode 100644 __tests__/next2d/geom/RectangleTest.ts create mode 100644 packages/geom/src/Rectangle.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleCloneService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleCloneService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleContainsPointService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleContainsPointService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleContainsRectService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleContainsRectService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleContainsService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleContainsService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleCopyFromService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleCopyFromService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleEqualsService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleEqualsService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleInflatePointService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleInflatePointService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleInflateService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleInflateService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleIntersectionService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleIntersectionService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleIntersectsService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleIntersectsService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleIsEmptyService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleIsEmptyService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleOffsetPointService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleOffsetPointService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleOffsetService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleOffsetService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleSetEmptyService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleSetEmptyService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleSetToService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleSetToService.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleUnionService.test.ts create mode 100644 packages/geom/src/Rectangle/service/RectangleUnionService.ts delete mode 100644 packages/webpack-worker-loader-plugin/LICENSE delete mode 100644 packages/webpack-worker-loader-plugin/index.js delete mode 100644 packages/webpack-worker-loader-plugin/package.json diff --git a/__tests__/next2d/geom/RectangleTest.ts b/__tests__/next2d/geom/RectangleTest.ts deleted file mode 100644 index ee886867..00000000 --- a/__tests__/next2d/geom/RectangleTest.ts +++ /dev/null @@ -1,2530 +0,0 @@ -import { Rectangle } from "../../../packages/geom/src/Rectangle"; -import { Point } from "../../../packages/geom/src/Point"; -import {$SHORT_INT_MAX, $SHORT_INT_MIN} from "../../../packages/share/src/RenderUtil"; - -describe("Rectangle.js toString test", () => -{ - it("toString test1 success", () => - { - const object = new Rectangle(); - expect(object.toString()).toBe("(x=0, y=0, w=0, h=0)"); - }); - - it("toString test2 success", () => - { - const object = new Rectangle(1, 2, 3, 4); - expect(object.toString()).toBe("(x=1, y=2, w=3, h=4)"); - }); - -}); - -describe("Rectangle.js static toString test", () => -{ - - it("static toString test", () => - { - expect(Rectangle.toString()).toBe("[class Rectangle]"); - }); - -}); - -describe("Rectangle.js namespace test", () => -{ - - it("namespace test public", () => - { - const object = new Rectangle(); - expect(object.namespace).toBe("next2d.geom.Rectangle"); - }); - - it("namespace test static", () => - { - expect(Rectangle.namespace).toBe("next2d.geom.Rectangle"); - }); - -}); - -describe("Rectangle.js property test", () => -{ - it("top test1", () => - { - - let r = new Rectangle(50, 50, 100, 100); - expect(r.top).toBe(50); - expect(r.bottom).toBe(150); - - // success - r.top = 160; - expect(r.toString()).toBe("(x=50, y=160, w=100, h=-10)"); - expect(r.bottom).toBe(150); - expect(r.y).toBe(160); - - // @ts-ignore - r.top = "a"; - expect(r.y).toBe(0); - expect(r.height).toBe(0); - }); - - it("top test2", () => - { - - let r = new Rectangle(-50, -50, -100, -100); - expect(r.top).toBe(-50); - expect(r.bottom).toBe(-150); - - // success - r.top = 160; - expect(r.toString()).toBe("(x=-50, y=160, w=-100, h=-310)"); - expect(r.bottom).toBe(-150); - expect(r.y).toBe(160); - - // @ts-ignore - r.top = "a"; - expect(r.y).toBe(0); - expect(r.height).toBe(0); - }); - - it("right test1", () => - { - - let r = new Rectangle(50, 100, 100, 100); - expect(r.right).toBe(150); - - // success - r.right = 20; - expect(r.toString()).toBe("(x=50, y=100, w=-30, h=100)"); - - // @ts-ignore - r.right = "a"; - expect(r.right).toBe(50); - }); - - it("right test2", () => - { - - let r = new Rectangle(50, -100, -100, -100); - expect(r.right).toBe(-50); - - // success - - r.right = 20; - expect(r.toString()).toBe("(x=50, y=-100, w=-30, h=-100)"); - - // @ts-ignore - r.right = "a"; - expect(r.right).toBe(50); - }); - - it("bottom test1", () => - { - - let r = new Rectangle(0, 100, 100, 100); - expect(r.bottom).toBe(200); - - // success - r.bottom = 50; - expect(r.toString()).toBe("(x=0, y=100, w=100, h=-50)"); - - // @ts-ignore - r.bottom = "a"; - expect(r.height).toBe(0); - }); - - it("bottom test2", () => - { - - let r = new Rectangle(0, -100, -100, -100); - expect(r.bottom).toBe(-200); - - // success - r.bottom = -50; - expect(r.toString()).toBe("(x=0, y=-100, w=-100, h=50)"); - - // @ts-ignore - r.bottom = "a"; - expect(r.height).toBe(0); - }); - - it("left test1", () => - { - - let r = new Rectangle(50, 50, 100, 100); - expect(r.left).toBe(50); - expect(r.right).toBe(150); - - // success - r.left = 160; - expect(r.toString()).toBe("(x=160, y=50, w=-10, h=100)"); - expect(r.right).toBe(150); - expect(r.x).toBe(160); - - // @ts-ignore - r.left = "a"; - expect(r.x).toBe(0); - expect(r.width).toBe(0); - }); - - it("left test2", () => - { - - let r = new Rectangle(-50, -50, -100, -100); - expect(r.left).toBe(-50); - expect(r.right).toBe(-150); - - // success - r.left = 160; - expect(r.toString()).toBe("(x=160, y=-50, w=-310, h=-100)"); - expect(r.right).toBe(-150); - expect(r.x).toBe(160); - - // @ts-ignore - r.left = "a"; - expect(r.x).toBe(0); - expect(r.width).toBe(0); - }); - - it("bottomRight test1", () => - { - - let r = new Rectangle(30, 50, 80, 100); - let p = r.bottomRight; - expect(p.toString()).toBe("(x=110, y=150)"); - - r.bottomRight = new Point(10 ,10); - expect(r.toString()).toBe("(x=30, y=50, w=-20, h=-40)"); - }); - - it("bottomRight test2", () => - { - - let r = new Rectangle(-30, -50, -80, -100); - let p = r.bottomRight; - expect(p.toString()).toBe("(x=-110, y=-150)"); - - r.bottomRight = new Point(10 ,10); - expect(r.toString()).toBe("(x=-30, y=-50, w=40, h=60)"); - }); - - it("topLeft test1", () => - { - - let r = new Rectangle(30, 50, 80, 100); - let p = r.topLeft; - expect(p.toString()).toBe("(x=30, y=50)"); - - r.topLeft = new Point(10 ,10); - expect(r.toString()).toBe("(x=10, y=10, w=100, h=140)"); - }); - - it("topLeft test2", () => - { - - let r = new Rectangle(-30, -50, -80, -100); - let p = r.topLeft; - expect(p.toString()).toBe("(x=-30, y=-50)"); - - r.topLeft = new Point(10 ,10); - expect(r.toString()).toBe("(x=10, y=10, w=-120, h=-160)"); - }); - - it("size test1", () => - { - - let r = new Rectangle(30, 50, 80, 100); - let p = r.size; - expect(p.toString()).toBe("(x=80, y=100)"); - - r.size = new Point(10 ,10); - expect(r.toString()).toBe("(x=30, y=50, w=10, h=10)"); - }); - - it("size test2", () => - { - - let r = new Rectangle(-30, -50, -80, -100); - let p = r.size; - expect(p.toString()).toBe("(x=-80, y=-100)"); - - r.size = new Point(10 ,10); - expect(r.toString()).toBe("(x=-30, y=-50, w=10, h=10)"); - }); -}); - -describe("Rectangle.js clone test", () => -{ - it("clone test", () => - { - let r1 = new Rectangle(30, 50, 80, 100); - let r2 = r1.clone(); - r2.x = 100; - - expect(r1.toString()).toBe("(x=30, y=50, w=80, h=100)"); - expect(r2.toString()).toBe("(x=100, y=50, w=80, h=100)"); - }); -}); - -describe("Rectangle.js contains test", () => -{ - - it("contains test1", () => - { - let r = new Rectangle(30, 50, 80, 100); - expect(r.contains(30, 50)).toBe(true); - expect(r.contains(110, 150)).toBe(false); - expect(r.contains(109, 149)).toBe(true); - expect(r.contains(20, 40)).toBe(false); - }); - - it("contains test2", () => - { - let r = new Rectangle(0, 0, 0, 0); - expect(r.contains(0, 0)).toBe(false); - // @ts-ignore - expect(r.contains("a", 0)).toBe(false); - // @ts-ignore - expect(r.contains(0, "a")).toBe(false); - }); - - it("contains test3", () => - { - let r = new Rectangle(0, 0, 1, 1); - expect(r.contains(0, 0)).toBe(true); - expect(r.contains(0.000001, 0.000001)).toBe(true); - expect(r.contains(0.999999, 0.999999)).toBe(true); - expect(r.contains(1, 0)).toBe(false); - expect(r.contains(0, 1)).toBe(false); - expect(r.contains(1, 1)).toBe(false); - }); - - it("contains test4", () => - { - let r = new Rectangle(-1, -1, 1, 1); - expect(r.contains(0, 0)).toBe(false); - expect(r.contains(-1, -1)).toBe(true); - expect(r.contains(-1, -0.5)).toBe(true); - expect(r.contains(-0.5, -1)).toBe(true); - }); - -}); - -describe("Rectangle.js containsPoint test", () => -{ - it("containsPoint test1", () => - { - let r = new Rectangle(30, 50, 80, 100); - - let p1 = new Point(30, 50); - expect(r.containsPoint(p1)).toBe(true); - - let p2 = new Point(110, 150); - expect(r.containsPoint(p2)).toBe(false); - - let p3 = new Point(109, 149); - expect(r.containsPoint(p3)).toBe(true); - - let p4 = new Point(20, 40); - expect(r.containsPoint(p4)).toBe(false); - }); - - it("containsPoint test2", () => - { - let r = new Rectangle(-30, -50, -80, -100); - - let p1 = new Point(-30, -50); - expect(r.containsPoint(p1)).toBe(false); - - let p2 = new Point(-110, -150); - expect(r.containsPoint(p2)).toBe(false); - - let p3 = new Point(-109, -149); - expect(r.containsPoint(p3)).toBe(false); - - let p5 = new Point(110, 150); - expect(r.containsPoint(p5)).toBe(false); - - let p6 = new Point(109, 149); - expect(r.containsPoint(p6)).toBe(false); - - let p4 = new Point(-20, -40); - expect(r.containsPoint(p4)).toBe(false); - }); -}); - -describe("Rectangle.js containsRect test", () => -{ - it("containsRect test1", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - let r2 = new Rectangle(15, 15, 5, 5); - expect(r1.containsRect(r2)).toBe(true); - - let r3 = new Rectangle(10, 10, 20, 20); - let r4 = new Rectangle(10, 10, 20, 20); - expect(r3.containsRect(r4)).toBe(true); - - let r5 = new Rectangle(10, 10, 20, 20); - let r6 = new Rectangle(9, 9, 20, 20); - expect(r5.containsRect(r6)).toBe(false); - - let r7 = new Rectangle(10, 10, 20, 20); - let r8 = new Rectangle(15, 15, 20, 20); - expect(r7.containsRect(r8)).toBe(false); - }); - - it("containsRect test2", () => - { - let r1 = new Rectangle(-10, -10, -20, -20); - let r2 = new Rectangle(-15, -15, -5, -5); - expect(r1.containsRect(r2)).toBe(false); - - let r3 = new Rectangle(-10, -10, 20, 20); - let r4 = new Rectangle(-15, -15, 5, 5); - expect(r3.containsRect(r4)).toBe(false); - }); -}); - -describe("Rectangle.js copyFrom test", () => -{ - it("copyFrom test", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - let r2 = new Rectangle(15, 15, 5, 5); - - r1.copyFrom(r2); - expect(r1.toString()).toBe("(x=15, y=15, w=5, h=5)"); - expect(r2.toString()).toBe("(x=15, y=15, w=5, h=5)"); - - r1.x = 10; - r1.y = 10; - r1.width = 20; - r1.height = 20; - expect(r1.toString()).toBe("(x=10, y=10, w=20, h=20)"); - expect(r2.toString()).toBe("(x=15, y=15, w=5, h=5)"); - }); -}); - -describe("Rectangle.js equals test", () => -{ - it("equals test", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - let r2 = new Rectangle(10, 10, 20, 20); - expect(r1.equals(r2)).toBe(true); - - let r3 = new Rectangle(10, 10, 20, 20); - let r4 = new Rectangle(15, 15, 5, 5); - expect(r3.equals(r4)).toBe(false); - }); -}); - -describe("Rectangle.js inflate test", () => -{ - it("inflate test1", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - r1.inflate(10, 10); - expect(r1.toString()).toBe("(x=0, y=0, w=40, h=40)"); - - let r2 = new Rectangle(10, 10, 20, 20); - r2.inflate(20, 20); - expect(r2.toString()).toBe("(x=-10, y=-10, w=60, h=60)"); - }); - - it("inflate test2", () => - { - let r1 = new Rectangle(-10, -10, -20, -20); - r1.inflate(10, 10); - expect(r1.toString()).toBe("(x=-20, y=-20, w=0, h=0)"); - - let r2 = new Rectangle(10, 10, 20, 20); - r2.inflate(-20, -20); - expect(r2.toString()).toBe("(x=30, y=30, w=-20, h=-20)"); - }); - - it("inflate test3", () => - { - let r1 = new Rectangle(-10, -10, -20, -20); - // @ts-ignore - r1.inflate("a", 10); - expect(r1.toString()).toBe("(x=0, y=-20, w=0, h=0)"); - - // @ts-ignore - let r2 = new Rectangle("a", -10, -20, -20); - r2.inflate(20, 20); - expect(r2.toString()).toBe("(x=-20, y=-30, w=20, h=20)"); - - // @ts-ignore - let r3 = new Rectangle(-10, "a", -20, -20); - r3.inflate(20, 20); - expect(r3.toString()).toBe("(x=-30, y=-20, w=20, h=20)"); - - // @ts-ignore - let r4 = new Rectangle(-10, -10, "a", -20); - r4.inflate(20, 20); - expect(r4.toString()).toBe("(x=-30, y=-30, w=40, h=20)"); - }); -}); - -describe("Rectangle.js inflatePoint test", () => -{ - it("inflatePoint test1", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - let p1 = new Point(10, 10); - r1.inflatePoint(p1); - expect(r1.toString()).toBe("(x=0, y=0, w=40, h=40)"); - - let r2 = new Rectangle(10, 10, 20, 20); - let p2 = new Point(20, 20); - r2.inflatePoint(p2); - expect(r2.toString()).toBe("(x=-10, y=-10, w=60, h=60)"); - }); - - it("inflatePoint test2", () => - { - let r1 = new Rectangle(-10, -10, -20, -20); - let p1 = new Point(10, 10); - r1.inflatePoint(p1); - expect(r1.toString()).toBe("(x=-20, y=-20, w=0, h=0)"); - - let r2 = new Rectangle(-10, -10, 20, 20); - let p2 = new Point(20, 20); - r2.inflatePoint(p2); - expect(r2.toString()).toBe("(x=-30, y=-30, w=60, h=60)"); - }); - - it("inflatePoint test3", () => - { - let r1 = new Rectangle(-10, -10, -20, -20); - // @ts-ignore - let p1 = new Point("a", 10); - r1.inflatePoint(p1); - expect(r1.toString()).toBe("(x=-10, y=-20, w=-20, h=0)"); - - // @ts-ignore - let r2 = new Rectangle("a", -10, -20, -20); - let p2 = new Point(20, 20); - r2.inflatePoint(p2); - expect(r2.toString()).toBe("(x=-20, y=-30, w=20, h=20)"); - - // @ts-ignore - let r3 = new Rectangle(-10, "a", -20, -20); - let p3 = new Point(20, 20); - r3.inflatePoint(p3); - expect(r3.toString()).toBe("(x=-30, y=-20, w=20, h=20)"); - - // @ts-ignore - let r4 = new Rectangle(-10, -10, "a", -20); - let p4 = new Point(20, 20); - r4.inflatePoint(p4); - expect(r4.toString()).toBe("(x=-30, y=-30, w=40, h=20)"); - }); -}); - -describe("Rectangle.js intersection test", () => -{ - it("intersection test1", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - let r2 = new Rectangle(5, 5, 5, 5); - let r3 = r1.intersection(r2); - expect(r3.toString()).toBe("(x=0, y=0, w=0, h=0)"); - - let r4 = new Rectangle(10, 10, 20, 20); - let r5 = new Rectangle(15, 15, 5, 5); - let r6 = r4.intersection(r5); - expect(r6.toString()).toBe("(x=15, y=15, w=5, h=5)"); - - let r7 = new Rectangle(10, 10, 20, 20); - let r8 = new Rectangle(5, 5, 25, 25); - let r9 = r7.intersection(r8); - expect(r9.toString()).toBe("(x=10, y=10, w=20, h=20)"); - }); - - it("intersection test2", () => - { - let r1 = new Rectangle(-10, -10, -20, -20); - let r2 = new Rectangle(-5, -5, -5, -5); - let r3 = r1.intersection(r2); - expect(r3.toString()).toBe("(x=0, y=0, w=0, h=0)"); - - let r4 = new Rectangle(-10, -10, -20, -20); - let r5 = new Rectangle(-15, -15, -5, -5); - let r6 = r4.intersection(r5); - expect(r6.toString()).toBe("(x=0, y=0, w=0, h=0)"); - - let r7 = new Rectangle(-10, -10, -20, -20); - let r8 = new Rectangle(-5, -5, -25, -25); - let r9 = r7.intersection(r8); - expect(r9.toString()).toBe("(x=0, y=0, w=0, h=0)"); - }); - - it("intersection test3", () => - { - let r1 = new Rectangle(-10, -10, 20, 20); - let r2 = new Rectangle(-5, -5, 5, 5); - let r3 = r1.intersection(r2); - expect(r3.toString()).toBe("(x=-5, y=-5, w=5, h=5)"); - - let r4 = new Rectangle(-10, -10, 20, 20); - let r5 = new Rectangle(-15, -15, 5, 5); - let r6 = r4.intersection(r5); - expect(r6.toString()).toBe("(x=0, y=0, w=0, h=0)"); - - let r7 = new Rectangle(-10, -10, 20, 20); - let r8 = new Rectangle(-5, -5, 25, 25); - let r9 = r7.intersection(r8); - expect(r9.toString()).toBe("(x=-5, y=-5, w=15, h=15)"); - }); - - it("intersection test4", () => - { - let r1 = new Rectangle(-10, -10, 20, 20); - let r2 = new Rectangle(-10, -10, 0, 10); - let r3 = r1.intersection(r2); - expect(r3.toString()).toBe("(x=0, y=0, w=0, h=0)"); - - let r4 = new Rectangle(-10, -10, 20, 20); - let r5 = new Rectangle(-10, -10, 5, 5); - let r6 = r4.intersection(r5); - expect(r6.toString()).toBe("(x=-10, y=-10, w=5, h=5)"); - - let r7 = new Rectangle(-5, -5, -25, -25); - let r8 = new Rectangle(-10, -10, -20, -20); - let r9 = r7.intersection(r8); - expect(r9.toString()).toBe("(x=0, y=0, w=0, h=0)"); - }); - - it("intersection test5", () => - { - // @ts-ignore - let r1 = new Rectangle("a", 10, 20, 20); - let r2 = new Rectangle(15, 15, 5, 5); - let r3 = r1.intersection(r2); - expect(r3.toString()).toBe("(x=15, y=15, w=5, h=5)"); - - // @ts-ignore - let r4 = new Rectangle(10, 10, "a", 20); - let r5 = new Rectangle(15, 15, 5, 5); - let r6 = r4.intersection(r5); - expect(r6.toString()).toBe("(x=0, y=0, w=0, h=0)"); - - let r7 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r8 = new Rectangle(5, "a", 25, 25); - let r9 = r7.intersection(r8); - expect(r9.toString()).toBe("(x=10, y=10, w=20, h=15)"); - - let r10 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r11 = new Rectangle(5, 5, 25, "a"); - let r12 = r10.intersection(r11); - expect(r12.toString()).toBe("(x=0, y=0, w=0, h=0)"); - }); -}); - -describe("Rectangle.js intersects test", () => -{ - it("intersects test1", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - let r2 = new Rectangle(5, 5, 5, 5); - expect(r1.intersects(r2)).toBe(false); - - let r3 = new Rectangle(10, 10, 20, 20); - let r4 = new Rectangle(5, 5, 25, 25); - expect(r3.intersects(r4)).toBe(true); - }); - - it("intersects test2", () => - { - let r1 = new Rectangle(-10, -10, -20, -20); - let r2 = new Rectangle(-5, -5, -25, -25); - expect(r1.intersects(r2)).toBe(false); - - let r3 = new Rectangle(-10, -10, 20, 20); - let r4 = new Rectangle(-5, -5, 25, 25); - expect(r3.intersects(r4)).toBe(true); - }); - - it("intersects test3", () => - { - // @ts-ignore - let r1 = new Rectangle("a", 10, 20, 20); - let r2 = new Rectangle(5, 5, 25, 25); - expect(r1.intersects(r2)).toBe(true); - - // @ts-ignore - let r3 = new Rectangle(10, 10, "a", 20); - let r4 = new Rectangle(5, 5, 25, 25); - expect(r3.intersects(r4)).toBe(false); - }); - - it("intersects test4", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r2 = new Rectangle(5, "a", 25, 25); - - expect(r1.intersects(r2)).toBe(true); - - let r3 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r4 = new Rectangle(5, 5, 25, "a"); - expect(r3.intersects(r4)).toBe(false); - }); - - it("intersects test5", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r2 = new Rectangle(5, "a", 5, 5); - expect(r1.intersects(r2)).toBe(false); - - let r3 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r4 = new Rectangle(5, 5, 5, "a"); - expect(r3.intersects(r4)).toBe(false); - }); - - it("intersects test6", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r2 = new Rectangle(5, "a", -5, 5); - expect(r1.intersects(r2)).toBe(false); - - let r3 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r4 = new Rectangle(5, 5, 100, "a"); - expect(r3.intersects(r4)).toBe(false); - }); - - it("intersects test7", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - let r2 = new Rectangle(5, 40, 10, 10); - expect(r1.intersects(r2)).toBe(false); - - let r3 = new Rectangle(10, 10, 20, 20); - let r4 = new Rectangle(5, 15, 10, 10); - expect(r3.intersects(r4)).toBe(true); - }); - - it("intersects test8", () => - { - // @ts-ignore - let r1 = new Rectangle("a", 10, 20, 20); - let r2 = new Rectangle(5, 40, 10, 10); - expect(r1.intersects(r2)).toBe(false); - - // @ts-ignore - let r3 = new Rectangle(10, "a", 20, 20); - let r4 = new Rectangle(5, 40, 10, 10); - expect(r3.intersects(r4)).toBe(false); - }); - - it("intersects test9", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r2 = new Rectangle("a", 40, 10, 10); - expect(r1.intersects(r2)).toBe(false); - - let r3 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r4 = new Rectangle(5, "a", 10, 10); - expect(r3.intersects(r4)).toBe(false); - }); - - it("intersects test10", () => - { - // @ts-ignore - let r1 = new Rectangle("a", 10, 20, 20); - let r2 = new Rectangle(5, 15, 10, 10); - expect(r1.intersects(r2)).toBe(true); - - // @ts-ignore - let r3 = new Rectangle(10, "a", 20, 20); - let r4 = new Rectangle(5, 15, 10, 10); - expect(r3.intersects(r4)).toBe(true); - }); - - it("intersects test11", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r2 = new Rectangle("a", 15, 10, 10); - expect(r1.intersects(r2)).toBe(false); - - let r3 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r4 = new Rectangle(5, "a", 10, 10); - expect(r3.intersects(r4)).toBe(false); - }); - - it("intersects test12", () => - { - // @ts-ignore - let r1 = new Rectangle(10, 10, "a", 20); - let r2 = new Rectangle(5, 40, 10, 10); - expect(r1.intersects(r2)).toBe(false); - - // @ts-ignore - let r3 = new Rectangle(10, 10, 20, "a"); - let r4 = new Rectangle(5, 40, 10, 10); - expect(r3.intersects(r4)).toBe(false); - }); - - it("intersects test13", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r2 = new Rectangle(5, 40, "a", 10); - expect(r1.intersects(r2)).toBe(false); - - let r3 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r4 = new Rectangle(5, 40, 10, "a"); - expect(r3.intersects(r4)).toBe(false); - }); - - it("intersects test14", () => - { - // @ts-ignore - let r1 = new Rectangle(10, 10, "a", 20); - let r2 = new Rectangle(5, 15, 10, 10); - expect(r1.intersects(r2)).toBe(false); - - // @ts-ignore - let r3 = new Rectangle(10, 10, 20, "a"); - let r4 = new Rectangle(5, 15, 10, 10); - expect(r3.intersects(r4)).toBe(false); - }); - - it("intersects test15", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r2 = new Rectangle(5, 15, "a", 10); - expect(r1.intersects(r2)).toBe(false); - - let r3 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - let r4 = new Rectangle(5, 15, 10, "a"); - expect(r3.intersects(r4)).toBe(false); - }); - -}); - -describe("Rectangle.js isEmpty test", () => -{ - it("isEmpty test1", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - let r2 = new Rectangle(-55, -55, 0, 0); - expect(r1.isEmpty()).toBe(false); - expect(r2.isEmpty()).toBe(true); - }); - - it("isEmpty test2", () => - { - let r1 = new Rectangle(10, 10, 0, 20); - expect(r1.isEmpty()).toBe(true); - }); - - it("isEmpty test3", () => - { - let r1 = new Rectangle(10, 10, 20, 0); - expect(r1.isEmpty()).toBe(true); - }); - - it("isEmpty test4", () => - { - // @ts-ignore - let r1 = new Rectangle("a", 10, 20, 0); - expect(r1.isEmpty()).toBe(true); - }); - - it("isEmpty test5", () => - { - // @ts-ignore - let r1 = new Rectangle(10, "a", 0, 20); - expect(r1.isEmpty()).toBe(true); - }); - - it("isEmpty test6", () => - { - // @ts-ignore - let r1 = new Rectangle(10, 10, "a", 20); - expect(r1.isEmpty()).toBe(true); - }); - - it("isEmpty test7", () => - { - // @ts-ignore - let r1 = new Rectangle(10, 10, 20, "a"); - expect(r1.isEmpty()).toBe(true); - }); - - it("isEmpty test8", () => - { - // @ts-ignore - let r1 = new Rectangle("a", 10, 0, 20); - expect(r1.isEmpty()).toBe(true); - }); - - it("isEmpty test9", () => - { - // @ts-ignore - let r1 = new Rectangle(10, "a", 0, 20); - expect(r1.isEmpty()).toBe(true); - }); - - it("isEmpty test10", () => - { - // @ts-ignore - let r1 = new Rectangle(10, 10, "a", 20); - expect(r1.isEmpty()).toBe(true); - }); - - it("isEmpty test11", () => - { - // @ts-ignore - let r1 = new Rectangle(10, 10, 0, "a"); - expect(r1.isEmpty()).toBe(true); - }); - - it("isEmpty test12", () => - { - // @ts-ignore - let r1 = new Rectangle(10, 10, "a", 0); - expect(r1.isEmpty()).toBe(true); - }); -}); - -describe("Rectangle.js offset test", () => -{ - it("offset test1", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - let r2 = new Rectangle(-55, -55, 0, 0); - - r1.offset(5, 8); - r2.offset(60, 30); - - expect(r1.toString()).toBe("(x=15, y=18, w=20, h=20)"); - expect(r2.toString()).toBe("(x=5, y=-25, w=0, h=0)"); - }); - - it("offsetPoint test2", () => - { - // @ts-ignore - let r1 = new Rectangle("a", 10, 20, 20); - let r2 = new Rectangle(-55, -55, 0, 0); - - r1.offset(5, 8); - // @ts-ignore - r2.offset("a", 30); - - expect(r1.toString()).toBe("(x=5, y=18, w=20, h=20)"); - expect(r2.toString()).toBe("(x=0, y=-25, w=0, h=0)"); - }); - - it("offsetPoint test3", () => - { - // @ts-ignore - let r1 = new Rectangle(10, 10, "a", 20); - let r2 = new Rectangle(-55, -55, 0, 0); - - r1.offset(5, 8); - // @ts-ignore - r2.offset(60, "a"); - - expect(r1.toString()).toBe("(x=15, y=18, w=0, h=20)"); - expect(r2.toString()).toBe("(x=5, y=0, w=0, h=0)"); - }); -}); - -describe("Rectangle.js offsetPoint test", () => -{ - it("offsetPoint test1", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - let r2 = new Rectangle(-55, -55, 0, 0); - - r1.offsetPoint(new Point(5, 8)); - r2.offsetPoint(new Point(60, 30)); - - expect(r1.toString()).toBe("(x=15, y=18, w=20, h=20)"); - expect(r2.toString()).toBe("(x=5, y=-25, w=0, h=0)"); - }); - - it("offsetPoint test2", () => - { - // @ts-ignore - let r1 = new Rectangle("a", 10, 20, 20); - let r2 = new Rectangle(-55, -55, 0, 0); - - r1.offsetPoint(new Point(5, 8)); - // @ts-ignore - r2.offsetPoint(new Point("a", 30)); - - expect(r1.toString()).toBe("(x=5, y=18, w=20, h=20)"); - expect(r2.toString()).toBe("(x=-55, y=-25, w=0, h=0)"); - }); - - it("offsetPoint test3", () => - { - // @ts-ignore - let r1 = new Rectangle(10, 10, "a", 20); - let r2 = new Rectangle(-55, -55, 0, 0); - - r1.offsetPoint(new Point(5, 8)); - // @ts-ignore - r2.offsetPoint(new Point(60, "a")); - - expect(r1.toString()).toBe("(x=15, y=18, w=0, h=20)"); - expect(r2.toString()).toBe("(x=5, y=-55, w=0, h=0)"); - }); -}); - -describe("Rectangle.js setEmpty test", () => -{ - it("setEmpty test1", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - let r2 = new Rectangle(-55, -55, 0, 0); - - r1.setEmpty(); - r2.setEmpty(); - - expect(r1.toString()).toBe("(x=0, y=0, w=0, h=0)"); - expect(r2.toString()).toBe("(x=0, y=0, w=0, h=0)"); - }); - - it("setEmpty test2", () => - { - // @ts-ignore - let r1 = new Rectangle("a", 10, 20, 20); - let r2 = new Rectangle(-55, -55, 0, 0); - - r1.setEmpty(); - r2.setEmpty(); - - expect(r1.toString()).toBe("(x=0, y=0, w=0, h=0)"); - expect(r2.toString()).toBe("(x=0, y=0, w=0, h=0)"); - }); -}); - -describe("Rectangle.js setTo test", () => -{ - it("setTo test1", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - let r2 = new Rectangle(-55, -55, 0, 0); - - r1.setTo(5, 5, 5, 5); - r2.setTo(10, 10, 10, 10); - - expect(r1.toString()).toBe("(x=5, y=5, w=5, h=5)"); - expect(r2.toString()).toBe("(x=10, y=10, w=10, h=10)"); - }); - - it("setTo test2", () => - { - // @ts-ignore - let r1 = new Rectangle("a", 10, 20, 20); - r1.setTo(5, 5, 5, 5); - expect(r1.toString()).toBe("(x=5, y=5, w=5, h=5)"); - }); - - it("setTo test3", () => - { - // @ts-ignore - let r1 = new Rectangle(10, "a", 20, 20); - r1.setTo(5, 5, 5, 5); - expect(r1.toString()).toBe("(x=5, y=5, w=5, h=5)"); - }); - - it("setTo test4", () => - { - // @ts-ignore - let r1 = new Rectangle(10, 10, "a", 20); - r1.setTo(5, 5, 5, 5); - expect(r1.toString()).toBe("(x=5, y=5, w=5, h=5)"); - }); - - it("setTo test5", () => - { - // @ts-ignore - let r1 = new Rectangle(10, 10, 20, "a"); - r1.setTo(5, 5, 5, 5); - expect(r1.toString()).toBe("(x=5, y=5, w=5, h=5)"); - }); - - it("setTo test6", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - r1.setTo("a", 5, 5, 5); - expect(r1.toString()).toBe("(x=0, y=5, w=5, h=5)"); - }); - - it("setTo test7", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - r1.setTo(5, "a", 5, 5); - expect(r1.toString()).toBe("(x=5, y=0, w=5, h=5)"); - }); - - it("setTo test8", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - r1.setTo(5, 5, "a", 5); - expect(r1.toString()).toBe("(x=5, y=5, w=0, h=5)"); - }); - - it("setTo test9", () => - { - let r1 = new Rectangle(10, 10, 20, 20); - // @ts-ignore - r1.setTo(5, 5, 5, "a"); - expect(r1.toString()).toBe("(x=5, y=5, w=5, h=0)"); - }); -}); - -describe("Rectangle.js union test", () => -{ - it("union test1", () => - { - let r1 = new Rectangle(10, 10, 0, 10); - let r2 = new Rectangle(-55, -25, 0, 20); - let r3 = r1.union(r2); - expect(r3.toString()).toBe("(x=-55, y=-25, w=0, h=20)"); - - let r4 = new Rectangle(10, 10, 10, 10); - let r5 = new Rectangle(-55, -25, 0, 20); - let r6 = r4.union(r5); - expect(r6.toString()).toBe("(x=10, y=10, w=10, h=10)"); - - let r7 = new Rectangle(10, 10, 10, 10); - let r8 = new Rectangle(-55, -25, 20, 20); - let r9 = r7.union(r8); - expect(r9.toString()).toBe("(x=-55, y=-25, w=75, h=45)"); - }); - - it("union test2", () => - { - let r1 = new Rectangle(10, 10, 10, 10); - let r2 = new Rectangle(20, 20, 10, 10); - let r3 = r1.union(r2); - expect(r3.toString()).toBe("(x=10, y=10, w=20, h=20)"); - }); - - it("union test3", () => - { - let r1 = new Rectangle(-10, 10, 10, 10); - let r2 = new Rectangle(20, 20, 10, 10); - let r3 = r1.union(r2); - expect(r3.toString()).toBe("(x=-10, y=10, w=40, h=20)"); - }); - - it("union test4", () => - { - let r1 = new Rectangle(10, -10, 10, 10); - let r2 = new Rectangle(20, 20, 10, 10); - let r3 = r1.union(r2); - expect(r3.toString()).toBe("(x=10, y=-10, w=20, h=40)"); - }); - - it("union test5", () => - { - let r1 = new Rectangle(-10, -10, 10, 10); - let r2 = new Rectangle(20, 20, 10, 10); - let r3 = r1.union(r2); - expect(r3.toString()).toBe("(x=-10, y=-10, w=40, h=40)"); - }); - - it("union test6", () => - { - let r1 = new Rectangle(10, 10, 10, 10); - let r2 = new Rectangle(20, 20, 10, 10); - let r3 = r2.union(r1); - expect(r3.toString()).toBe("(x=10, y=10, w=20, h=20)"); - }); - - it("union test7", () => - { - let r1 = new Rectangle(-10, 10, 10, 10); - let r2 = new Rectangle(20, 20, 10, 10); - let r3 = r2.union(r1); - expect(r3.toString()).toBe("(x=-10, y=10, w=40, h=20)"); - }); - - it("union test8", () => - { - let r1 = new Rectangle(10, -10, 10, 10); - let r2 = new Rectangle(20, 20, 10, 10); - let r3 = r2.union(r1); - expect(r3.toString()).toBe("(x=10, y=-10, w=20, h=40)"); - }); - - it("union test9", () => - { - let r1 = new Rectangle(-10, -10, 10, 10); - let r2 = new Rectangle(20, 20, 10, 10); - let r3 = r2.union(r1); - expect(r3.toString()).toBe("(x=-10, y=-10, w=40, h=40)"); - }); - - it("union test2", () => - { - // @ts-ignore - let r1 = new Rectangle("a", 10, 10, 10); - let r2 = new Rectangle(20, 20, 10, 10); - let r3 = r1.union(r2); - expect(r3.toString()).toBe("(x=0, y=10, w=30, h=20)"); - }); - - it("union test2", () => - { - // @ts-ignore - let r1 = new Rectangle(10, "a", 10, 10); - let r2 = new Rectangle(20, 20, 10, 10); - let r3 = r1.union(r2); - expect(r3.toString()).toBe("(x=10, y=0, w=20, h=30)"); - }); - - it("union test2", () => - { - // @ts-ignore - let r1 = new Rectangle(10, 10, "a", 10); - let r2 = new Rectangle(20, 20, 10, 10); - let r3 = r1.union(r2); - expect(r3.toString()).toBe("(x=20, y=20, w=10, h=10)"); - }); - - it("union test2", () => - { - // @ts-ignore - let r1 = new Rectangle(10, 10, 10, "a"); - let r2 = new Rectangle(20, 20, 10, 10); - let r3 = r1.union(r2); - expect(r3.toString()).toBe("(x=20, y=20, w=10, h=10)"); - }); -}); - -describe("Rectangle.js bottom test", () => -{ - - it("default test case1", () => - { - let r = new Rectangle(); - expect(r.bottom).toBe(0); - }); - - it("default test case2", () => - { - let r = new Rectangle(); - // @ts-ignore - r.bottom = null; - expect(r.bottom).toBe(0); - }); - - it("default test case3", () => - { - let r = new Rectangle(); - // @ts-ignore - r.bottom = undefined; - expect(r.bottom).toBe(0); - }); - - it("default test case4", () => - { - let r = new Rectangle(); - // @ts-ignore - r.bottom = true; - expect(r.bottom).toBe(1); - }); - - it("default test case5", () => - { - let r = new Rectangle(); - // @ts-ignore - r.bottom = ""; - expect(r.bottom).toBe(0); - }); - - it("default test case6", () => - { - let r = new Rectangle(); - // @ts-ignore - r.bottom = "abc"; - expect(r.bottom).toBe(0); - }); - - it("default test case7", () => - { - let r = new Rectangle(); - r.bottom = 0; - expect(r.bottom).toBe(0); - }); - - it("default test case8", () => - { - let r = new Rectangle(); - r.bottom = 1; - expect(r.bottom).toBe(1); - }); - - it("default test case9", () => - { - let r = new Rectangle(); - r.bottom = 500; - expect(r.bottom).toBe(500); - }); - - it("default test case10", () => - { - let r = new Rectangle(); - r.bottom = 50000000000000000; - expect(r.bottom).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let r = new Rectangle(); - r.bottom = -1; - expect(r.bottom).toBe(-1); - }); - - it("default test case12", () => - { - let r = new Rectangle(); - r.bottom = -500; - expect(r.bottom).toBe(-500); - }); - - it("default test case13", () => - { - let r = new Rectangle(); - r.bottom = -50000000000000000; - expect(r.bottom).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let r = new Rectangle(); - // @ts-ignore - r.bottom = { "a":0 }; - expect(r.bottom).toBe(0); - }); - - it("default test case15", () => - { - let r = new Rectangle(); - // @ts-ignore - r.bottom = function a() {}; - expect(r.bottom).toBe(0); - }); - - it("default test case16", () => - { - let r = new Rectangle(); - // @ts-ignore - r.bottom = [1]; - expect(r.bottom).toBe(1); - }); - - it("default test case17", () => - { - let r = new Rectangle(); - // @ts-ignore - r.bottom = [1,2]; - expect(r.bottom).toBe(0); - }); - - it("default test case18", () => - { - let r = new Rectangle(); - // @ts-ignore - r.bottom = {}; - expect(r.bottom).toBe(0); - }); - - it("default test case19", () => - { - let r = new Rectangle(); - // @ts-ignore - r.bottom = { "toString":() => { return 1 } }; - expect(r.bottom).toBe(1); - }); - - it("default test case20", () => - { - let r = new Rectangle(); - // @ts-ignore - r.bottom = { "toString":() => { return "1" } }; - expect(r.bottom).toBe(1); - }); - - it("default test case21", () => - { - let r = new Rectangle(); - // @ts-ignore - r.bottom = { "toString":() => { return "1a" } }; - expect(r.bottom).toBe(0); - }); - -}); - -describe("Rectangle.js height test", () => -{ - - it("default test case1", () => - { - let r = new Rectangle(); - expect(r.height).toBe(0); - }); - - it("default test case2", () => - { - let r = new Rectangle(); - // @ts-ignore - r.height = null; - expect(r.height).toBe(0); - }); - - it("default test case3", () => - { - let r = new Rectangle(); - // @ts-ignore - r.height = undefined; - expect(r.height).toBe(0); - }); - - it("default test case4", () => - { - let r = new Rectangle(); - // @ts-ignore - r.height = true; - expect(r.height).toBe(1); - }); - - it("default test case5", () => - { - let r = new Rectangle(); - // @ts-ignore - r.height = ""; - expect(r.height).toBe(0); - }); - - it("default test case6", () => - { - let r = new Rectangle(); - // @ts-ignore - r.height = "abc"; - expect(r.height).toBe(0); - }); - - it("default test case7", () => - { - let r = new Rectangle(); - r.height = 0; - expect(r.height).toBe(0); - }); - - it("default test case8", () => - { - let r = new Rectangle(); - r.height = 1; - expect(r.height).toBe(1); - }); - - it("default test case9", () => - { - let r = new Rectangle(); - r.height = 500; - expect(r.height).toBe(500); - }); - - it("default test case10", () => - { - let r = new Rectangle(); - r.height = 50000000000000000; - expect(r.height).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let r = new Rectangle(); - r.height = -1; - expect(r.height).toBe(-1); - }); - - it("default test case12", () => - { - let r = new Rectangle(); - r.height = -500; - expect(r.height).toBe(-500); - }); - - it("default test case13", () => - { - let r = new Rectangle(); - r.height = -50000000000000000; - expect(r.height).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let r = new Rectangle(); - // @ts-ignore - r.height = { "a":0 }; - expect(r.height).toBe(0); - }); - - it("default test case15", () => - { - let r = new Rectangle(); - // @ts-ignore - r.height = function a() {}; - expect(r.height).toBe(0); - }); - - it("default test case16", () => - { - let r = new Rectangle(); - // @ts-ignore - r.height = [1]; - expect(r.height).toBe(1); - }); - - it("default test case17", () => - { - let r = new Rectangle(); - // @ts-ignore - r.height = [1,2]; - expect(r.height).toBe(0); - }); - - it("default test case18", () => - { - let r = new Rectangle(); - // @ts-ignore - r.height = {}; - expect(r.height).toBe(0); - }); - - it("default test case19", () => - { - let r = new Rectangle(); - // @ts-ignore - r.height = { "toString":() => { return 1 } }; - expect(r.height).toBe(1); - }); - - it("default test case20", () => - { - let r = new Rectangle(); - // @ts-ignore - r.height = { "toString":() => { return "1" } }; - expect(r.height).toBe(1); - }); - - it("default test case21", () => - { - let r = new Rectangle(); - // @ts-ignore - r.height = { "toString":() => { return "1a" } }; - expect(r.height).toBe(0); - }); - -}); - -describe("Rectangle.js left test", () => -{ - - it("default test case1", () => - { - let r = new Rectangle(); - expect(r.left).toBe(0); - }); - - it("default test case2", () => - { - let r = new Rectangle(); - // @ts-ignore - r.left = null; - expect(r.left).toBe(0); - }); - - it("default test case3", () => - { - let r = new Rectangle(); - // @ts-ignore - r.left = undefined; - expect(r.left).toBe(0); - }); - - it("default test case4", () => - { - let r = new Rectangle(); - // @ts-ignore - r.left = true; - expect(r.left).toBe(1); - }); - - it("default test case5", () => - { - let r = new Rectangle(); - // @ts-ignore - r.left = ""; - expect(r.left).toBe(0); - }); - - it("default test case6", () => - { - let r = new Rectangle(); - // @ts-ignore - r.left = "abc"; - expect(r.left).toBe(0); - }); - - it("default test case7", () => - { - let r = new Rectangle(); - r.left = 0; - expect(r.left).toBe(0); - }); - - it("default test case8", () => - { - let r = new Rectangle(); - r.left = 1; - expect(r.left).toBe(1); - }); - - it("default test case9", () => - { - let r = new Rectangle(); - r.left = 500; - expect(r.left).toBe(500); - }); - - it("default test case10", () => - { - let r = new Rectangle(); - r.left = 50000000000000000; - expect(r.left).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let r = new Rectangle(); - r.left = -1; - expect(r.left).toBe(-1); - }); - - it("default test case12", () => - { - let r = new Rectangle(); - r.left = -500; - expect(r.left).toBe(-500); - }); - - it("default test case13", () => - { - let r = new Rectangle(); - r.left = -50000000000000000; - expect(r.left).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let r = new Rectangle(); - // @ts-ignore - r.left = { "a":0 }; - expect(r.left).toBe(0); - }); - - it("default test case15", () => - { - let r = new Rectangle(); - // @ts-ignore - r.left = function a() {}; - expect(r.left).toBe(0); - }); - - it("default test case16", () => - { - let r = new Rectangle(); - // @ts-ignore - r.left = [1]; - expect(r.left).toBe(1); - }); - - it("default test case17", () => - { - let r = new Rectangle(); - // @ts-ignore - r.left = [1,2]; - expect(r.left).toBe(0); - }); - - it("default test case18", () => - { - let r = new Rectangle(); - // @ts-ignore - r.left = {}; - expect(r.left).toBe(0); - }); - - it("default test case19", () => - { - let r = new Rectangle(); - // @ts-ignore - r.left = { "toString":() => { return 1 } }; - expect(r.left).toBe(1); - }); - - it("default test case20", () => - { - let r = new Rectangle(); - // @ts-ignore - r.left = { "toString":() => { return "1" } }; - expect(r.left).toBe(1); - }); - - it("default test case21", () => - { - let r = new Rectangle(); - // @ts-ignore - r.left = { "toString":() => { return "1a" } }; - expect(r.left).toBe(0); - }); - -}); - -describe("Rectangle.js right test", () => -{ - - it("default test case1", () => - { - let r = new Rectangle(); - expect(r.right).toBe(0); - }); - - it("default test case2", () => - { - let r = new Rectangle(); - // @ts-ignore - r.right = null; - expect(r.right).toBe(0); - }); - - it("default test case3", () => - { - let r = new Rectangle(); - // @ts-ignore - r.right = undefined; - expect(r.right).toBe(0); - }); - - it("default test case4", () => - { - let r = new Rectangle(); - // @ts-ignore - r.right = true; - expect(r.right).toBe(1); - }); - - it("default test case5", () => - { - let r = new Rectangle(); - // @ts-ignore - r.right = ""; - expect(r.right).toBe(0); - }); - - it("default test case6", () => - { - let r = new Rectangle(); - // @ts-ignore - r.right = "abc"; - expect(r.right).toBe(0); - }); - - it("default test case7", () => - { - let r = new Rectangle(); - r.right = 0; - expect(r.right).toBe(0); - }); - - it("default test case8", () => - { - let r = new Rectangle(); - r.right = 1; - expect(r.right).toBe(1); - }); - - it("default test case9", () => - { - let r = new Rectangle(); - r.right = 500; - expect(r.right).toBe(500); - }); - - it("default test case10", () => - { - let r = new Rectangle(); - r.right = 50000000000000000; - expect(r.right).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let r = new Rectangle(); - r.right = -1; - expect(r.right).toBe(-1); - }); - - it("default test case12", () => - { - let r = new Rectangle(); - r.right = -500; - expect(r.right).toBe(-500); - }); - - it("default test case13", () => - { - let r = new Rectangle(); - r.right = -50000000000000000; - expect(r.right).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let r = new Rectangle(); - // @ts-ignore - r.right = { "a":0 }; - expect(r.right).toBe(0); - }); - - it("default test case15", () => - { - let r = new Rectangle(); - // @ts-ignore - r.right = function a() {}; - expect(r.right).toBe(0); - }); - - it("default test case16", () => - { - let r = new Rectangle(); - // @ts-ignore - r.right = [1]; - expect(r.right).toBe(1); - }); - - it("default test case17", () => - { - let r = new Rectangle(); - // @ts-ignore - r.right = [1,2]; - expect(r.right).toBe(0); - }); - - it("default test case18", () => - { - let r = new Rectangle(); - // @ts-ignore - r.right = {}; - expect(r.right).toBe(0); - }); - - it("default test case19", () => - { - let r = new Rectangle(); - // @ts-ignore - r.right = { "toString":() => { return 1 } }; - expect(r.right).toBe(1); - }); - - it("default test case20", () => - { - let r = new Rectangle(); - // @ts-ignore - r.right = { "toString":() => { return "1" } }; - expect(r.right).toBe(1); - }); - - it("default test case21", () => - { - let r = new Rectangle(); - // @ts-ignore - r.right = { "toString":() => { return "1a" } }; - expect(r.right).toBe(0); - }); - -}); - -describe("Rectangle.js top test", () => -{ - - it("default test case1", () => - { - let r = new Rectangle(); - expect(r.top).toBe(0); - }); - - it("default test case2", () => - { - let r = new Rectangle(); - // @ts-ignore - r.top = null; - expect(r.top).toBe(0); - }); - - it("default test case3", () => - { - let r = new Rectangle(); - // @ts-ignore - r.top = undefined; - expect(r.top).toBe(0); - }); - - it("default test case4", () => - { - let r = new Rectangle(); - // @ts-ignore - r.top = true; - expect(r.top).toBe(1); - }); - - it("default test case5", () => - { - let r = new Rectangle(); - // @ts-ignore - r.top = ""; - expect(r.top).toBe(0); - }); - - it("default test case6", () => - { - let r = new Rectangle(); - // @ts-ignore - r.top = "abc"; - expect(r.top).toBe(0); - }); - - it("default test case7", () => - { - let r = new Rectangle(); - r.top = 0; - expect(r.top).toBe(0); - }); - - it("default test case8", () => - { - let r = new Rectangle(); - r.top = 1; - expect(r.top).toBe(1); - }); - - it("default test case9", () => - { - let r = new Rectangle(); - r.top = 500; - expect(r.top).toBe(500); - }); - - it("default test case10", () => - { - let r = new Rectangle(); - r.top = 50000000000000000; - expect(r.top).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let r = new Rectangle(); - r.top = -1; - expect(r.top).toBe(-1); - }); - - it("default test case12", () => - { - let r = new Rectangle(); - r.top = -500; - expect(r.top).toBe(-500); - }); - - it("default test case13", () => - { - let r = new Rectangle(); - r.top = -50000000000000000; - expect(r.top).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let r = new Rectangle(); - // @ts-ignore - r.top = { "a":0 }; - expect(r.top).toBe(0); - }); - - it("default test case15", () => - { - let r = new Rectangle(); - // @ts-ignore - r.top = function a() {}; - expect(r.top).toBe(0); - }); - - it("default test case16", () => - { - let r = new Rectangle(); - // @ts-ignore - r.top = [1]; - expect(r.top).toBe(1); - }); - - it("default test case17", () => - { - let r = new Rectangle(); - // @ts-ignore - r.top = [1,2]; - expect(r.top).toBe(0); - }); - - it("default test case18", () => - { - let r = new Rectangle(); - // @ts-ignore - r.top = {}; - expect(r.top).toBe(0); - }); - - it("default test case19", () => - { - let r = new Rectangle(); - // @ts-ignore - r.top = { "toString":() => { return 1 } }; - expect(r.top).toBe(1); - }); - - it("default test case20", () => - { - let r = new Rectangle(); - // @ts-ignore - r.top = { "toString":() => { return "1" } }; - expect(r.top).toBe(1); - }); - - it("default test case21", () => - { - let r = new Rectangle(); - // @ts-ignore - r.top = { "toString":() => { return "1a" } }; - expect(r.top).toBe(0); - }); - -}); - -describe("Rectangle.js width test", () => -{ - - it("default test case1", () => - { - let r = new Rectangle(); - expect(r.width).toBe(0); - }); - - it("default test case2", () => - { - let r = new Rectangle(); - // @ts-ignore - r.width = null; - expect(r.width).toBe(0); - }); - - it("default test case3", () => - { - let r = new Rectangle(); - // @ts-ignore - r.width = undefined; - expect(r.width).toBe(0); - }); - - it("default test case4", () => - { - let r = new Rectangle(); - // @ts-ignore - r.width = true; - expect(r.width).toBe(1); - }); - - it("default test case5", () => - { - let r = new Rectangle(); - // @ts-ignore - r.width = ""; - expect(r.width).toBe(0); - }); - - it("default test case6", () => - { - let r = new Rectangle(); - // @ts-ignore - r.width = "abc"; - expect(r.width).toBe(0); - }); - - it("default test case7", () => - { - let r = new Rectangle(); - r.width = 0; - expect(r.width).toBe(0); - }); - - it("default test case8", () => - { - let r = new Rectangle(); - r.width = 1; - expect(r.width).toBe(1); - }); - - it("default test case9", () => - { - let r = new Rectangle(); - r.width = 500; - expect(r.width).toBe(500); - }); - - it("default test case10", () => - { - let r = new Rectangle(); - r.width = 50000000000000000; - expect(r.width).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let r = new Rectangle(); - r.width = -1; - expect(r.width).toBe(-1); - }); - - it("default test case12", () => - { - let r = new Rectangle(); - r.width = -500; - expect(r.width).toBe(-500); - }); - - it("default test case13", () => - { - let r = new Rectangle(); - r.width = -50000000000000000; - expect(r.width).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let r = new Rectangle(); - // @ts-ignore - r.width = { "a":0 }; - expect(r.width).toBe(0); - }); - - it("default test case15", () => - { - let r = new Rectangle(); - // @ts-ignore - r.width = function a() {}; - expect(r.width).toBe(0); - }); - - it("default test case16", () => - { - let r = new Rectangle(); - // @ts-ignore - r.width = [1]; - expect(r.width).toBe(1); - }); - - it("default test case17", () => - { - let r = new Rectangle(); - // @ts-ignore - r.width = [1,2]; - expect(r.width).toBe(0); - }); - - it("default test case18", () => - { - let r = new Rectangle(); - // @ts-ignore - r.width = {}; - expect(r.width).toBe(0); - }); - - it("default test case19", () => - { - let r = new Rectangle(); - // @ts-ignore - r.width = { "toString":() => { return 1 } }; - expect(r.width).toBe(1); - }); - - it("default test case20", () => - { - let r = new Rectangle(); - // @ts-ignore - r.width = { "toString":() => { return "1" } }; - expect(r.width).toBe(1); - }); - - it("default test case21", () => - { - let r = new Rectangle(); - // @ts-ignore - r.width = { "toString":() => { return "1a" } }; - expect(r.width).toBe(0); - }); - -}); - -describe("Rectangle.js x test", () => -{ - - it("default test case1", () => - { - let r = new Rectangle(); - expect(r.x).toBe(0); - }); - - it("default test case2", () => - { - let r = new Rectangle(); - // @ts-ignore - r.x = null; - expect(r.x).toBe(0); - }); - - it("default test case3", () => - { - let r = new Rectangle(); - // @ts-ignore - r.x = undefined; - expect(r.x).toBe(0); - }); - - it("default test case4", () => - { - let r = new Rectangle(); - // @ts-ignore - r.x = true; - expect(r.x).toBe(1); - }); - - it("default test case5", () => - { - let r = new Rectangle(); - // @ts-ignore - r.x = ""; - expect(r.x).toBe(0); - }); - - it("default test case6", () => - { - let r = new Rectangle(); - // @ts-ignore - r.x = "abc"; - expect(r.x).toBe(0); - }); - - it("default test case7", () => - { - let r = new Rectangle(); - r.x = 0; - expect(r.x).toBe(0); - }); - - it("default test case8", () => - { - let r = new Rectangle(); - r.x = 1; - expect(r.x).toBe(1); - }); - - it("default test case9", () => - { - let r = new Rectangle(); - r.x = 500; - expect(r.x).toBe(500); - }); - - it("default test case10", () => - { - let r = new Rectangle(); - r.x = 50000000000000000; - expect(r.x).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let r = new Rectangle(); - r.x = -1; - expect(r.x).toBe(-1); - }); - - it("default test case12", () => - { - let r = new Rectangle(); - r.x = -500; - expect(r.x).toBe(-500); - }); - - it("default test case13", () => - { - let r = new Rectangle(); - r.x = -50000000000000000; - expect(r.x).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let r = new Rectangle(); - // @ts-ignore - r.x = { "a":0 }; - expect(r.x).toBe(0); - }); - - it("default test case15", () => - { - let r = new Rectangle(); - // @ts-ignore - r.x = function a() {}; - expect(r.x).toBe(0); - }); - - it("default test case16", () => - { - let r = new Rectangle(); - // @ts-ignore - r.x = [1]; - expect(r.x).toBe(1); - }); - - it("default test case17", () => - { - let r = new Rectangle(); - // @ts-ignore - r.x = [1,2]; - expect(r.x).toBe(0); - }); - - it("default test case18", () => - { - let r = new Rectangle(); - // @ts-ignore - r.x = {}; - expect(r.x).toBe(0); - }); - - it("default test case19", () => - { - let r = new Rectangle(); - // @ts-ignore - r.x = { "toString":() => { return 1 } }; - expect(r.x).toBe(1); - }); - - it("default test case20", () => - { - let r = new Rectangle(); - // @ts-ignore - r.x = { "toString":() => { return "1" } }; - expect(r.x).toBe(1); - }); - - it("default test case21", () => - { - let r = new Rectangle(); - // @ts-ignore - r.x = { "toString":() => { return "1a" } }; - expect(r.x).toBe(0); - }); - -}); - -describe("Rectangle.js y test", () => -{ - - it("default test case1", () => - { - let r = new Rectangle(); - expect(r.y).toBe(0); - }); - - it("default test case2", () => - { - let r = new Rectangle(); - // @ts-ignore - r.y = null; - expect(r.y).toBe(0); - }); - - it("default test case3", () => - { - let r = new Rectangle(); - // @ts-ignore - r.y = undefined; - expect(r.y).toBe(0); - }); - - it("default test case4", () => - { - let r = new Rectangle(); - // @ts-ignore - r.y = true; - expect(r.y).toBe(1); - }); - - it("default test case5", () => - { - let r = new Rectangle(); - // @ts-ignore - r.y = ""; - expect(r.y).toBe(0); - }); - - it("default test case6", () => - { - let r = new Rectangle(); - // @ts-ignore - r.y = "abc"; - expect(r.y).toBe(0); - }); - - it("default test case7", () => - { - let r = new Rectangle(); - r.y = 0; - expect(r.y).toBe(0); - }); - - it("default test case8", () => - { - let r = new Rectangle(); - r.y = 1; - expect(r.y).toBe(1); - }); - - it("default test case9", () => - { - let r = new Rectangle(); - r.y = 500; - expect(r.y).toBe(500); - }); - - it("default test case10", () => - { - let r = new Rectangle(); - r.y = 50000000000000000; - expect(r.y).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let r = new Rectangle(); - r.y = -1; - expect(r.y).toBe(-1); - }); - - it("default test case12", () => - { - let r = new Rectangle(); - r.y = -500; - expect(r.y).toBe(-500); - }); - - it("default test case13", () => - { - let r = new Rectangle(); - r.y = -50000000000000000; - expect(r.y).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let r = new Rectangle(); - // @ts-ignore - r.y = { "a":0 }; - expect(r.y).toBe(0); - }); - - it("default test case15", () => - { - let r = new Rectangle(); - // @ts-ignore - r.y = function a() {}; - expect(r.y).toBe(0); - }); - - it("default test case16", () => - { - let r = new Rectangle(); - // @ts-ignore - r.y = [1]; - expect(r.y).toBe(1); - }); - - it("default test case17", () => - { - let r = new Rectangle(); - // @ts-ignore - r.y = [1,2]; - expect(r.y).toBe(0); - }); - - it("default test case18", () => - { - let r = new Rectangle(); - // @ts-ignore - r.y = {}; - expect(r.y).toBe(0); - }); - - it("default test case19", () => - { - let r = new Rectangle(); - // @ts-ignore - r.y = { "toString":() => { return 1 } }; - expect(r.y).toBe(1); - }); - - it("default test case20", () => - { - let r = new Rectangle(); - // @ts-ignore - r.y = { "toString":() => { return "1" } }; - expect(r.y).toBe(1); - }); - - it("default test case21", () => - { - let r = new Rectangle(); - // @ts-ignore - r.y = { "toString":() => { return "1a" } }; - expect(r.y).toBe(0); - }); - -}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle.test.ts b/packages/geom/src/Rectangle.test.ts new file mode 100644 index 00000000..e0fe3284 --- /dev/null +++ b/packages/geom/src/Rectangle.test.ts @@ -0,0 +1,224 @@ +import { Rectangle } from "./Rectangle"; +import { Point } from "./Point"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js toString test", () => +{ + it("toString test1 success", () => + { + const rectangle = new Rectangle(); + expect(rectangle.toString()).toBe("(x=0, y=0, w=0, h=0)"); + }); + + it("toString test2 success", () => + { + const rectangle = new Rectangle(1, 2, 3, 4); + expect(rectangle.toString()).toBe("(x=1, y=2, w=3, h=4)"); + }); + +}); + +describe("Rectangle.js static toString test", () => +{ + + it("static toString test", () => + { + expect(Rectangle.toString()).toBe("[class Rectangle]"); + }); + +}); + +describe("Rectangle.js namespace test", () => +{ + + it("namespace test public", () => + { + const rectangle = new Rectangle(); + expect(rectangle.namespace).toBe("next2d.geom.Rectangle"); + }); + + it("namespace test static", () => + { + expect(Rectangle.namespace).toBe("next2d.geom.Rectangle"); + }); + +}); + +describe("Rectangle.js property test", () => +{ + it("top test case1", () => + { + const rectangle = new Rectangle(50, 50, 100, 100); + expect(rectangle.top).toBe(50); + expect(rectangle.bottom).toBe(150); + + // success + rectangle.top = 160; + expect(rectangle.toString()).toBe("(x=50, y=160, w=100, h=-10)"); + expect(rectangle.bottom).toBe(150); + expect(rectangle.y).toBe(160); + + rectangle.top = 0; + expect(rectangle.y).toBe(0); + expect(rectangle.height).toBe(150); + }); + + it("top test case2", () => + { + const rectangle = new Rectangle(-50, -50, -100, -100); + expect(rectangle.top).toBe(-50); + expect(rectangle.bottom).toBe(-150); + + // success + rectangle.top = 160; + expect(rectangle.toString()).toBe("(x=-50, y=160, w=-100, h=-310)"); + expect(rectangle.bottom).toBe(-150); + expect(rectangle.y).toBe(160); + }); + + it("right test case1", () => + { + const rectangle = new Rectangle(50, 100, 100, 100); + expect(rectangle.right).toBe(150); + + // success + rectangle.right = 20; + expect(rectangle.toString()).toBe("(x=50, y=100, w=-30, h=100)"); + + rectangle.right = 0; + expect(rectangle.right).toBe(0); + }); + + it("right test case2", () => + { + const rectangle = new Rectangle(50, -100, -100, -100); + expect(rectangle.right).toBe(-50); + + // success + rectangle.right = 20; + expect(rectangle.toString()).toBe("(x=50, y=-100, w=-30, h=-100)"); + + rectangle.right = 0; + expect(rectangle.right).toBe(0); + }); + + it("bottom test case1", () => + { + const rectangle = new Rectangle(0, 100, 100, 100); + expect(rectangle.bottom).toBe(200); + + // success + rectangle.bottom = 50; + expect(rectangle.toString()).toBe("(x=0, y=100, w=100, h=-50)"); + + rectangle.bottom = 0; + expect(rectangle.height).toBe(-100); + }); + + it("bottom test case2", () => + { + const rectangle = new Rectangle(0, -100, -100, -100); + expect(rectangle.bottom).toBe(-200); + + // success + rectangle.bottom = -50; + expect(rectangle.toString()).toBe("(x=0, y=-100, w=-100, h=50)"); + + rectangle.bottom = 0; + expect(rectangle.height).toBe(100); + }); + + it("left test case1", () => + { + const rectangle = new Rectangle(50, 50, 100, 100); + expect(rectangle.left).toBe(50); + expect(rectangle.right).toBe(150); + + // success + rectangle.left = 160; + expect(rectangle.toString()).toBe("(x=160, y=50, w=-10, h=100)"); + expect(rectangle.right).toBe(150); + expect(rectangle.x).toBe(160); + + rectangle.left = 0; + expect(rectangle.x).toBe(0); + expect(rectangle.width).toBe(150); + }); + + it("left test case2", () => + { + const rectangle = new Rectangle(-50, -50, -100, -100); + expect(rectangle.left).toBe(-50); + expect(rectangle.right).toBe(-150); + + // success + rectangle.left = 160; + expect(rectangle.toString()).toBe("(x=160, y=-50, w=-310, h=-100)"); + expect(rectangle.right).toBe(-150); + expect(rectangle.x).toBe(160); + + rectangle.left = 0; + expect(rectangle.x).toBe(0); + expect(rectangle.width).toBe(-150); + }); + + it("bottomRight test case1", () => + { + const rectangle = new Rectangle(30, 50, 80, 100); + const point = rectangle.bottomRight; + expect(point.toString()).toBe("(x=110, y=150)"); + + rectangle.bottomRight = new Point(10 ,10); + expect(rectangle.toString()).toBe("(x=30, y=50, w=-20, h=-40)"); + }); + + it("bottomRight test case2", () => + { + const rectangle = new Rectangle(-30, -50, -80, -100); + const point = rectangle.bottomRight; + expect(point.toString()).toBe("(x=-110, y=-150)"); + + rectangle.bottomRight = new Point(10 ,10); + expect(rectangle.toString()).toBe("(x=-30, y=-50, w=40, h=60)"); + }); + + it("topLeft test case1", () => + { + const rectangle = new Rectangle(30, 50, 80, 100); + const point = rectangle.topLeft; + expect(point.toString()).toBe("(x=30, y=50)"); + + rectangle.topLeft = new Point(10 ,10); + expect(rectangle.toString()).toBe("(x=10, y=10, w=100, h=140)"); + }); + + it("topLeft test case2", () => + { + const rectangle = new Rectangle(-30, -50, -80, -100); + const point = rectangle.topLeft; + expect(point.toString()).toBe("(x=-30, y=-50)"); + + rectangle.topLeft = new Point(10 ,10); + expect(rectangle.toString()).toBe("(x=10, y=10, w=-120, h=-160)"); + }); + + it("size test case1", () => + { + const rectangle = new Rectangle(30, 50, 80, 100); + const point = rectangle.size; + expect(point.toString()).toBe("(x=80, y=100)"); + + rectangle.size = new Point(10 ,10); + expect(rectangle.toString()).toBe("(x=30, y=50, w=10, h=10)"); + }); + + it("size test case2", () => + { + const rectangle = new Rectangle(-30, -50, -80, -100); + const point = rectangle.size; + expect(point.toString()).toBe("(x=-80, y=-100)"); + + rectangle.size = new Point(10 ,10); + expect(rectangle.toString()).toBe("(x=-30, y=-50, w=10, h=10)"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle.ts b/packages/geom/src/Rectangle.ts index e5ce111d..2f432944 100644 --- a/packages/geom/src/Rectangle.ts +++ b/packages/geom/src/Rectangle.ts @@ -1,4 +1,20 @@ import { Point } from "./Point"; +import { execute as rectangleCloneService } from "../src/Rectangle/service/RectangleCloneService"; +import { execute as rectangleContainsService } from "../src/Rectangle/service/RectangleContainsService"; +import { execute as rectangleContainsPointService } from "../src/Rectangle/service/RectangleContainsPointService"; +import { execute as rectangleContainsRectService } from "../src/Rectangle/service/RectangleContainsRectService"; +import { execute as rectangleCopyFromService } from "../src/Rectangle/service/RectangleCopyFromService"; +import { execute as rectangleEqualsService } from "../src/Rectangle/service/RectangleEqualsService"; +import { execute as rectangleInflateService } from "../src/Rectangle/service/RectangleInflateService"; +import { execute as rectangleInflatePointService } from "../src/Rectangle/service/RectangleInflatePointService"; +import { execute as rectangleIntersectionService } from "../src/Rectangle/service/RectangleIntersectionService"; +import { execute as rectangleIntersectsService } from "../src/Rectangle/service/RectangleIntersectsService"; +import { execute as rectangleIsEmptyService } from "../src/Rectangle/service/RectangleIsEmptyService"; +import { execute as rectangleOffsetService } from "../src/Rectangle/service/RectangleOffsetService"; +import { execute as rectangleOffsetPointService } from "../src/Rectangle/service/RectangleOffsetPointService"; +import { execute as rectangleSetEmptyService } from "../src/Rectangle/service/RectangleSetEmptyService"; +import { execute as rectangleSetToService } from "../src/Rectangle/service/RectangleSetToService"; +import { execute as rectangleUnionService } from "../src/Rectangle/service/RectangleUnionService"; /** * @description Rectangle オブジェクトは、その位置(左上隅のポイント (x, y) で示される)、および幅と高さで定義される領域です。 @@ -106,7 +122,7 @@ export class Rectangle */ toString (): string { - return `(x=${this.x}, y=${this.y}, w=${this.width}, h=${this.height})`; + return `(x=${this._$x}, y=${this._$y}, w=${this._$width}, h=${this._$height})`; } /** @@ -322,7 +338,7 @@ export class Rectangle */ clone (): Rectangle { - return new Rectangle(this._$x, this._$y, this._$width, this._$height); + return rectangleCloneService(this); } /** @@ -338,7 +354,7 @@ export class Rectangle */ contains (x: number, y: number): boolean { - return this._$x <= x && this._$y <= y && this.right > x && this.bottom > y; + return rectangleContainsService(this, x, y); } /** @@ -353,8 +369,7 @@ export class Rectangle */ containsPoint (point: Point): boolean { - return this._$x <= point.x && this._$y <= point.y && - this.right > point.x && this.bottom > point.y; + return rectangleContainsPointService(this, point); } /** @@ -362,15 +377,14 @@ export class Rectangle * Determines whether the Rectangle object specified by * the rect parameter is contained within this Rectangle object. * - * @param {Rectangle} rect + * @param {Rectangle} rectangle * @return {boolean} * @method * @public */ - containsRect (rect: Rectangle): boolean + containsRect (rectangle: Rectangle): boolean { - return this._$x <= rect.x && this._$y <= rect.y && - this.right >= rect.right && this.bottom >= rect.bottom; + return rectangleContainsRectService(this, rectangle); } /** @@ -379,17 +393,14 @@ export class Rectangle * Copies all of rectangle data from * the source Rectangle object into the calling Rectangle object. * - * @param {Rectangle} source_rect + * @param {Rectangle} rectangle * @return {void} * @method * @public */ - copyFrom (source_rect: Rectangle): void + copyFrom (rectangle: Rectangle): void { - this._$x = source_rect.x; - this._$y = source_rect.y; - this._$width = source_rect.width; - this._$height = source_rect.height; + rectangleCopyFromService(this, rectangle); } /** @@ -398,15 +409,14 @@ export class Rectangle * Determines whether the object specified * in the toCompare parameter is equal to this Rectangle object. * - * @param {Rectangle} to_compare + * @param {Rectangle} rectangle * @return {boolean} * @method * @public */ - equals (to_compare: Rectangle): boolean + equals (rectangle: Rectangle): boolean { - return this._$x === to_compare.x && this._$y === to_compare.y && - this._$width === to_compare.width && this._$height === to_compare.height; + return rectangleEqualsService(this, rectangle); } /** @@ -415,17 +425,13 @@ export class Rectangle * * @param {number} dx * @param {number} dy - * @return void + * @return {void} * @method * @public */ inflate (dx: number, dy: number): void { - this._$x = this._$x - dx; - this._$width = this._$width + 2 * dx; - - this._$y = this._$y - dy; - this._$height = this._$height + 2 * dy; + rectangleInflateService(this, dx, dy); } /** @@ -439,11 +445,7 @@ export class Rectangle */ inflatePoint (point: Point): void { - this._$x = this._$x - point.x; - this._$width = this._$width + 2 * point.x; - - this._$y = this._$y - point.y; - this._$height = this._$height + 2 * point.y; + rectangleInflatePointService(this, point); } /** @@ -452,21 +454,14 @@ export class Rectangle * If the Rectangle object specified in the toIntersect parameter intersects * with this Rectangle object, returns the area of intersection as a Rectangle object. * - * @param {Rectangle} to_intersect + * @param {Rectangle} rectangle * @return {Rectangle} * @method * @public */ - intersection (to_intersect: Rectangle): Rectangle + intersection (rectangle: Rectangle): Rectangle { - const sx = Math.max(this._$x, to_intersect.x); - const sy = Math.max(this._$y, to_intersect.y); - const ex = Math.min(this.right, to_intersect.right); - const ey = Math.min(this.bottom, to_intersect.bottom); - - const w = ex - sx; - const h = ey - sy; - return w > 0 && h > 0 ? new Rectangle(sx, sy, w, h) : new Rectangle(0, 0, 0, 0); + return rectangleIntersectionService(this, rectangle); } /** @@ -475,18 +470,14 @@ export class Rectangle * Determines whether the object specified * in the toIntersect parameter intersects with this Rectangle object. * - * @param {Rectangle} to_intersect + * @param {Rectangle} rectangle * @return {boolean} * @method * @public */ - intersects (to_intersect: Rectangle): boolean + intersects (rectangle: Rectangle): boolean { - const sx = Math.max(this._$x, to_intersect.x); - const sy = Math.max(this._$y, to_intersect.y); - const ex = Math.min(this.right, to_intersect.right); - const ey = Math.min(this.bottom, to_intersect.bottom); - return ex - sx > 0 && ey - sy > 0; + return rectangleIntersectsService(this, rectangle); } /** @@ -499,7 +490,7 @@ export class Rectangle */ isEmpty (): boolean { - return this._$width <= 0 || this._$height <= 0; + return rectangleIsEmptyService(this); } /** @@ -515,8 +506,7 @@ export class Rectangle */ offset (dx: number ,dy: number): void { - this._$x += dx; - this._$y += dy; + rectangleOffsetService(this, dx, dy); } /** @@ -530,8 +520,7 @@ export class Rectangle */ offsetPoint (point: Point): void { - this._$x += point.x; - this._$y += point.y; + rectangleOffsetPointService(this, point); } /** @@ -544,10 +533,7 @@ export class Rectangle */ setEmpty (): void { - this._$x = 0; - this._$y = 0; - this._$width = 0; - this._$height = 0; + rectangleSetEmptyService(this); } /** @@ -564,10 +550,7 @@ export class Rectangle */ setTo (x: number, y: number, width: number, height: number): void { - this._$x = x; - this._$y = y; - this._$width = width; - this._$height = height; + rectangleSetToService(this, x, y, width, height); } /** @@ -576,26 +559,13 @@ export class Rectangle * Adds two rectangles together to create a new Rectangle object, * by filling in the horizontal and vertical space between the two rectangles. * - * @param {Rectangle} to_union + * @param {Rectangle} rectangle * @return {Rectangle} * @method * @public */ - union (to_union: Rectangle): Rectangle + union (rectangle: Rectangle): Rectangle { - if (this.isEmpty()) { - return to_union.clone(); - } - - if (to_union.isEmpty()) { - return this.clone(); - } - - return new Rectangle( - Math.min(this._$x, to_union.x), - Math.min(this._$y, to_union.y), - Math.max(this.right - to_union.left, to_union.right - this.left), - Math.max(this.bottom - to_union.top, to_union.bottom - this.top) - ); + return rectangleUnionService(this, rectangle); } } diff --git a/packages/geom/src/Rectangle/service/RectangleCloneService.test.ts b/packages/geom/src/Rectangle/service/RectangleCloneService.test.ts new file mode 100644 index 00000000..84479bde --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleCloneService.test.ts @@ -0,0 +1,15 @@ +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js clone test", () => +{ + it("clone test", () => + { + const rectangle1 = new Rectangle(30, 50, 80, 100); + const rectangle2 = rectangle1.clone(); + rectangle2.x = 100; + + expect(rectangle1.toString()).toBe("(x=30, y=50, w=80, h=100)"); + expect(rectangle2.toString()).toBe("(x=100, y=50, w=80, h=100)"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleCloneService.ts b/packages/geom/src/Rectangle/service/RectangleCloneService.ts new file mode 100644 index 00000000..28fdcfe9 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleCloneService.ts @@ -0,0 +1,15 @@ +import { Rectangle } from "../../Rectangle"; + +/** + * @description 指定のRectangleを複製を返却 + * Returns a duplicate of the specified Rectangle + * + * @param {Rectangle} src + * @return {Rectangle} + * @method + * @public + */ +export const execute = (src: Rectangle): Rectangle => +{ + return new Rectangle(src.x, src.y, src.width, src.height); +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleContainsPointService.test.ts b/packages/geom/src/Rectangle/service/RectangleContainsPointService.test.ts new file mode 100644 index 00000000..0c0a6b88 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleContainsPointService.test.ts @@ -0,0 +1,46 @@ +import { Rectangle } from "../../Rectangle"; +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js containsPoint test", () => +{ + it("containsPoint test case1", () => + { + const rectangle = new Rectangle(30, 50, 80, 100); + + const p1 = new Point(30, 50); + expect(rectangle.containsPoint(p1)).toBe(true); + + const p2 = new Point(110, 150); + expect(rectangle.containsPoint(p2)).toBe(false); + + const p3 = new Point(109, 149); + expect(rectangle.containsPoint(p3)).toBe(true); + + const p4 = new Point(20, 40); + expect(rectangle.containsPoint(p4)).toBe(false); + }); + + it("containsPoint test case2", () => + { + const rectangle = new Rectangle(-30, -50, -80, -100); + + const p1 = new Point(-30, -50); + expect(rectangle.containsPoint(p1)).toBe(false); + + const p2 = new Point(-110, -150); + expect(rectangle.containsPoint(p2)).toBe(false); + + const p3 = new Point(-109, -149); + expect(rectangle.containsPoint(p3)).toBe(false); + + const p5 = new Point(110, 150); + expect(rectangle.containsPoint(p5)).toBe(false); + + const p6 = new Point(109, 149); + expect(rectangle.containsPoint(p6)).toBe(false); + + const p4 = new Point(-20, -40); + expect(rectangle.containsPoint(p4)).toBe(false); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleContainsPointService.ts b/packages/geom/src/Rectangle/service/RectangleContainsPointService.ts new file mode 100644 index 00000000..071bb483 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleContainsPointService.ts @@ -0,0 +1,20 @@ +import type { Rectangle } from "../../Rectangle"; +import type { Point } from "../../Point"; + +/** + * @description 指定の座標がRectangle内に含まれるかを判定 + * Determines whether the specified coordinates are within the Rectangle + * + * @param {Rectangle} src + * @param {Point} point + * @return {boolean} + * @method + * @public + */ +export const execute = (src: Rectangle, point: Point): boolean => +{ + return src.x <= point.x + && src.y <= point.y + && src.right > point.x + && src.bottom > point.y; +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleContainsRectService.test.ts b/packages/geom/src/Rectangle/service/RectangleContainsRectService.test.ts new file mode 100644 index 00000000..b107a9a4 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleContainsRectService.test.ts @@ -0,0 +1,35 @@ +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js containsRect test", () => +{ + it("containsRect test case1", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 20); + const rectangle2 = new Rectangle(15, 15, 5, 5); + expect(rectangle1.containsRect(rectangle2)).toBe(true); + + const rectangle3 = new Rectangle(10, 10, 20, 20); + const rectangle4 = new Rectangle(10, 10, 20, 20); + expect(rectangle3.containsRect(rectangle4)).toBe(true); + + const rectangle5 = new Rectangle(10, 10, 20, 20); + const rectangle6 = new Rectangle(9, 9, 20, 20); + expect(rectangle5.containsRect(rectangle6)).toBe(false); + + const rectangle7 = new Rectangle(10, 10, 20, 20); + const rectangle8 = new Rectangle(15, 15, 20, 20); + expect(rectangle7.containsRect(rectangle8)).toBe(false); + }); + + it("containsRect test case2", () => + { + const rectangle1 = new Rectangle(-10, -10, -20, -20); + const rectangle2 = new Rectangle(-15, -15, -5, -5); + expect(rectangle1.containsRect(rectangle2)).toBe(false); + + const rectangle3 = new Rectangle(-10, -10, 20, 20); + const rectangle4 = new Rectangle(-15, -15, 5, 5); + expect(rectangle3.containsRect(rectangle4)).toBe(false); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleContainsRectService.ts b/packages/geom/src/Rectangle/service/RectangleContainsRectService.ts new file mode 100644 index 00000000..52867754 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleContainsRectService.ts @@ -0,0 +1,19 @@ +import type { Rectangle } from "../../Rectangle"; + +/** + * @description 指定のRectangleがRectangle内に含まれるかを判定 + * Determines whether the specified Rectangle is within the Rectangle + * + * @param {Rectangle} src + * @param {Rectangle} dst + * @return {boolean} + * @method + * @public + */ +export const execute = (src: Rectangle, dst: Rectangle): boolean => +{ + return src.x <= dst.x + && src.y <= dst.y + && src.right >= dst.right + && src.bottom >= dst.bottom; +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleContainsService.test.ts b/packages/geom/src/Rectangle/service/RectangleContainsService.test.ts new file mode 100644 index 00000000..b2b15fae --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleContainsService.test.ts @@ -0,0 +1,41 @@ +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js contains test", () => +{ + it("contains test case1", () => + { + const rectangle = new Rectangle(30, 50, 80, 100); + expect(rectangle.contains(30, 50)).toBe(true); + expect(rectangle.contains(110, 150)).toBe(false); + expect(rectangle.contains(109, 149)).toBe(true); + expect(rectangle.contains(20, 40)).toBe(false); + }); + + it("contains test case2", () => + { + const rectangle = new Rectangle(0, 0, 0, 0); + expect(rectangle.contains(0, 0)).toBe(false); + }); + + it("contains test case3", () => + { + const rectangle = new Rectangle(0, 0, 1, 1); + expect(rectangle.contains(0, 0)).toBe(true); + expect(rectangle.contains(0.000001, 0.000001)).toBe(true); + expect(rectangle.contains(0.999999, 0.999999)).toBe(true); + expect(rectangle.contains(1, 0)).toBe(false); + expect(rectangle.contains(0, 1)).toBe(false); + expect(rectangle.contains(1, 1)).toBe(false); + }); + + it("contains test case4", () => + { + const rectangle = new Rectangle(-1, -1, 1, 1); + expect(rectangle.contains(0, 0)).toBe(false); + expect(rectangle.contains(-1, -1)).toBe(true); + expect(rectangle.contains(-1, -0.5)).toBe(true); + expect(rectangle.contains(-0.5, -1)).toBe(true); + }); + +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleContainsService.ts b/packages/geom/src/Rectangle/service/RectangleContainsService.ts new file mode 100644 index 00000000..cc9a1134 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleContainsService.ts @@ -0,0 +1,17 @@ +import type { Rectangle } from "../../Rectangle"; + +/** + * @description 指定の座標がRectangle内に含まれるかを判定 + * Determines whether the specified coordinates are within the Rectangle + * + * @param {Rectangle} src + * @param {number} x + * @param {number} y + * @return {boolean} + * @method + * @public + */ +export const execute = (src: Rectangle, x: number, y: number): boolean => +{ + return src.x <= x && src.y <= y && src.right > x && src.bottom > y; +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleCopyFromService.test.ts b/packages/geom/src/Rectangle/service/RectangleCopyFromService.test.ts new file mode 100644 index 00000000..e0070429 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleCopyFromService.test.ts @@ -0,0 +1,20 @@ +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js copyFrom test", () => +{ + it("copyFrom test", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 20); + const rectangle2 = new Rectangle(15, 15, 5, 5); + + rectangle1.copyFrom(rectangle2); + expect(rectangle1.toString()).toBe("(x=15, y=15, w=5, h=5)"); + expect(rectangle2.toString()).toBe("(x=15, y=15, w=5, h=5)"); + + rectangle1.x = rectangle1.y = 10; + rectangle1.width = rectangle1.height = 20; + expect(rectangle1.toString()).toBe("(x=10, y=10, w=20, h=20)"); + expect(rectangle2.toString()).toBe("(x=15, y=15, w=5, h=5)"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleCopyFromService.ts b/packages/geom/src/Rectangle/service/RectangleCopyFromService.ts new file mode 100644 index 00000000..ffb3b2fb --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleCopyFromService.ts @@ -0,0 +1,19 @@ +import type { Rectangle } from "../../Rectangle"; + +/** + * @description 指定のRectangleの値をコピー + * Copy the value of the specified Rectangle + * + * @param {Rectangle} src + * @param {Rectangle} dst + * @return {void} + * @method + * @public + */ +export const execute = (src: Rectangle, dst: Rectangle): void => +{ + src.x = dst.x; + src.y = dst.y; + src.width = dst.width; + src.height = dst.height; +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleEqualsService.test.ts b/packages/geom/src/Rectangle/service/RectangleEqualsService.test.ts new file mode 100644 index 00000000..83790e92 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleEqualsService.test.ts @@ -0,0 +1,16 @@ +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js equals test", () => +{ + it("equals test", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 20); + const rectangle2 = new Rectangle(10, 10, 20, 20); + expect(rectangle1.equals(rectangle2)).toBe(true); + + const rectangle3 = new Rectangle(10, 10, 20, 20); + const rectangle4 = new Rectangle(15, 15, 5, 5); + expect(rectangle3.equals(rectangle4)).toBe(false); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleEqualsService.ts b/packages/geom/src/Rectangle/service/RectangleEqualsService.ts new file mode 100644 index 00000000..c4e34936 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleEqualsService.ts @@ -0,0 +1,19 @@ +import type { Rectangle } from "../../Rectangle"; + +/** + * @description 指定のRectangleが等しいかを判定 + * Determines whether the specified Rectangle is equal + * + * @param {Rectangle} src + * @param {Rectangle} dst + * @return {boolean} + * @method + * @public + */ +export const execute = (src: Rectangle, dst: Rectangle): boolean => +{ + return src.x === dst.x + && src.y === dst.y + && src.width === dst.width + && src.height === dst.height; +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleInflatePointService.test.ts b/packages/geom/src/Rectangle/service/RectangleInflatePointService.test.ts new file mode 100644 index 00000000..bd4212e8 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleInflatePointService.test.ts @@ -0,0 +1,33 @@ +import { Rectangle } from "../../Rectangle"; +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js inflatePoint test", () => +{ + it("inflatePoint test case1", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 20); + const point1 = new Point(10, 10); + rectangle1.inflatePoint(point1); + expect(rectangle1.toString()).toBe("(x=0, y=0, w=40, h=40)"); + + const rectangle2 = new Rectangle(10, 10, 20, 20); + const point2 = new Point(20, 20); + rectangle2.inflatePoint(point2); + expect(rectangle2.toString()).toBe("(x=-10, y=-10, w=60, h=60)"); + }); + + it("inflatePoint test case2", () => + { + const rectangle1 = new Rectangle(-10, -10, -20, -20); + const point1 = new Point(10, 10); + rectangle1.inflatePoint(point1); + expect(rectangle1.toString()).toBe("(x=-20, y=-20, w=0, h=0)"); + + const rectangle2 = new Rectangle(-10, -10, 20, 20); + const point2 = new Point(20, 20); + rectangle2.inflatePoint(point2); + expect(rectangle2.toString()).toBe("(x=-30, y=-30, w=60, h=60)"); + }); + +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleInflatePointService.ts b/packages/geom/src/Rectangle/service/RectangleInflatePointService.ts new file mode 100644 index 00000000..eed8dcd5 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleInflatePointService.ts @@ -0,0 +1,20 @@ +import type { Point } from "../../Point"; +import type { Rectangle } from "../../Rectangle"; + +/** + * @description 指定のRectangleの値を変更 + * Change the value of the specified Rectangle + * + * @param {Rectangle} src + * @param {Point} point + * @return {void} + * @method + * @public + */ +export const execute = (src: Rectangle, point: Point): void => +{ + src.x -= point.x; + src.width += 2 * point.x; + src.y -= point.y; + src.height += 2 * point.y; +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleInflateService.test.ts b/packages/geom/src/Rectangle/service/RectangleInflateService.test.ts new file mode 100644 index 00000000..b19351d7 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleInflateService.test.ts @@ -0,0 +1,27 @@ +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js inflate test", () => +{ + it("inflate test case1", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 20); + rectangle1.inflate(10, 10); + expect(rectangle1.toString()).toBe("(x=0, y=0, w=40, h=40)"); + + const rectangle2 = new Rectangle(10, 10, 20, 20); + rectangle2.inflate(20, 20); + expect(rectangle2.toString()).toBe("(x=-10, y=-10, w=60, h=60)"); + }); + + it("inflate test case2", () => + { + const rectangle1 = new Rectangle(-10, -10, -20, -20); + rectangle1.inflate(10, 10); + expect(rectangle1.toString()).toBe("(x=-20, y=-20, w=0, h=0)"); + + const rectangle2 = new Rectangle(10, 10, 20, 20); + rectangle2.inflate(-20, -20); + expect(rectangle2.toString()).toBe("(x=30, y=30, w=-20, h=-20)"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleInflateService.ts b/packages/geom/src/Rectangle/service/RectangleInflateService.ts new file mode 100644 index 00000000..8cdc9e41 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleInflateService.ts @@ -0,0 +1,20 @@ +import type { Rectangle } from "../../Rectangle"; + +/** + * @description 指定のRectangleの値を変更 + * Change the value of the specified Rectangle + * + * @param {Rectangle} src + * @param {number} dx + * @param {number} dy + * @return {void} + * @method + * @public + */ +export const execute = (src: Rectangle, dx: number, dy: number): void => +{ + src.x -= dx; + src.width += 2 * dx; + src.y -= dy; + src.height += 2 * dy; +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleIntersectionService.test.ts b/packages/geom/src/Rectangle/service/RectangleIntersectionService.test.ts new file mode 100644 index 00000000..84a51467 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleIntersectionService.test.ts @@ -0,0 +1,77 @@ +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js intersection test", () => +{ + it("intersection test case1", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 20); + const rectangle2 = new Rectangle(5, 5, 5, 5); + const rectangle3 = rectangle1.intersection(rectangle2); + expect(rectangle3.toString()).toBe("(x=0, y=0, w=0, h=0)"); + + const rectangle4 = new Rectangle(10, 10, 20, 20); + const rectangle5 = new Rectangle(15, 15, 5, 5); + const rectangle6 = rectangle4.intersection(rectangle5); + expect(rectangle6.toString()).toBe("(x=15, y=15, w=5, h=5)"); + + const rectangle7 = new Rectangle(10, 10, 20, 20); + const rectangle8 = new Rectangle(5, 5, 25, 25); + const rectangle9 = rectangle7.intersection(rectangle8); + expect(rectangle9.toString()).toBe("(x=10, y=10, w=20, h=20)"); + }); + + it("intersection test case2", () => + { + const rectangle1 = new Rectangle(-10, -10, -20, -20); + const rectangle2 = new Rectangle(-5, -5, -5, -5); + const rectangle3 = rectangle1.intersection(rectangle2); + expect(rectangle3.toString()).toBe("(x=0, y=0, w=0, h=0)"); + + const rectangle4 = new Rectangle(-10, -10, -20, -20); + const rectangle5 = new Rectangle(-15, -15, -5, -5); + const rectangle6 = rectangle4.intersection(rectangle5); + expect(rectangle6.toString()).toBe("(x=0, y=0, w=0, h=0)"); + + const rectangle7 = new Rectangle(-10, -10, -20, -20); + const rectangle8 = new Rectangle(-5, -5, -25, -25); + const rectangle9 = rectangle7.intersection(rectangle8); + expect(rectangle9.toString()).toBe("(x=0, y=0, w=0, h=0)"); + }); + + it("intersection test case3", () => + { + const rectangle1 = new Rectangle(-10, -10, 20, 20); + const rectangle2 = new Rectangle(-5, -5, 5, 5); + const rectangle3 = rectangle1.intersection(rectangle2); + expect(rectangle3.toString()).toBe("(x=-5, y=-5, w=5, h=5)"); + + const rectangle4 = new Rectangle(-10, -10, 20, 20); + const rectangle5 = new Rectangle(-15, -15, 5, 5); + const rectangle6 = rectangle4.intersection(rectangle5); + expect(rectangle6.toString()).toBe("(x=0, y=0, w=0, h=0)"); + + const rectangle7 = new Rectangle(-10, -10, 20, 20); + const rectangle8 = new Rectangle(-5, -5, 25, 25); + const rectangle9 = rectangle7.intersection(rectangle8); + expect(rectangle9.toString()).toBe("(x=-5, y=-5, w=15, h=15)"); + }); + + it("intersection test case4", () => + { + const rectangle1 = new Rectangle(-10, -10, 20, 20); + const rectangle2 = new Rectangle(-10, -10, 0, 10); + const rectangle3 = rectangle1.intersection(rectangle2); + expect(rectangle3.toString()).toBe("(x=0, y=0, w=0, h=0)"); + + const rectangle4 = new Rectangle(-10, -10, 20, 20); + const rectangle5 = new Rectangle(-10, -10, 5, 5); + const rectangle6 = rectangle4.intersection(rectangle5); + expect(rectangle6.toString()).toBe("(x=-10, y=-10, w=5, h=5)"); + + const rectangle7 = new Rectangle(-5, -5, -25, -25); + const rectangle8 = new Rectangle(-10, -10, -20, -20); + const rectangle9 = rectangle7.intersection(rectangle8); + expect(rectangle9.toString()).toBe("(x=0, y=0, w=0, h=0)"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleIntersectionService.ts b/packages/geom/src/Rectangle/service/RectangleIntersectionService.ts new file mode 100644 index 00000000..830bd435 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleIntersectionService.ts @@ -0,0 +1,25 @@ +import { Rectangle } from "../../Rectangle"; + +/** + * @description 指定のRectangleの交差部分を取得 + * Get the intersection of the specified Rectangle + * + * @param {Rectangle} src + * @param {Rectangle} dst + * @return {Rectangle} + * @method + * @public + */ +export const execute = (src: Rectangle, dst: Rectangle): Rectangle => +{ + const sx = Math.max(src.x, dst.x); + const sy = Math.max(src.y, dst.y); + const ex = Math.min(src.right, dst.right); + const ey = Math.min(src.bottom, dst.bottom); + + const w = ex - sx; + const h = ey - sy; + return w > 0 && h > 0 + ? new Rectangle(sx, sy, w, h) + : new Rectangle(0, 0, 0, 0); +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleIntersectsService.test.ts b/packages/geom/src/Rectangle/service/RectangleIntersectsService.test.ts new file mode 100644 index 00000000..df278e3b --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleIntersectsService.test.ts @@ -0,0 +1,38 @@ +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js intersects test", () => +{ + it("intersects test case1", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 20); + const rectangle2 = new Rectangle(5, 5, 5, 5); + expect(rectangle1.intersects(rectangle2)).toBe(false); + + const rectangle3 = new Rectangle(10, 10, 20, 20); + const rectangle4 = new Rectangle(5, 5, 25, 25); + expect(rectangle3.intersects(rectangle4)).toBe(true); + }); + + it("intersects test case2", () => + { + const rectangle1 = new Rectangle(-10, -10, -20, -20); + const rectangle2 = new Rectangle(-5, -5, -25, -25); + expect(rectangle1.intersects(rectangle2)).toBe(false); + + const rectangle3 = new Rectangle(-10, -10, 20, 20); + const rectangle4 = new Rectangle(-5, -5, 25, 25); + expect(rectangle3.intersects(rectangle4)).toBe(true); + }); + + it("intersects test case3", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 20); + const rectangle2 = new Rectangle(5, 40, 10, 10); + expect(rectangle1.intersects(rectangle2)).toBe(false); + + const rectangle3 = new Rectangle(10, 10, 20, 20); + const rectangle4 = new Rectangle(5, 15, 10, 10); + expect(rectangle3.intersects(rectangle4)).toBe(true); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleIntersectsService.ts b/packages/geom/src/Rectangle/service/RectangleIntersectsService.ts new file mode 100644 index 00000000..1d03d1a3 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleIntersectsService.ts @@ -0,0 +1,20 @@ +import type { Rectangle } from "../../Rectangle"; + +/** + * @description 指定のRectangle同士が重なっているかどうかを判定 + * Determine whether the specified Rectangles overlap + * + * @param {Rectangle} src + * @param {Rectangle} dst + * @return {boolean} + * @method + * @public + */ +export const execute = (src: Rectangle, dst: Rectangle): boolean => +{ + const sx = Math.max(src.x, dst.x); + const sy = Math.max(src.y, dst.y); + const ex = Math.min(src.right, dst.right); + const ey = Math.min(src.bottom, dst.bottom); + return ex - sx > 0 && ey - sy > 0; +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleIsEmptyService.test.ts b/packages/geom/src/Rectangle/service/RectangleIsEmptyService.test.ts new file mode 100644 index 00000000..41975122 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleIsEmptyService.test.ts @@ -0,0 +1,25 @@ +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js isEmpty test", () => +{ + it("isEmpty test case1", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 20); + const rectangle2 = new Rectangle(-55, -55, 0, 0); + expect(rectangle1.isEmpty()).toBe(false); + expect(rectangle2.isEmpty()).toBe(true); + }); + + it("isEmpty test case2", () => + { + const rectangle1 = new Rectangle(10, 10, 0, 20); + expect(rectangle1.isEmpty()).toBe(true); + }); + + it("isEmpty test case3", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 0); + expect(rectangle1.isEmpty()).toBe(true); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleIsEmptyService.ts b/packages/geom/src/Rectangle/service/RectangleIsEmptyService.ts new file mode 100644 index 00000000..c70441ba --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleIsEmptyService.ts @@ -0,0 +1,15 @@ +import type { Rectangle } from "../../Rectangle"; + +/** + * @description 指定のRectangleが空かどうかを返す + * Returns whether the specified Rectangle is empty + * + * @param {Rectangle} src + * @return {boolean} + * @method + * @public + */ +export const execute = (src: Rectangle): boolean => +{ + return src.width <= 0 || src.height <= 0; +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleOffsetPointService.test.ts b/packages/geom/src/Rectangle/service/RectangleOffsetPointService.test.ts new file mode 100644 index 00000000..8fe2c8e3 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleOffsetPointService.test.ts @@ -0,0 +1,19 @@ +import { Point } from "../../Point"; +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js offsetPoint test", () => +{ + it("offsetPoint test case1", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 20); + const rectangle2 = new Rectangle(-55, -55, 0, 0); + + rectangle1.offsetPoint(new Point(5, 8)); + rectangle2.offsetPoint(new Point(60, 30)); + + expect(rectangle1.toString()).toBe("(x=15, y=18, w=20, h=20)"); + expect(rectangle2.toString()).toBe("(x=5, y=-25, w=0, h=0)"); + }); + +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleOffsetPointService.ts b/packages/geom/src/Rectangle/service/RectangleOffsetPointService.ts new file mode 100644 index 00000000..196651b8 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleOffsetPointService.ts @@ -0,0 +1,18 @@ +import type { Point } from "../../Point"; +import type { Rectangle } from "../../Rectangle"; + +/** + * @description 矩形を指定された量だけオフセットする。 + * Offset the Rectangle by the given amount. + * + * @param {Rectangle} src + * @param {Point} point + * @return {void} + * @method + * @public + */ +export const execute = (src: Rectangle, point: Point): void => +{ + src.x += point.x; + src.y += point.y; +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleOffsetService.test.ts b/packages/geom/src/Rectangle/service/RectangleOffsetService.test.ts new file mode 100644 index 00000000..3d0f6856 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleOffsetService.test.ts @@ -0,0 +1,17 @@ +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js offset test", () => +{ + it("offset test case1", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 20); + const rectangle2 = new Rectangle(-55, -55, 0, 0); + + rectangle1.offset(5, 8); + rectangle2.offset(60, 30); + + expect(rectangle1.toString()).toBe("(x=15, y=18, w=20, h=20)"); + expect(rectangle2.toString()).toBe("(x=5, y=-25, w=0, h=0)"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleOffsetService.ts b/packages/geom/src/Rectangle/service/RectangleOffsetService.ts new file mode 100644 index 00000000..8588c56f --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleOffsetService.ts @@ -0,0 +1,18 @@ +import type { Rectangle } from "../../Rectangle"; + +/** + * @description 矩形を指定された量だけオフセットする。 + * Offset the Rectangle by the given amount. + * + * @param {Rectangle} src + * @param {number} dx + * @param {number} dy + * @return {void} + * @method + * @public + */ +export const execute = (src: Rectangle, dx: number, dy: number): void => +{ + src.x += dx; + src.y += dy; +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleSetEmptyService.test.ts b/packages/geom/src/Rectangle/service/RectangleSetEmptyService.test.ts new file mode 100644 index 00000000..91fe8b70 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleSetEmptyService.test.ts @@ -0,0 +1,17 @@ +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js setEmpty test", () => +{ + it("setEmpty test case1", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 20); + const rectangle2 = new Rectangle(-55, -55, 0, 0); + + rectangle1.setEmpty(); + rectangle2.setEmpty(); + + expect(rectangle1.toString()).toBe("(x=0, y=0, w=0, h=0)"); + expect(rectangle2.toString()).toBe("(x=0, y=0, w=0, h=0)"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleSetEmptyService.ts b/packages/geom/src/Rectangle/service/RectangleSetEmptyService.ts new file mode 100644 index 00000000..0b27dff8 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleSetEmptyService.ts @@ -0,0 +1,15 @@ +import type { Rectangle } from "../../Rectangle"; + +/** + * @description 矩形を空にする + * Make the rectangle empty + * + * @param {Rectangle} src + * @return {void} + * @method + * @public + */ +export const execute = (src: Rectangle): void => +{ + src.x = src.y = src.width = src.height = 0; +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleSetToService.test.ts b/packages/geom/src/Rectangle/service/RectangleSetToService.test.ts new file mode 100644 index 00000000..7c2eb8bb --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleSetToService.test.ts @@ -0,0 +1,17 @@ +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js setTo test", () => +{ + it("setTo test case1", () => + { + const rectangle1 = new Rectangle(10, 10, 20, 20); + const rectangle2 = new Rectangle(-55, -55, 0, 0); + + rectangle1.setTo(5, 5, 5, 5); + rectangle2.setTo(10, 10, 10, 10); + + expect(rectangle1.toString()).toBe("(x=5, y=5, w=5, h=5)"); + expect(rectangle2.toString()).toBe("(x=10, y=10, w=10, h=10)"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleSetToService.ts b/packages/geom/src/Rectangle/service/RectangleSetToService.ts new file mode 100644 index 00000000..e35b1f6a --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleSetToService.ts @@ -0,0 +1,27 @@ +import type { Rectangle } from "../../Rectangle"; + +/** + * @description 矩形を指定された値に設定する + * Set the rectangle to the specified value + * + * @param {Rectangle} src + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + * @return {void} + * @method + * @public + */ +export const execute = ( + src: Rectangle, + x: number, + y: number, + width: number, + height: number +): void => { + src.x = x; + src.y = y; + src.width = width; + src.height = height; +}; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleUnionService.test.ts b/packages/geom/src/Rectangle/service/RectangleUnionService.test.ts new file mode 100644 index 00000000..86b18e32 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleUnionService.test.ts @@ -0,0 +1,87 @@ +import { Rectangle } from "../../Rectangle"; +import { describe, expect, it } from "vitest"; + +describe("Rectangle.js union test", () => +{ + it("union test case1", () => + { + const rectangle1 = new Rectangle(10, 10, 0, 10); + const rectangle2 = new Rectangle(-55, -25, 0, 20); + const rectangle3 = rectangle1.union(rectangle2); + expect(rectangle3.toString()).toBe("(x=-55, y=-25, w=0, h=20)"); + + const rectangle4 = new Rectangle(10, 10, 10, 10); + const rectangle5 = new Rectangle(-55, -25, 0, 20); + const rectangle6 = rectangle4.union(rectangle5); + expect(rectangle6.toString()).toBe("(x=10, y=10, w=10, h=10)"); + + const rectangle7 = new Rectangle(10, 10, 10, 10); + const rectangle8 = new Rectangle(-55, -25, 20, 20); + const rectangle9 = rectangle7.union(rectangle8); + expect(rectangle9.toString()).toBe("(x=-55, y=-25, w=75, h=45)"); + }); + + it("union test case2", () => + { + const rectangle1 = new Rectangle(10, 10, 10, 10); + const rectangle2 = new Rectangle(20, 20, 10, 10); + const rectangle3 = rectangle1.union(rectangle2); + expect(rectangle3.toString()).toBe("(x=10, y=10, w=20, h=20)"); + }); + + it("union test case3", () => + { + const rectangle1 = new Rectangle(-10, 10, 10, 10); + const rectangle2 = new Rectangle(20, 20, 10, 10); + const rectangle3 = rectangle1.union(rectangle2); + expect(rectangle3.toString()).toBe("(x=-10, y=10, w=40, h=20)"); + }); + + it("union test case4", () => + { + const rectangle1 = new Rectangle(10, -10, 10, 10); + const rectangle2 = new Rectangle(20, 20, 10, 10); + const rectangle3 = rectangle1.union(rectangle2); + expect(rectangle3.toString()).toBe("(x=10, y=-10, w=20, h=40)"); + }); + + it("union test cacse5", () => + { + const rectangle1 = new Rectangle(-10, -10, 10, 10); + const rectangle2 = new Rectangle(20, 20, 10, 10); + const rectangle3 = rectangle1.union(rectangle2); + expect(rectangle3.toString()).toBe("(x=-10, y=-10, w=40, h=40)"); + }); + + it("union test case6", () => + { + const rectangle1 = new Rectangle(10, 10, 10, 10); + const rectangle2 = new Rectangle(20, 20, 10, 10); + const rectangle3 = rectangle2.union(rectangle1); + expect(rectangle3.toString()).toBe("(x=10, y=10, w=20, h=20)"); + }); + + it("union test case7", () => + { + const rectangle1 = new Rectangle(-10, 10, 10, 10); + const rectangle2 = new Rectangle(20, 20, 10, 10); + const rectangle3 = rectangle2.union(rectangle1); + expect(rectangle3.toString()).toBe("(x=-10, y=10, w=40, h=20)"); + }); + + it("union test case8", () => + { + const rectangle1 = new Rectangle(10, -10, 10, 10); + const rectangle2 = new Rectangle(20, 20, 10, 10); + const rectangle3 = rectangle2.union(rectangle1); + expect(rectangle3.toString()).toBe("(x=10, y=-10, w=20, h=40)"); + }); + + it("union test case9", () => + { + const rectangle1 = new Rectangle(-10, -10, 10, 10); + const rectangle2 = new Rectangle(20, 20, 10, 10); + const rectangle3 = rectangle2.union(rectangle1); + expect(rectangle3.toString()).toBe("(x=-10, y=-10, w=40, h=40)"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleUnionService.ts b/packages/geom/src/Rectangle/service/RectangleUnionService.ts new file mode 100644 index 00000000..c1345b51 --- /dev/null +++ b/packages/geom/src/Rectangle/service/RectangleUnionService.ts @@ -0,0 +1,29 @@ +import { Rectangle } from "../../Rectangle"; + +/** + * @description 2つの矩形を結合した矩形を返す + * Returns a rectangle that is the union of two rectangles + * + * @param {Rectangle} src + * @param {Rectangle} dst + * @return {void} + * @method + * @public + */ +export const execute = (src: Rectangle, dst: Rectangle): Rectangle => +{ + if (src.isEmpty()) { + return dst.clone(); + } + + if (dst.isEmpty()) { + return src.clone(); + } + + return new Rectangle( + Math.min(src.x, dst.x), + Math.min(src.y, dst.y), + Math.max(src.right - dst.left, dst.right - src.left), + Math.max(src.bottom - dst.top, dst.bottom - src.top) + ); +}; \ No newline at end of file diff --git a/packages/webpack-worker-loader-plugin/LICENSE b/packages/webpack-worker-loader-plugin/LICENSE deleted file mode 100644 index a536abed..00000000 --- a/packages/webpack-worker-loader-plugin/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Next2D - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/webpack-worker-loader-plugin/index.js b/packages/webpack-worker-loader-plugin/index.js deleted file mode 100644 index 0474155a..00000000 --- a/packages/webpack-worker-loader-plugin/index.js +++ /dev/null @@ -1,152 +0,0 @@ -"use strict"; - -const fs = require("fs"); - -module.exports = class Next2DWebpackWorkerLoaderPlugin -{ - /** - * @param {Compiler} compiler - * @returns {void} - * @method - * @public - */ - apply (compiler) - { - compiler.hooks.beforeCompile.tapAsync("Next2DWebpackWorkerLoaderPlugin", (compilation, callback) => - { - if (compiler.options.mode === "production") { - this._$margeVersion(compilation.normalModuleFactory.context); - this._$margeUnzipWorker(compilation.normalModuleFactory.context); - this._$margeRenderWorker(compilation.normalModuleFactory.context); - } - callback(); - }); - } - - /** - * @param {string} dir - * @return {void} - * @method - * @private - */ - _$margeVersion (dir) - { - const indexPath = `${dir}/src/index.ts`; - if (fs.existsSync(indexPath)) { - - const src = fs.readFileSync(indexPath, "utf8"); - const packageJson = require(`${dir}/package.json`); - - const texts = src.split("\n"); - for (let idx = 0; idx < texts.length; ++idx) { - - const text = texts[idx]; - if (text.indexOf("Next2D Player") === -1) { - continue; - } - - const top = texts.slice(0, idx).join("\n"); - const lower = texts.slice(idx + 1).join("\n"); - - fs.writeFileSync( - indexPath, - `${top} - console.log("%c Next2D Player %c ${packageJson.version} %c https://next2d.app", -${lower}` - ); - - break; - } - } - } - - /** - * @param {string} dir - * @return {void} - * @method - * @private - */ - _$margeRenderWorker (dir) - { - const RenderWorkerPath = `${dir}/worker/renderer/RendererWorker.min.js`; - - if (fs.existsSync(RenderWorkerPath)) { - - const worker = fs.readFileSync(RenderWorkerPath, "utf8") - .replace(/\\/g, "\\\\") - .replace(/"/g, "\\\"") - .replace(/\n/g, ""); - - const utilPath = `${dir}/packages/util/src/Util.ts`; - - const util = fs.readFileSync(utilPath, "utf8"); - const index = util.indexOf("const $renderURL"); - const top = util.slice(0, index - 1); - - let lower = ""; - const texts = util.split("\n"); - for (let idx = 0; idx < texts.length; ++idx) { - - const text = texts[idx]; - if (text.indexOf("const $renderURL") === -1) { - continue; - } - - lower = texts.slice(idx + 1).join("\n"); - break; - } - - fs.writeFileSync( - utilPath, - `${top} -const $renderURL: string = "${worker}"; -${lower}` - ); - } - } - - /** - * - * @param {string} dir - * @return {void} - * @method - * @private - */ - _$margeUnzipWorker (dir) - { - const UnzipWorkerPath = `${dir}/worker/unzip/UnzipWorker.min.js`; - if (fs.existsSync(UnzipWorkerPath)) { - - const worker = fs.readFileSync(UnzipWorkerPath, "utf8") - .replace(/\\/g, "\\\\") - .replace(/"/g, "\\\"") - .replace(/\n/g, ""); - - const utilPath = `${dir}/packages/util/src/Util.ts`; - - const util = fs.readFileSync(utilPath, "utf8"); - const index = util.indexOf("const $unzipURL"); - const top = util.slice(0, index - 1); - - let lower = ""; - const texts = util.split("\n"); - for (let idx = 0; idx < texts.length; ++idx) { - - const text = texts[idx]; - if (text.indexOf("const $unzipURL") === -1) { - continue; - } - - lower = texts.slice(idx + 1).join("\n"); - break; - } - - fs.writeFileSync( - utilPath, - `${top} -const $unzipURL: string = URL.createObjectURL(new Blob(["${worker}"], { "type": "text/javascript" })); -${lower}` - ); - } - } -}; diff --git a/packages/webpack-worker-loader-plugin/package.json b/packages/webpack-worker-loader-plugin/package.json deleted file mode 100644 index 2887ba8e..00000000 --- a/packages/webpack-worker-loader-plugin/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "@next2d/webpack-worker-loader-plugin", - "description": "Next2D Framework webpack Worker Loader plugin.", - "author": "Toshiyuki Ienaga (https://github.com/ienaga/)", - "license": "MIT", - "main": "index.js", - "homepage": "https://next2d.app", - "bugs": "https://github.com/Next2D/Player/issues", - "exports": { - ".": { - "import": { - "default": "./index.js" - }, - "require": { - "default": "./index.js" - } - } - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Next2D/Player.git" - } -} From 38e450e1ad7753ce1ba8d68af01376a30a95d532 Mon Sep 17 00:00:00 2001 From: ienaga Date: Tue, 23 Jul 2024 00:40:12 +0900 Subject: [PATCH 006/343] =?UTF-8?q?#154=20feat:=20ColorTransform=E3=82=92?= =?UTF-8?q?=E7=A7=BB=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/next2d/geom/ColorTransformTest.ts | 56 ----- packages/geom/src/ColorTransform.test.ts | 57 +++++ packages/geom/src/ColorTransform.ts | 213 +++++++++++------- .../ColorTransformConcatService.test.ts | 50 ++++ .../service/ColorTransformConcatService.ts | 32 +++ 5 files changed, 269 insertions(+), 139 deletions(-) create mode 100644 packages/geom/src/ColorTransform.test.ts create mode 100644 packages/geom/src/ColorTransform/service/ColorTransformConcatService.test.ts create mode 100644 packages/geom/src/ColorTransform/service/ColorTransformConcatService.ts diff --git a/__tests__/next2d/geom/ColorTransformTest.ts b/__tests__/next2d/geom/ColorTransformTest.ts index a49107e6..d3379f5f 100644 --- a/__tests__/next2d/geom/ColorTransformTest.ts +++ b/__tests__/next2d/geom/ColorTransformTest.ts @@ -151,62 +151,6 @@ describe("ColorTransform.js property test", () => }); -describe("ColorTransform.js concat test", () => -{ - it("concat test1", () => - { - - const ct1 = new ColorTransform(0.1, 0.2, 0.3, 0.5, 50, 100, 150, 200); - const ct2 = new ColorTransform(0.9, 0.8, 0.7, 0.6, -255, -200, -150, -100); - ct1.concat(ct2); - - expect(ct1.toString()).toBe( - "(redMultiplier=0.08999999612569809, greenMultiplier=0.1600000113248825, blueMultiplier=0.21000000834465027, alphaMultiplier=0.30000001192092896, redOffset=24, greenOffset=60, blueOffset=105, alphaOffset=150)" - ); - - }); - - it("concat test2", () => - { - - const ct1 = new ColorTransform(100, 0.2, 0.3, 0.5, 50, 100, 150, 200); - const ct2 = new ColorTransform(0.9, 0.8, 0.7, 0.6, -255, -200, -150, -100); - ct1.concat(ct2); - - expect(ct1.toString()).toBe( - "(redMultiplier=0.8999999761581421, greenMultiplier=0.1600000113248825, blueMultiplier=0.21000000834465027, alphaMultiplier=0.30000001192092896, redOffset=-205, greenOffset=60, blueOffset=105, alphaOffset=150)" - ); - - }); - - it("concat test3", () => - { - - const ct1 = new ColorTransform(0.1, 0.2, 0.3, 0.5, 5000, 100, 150, 200); - const ct2 = new ColorTransform(0.9, 0.8, 0.7, 0.6, -255, -200, -150, -100); - ct1.concat(ct2); - - expect(ct1.toString()).toBe( - "(redMultiplier=0.08999999612569809, greenMultiplier=0.1600000113248825, blueMultiplier=0.21000000834465027, alphaMultiplier=0.30000001192092896, redOffset=229, greenOffset=60, blueOffset=105, alphaOffset=150)" - ); - - }); - - it("concat test4", () => - { - - const ct1 = new ColorTransform(0, -9, 0.3, 0.5, 50, 100, 150, 200); - const ct2 = new ColorTransform(0.9, 0.8, 0.7, 0.6, -255, -200, -150, -100); - ct1.concat(ct2); - - expect(ct1.toString()).toBe( - "(redMultiplier=0, greenMultiplier=0, blueMultiplier=0.21000000834465027, alphaMultiplier=0.30000001192092896, redOffset=50, greenOffset=100, blueOffset=105, alphaOffset=150)" - ); - - }); - -}); - // properties describe("ColorTransform.js alphaMultiplier test", () => { diff --git a/packages/geom/src/ColorTransform.test.ts b/packages/geom/src/ColorTransform.test.ts new file mode 100644 index 00000000..e2fb1862 --- /dev/null +++ b/packages/geom/src/ColorTransform.test.ts @@ -0,0 +1,57 @@ +import { ColorTransform } from "./ColorTransform"; +import { describe, expect, it } from "vitest"; + +describe("ColorTransform.js toString test", () => +{ + it("toString test case1", () => + { + const colorTransform = new ColorTransform(); + expect(colorTransform.toString()).toBe("(redMultiplier=1, greenMultiplier=1, blueMultiplier=1, alphaMultiplier=1, redOffset=0, greenOffset=0, blueOffset=0, alphaOffset=0)"); + }); + + it("toString test case2", () => + { + const colorTransform = new ColorTransform(2, 3, 4, 5, 6, 7, 8, 9); + expect(colorTransform.toString()).toBe("(redMultiplier=2, greenMultiplier=3, blueMultiplier=4, alphaMultiplier=5, redOffset=6, greenOffset=7, blueOffset=8, alphaOffset=9)"); + }); +}); + +describe("ColorTransform.js static toString test", () => +{ + + it("static toString test", () => + { + expect(ColorTransform.toString()).toBe("[class ColorTransform]"); + }); +}); + +describe("ColorTransform.js namespace test", () => +{ + it("namespace test public", () => + { + const colorTransform = new ColorTransform(); + expect(colorTransform.namespace).toBe("next2d.geom.ColorTransform"); + }); + + it("namespace test static", () => + { + expect(ColorTransform.namespace).toBe("next2d.geom.ColorTransform"); + }); +}); + +describe("ColorTransform.js property test", () => +{ + it("test case1", () => { + + const colorTransform = new ColorTransform(0.1, 0.2, 0.3, 0.4, 1, 2, 3, 4); + + expect(colorTransform.redMultiplier).toBe(0.10000000149011612); + expect(colorTransform.greenMultiplier).toBe(0.20000000298023224); + expect(colorTransform.blueMultiplier).toBe(0.30000001192092896); + expect(colorTransform.alphaMultiplier).toBe(0.4000000059604645); + expect(colorTransform.redOffset).toBe(1); + expect(colorTransform.greenOffset).toBe(2); + expect(colorTransform.blueOffset).toBe(3); + expect(colorTransform.alphaOffset).toBe(4); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/ColorTransform.ts b/packages/geom/src/ColorTransform.ts index d3b02a6c..7cdcc801 100644 --- a/packages/geom/src/ColorTransform.ts +++ b/packages/geom/src/ColorTransform.ts @@ -1,34 +1,84 @@ -import { $getColorTransform } from "@next2d/util"; -import { - $getFloat32Array8, - $clamp, - $multiplicationColor, - $poolFloat32Array8 -} from "@next2d/share"; +import { execute as colorTransformConcatService } from "../src/ColorTransform/service/ColorTransformConcatService"; /** - * ColorTransform クラスを使用すると、表示オブジェクトのカラー値を調整することができます。 - * カラー調整、つまり "カラー変換" は、赤、緑、青、アルファ透明度の 4 つのチャンネルすべてに適用できます。 - *
    - *
  • 新しい red 値 = (古い red 値 * redMultiplier ) + redOffset
  • - *
  • 新しい green 値 = (古い green 値 * greenMultiplier ) + greenOffset
  • - *
  • 新しい blue 値 = (古い blue 値 * blueMultiplier ) + blueOffset
  • - *
  • 新しい alpha 値 = (古い alpha 値 * alphaMultiplier ) + alphaOffset
  • - *
- * 算出後、カラーチャンネル値が 255 よりも大きい場合は 255 に設定されます。 - * 0 より小さい場合は 0 に設定されます。 + * @type {Float32Array[]} + * @private + */ +const $objectPool: Float32Array[] = []; + +/** + * @description オブジェクトプールから Float32Array オブジェクトを取得します。 + * Get a Float32Array object from the object pool. + * + * @param {number} [f0=0] + * @param {number} [f1=0] + * @param {number} [f2=0] + * @param {number} [f3=0] + * @param {number} [f4=0] + * @param {number} [f5=0] + * @param {number} [f6=0] + * @param {number} [f7=0] + * @return {Float32Array} + * @method + * @private + */ +const $getFloat32Array = ( + f0: number = 1, f1: number = 1, + f2: number = 1, f3: number = 1, + f4: number = 0, f5: number = 0, + f6: number = 0, f7: number = 0 +): Float32Array => { + + const array: Float32Array = $objectPool.pop() || new Float32Array(8); + + array[0] = f0; + array[1] = f1; + array[2] = f2; + array[3] = f3; + array[4] = f4; + array[5] = f5; + array[6] = f6; + array[7] = f7; + + return array; +}; + +/** + * @description 再利用する為に、オブジェクトプールに Float32Array オブジェクトを追加します。 + * Add a Float32Array object to the object pool for reuse. * - * The ColorTransform class lets you adjust the color values in a display object. - * The color adjustment or color transformation can be applied - * to all four channels: red, green, blue, and alpha transparency. - *
    - *
  • New red value = (old red value * redMultiplier) + redOffset
  • - *
  • New green value = (old green value * greenMultiplier) + greenOffset
  • - *
  • New blue value = (old blue value * blueMultiplier) + blueOffset
  • - *
  • New alpha value = (old alpha value * alphaMultiplier) + alphaOffset
  • - *
- * If any of the color channel values is greater than 255 after the calculation, - * it is set to 255. If it is less than 0, it is set to 0. + * @param {Float32Array} array + * @method + * @private + */ +const $poolFloat32Array = (array: Float32Array): void => +{ + $objectPool.push(array); +}; + +/** + * @description ColorTransform クラスを使用すると、表示オブジェクトのカラー値を調整することができます。 + * カラー調整、つまり "カラー変換" は、赤、緑、青、アルファ透明度の 4 つのチャンネルすべてに適用できます。 + *
    + *
  • 新しい red 値 = (古い red 値 * redMultiplier ) + redOffset
  • + *
  • 新しい green 値 = (古い green 値 * greenMultiplier ) + greenOffset
  • + *
  • 新しい blue 値 = (古い blue 値 * blueMultiplier ) + blueOffset
  • + *
  • 新しい alpha 値 = (古い alpha 値 * alphaMultiplier ) + alphaOffset
  • + *
+ * 算出後、カラーチャンネル値が 255 よりも大きい場合は 255 に設定されます。 + * 0 より小さい場合は 0 に設定されます。 + * + * The ColorTransform class lets you adjust the color values in a display object. + * The color adjustment or color transformation can be applied + * to all four channels: red, green, blue, and alpha transparency. + *
    + *
  • New red value = (old red value * redMultiplier) + redOffset
  • + *
  • New green value = (old green value * greenMultiplier) + greenOffset
  • + *
  • New blue value = (old blue value * blueMultiplier) + blueOffset
  • + *
  • New alpha value = (old alpha value * alphaMultiplier) + alphaOffset
  • + *
+ * If any of the color channel values is greater than 255 after the calculation, + * it is set to 255. If it is less than 0, it is set to 0. * * @class * @memberOf next2d.geom @@ -47,15 +97,6 @@ export class ColorTransform * @param {number} [blue_offset=0] * @param {number} [alpha_offset=0] * - * @example Example usage of ColorTransform. - * // new ColorTransform - * const {ColorTransform} = next2d.geom; - * const colorTransform = new ColorTransform(); - * // set new ColorTransform - * const {MovieClip} = next2d.display; - * const movieClip = new MovieClip(); - * movieClip.transform.colorTransform = colorTransform; - * * @constructor * @public */ @@ -65,22 +106,14 @@ export class ColorTransform red_offset: number = 0, green_offset: number = 0, blue_offset: number = 0, alpha_offset: number = 0 ) { - /** * @type {Float32Array} * @private */ - this._$colorTransform = $getFloat32Array8(); - - // setup - this.redMultiplier = red_multiplier; - this.greenMultiplier = green_multiplier; - this.blueMultiplier = blue_multiplier; - this.alphaMultiplier = alpha_multiplier; - this.redOffset = red_offset; - this.greenOffset = green_offset; - this.blueOffset = blue_offset; - this.alphaOffset = alpha_offset; + this._$colorTransform = $getFloat32Array( + red_multiplier, green_multiplier, blue_multiplier, alpha_multiplier, + red_offset, green_offset, blue_offset, alpha_offset + ); } /** @@ -88,7 +121,7 @@ export class ColorTransform * Returns the string representation of the specified class. * * @return {string} - * @default [class ColorTransform] + * @default "[class ColorTransform]" * @method * @static */ @@ -102,7 +135,7 @@ export class ColorTransform * Returns the space name of the specified class. * * @member {string} - * @default next2d.geom.ColorTransform + * @default "next2d.geom.ColorTransform" * @const * @static */ @@ -136,7 +169,7 @@ export class ColorTransform * Returns the space name of the specified object. * * @member {string} - * @default next2d.geom.ColorTransform + * @default "next2d.geom.ColorTransform" * @const * @public */ @@ -159,7 +192,7 @@ export class ColorTransform } set alphaMultiplier (alpha_multiplier: number) { - this._$colorTransform[3] = $clamp(+alpha_multiplier, 0, 1, 0); + this._$colorTransform[3] = alpha_multiplier; } /** @@ -178,7 +211,7 @@ export class ColorTransform } set alphaOffset (alpha_offset: number) { - this._$colorTransform[7] = $clamp(alpha_offset | 0, -255, 255, 0); + this._$colorTransform[7] = alpha_offset; } /** @@ -195,7 +228,7 @@ export class ColorTransform } set blueMultiplier (blue_multiplier: number) { - this._$colorTransform[2] = $clamp(+blue_multiplier, 0, 1, 0); + this._$colorTransform[2] = blue_multiplier; } /** @@ -214,7 +247,7 @@ export class ColorTransform } set blueOffset (blue_offset: number) { - this._$colorTransform[6] = $clamp(blue_offset | 0, -255, 255, 0); + this._$colorTransform[6] = blue_offset; } /** @@ -231,7 +264,7 @@ export class ColorTransform } set greenMultiplier (green_multiplier: number) { - this._$colorTransform[1] = $clamp(+green_multiplier, 0, 1, 0); + this._$colorTransform[1] = green_multiplier; } /** @@ -250,7 +283,7 @@ export class ColorTransform } set greenOffset (green_offset: number) { - this._$colorTransform[5] = $clamp(green_offset | 0, -255, 255, 0); + this._$colorTransform[5] = green_offset; } /** @@ -267,7 +300,7 @@ export class ColorTransform } set redMultiplier (red_multiplier: number) { - this._$colorTransform[0] = $clamp(+red_multiplier, 0, 1, 0); + this._$colorTransform[0] = red_multiplier; } /** @@ -286,7 +319,7 @@ export class ColorTransform } set redOffset (red_offset: number) { - this._$colorTransform[4] = $clamp(red_offset | 0, -255, 255, 0); + this._$colorTransform[4] = red_offset; } /** @@ -298,29 +331,35 @@ export class ColorTransform * and sets the current object as the result, * which is an additive combination of the two color transformations. * - * @param {ColorTransform} second - ColorTransformオブジェクト + * @param {ColorTransform} color_transform * @return {void} * @method * @public */ - concat (second: ColorTransform): void + concat (color_transform: ColorTransform): void { - const multiColor = $multiplicationColor( - this._$colorTransform, - second._$colorTransform - ); - - // update - this.redMultiplier = multiColor[0]; - this.greenMultiplier = multiColor[1]; - this.blueMultiplier = multiColor[2]; - this.alphaMultiplier = multiColor[3]; - this.redOffset = multiColor[4]; - this.greenOffset = multiColor[5]; - this.blueOffset = multiColor[6]; - this.alphaOffset = multiColor[7]; + colorTransformConcatService(this, color_transform); + } - $poolFloat32Array8(multiColor); + /** + * @param {Float32Array} a + * @param {Float32Array} b + * @return {Float32Array} + * @method + * @private + */ + _$multiplicationColor (a: Float32Array, b: Float32Array): Float32Array + { + return $getFloat32Array( + a[0] * b[0], + a[1] * b[1], + a[2] * b[2], + a[3] * b[3], + a[0] * b[4] + a[4], + a[1] * b[5] + a[5], + a[2] * b[6] + a[6], + a[3] * b[7] + a[7] + ); } /** @@ -330,11 +369,19 @@ export class ColorTransform */ _$clone (): ColorTransform { - return $getColorTransform( - this._$colorTransform[0], this._$colorTransform[1], - this._$colorTransform[2], this._$colorTransform[3], - this._$colorTransform[4], this._$colorTransform[5], - this._$colorTransform[6], this._$colorTransform[7] - ); + return new ColorTransform(...this._$colorTransform); + } + + /** + * @param {Float32Array} buffer + * @method + * @private + */ + _$poolBuffer (buffer: Float32Array): void + { + if ($objectPool.length > 10) { + return ; + } + $poolFloat32Array(buffer); } } diff --git a/packages/geom/src/ColorTransform/service/ColorTransformConcatService.test.ts b/packages/geom/src/ColorTransform/service/ColorTransformConcatService.test.ts new file mode 100644 index 00000000..f68c663e --- /dev/null +++ b/packages/geom/src/ColorTransform/service/ColorTransformConcatService.test.ts @@ -0,0 +1,50 @@ +import { ColorTransform } from "../../ColorTransform"; +import { describe, expect, it } from "vitest"; + +describe("ColorTransform.js concat test", () => +{ + it("concat test case1", () => + { + const ct1 = new ColorTransform(0.1, 0.2, 0.3, 0.5, 50, 100, 150, 200); + const ct2 = new ColorTransform(0.9, 0.8, 0.7, 0.6, -255, -200, -150, -100); + ct1.concat(ct2); + + expect(ct1.toString()).toBe( + "(redMultiplier=0.08999999612569809, greenMultiplier=0.1600000113248825, blueMultiplier=0.21000000834465027, alphaMultiplier=0.30000001192092896, redOffset=24.5, greenOffset=60, blueOffset=105, alphaOffset=150)" + ); + + }); + + it("concat test case2", () => + { + const ct1 = new ColorTransform(100, 0.2, 0.3, 0.5, 50, 100, 150, 200); + const ct2 = new ColorTransform(0.9, 0.8, 0.7, 0.6, -255, -200, -150, -100); + ct1.concat(ct2); + + expect(ct1.toString()).toBe( + "(redMultiplier=90, greenMultiplier=0.1600000113248825, blueMultiplier=0.21000000834465027, alphaMultiplier=0.30000001192092896, redOffset=-25450, greenOffset=60, blueOffset=105, alphaOffset=150)" + ); + }); + + it("concat test case3", () => + { + const ct1 = new ColorTransform(0.1, 0.2, 0.3, 0.5, 5000, 100, 150, 200); + const ct2 = new ColorTransform(0.9, 0.8, 0.7, 0.6, -255, -200, -150, -100); + ct1.concat(ct2); + + expect(ct1.toString()).toBe( + "(redMultiplier=0.08999999612569809, greenMultiplier=0.1600000113248825, blueMultiplier=0.21000000834465027, alphaMultiplier=0.30000001192092896, redOffset=4974.5, greenOffset=60, blueOffset=105, alphaOffset=150)" + ); + }); + + it("concat test case4", () => + { + const ct1 = new ColorTransform(0, -9, 0.3, 0.5, 50, 100, 150, 200); + const ct2 = new ColorTransform(0.9, 0.8, 0.7, 0.6, -255, -200, -150, -100); + ct1.concat(ct2); + + expect(ct1.toString()).toBe( + "(redMultiplier=0, greenMultiplier=-7.200000286102295, blueMultiplier=0.21000000834465027, alphaMultiplier=0.30000001192092896, redOffset=50, greenOffset=1900, blueOffset=105, alphaOffset=150)" + ); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/ColorTransform/service/ColorTransformConcatService.ts b/packages/geom/src/ColorTransform/service/ColorTransformConcatService.ts new file mode 100644 index 00000000..c1a5d5ab --- /dev/null +++ b/packages/geom/src/ColorTransform/service/ColorTransformConcatService.ts @@ -0,0 +1,32 @@ +import type { ColorTransform } from "../../ColorTransform"; + +/** + * @description 指定のColorTransformを連結 + * Concatenate the specified ColorTransform + * + * @param {ColorTransform} src + * @param {ColorTransform} dst + * @return {void} + * @method + * @public + */ +export const execute = (src: ColorTransform, dst: ColorTransform): void => +{ + const multiColor = src._$multiplicationColor( + src._$colorTransform, + dst._$colorTransform + ); + + // update + src._$colorTransform[0] = multiColor[0]; + src._$colorTransform[1] = multiColor[1]; + src._$colorTransform[2] = multiColor[2]; + src._$colorTransform[3] = multiColor[3]; + src._$colorTransform[4] = multiColor[4]; + src._$colorTransform[5] = multiColor[5]; + src._$colorTransform[6] = multiColor[6]; + src._$colorTransform[7] = multiColor[7]; + + // pool + src._$poolBuffer(multiColor); +}; \ No newline at end of file From f9b3e0c57ec7f2ce44fd5d059a0ffbe555190048 Mon Sep 17 00:00:00 2001 From: ienaga Date: Tue, 23 Jul 2024 01:04:04 +0900 Subject: [PATCH 007/343] =?UTF-8?q?#154=20feat:=20Matrix=E3=81=AE=E7=A7=BB?= =?UTF-8?q?=E8=A1=8C=E6=BA=96=E5=82=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/next2d/geom/MatrixTest.ts | 88 -------- packages/geom/src/ColorTransform.ts | 2 +- .../service/ColorTransformConcatService.ts | 2 +- packages/geom/src/Matrix.test.ts | 41 ++++ packages/geom/src/Matrix.ts | 192 +++++++++++------- .../Matrix/service/MatrixCloneService.test.ts | 23 +++ .../src/Matrix/service/MatrixCloneService.ts | 19 ++ packages/geom/src/Transform.ts | 8 +- 8 files changed, 212 insertions(+), 163 deletions(-) create mode 100644 packages/geom/src/Matrix.test.ts create mode 100644 packages/geom/src/Matrix/service/MatrixCloneService.test.ts create mode 100644 packages/geom/src/Matrix/service/MatrixCloneService.ts diff --git a/__tests__/next2d/geom/MatrixTest.ts b/__tests__/next2d/geom/MatrixTest.ts index 613a2133..a4bc4d9a 100644 --- a/__tests__/next2d/geom/MatrixTest.ts +++ b/__tests__/next2d/geom/MatrixTest.ts @@ -46,95 +46,7 @@ describe("Matrix.js namespace test", () => }); -describe("Matrix.js property valid test and clone test", () => -{ - - it("property success case1", () => - { - let m = new Matrix(); - m.a = 1.2; - m.b = 0.765; - m.c = -0.872; - m.d = -1.5; - m.tx = 10; - m.ty = -10; - - expect(m.a).toBe(1.2000000476837158); - expect(m.b).toBe(0.7649999856948853); - expect(m.c).toBe(-0.871999979019165); - expect(m.d).toBe(-1.5); - expect(m.tx).toBe(10); - expect(m.ty).toBe(-10); - }); - - it("property success case2", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = "1.2"; - // @ts-ignore - m.b = "0.765"; - // @ts-ignore - m.c = "-0.872"; - // @ts-ignore - m.d = "-1.5"; - // @ts-ignore - m.tx = "10"; - // @ts-ignore - m.ty = "-10"; - expect(m.a).toBe(1.2000000476837158); - expect(m.b).toBe(0.7649999856948853); - expect(m.c).toBe(-0.871999979019165); - expect(m.d).toBe(-1.5); - expect(m.tx).toBe(10); - expect(m.ty).toBe(-10); - }); - - it("valid and clone test", () => - { - // valid - // @ts-ignore - let m1 = new Matrix("a", "b", "c", "d", "tx", "ty"); - // @ts-ignore - m1.a = "a"; - // @ts-ignore - m1.b = "b"; - // @ts-ignore - m1.c = "c"; - // @ts-ignore - m1.d = "d"; - // @ts-ignore - m1.tx = "tx"; - // @ts-ignore - m1.ty = "ty"; - - // clone matrix - let m2 = m1._$clone(); - m2.a = 1.2; - m2.b = 0.765; - m2.c = -0.872; - m2.d = -1.5; - m2.tx = 10; - m2.ty = -10; - - // origin - expect(m1.a).toBe(0); - expect(m1.b).toBe(0); - expect(m1.c).toBe(0); - expect(m1.d).toBe(0); - expect(m1.tx).toBe(0); - expect(m1.ty).toBe(0); - - // clone - expect(m2.a).toBe(1.2000000476837158); - expect(m2.b).toBe(0.7649999856948853); - expect(m2.c).toBe(-0.871999979019165); - expect(m2.d).toBe(-1.5); - expect(m2.tx).toBe(10); - expect(m2.ty).toBe(-10); - }); -}); describe("Matrix.js concat test", () => { diff --git a/packages/geom/src/ColorTransform.ts b/packages/geom/src/ColorTransform.ts index 7cdcc801..9a65d296 100644 --- a/packages/geom/src/ColorTransform.ts +++ b/packages/geom/src/ColorTransform.ts @@ -348,7 +348,7 @@ export class ColorTransform * @method * @private */ - _$multiplicationColor (a: Float32Array, b: Float32Array): Float32Array + _$multiplication (a: Float32Array, b: Float32Array): Float32Array { return $getFloat32Array( a[0] * b[0], diff --git a/packages/geom/src/ColorTransform/service/ColorTransformConcatService.ts b/packages/geom/src/ColorTransform/service/ColorTransformConcatService.ts index c1a5d5ab..0ce33604 100644 --- a/packages/geom/src/ColorTransform/service/ColorTransformConcatService.ts +++ b/packages/geom/src/ColorTransform/service/ColorTransformConcatService.ts @@ -12,7 +12,7 @@ import type { ColorTransform } from "../../ColorTransform"; */ export const execute = (src: ColorTransform, dst: ColorTransform): void => { - const multiColor = src._$multiplicationColor( + const multiColor = src._$multiplication( src._$colorTransform, dst._$colorTransform ); diff --git a/packages/geom/src/Matrix.test.ts b/packages/geom/src/Matrix.test.ts new file mode 100644 index 00000000..67d46000 --- /dev/null +++ b/packages/geom/src/Matrix.test.ts @@ -0,0 +1,41 @@ +import { Matrix } from "./Matrix"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js toString test", () => +{ + it("toString test1 success", () => + { + const matrix = new Matrix(); + expect(matrix.toString()).toBe("(a=1, b=0, c=0, d=1, tx=0, ty=0)"); + }); + + it("toString test2 success", () => + { + const matrix = new Matrix(2, 3, 4, 5, 6, 7); + expect(matrix.toString()).toBe("(a=2, b=3, c=4, d=5, tx=6, ty=7)"); + }); +}); + +describe("Matrix.js static toString test", () => +{ + + it("static toString test", () => + { + expect(Matrix.toString()).toBe("[class Matrix]"); + }); + +}); + +describe("Matrix.js namespace test", () => +{ + it("namespace test public", () => + { + const matrix = new Matrix(); + expect(matrix.namespace).toBe("next2d.geom.Matrix"); + }); + + it("namespace test static", () => + { + expect(Matrix.namespace).toBe("next2d.geom.Matrix"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix.ts b/packages/geom/src/Matrix.ts index 03fe1671..104c66f0 100644 --- a/packages/geom/src/Matrix.ts +++ b/packages/geom/src/Matrix.ts @@ -1,33 +1,68 @@ import { Point } from "./Point"; -import { $getMatrix } from "@next2d/util"; -import { - $getFloat32Array6, - $clamp, - $Math, - $SHORT_INT_MIN, - $SHORT_INT_MAX -} from "@next2d/share"; +import { execute as matrixCloneService } from "../src/Matrix/service/MatrixCloneService"; /** - * Matrix クラスは、2 つの座標空間の間におけるポイントのマッピング方法を決定する変換マトリックスを表します。 - * Matrix オブジェクトのプロパティを設定し、Matrix オブジェクトを Transform オブジェクトの matrix プロパティに適用し、 - * 次に Transform オブジェクトを表示オブジェクトの transform プロパティとして適用することで、表示オブジェクトに対する各種グラフィック変換を実行できます。 - * これらの変換機能には、平行移動(x と y の位置変更)、回転、拡大 / 縮小、傾斜などが含まれます。 + * @type {Float32Array[]} + * @private + */ +const $objectPool: Float32Array[] = []; + +/** + * @description オブジェクトプールから Float32Array オブジェクトを取得します。 + * Get a Float32Array object from the object pool. * - * The Matrix class represents a transformation matrix that determines how to map points from one coordinate space to another. - * You can perform various graphical transformations on a display object by setting the properties of a Matrix object, - * applying that Matrix object to the matrix property of a Transform object, - * and then applying that Transform object as the transform property of the display object. - * These transformation functions include translation (x and y repositioning), rotation, scaling, and skewing. + * @param {number} [f0=0] + * @param {number} [f1=0] + * @param {number} [f2=0] + * @param {number} [f3=0] + * @param {number} [f4=0] + * @param {number} [f5=0] + * @return {Float32Array} + * @method + * @private + */ +const $getFloat32Array = ( + f0: number = 1, f1: number = 0, + f2: number = 0, f3: number = 1, + f4: number = 0, f5: number = 0 +): Float32Array => { + + const array: Float32Array = $objectPool.pop() || new Float32Array(6); + + array[0] = f0; + array[1] = f1; + array[2] = f2; + array[3] = f3; + array[4] = f4; + array[5] = f5; + + return array; +}; + +/** + * @description 再利用する為に、オブジェクトプールに Float32Array オブジェクトを追加します。 + * Add a Float32Array object to the object pool for reuse. + * + * @param {Float32Array} array + * @method + * @private + */ +const $poolFloat32Array = (array: Float32Array): void => +{ + $objectPool.push(array); +}; + +/** + * @description Matrix クラスは、2 つの座標空間の間におけるポイントのマッピング方法を決定する変換マトリックスを表します。 + * Matrix オブジェクトのプロパティを設定し、Matrix オブジェクトを Transform オブジェクトの matrix プロパティに適用し、 + * 次に Transform オブジェクトを表示オブジェクトの transform プロパティとして適用することで、表示オブジェクトに対する各種グラフィック変換を実行できます。 + * これらの変換機能には、平行移動(x と y の位置変更)、回転、拡大 / 縮小、傾斜などが含まれます。 * - * @example Example usage of Matrix. - * // new Matrix - * const {Matrix} = next2d.geom; - * const matrix = new Matrix(); - * // set new Matrix - * const {MovieClip} = next2d.display; - * const movieClip = new MovieClip(); - * movieClip.transform.matrix = matrix; + * The Matrix class represents a transformation matrix that determines how to map points from one coordinate space to another. + * You can perform various graphical transformations on a display object by setting the properties of a Matrix object, + * applying that Matrix object to the matrix property of a Transform object, + * and then applying that Transform object as the transform property of the display object. + * These transformation functions include translation (x and y repositioning), rotation, scaling, and skewing. * * @class * @memberOf next2d.geom @@ -56,15 +91,7 @@ export class Matrix * @type {Float32Array} * @private */ - this._$matrix = $getFloat32Array6(1, 0, 0, 1, 0, 0); - - // setup - this.a = a; - this.b = b; - this.c = c; - this.d = d; - this.tx = tx; - this.ty = ty; + this._$matrix = $getFloat32Array(a, b, c, d, tx, ty); } /** @@ -72,7 +99,7 @@ export class Matrix * Returns the string representation of the specified class. * * @return {string} - * @default [class Matrix] + * @default "[class Matrix]" * @method * @static */ @@ -86,7 +113,7 @@ export class Matrix * Returns the space name of the specified class. * * @member {string} - * @default next2d.geom.Matrix + * @default "next2d.geom.Matrix" * @const * @static */ @@ -113,7 +140,7 @@ export class Matrix * Returns the space name of the specified object. * * @member {string} - * @default next2d.geom.Matrix + * @default "next2d.geom.Matrix" * @const * @public */ @@ -137,7 +164,7 @@ export class Matrix } set a (a: number) { - this._$matrix[0] = $clamp(+a, $SHORT_INT_MIN, $SHORT_INT_MAX, 0); + this._$matrix[0] = a; } /** @@ -155,7 +182,7 @@ export class Matrix } set b (b: number) { - this._$matrix[1] = $clamp(+b, $SHORT_INT_MIN, $SHORT_INT_MAX, 0); + this._$matrix[1] = b; } /** @@ -173,7 +200,7 @@ export class Matrix } set c (c: number) { - this._$matrix[2] = $clamp(+c, $SHORT_INT_MIN, $SHORT_INT_MAX, 0); + this._$matrix[2] = c; } /** @@ -191,7 +218,7 @@ export class Matrix } set d (d: number) { - this._$matrix[3] = $clamp(+d, $SHORT_INT_MIN, $SHORT_INT_MAX, 0); + this._$matrix[3] = d; } /** @@ -208,7 +235,7 @@ export class Matrix } set tx (tx: number) { - this._$matrix[4] = $clamp(+tx, $SHORT_INT_MIN, $SHORT_INT_MAX, 0); + this._$matrix[4] = tx; } /** @@ -225,7 +252,7 @@ export class Matrix } set ty (ty: number) { - this._$matrix[5] = $clamp(+ty, $SHORT_INT_MIN, $SHORT_INT_MAX, 0); + this._$matrix[5] = ty; } /** @@ -235,7 +262,7 @@ export class Matrix */ _$clone (): Matrix { - return this.clone(); + return matrixCloneService(this); } /** @@ -250,11 +277,7 @@ export class Matrix */ clone (): Matrix { - return $getMatrix( - this._$matrix[0], this._$matrix[1], - this._$matrix[2], this._$matrix[3], - this._$matrix[4], this._$matrix[5] - ); + return matrixCloneService(this); } /** @@ -289,12 +312,12 @@ export class Matrix ty += matrix[4] * target[1]; } - this.a = a; - this.b = b; - this.c = c; - this.d = d; - this.tx = tx; - this.ty = ty; + this._$matrix[0] = a; + this._$matrix[1] = b; + this._$matrix[2] = c; + this._$matrix[3] = d; + this._$matrix[4] = tx; + this._$matrix[5] = ty; } /** @@ -307,12 +330,12 @@ export class Matrix */ copyFrom (source_matrix: Matrix): void { - this.a = source_matrix.a; - this.b = source_matrix.b; - this.c = source_matrix.c; - this.d = source_matrix.d; - this.tx = source_matrix.tx; - this.ty = source_matrix.ty; + this._$matrix[0] = source_matrix.a; + this._$matrix[1] = source_matrix.b; + this._$matrix[2] = source_matrix.c; + this._$matrix[3] = source_matrix.d; + this._$matrix[4] = source_matrix.tx; + this._$matrix[5] = source_matrix.ty; } /** @@ -363,8 +386,8 @@ export class Matrix this.d = height / 1638.4; if (rotation) { - const cos = $Math.cos(rotation); - const sin = $Math.sin(rotation); + const cos = Math.cos(rotation); + const sin = Math.sin(rotation); this.b = sin * this.d; this.c = -sin * this.a; @@ -479,12 +502,12 @@ export class Matrix const tx = this._$matrix[4]; const ty = this._$matrix[5]; - this.a = a * $Math.cos(rotation) - b * $Math.sin(rotation); - this.b = a * $Math.sin(rotation) + b * $Math.cos(rotation); - this.c = c * $Math.cos(rotation) - d * $Math.sin(rotation); - this.d = c * $Math.sin(rotation) + d * $Math.cos(rotation); - this.tx = tx * $Math.cos(rotation) - ty * $Math.sin(rotation); - this.ty = tx * $Math.sin(rotation) + ty * $Math.cos(rotation); + this.a = a * Math.cos(rotation) - b * Math.sin(rotation); + this.b = a * Math.sin(rotation) + b * Math.cos(rotation); + this.c = c * Math.cos(rotation) - d * Math.sin(rotation); + this.d = c * Math.sin(rotation) + d * Math.cos(rotation); + this.tx = tx * Math.cos(rotation) - ty * Math.sin(rotation); + this.ty = tx * Math.sin(rotation) + ty * Math.cos(rotation); } /** @@ -570,4 +593,35 @@ export class Matrix this.tx += dx; this.ty += dy; } + + /** + * @param {Float32Array} a + * @param {Float32Array} b + * @return {Float32Array} + * @method + * @private + */ + _$multiplication (a: Float32Array, b: Float32Array): Float32Array + { + return $getFloat32Array( + a[0] * b[0] + a[2] * b[1], + a[1] * b[0] + a[3] * b[1], + a[0] * b[2] + a[2] * b[3], + a[1] * b[2] + a[3] * b[3], + a[0] * b[4] + a[2] * b[5] + a[4], + a[1] * b[4] + a[3] * b[5] + a[5] + ); + } + /** + * @param {Float32Array} buffer + * @method + * @private + */ + _$poolBuffer (buffer: Float32Array): void + { + if ($objectPool.length > 10) { + return ; + } + $poolFloat32Array(buffer); + } } diff --git a/packages/geom/src/Matrix/service/MatrixCloneService.test.ts b/packages/geom/src/Matrix/service/MatrixCloneService.test.ts new file mode 100644 index 00000000..d098efe6 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixCloneService.test.ts @@ -0,0 +1,23 @@ +import { Matrix } from "../../Matrix"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js property valid test and clone test", () => +{ + it("property success case1", () => + { + const matrix = new Matrix(); + matrix.a = 1.2; + matrix.b = 0.765; + matrix.c = -0.872; + matrix.d = -1.5; + matrix.tx = 10; + matrix.ty = -10; + + expect(matrix.a).toBe(1.2000000476837158); + expect(matrix.b).toBe(0.7649999856948853); + expect(matrix.c).toBe(-0.871999979019165); + expect(matrix.d).toBe(-1.5); + expect(matrix.tx).toBe(10); + expect(matrix.ty).toBe(-10); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixCloneService.ts b/packages/geom/src/Matrix/service/MatrixCloneService.ts new file mode 100644 index 00000000..824235b6 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixCloneService.ts @@ -0,0 +1,19 @@ +import { Matrix } from "../../Matrix"; + +/** + * @description 指定のMatrixオブジェクトのクローンを生成して返却 + * Generate and return a clone of the specified Matrix object + * + * @param {Matrix} matrix + * @return {Matrix} + * @method + * @public + */ +export const execute = (matrix: Matrix): Matrix => +{ + return new Matrix( + matrix._$matrix[0], matrix._$matrix[1], + matrix._$matrix[2], matrix._$matrix[3], + matrix._$matrix[4], matrix._$matrix[5] + ); +}; \ No newline at end of file diff --git a/packages/geom/src/Transform.ts b/packages/geom/src/Transform.ts index 212a3888..563c768c 100644 --- a/packages/geom/src/Transform.ts +++ b/packages/geom/src/Transform.ts @@ -71,10 +71,10 @@ import { export class Transform { private readonly _$displayObject: DisplayObjectImpl; - public _$matrix: Matrix|null; - public _$colorTransform: ColorTransform|null; - public _$blendMode: BlendModeImpl|null; - public _$filters: FilterArrayImpl|null; + public _$matrix: Matrix | null; + public _$colorTransform: ColorTransform | null; + public _$blendMode: BlendModeImpl | null; + public _$filters: FilterArrayImpl | null; /** * @param {DisplayObject} src From 59d021074b0ebf17e4b41e88a5cc20d4e5529225 Mon Sep 17 00:00:00 2001 From: ienaga Date: Tue, 23 Jul 2024 09:49:57 +0900 Subject: [PATCH 008/343] =?UTF-8?q?#154=20update:=20=E5=A4=89=E6=95=B0?= =?UTF-8?q?=E5=90=8D=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/next2d/geom/MatrixTest.ts | 113 ------------------ .../service/ColorTransformConcatService.ts | 35 +++--- packages/geom/src/Matrix.ts | 31 +---- .../service/MatirxConcatService.test.ts | 85 +++++++++++++ .../src/Matrix/service/MatirxConcatService.ts | 40 +++++++ .../service/MatrixCopyFromService.test.ts | 33 +++++ .../Matrix/service/MatrixCopyFromService.ts | 21 ++++ .../geom/src/Point/service/PointAddService.ts | 8 +- .../src/Point/service/PointCopyFromService.ts | 8 +- .../src/Point/service/PointEqualsService.ts | 8 +- .../Point/service/PointNormalizeService.ts | 9 +- .../src/Point/service/PointOffsetService.ts | 8 +- .../src/Point/service/PointSetToService.ts | 8 +- .../src/Point/service/PointSubtractService.ts | 8 +- .../service/RectangleCloneService.ts | 6 +- .../service/RectangleContainsPointService.ts | 12 +- .../service/RectangleContainsRectService.ts | 14 +-- .../service/RectangleContainsService.ts | 9 +- .../service/RectangleCopyFromService.ts | 12 +- .../service/RectangleEqualsService.ts | 12 +- .../service/RectangleInflatePointService.ts | 12 +- .../service/RectangleInflateService.ts | 12 +- .../service/RectangleIntersectionService.ts | 14 +-- .../service/RectangleIntersectsService.ts | 14 +-- .../service/RectangleIsEmptyService.ts | 6 +- .../service/RectangleOffsetPointService.ts | 8 +- .../service/RectangleOffsetService.ts | 8 +- .../service/RectangleSetEmptyService.ts | 6 +- .../service/RectangleSetToService.ts | 12 +- .../service/RectangleUnionService.ts | 18 +-- 30 files changed, 320 insertions(+), 270 deletions(-) create mode 100644 packages/geom/src/Matrix/service/MatirxConcatService.test.ts create mode 100644 packages/geom/src/Matrix/service/MatirxConcatService.ts create mode 100644 packages/geom/src/Matrix/service/MatrixCopyFromService.test.ts create mode 100644 packages/geom/src/Matrix/service/MatrixCopyFromService.ts diff --git a/__tests__/next2d/geom/MatrixTest.ts b/__tests__/next2d/geom/MatrixTest.ts index a4bc4d9a..930b3c15 100644 --- a/__tests__/next2d/geom/MatrixTest.ts +++ b/__tests__/next2d/geom/MatrixTest.ts @@ -48,88 +48,7 @@ describe("Matrix.js namespace test", () => -describe("Matrix.js concat test", () => -{ - it("concat test1", () => - { - let m1 = new Matrix(2, 1, -1, 1, 0, 5); - let m2 = new Matrix(1.3, 0.75, 0, -1.5, 10, -10); - m1.concat(m2); - expect(m1.toString()).toBe( - "(a=2.5999999046325684, b=0, c=-1.2999999523162842, d=-2.25, tx=10, ty=-17.5)" - ); - }); - - it("concat test2", () => - { - let m1 = new Matrix(2, 1, -1, 1, 0, 5); - let m2 = new Matrix(0, 0.75, 0, -1.5, 10, -10); - m1.concat(m2); - expect(m1.toString()).toBe( - "(a=0, b=0, c=0, d=-2.25, tx=10, ty=-17.5)" - ); - }); - - it("concat test3", () => - { - let m1 = new Matrix(2, 1, -1, 1, 0, 5); - let m2 = new Matrix(1.3, 0, 0, -1.5, 10, -10); - m1.concat(m2); - expect(m1.toString()).toBe( - "(a=2.5999999046325684, b=-1.5, c=-1.2999999523162842, d=-1.5, tx=10, ty=-17.5)" - ); - }); - - it("concat test4", () => - { - let m1 = new Matrix(2, 1, -1, 1, 0, 5); - let m2 = new Matrix(1.3, 0.75, 0, 0, 10, -10); - m1.concat(m2); - expect(m1.toString()).toBe( - "(a=2.5999999046325684, b=1.5, c=-1.2999999523162842, d=-0.75, tx=10, ty=-10)" - ); - }); - it("concat test5", () => - { - let m1 = new Matrix(2, 1, -1, 1, 0, 5); - let m2 = new Matrix(1.3, 0.75, 0, -1.5, 0, -10); - m1.concat(m2); - expect(m1.toString()).toBe( - "(a=2.5999999046325684, b=0, c=-1.2999999523162842, d=-2.25, tx=0, ty=-17.5)" - ); - }); - - it("concat test6", () => - { - let m1 = new Matrix(2, 1, -1, 1, 0, 5); - let m2 = new Matrix(1.3, 0.75, 0, -1.5, 10, 0); - m1.concat(m2); - expect(m1.toString()).toBe( - "(a=2.5999999046325684, b=0, c=-1.2999999523162842, d=-2.25, tx=10, ty=-7.5)" - ); - }); - - it("concat test7", () => - { - let m1 = new Matrix(1,0,0,1,0,0); - let m2 = new Matrix(1.3, 0.75, 0, -1.5, 10, -10); - m1.concat(m2); - expect(m1.toString()).toBe( - "(a=1.2999999523162842, b=0.75, c=0, d=-1.5, tx=10, ty=-10)" - ); - }); - - it("concat test8", () => - { - let m1 = new Matrix(1,0,0,1,10,10); - let m2 = new Matrix(1.3, 0.75, 0, -1.5, 10, -10); - m1.concat(m2); - expect(m1.toString()).toBe( - "(a=1.2999999523162842, b=0.75, c=0, d=-1.5, tx=23, ty=-17.5)" - ); - }); -}); describe("Matrix.js rotate test", () => { @@ -2794,39 +2713,7 @@ describe("Matrix.js BugFix", () => }); }); -describe("Matrix.js copyFrom", () => -{ - it("copy test case1", () => - { - - const defaultMatrix = new Matrix(); - expect(defaultMatrix.toString()).toBe( - "(a=1, b=0, c=0, d=1, tx=0, ty=0)" - ); - const matrix = new Matrix(1, 2, 3, 4, 5, 6); - defaultMatrix.copyFrom(matrix); - expect(defaultMatrix.toString()).toBe( - "(a=1, b=2, c=3, d=4, tx=5, ty=6)" - ); - - defaultMatrix.a = 1; - defaultMatrix.b = 0; - defaultMatrix.c = 0; - defaultMatrix.d = 1; - defaultMatrix.tx = 100; - defaultMatrix.ty = 200; - expect(defaultMatrix.toString()).toBe( - "(a=1, b=0, c=0, d=1, tx=100, ty=200)" - ); - - expect(matrix.toString()).toBe( - "(a=1, b=2, c=3, d=4, tx=5, ty=6)" - ); - - }); - -}); describe("Matrix.js setTo", () => { diff --git a/packages/geom/src/ColorTransform/service/ColorTransformConcatService.ts b/packages/geom/src/ColorTransform/service/ColorTransformConcatService.ts index 0ce33604..35aeed24 100644 --- a/packages/geom/src/ColorTransform/service/ColorTransformConcatService.ts +++ b/packages/geom/src/ColorTransform/service/ColorTransformConcatService.ts @@ -4,29 +4,32 @@ import type { ColorTransform } from "../../ColorTransform"; * @description 指定のColorTransformを連結 * Concatenate the specified ColorTransform * - * @param {ColorTransform} src - * @param {ColorTransform} dst + * @param {ColorTransform} color_transform1 + * @param {ColorTransform} color_transform2 * @return {void} * @method * @public */ -export const execute = (src: ColorTransform, dst: ColorTransform): void => -{ - const multiColor = src._$multiplication( - src._$colorTransform, - dst._$colorTransform +export const execute = ( + color_transform1: ColorTransform, + color_transform2: ColorTransform +): void => { + + const multiColor = color_transform1._$multiplication( + color_transform1._$colorTransform, + color_transform2._$colorTransform ); // update - src._$colorTransform[0] = multiColor[0]; - src._$colorTransform[1] = multiColor[1]; - src._$colorTransform[2] = multiColor[2]; - src._$colorTransform[3] = multiColor[3]; - src._$colorTransform[4] = multiColor[4]; - src._$colorTransform[5] = multiColor[5]; - src._$colorTransform[6] = multiColor[6]; - src._$colorTransform[7] = multiColor[7]; + color_transform1._$colorTransform[0] = multiColor[0]; + color_transform1._$colorTransform[1] = multiColor[1]; + color_transform1._$colorTransform[2] = multiColor[2]; + color_transform1._$colorTransform[3] = multiColor[3]; + color_transform1._$colorTransform[4] = multiColor[4]; + color_transform1._$colorTransform[5] = multiColor[5]; + color_transform1._$colorTransform[6] = multiColor[6]; + color_transform1._$colorTransform[7] = multiColor[7]; // pool - src._$poolBuffer(multiColor); + color_transform1._$poolBuffer(multiColor); }; \ No newline at end of file diff --git a/packages/geom/src/Matrix.ts b/packages/geom/src/Matrix.ts index 104c66f0..d722539b 100644 --- a/packages/geom/src/Matrix.ts +++ b/packages/geom/src/Matrix.ts @@ -1,5 +1,6 @@ import { Point } from "./Point"; import { execute as matrixCloneService } from "../src/Matrix/service/MatrixCloneService"; +import { execute as matirxConcatService } from "../src/Matrix/service/MatirxConcatService"; /** * @type {Float32Array[]} @@ -286,38 +287,14 @@ export class Matrix * Concatenates a matrix with the current matrix, * effectively combining the geometric effects of the two. * - * @param {Matrix} m + * @param {Matrix} matrix * @return {void} * @method * @public */ - concat (m: Matrix): void + concat (matrix: Matrix): void { - const matrix = this._$matrix; - const target = m._$matrix; - - let a = matrix[0] * target[0]; - let b = 0.0; - let c = 0.0; - let d = matrix[3] * target[3]; - let tx = matrix[4] * target[0] + target[4]; - let ty = matrix[5] * target[3] + target[5]; - - if (matrix[1] || matrix[2] || target[1] || target[2]) { - a += matrix[1] * target[2]; - d += matrix[2] * target[1]; - b += matrix[0] * target[1] + matrix[1] * target[3]; - c += matrix[2] * target[0] + matrix[3] * target[2]; - tx += matrix[5] * target[2]; - ty += matrix[4] * target[1]; - } - - this._$matrix[0] = a; - this._$matrix[1] = b; - this._$matrix[2] = c; - this._$matrix[3] = d; - this._$matrix[4] = tx; - this._$matrix[5] = ty; + matirxConcatService(this, matrix); } /** diff --git a/packages/geom/src/Matrix/service/MatirxConcatService.test.ts b/packages/geom/src/Matrix/service/MatirxConcatService.test.ts new file mode 100644 index 00000000..b12eed8a --- /dev/null +++ b/packages/geom/src/Matrix/service/MatirxConcatService.test.ts @@ -0,0 +1,85 @@ +import { Matrix } from "../../Matrix"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js concat test", () => +{ + it("concat test case1", () => + { + const matrix1 = new Matrix(2, 1, -1, 1, 0, 5); + const matrix2 = new Matrix(1.3, 0.75, 0, -1.5, 10, -10); + matrix1.concat(matrix2); + expect(matrix1.toString()).toBe( + "(a=2.5999999046325684, b=0, c=-1.2999999523162842, d=-2.25, tx=10, ty=-17.5)" + ); + }); + + it("concat test case2", () => + { + const matrix1 = new Matrix(2, 1, -1, 1, 0, 5); + const matrix2 = new Matrix(0, 0.75, 0, -1.5, 10, -10); + matrix1.concat(matrix2); + expect(matrix1.toString()).toBe( + "(a=0, b=0, c=0, d=-2.25, tx=10, ty=-17.5)" + ); + }); + + it("concat test case3", () => + { + const matrix1 = new Matrix(2, 1, -1, 1, 0, 5); + const matrix2 = new Matrix(1.3, 0, 0, -1.5, 10, -10); + matrix1.concat(matrix2); + expect(matrix1.toString()).toBe( + "(a=2.5999999046325684, b=-1.5, c=-1.2999999523162842, d=-1.5, tx=10, ty=-17.5)" + ); + }); + + it("concat test case4", () => + { + const matrix1 = new Matrix(2, 1, -1, 1, 0, 5); + const matrix2 = new Matrix(1.3, 0.75, 0, 0, 10, -10); + matrix1.concat(matrix2); + expect(matrix1.toString()).toBe( + "(a=2.5999999046325684, b=1.5, c=-1.2999999523162842, d=-0.75, tx=10, ty=-10)" + ); + }); + + it("concat test case5", () => + { + const matrix1 = new Matrix(2, 1, -1, 1, 0, 5); + const matrix2 = new Matrix(1.3, 0.75, 0, -1.5, 0, -10); + matrix1.concat(matrix2); + expect(matrix1.toString()).toBe( + "(a=2.5999999046325684, b=0, c=-1.2999999523162842, d=-2.25, tx=0, ty=-17.5)" + ); + }); + + it("concat test case6", () => + { + const matrix1 = new Matrix(2, 1, -1, 1, 0, 5); + const matrix2 = new Matrix(1.3, 0.75, 0, -1.5, 10, 0); + matrix1.concat(matrix2); + expect(matrix1.toString()).toBe( + "(a=2.5999999046325684, b=0, c=-1.2999999523162842, d=-2.25, tx=10, ty=-7.5)" + ); + }); + + it("concat test case7", () => + { + const matrix1 = new Matrix(1,0,0,1,0,0); + const matrix2 = new Matrix(1.3, 0.75, 0, -1.5, 10, -10); + matrix1.concat(matrix2); + expect(matrix1.toString()).toBe( + "(a=1.2999999523162842, b=0.75, c=0, d=-1.5, tx=10, ty=-10)" + ); + }); + + it("concat test case8", () => + { + const matrix1 = new Matrix(1,0,0,1,10,10); + const matrix2 = new Matrix(1.3, 0.75, 0, -1.5, 10, -10); + matrix1.concat(matrix2); + expect(matrix1.toString()).toBe( + "(a=1.2999999523162842, b=0.75, c=0, d=-1.5, tx=23, ty=-17.5)" + ); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatirxConcatService.ts b/packages/geom/src/Matrix/service/MatirxConcatService.ts new file mode 100644 index 00000000..bb616afc --- /dev/null +++ b/packages/geom/src/Matrix/service/MatirxConcatService.ts @@ -0,0 +1,40 @@ +import { Matrix } from "../../Matrix"; + +/** + * @description 指定のMatrixを連結 + * Concatenate specified Matrix + * + * @param {Matrix} matrix1 + * @param {Matrix} matrix2 + * @return {void} + * @method + * @public + */ +export const execute = (matrix1: Matrix, matrix2: Matrix): void => +{ + const matrixArray1 = matrix1._$matrix; + const matrixArray2 = matrix2._$matrix; + + let a = matrixArray1[0] * matrixArray2[0]; + let b = 0.0; + let c = 0.0; + let d = matrixArray1[3] * matrixArray2[3]; + let tx = matrixArray1[4] * matrixArray2[0] + matrixArray2[4]; + let ty = matrixArray1[5] * matrixArray2[3] + matrixArray2[5]; + + if (matrixArray1[1] || matrixArray1[2] || matrixArray2[1] || matrixArray2[2]) { + a += matrixArray1[1] * matrixArray2[2]; + d += matrixArray1[2] * matrixArray2[1]; + b += matrixArray1[0] * matrixArray2[1] + matrixArray1[1] * matrixArray2[3]; + c += matrixArray1[2] * matrixArray2[0] + matrixArray1[3] * matrixArray2[2]; + tx += matrixArray1[5] * matrixArray2[2]; + ty += matrixArray1[4] * matrixArray2[1]; + } + + matrixArray1[0] = a; + matrixArray1[1] = b; + matrixArray1[2] = c; + matrixArray1[3] = d; + matrixArray1[4] = tx; + matrixArray1[5] = ty; +}; \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixCopyFromService.test.ts b/packages/geom/src/Matrix/service/MatrixCopyFromService.test.ts new file mode 100644 index 00000000..c41e7103 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixCopyFromService.test.ts @@ -0,0 +1,33 @@ +import { Matrix } from "../../Matrix"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js copyFrom", () => +{ + it("copy test case1", () => + { + const matrix1 = new Matrix(); + expect(matrix1.toString()).toBe( + "(a=1, b=0, c=0, d=1, tx=0, ty=0)" + ); + + const matrix2 = new Matrix(1, 2, 3, 4, 5, 6); + matrix1.copyFrom(matrix2); + expect(matrix1.toString()).toBe( + "(a=1, b=2, c=3, d=4, tx=5, ty=6)" + ); + + matrix1.a = 1; + matrix1.b = 0; + matrix1.c = 0; + matrix1.d = 1; + matrix1.tx = 100; + matrix1.ty = 200; + expect(matrix1.toString()).toBe( + "(a=1, b=0, c=0, d=1, tx=100, ty=200)" + ); + + expect(matrix2.toString()).toBe( + "(a=1, b=2, c=3, d=4, tx=5, ty=6)" + ); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixCopyFromService.ts b/packages/geom/src/Matrix/service/MatrixCopyFromService.ts new file mode 100644 index 00000000..76e2ef36 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixCopyFromService.ts @@ -0,0 +1,21 @@ +import { Matrix } from "../../Matrix"; + +/** + * @description 指定のMatrixオブジェクトの値をコピー + * Copy the value of the specified Matrix object + * + * @param {Matrix} dst + * @param {Matrix} src + * @return {void} + * @method + * @public + */ +export const execute = (dst: Matrix, src: Matrix): void => +{ + dst._$matrix[0] = src._$matrix[0]; + dst._$matrix[1] = src._$matrix[1]; + dst._$matrix[2] = src._$matrix[2]; + dst._$matrix[3] = src._$matrix[3]; + dst._$matrix[4] = src._$matrix[4]; + dst._$matrix[5] = src._$matrix[5]; +}; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointAddService.ts b/packages/geom/src/Point/service/PointAddService.ts index 41b15449..f8310b1d 100644 --- a/packages/geom/src/Point/service/PointAddService.ts +++ b/packages/geom/src/Point/service/PointAddService.ts @@ -4,13 +4,13 @@ import { Point } from "../../Point"; * @description 2つの座標を加算します。 * Adds two points. * - * @param {Point} src - * @param {Point} dst + * @param {Point} point1 + * @param {Point} point2 * @return {Point} * @method * @public */ -export const execute = (src: Point, dst: Point): Point => +export const execute = (point1: Point, point2: Point): Point => { - return new Point(src.x + dst.x, src.y + dst.y); + return new Point(point1.x + point2.x, point1.y + point2.y); }; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointCopyFromService.ts b/packages/geom/src/Point/service/PointCopyFromService.ts index eed86113..1218a7b6 100644 --- a/packages/geom/src/Point/service/PointCopyFromService.ts +++ b/packages/geom/src/Point/service/PointCopyFromService.ts @@ -4,14 +4,14 @@ import type { Point } from "../../Point"; * @description 指定されたポイントの値をコピーします。 * Copies the value of the specified point. * - * @param {Point} src * @param {Point} dst + * @param {Point} src * @return {void} * @method * @public */ -export const execute = (src: Point, dst: Point): void => +export const execute = (dst: Point, src: Point): void => { - src.x = dst.x; - src.y = dst.y; + dst.x = src.x; + dst.y = src.y; }; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointEqualsService.ts b/packages/geom/src/Point/service/PointEqualsService.ts index caf2bbc5..4f742109 100644 --- a/packages/geom/src/Point/service/PointEqualsService.ts +++ b/packages/geom/src/Point/service/PointEqualsService.ts @@ -4,13 +4,13 @@ import type { Point } from "../../Point"; * @description 2点が等しいかどうかを返します。 * Returns whether two points are equal. * - * @param {Point} src - * @param {Point} dst + * @param {Point} point1 + * @param {Point} point2 * @return {boolean} * @method * @public */ -export const execute = (src: Point, dst: Point): boolean => +export const execute = (point1: Point, point2: Point): boolean => { - return src.x === dst.x && src.y === dst.y; + return point1.x === point2.x && point1.y === point2.y; }; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointNormalizeService.ts b/packages/geom/src/Point/service/PointNormalizeService.ts index 05757cd3..b91ad425 100644 --- a/packages/geom/src/Point/service/PointNormalizeService.ts +++ b/packages/geom/src/Point/service/PointNormalizeService.ts @@ -4,14 +4,15 @@ import type { Point } from "../../Point"; * @description (0,0) と現在のポイント間の線のセグメントを設定された長さに拡大 / 縮小します。 * Expands / contracts the line segment between (0,0) and the current point to the specified length. * + * @param {Point} point * @param {number} thickness * @return {void} * @method * @public */ -export const execute = (src: Point, thickness: number): void => +export const execute = (point: Point, thickness: number): void => { - const value = thickness / src.length; - src.x *= value; - src.y *= value; + const value = thickness / point.length; + point.x *= value; + point.y *= value; }; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointOffsetService.ts b/packages/geom/src/Point/service/PointOffsetService.ts index beb33dec..e54ffe72 100644 --- a/packages/geom/src/Point/service/PointOffsetService.ts +++ b/packages/geom/src/Point/service/PointOffsetService.ts @@ -4,15 +4,15 @@ import type { Point } from "../../Point"; * @description 2点間の補間を返します。 * Returns the interpolation between two points. * - * @param {Point} src + * @param {Point} point * @param {number} dx * @param {number} dy * @return {Point} * @method * @public */ -export const execute = (src: Point, dx: number, dy: number): void => +export const execute = (point: Point, dx: number, dy: number): void => { - src.x += dx; - src.y += dy; + point.x += dx; + point.y += dy; }; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointSetToService.ts b/packages/geom/src/Point/service/PointSetToService.ts index 7c3261b5..16a6e29a 100644 --- a/packages/geom/src/Point/service/PointSetToService.ts +++ b/packages/geom/src/Point/service/PointSetToService.ts @@ -4,15 +4,15 @@ import type { Point } from "../../Point"; * @description 指定されたポイントの座標を設定します。 * Sets the coordinates of the specified point. * - * @param {Point} src + * @param {Point} point * @param {number} x * @param {number} y * @return {void} * @method * @public */ -export const execute = (src: Point, x: number, y: number): void => +export const execute = (point: Point, x: number, y: number): void => { - src.x = x; - src.y = y; + point.x = x; + point.y = y; }; \ No newline at end of file diff --git a/packages/geom/src/Point/service/PointSubtractService.ts b/packages/geom/src/Point/service/PointSubtractService.ts index 6be1dc23..38bc67a6 100644 --- a/packages/geom/src/Point/service/PointSubtractService.ts +++ b/packages/geom/src/Point/service/PointSubtractService.ts @@ -4,13 +4,13 @@ import { Point } from "../../Point"; * @description 指定の座標を減算して、新しいポイントを作成 * Subtracts the specified coordinates to create a new point. * - * @param {Point} src - * @param {Point} dst + * @param {Point} point1 + * @param {Point} point2 * @return {Point} * @method * @public */ -export const execute = (src: Point, dst: Point): Point => +export const execute = (point1: Point, point2: Point): Point => { - return new Point(src.x - dst.x, src.y - dst.y); + return new Point(point1.x - point2.x, point1.y - point2.y); }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleCloneService.ts b/packages/geom/src/Rectangle/service/RectangleCloneService.ts index 28fdcfe9..519a59c0 100644 --- a/packages/geom/src/Rectangle/service/RectangleCloneService.ts +++ b/packages/geom/src/Rectangle/service/RectangleCloneService.ts @@ -4,12 +4,12 @@ import { Rectangle } from "../../Rectangle"; * @description 指定のRectangleを複製を返却 * Returns a duplicate of the specified Rectangle * - * @param {Rectangle} src + * @param {Rectangle} rectangle * @return {Rectangle} * @method * @public */ -export const execute = (src: Rectangle): Rectangle => +export const execute = (rectangle: Rectangle): Rectangle => { - return new Rectangle(src.x, src.y, src.width, src.height); + return new Rectangle(rectangle.x, rectangle.y, rectangle.width, rectangle.height); }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleContainsPointService.ts b/packages/geom/src/Rectangle/service/RectangleContainsPointService.ts index 071bb483..cefaa0ee 100644 --- a/packages/geom/src/Rectangle/service/RectangleContainsPointService.ts +++ b/packages/geom/src/Rectangle/service/RectangleContainsPointService.ts @@ -5,16 +5,16 @@ import type { Point } from "../../Point"; * @description 指定の座標がRectangle内に含まれるかを判定 * Determines whether the specified coordinates are within the Rectangle * - * @param {Rectangle} src + * @param {Rectangle} rectangle * @param {Point} point * @return {boolean} * @method * @public */ -export const execute = (src: Rectangle, point: Point): boolean => +export const execute = (rectangle: Rectangle, point: Point): boolean => { - return src.x <= point.x - && src.y <= point.y - && src.right > point.x - && src.bottom > point.y; + return rectangle.x <= point.x + && rectangle.y <= point.y + && rectangle.right > point.x + && rectangle.bottom > point.y; }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleContainsRectService.ts b/packages/geom/src/Rectangle/service/RectangleContainsRectService.ts index 52867754..6c3193c5 100644 --- a/packages/geom/src/Rectangle/service/RectangleContainsRectService.ts +++ b/packages/geom/src/Rectangle/service/RectangleContainsRectService.ts @@ -4,16 +4,16 @@ import type { Rectangle } from "../../Rectangle"; * @description 指定のRectangleがRectangle内に含まれるかを判定 * Determines whether the specified Rectangle is within the Rectangle * - * @param {Rectangle} src - * @param {Rectangle} dst + * @param {Rectangle} rectangle1 + * @param {Rectangle} rectangle2 * @return {boolean} * @method * @public */ -export const execute = (src: Rectangle, dst: Rectangle): boolean => +export const execute = (rectangle1: Rectangle, rectangle2: Rectangle): boolean => { - return src.x <= dst.x - && src.y <= dst.y - && src.right >= dst.right - && src.bottom >= dst.bottom; + return rectangle1.x <= rectangle2.x + && rectangle1.y <= rectangle2.y + && rectangle1.right >= rectangle2.right + && rectangle1.bottom >= rectangle2.bottom; }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleContainsService.ts b/packages/geom/src/Rectangle/service/RectangleContainsService.ts index cc9a1134..9cd5d59c 100644 --- a/packages/geom/src/Rectangle/service/RectangleContainsService.ts +++ b/packages/geom/src/Rectangle/service/RectangleContainsService.ts @@ -4,14 +4,17 @@ import type { Rectangle } from "../../Rectangle"; * @description 指定の座標がRectangle内に含まれるかを判定 * Determines whether the specified coordinates are within the Rectangle * - * @param {Rectangle} src + * @param {Rectangle} rectangle * @param {number} x * @param {number} y * @return {boolean} * @method * @public */ -export const execute = (src: Rectangle, x: number, y: number): boolean => +export const execute = (rectangle: Rectangle, x: number, y: number): boolean => { - return src.x <= x && src.y <= y && src.right > x && src.bottom > y; + return rectangle.x <= x + && rectangle.y <= y + && rectangle.right > x + && rectangle.bottom > y; }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleCopyFromService.ts b/packages/geom/src/Rectangle/service/RectangleCopyFromService.ts index ffb3b2fb..9cb0a8fc 100644 --- a/packages/geom/src/Rectangle/service/RectangleCopyFromService.ts +++ b/packages/geom/src/Rectangle/service/RectangleCopyFromService.ts @@ -4,16 +4,16 @@ import type { Rectangle } from "../../Rectangle"; * @description 指定のRectangleの値をコピー * Copy the value of the specified Rectangle * - * @param {Rectangle} src * @param {Rectangle} dst + * @param {Rectangle} src * @return {void} * @method * @public */ -export const execute = (src: Rectangle, dst: Rectangle): void => +export const execute = (dst: Rectangle, src: Rectangle): void => { - src.x = dst.x; - src.y = dst.y; - src.width = dst.width; - src.height = dst.height; + dst.x = src.x; + dst.y = src.y; + dst.width = src.width; + dst.height = src.height; }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleEqualsService.ts b/packages/geom/src/Rectangle/service/RectangleEqualsService.ts index c4e34936..dbfc4b9e 100644 --- a/packages/geom/src/Rectangle/service/RectangleEqualsService.ts +++ b/packages/geom/src/Rectangle/service/RectangleEqualsService.ts @@ -4,16 +4,16 @@ import type { Rectangle } from "../../Rectangle"; * @description 指定のRectangleが等しいかを判定 * Determines whether the specified Rectangle is equal * - * @param {Rectangle} src + * @param {Rectangle} rectangle1 * @param {Rectangle} dst * @return {boolean} * @method * @public */ -export const execute = (src: Rectangle, dst: Rectangle): boolean => +export const execute = (rectangle1: Rectangle, rectangle2: Rectangle): boolean => { - return src.x === dst.x - && src.y === dst.y - && src.width === dst.width - && src.height === dst.height; + return rectangle1.x === rectangle2.x + && rectangle1.y === rectangle2.y + && rectangle1.width === rectangle2.width + && rectangle1.height === rectangle2.height; }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleInflatePointService.ts b/packages/geom/src/Rectangle/service/RectangleInflatePointService.ts index eed8dcd5..ff920568 100644 --- a/packages/geom/src/Rectangle/service/RectangleInflatePointService.ts +++ b/packages/geom/src/Rectangle/service/RectangleInflatePointService.ts @@ -5,16 +5,16 @@ import type { Rectangle } from "../../Rectangle"; * @description 指定のRectangleの値を変更 * Change the value of the specified Rectangle * - * @param {Rectangle} src + * @param {Rectangle} rectangle * @param {Point} point * @return {void} * @method * @public */ -export const execute = (src: Rectangle, point: Point): void => +export const execute = (rectangle: Rectangle, point: Point): void => { - src.x -= point.x; - src.width += 2 * point.x; - src.y -= point.y; - src.height += 2 * point.y; + rectangle.x -= point.x; + rectangle.width += 2 * point.x; + rectangle.y -= point.y; + rectangle.height += 2 * point.y; }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleInflateService.ts b/packages/geom/src/Rectangle/service/RectangleInflateService.ts index 8cdc9e41..ab6af663 100644 --- a/packages/geom/src/Rectangle/service/RectangleInflateService.ts +++ b/packages/geom/src/Rectangle/service/RectangleInflateService.ts @@ -4,17 +4,17 @@ import type { Rectangle } from "../../Rectangle"; * @description 指定のRectangleの値を変更 * Change the value of the specified Rectangle * - * @param {Rectangle} src + * @param {Rectangle} rectangle * @param {number} dx * @param {number} dy * @return {void} * @method * @public */ -export const execute = (src: Rectangle, dx: number, dy: number): void => +export const execute = (rectangle: Rectangle, dx: number, dy: number): void => { - src.x -= dx; - src.width += 2 * dx; - src.y -= dy; - src.height += 2 * dy; + rectangle.x -= dx; + rectangle.width += 2 * dx; + rectangle.y -= dy; + rectangle.height += 2 * dy; }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleIntersectionService.ts b/packages/geom/src/Rectangle/service/RectangleIntersectionService.ts index 830bd435..9f7e6159 100644 --- a/packages/geom/src/Rectangle/service/RectangleIntersectionService.ts +++ b/packages/geom/src/Rectangle/service/RectangleIntersectionService.ts @@ -4,18 +4,18 @@ import { Rectangle } from "../../Rectangle"; * @description 指定のRectangleの交差部分を取得 * Get the intersection of the specified Rectangle * - * @param {Rectangle} src - * @param {Rectangle} dst + * @param {Rectangle} rectangle1 + * @param {Rectangle} rectangle2 * @return {Rectangle} * @method * @public */ -export const execute = (src: Rectangle, dst: Rectangle): Rectangle => +export const execute = (rectangle1: Rectangle, rectangle2: Rectangle): Rectangle => { - const sx = Math.max(src.x, dst.x); - const sy = Math.max(src.y, dst.y); - const ex = Math.min(src.right, dst.right); - const ey = Math.min(src.bottom, dst.bottom); + const sx = Math.max(rectangle1.x, rectangle2.x); + const sy = Math.max(rectangle1.y, rectangle2.y); + const ex = Math.min(rectangle1.right, rectangle2.right); + const ey = Math.min(rectangle1.bottom, rectangle2.bottom); const w = ex - sx; const h = ey - sy; diff --git a/packages/geom/src/Rectangle/service/RectangleIntersectsService.ts b/packages/geom/src/Rectangle/service/RectangleIntersectsService.ts index 1d03d1a3..37fc4440 100644 --- a/packages/geom/src/Rectangle/service/RectangleIntersectsService.ts +++ b/packages/geom/src/Rectangle/service/RectangleIntersectsService.ts @@ -4,17 +4,17 @@ import type { Rectangle } from "../../Rectangle"; * @description 指定のRectangle同士が重なっているかどうかを判定 * Determine whether the specified Rectangles overlap * - * @param {Rectangle} src - * @param {Rectangle} dst + * @param {Rectangle} rectangle1 + * @param {Rectangle} rectangle2 * @return {boolean} * @method * @public */ -export const execute = (src: Rectangle, dst: Rectangle): boolean => +export const execute = (rectangle1: Rectangle, rectangle2: Rectangle): boolean => { - const sx = Math.max(src.x, dst.x); - const sy = Math.max(src.y, dst.y); - const ex = Math.min(src.right, dst.right); - const ey = Math.min(src.bottom, dst.bottom); + const sx = Math.max(rectangle1.x, rectangle2.x); + const sy = Math.max(rectangle1.y, rectangle2.y); + const ex = Math.min(rectangle1.right, rectangle2.right); + const ey = Math.min(rectangle1.bottom, rectangle2.bottom); return ex - sx > 0 && ey - sy > 0; }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleIsEmptyService.ts b/packages/geom/src/Rectangle/service/RectangleIsEmptyService.ts index c70441ba..15828774 100644 --- a/packages/geom/src/Rectangle/service/RectangleIsEmptyService.ts +++ b/packages/geom/src/Rectangle/service/RectangleIsEmptyService.ts @@ -4,12 +4,12 @@ import type { Rectangle } from "../../Rectangle"; * @description 指定のRectangleが空かどうかを返す * Returns whether the specified Rectangle is empty * - * @param {Rectangle} src + * @param {Rectangle} rectangle * @return {boolean} * @method * @public */ -export const execute = (src: Rectangle): boolean => +export const execute = (rectangle: Rectangle): boolean => { - return src.width <= 0 || src.height <= 0; + return rectangle.width <= 0 || rectangle.height <= 0; }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleOffsetPointService.ts b/packages/geom/src/Rectangle/service/RectangleOffsetPointService.ts index 196651b8..8f9199d8 100644 --- a/packages/geom/src/Rectangle/service/RectangleOffsetPointService.ts +++ b/packages/geom/src/Rectangle/service/RectangleOffsetPointService.ts @@ -5,14 +5,14 @@ import type { Rectangle } from "../../Rectangle"; * @description 矩形を指定された量だけオフセットする。 * Offset the Rectangle by the given amount. * - * @param {Rectangle} src + * @param {Rectangle} rectangle * @param {Point} point * @return {void} * @method * @public */ -export const execute = (src: Rectangle, point: Point): void => +export const execute = (rectangle: Rectangle, point: Point): void => { - src.x += point.x; - src.y += point.y; + rectangle.x += point.x; + rectangle.y += point.y; }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleOffsetService.ts b/packages/geom/src/Rectangle/service/RectangleOffsetService.ts index 8588c56f..3f888823 100644 --- a/packages/geom/src/Rectangle/service/RectangleOffsetService.ts +++ b/packages/geom/src/Rectangle/service/RectangleOffsetService.ts @@ -4,15 +4,15 @@ import type { Rectangle } from "../../Rectangle"; * @description 矩形を指定された量だけオフセットする。 * Offset the Rectangle by the given amount. * - * @param {Rectangle} src + * @param {Rectangle} rectangle * @param {number} dx * @param {number} dy * @return {void} * @method * @public */ -export const execute = (src: Rectangle, dx: number, dy: number): void => +export const execute = (rectangle: Rectangle, dx: number, dy: number): void => { - src.x += dx; - src.y += dy; + rectangle.x += dx; + rectangle.y += dy; }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleSetEmptyService.ts b/packages/geom/src/Rectangle/service/RectangleSetEmptyService.ts index 0b27dff8..089f92ad 100644 --- a/packages/geom/src/Rectangle/service/RectangleSetEmptyService.ts +++ b/packages/geom/src/Rectangle/service/RectangleSetEmptyService.ts @@ -4,12 +4,12 @@ import type { Rectangle } from "../../Rectangle"; * @description 矩形を空にする * Make the rectangle empty * - * @param {Rectangle} src + * @param {Rectangle} rectangle * @return {void} * @method * @public */ -export const execute = (src: Rectangle): void => +export const execute = (rectangle: Rectangle): void => { - src.x = src.y = src.width = src.height = 0; + rectangle.x = rectangle.y = rectangle.width = rectangle.height = 0; }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleSetToService.ts b/packages/geom/src/Rectangle/service/RectangleSetToService.ts index e35b1f6a..1c1ff7f3 100644 --- a/packages/geom/src/Rectangle/service/RectangleSetToService.ts +++ b/packages/geom/src/Rectangle/service/RectangleSetToService.ts @@ -4,7 +4,7 @@ import type { Rectangle } from "../../Rectangle"; * @description 矩形を指定された値に設定する * Set the rectangle to the specified value * - * @param {Rectangle} src + * @param {Rectangle} rectangle * @param {number} x * @param {number} y * @param {number} width @@ -14,14 +14,14 @@ import type { Rectangle } from "../../Rectangle"; * @public */ export const execute = ( - src: Rectangle, + rectangle: Rectangle, x: number, y: number, width: number, height: number ): void => { - src.x = x; - src.y = y; - src.width = width; - src.height = height; + rectangle.x = x; + rectangle.y = y; + rectangle.width = width; + rectangle.height = height; }; \ No newline at end of file diff --git a/packages/geom/src/Rectangle/service/RectangleUnionService.ts b/packages/geom/src/Rectangle/service/RectangleUnionService.ts index c1345b51..bc336c0e 100644 --- a/packages/geom/src/Rectangle/service/RectangleUnionService.ts +++ b/packages/geom/src/Rectangle/service/RectangleUnionService.ts @@ -10,20 +10,20 @@ import { Rectangle } from "../../Rectangle"; * @method * @public */ -export const execute = (src: Rectangle, dst: Rectangle): Rectangle => +export const execute = (rectangle1: Rectangle, rectangle2: Rectangle): Rectangle => { - if (src.isEmpty()) { - return dst.clone(); + if (rectangle1.isEmpty()) { + return rectangle2.clone(); } - if (dst.isEmpty()) { - return src.clone(); + if (rectangle2.isEmpty()) { + return rectangle1.clone(); } return new Rectangle( - Math.min(src.x, dst.x), - Math.min(src.y, dst.y), - Math.max(src.right - dst.left, dst.right - src.left), - Math.max(src.bottom - dst.top, dst.bottom - src.top) + Math.min(rectangle1.x, rectangle2.x), + Math.min(rectangle1.y, rectangle2.y), + Math.max(rectangle1.right - rectangle2.left, rectangle2.right - rectangle1.left), + Math.max(rectangle1.bottom - rectangle2.top, rectangle2.bottom - rectangle1.top) ); }; \ No newline at end of file From 90be08fb0b85c2e68dab9d7f60a9f7cf81d6795b Mon Sep 17 00:00:00 2001 From: ienaga Date: Tue, 23 Jul 2024 13:40:55 +0900 Subject: [PATCH 009/343] =?UTF-8?q?#154=20feat:=20Matrix=E3=82=92=E7=A7=BB?= =?UTF-8?q?=E6=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/next2d/geom/MatrixTest.ts | 2188 +---------------- packages/geom/src/Matrix.ts | 137 +- .../src/Matrix/service/MatirxConcatService.ts | 2 +- .../Matrix/service/MatrixCopyFromService.ts | 2 +- .../service/MatrixCreateBoxService.test.ts | 451 ++++ .../Matrix/service/MatrixCreateBoxService.ts | 27 + .../MatrixCreateGradientBoxService.test.ts | 131 + .../service/MatrixCreateGradientBoxService.ts | 44 + .../MatrixDeltaTransformPointService.test.ts | 254 ++ .../MatrixDeltaTransformPointService.ts | 20 + .../service/MatrixIdentityService.test.ts | 18 + .../Matrix/service/MatrixIdentityService.ts | 20 + .../service/MatrixInvertService.test.ts | 69 + .../src/Matrix/service/MatrixInvertService.ts | 48 + .../service/MatrixRotateService.test.ts | 177 ++ .../src/Matrix/service/MatrixRotateService.ts | 29 + .../Matrix/service/MatrixScaleService.test.ts | 40 + .../src/Matrix/service/MatrixScaleService.ts | 25 + .../Matrix/service/MatrixSetToService.test.ts | 20 + .../src/Matrix/service/MatrixSetToService.ts | 32 + .../MatrixTransformPointService.test.ts | 172 ++ .../service/MatrixTransformPointService.ts | 23 + .../service/MatrixTranslateService.test.ts | 37 + .../Matrix/service/MatrixTranslateService.ts | 18 + 24 files changed, 1696 insertions(+), 2288 deletions(-) create mode 100644 packages/geom/src/Matrix/service/MatrixCreateBoxService.test.ts create mode 100644 packages/geom/src/Matrix/service/MatrixCreateBoxService.ts create mode 100644 packages/geom/src/Matrix/service/MatrixCreateGradientBoxService.test.ts create mode 100644 packages/geom/src/Matrix/service/MatrixCreateGradientBoxService.ts create mode 100644 packages/geom/src/Matrix/service/MatrixDeltaTransformPointService.test.ts create mode 100644 packages/geom/src/Matrix/service/MatrixDeltaTransformPointService.ts create mode 100644 packages/geom/src/Matrix/service/MatrixIdentityService.test.ts create mode 100644 packages/geom/src/Matrix/service/MatrixIdentityService.ts create mode 100644 packages/geom/src/Matrix/service/MatrixInvertService.test.ts create mode 100644 packages/geom/src/Matrix/service/MatrixInvertService.ts create mode 100644 packages/geom/src/Matrix/service/MatrixRotateService.test.ts create mode 100644 packages/geom/src/Matrix/service/MatrixRotateService.ts create mode 100644 packages/geom/src/Matrix/service/MatrixScaleService.test.ts create mode 100644 packages/geom/src/Matrix/service/MatrixScaleService.ts create mode 100644 packages/geom/src/Matrix/service/MatrixSetToService.test.ts create mode 100644 packages/geom/src/Matrix/service/MatrixSetToService.ts create mode 100644 packages/geom/src/Matrix/service/MatrixTransformPointService.test.ts create mode 100644 packages/geom/src/Matrix/service/MatrixTransformPointService.ts create mode 100644 packages/geom/src/Matrix/service/MatrixTranslateService.test.ts create mode 100644 packages/geom/src/Matrix/service/MatrixTranslateService.ts diff --git a/__tests__/next2d/geom/MatrixTest.ts b/__tests__/next2d/geom/MatrixTest.ts index 930b3c15..c85a501f 100644 --- a/__tests__/next2d/geom/MatrixTest.ts +++ b/__tests__/next2d/geom/MatrixTest.ts @@ -5,447 +5,6 @@ import { $SHORT_INT_MIN } from "../../../packages/share/src/RenderUtil"; -describe("Matrix.js toString test", () => -{ - it("toString test1 success", () => - { - const object = new Matrix(); - expect(object.toString()).toBe("(a=1, b=0, c=0, d=1, tx=0, ty=0)"); - }); - - it("toString test2 success", () => - { - const object = new Matrix(2, 3, 4, 5, 6, 7); - expect(object.toString()).toBe("(a=2, b=3, c=4, d=5, tx=6, ty=7)"); - }); -}); - -describe("Matrix.js static toString test", () => -{ - - it("static toString test", () => - { - expect(Matrix.toString()).toBe("[class Matrix]"); - }); - -}); - -describe("Matrix.js namespace test", () => -{ - - it("namespace test public", () => - { - const object = new Matrix(); - expect(object.namespace).toBe("next2d.geom.Matrix"); - }); - - it("namespace test static", () => - { - expect(Matrix.namespace).toBe("next2d.geom.Matrix"); - }); - -}); - - - - - -describe("Matrix.js rotate test", () => -{ - it("rotate test1", () => - { - let m = new Matrix(1, 0, 0, 1, 100, 110); - m.rotate(45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=0.7071067690849304, b=0.7071067690849304, c=-0.7071067690849304, d=0.7071067690849304, tx=-7.071067810058594, ty=148.492431640625)" - ); - }); - - it("rotate test2", () => - { - let m = new Matrix(1, 0, 0, -1, 100, 110); - m.rotate(45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=0.7071067690849304, b=0.7071067690849304, c=0.7071067690849304, d=-0.7071067690849304, tx=-7.071067810058594, ty=148.492431640625)" - ); - }); - - it("rotate test3", () => - { - let m = new Matrix(-1, 0, 0, 1, 100, 110); - m.rotate(45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=-0.7071067690849304, b=-0.7071067690849304, c=-0.7071067690849304, d=0.7071067690849304, tx=-7.071067810058594, ty=148.492431640625)" - ); - }); - - it("rotate test4", () => - { - let m = new Matrix(-1, 0, 0, -1, 100, 110); - m.rotate(45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=-0.7071067690849304, b=-0.7071067690849304, c=0.7071067690849304, d=-0.7071067690849304, tx=-7.071067810058594, ty=148.492431640625)" - ); - }); - - it("rotate test5", () => - { - let m = new Matrix(1, 10, 10, 1, 100, 110); - m.rotate(45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=-6.363961219787598, b=7.77817440032959, c=6.363961219787598, d=7.77817440032959, tx=-7.071067810058594, ty=148.492431640625)" - ); - }); - - it("rotate test6", () => - { - let m = new Matrix(1, -10, 10, 1, 100, 110); - m.rotate(45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=7.77817440032959, b=-6.363961219787598, c=6.363961219787598, d=7.77817440032959, tx=-7.071067810058594, ty=148.492431640625)" - ); - }); - - it("rotate test7", () => - { - let m = new Matrix(1, 10, -10, 1, 100, 110); - m.rotate(45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=-6.363961219787598, b=7.77817440032959, c=-7.77817440032959, d=-6.363961219787598, tx=-7.071067810058594, ty=148.492431640625)" - ); - }); - - it("rotate test8", () => - { - let m = new Matrix(1, 10, 10, 1, -100, 110); - m.rotate(45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=-6.363961219787598, b=7.77817440032959, c=6.363961219787598, d=7.77817440032959, tx=-148.492431640625, ty=7.071067810058594)" - ); - }); - - it("rotate test9", () => - { - let m = new Matrix(1, 10, 10, 1, 100, -110); - m.rotate(45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=-6.363961219787598, b=7.77817440032959, c=6.363961219787598, d=7.77817440032959, tx=148.492431640625, ty=-7.071067810058594)" - ); - }); - - it("rotate test10", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - m.rotate(45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=6.363961219787598, b=-7.77817440032959, c=-6.363961219787598, d=-7.77817440032959, tx=7.071067810058594, ty=-148.492431640625)" - ); - }); - - it("rotate test11", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - m.rotate(0.5); - expect(m.toString()).toBe( - "(a=3.916672706604004, b=-9.255250930786133, c=-8.29640007019043, d=-5.67183780670166, tx=-35.021446228027344, ty=-144.4766387939453)" - ); - }); - - it("rotate test12", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - m.rotate(-0.5); - expect(m.toString()).toBe( - "(a=-5.67183780670166, b=-8.29640007019043, c=-9.255250930786133, d=3.916672706604004, tx=-140.4950714111328, ty=-48.591529846191406)" - ); - }); - - it("rotate test13", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - m.rotate(90 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=10, b=-1, c=1, d=-10, tx=110, ty=-100)" - ); - }); - - it("rotate test14", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - m.rotate(135 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=7.77817440032959, b=6.363961219787598, c=7.77817440032959, d=-6.363961219787598, tx=148.492431640625, ty=7.071067810058594)" - ); - }); - - it("rotate test15", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - m.rotate(Math.PI); - expect(m.toString()).toBe( - "(a=1, b=10, c=10, d=1, tx=100, ty=110)" - ); - }); - - it("rotate test16", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - m.rotate(-45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=-7.77817440032959, b=-6.363961219787598, c=-7.77817440032959, d=6.363961219787598, tx=-148.492431640625, ty=-7.071067810058594)" - ); - }); - - it("rotate test17", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - m.rotate(-90 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=-10, b=1, c=-1, d=10, tx=-110, ty=100)" - ); - }); - - it("rotate test18", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - m.rotate(-135 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=-6.363961219787598, b=7.77817440032959, c=6.363961219787598, d=7.77817440032959, tx=-7.071067810058594, ty=148.492431640625)" - ); - }); - - it("rotate test19", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - m.rotate(-1 * Math.PI); - expect(m.toString()).toBe( - "(a=1, b=10, c=10, d=1, tx=100, ty=110)" - ); - }); - - it("rotate test20", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - // @ts-ignore - m.rotate("a"); - expect(m.toString()).toBe( - "(a=0, b=0, c=0, d=0, tx=0, ty=0)" - ); - }); - - it("rotate test21", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - // @ts-ignore - m.a = "a"; - m.rotate(45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=7.071067810058594, b=-7.071067810058594, c=-6.363961219787598, d=-7.77817440032959, tx=7.071067810058594, ty=-148.492431640625)" - ); - }); - - it("rotate test22", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - // @ts-ignore - m.c = "a"; - m.rotate(45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=6.363961219787598, b=-7.77817440032959, c=0.7071067690849304, d=-0.7071067690849304, tx=7.071067810058594, ty=-148.492431640625)" - ); - }); - - it("rotate test23", () => - { - let m = new Matrix(-1, -10, -10, -1, -100, -110); - // @ts-ignore - m.tx = "a"; - m.rotate(45 / 180 * Math.PI); - expect(m.toString()).toBe( - "(a=6.363961219787598, b=-7.77817440032959, c=-6.363961219787598, d=-7.77817440032959, tx=77.78174591064453, ty=-77.78174591064453)" - ); - }); -}); - -describe("Matrix.js createGradientBox test", () => -{ - it("createGradientBox test1", () => - { - let m = new Matrix(); - m.createGradientBox(1, 0, 9, 0, 0); - expect(m.toString()).toBe( - "(a=-0.0005561097641475499, b=0, c=-0.0002515371597837657, d=0, tx=0.5, ty=0)" - ); - }); - - it("createGradientBox test2", () => - { - let m = new Matrix(); - m.createGradientBox(1, 1, 9, 0, 0); - expect(m.toString()).toBe( - "(a=-0.0005561097641475499, b=0.0002515371597837657, c=-0.0002515371597837657, d=-0.0005561097641475499, tx=0.5, ty=0.5)" - ); - }); - - it("createGradientBox test3", () => - { - let m = new Matrix(); - m.createGradientBox(1, 0, 9, 1, 0); - expect(m.toString()).toBe( - "(a=-0.0005561097641475499, b=0, c=-0.0002515371597837657, d=0, tx=1.5, ty=0)" - ); - }); - - it("createGradientBox test4", () => - { - let m = new Matrix(); - m.createGradientBox(1, 0, 9, 0, 1); - expect(m.toString()).toBe( - "(a=-0.0005561097641475499, b=0, c=-0.0002515371597837657, d=0, tx=0.5, ty=1)" - ); - }); - - it("createGradientBox test5", () => - { - let m = new Matrix(); - m.createGradientBox(1, 1, 9, 1, 1); - expect(m.toString()).toBe( - "(a=-0.0005561097641475499, b=0.0002515371597837657, c=-0.0002515371597837657, d=-0.0005561097641475499, tx=1.5, ty=1.5)" - ); - }); - - it("createGradientBox test6", () => - { - let m = new Matrix(); - m.createGradientBox(-1, -1, -9, -1, -1); - expect(m.toString()).toBe( - "(a=0.0005561097641475499, b=0.0002515371597837657, c=-0.0002515371597837657, d=0.0005561097641475499, tx=-1.5, ty=-1.5)" - ); - }); - - it("createGradientBox test7", () => - { - let m = new Matrix(); - // @ts-ignore - m.createGradientBox("a", -1, -9, -1, -1); - expect(m.toString()).toBe( - "(a=0, b=0.0002515371597837657, c=0, d=0.0005561097641475499, tx=0, ty=-1.5)" - ); - }); - - it("createGradientBox test8", () => - { - let m = new Matrix(); - // @ts-ignore - m.createGradientBox(-1, "a", -9, -1, -1); - expect(m.toString()).toBe( - "(a=0.0005561097641475499, b=0, c=-0.0002515371597837657, d=0, tx=-1.5, ty=0)" - ); - }); - - it("createGradientBox test9", () => - { - let m = new Matrix(); - // @ts-ignore - m.createGradientBox(-1, -1, "a", -1, -1); - expect(m.toString()).toBe( - "(a=0, b=0, c=0, d=0, tx=-1.5, ty=-1.5)" - ); - }); - - it("createGradientBox test10", () => - { - let m = new Matrix(); - // @ts-ignore - m.createGradientBox(-1, -1, -9, "a", -1); - expect(m.toString()).toBe( - "(a=0.0005561097641475499, b=0.0002515371597837657, c=-0.0002515371597837657, d=0.0005561097641475499, tx=0, ty=-1.5)" - ); - }); - - it("createGradientBox test11", () => - { - let m = new Matrix(); - // @ts-ignore - m.createGradientBox(-1, -1, -9, -1, "a"); - expect(m.toString()).toBe( - "(a=0.0005561097641475499, b=0.0002515371597837657, c=-0.0002515371597837657, d=0.0005561097641475499, tx=-1.5, ty=0)" - ); - }); - - it("createGradientBox test12", () => - { - let m = new Matrix(); - m.createGradientBox(1, 1, 45 / 180 * Math.PI, 1, 1); - expect(m.toString()).toBe( - "(a=0.0004315837286412716, b=0.0004315837286412716, c=-0.0004315837286412716, d=0.0004315837286412716, tx=1.5, ty=1.5)" - ); - }); - - it("createGradientBox test13", () => - { - let m = new Matrix(); - m.createGradientBox(1, 1, 90 / 180 * Math.PI, 1, 1); - expect(m.toString()).toBe( - "(a=3.7373254383716084e-20, b=0.0006103515625, c=-0.0006103515625, d=3.7373254383716084e-20, tx=1.5, ty=1.5)" - ); - }); - - it("createGradientBox test14", () => - { - let m = new Matrix(); - m.createGradientBox(1, 1, 135 / 180 * Math.PI, 1, 1); - expect(m.toString()).toBe( - "(a=-0.0004315837286412716, b=0.0004315837286412716, c=-0.0004315837286412716, d=-0.0004315837286412716, tx=1.5, ty=1.5)" - ); - }); - - it("createGradientBox test15", () => - { - let m = new Matrix(); - m.createGradientBox(1, 1, 180 / 180 * Math.PI, 1, 1); - expect(m.toString()).toBe( - "(a=-0.0006103515625, b=7.474650876743217e-20, c=-7.474650876743217e-20, d=-0.0006103515625, tx=1.5, ty=1.5)" - ); - }); - - it("createGradientBox test16", () => - { - let m = new Matrix(); - m.createGradientBox(1, 1, -45 / 180 * Math.PI, 1, 1); - expect(m.toString()).toBe( - "(a=0.0004315837286412716, b=-0.0004315837286412716, c=0.0004315837286412716, d=0.0004315837286412716, tx=1.5, ty=1.5)" - ); - }); - - it("createGradientBox test17", () => - { - let m = new Matrix(); - m.createGradientBox(1, 1, -90 / 180 * Math.PI, 1, 1); - expect(m.toString()).toBe( - "(a=3.7373254383716084e-20, b=-0.0006103515625, c=0.0006103515625, d=3.7373254383716084e-20, tx=1.5, ty=1.5)" - ); - }); - - it("createGradientBox test18", () => - { - let m = new Matrix(); - m.createGradientBox(1, 1, -135 / 180 * Math.PI, 1, 1); - expect(m.toString()).toBe( - "(a=-0.0004315837286412716, b=-0.0004315837286412716, c=0.0004315837286412716, d=-0.0004315837286412716, tx=1.5, ty=1.5)" - ); - }); - - it("createGradientBox test19", () => - { - let m = new Matrix(); - m.createGradientBox(1, 1, -180 / 180 * Math.PI, 1, 1); - expect(m.toString()).toBe( - "(a=-0.0006103515625, b=-7.474650876743217e-20, c=7.474650876743217e-20, d=-0.0006103515625, tx=1.5, ty=1.5)" - ); - }); -}); - describe("Matrix.js createBox test", () => { it("createBox test1", () => @@ -988,1714 +547,29 @@ describe("Matrix.js createBox test", () => }); }); -describe("Matrix.js invert test", () => -{ - it("invert test1", () => - { - let m = new Matrix(2, 1, 1, 2, -200, -200); - m.invert(); - expect(m.toString()).toBe( - "(a=0.6666666865348816, b=-0.3333333432674408, c=-0.3333333432674408, d=0.6666666865348816, tx=66.66667175292969, ty=66.66667175292969)" - ); - }); - - it("invert test2", () => - { - let m = new Matrix(2, 1, 1, 2, -200, -200); - m.invert(); - m.invert(); - expect(m.toString()).toBe( - "(a=2, b=1, c=1, d=2, tx=-200.00001525878906, ty=-200.00001525878906)" - ); - }); - - it("invert test3", () => - { - let m = new Matrix(-2, 1, 1, 2, -200, -200); - m.invert(); - expect(m.toString()).toBe( - "(a=-0.4000000059604645, b=0.20000000298023224, c=0.20000000298023224, d=0.4000000059604645, tx=-40, ty=120)" - ); - }); - - it("invert test4", () => - { - let m = new Matrix(2, -1, 1, 2, -200, -200); - m.invert(); - expect(m.toString()).toBe( - "(a=0.4000000059604645, b=0.20000000298023224, c=-0.20000000298023224, d=0.4000000059604645, tx=40, ty=120)" - ); - }); - - it("invert test5", () => - { - let m = new Matrix(2, 1, -1, 2, -200, -200); - m.invert(); - expect(m.toString()).toBe( - "(a=0.4000000059604645, b=-0.20000000298023224, c=0.20000000298023224, d=0.4000000059604645, tx=120, ty=40)" - ); - }); - - it("invert test6", () => - { - let m = new Matrix(2, 1, 1, -2, -200, -200); - m.invert(); - expect(m.toString()).toBe( - "(a=0.4000000059604645, b=0.20000000298023224, c=0.20000000298023224, d=-0.4000000059604645, tx=120, ty=-40)" - ); - }); - - it("invert test7", () => - { - let m = new Matrix(-2, -1, -1, -2, -200, -200); - m.invert(); - expect(m.toString()).toBe( - "(a=-0.6666666865348816, b=0.3333333432674408, c=0.3333333432674408, d=-0.6666666865348816, tx=-66.66667175292969, ty=-66.66667175292969)" - ); - }); - - it("invert test8", () => - { - // @ts-ignore - let m = new Matrix("a", -1, -1, -2, -200, -200); - m.invert(); - expect(m.toString()).toBe( - "(a=2, b=-1, c=-1, d=0, tx=200, ty=-200)" - ); - }); -}); - -describe("Matrix.js transformPoint test", () => -{ - it("transformPoint test1", () => - { - let m = new Matrix(1, 0, 0, 1, 100, 110); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-19.79898965358734, y=164.04878056049347)" - ); - }); - - it("transformPoint test2", () => - { - let m = new Matrix(1, 1, 0, 1, 100, 110); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-21.213203191757202, y=165.46299409866333)" - ); - }); - - it("transformPoint test3", () => - { - let m = new Matrix(1, 0, 1, 1, 100, 110); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.x | 0).toBe(-5); - expect(p2.y | 0).toBe(178); - - }); - - it("transformPoint test4", () => - { - let m = new Matrix(1, 1, 1, 1, 100, 110); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.x | 0).toBe(-7); - expect(p2.y | 0).toBe(179); - }); - - it("transformPoint test5", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.x | 0).toBe(-7); - expect(p2.y | 0).toBe(117); - }); - - it("transformPoint test6", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - // @ts-ignore - m.rotate("a"); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.toString()).toBe( - "(x=0, y=0)" - ); - }); - - it("transformPoint test7", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - // @ts-ignore - m.a = "a"; - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.x | 0).toBe(-5); - expect(p2.y | 0).toBe(118); - }); - - it("transformPoint test8", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - // @ts-ignore - m.c = "a"; - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.toString()).toBe( - "(x=7.071067571640015, y=131.52186918258667)" - ); - }); - - it("transformPoint test9", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - // @ts-ignore - m.tx = "a"; - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-77.78174591064453, y=46.66904807090759)" - ); - }); - - it("transformPoint test10", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - // @ts-ignore - p1.x = "a"; - let p2 = m.transformPoint(p1); - - expect(p2.x | 0).toBe(-7); - expect(p2.y | 0).toBe(120); - }); - - it("transformPoint test11", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.x | 0).toBe(-7); - expect(p2.y | 0).toBe(117); - }); - - it("transformPoint test12", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - m.rotate(90 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-88, y=78)" - ); - }); - - it("transformPoint test13", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - m.rotate(135 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-117.37973380088806, y=-7.071067810058596)" - ); - }); - - it("transformPoint test14", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - m.rotate(180 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-78, y=-88)" - ); - }); - - it("transformPoint test15", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - m.rotate(-45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.x | 0).toBe(117); - expect(p2.y | 0).toBe(7); - - }); - - it("transformPoint test16", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - m.rotate(-90 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.toString()).toBe( - "(x=88, y=-78)" - ); - }); - - it("transformPoint test17", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - m.rotate(-135 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.toString()).toBe( - "(x=7.071067810058591, y=-117.37973380088806)" - ); - }); - - it("transformPoint test18", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - m.rotate(-180 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.transformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-78, y=-88)" - ); - }); -}); - -describe("Matrix.js deltaTransformPoint test", () => -{ - it("deltaTransformPoint test1", () => - { - let m = new Matrix(1, 0, 0, 1, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-12.727921843528748, y=15.55634891986847)" - ); - }); - - it("deltaTransformPoint test2", () => - { - let m = new Matrix(10, 0, 0, 1, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=2.384185791015625e-7, y=28.284271001815796)" - ); - }); - - it("deltaTransformPoint test3", () => - { - let m = new Matrix(1, 10, 0, 1, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.x | 0).toBe(-26); - expect(p2.y | 0).toBe(29); - }); - - it("deltaTransformPoint test4", () => - { - let m = new Matrix(1, 0, 10, 1, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=128.6934379339218, y=156.97770154476166)" - ); - }); - - it("deltaTransformPoint test5", () => - { - let m = new Matrix(1, 0, 0, 10, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-140.007142663002, y=142.83556973934174)" - ); - }); - - it("deltaTransformPoint test6", () => - { - let m = new Matrix(-1, 0, 0, 1, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-15.55634891986847, y=12.727921843528748)" - ); - }); - - it("deltaTransformPoint test7", () => - { - let m = new Matrix(1, 0, 0, -1, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=15.55634891986847, y=-12.727921843528748)" - ); - }); - - it("deltaTransformPoint test8", () => - { - let m = new Matrix(-1, 0, 0, -1, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=12.727921843528748, y=-15.55634891986847)" - ); - }); - - it("deltaTransformPoint test9", () => - { - let m = new Matrix(-1, -1, 0, -1, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=14.142135381698608, y=-16.97056245803833)" - ); - }); - - it("deltaTransformPoint test10", () => - { - let m = new Matrix(-1, 0, -1, -1, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.x | 0).toBe(-1); - expect(p2.y | 0).toBe(-29); - }); - - it("deltaTransformPoint test11", () => - { - let m = new Matrix(-1, -1, -1, -1, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.x | 0).toBe(0); - expect(p2.y | 0).toBe(-31); - }); - - it("deltaTransformPoint test12", () => - { - // @ts-ignore - let m = new Matrix("a", 1, 1, 1, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.x | 0).toBe(-1); - expect(p2.y | 0).toBe(29); - - }); - - it("deltaTransformPoint test13", () => - { - let m = new Matrix(1, 1, 1, 1, 100, 110); - // @ts-ignore - m.translate("a", 0); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.x | 0).toBe(0); - expect(p2.y | 0).toBe(31); - }); - - it("deltaTransformPoint test14", () => - { - let m = new Matrix(1, 1, 1, 1, 100, 110); - // @ts-ignore - m.translate(10, "a"); - m.rotate(45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.x | 0).toBe(0); - expect(p2.y | 0).toBe(31); - }); - - it("deltaTransformPoint test15", () => - { - let m = new Matrix(1, 1, 1, 1, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - // @ts-ignore - let p1 = new Point("a", 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.x | 0).toBe(0); - expect(p2.y | 0).toBe(28); - }); - - it("deltaTransformPoint test16", () => - { - let m = new Matrix(1, 1, 1, 1, 100, 110); - m.translate(10, 0); - m.rotate(45 / 180 * Math.PI); - - // @ts-ignore - let p1 = new Point(2, "a"); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.x | 0).toBe(0); - expect(p2.y | 0).toBe(2); - }); - - it("deltaTransformPoint test17", () => - { - let m = new Matrix(1, 1, 1, 1, 100, 110); - m.translate(10, 0); - - // @ts-ignore - m.rotate("a"); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=0, y=0)" - ); - }); - - it("deltaTransformPoint test18", () => - { - let m = new Matrix(1, 1, 1, 1, 100, 110); - m.translate(10, 0); - m.rotate(90 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-22, y=22)" - ); - }); - - it("deltaTransformPoint test19", () => - { - let m = new Matrix(1, 1, 1, 1, 100, 110); - m.translate(10, 0); - m.rotate(135 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-31.11269783973694, y=2.4424906541753444e-15)" - ); - }); - - it("deltaTransformPoint test20", () => - { - let m = new Matrix(1, 1, 1, 1, 100, 110); - m.translate(10, 0); - m.rotate(180 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-22, y=-22)" - ); - }); - - it("deltaTransformPoint test21", () => - { - let m = new Matrix(1, 1, 1, 1, 100, 110); - m.translate(10, 0); - m.rotate(-45 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.x | 0).toBe(31); - expect(p2.y | 0).toBe(0); - }); - - it("deltaTransformPoint test22", () => - { - let m = new Matrix(1, 1, 1, 1, 100, 110); - m.translate(10, 0); - m.rotate(-90 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=22, y=-22)" - ); - }); - - it("deltaTransformPoint test23", () => - { - let m = new Matrix(1, 1, 1, 1, 100, 110); - m.translate(10, 0); - m.rotate(-135 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.x | 0).toBe(0); - expect(p2.y | 0).toBe(-31); - - }); - - it("deltaTransformPoint test24", () => - { - let m = new Matrix(1, 1, 1, 1, 100, 110); - m.translate(10, 0); - m.rotate(-180 / 180 * Math.PI); - - let p1 = new Point(2, 20); - let p2 = m.deltaTransformPoint(p1); - - expect(p2.toString()).toBe( - "(x=-22, y=-22)" - ); - }); -}); - -describe("Matrix.js pattern test", () => -{ - - it("pattern test case1", () => - { - let matrix = new Matrix(); - - // 単位行列化 - matrix.identity(); - // 拡大縮小成分を乗算 - matrix.scale( 256 / 1638.4 , 256 / 1638.4 ); - // 角度成分を乗算 - matrix.rotate(Math.PI / 180); - // 移動成分を乗算 - matrix.translate( 128.0 , 128.0 ); - - expect(matrix.toString()).toBe("(a=0.15622620284557343, b=0.0027269385755062103, c=-0.0027269385755062103, d=0.15622620284557343, tx=128, ty=128)"); - }); - -}); - -describe("Matrix.js scale test", () => -{ - - it("scale test case1", () => - { - let matrix = new Matrix(1, 0.5, -0.5, 1, 0, 0); - matrix.scale(2, 2); - expect(matrix.toString()).toBe("(a=2, b=1, c=-1, d=2, tx=0, ty=0)"); - }); - - it("scale test case2", () => - { - let matrix = new Matrix(1, 0.5, -0.5, 1, 0, 0); - matrix.scale(2, 3); - expect(matrix.toString()).toBe("(a=2, b=1.5, c=-1, d=3, tx=0, ty=0)"); - }); - - it("scale test case3", () => - { - let matrix = new Matrix(1, 0.5, -0.5, 1, 0, 0); - matrix.scale(3, 2); - expect(matrix.toString()).toBe("(a=3, b=1, c=-1.5, d=2, tx=0, ty=0)"); - }); - - it("scale test case4", () => - { - let matrix = new Matrix(1, 0.5, -0.5, 1, 10, 0); - matrix.scale(-1, 2); - expect(matrix.toString()).toBe("(a=-1, b=1, c=0.5, d=2, tx=-10, ty=0)"); - }); - - it("scale test case5", () => - { - let matrix = new Matrix(1, 0.5, -0.5, 1, 0, 10); - matrix.scale(3, -2); - expect(matrix.toString()).toBe("(a=3, b=-1, c=-1.5, d=-2, tx=0, ty=-20)"); - }); - - it("scale test case6", () => - { - let matrix = new Matrix(1, 0.5, -0.5, 1, 0, 10); - // @ts-ignore - matrix.scale("a", 2); - expect(matrix.toString()).toBe("(a=0, b=1, c=0, d=2, tx=0, ty=20)"); - }); - -}); - -describe("Matrix.js a test", () => -{ - - it("default test case1", () => - { - let m = new Matrix(); - expect(m.a).toBe(1); - }); - - it("default test case2", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = null; - expect(m.a).toBe(0); - }); - - it("default test case3", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = undefined; - expect(m.a).toBe(0); - }); - - it("default test case4", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = true; - expect(m.a).toBe(1); - }); - - it("default test case5", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = ""; - expect(m.a).toBe(0); - }); - - it("default test case6", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = "abc"; - expect(m.a).toBe(0); - }); - - it("default test case7", () => - { - let m = new Matrix(); - m.a = 0; - expect(m.a).toBe(0); - }); - - it("default test case8", () => - { - let m = new Matrix(); - m.a = 1; - expect(m.a).toBe(1); - }); - - it("default test case9", () => - { - let m = new Matrix(); - m.a = 500; - expect(m.a).toBe(500); - }); - - it("default test case10", () => - { - let m = new Matrix(); - m.a = 50000000000000000; - expect(m.a).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let m = new Matrix(); - m.a = -1; - expect(m.a).toBe(-1); - }); - - it("default test case12", () => - { - let m = new Matrix(); - m.a = -500; - expect(m.a).toBe(-500); - }); - - it("default test case13", () => - { - let m = new Matrix(); - m.a = -50000000000000000; - expect(m.a).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = { "a":0 }; - expect(m.a).toBe(0); - }); - - it("default test case15", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = function a() {}; - expect(m.a).toBe(0); - }); - - it("default test case16", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = [1]; - expect(m.a).toBe(1); - }); - - it("default test case17", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = [1,2]; - expect(m.a).toBe(0); - }); - - it("default test case18", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = {}; - expect(m.a).toBe(0); - }); - - it("default test case19", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = { "toString":function () { return 1 } }; - expect(m.a).toBe(1); - }); - - it("default test case20", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = { "toString":function () { return "1" } }; - expect(m.a).toBe(1); - }); - - it("default test case21", () => - { - let m = new Matrix(); - // @ts-ignore - m.a = { "toString":function () { return "1a" } }; - expect(m.a).toBe(0); - }); - -}); - -describe("Matrix.js b test", () => -{ - - it("default test case1", () => - { - let m = new Matrix(); - expect(m.b).toBe(0); - }); - - it("default test case2", () => - { - let m = new Matrix(); - // @ts-ignore - m.b = null; - expect(m.b).toBe(0); - }); - - it("default test case3", () => - { - let m = new Matrix(); - // @ts-ignore - m.b = undefined; - expect(m.b).toBe(0); - }); - - it("default test case4", () => - { - let m = new Matrix(); - // @ts-ignore - m.b = true; - expect(m.b).toBe(1); - }); - - it("default test case5", () => - { - let m = new Matrix(); - // @ts-ignore - m.b = ""; - expect(m.b).toBe(0); - }); - - it("default test case6", () => - { - let m = new Matrix(); - // @ts-ignore - m.b = "abc"; - expect(m.b).toBe(0); - }); - - it("default test case7", () => - { - let m = new Matrix(); - m.b = 0; - expect(m.b).toBe(0); - }); - - it("default test case8", () => - { - let m = new Matrix(); - m.b = 1; - expect(m.b).toBe(1); - }); - - it("default test case9", () => - { - let m = new Matrix(); - m.b = 500; - expect(m.b).toBe(500); - }); - - it("default test case10", () => - { - let m = new Matrix(); - m.b = 50000000000000000; - expect(m.b).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let m = new Matrix(); - m.b = -1; - expect(m.b).toBe(-1); - }); - - it("default test case12", () => - { - let m = new Matrix(); - m.b = -500; - expect(m.b).toBe(-500); - }); - - it("default test case13", () => - { - let m = new Matrix(); - m.b = -50000000000000000; - expect(m.b).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let m = new Matrix(); - // @ts-ignore - m.b = { "a":0 }; - expect(m.b).toBe(0); - }); - - it("default test case15", () => - { - let m = new Matrix(); - // @ts-ignore - m.b = function a() {}; - expect(m.b).toBe(0); - }); - - it("default test case16", () => - { - let m = new Matrix(); - // @ts-ignore - m.b = [1]; - expect(m.b).toBe(1); - }); - - it("default test case17", () => - { - let m = new Matrix(); - // @ts-ignore - m.b = [1,2]; - expect(m.b).toBe(0); - }); - - it("default test case18", () => - { - let m = new Matrix(); - // @ts-ignore - m.b = {}; - expect(m.b).toBe(0); - }); - - it("default test case19", () => - { - let m = new Matrix(); - // @ts-ignore - m.b = { "toString":function () { return 1 } }; - expect(m.b).toBe(1); - }); - - it("default test case20", () => - { - let m = new Matrix(); - // @ts-ignore - m.b = { "toString":function () { return "1" } }; - expect(m.b).toBe(1); - }); - - it("default test case21", () => - { - let m = new Matrix(); - // @ts-ignore - m.b = { "toString":function () { return "1a" } }; - expect(m.b).toBe(0); - }); - -}); - -describe("Matrix.js c test", () => -{ - - it("default test case1", () => - { - let m = new Matrix(); - expect(m.c).toBe(0); - }); - - it("default test case2", () => - { - let m = new Matrix(); - // @ts-ignore - m.c = null; - expect(m.c).toBe(0); - }); - - it("default test case3", () => - { - let m = new Matrix(); - // @ts-ignore - m.c = undefined; - expect(m.c).toBe(0); - }); - - it("default test case4", () => - { - let m = new Matrix(); - // @ts-ignore - m.c = true; - expect(m.c).toBe(1); - }); - - it("default test case5", () => - { - let m = new Matrix(); - // @ts-ignore - m.c = ""; - expect(m.c).toBe(0); - }); - - it("default test case6", () => - { - let m = new Matrix(); - // @ts-ignore - m.c = "abc"; - expect(m.c).toBe(0); - }); - - it("default test case7", () => - { - let m = new Matrix(); - m.c = 0; - expect(m.c).toBe(0); - }); - - it("default test case8", () => - { - let m = new Matrix(); - m.c = 1; - expect(m.c).toBe(1); - }); - - it("default test case9", () => - { - let m = new Matrix(); - m.c = 500; - expect(m.c).toBe(500); - }); - - it("default test case10", () => - { - let m = new Matrix(); - m.c = 50000000000000000; - expect(m.c).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let m = new Matrix(); - m.c = -1; - expect(m.c).toBe(-1); - }); - - it("default test case12", () => - { - let m = new Matrix(); - m.c = -500; - expect(m.c).toBe(-500); - }); - - it("default test case13", () => - { - let m = new Matrix(); - m.c = -50000000000000000; - expect(m.c).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let m = new Matrix(); - // @ts-ignore - m.c = { "a":0 }; - expect(m.c).toBe(0); - }); - - it("default test case15", () => - { - let m = new Matrix(); - // @ts-ignore - m.c = function a() {}; - expect(m.c).toBe(0); - }); - - it("default test case16", () => - { - let m = new Matrix(); - // @ts-ignore - m.c = [1]; - expect(m.c).toBe(1); - }); - - it("default test case17", () => - { - let m = new Matrix(); - // @ts-ignore - m.c = [1,2]; - expect(m.c).toBe(0); - }); - - it("default test case18", () => - { - let m = new Matrix(); - // @ts-ignore - m.c = {}; - expect(m.c).toBe(0); - }); - - it("default test case19", () => - { - let m = new Matrix(); - // @ts-ignore - m.c = { "toString":function () { return 1 } }; - expect(m.c).toBe(1); - }); - - it("default test case20", () => - { - let m = new Matrix(); - // @ts-ignore - m.c = { "toString":function () { return "1" } }; - expect(m.c).toBe(1); - }); - - it("default test case21", () => - { - let m = new Matrix(); - // @ts-ignore - m.c = { "toString":function () { return "1a" } }; - expect(m.c).toBe(0); - }); - -}); - -describe("Matrix.js d test", () => -{ - - it("default test case1", () => - { - let m = new Matrix(); - expect(m.d).toBe(1); - }); - - it("default test case2", () => - { - let m = new Matrix(); - // @ts-ignore - m.d = null; - expect(m.d).toBe(0); - }); - - it("default test case3", () => - { - let m = new Matrix(); - // @ts-ignore - m.d = undefined; - expect(m.d).toBe(0); - }); - - it("default test case4", () => - { - let m = new Matrix(); - // @ts-ignore - m.d = true; - expect(m.d).toBe(1); - }); - - it("default test case5", () => - { - let m = new Matrix(); - // @ts-ignore - m.d = ""; - expect(m.d).toBe(0); - }); - - it("default test case6", () => - { - let m = new Matrix(); - // @ts-ignore - m.d = "abc"; - expect(m.d).toBe(0); - }); - - it("default test case7", () => - { - let m = new Matrix(); - m.d = 0; - expect(m.d).toBe(0); - }); - - it("default test case8", () => - { - let m = new Matrix(); - m.d = 1; - expect(m.d).toBe(1); - }); - - it("default test case9", () => - { - let m = new Matrix(); - m.d = 500; - expect(m.d).toBe(500); - }); - - it("default test case10", () => - { - let m = new Matrix(); - m.d = 50000000000000000; - expect(m.d).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let m = new Matrix(); - m.d = -1; - expect(m.d).toBe(-1); - }); - - it("default test case12", () => - { - let m = new Matrix(); - m.d = -500; - expect(m.d).toBe(-500); - }); - - it("default test case13", () => - { - let m = new Matrix(); - m.d = -50000000000000000; - expect(m.d).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let m = new Matrix(); - // @ts-ignore - m.d = { "a":0 }; - expect(m.d).toBe(0); - }); - - it("default test case15", () => - { - let m = new Matrix(); - // @ts-ignore - m.d = function a() {}; - expect(m.d).toBe(0); - }); - - it("default test case16", () => - { - let m = new Matrix(); - // @ts-ignore - m.d = [1]; - expect(m.d).toBe(1); - }); - - it("default test case17", () => - { - let m = new Matrix(); - // @ts-ignore - m.d = [1,2]; - expect(m.d).toBe(0); - }); - - it("default test case18", () => - { - let m = new Matrix(); - // @ts-ignore - m.d = {}; - expect(m.d).toBe(0); - }); - - it("default test case19", () => - { - let m = new Matrix(); - // @ts-ignore - m.d = { "toString":function () { return 1 } }; - expect(m.d).toBe(1); - }); - - it("default test case20", () => - { - let m = new Matrix(); - // @ts-ignore - m.d = { "toString":function () { return "1" } }; - expect(m.d).toBe(1); - }); - it("default test case21", () => - { - let m = new Matrix(); - // @ts-ignore - m.d = { "toString":function () { return "1a" } }; - expect(m.d).toBe(0); - }); - -}); -describe("Matrix.js tx test", () => +describe("Matrix.js pattern test", () => { - it("default test case1", () => - { - let m = new Matrix(); - expect(m.tx).toBe(0); - }); - - it("default test case2", () => - { - let m = new Matrix(); - // @ts-ignore - m.tx = null; - expect(m.tx).toBe(0); - }); - - it("default test case3", () => - { - let m = new Matrix(); - // @ts-ignore - m.tx = undefined; - expect(m.tx).toBe(0); - }); - - it("default test case4", () => - { - let m = new Matrix(); - // @ts-ignore - m.tx = true; - expect(m.tx).toBe(1); - }); - - it("default test case5", () => - { - let m = new Matrix(); - // @ts-ignore - m.tx = ""; - expect(m.tx).toBe(0); - }); - - it("default test case6", () => - { - let m = new Matrix(); - // @ts-ignore - m.tx = "abc"; - expect(m.tx).toBe(0); - }); - - it("default test case7", () => - { - let m = new Matrix(); - m.tx = 0; - expect(m.tx).toBe(0); - }); - - it("default test case8", () => - { - let m = new Matrix(); - m.tx = 1; - expect(m.tx).toBe(1); - }); - - it("default test case9", () => - { - let m = new Matrix(); - m.tx = 500; - expect(m.tx).toBe(500); - }); - - it("default test case10", () => - { - let m = new Matrix(); - m.tx = 50000000000000000; - expect(m.tx).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let m = new Matrix(); - m.tx = -1; - expect(m.tx).toBe(-1); - }); - - it("default test case12", () => - { - let m = new Matrix(); - m.tx = -500; - expect(m.tx).toBe(-500); - }); - - it("default test case13", () => - { - let m = new Matrix(); - m.tx = -50000000000000000; - expect(m.tx).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let m = new Matrix(); - // @ts-ignore - m.tx = { "a":0 }; - expect(m.tx).toBe(0); - }); - - it("default test case15", () => - { - let m = new Matrix(); - // @ts-ignore - m.tx = function a() {}; - expect(m.tx).toBe(0); - }); - - it("default test case16", () => - { - let m = new Matrix(); - // @ts-ignore - m.tx = [1]; - expect(m.tx).toBe(1); - }); - - it("default test case17", () => - { - let m = new Matrix(); - // @ts-ignore - m.tx = [1,2]; - expect(m.tx).toBe(0); - }); - - it("default test case18", () => - { - let m = new Matrix(); - // @ts-ignore - m.tx = {}; - expect(m.tx).toBe(0); - }); - - it("default test case19", () => + it("pattern test case1", () => { - let m = new Matrix(); - // @ts-ignore - m.tx = { "toString":function () { return 1 } }; - expect(m.tx).toBe(1); - }); + let matrix = new Matrix(); - it("default test case20", () => - { - let m = new Matrix(); - // @ts-ignore - m.tx = { "toString":function () { return "1" } }; - expect(m.tx).toBe(1); - }); + // 単位行列化 + matrix.identity(); + // 拡大縮小成分を乗算 + matrix.scale( 256 / 1638.4 , 256 / 1638.4 ); + // 角度成分を乗算 + matrix.rotate(Math.PI / 180); + // 移動成分を乗算 + matrix.translate( 128.0 , 128.0 ); - it("default test case21", () => - { - let m = new Matrix(); - // @ts-ignore - m.tx = { "toString":function () { return "1a" } }; - expect(m.tx).toBe(0); + expect(matrix.toString()).toBe("(a=0.15622620284557343, b=0.0027269385755062103, c=-0.0027269385755062103, d=0.15622620284557343, tx=128, ty=128)"); }); }); -describe("Matrix.js ty test", () => -{ - - it("default test case1", () => - { - let m = new Matrix(); - expect(m.ty).toBe(0); - }); - - it("default test case2", () => - { - let m = new Matrix(); - // @ts-ignore - m.ty = null; - expect(m.ty).toBe(0); - }); - - it("default test case3", () => - { - let m = new Matrix(); - // @ts-ignore - m.ty = undefined; - expect(m.ty).toBe(0); - }); - - it("default test case4", () => - { - let m = new Matrix(); - // @ts-ignore - m.ty = true; - expect(m.ty).toBe(1); - }); - - it("default test case5", () => - { - let m = new Matrix(); - // @ts-ignore - m.ty = ""; - expect(m.ty).toBe(0); - }); - - it("default test case6", () => - { - let m = new Matrix(); - // @ts-ignore - m.ty = "abc"; - expect(m.ty).toBe(0); - }); - - it("default test case7", () => - { - let m = new Matrix(); - m.ty = 0; - expect(m.ty).toBe(0); - }); - - it("default test case8", () => - { - let m = new Matrix(); - m.ty = 1; - expect(m.ty).toBe(1); - }); - - it("default test case9", () => - { - let m = new Matrix(); - m.ty = 500; - expect(m.ty).toBe(500); - }); - - it("default test case10", () => - { - let m = new Matrix(); - m.ty = 50000000000000000; - expect(m.ty).toBe($SHORT_INT_MAX); - }); - - it("default test case11", () => - { - let m = new Matrix(); - m.ty = -1; - expect(m.ty).toBe(-1); - }); - - it("default test case12", () => - { - let m = new Matrix(); - m.ty = -500; - expect(m.ty).toBe(-500); - }); - - it("default test case13", () => - { - let m = new Matrix(); - m.ty = -50000000000000000; - expect(m.ty).toBe($SHORT_INT_MIN); - }); - - it("default test case14", () => - { - let m = new Matrix(); - // @ts-ignore - m.ty = { "a":0 }; - expect(m.ty).toBe(0); - }); - - it("default test case15", () => - { - let m = new Matrix(); - // @ts-ignore - m.ty = function a() {}; - expect(m.ty).toBe(0); - }); - - it("default test case16", () => - { - let m = new Matrix(); - // @ts-ignore - m.ty = [1]; - expect(m.ty).toBe(1); - }); - - it("default test case17", () => - { - let m = new Matrix(); - // @ts-ignore - m.ty = [1,2]; - expect(m.ty).toBe(0); - }); - - it("default test case18", () => - { - let m = new Matrix(); - // @ts-ignore - m.ty = {}; - expect(m.ty).toBe(0); - }); - - it("default test case19", () => - { - let m = new Matrix(); - // @ts-ignore - m.ty = { "toString":function () { return 1 } }; - expect(m.ty).toBe(1); - }); - - it("default test case20", () => - { - let m = new Matrix(); - // @ts-ignore - m.ty = { "toString":function () { return "1" } }; - expect(m.ty).toBe(1); - }); - - it("default test case21", () => - { - let m = new Matrix(); - // @ts-ignore - m.ty = { "toString":function () { return "1a" } }; - expect(m.ty).toBe(0); - }); - -}); describe("Matrix.js BugFix", () => { @@ -2710,43 +584,5 @@ describe("Matrix.js BugFix", () => mat.translate(100, 100); expect(mat.toString()).toBe("(a=0, b=0, c=0, d=1, tx=100, ty=0)"); - }); -}); - - - -describe("Matrix.js setTo", () => -{ - it("copy test case1", () => - { - - const matrix = new Matrix(); - expect(matrix.toString()).toBe( - "(a=1, b=0, c=0, d=1, tx=0, ty=0)" - ); - - matrix.setTo(1, 2, 3, 4, 5, 6); - expect(matrix.toString()).toBe( - "(a=1, b=2, c=3, d=4, tx=5, ty=6)" - ); - - }); -}); - -describe("Matrix.js identity", () => -{ - it("clear test case1", () => - { - - const matrix = new Matrix(1, 2, 3, 4, 5, 6); - expect(matrix.toString()).toBe( - "(a=1, b=2, c=3, d=4, tx=5, ty=6)" - ); - - matrix.identity(); - expect(matrix.toString()).toBe( - "(a=1, b=0, c=0, d=1, tx=0, ty=0)" - ); - }); }); \ No newline at end of file diff --git a/packages/geom/src/Matrix.ts b/packages/geom/src/Matrix.ts index d722539b..ae49e5cc 100644 --- a/packages/geom/src/Matrix.ts +++ b/packages/geom/src/Matrix.ts @@ -1,6 +1,17 @@ import { Point } from "./Point"; import { execute as matrixCloneService } from "../src/Matrix/service/MatrixCloneService"; import { execute as matirxConcatService } from "../src/Matrix/service/MatirxConcatService"; +import { execute as matrixCopyFromService } from "../src/Matrix/service/MatrixCopyFromService"; +import { execute as matrixCreateBoxService } from "../src/Matrix/service/MatrixCreateBoxService"; +import { execute as matrixCreateGradientBoxService } from "../src/Matrix/service/MatrixCreateGradientBoxService"; +import { execute as matrixDeltaTransformPointService } from "../src/Matrix/service/MatrixDeltaTransformPointService"; +import { execute as matrixIdentityService } from "../src/Matrix/service/MatrixIdentityService"; +import { execute as matrixInvertService } from "../src/Matrix/service/MatrixInvertService"; +import { execute as matrixRotateService } from "../src/Matrix/service/MatrixRotateService"; +import { execute as matrixScaleService } from "../src/Matrix/service/MatrixScaleService"; +import { execute as matrixSetToService } from "../src/Matrix/service/MatrixSetToService"; +import { execute as matrixTransformPointService } from "../src/Matrix/service/MatrixTransformPointService"; +import { execute as matrixTranslateService } from "../src/Matrix/service/MatrixTranslateService"; /** * @type {Float32Array[]} @@ -301,18 +312,13 @@ export class Matrix * @description すべてのマトリックスデータを、ソース Matrix オブジェクトから、 * 呼び出し元の Matrix オブジェクトにコピーします。 * - * @param {Matrix} source_matrix + * @param {Matrix} matrix * @method * @return {void} */ - copyFrom (source_matrix: Matrix): void + copyFrom (matrix: Matrix): void { - this._$matrix[0] = source_matrix.a; - this._$matrix[1] = source_matrix.b; - this._$matrix[2] = source_matrix.c; - this._$matrix[3] = source_matrix.d; - this._$matrix[4] = source_matrix.tx; - this._$matrix[5] = source_matrix.ty; + matrixCopyFromService(this, matrix); } /** @@ -333,10 +339,7 @@ export class Matrix rotation: number = 0, tx: number = 0, ty: number = 0 ): void { - this.identity(); - this.rotate(rotation); - this.scale(scale_x, scale_y); - this.translate(tx, ty); + matrixCreateBoxService(this, scale_x, scale_y, rotation, tx, ty); } /** @@ -358,25 +361,7 @@ export class Matrix rotation: number = 0, tx: number = 0, ty: number = 0 ): void { - - this.a = width / 1638.4; - this.d = height / 1638.4; - - if (rotation) { - const cos = Math.cos(rotation); - const sin = Math.sin(rotation); - - this.b = sin * this.d; - this.c = -sin * this.a; - this.a *= cos; - this.d *= cos; - } else { - this.b = 0; - this.c = 0; - } - - this.tx = tx + width / 2; - this.ty = ty + height / 2; + matrixCreateGradientBoxService(this, width, height, rotation, tx, ty); } /** @@ -391,10 +376,7 @@ export class Matrix */ deltaTransformPoint (point: Point): Point { - return new Point( - point.x * this._$matrix[0] + point.y * this._$matrix[2], - point.x * this._$matrix[1] + point.y * this._$matrix[3] - ); + return matrixDeltaTransformPointService(this, point); } /** @@ -407,12 +389,7 @@ export class Matrix */ identity (): void { - this._$matrix[0] = 1; - this._$matrix[1] = 0; - this._$matrix[2] = 0; - this._$matrix[3] = 1; - this._$matrix[4] = 0; - this._$matrix[5] = 0; + matrixIdentityService(this); } /** @@ -425,40 +402,7 @@ export class Matrix */ invert (): void { - const a: number = this._$matrix[0]; - const b: number = this._$matrix[1]; - const c: number = this._$matrix[2]; - const d: number = this._$matrix[3]; - const tx: number = this._$matrix[4]; - const ty: number = this._$matrix[5]; - - if (b === 0 && c === 0) { - - this.a = 1 / a; - this.b = 0; - this.c = 0; - this.d = 1 / d; - this.tx = -this.a * tx; - this.ty = -this.d * ty; - - } else { - - const det = a * d - b * c; - - if (det) { - - const rdet: number = 1 / det; - - this.a = d * rdet; - this.b = -b * rdet; - this.c = -c * rdet; - this.d = a * rdet; - this.tx = -(this.a * tx + this.c * ty); - this.ty = -(this.b * tx + this.d * ty); - - } - - } + matrixInvertService(this); } /** @@ -472,40 +416,22 @@ export class Matrix */ rotate (rotation: number): void { - const a = this._$matrix[0]; - const b = this._$matrix[1]; - const c = this._$matrix[2]; - const d = this._$matrix[3]; - const tx = this._$matrix[4]; - const ty = this._$matrix[5]; - - this.a = a * Math.cos(rotation) - b * Math.sin(rotation); - this.b = a * Math.sin(rotation) + b * Math.cos(rotation); - this.c = c * Math.cos(rotation) - d * Math.sin(rotation); - this.d = c * Math.sin(rotation) + d * Math.cos(rotation); - this.tx = tx * Math.cos(rotation) - ty * Math.sin(rotation); - this.ty = tx * Math.sin(rotation) + ty * Math.cos(rotation); + matrixRotateService(this, rotation); } /** * @description 行列に拡大 / 縮小の変換を適用します。 * Applies a scaling transformation to the matrix. * - * @param {number} sx - * @param {number} sy + * @param {number} scale_x + * @param {number} scale_y * @return {void} * @method * @public */ - scale (sx: number, sy: number): void + scale (scale_x: number, scale_y: number): void { - this.a *= sx; - this.c *= sx; - this.tx *= sx; - - this.b *= sy; - this.d *= sy; - this.ty *= sy; + matrixScaleService(this, scale_x, scale_y); } /** @@ -527,12 +453,7 @@ export class Matrix c: number, d: number, tx: number, ty: number ): void { - this.a = a; - this.b = b; - this.c = c; - this.d = d; - this.tx = tx; - this.ty = ty; + matrixSetToService(this, a, b, c, d, tx, ty); } /** @@ -547,10 +468,7 @@ export class Matrix */ transformPoint (point: Point): Point { - return new Point( - point.x * this._$matrix[0] + point.y * this._$matrix[2] + this._$matrix[4], - point.x * this._$matrix[1] + point.y * this._$matrix[3] + this._$matrix[5] - ); + return matrixTransformPointService(this, point); } /** @@ -567,8 +485,7 @@ export class Matrix */ translate (dx: number, dy: number): void { - this.tx += dx; - this.ty += dy; + matrixTranslateService(this, dx, dy); } /** diff --git a/packages/geom/src/Matrix/service/MatirxConcatService.ts b/packages/geom/src/Matrix/service/MatirxConcatService.ts index bb616afc..ff17d263 100644 --- a/packages/geom/src/Matrix/service/MatirxConcatService.ts +++ b/packages/geom/src/Matrix/service/MatirxConcatService.ts @@ -1,4 +1,4 @@ -import { Matrix } from "../../Matrix"; +import type { Matrix } from "../../Matrix"; /** * @description 指定のMatrixを連結 diff --git a/packages/geom/src/Matrix/service/MatrixCopyFromService.ts b/packages/geom/src/Matrix/service/MatrixCopyFromService.ts index 76e2ef36..3a688fbc 100644 --- a/packages/geom/src/Matrix/service/MatrixCopyFromService.ts +++ b/packages/geom/src/Matrix/service/MatrixCopyFromService.ts @@ -1,4 +1,4 @@ -import { Matrix } from "../../Matrix"; +import type { Matrix } from "../../Matrix"; /** * @description 指定のMatrixオブジェクトの値をコピー diff --git a/packages/geom/src/Matrix/service/MatrixCreateBoxService.test.ts b/packages/geom/src/Matrix/service/MatrixCreateBoxService.test.ts new file mode 100644 index 00000000..f9c84cb1 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixCreateBoxService.test.ts @@ -0,0 +1,451 @@ +import { Matrix } from "../../Matrix"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js createBox test", () => +{ + it("createBox test case1", () => + { + const matrix = new Matrix(1, 0.5, -0.2); + const xScale = 2.0; + const yScale = 3.0; + const rotation = 2 * Math.PI * (45 / 360); + const tx = 10; + const ty = 20; + matrix.createBox(xScale, yScale, rotation, tx, ty); + expect(matrix.toString()).toBe( + "(a=1.4142135381698608, b=2.1213202476501465, c=-1.4142135381698608, d=2.1213202476501465, tx=10, ty=20)" + ); + }); + + it("createBox test case2", () => + { + const matrix = new Matrix(-1, 0.5, -0.2); + const xScale = 2.0; + const yScale = 3.0; + const rotation = 2 * Math.PI * (45 / 360); + const tx = 10; + const ty = 20; + matrix.createBox(xScale, yScale, rotation, tx, ty); + expect(matrix.toString()).toBe( + "(a=1.4142135381698608, b=2.1213202476501465, c=-1.4142135381698608, d=2.1213202476501465, tx=10, ty=20)" + ); + }); + + it("createBox test case3", () => + { + const matrix = new Matrix(-1, -0.5, -0.2); + const xScale = 2.0; + const yScale = 3.0; + const rotation = 2 * Math.PI * (45 / 360); + const tx = 10; + const ty = 20; + matrix.createBox(xScale, yScale, rotation, tx, ty); + expect(matrix.toString()).toBe( + "(a=1.4142135381698608, b=2.1213202476501465, c=-1.4142135381698608, d=2.1213202476501465, tx=10, ty=20)" + ); + }); + + it("createBox test case4", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = 2.0; + const yScale = 3.0; + const rotation = -2 * Math.PI * (45 / 360); + const tx = 10; + const ty = 20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=1.4142135381698608, b=-2.1213202476501465, c=1.4142135381698608, d=2.1213202476501465, tx=10, ty=20)" + ); + }); + + it("createBox test case5", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = 2 * Math.PI * (45 / 360); + const tx = 10; + const ty = 20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=-1.4142135381698608, b=-2.1213202476501465, c=1.4142135381698608, d=-2.1213202476501465, tx=10, ty=20)" + ); + }); + + it("createBox test case6", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = 2.0; + const yScale = 3.0; + const rotation = 2 * Math.PI * (45 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=1.4142135381698608, b=2.1213202476501465, c=-1.4142135381698608, d=2.1213202476501465, tx=-10, ty=-20)" + ); + }); + + it("createBox test case7", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = -2 * Math.PI * (45 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=-1.4142135381698608, b=2.1213202476501465, c=-1.4142135381698608, d=-2.1213202476501465, tx=-10, ty=-20)" + ); + }); + + it("createBox test case8", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = -2 * Math.PI * (90 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=-1.2246468525851679e-16, b=3, c=-2, d=-1.8369702788777518e-16, tx=-10, ty=-20)" + ); + }); + + it("createBox test case9", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = -2 * Math.PI * (135 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=1.4142135381698608, b=2.1213202476501465, c=-1.4142135381698608, d=2.1213202476501465, tx=-10, ty=-20)" + ); + }); + + it("createBox test case10", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = -2 * Math.PI * (180 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=2, b=3.6739405577555036e-16, c=-2.4492937051703357e-16, d=3, tx=-10, ty=-20)" + ); + }); + + it("createBox test case11", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = -2 * Math.PI * (225 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=1.4142135381698608, b=-2.1213202476501465, c=1.4142135381698608, d=2.1213202476501465, tx=-10, ty=-20)" + ); + }); + + it("createBox test case12", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = -2 * Math.PI * (270 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=3.6739402930577075e-16, b=-3, c=2, d=5.510910704284357e-16, tx=-10, ty=-20)" + ); + }); + + it("createBox test case13", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = -2 * Math.PI * (315 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + + expect(m.a).toBe(-1.4142135381698608); + expect(m.b).toBe(-2.1213202476501465); + expect(m.c).toBe(1.4142135381698608); + expect(m.d).toBe(-2.1213202476501465); + expect(m.tx).toBe(-10); + expect(m.ty).toBe(-20); + }); + + it("createBox test case14", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = -2 * Math.PI * (360 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=-2, b=-7.347881115511007e-16, c=4.898587410340671e-16, d=-3, tx=-10, ty=-20)" + ); + }); + + it("createBox test case15", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = 0; + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=-2, b=0, c=0, d=-3, tx=-10, ty=-20)" + ); + }); + + it("createBox test case16", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = 2 * Math.PI * (45 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=-1.4142135381698608, b=-2.1213202476501465, c=1.4142135381698608, d=-2.1213202476501465, tx=-10, ty=-20)" + ); + }); + + it("createBox test case17", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = 2 * Math.PI * (90 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=-1.2246468525851679e-16, b=-3, c=2, d=-1.8369702788777518e-16, tx=-10, ty=-20)" + ); + }); + + it("createBox test case18", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = 2 * Math.PI * (135 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=1.4142135381698608, b=-2.1213202476501465, c=1.4142135381698608, d=2.1213202476501465, tx=-10, ty=-20)" + ); + }); + + it("createBox test case19", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = 2 * Math.PI * (180 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=2, b=-3.6739405577555036e-16, c=2.4492937051703357e-16, d=3, tx=-10, ty=-20)" + ); + }); + + it("createBox test case20", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = 2 * Math.PI * (225 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=1.4142135381698608, b=2.1213202476501465, c=-1.4142135381698608, d=2.1213202476501465, tx=-10, ty=-20)" + ); + }); + + it("createBox test case21", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = 2 * Math.PI * (270 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=3.6739402930577075e-16, b=3, c=-2, d=5.510910704284357e-16, tx=-10, ty=-20)" + ); + }); + + it("createBox test case22", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = 2 * Math.PI * (315 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + + expect(m.a).toBe(-1.4142135381698608); + expect(m.b).toBe(2.1213202476501465); + expect(m.c).toBe(-1.4142135381698608); + expect(m.d).toBe(-2.1213202476501465); + expect(m.tx).toBe(-10); + expect(m.ty).toBe(-20); + }); + + it("createBox test case23", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = 2 * Math.PI * (360 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=-2, b=7.347881115511007e-16, c=-4.898587410340671e-16, d=-3, tx=-10, ty=-20)" + ); + }); + + it("createBox test case24", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = Math.PI * (45 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=-1.8477590084075928, b=-1.148050308227539, c=0.7653668522834778, d=-2.7716383934020996, tx=-10, ty=-20)" + ); + }); + + it("createBox test case25", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = Math.PI * (90 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=-1.4142135381698608, b=-2.1213202476501465, c=1.4142135381698608, d=-2.1213202476501465, tx=-10, ty=-20)" + ); + }); + + it("createBox test case26", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = Math.PI * (135 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=-0.7653668522834778, b=-2.7716383934020996, c=1.8477590084075928, d=-1.148050308227539, tx=-10, ty=-20)" + ); + }); + + it("createBox test case27", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = Math.PI * (180 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=-1.2246468525851679e-16, b=-3, c=2, d=-1.8369702788777518e-16, tx=-10, ty=-20)" + ); + }); + + it("createBox test case28", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = Math.PI * (225 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=0.7653668522834778, b=-2.7716383934020996, c=1.8477590084075928, d=1.148050308227539, tx=-10, ty=-20)" + ); + }); + + it("createBox test case29", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = Math.PI * (270 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=1.4142135381698608, b=-2.1213202476501465, c=1.4142135381698608, d=2.1213202476501465, tx=-10, ty=-20)" + ); + }); + + it("createBox test case30", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = Math.PI * (315 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + + expect(m.a).toBe(1.8477590084075928); + expect(m.b).toBe(-1.148050308227539); + expect(m.c).toBe(0.7653668522834778); + expect(m.d).toBe(2.7716383934020996); + expect(m.tx).toBe(-10); + expect(m.ty).toBe(-20); + }); + + it("createBox test case31", () => + { + const m = new Matrix(1, 0.5, -0.2); + const xScale = -2.0; + const yScale = -3.0; + const rotation = Math.PI * (360 / 360); + const tx = -10; + const ty = -20; + m.createBox(xScale, yScale, rotation, tx, ty); + expect(m.toString()).toBe( + "(a=2, b=-3.6739405577555036e-16, c=2.4492937051703357e-16, d=3, tx=-10, ty=-20)" + ); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixCreateBoxService.ts b/packages/geom/src/Matrix/service/MatrixCreateBoxService.ts new file mode 100644 index 00000000..70f82cf4 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixCreateBoxService.ts @@ -0,0 +1,27 @@ +import type { Matrix } from "../../Matrix"; + +/** + * @description + * + * @param {Matrix} matrix + * @param {number} scale_x + * @param {number} scale_y + * @param {number} rotation + * @param {number} [tx=0] + * @param {number} [ty=0] + * @return {void} + * @method + * @public + */ +export const execute = ( + matrix: Matrix, + scale_x: number, scale_y: number, + rotation: number = 0, + tx: number = 0, ty: number = 0 +): void => +{ + matrix.identity(); + matrix.rotate(rotation); + matrix.scale(scale_x, scale_y); + matrix.translate(tx, ty); +}; \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixCreateGradientBoxService.test.ts b/packages/geom/src/Matrix/service/MatrixCreateGradientBoxService.test.ts new file mode 100644 index 00000000..8515ddfd --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixCreateGradientBoxService.test.ts @@ -0,0 +1,131 @@ +import { Matrix } from "../../Matrix"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js createGradientBox test", () => +{ + it("createGradientBox test case1", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(1, 0, 9, 0, 0); + expect(matrix.toString()).toBe( + "(a=-0.0005561097641475499, b=0, c=-0.0002515371597837657, d=0, tx=0.5, ty=0)" + ); + }); + + it("createGradientBox test case2", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(1, 1, 9, 0, 0); + expect(matrix.toString()).toBe( + "(a=-0.0005561097641475499, b=0.0002515371597837657, c=-0.0002515371597837657, d=-0.0005561097641475499, tx=0.5, ty=0.5)" + ); + }); + + it("createGradientBox test case3", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(1, 0, 9, 1, 0); + expect(matrix.toString()).toBe( + "(a=-0.0005561097641475499, b=0, c=-0.0002515371597837657, d=0, tx=1.5, ty=0)" + ); + }); + + it("createGradientBox test case4", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(1, 0, 9, 0, 1); + expect(matrix.toString()).toBe( + "(a=-0.0005561097641475499, b=0, c=-0.0002515371597837657, d=0, tx=0.5, ty=1)" + ); + }); + + it("createGradientBox test case5", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(1, 1, 9, 1, 1); + expect(matrix.toString()).toBe( + "(a=-0.0005561097641475499, b=0.0002515371597837657, c=-0.0002515371597837657, d=-0.0005561097641475499, tx=1.5, ty=1.5)" + ); + }); + + it("createGradientBox test case6", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(-1, -1, -9, -1, -1); + expect(matrix.toString()).toBe( + "(a=0.0005561097641475499, b=0.0002515371597837657, c=-0.0002515371597837657, d=0.0005561097641475499, tx=-1.5, ty=-1.5)" + ); + }); + + it("createGradientBox test case6", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(1, 1, 45 / 180 * Math.PI, 1, 1); + expect(matrix.toString()).toBe( + "(a=0.0004315837286412716, b=0.0004315837286412716, c=-0.0004315837286412716, d=0.0004315837286412716, tx=1.5, ty=1.5)" + ); + }); + + it("createGradientBox test case7", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(1, 1, 90 / 180 * Math.PI, 1, 1); + expect(matrix.toString()).toBe( + "(a=3.7373254383716084e-20, b=0.0006103515625, c=-0.0006103515625, d=3.7373254383716084e-20, tx=1.5, ty=1.5)" + ); + }); + + it("createGradientBox test case8", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(1, 1, 135 / 180 * Math.PI, 1, 1); + expect(matrix.toString()).toBe( + "(a=-0.0004315837286412716, b=0.0004315837286412716, c=-0.0004315837286412716, d=-0.0004315837286412716, tx=1.5, ty=1.5)" + ); + }); + + it("createGradientBox test case9", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(1, 1, 180 / 180 * Math.PI, 1, 1); + expect(matrix.toString()).toBe( + "(a=-0.0006103515625, b=7.474650876743217e-20, c=-7.474650876743217e-20, d=-0.0006103515625, tx=1.5, ty=1.5)" + ); + }); + + it("createGradientBox test case10", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(1, 1, -45 / 180 * Math.PI, 1, 1); + expect(matrix.toString()).toBe( + "(a=0.0004315837286412716, b=-0.0004315837286412716, c=0.0004315837286412716, d=0.0004315837286412716, tx=1.5, ty=1.5)" + ); + }); + + it("createGradientBox test case11", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(1, 1, -90 / 180 * Math.PI, 1, 1); + expect(matrix.toString()).toBe( + "(a=3.7373254383716084e-20, b=-0.0006103515625, c=0.0006103515625, d=3.7373254383716084e-20, tx=1.5, ty=1.5)" + ); + }); + + it("createGradientBox test case12", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(1, 1, -135 / 180 * Math.PI, 1, 1); + expect(matrix.toString()).toBe( + "(a=-0.0004315837286412716, b=-0.0004315837286412716, c=0.0004315837286412716, d=-0.0004315837286412716, tx=1.5, ty=1.5)" + ); + }); + + it("createGradientBox test case13", () => + { + const matrix = new Matrix(); + matrix.createGradientBox(1, 1, -180 / 180 * Math.PI, 1, 1); + expect(matrix.toString()).toBe( + "(a=-0.0006103515625, b=-7.474650876743217e-20, c=7.474650876743217e-20, d=-0.0006103515625, tx=1.5, ty=1.5)" + ); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixCreateGradientBoxService.ts b/packages/geom/src/Matrix/service/MatrixCreateGradientBoxService.ts new file mode 100644 index 00000000..57db5060 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixCreateGradientBoxService.ts @@ -0,0 +1,44 @@ +import type { Matrix } from "../../Matrix"; + +/** + * @description Gradient用のMatrixを生成 + * Create a Matrix for Gradient + * + * @param {Matrix} matrix + * @param {number} width + * @param {number} height + * @param {number} [rotation=0] + * @param {number} [tx=0] + * @param {number} [ty=0] + * @return {void} + * @method + * @public + */ +export const execute = ( + matrix: Matrix, + width: number, height: number, + rotation: number = 0, + tx: number = 0, ty: number = 0 +): void => { + + const array = matrix._$matrix; + + array[0] = width / 1638.4; + array[3] = height / 1638.4; + + if (rotation) { + const cos = Math.cos(rotation); + const sin = Math.sin(rotation); + + array[1] = sin * array[3]; + array[2] = -sin * array[0]; + array[0] *= cos; + array[3] *= cos; + } else { + array[1] = 0; + array[2] = 0; + } + + array[4] = tx + width / 2; + array[5] = ty + height / 2; +}; \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixDeltaTransformPointService.test.ts b/packages/geom/src/Matrix/service/MatrixDeltaTransformPointService.test.ts new file mode 100644 index 00000000..ee26d7bb --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixDeltaTransformPointService.test.ts @@ -0,0 +1,254 @@ +import { Matrix } from "../../Matrix"; +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js deltaTransformPoint test", () => +{ + it("deltaTransformPoint test case1", () => + { + const matrix = new Matrix(1, 0, 0, 1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.toString()).toBe( + "(x=-12.727921843528748, y=15.55634891986847)" + ); + }); + + it("deltaTransformPoint test case2", () => + { + const matrix = new Matrix(10, 0, 0, 1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.toString()).toBe( + "(x=2.384185791015625e-7, y=28.284271001815796)" + ); + }); + + it("deltaTransformPoint test case3", () => + { + const matrix = new Matrix(1, 10, 0, 1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.x | 0).toBe(-26); + expect(point2.y | 0).toBe(29); + }); + + it("deltaTransformPoint test case4", () => + { + const matrix = new Matrix(1, 0, 10, 1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.toString()).toBe( + "(x=128.6934379339218, y=156.97770154476166)" + ); + }); + + it("deltaTransformPoint test case5", () => + { + const matrix = new Matrix(1, 0, 0, 10, 100, 110); + matrix.translate(10, 0); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.toString()).toBe( + "(x=-140.007142663002, y=142.83556973934174)" + ); + }); + + it("deltaTransformPoint test case6", () => + { + const matrix = new Matrix(-1, 0, 0, 1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.toString()).toBe( + "(x=-15.55634891986847, y=12.727921843528748)" + ); + }); + + it("deltaTransformPoint test case7", () => + { + const matrix = new Matrix(1, 0, 0, -1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.toString()).toBe( + "(x=15.55634891986847, y=-12.727921843528748)" + ); + }); + + it("deltaTransformPoint test case8", () => + { + const matrix = new Matrix(-1, 0, 0, -1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.toString()).toBe( + "(x=12.727921843528748, y=-15.55634891986847)" + ); + }); + + it("deltaTransformPoint test case9", () => + { + const matrix = new Matrix(-1, -1, 0, -1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.toString()).toBe( + "(x=14.142135381698608, y=-16.97056245803833)" + ); + }); + + it("deltaTransformPoint test case10", () => + { + const matrix = new Matrix(-1, 0, -1, -1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.x | 0).toBe(-1); + expect(point2.y | 0).toBe(-29); + }); + + it("deltaTransformPoint test case11", () => + { + const matrix = new Matrix(-1, -1, -1, -1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.x | 0).toBe(0); + expect(point2.y | 0).toBe(-31); + }); + + it("deltaTransformPoint test case12", () => + { + const matrix = new Matrix(1, 1, 1, 1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(90 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.toString()).toBe( + "(x=-22, y=22)" + ); + }); + + it("deltaTransformPoint test case13", () => + { + const matrix = new Matrix(1, 1, 1, 1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(135 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.toString()).toBe( + "(x=-31.11269783973694, y=2.4424906541753444e-15)" + ); + }); + + it("deltaTransformPoint test case14", () => + { + const matrix = new Matrix(1, 1, 1, 1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(180 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.toString()).toBe( + "(x=-22, y=-22)" + ); + }); + + it("deltaTransformPoint test case15", () => + { + const matrix = new Matrix(1, 1, 1, 1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(-45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.x | 0).toBe(31); + expect(point2.y | 0).toBe(0); + }); + + it("deltaTransformPoint test case16", () => + { + const matrix = new Matrix(1, 1, 1, 1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(-90 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.toString()).toBe( + "(x=22, y=-22)" + ); + }); + + it("deltaTransformPoint test case17", () => + { + const matrix = new Matrix(1, 1, 1, 1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(-135 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.x | 0).toBe(0); + expect(point2.y | 0).toBe(-31); + + }); + + it("deltaTransformPoint test case18", () => + { + const matrix = new Matrix(1, 1, 1, 1, 100, 110); + matrix.translate(10, 0); + matrix.rotate(-180 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.deltaTransformPoint(point1); + + expect(point2.toString()).toBe( + "(x=-22, y=-22)" + ); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixDeltaTransformPointService.ts b/packages/geom/src/Matrix/service/MatrixDeltaTransformPointService.ts new file mode 100644 index 00000000..e08ffcd8 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixDeltaTransformPointService.ts @@ -0,0 +1,20 @@ +import type { Matrix } from "../../Matrix"; +import { Point } from "../../Point"; + +/** + * @description Matrixを使ってPointを変換 + * Transform Point using Matrix + * + * @param {Matrix} matrix + * @param {Point} point + * @return {Point} + * @method + * @public + */ +export const execute = (matrix: Matrix, point: Point): Point => +{ + return new Point( + point.x * matrix._$matrix[0] + point.y * matrix._$matrix[2], + point.x * matrix._$matrix[1] + point.y * matrix._$matrix[3] + ); +}; \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixIdentityService.test.ts b/packages/geom/src/Matrix/service/MatrixIdentityService.test.ts new file mode 100644 index 00000000..84e88904 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixIdentityService.test.ts @@ -0,0 +1,18 @@ +import { Matrix } from "../../Matrix"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js identity", () => +{ + it("identity test case1", () => + { + const matrix = new Matrix(1, 2, 3, 4, 5, 6); + expect(matrix.toString()).toBe( + "(a=1, b=2, c=3, d=4, tx=5, ty=6)" + ); + + matrix.identity(); + expect(matrix.toString()).toBe( + "(a=1, b=0, c=0, d=1, tx=0, ty=0)" + ); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixIdentityService.ts b/packages/geom/src/Matrix/service/MatrixIdentityService.ts new file mode 100644 index 00000000..1dda9e38 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixIdentityService.ts @@ -0,0 +1,20 @@ +import type { Matrix } from "../../Matrix"; + +/** + * @description Matrixの値を初期化 + * Initialize Matrix values + * + * @param {Matrix} matrix + * @return {void} + * @method + * @public + */ +export const execute = (matrix: Matrix): void => +{ + matrix._$matrix[0] = 1; + matrix._$matrix[1] = 0; + matrix._$matrix[2] = 0; + matrix._$matrix[3] = 1; + matrix._$matrix[4] = 0; + matrix._$matrix[5] = 0; +}; \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixInvertService.test.ts b/packages/geom/src/Matrix/service/MatrixInvertService.test.ts new file mode 100644 index 00000000..a3fbbafb --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixInvertService.test.ts @@ -0,0 +1,69 @@ +import { Matrix } from "../../Matrix"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js invert test", () => +{ + it("invert test case1", () => + { + const matrix = new Matrix(2, 1, 1, 2, -200, -200); + matrix.invert(); + expect(matrix.toString()).toBe( + "(a=0.6666666865348816, b=-0.3333333432674408, c=-0.3333333432674408, d=0.6666666865348816, tx=66.66667175292969, ty=66.66667175292969)" + ); + }); + + it("invert test case2", () => + { + const matrix = new Matrix(2, 1, 1, 2, -200, -200); + matrix.invert(); + matrix.invert(); + expect(matrix.toString()).toBe( + "(a=2, b=1, c=1, d=2, tx=-200.00001525878906, ty=-200.00001525878906)" + ); + }); + + it("invert test case3", () => + { + const matrix = new Matrix(-2, 1, 1, 2, -200, -200); + matrix.invert(); + expect(matrix.toString()).toBe( + "(a=-0.4000000059604645, b=0.20000000298023224, c=0.20000000298023224, d=0.4000000059604645, tx=-40, ty=120)" + ); + }); + + it("invert test case4", () => + { + const matrix = new Matrix(2, -1, 1, 2, -200, -200); + matrix.invert(); + expect(matrix.toString()).toBe( + "(a=0.4000000059604645, b=0.20000000298023224, c=-0.20000000298023224, d=0.4000000059604645, tx=40, ty=120)" + ); + }); + + it("invert test case5", () => + { + const matrix = new Matrix(2, 1, -1, 2, -200, -200); + matrix.invert(); + expect(matrix.toString()).toBe( + "(a=0.4000000059604645, b=-0.20000000298023224, c=0.20000000298023224, d=0.4000000059604645, tx=120, ty=40)" + ); + }); + + it("invert test case6", () => + { + const matrix = new Matrix(2, 1, 1, -2, -200, -200); + matrix.invert(); + expect(matrix.toString()).toBe( + "(a=0.4000000059604645, b=0.20000000298023224, c=0.20000000298023224, d=-0.4000000059604645, tx=120, ty=-40)" + ); + }); + + it("invert test case7", () => + { + const matrix = new Matrix(-2, -1, -1, -2, -200, -200); + matrix.invert(); + expect(matrix.toString()).toBe( + "(a=-0.6666666865348816, b=0.3333333432674408, c=0.3333333432674408, d=-0.6666666865348816, tx=-66.66667175292969, ty=-66.66667175292969)" + ); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixInvertService.ts b/packages/geom/src/Matrix/service/MatrixInvertService.ts new file mode 100644 index 00000000..0acd0391 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixInvertService.ts @@ -0,0 +1,48 @@ +import type { Matrix } from "../../Matrix"; + +/** + * @description マトリックスを逆変換 + * Invert the matrix + * + * @param {Matrix} matrix + * @return {void} + * @method + * @public + */ +export const execute = (matrix: Matrix): void => +{ + const a: number = matrix._$matrix[0]; + const b: number = matrix._$matrix[1]; + const c: number = matrix._$matrix[2]; + const d: number = matrix._$matrix[3]; + const tx: number = matrix._$matrix[4]; + const ty: number = matrix._$matrix[5]; + + if (b === 0 && c === 0) { + + matrix._$matrix[0] = 1 / a; + matrix._$matrix[1] = 0; + matrix._$matrix[2] = 0; + matrix._$matrix[3] = 1 / d; + matrix._$matrix[4] = -matrix._$matrix[0] * tx; + matrix._$matrix[5] = -matrix._$matrix[3] * ty; + + } else { + + const det = a * d - b * c; + + if (det) { + + const rdet: number = 1 / det; + + matrix._$matrix[0] = d * rdet; + matrix._$matrix[1] = -b * rdet; + matrix._$matrix[2] = -c * rdet; + matrix._$matrix[3] = a * rdet; + matrix._$matrix[4] = -(matrix._$matrix[0] * tx + matrix._$matrix[2] * ty); + matrix._$matrix[5] = -(matrix._$matrix[1] * tx + matrix._$matrix[3] * ty); + + } + + } +}; \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixRotateService.test.ts b/packages/geom/src/Matrix/service/MatrixRotateService.test.ts new file mode 100644 index 00000000..d87d46c4 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixRotateService.test.ts @@ -0,0 +1,177 @@ +import { Matrix } from "../../Matrix"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js rotate test", () => +{ + it("rotate test case1", () => + { + const matrix = new Matrix(1, 0, 0, 1, 100, 110); + matrix.rotate(45 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=0.7071067690849304, b=0.7071067690849304, c=-0.7071067690849304, d=0.7071067690849304, tx=-7.071067810058594, ty=148.492431640625)" + ); + }); + + it("rotate test case2", () => + { + const matrix = new Matrix(1, 0, 0, -1, 100, 110); + matrix.rotate(45 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=0.7071067690849304, b=0.7071067690849304, c=0.7071067690849304, d=-0.7071067690849304, tx=-7.071067810058594, ty=148.492431640625)" + ); + }); + + it("rotate test case3", () => + { + const matrix = new Matrix(-1, 0, 0, 1, 100, 110); + matrix.rotate(45 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=-0.7071067690849304, b=-0.7071067690849304, c=-0.7071067690849304, d=0.7071067690849304, tx=-7.071067810058594, ty=148.492431640625)" + ); + }); + + it("rotate test case4", () => + { + const matrix = new Matrix(-1, 0, 0, -1, 100, 110); + matrix.rotate(45 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=-0.7071067690849304, b=-0.7071067690849304, c=0.7071067690849304, d=-0.7071067690849304, tx=-7.071067810058594, ty=148.492431640625)" + ); + }); + + it("rotate test case5", () => + { + const matrix = new Matrix(1, 10, 10, 1, 100, 110); + matrix.rotate(45 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=-6.363961219787598, b=7.77817440032959, c=6.363961219787598, d=7.77817440032959, tx=-7.071067810058594, ty=148.492431640625)" + ); + }); + + it("rotate test case6", () => + { + const matrix = new Matrix(1, -10, 10, 1, 100, 110); + matrix.rotate(45 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=7.77817440032959, b=-6.363961219787598, c=6.363961219787598, d=7.77817440032959, tx=-7.071067810058594, ty=148.492431640625)" + ); + }); + + it("rotate test case7", () => + { + const matrix = new Matrix(1, 10, -10, 1, 100, 110); + matrix.rotate(45 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=-6.363961219787598, b=7.77817440032959, c=-7.77817440032959, d=-6.363961219787598, tx=-7.071067810058594, ty=148.492431640625)" + ); + }); + + it("rotate test case8", () => + { + const matrix = new Matrix(1, 10, 10, 1, -100, 110); + matrix.rotate(45 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=-6.363961219787598, b=7.77817440032959, c=6.363961219787598, d=7.77817440032959, tx=-148.492431640625, ty=7.071067810058594)" + ); + }); + + it("rotate test case9", () => + { + const matrix = new Matrix(1, 10, 10, 1, 100, -110); + matrix.rotate(45 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=-6.363961219787598, b=7.77817440032959, c=6.363961219787598, d=7.77817440032959, tx=148.492431640625, ty=-7.071067810058594)" + ); + }); + + it("rotate test case10", () => + { + const matrix = new Matrix(-1, -10, -10, -1, -100, -110); + matrix.rotate(45 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=6.363961219787598, b=-7.77817440032959, c=-6.363961219787598, d=-7.77817440032959, tx=7.071067810058594, ty=-148.492431640625)" + ); + }); + + it("rotate test case11", () => + { + const matrix = new Matrix(-1, -10, -10, -1, -100, -110); + matrix.rotate(0.5); + expect(matrix.toString()).toBe( + "(a=3.916672706604004, b=-9.255250930786133, c=-8.29640007019043, d=-5.67183780670166, tx=-35.021446228027344, ty=-144.4766387939453)" + ); + }); + + it("rotate test case12", () => + { + const matrix = new Matrix(-1, -10, -10, -1, -100, -110); + matrix.rotate(-0.5); + expect(matrix.toString()).toBe( + "(a=-5.67183780670166, b=-8.29640007019043, c=-9.255250930786133, d=3.916672706604004, tx=-140.4950714111328, ty=-48.591529846191406)" + ); + }); + + it("rotate test case13", () => + { + const matrix = new Matrix(-1, -10, -10, -1, -100, -110); + matrix.rotate(90 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=10, b=-1, c=1, d=-10, tx=110, ty=-100)" + ); + }); + + it("rotate test case14", () => + { + const matrix = new Matrix(-1, -10, -10, -1, -100, -110); + matrix.rotate(135 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=7.77817440032959, b=6.363961219787598, c=7.77817440032959, d=-6.363961219787598, tx=148.492431640625, ty=7.071067810058594)" + ); + }); + + it("rotate test case15", () => + { + const matrix = new Matrix(-1, -10, -10, -1, -100, -110); + matrix.rotate(Math.PI); + expect(matrix.toString()).toBe( + "(a=1, b=10, c=10, d=1, tx=100, ty=110)" + ); + }); + + it("rotate test case16", () => + { + const matrix = new Matrix(-1, -10, -10, -1, -100, -110); + matrix.rotate(-45 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=-7.77817440032959, b=-6.363961219787598, c=-7.77817440032959, d=6.363961219787598, tx=-148.492431640625, ty=-7.071067810058594)" + ); + }); + + it("rotate test case17", () => + { + const matrix = new Matrix(-1, -10, -10, -1, -100, -110); + matrix.rotate(-90 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=-10, b=1, c=-1, d=10, tx=-110, ty=100)" + ); + }); + + it("rotate test case18", () => + { + const matrix = new Matrix(-1, -10, -10, -1, -100, -110); + matrix.rotate(-135 / 180 * Math.PI); + expect(matrix.toString()).toBe( + "(a=-6.363961219787598, b=7.77817440032959, c=6.363961219787598, d=7.77817440032959, tx=-7.071067810058594, ty=148.492431640625)" + ); + }); + + it("rotate test case19", () => + { + const matrix = new Matrix(-1, -10, -10, -1, -100, -110); + matrix.rotate(-1 * Math.PI); + expect(matrix.toString()).toBe( + "(a=1, b=10, c=10, d=1, tx=100, ty=110)" + ); + }); + +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixRotateService.ts b/packages/geom/src/Matrix/service/MatrixRotateService.ts new file mode 100644 index 00000000..fd6e167b --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixRotateService.ts @@ -0,0 +1,29 @@ +import type { Matrix } from "../../Matrix"; + +/** + * @description マトリックスの回転変換 + * Rotate transformation of matrix + * + * @param {Matrix} matrix + * @return {void} + * @method + * @public + */ +export const execute = (matrix: Matrix, rotation: number): void => +{ + const array = matrix._$matrix; + + const a = array[0]; + const b = array[1]; + const c = array[2]; + const d = array[3]; + const tx = array[4]; + const ty = array[5]; + + array[0] = a * Math.cos(rotation) - b * Math.sin(rotation); + array[1] = a * Math.sin(rotation) + b * Math.cos(rotation); + array[2] = c * Math.cos(rotation) - d * Math.sin(rotation); + array[3] = c * Math.sin(rotation) + d * Math.cos(rotation); + array[4] = tx * Math.cos(rotation) - ty * Math.sin(rotation); + array[5] = tx * Math.sin(rotation) + ty * Math.cos(rotation); +}; \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixScaleService.test.ts b/packages/geom/src/Matrix/service/MatrixScaleService.test.ts new file mode 100644 index 00000000..4c47b339 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixScaleService.test.ts @@ -0,0 +1,40 @@ +import { Matrix } from "../../Matrix"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js scale test", () => +{ + it("scale test case1", () => + { + const matrix = new Matrix(1, 0.5, -0.5, 1, 0, 0); + matrix.scale(2, 2); + expect(matrix.toString()).toBe("(a=2, b=1, c=-1, d=2, tx=0, ty=0)"); + }); + + it("scale test case2", () => + { + const matrix = new Matrix(1, 0.5, -0.5, 1, 0, 0); + matrix.scale(2, 3); + expect(matrix.toString()).toBe("(a=2, b=1.5, c=-1, d=3, tx=0, ty=0)"); + }); + + it("scale test case3", () => + { + const matrix = new Matrix(1, 0.5, -0.5, 1, 0, 0); + matrix.scale(3, 2); + expect(matrix.toString()).toBe("(a=3, b=1, c=-1.5, d=2, tx=0, ty=0)"); + }); + + it("scale test case4", () => + { + const matrix = new Matrix(1, 0.5, -0.5, 1, 10, 0); + matrix.scale(-1, 2); + expect(matrix.toString()).toBe("(a=-1, b=1, c=0.5, d=2, tx=-10, ty=0)"); + }); + + it("scale test case5", () => + { + const matrix = new Matrix(1, 0.5, -0.5, 1, 0, 10); + matrix.scale(3, -2); + expect(matrix.toString()).toBe("(a=3, b=-1, c=-1.5, d=-2, tx=0, ty=-20)"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixScaleService.ts b/packages/geom/src/Matrix/service/MatrixScaleService.ts new file mode 100644 index 00000000..c4b8505b --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixScaleService.ts @@ -0,0 +1,25 @@ +import type { Matrix } from "../../Matrix"; + +/** + * @description マトリックスの拡大変換 + * Scale transformation of matrix + * + * @param {Matrix} matrix + * @param {number} scale_x + * @param {number} scale_y + * @return {void} + * @method + * @public + */ +export const execute = (matrix: Matrix, scale_x: number, scale_y: number): void => +{ + const array = matrix._$matrix; + + array[0] *= scale_x; + array[2] *= scale_x; + array[4] *= scale_x; + + array[1] *= scale_y; + array[3] *= scale_y; + array[5] *= scale_y; +}; \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixSetToService.test.ts b/packages/geom/src/Matrix/service/MatrixSetToService.test.ts new file mode 100644 index 00000000..39087a4b --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixSetToService.test.ts @@ -0,0 +1,20 @@ +import { Matrix } from "../../Matrix"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js setTo", () => +{ + it("copy test case1", () => + { + + const matrix = new Matrix(); + expect(matrix.toString()).toBe( + "(a=1, b=0, c=0, d=1, tx=0, ty=0)" + ); + + matrix.setTo(1, 2, 3, 4, 5, 6); + expect(matrix.toString()).toBe( + "(a=1, b=2, c=3, d=4, tx=5, ty=6)" + ); + + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixSetToService.ts b/packages/geom/src/Matrix/service/MatrixSetToService.ts new file mode 100644 index 00000000..87fca257 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixSetToService.ts @@ -0,0 +1,32 @@ +import type { Matrix } from "../../Matrix"; + +/** + * @description マトリックスの設定変換 + * Set transformation of matrix + * + * @param {Matrix} matrix + * @param {number} a + * @param {number} b + * @param {number} c + * @param {number} d + * @param {number} tx + * @param {number} ty + * @return {void} + * @method + * @public + */ +export const execute = ( + matrix: Matrix, + a: number, b: number, + c: number, d: number, + tx: number, ty: number +): void => { + + const array = matrix._$matrix; + array[0] = a; + array[1] = b; + array[2] = c; + array[3] = d; + array[4] = tx; + array[5] = ty; +}; \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixTransformPointService.test.ts b/packages/geom/src/Matrix/service/MatrixTransformPointService.test.ts new file mode 100644 index 00000000..723fb3dd --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixTransformPointService.test.ts @@ -0,0 +1,172 @@ +import { Matrix } from "../../Matrix"; +import { Point } from "../../Point"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js transformPoint test", () => +{ + it("transformPoint test case1", () => + { + const matrix = new Matrix(1, 0, 0, 1, 100, 110); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.transformPoint(point1); + + expect(point2.toString()).toBe( + "(x=-19.79898965358734, y=164.04878056049347)" + ); + }); + + it("transformPoint test case2", () => + { + const matrix = new Matrix(1, 1, 0, 1, 100, 110); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.transformPoint(point1); + + expect(point2.toString()).toBe( + "(x=-21.213203191757202, y=165.46299409866333)" + ); + }); + + it("transformPoint test case3", () => + { + const matrix = new Matrix(1, 0, 1, 1, 100, 110); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.transformPoint(point1); + + expect(point2.x | 0).toBe(-5); + expect(point2.y | 0).toBe(178); + + }); + + it("transformPoint test case4", () => + { + const matrix = new Matrix(1, 1, 1, 1, 100, 110); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.transformPoint(point1); + + expect(point2.x | 0).toBe(-7); + expect(point2.y | 0).toBe(179); + }); + + it("transformPoint test case5", () => + { + const matrix = new Matrix(-1, -1, -1, -1, 100, 110); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.transformPoint(point1); + + expect(point2.x | 0).toBe(-7); + expect(point2.y | 0).toBe(117); + }); + + it("transformPoint test case6", () => + { + const matrix = new Matrix(-1, -1, -1, -1, 100, 110); + matrix.rotate(45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.transformPoint(point1); + + expect(point2.x | 0).toBe(-7); + expect(point2.y | 0).toBe(117); + }); + + it("transformPoint test case7", () => + { + const matrix = new Matrix(-1, -1, -1, -1, 100, 110); + matrix.rotate(90 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.transformPoint(point1); + + expect(point2.toString()).toBe( + "(x=-88, y=78)" + ); + }); + + it("transformPoint test case8", () => + { + const matrix = new Matrix(-1, -1, -1, -1, 100, 110); + matrix.rotate(135 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.transformPoint(point1); + + expect(point2.toString()).toBe( + "(x=-117.37973380088806, y=-7.071067810058596)" + ); + }); + + it("transformPoint test case9", () => + { + const matrix = new Matrix(-1, -1, -1, -1, 100, 110); + matrix.rotate(180 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.transformPoint(point1); + + expect(point2.toString()).toBe( + "(x=-78, y=-88)" + ); + }); + + it("transformPoint test case10", () => + { + const matrix = new Matrix(-1, -1, -1, -1, 100, 110); + matrix.rotate(-45 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.transformPoint(point1); + + expect(point2.x | 0).toBe(117); + expect(point2.y | 0).toBe(7); + + }); + + it("transformPoint test case11", () => + { + const matrix = new Matrix(-1, -1, -1, -1, 100, 110); + matrix.rotate(-90 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.transformPoint(point1); + + expect(point2.toString()).toBe( + "(x=88, y=-78)" + ); + }); + + it("transformPoint test case12", () => + { + const matrix = new Matrix(-1, -1, -1, -1, 100, 110); + matrix.rotate(-135 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.transformPoint(point1); + + expect(point2.toString()).toBe( + "(x=7.071067810058591, y=-117.37973380088806)" + ); + }); + + it("transformPoint test case13", () => + { + const matrix = new Matrix(-1, -1, -1, -1, 100, 110); + matrix.rotate(-180 / 180 * Math.PI); + + const point1 = new Point(2, 20); + const point2 = matrix.transformPoint(point1); + + expect(point2.toString()).toBe( + "(x=-78, y=-88)" + ); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixTransformPointService.ts b/packages/geom/src/Matrix/service/MatrixTransformPointService.ts new file mode 100644 index 00000000..9497c51f --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixTransformPointService.ts @@ -0,0 +1,23 @@ +import type { Matrix } from "../../Matrix"; +import { Point } from "../../Point"; + +/** + * @description マトリックスの座標変換 + * Coordinate transformation of matrix + * + * @param {Matrix} matrix + * @param {Point} point + * @return {void} + * @method + * @public + */ +export const execute = (matrix: Matrix, point: Point): Point => +{ + const x = point.x; + const y = point.y; + const array = matrix._$matrix; + return new Point( + x * array[0] + y * array[2] + array[4], + x * array[1] + y * array[3] + array[5] + ); +}; \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixTranslateService.test.ts b/packages/geom/src/Matrix/service/MatrixTranslateService.test.ts new file mode 100644 index 00000000..71a8a8a1 --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixTranslateService.test.ts @@ -0,0 +1,37 @@ +import { Matrix } from "../../Matrix"; +import { describe, expect, it } from "vitest"; + +describe("Matrix.js translate", () => +{ + it("default test case1", () => + { + const matrix = new Matrix(); + expect(matrix.toString()).toBe("(a=1, b=0, c=0, d=1, tx=0, ty=0)"); + + matrix.translate(-100, -100); + expect(matrix.toString()).toBe("(a=1, b=0, c=0, d=1, tx=-100, ty=-100)"); + + matrix.scale(0.0, 1.0); + expect(matrix.toString()).toBe("(a=0, b=0, c=0, d=1, tx=0, ty=-100)"); + + matrix.translate(100, 100); + expect(matrix.toString()).toBe("(a=0, b=0, c=0, d=1, tx=100, ty=0)"); + }); + + it("pattern test case2", () => + { + const matrix = new Matrix(); + + // 単位行列化 + matrix.identity(); + // 拡大縮小成分を乗算 + matrix.scale( 256 / 1638.4 , 256 / 1638.4 ); + // 角度成分を乗算 + matrix.rotate(Math.PI / 180); + // 移動成分を乗算 + matrix.translate( 128.0 , 128.0 ); + + expect(matrix.toString()) + .toBe("(a=0.15622620284557343, b=0.0027269385755062103, c=-0.0027269385755062103, d=0.15622620284557343, tx=128, ty=128)"); + }); +}); \ No newline at end of file diff --git a/packages/geom/src/Matrix/service/MatrixTranslateService.ts b/packages/geom/src/Matrix/service/MatrixTranslateService.ts new file mode 100644 index 00000000..e7becf4e --- /dev/null +++ b/packages/geom/src/Matrix/service/MatrixTranslateService.ts @@ -0,0 +1,18 @@ +import type { Matrix } from "../../Matrix"; + +/** + * @description マトリックスの座標移動 + * Coordinate movement of matrix + * + * @param {Matrix} matrix + * @param {number} dx + * @param {number} dy + * @return {void} + * @method + * @public + */ +export const execute = (matrix: Matrix, dx: number, dy: number): void => +{ + matrix.tx += dx; + matrix.ty += dy; +}; \ No newline at end of file From 98a1220d6ade73d147fe043c221bdf7af3ea2bab Mon Sep 17 00:00:00 2001 From: ienaga Date: Wed, 24 Jul 2024 06:19:52 +0900 Subject: [PATCH 010/343] =?UTF-8?q?#154=20feat:=20Easing=E3=82=92=E7=A7=BB?= =?UTF-8?q?=E6=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/next2d/ui/EasingTest.ts | 196 ------------------ packages/geom/src/Transform.ts | 67 +++--- packages/ui/src/Easing.test.ts | 31 +++ packages/ui/src/Easing.ts | 158 ++++++-------- .../service/EasingInBackService.test.ts | 10 + .../src/Easing/service/EasingInBackService.ts | 15 ++ .../service/EasingInBounceService.test.ts | 10 + .../Easing/service/EasingInBounceService.ts | 17 ++ .../service/EasingInCircService.test.ts | 10 + .../src/Easing/service/EasingInCircService.ts | 15 ++ .../service/EasingInCubicService.test.ts | 10 + .../Easing/service/EasingInCubicService.ts | 15 ++ .../service/EasingInElasticService.test.ts | 10 + .../Easing/service/EasingInElasticService.ts | 21 ++ .../service/EasingInExpoService.test.ts | 10 + .../src/Easing/service/EasingInExpoService.ts | 15 ++ .../service/EasingInOutBackService.test.ts | 10 + .../Easing/service/EasingInOutBackService.ts | 18 ++ .../service/EasingInOutBounceService.test.ts | 11 + .../service/EasingInOutBounceService.ts | 19 ++ .../service/EasingInOutCircService.test.ts | 10 + .../Easing/service/EasingInOutCircService.ts | 17 ++ .../service/EasingInOutCubicService.test.ts | 10 + .../Easing/service/EasingInOutCubicService.ts | 17 ++ .../service/EasingInOutElasticService.test.ts | 10 + .../service/EasingInOutElasticService.ts | 21 ++ .../service/EasingInOutExpoService.test.ts | 10 + .../Easing/service/EasingInOutExpoService.ts | 17 ++ .../service/EasingInOutQuadService.test.ts | 10 + .../Easing/service/EasingInOutQuadService.ts | 17 ++ .../service/EasingInOutQuartService.test.ts | 10 + .../Easing/service/EasingInOutQuartService.ts | 17 ++ .../service/EasingInOutQuintService.test.ts | 10 + .../Easing/service/EasingInOutQuintService.ts | 17 ++ .../service/EasingInOutSineService.test.ts | 10 + .../Easing/service/EasingInOutSineService.ts | 15 ++ .../service/EasingInQuadService.test.ts | 10 + .../src/Easing/service/EasingInQuadService.ts | 15 ++ .../service/EasingInQuartService.test.ts | 10 + .../Easing/service/EasingInQuartService.ts | 15 ++ .../service/EasingInQuintService.test.ts | 10 + .../Easing/service/EasingInQuintService.ts | 15 ++ .../service/EasingInSineService.test.ts | 10 + .../src/Easing/service/EasingInSineService.ts | 15 ++ .../service/EasingLinearService.test.ts | 10 + .../src/Easing/service/EasingLinearService.ts | 15 ++ .../service/EasingOutBackService.test.ts | 10 + .../Easing/service/EasingOutBackService.ts | 18 ++ .../service/EasingOutBounceService.test.ts | 10 + .../Easing/service/EasingOutBounceService.ts | 24 +++ .../service/EasingOutCircService.test.ts | 10 + .../Easing/service/EasingOutCircService.ts | 16 ++ .../service/EasingOutCubicService.test.ts | 10 + .../Easing/service/EasingOutCubicService.ts | 16 ++ .../service/EasingOutElasticService.test.ts | 10 + .../Easing/service/EasingOutElasticService.ts | 21 ++ .../service/EasingOutExpoService.test.ts | 10 + .../Easing/service/EasingOutExpoService.ts | 15 ++ .../service/EasingOutQuadService.test.ts | 10 + .../Easing/service/EasingOutQuadService.ts | 15 ++ .../service/EasingOutQuartService.test.ts | 10 + .../Easing/service/EasingOutQuartService.ts | 16 ++ .../service/EasingOutQuintService.test.ts | 10 + .../Easing/service/EasingOutQuintService.ts | 16 ++ .../service/EasingOutSineService.test.ts | 10 + .../Easing/service/EasingOutSineService.ts | 15 ++ 66 files changed, 966 insertions(+), 317 deletions(-) delete mode 100644 __tests__/next2d/ui/EasingTest.ts create mode 100644 packages/ui/src/Easing.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInBackService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInBackService.ts create mode 100644 packages/ui/src/Easing/service/EasingInBounceService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInBounceService.ts create mode 100644 packages/ui/src/Easing/service/EasingInCircService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInCircService.ts create mode 100644 packages/ui/src/Easing/service/EasingInCubicService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInCubicService.ts create mode 100644 packages/ui/src/Easing/service/EasingInElasticService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInElasticService.ts create mode 100644 packages/ui/src/Easing/service/EasingInExpoService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInExpoService.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutBackService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutBackService.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutBounceService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutBounceService.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutCircService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutCircService.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutCubicService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutCubicService.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutElasticService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutElasticService.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutExpoService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutExpoService.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutQuadService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutQuadService.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutQuartService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutQuartService.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutQuintService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutQuintService.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutSineService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInOutSineService.ts create mode 100644 packages/ui/src/Easing/service/EasingInQuadService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInQuadService.ts create mode 100644 packages/ui/src/Easing/service/EasingInQuartService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInQuartService.ts create mode 100644 packages/ui/src/Easing/service/EasingInQuintService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInQuintService.ts create mode 100644 packages/ui/src/Easing/service/EasingInSineService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingInSineService.ts create mode 100644 packages/ui/src/Easing/service/EasingLinearService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingLinearService.ts create mode 100644 packages/ui/src/Easing/service/EasingOutBackService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingOutBackService.ts create mode 100644 packages/ui/src/Easing/service/EasingOutBounceService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingOutBounceService.ts create mode 100644 packages/ui/src/Easing/service/EasingOutCircService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingOutCircService.ts create mode 100644 packages/ui/src/Easing/service/EasingOutCubicService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingOutCubicService.ts create mode 100644 packages/ui/src/Easing/service/EasingOutElasticService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingOutElasticService.ts create mode 100644 packages/ui/src/Easing/service/EasingOutExpoService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingOutExpoService.ts create mode 100644 packages/ui/src/Easing/service/EasingOutQuadService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingOutQuadService.ts create mode 100644 packages/ui/src/Easing/service/EasingOutQuartService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingOutQuartService.ts create mode 100644 packages/ui/src/Easing/service/EasingOutQuintService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingOutQuintService.ts create mode 100644 packages/ui/src/Easing/service/EasingOutSineService.test.ts create mode 100644 packages/ui/src/Easing/service/EasingOutSineService.ts diff --git a/__tests__/next2d/ui/EasingTest.ts b/__tests__/next2d/ui/EasingTest.ts deleted file mode 100644 index cce330c4..00000000 --- a/__tests__/next2d/ui/EasingTest.ts +++ /dev/null @@ -1,196 +0,0 @@ -import { Easing } from "../../../packages/ui/src/Easing"; - -describe("Easing.js toString test", function() -{ - it("toString test success", function() - { - let object = new Easing(); - expect(object.toString()).toBe("[object Easing]"); - }); - -}); - -describe("Easing.js static toString test", function() -{ - - it("static toString test", function() - { - expect(Easing.toString()).toBe("[class Easing]"); - }); - -}); - -describe("Easing.js namespace test", function() -{ - - it("namespace test public", function() - { - expect(new Easing().namespace).toBe("next2d.ui.Easing"); - }); - - it("namespace test static", function() - { - expect(Easing.namespace).toBe("next2d.ui.Easing"); - }); - -}); - -describe("Easing.js method test", function() -{ - it("linear method test", function() - { - expect(Easing.linear(0.1, 0.5, 0.5, 1)).toBe(0.55); - }); - - it("inQuad method test", function() - { - expect(Easing.inQuad(0.1, 0.5, 0.5, 1)).toBe(0.505); - }); - - it("outQuad method test", function() - { - expect(Easing.outQuad(0.1, 0.5, 0.5, 1)).toBe(0.595); - }); - - it("inOutQuad method test", function() - { - expect(Easing.inOutQuad(0.1, 0.5, 0.5, 1)).toBe(0.51); - }); - - it("inCubic method test", function() - { - expect(Easing.inCubic(0.1, 0.5, 0.5, 1)).toBe(0.5005); - }); - - it("outCubic method test", function() - { - expect(Easing.outCubic(0.1, 0.5, 0.5, 1)).toBe(0.6355); - }); - - it("inOutCubic method test", function() - { - expect(Easing.inOutCubic(0.1, 0.5, 0.5, 1)).toBe(0.502); - }); - - it("inQuart method test", function() - { - expect(Easing.inQuart(0.1, 0.5, 0.5, 1)).toBe(0.50005); - }); - - it("outQuart method test", function() - { - expect(Easing.outQuart(0.1, 0.5, 0.5, 1)).toBe(0.6719499999999999); - }); - - it("inOutQuart method test", function() - { - expect(Easing.inOutQuart(0.1, 0.5, 0.5, 1)).toBe(0.5004); - }); - - it("inQuint method test", function() - { - expect(Easing.inQuint(0.1, 0.5, 0.5, 1)).toBe(0.500005); - }); - - it("outQuint method test", function() - { - expect(Easing.outQuint(0.1, 0.5, 0.5, 1)).toBe(0.7047549999999999); - }); - - it("inOutQuint method test", function() - { - expect(Easing.inOutQuint(0.1, 0.5, 0.5, 1)).toBe(0.50008); - }); - - it("inSine method test", function() - { - expect(Easing.inSine(0.1, 0.5, 0.5, 1)).toBe(0.5061558297024311); - }); - - it("outSine method test", function() - { - expect(Easing.outSine(0.1, 0.5, 0.5, 1)).toBe(0.5782172325201155); - }); - - it("inOutSine method test", function() - { - expect(Easing.inOutSine(0.1, 0.5, 0.5, 1)).toBe(0.5122358709262116); - }); - - it("inExpo method test", function() - { - expect(Easing.inExpo(0.1, 0.5, 0.5, 1)).toBe(0.5009765625); - }); - - it("outExpo method test", function() - { - expect(Easing.outExpo(0.1, 0.5, 0.5, 1)).toBe(0.75); - }); - - it("inOutExpo method test", function() - { - expect(Easing.inOutExpo(0.1, 0.5, 0.5, 1)).toBe(0.5009765625); - }); - - it("inCirc method test", function() - { - expect(Easing.inCirc(0.1, 0.5, 0.5, 1)).toBe(0.5025062814466901); - }); - - it("outCirc method test", function() - { - expect(Easing.outCirc(0.1, 0.5, 0.5, 1)).toBe(0.7179449471770336); - }); - - it("inOutCirc method test", function() - { - expect(Easing.inOutCirc(0.1, 0.5, 0.5, 1)).toBe(0.5003126955570227); - }); - - it("inBack method test", function() - { - expect(Easing.inBack(0.1, 0.5, 0.5, 1)).toBe(0.49284289); - }); - - it("outBack method test", function() - { - expect(Easing.outBack(0.1, 0.5, 0.5, 1)).toBe(0.7044139899999999); - }); - - it("inOutBack method test", function() - { - expect(Easing.inOutBack(0.1, 0.5, 0.5, 1)).toBe(0.481240724); - }); - - it("inElastic method test", function() - { - expect(Easing.inElastic(0.1, 0.5, 0.5, 1)).toBe(0.5009765625); - }); - - it("outElastic method test", function() - { - expect(Easing.outElastic(0.1, 0.5, 0.5, 1)).toBe(1.125); - }); - - it("inOutElastic method test", function() - { - expect(Easing.inOutElastic(0.1, 0.5, 0.5, 1)).toBe(0.5001695782985028); - }); - - it("outBounce method test", function() - { - expect(Easing.outBounce(0.1, 0.5, 0.5, 1)).toBe(0.5378125); - }); - - it("inBounce method test", function() - { - expect(Easing.inBounce(0.1, 0.5, 0.5, 1)).toBe(0.5059375); - }); - - it("inOutBounce method test", function() - { - expect(Easing.inOutBounce(0.1, 0.5, 0.5, 1)).toBe(0.515); - }); - -}); - diff --git a/packages/geom/src/Transform.ts b/packages/geom/src/Transform.ts index 563c768c..39428dab 100644 --- a/packages/geom/src/Transform.ts +++ b/packages/geom/src/Transform.ts @@ -27,9 +27,6 @@ import { } from "@next2d/util"; import { $Array, - $Math, - $MATRIX_ARRAY_IDENTITY, - $COLOR_ARRAY_IDENTITY, $doUpdated, $getFloat32Array6, $getArray, @@ -41,29 +38,36 @@ import { } from "@next2d/share"; /** - * Transform クラスは、表示オブジェクトに適用されるカラー調整プロパティと 2 次元の変換オブジェクトへのアクセスを提供します。 - * 変換時に、表示オブジェクトのカラーまたは方向と位置が、現在の値または座標から新しい値または座標に調整(オフセット)されます。 - * Transform クラスは、表示オブジェクトおよびすべての親オブジェクトに適用されるカラー変換と 2 次元マトリックス変換に関するデータも収集します。 - * concatenatedColorTransform プロパティと concatenatedMatrix プロパティを使用して、これらの結合された変換にアクセスできます。 - * カラー変換を適用するには、ColorTransform オブジェクトを作成し、オブジェクトのメソッドとプロパティを使用してカラー調整を設定した後、 - * colorTransformation プロパティ(表示オブジェクトの transform プロパティの)を新しい ColorTransformation オブジェクトに割り当てます。 - * 2 次元変換を適用するには、Matrix オブジェクトを作成し、マトリックスの 2 次元変換を設定した後、表示オブジェクトの transform.matrix プロパティを新しい Matrix オブジェクトに割り当てます。 - * - * The Transform class provides access to color adjustment properties and two--dimensional transformation objects that can be applied to a display object. - * During the transformation, the color or the orientation and position of a display object is adjusted (offset) from the current values or coordinates to new values or coordinates. - * The Transform class also collects data about color and two-dimensional matrix transformations that are applied to a display object and all of its parent objects. - * You can access these combined transformations through the concatenatedColorTransform and concatenatedMatrix properties. - * To apply color transformations: create a ColorTransform object, - * set the color adjustments using the object's methods and properties, - * and then assign the colorTransformation property of the transform property of the display object to the new ColorTransformation object. - * To apply two-dimensional transformations: create a Matrix object, - * set the matrix's two-dimensional transformation, - * and then assign the transform.matrix property of the display object to the new Matrix object. + * @type {Float32Array} + * @private + */ +const $MATRIX_ARRAY_IDENTITY: Float32Array = new Float32Array([1, 0, 0, 1, 0, 0]); + +/** + * @type {Float32Array} + * @private + */ +const $COLOR_ARRAY_IDENTITY: Float32Array = new Float32Array([1, 1, 1, 1, 0, 0, 0, 0]); + +/** + * @description Transform クラスは、表示オブジェクトに適用されるカラー調整プロパティと 2 次元の変換オブジェクトへのアクセスを提供します。 + * 変換時に、表示オブジェクトのカラーまたは方向と位置が、現在の値または座標から新しい値または座標に調整(オフセット)されます。 + * Transform クラスは、表示オブジェクトおよびすべての親オブジェクトに適用されるカラー変換と 2 次元マトリックス変換に関するデータも収集します。 + * concatenatedColorTransform プロパティと concatenatedMatrix プロパティを使用して、これらの結合された変換にアクセスできます。 + * カラー変換を適用するには、ColorTransform オブジェクトを作成し、オブジェクトのメソッドとプロパティを使用してカラー調整を設定した後、 + * colorTransformation プロパティ(表示オブジェクトの transform プロパティの)を新しい ColorTransformation オブジェクトに割り当てます。 + * 2 次元変換を適用するには、Matrix オブジェクトを作成し、マトリックスの 2 次元変換を設定した後、表示オブジェクトの transform.matrix プロパティを新しい Matrix オブジェクトに割り当てます。 * - * @example Example usage of Transform. - * // new Transform - * const {Transform} = next2d.geom; - * const transform = new Transform(displayObject); + * The Transform class provides access to color adjustment properties and two--dimensional transformation objects that can be applied to a display object. + * During the transformation, the color or the orientation and position of a display object is adjusted (offset) from the current values or coordinates to new values or coordinates. + * The Transform class also collects data about color and two-dimensional matrix transformations that are applied to a display object and all of its parent objects. + * You can access these combined transformations through the concatenatedColorTransform and concatenatedMatrix properties. + * To apply color transformations: create a ColorTransform object, + * set the color adjustments using the object's methods and properties, + * and then assign the colorTransformation property of the transform property of the display object to the new ColorTransformation object. + * To apply two-dimensional transformations: create a Matrix object, + * set the matrix's two-dimensional transformation, + * and then assign the transform.matrix property of the display object to the new Matrix object. * * @class * @memberOf next2d.geom @@ -82,7 +86,7 @@ export class Transform * @constructor * @public */ - constructor (src: DisplayObjectImpl) + constructor (src: DisplayObjectImpl = null) { /** * @type {DisplayObject} @@ -124,7 +128,7 @@ export class Transform * Returns the string representation of the specified class. * * @return {string} - * @default [class Transform] + * @default "[class Transform]" * @method * @static */ @@ -138,7 +142,7 @@ export class Transform * Returns the space name of the specified class. * * @member {string} - * @default next2d.geom.Transform + * @default "next2d.geom.Transform" * @const * @static */ @@ -152,6 +156,7 @@ export class Transform * Returns the string representation of the specified object. * * @return {string} + * @default "[object Transform]" * @method * @public */ @@ -165,7 +170,7 @@ export class Transform * Returns the space name of the specified object. * * @member {string} - * @default next2d.geom.Transform + * @default "next2d.geom.Transform" * @const * @public */ @@ -339,8 +344,8 @@ export class Transform const rectangle: Rectangle = new Rectangle( bounds.xMin, bounds.yMin, - +$Math.abs(bounds.xMax - bounds.xMin), - +$Math.abs(bounds.yMax - bounds.yMin) + +Math.abs(bounds.xMax - bounds.xMin), + +Math.abs(bounds.yMax - bounds.yMin) ); $poolBoundsObject(bounds); diff --git a/packages/ui/src/Easing.test.ts b/packages/ui/src/Easing.test.ts new file mode 100644 index 00000000..9abf36f8 --- /dev/null +++ b/packages/ui/src/Easing.test.ts @@ -0,0 +1,31 @@ +import { Easing } from "./Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js toString test", function() +{ + it("toString test success", function() + { + expect(new Easing().toString()).toBe("[object Easing]"); + }); +}); + +describe("Easing.js static toString test", function() +{ + it("static toString test", function() + { + expect(Easing.toString()).toBe("[class Easing]"); + }); +}); + +describe("Easing.js namespace test", function() +{ + it("namespace test public", function() + { + expect(new Easing().namespace).toBe("next2d.ui.Easing"); + }); + + it("namespace test static", function() + { + expect(Easing.namespace).toBe("next2d.ui.Easing"); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing.ts b/packages/ui/src/Easing.ts index 25009707..d8638235 100644 --- a/packages/ui/src/Easing.ts +++ b/packages/ui/src/Easing.ts @@ -1,8 +1,38 @@ -import { $Math } from "@next2d/share"; +import { execute as easingLinearService } from "./Easing/service/EasingLinearService"; +import { execute as easingInQuadService } from "./Easing/service/EasingInQuadService"; +import { execute as easingOutQuadService } from "./Easing/service/EasingOutQuadService"; +import { execute as easingInOutQuadService } from "./Easing/service/EasingInOutQuadService"; +import { execute as easingInCubicService } from "./Easing/service/EasingInCubicService"; +import { execute as easingOutCubicService } from "./Easing/service/EasingOutCubicService"; +import { execute as easingInOutCubicService } from "./Easing/service/EasingInOutCubicService"; +import { execute as easingInQuartService } from "./Easing/service/EasingInQuartService"; +import { execute as easingOutQuartService } from "./Easing/service/EasingOutQuartService"; +import { execute as easingInOutQuartService } from "./Easing/service/EasingInOutQuartService"; +import { execute as easingInQuintService } from "./Easing/service/EasingInQuintService"; +import { execute as easingOutQuintService } from "./Easing/service/EasingOutQuintService"; +import { execute as easingInOutQuintService } from "./Easing/service/EasingInOutQuintService"; +import { execute as easingInSineService } from "./Easing/service/EasingInSineService"; +import { execute as easingOutSineService } from "./Easing/service/EasingOutSineService"; +import { execute as easingInOutSineService } from "./Easing/service/EasingInOutSineService"; +import { execute as easingInExpoService } from "./Easing/service/EasingInExpoService"; +import { execute as easingOutExpoService } from "./Easing/service/EasingOutExpoService"; +import { execute as easingInOutExpoService } from "./Easing/service/EasingInOutExpoService"; +import { execute as easingInCircService } from "./Easing/service/EasingInCircService"; +import { execute as easingOutCircService } from "./Easing/service/EasingOutCircService"; +import { execute as easingInOutCircService } from "./Easing/service/EasingInOutCircService"; +import { execute as easingInBackService } from "./Easing/service/EasingInBackService"; +import { execute as easingOutBackService } from "./Easing/service/EasingOutBackService"; +import { execute as easingInOutBackService } from "./Easing/service/EasingInOutBackService"; +import { execute as easingInElasticService } from "./Easing/service/EasingInElasticService"; +import { execute as easingOutElasticService } from "./Easing/service/EasingOutElasticService"; +import { execute as easingInOutElasticService } from "./Easing/service/EasingInOutElasticService"; +import { execute as easingOutBounceService } from "./Easing/service/EasingOutBounceService"; +import { execute as easingInBounceService } from "./Easing/service/EasingInBounceService"; +import { execute as easingInOutBounceService } from "./Easing/service/EasingInOutBounceService"; /** - * Easeクラスは、イージング機能の関数を提供します。 - * The Ease class provides a collection of easing functions + * @description Easeクラスは、イージング機能の関数を提供します。 + * The Ease class provides a collection of easing functions * * @class * @memberOf next2d.ui @@ -14,7 +44,7 @@ export class Easing * Returns the string representation of the specified class. * * @return {string} - * @default [class Easing] + * @default "[class Easing]" * @method * @static */ @@ -28,7 +58,7 @@ export class Easing * Returns the space name of the specified class. * * @return {string} - * @default next2d.ui.Easing + * @default "next2d.ui.Easing" * @const * @static */ @@ -42,7 +72,7 @@ export class Easing * Returns the string representation of the specified object. * * @return {string} - * @default [object Easing] + * @default "[object Easing]" * @method * @public */ @@ -56,7 +86,7 @@ export class Easing * Returns the space name of the specified object. * * @return {string} - * @default next2d.ui.Easing + * @default "next2d.ui.Easing" * @const * @public */ @@ -76,7 +106,7 @@ export class Easing */ static linear (t: number, b: number, c: number, d: number): number { - return t / d * c + b; + return easingLinearService(t, b, c, d); } /** @@ -90,7 +120,7 @@ export class Easing */ static inQuad (t: number, b: number, c: number, d: number): number { - return (t /= d) * t * c + b; + return easingInQuadService(t, b, c, d); } /** @@ -104,7 +134,7 @@ export class Easing */ static outQuad (t: number, b: number, c: number, d: number): number { - return -(t /= d) * (t - 2) * c + b; + return easingOutQuadService(t, b, c, d); } /** @@ -118,9 +148,7 @@ export class Easing */ static inOutQuad (t: number, b: number, c: number, d: number): number { - return (t /= d / 2) < 1 - ? t * t * c / 2 + b - : -((t -= 1) * (t - 2) - 1) * c / 2 + b; + return easingInOutQuadService(t, b, c, d); } /** @@ -134,7 +162,7 @@ export class Easing */ static inCubic (t: number, b: number, c: number, d: number): number { - return (t /= d) * t * t * c + b; + return easingInCubicService(t, b, c, d); } /** @@ -148,8 +176,7 @@ export class Easing */ static outCubic (t: number, b: number, c: number, d: number): number { - t /= d; - return (--t * t * t + 1) * c + b; + return easingOutCubicService(t, b, c, d); } /** @@ -163,9 +190,7 @@ export class Easing */ static inOutCubic (t: number, b: number, c: number, d: number): number { - return (t /= d / 2) < 1 - ? t * t * t * c / 2 + b - : ((t -= 2) * t * t + 2) * c / 2 + b; + return easingInOutCubicService(t, b, c, d); } /** @@ -179,7 +204,7 @@ export class Easing */ static inQuart (t: number, b: number, c: number, d: number): number { - return (t /= d) * t * t * t * c + b; + return easingInQuartService(t, b, c, d); } /** @@ -193,8 +218,7 @@ export class Easing */ static outQuart (t: number, b: number, c: number, d: number): number { - t /= d; - return (--t * t * t * t - 1) * -c + b; + return easingOutQuartService(t, b, c, d); } /** @@ -208,9 +232,7 @@ export class Easing */ static inOutQuart (t: number, b: number, c: number, d: number): number { - return (t /= d / 2) < 1 - ? t * t * t * t * c / 2 + b - : ((t -= 2) * t * t * t - 2) * -c / 2 + b; + return easingInOutQuartService(t, b, c, d); } /** @@ -224,7 +246,7 @@ export class Easing */ static inQuint (t: number, b: number, c: number, d: number): number { - return (t /= d) * t * t * t * t * c + b; + return easingInQuintService(t, b, c, d); } /** @@ -238,8 +260,7 @@ export class Easing */ static outQuint (t: number, b: number, c: number, d: number): number { - t /= d; - return (--t * t * t * t * t + 1) * c + b; + return easingOutQuintService(t, b, c, d); } /** @@ -253,9 +274,7 @@ export class Easing */ static inOutQuint (t: number, b: number, c: number, d: number): number { - return (t /= d / 2) < 1 - ? t * t * t * t * t * c / 2 + b - : ((t -= 2) * t * t * t * t + 2) * c / 2 + b; + return easingInOutQuintService(t, b, c, d); } /** @@ -269,7 +288,7 @@ export class Easing */ static inSine (t: number, b: number, c: number, d: number): number { - return -c * $Math.cos(t / d * ($Math.PI / 2)) + c + b; + return easingInSineService(t, b, c, d); } /** @@ -283,7 +302,7 @@ export class Easing */ static outSine (t: number, b: number, c: number, d: number): number { - return c * $Math.sin(t / d * ($Math.PI / 2)) + b; + return easingOutSineService(t, b, c, d); } /** @@ -297,7 +316,7 @@ export class Easing */ static inOutSine (t: number, b: number, c: number, d: number): number { - return -c / 2 * ($Math.cos($Math.PI * t / d) - 1) + b; + return easingInOutSineService(t, b, c, d); } /** @@ -311,7 +330,7 @@ export class Easing */ static inExpo (t: number, b: number, c: number, d: number): number { - return c * $Math.pow(2, 10 * (t / d - 1) ) + b; + return easingInExpoService(t, b, c, d); } /** @@ -325,7 +344,7 @@ export class Easing */ static outExpo (t: number, b: number, c: number, d: number): number { - return c * (-$Math.pow(2, -10 * t / d) + 1) + b; + return easingOutExpoService(t, b, c, d); } /** @@ -339,9 +358,7 @@ export class Easing */ static inOutExpo (t: number, b: number, c: number, d: number): number { - return (t /= d / 2) < 1 - ? c / 2 * $Math.pow(2, 10 * (t - 1)) + b - : c / 2 * (-$Math.pow(2, -10 * (t - 1)) + 2) + b; + return easingInOutExpoService(t, b, c, d); } /** @@ -355,7 +372,7 @@ export class Easing */ static inCirc (t: number, b: number, c: number, d: number): number { - return (1 - $Math.sqrt(1 - (t /= d) * t)) * c + b; + return easingInCircService(t, b, c, d); } /** @@ -369,8 +386,7 @@ export class Easing */ static outCirc (t: number, b: number, c: number, d: number): number { - t /= d; - return $Math.sqrt(1 - --t * t) * c + b; + return easingOutCircService(t, b, c, d); } /** @@ -384,9 +400,7 @@ export class Easing */ static inOutCirc (t: number, b: number, c: number, d: number): number { - return (t /= d * 2) < 1 - ? ($Math.sqrt(1 - t * t) - 1) / -2 * c + b - : ($Math.sqrt(1 - (t -= 2) * t) + 1) / 2 * c + b; + return easingInOutCircService(t, b, c, d); } /** @@ -400,7 +414,7 @@ export class Easing */ static inBack (t: number, b: number, c: number, d: number): number { - return (2.70158 * (t /= d) * t * t - 1.70158 * t * t) * c + b; + return easingInBackService(t, b, c, d); } /** @@ -414,10 +428,7 @@ export class Easing */ static outBack (t: number, b: number, c: number, d: number): number { - return (1 + 2.70158 - * $Math.pow((t /= d) - 1, 3) + 1.70158 - * $Math.pow(t - 1, 2) - ) * c + b; + return easingOutBackService(t, b, c, d); } /** @@ -431,11 +442,7 @@ export class Easing */ static inOutBack (t: number, b: number, c: number, d: number): number { - let s = 1.70158; - if ((t /= d / 2) < 1) { - return t * t * (((s *= 1.525) + 1) * t - s) * c / 2 + b; - } - return ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) * c / 2 + b; + return easingInOutBackService(t, b, c, d); } /** @@ -449,13 +456,7 @@ export class Easing */ static inElastic (t: number, b: number, c: number, d: number): number { - return (t /= d) === 0 - ? b - : t === 1 - ? c + b - : -$Math.pow(2, (t *= 10) - 10) - * $Math.sin((t - 10.75) * (2 * $Math.PI / 3)) - * c + b; + return easingInElasticService(t, b, c, d); } /** @@ -469,13 +470,7 @@ export class Easing */ static outElastic (t: number, b: number, c: number, d: number): number { - return (t /= d) === 0 - ? b - : t === 1 - ? c + b - : ($Math.pow(2, -10 * t) - * $Math.sin((t * 10 - 0.75) * (2 * $Math.PI / 3)) + 1) - * c + b; + return easingOutElasticService(t, b, c, d); } /** @@ -489,13 +484,7 @@ export class Easing */ static inOutElastic (t: number, b: number, c: number, d: number): number { - return (t /= d) === 0 - ? b - : t === 1 - ? c + b - : t < 0.5 - ? -($Math.pow(2, 20 * t - 10) * $Math.sin((20 * t - 11.125) * (2 * $Math.PI / 4.5))) / 2 * c + b - : ($Math.pow(2, -20 * t + 10) * $Math.sin((20 * t - 11.125) * (2 * $Math.PI / 4.5)) / 2 + 1) * c + b; + return easingInOutElasticService(t, b, c, d); } /** @@ -509,16 +498,7 @@ export class Easing */ static outBounce (t: number, b: number, c: number, d: number): number { - if ((t /= d) < 1 / 2.75) { - return 7.5625 * t * t * c + b; - } - if (t < 2 / 2.75) { - return (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) * c + b; - } - if (t < 2.5 / 2.75) { - return (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) * c + b; - } - return (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) * c + b; + return easingOutBounceService(t, b, c, d); } /** @@ -532,7 +512,7 @@ export class Easing */ static inBounce (t: number, b: number, c: number, d: number): number { - return c - Easing.outBounce(d - t, 0, c, d) + b; + return easingInBounceService(t, b, c, d); } /** @@ -546,8 +526,6 @@ export class Easing */ static inOutBounce (t: number, b: number, c: number, d: number): number { - return t < d / 2 - ? Easing.inBounce(t * 2, b, c / 2, d) - : Easing.outBounce(t * 2 - d, b + c / 2, c / 2, d); + return easingInOutBounceService(t, b, c, d); } } diff --git a/packages/ui/src/Easing/service/EasingInBackService.test.ts b/packages/ui/src/Easing/service/EasingInBackService.test.ts new file mode 100644 index 00000000..1f0995b5 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInBackService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inCubic method test", function() + { + expect(Easing.inCirc(0.1, 0.5, 0.5, 1)).toBe(0.5025062814466901); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInBackService.ts b/packages/ui/src/Easing/service/EasingInBackService.ts new file mode 100644 index 00000000..58dd6f1c --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInBackService.ts @@ -0,0 +1,15 @@ +/** + * @description Easing in back service + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (2.70158 * (t /= d) * t * t - 1.70158 * t * t) * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInBounceService.test.ts b/packages/ui/src/Easing/service/EasingInBounceService.test.ts new file mode 100644 index 00000000..cdaa82d6 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInBounceService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inBounce method test", function() + { + expect(Easing.inBounce(0.1, 0.5, 0.5, 1)).toBe(0.5059375); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInBounceService.ts b/packages/ui/src/Easing/service/EasingInBounceService.ts new file mode 100644 index 00000000..ab8daa34 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInBounceService.ts @@ -0,0 +1,17 @@ +import { Easing } from "../../Easing"; + +/** + * @description Easing out bounce function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return c - Easing.outBounce(d - t, 0, c, d) + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInCircService.test.ts b/packages/ui/src/Easing/service/EasingInCircService.test.ts new file mode 100644 index 00000000..1f41d58d --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInCircService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inBack method test", function() + { + expect(Easing.inBack(0.1, 0.5, 0.5, 1)).toBe(0.49284289); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInCircService.ts b/packages/ui/src/Easing/service/EasingInCircService.ts new file mode 100644 index 00000000..7204efa6 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInCircService.ts @@ -0,0 +1,15 @@ +/** + * @description Easing in circ service + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (1 - Math.sqrt(1 - (t /= d) * t)) * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInCubicService.test.ts b/packages/ui/src/Easing/service/EasingInCubicService.test.ts new file mode 100644 index 00000000..4b35f5f6 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInCubicService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inCubic method test", function() + { + expect(Easing.inCubic(0.1, 0.5, 0.5, 1)).toBe(0.5005); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInCubicService.ts b/packages/ui/src/Easing/service/EasingInCubicService.ts new file mode 100644 index 00000000..cc0ff288 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInCubicService.ts @@ -0,0 +1,15 @@ +/** + * @description Cubic easing in function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (t /= d) * t * t * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInElasticService.test.ts b/packages/ui/src/Easing/service/EasingInElasticService.test.ts new file mode 100644 index 00000000..4ff621b8 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInElasticService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inElastic method test", function() + { + expect(Easing.inElastic(0.1, 0.5, 0.5, 1)).toBe(0.5009765625); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInElasticService.ts b/packages/ui/src/Easing/service/EasingInElasticService.ts new file mode 100644 index 00000000..9670366d --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInElasticService.ts @@ -0,0 +1,21 @@ +/** + * @description Easing in elastic service + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (t /= d) === 0 + ? b + : t === 1 + ? c + b + : -Math.pow(2, (t *= 10) - 10) + * Math.sin((t - 10.75) * (2 * Math.PI / 3)) + * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInExpoService.test.ts b/packages/ui/src/Easing/service/EasingInExpoService.test.ts new file mode 100644 index 00000000..2b9c0afd --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInExpoService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inExpo method test", function() + { + expect(Easing.inExpo(0.1, 0.5, 0.5, 1)).toBe(0.5009765625); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInExpoService.ts b/packages/ui/src/Easing/service/EasingInExpoService.ts new file mode 100644 index 00000000..86b39361 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInExpoService.ts @@ -0,0 +1,15 @@ +/** + * @description Easing in expo function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return c * Math.pow(2, 10 * (t / d - 1) ) + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutBackService.test.ts b/packages/ui/src/Easing/service/EasingInOutBackService.test.ts new file mode 100644 index 00000000..68f58142 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutBackService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inOutBack method test", function() + { + expect(Easing.inOutBack(0.1, 0.5, 0.5, 1)).toBe(0.481240724); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutBackService.ts b/packages/ui/src/Easing/service/EasingInOutBackService.ts new file mode 100644 index 00000000..ca524eb8 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutBackService.ts @@ -0,0 +1,18 @@ +/** + * @description Easing in out back service + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + let s = 1.70158; + return (t /= d / 2) < 1 + ? t * t * (((s *= 1.525) + 1) * t - s) * c / 2 + b + : ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) * c / 2 + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutBounceService.test.ts b/packages/ui/src/Easing/service/EasingInOutBounceService.test.ts new file mode 100644 index 00000000..67a0a8f7 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutBounceService.test.ts @@ -0,0 +1,11 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inOutBounce method test", function() + { + expect(Easing.inOutBounce(0.1, 0.5, 0.5, 1)).toBe(0.515); + }); + +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutBounceService.ts b/packages/ui/src/Easing/service/EasingInOutBounceService.ts new file mode 100644 index 00000000..a6a9c9d5 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutBounceService.ts @@ -0,0 +1,19 @@ +import { Easing } from "../../Easing"; + +/** + * @description Easing in out bounce function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return t < d / 2 + ? Easing.inBounce(t * 2, b, c / 2, d) + : Easing.outBounce(t * 2 - d, b + c / 2, c / 2, d); +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutCircService.test.ts b/packages/ui/src/Easing/service/EasingInOutCircService.test.ts new file mode 100644 index 00000000..d525da59 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutCircService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inOutCirc method test", function() + { + expect(Easing.inOutCirc(0.1, 0.5, 0.5, 1)).toBe(0.5003126955570227); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutCircService.ts b/packages/ui/src/Easing/service/EasingInOutCircService.ts new file mode 100644 index 00000000..de00be80 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutCircService.ts @@ -0,0 +1,17 @@ +/** + * @description Easing in out circ service + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (t /= d * 2) < 1 + ? (Math.sqrt(1 - t * t) - 1) / -2 * c + b + : (Math.sqrt(1 - (t -= 2) * t) + 1) / 2 * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutCubicService.test.ts b/packages/ui/src/Easing/service/EasingInOutCubicService.test.ts new file mode 100644 index 00000000..eae10a52 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutCubicService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inOutCubic method test", function() + { + expect(Easing.inOutCubic(0.1, 0.5, 0.5, 1)).toBe(0.502); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutCubicService.ts b/packages/ui/src/Easing/service/EasingInOutCubicService.ts new file mode 100644 index 00000000..c2e4453b --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutCubicService.ts @@ -0,0 +1,17 @@ +/** + * @description Cubic easing in/out function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (t /= d / 2) < 1 + ? t * t * t * c / 2 + b + : ((t -= 2) * t * t + 2) * c / 2 + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutElasticService.test.ts b/packages/ui/src/Easing/service/EasingInOutElasticService.test.ts new file mode 100644 index 00000000..ba4c45d7 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutElasticService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inOutElastic method test", function() + { + expect(Easing.inOutElastic(0.1, 0.5, 0.5, 1)).toBe(0.5001695782985028); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutElasticService.ts b/packages/ui/src/Easing/service/EasingInOutElasticService.ts new file mode 100644 index 00000000..4865777c --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutElasticService.ts @@ -0,0 +1,21 @@ +/** + * @description Easing in out elastic service + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (t /= d) === 0 + ? b + : t === 1 + ? c + b + : t < 0.5 + ? -(Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * (2 * Math.PI / 4.5))) / 2 * c + b + : (Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * (2 * Math.PI / 4.5)) / 2 + 1) * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutExpoService.test.ts b/packages/ui/src/Easing/service/EasingInOutExpoService.test.ts new file mode 100644 index 00000000..e823f6f5 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutExpoService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inOutExpo method test", function() + { + expect(Easing.inOutExpo(0.1, 0.5, 0.5, 1)).toBe(0.5009765625); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutExpoService.ts b/packages/ui/src/Easing/service/EasingInOutExpoService.ts new file mode 100644 index 00000000..9689b0e4 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutExpoService.ts @@ -0,0 +1,17 @@ +/** + * @description Easing in out expo function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (t /= d / 2) < 1 + ? c / 2 * Math.pow(2, 10 * (t - 1)) + b + : c / 2 * (-Math.pow(2, -10 * (t - 1)) + 2) + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutQuadService.test.ts b/packages/ui/src/Easing/service/EasingInOutQuadService.test.ts new file mode 100644 index 00000000..f7f8f19e --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutQuadService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inOutQuad method test", function() + { + expect(Easing.inOutQuad(0.1, 0.5, 0.5, 1)).toBe(0.51); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutQuadService.ts b/packages/ui/src/Easing/service/EasingInOutQuadService.ts new file mode 100644 index 00000000..b2c27d85 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutQuadService.ts @@ -0,0 +1,17 @@ +/** + * @description Quad easing in/out function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (t /= d / 2) < 1 + ? t * t * c / 2 + b + : -((t -= 1) * (t - 2) - 1) * c / 2 + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutQuartService.test.ts b/packages/ui/src/Easing/service/EasingInOutQuartService.test.ts new file mode 100644 index 00000000..3d2b446f --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutQuartService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inOutQuart method test", function() + { + expect(Easing.inOutQuart(0.1, 0.5, 0.5, 1)).toBe(0.5004); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutQuartService.ts b/packages/ui/src/Easing/service/EasingInOutQuartService.ts new file mode 100644 index 00000000..d617c230 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutQuartService.ts @@ -0,0 +1,17 @@ +/** + * @description Quart easing in/out function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (t /= d / 2) < 1 + ? t * t * t * t * c / 2 + b + : ((t -= 2) * t * t * t - 2) * -c / 2 + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutQuintService.test.ts b/packages/ui/src/Easing/service/EasingInOutQuintService.test.ts new file mode 100644 index 00000000..9d81bd9f --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutQuintService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inOutQuint method test", function() + { + expect(Easing.inOutQuint(0.1, 0.5, 0.5, 1)).toBe(0.50008); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutQuintService.ts b/packages/ui/src/Easing/service/EasingInOutQuintService.ts new file mode 100644 index 00000000..85422f39 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutQuintService.ts @@ -0,0 +1,17 @@ +/** + * @description Quint easing in/out function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (t /= d / 2) < 1 + ? t * t * t * t * t * c / 2 + b + : ((t -= 2) * t * t * t * t + 2) * c / 2 + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutSineService.test.ts b/packages/ui/src/Easing/service/EasingInOutSineService.test.ts new file mode 100644 index 00000000..c4302c8b --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutSineService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inOutSine method test", function() + { + expect(Easing.inOutSine(0.1, 0.5, 0.5, 1)).toBe(0.5122358709262116); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInOutSineService.ts b/packages/ui/src/Easing/service/EasingInOutSineService.ts new file mode 100644 index 00000000..946eaf7d --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInOutSineService.ts @@ -0,0 +1,15 @@ +/** + * @description Easing in out sine function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInQuadService.test.ts b/packages/ui/src/Easing/service/EasingInQuadService.test.ts new file mode 100644 index 00000000..8bd6200e --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInQuadService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inQuad method test", function() + { + expect(Easing.inQuad(0.1, 0.5, 0.5, 1)).toBe(0.505); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInQuadService.ts b/packages/ui/src/Easing/service/EasingInQuadService.ts new file mode 100644 index 00000000..726d2378 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInQuadService.ts @@ -0,0 +1,15 @@ +/** + * @description Quad easing in function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (t /= d) * t * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInQuartService.test.ts b/packages/ui/src/Easing/service/EasingInQuartService.test.ts new file mode 100644 index 00000000..61e2d30b --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInQuartService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inQuart method test", function() + { + expect(Easing.inQuart(0.1, 0.5, 0.5, 1)).toBe(0.50005); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInQuartService.ts b/packages/ui/src/Easing/service/EasingInQuartService.ts new file mode 100644 index 00000000..8d59fb50 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInQuartService.ts @@ -0,0 +1,15 @@ +/** + * @description Quart easing in function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (t /= d) * t * t * t * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInQuintService.test.ts b/packages/ui/src/Easing/service/EasingInQuintService.test.ts new file mode 100644 index 00000000..d9de6aa9 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInQuintService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inQuint method test", function() + { + expect(Easing.inQuint(0.1, 0.5, 0.5, 1)).toBe(0.500005); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInQuintService.ts b/packages/ui/src/Easing/service/EasingInQuintService.ts new file mode 100644 index 00000000..4f1566bd --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInQuintService.ts @@ -0,0 +1,15 @@ +/** + * @description Quint easing in function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (t /= d) * t * t * t * t * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInSineService.test.ts b/packages/ui/src/Easing/service/EasingInSineService.test.ts new file mode 100644 index 00000000..a683b222 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInSineService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("inSine method test", function() + { + expect(Easing.inSine(0.1, 0.5, 0.5, 1)).toBe(0.5061558297024311); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingInSineService.ts b/packages/ui/src/Easing/service/EasingInSineService.ts new file mode 100644 index 00000000..928a3e80 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingInSineService.ts @@ -0,0 +1,15 @@ +/** + * @description Easing in sine function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingLinearService.test.ts b/packages/ui/src/Easing/service/EasingLinearService.test.ts new file mode 100644 index 00000000..d12627d1 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingLinearService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("linear method test", function() + { + expect(Easing.linear(0.1, 0.5, 0.5, 1)).toBe(0.55); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingLinearService.ts b/packages/ui/src/Easing/service/EasingLinearService.ts new file mode 100644 index 00000000..9cdaf57f --- /dev/null +++ b/packages/ui/src/Easing/service/EasingLinearService.ts @@ -0,0 +1,15 @@ +/** + * @description Linear easing function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return t / d * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutBackService.test.ts b/packages/ui/src/Easing/service/EasingOutBackService.test.ts new file mode 100644 index 00000000..a5cffc8e --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutBackService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("outBack method test", function() + { + expect(Easing.outBack(0.1, 0.5, 0.5, 1)).toBe(0.7044139899999999); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutBackService.ts b/packages/ui/src/Easing/service/EasingOutBackService.ts new file mode 100644 index 00000000..098b9146 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutBackService.ts @@ -0,0 +1,18 @@ +/** + * @description Easing out back service + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (1 + 2.70158 + * Math.pow((t /= d) - 1, 3) + 1.70158 + * Math.pow(t - 1, 2) + ) * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutBounceService.test.ts b/packages/ui/src/Easing/service/EasingOutBounceService.test.ts new file mode 100644 index 00000000..dd3abd8d --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutBounceService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("outBounce method test", function() + { + expect(Easing.outBounce(0.1, 0.5, 0.5, 1)).toBe(0.5378125); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutBounceService.ts b/packages/ui/src/Easing/service/EasingOutBounceService.ts new file mode 100644 index 00000000..60b06d71 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutBounceService.ts @@ -0,0 +1,24 @@ +/** + * @description Easing out bounce function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + if ((t /= d) < 1 / 2.75) { + return 7.5625 * t * t * c + b; + } + if (t < 2 / 2.75) { + return (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) * c + b; + } + if (t < 2.5 / 2.75) { + return (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) * c + b; + } + return (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutCircService.test.ts b/packages/ui/src/Easing/service/EasingOutCircService.test.ts new file mode 100644 index 00000000..932eca70 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutCircService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("outCirc method test", function() + { + expect(Easing.outCirc(0.1, 0.5, 0.5, 1)).toBe(0.7179449471770336); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutCircService.ts b/packages/ui/src/Easing/service/EasingOutCircService.ts new file mode 100644 index 00000000..7543372a --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutCircService.ts @@ -0,0 +1,16 @@ +/** + * @description Easing out circ service + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + t /= d; + return Math.sqrt(1 - --t * t) * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutCubicService.test.ts b/packages/ui/src/Easing/service/EasingOutCubicService.test.ts new file mode 100644 index 00000000..4e56d057 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutCubicService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("outCubic method test", function() + { + expect(Easing.outCubic(0.1, 0.5, 0.5, 1)).toBe(0.6355); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutCubicService.ts b/packages/ui/src/Easing/service/EasingOutCubicService.ts new file mode 100644 index 00000000..155e8d35 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutCubicService.ts @@ -0,0 +1,16 @@ +/** + * @description Cubic easing out function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + t /= d; + return (--t * t * t + 1) * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutElasticService.test.ts b/packages/ui/src/Easing/service/EasingOutElasticService.test.ts new file mode 100644 index 00000000..43ad301c --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutElasticService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("outElastic method test", function() + { + expect(Easing.outElastic(0.1, 0.5, 0.5, 1)).toBe(1.125); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutElasticService.ts b/packages/ui/src/Easing/service/EasingOutElasticService.ts new file mode 100644 index 00000000..8ce59483 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutElasticService.ts @@ -0,0 +1,21 @@ +/** + * @description Easing out elastic service + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return (t /= d) === 0 + ? b + : t === 1 + ? c + b + : (Math.pow(2, -10 * t) + * Math.sin((t * 10 - 0.75) * (2 * Math.PI / 3)) + 1) + * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutExpoService.test.ts b/packages/ui/src/Easing/service/EasingOutExpoService.test.ts new file mode 100644 index 00000000..a5a24dd1 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutExpoService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("outExpo method test", function() + { + expect(Easing.outExpo(0.1, 0.5, 0.5, 1)).toBe(0.75); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutExpoService.ts b/packages/ui/src/Easing/service/EasingOutExpoService.ts new file mode 100644 index 00000000..924ddc2f --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutExpoService.ts @@ -0,0 +1,15 @@ +/** + * @description Easing out expo function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return c * (-Math.pow(2, -10 * t / d) + 1) + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutQuadService.test.ts b/packages/ui/src/Easing/service/EasingOutQuadService.test.ts new file mode 100644 index 00000000..391615f2 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutQuadService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("outQuad method test", function() + { + expect(Easing.outQuad(0.1, 0.5, 0.5, 1)).toBe(0.595); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutQuadService.ts b/packages/ui/src/Easing/service/EasingOutQuadService.ts new file mode 100644 index 00000000..37fc5921 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutQuadService.ts @@ -0,0 +1,15 @@ +/** + * @description Quad easing out function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return -(t /= d) * (t - 2) * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutQuartService.test.ts b/packages/ui/src/Easing/service/EasingOutQuartService.test.ts new file mode 100644 index 00000000..00d05171 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutQuartService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("outQuart method test", function() + { + expect(Easing.outQuart(0.1, 0.5, 0.5, 1)).toBe(0.6719499999999999); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutQuartService.ts b/packages/ui/src/Easing/service/EasingOutQuartService.ts new file mode 100644 index 00000000..9a3065a7 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutQuartService.ts @@ -0,0 +1,16 @@ +/** + * @description Quart easing out function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + t /= d; + return (--t * t * t * t - 1) * -c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutQuintService.test.ts b/packages/ui/src/Easing/service/EasingOutQuintService.test.ts new file mode 100644 index 00000000..2db94f77 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutQuintService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("outQuint method test", function() + { + expect(Easing.outQuint(0.1, 0.5, 0.5, 1)).toBe(0.7047549999999999); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutQuintService.ts b/packages/ui/src/Easing/service/EasingOutQuintService.ts new file mode 100644 index 00000000..7908f551 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutQuintService.ts @@ -0,0 +1,16 @@ +/** + * @description Quint easing out function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + t /= d; + return (--t * t * t * t * t + 1) * c + b; +}; \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutSineService.test.ts b/packages/ui/src/Easing/service/EasingOutSineService.test.ts new file mode 100644 index 00000000..49f350bf --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutSineService.test.ts @@ -0,0 +1,10 @@ +import { Easing } from "../../Easing"; +import { describe, expect, it } from "vitest"; + +describe("Easing.js method test", function() +{ + it("outSine method test", function() + { + expect(Easing.outSine(0.1, 0.5, 0.5, 1)).toBe(0.5782172325201155); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Easing/service/EasingOutSineService.ts b/packages/ui/src/Easing/service/EasingOutSineService.ts new file mode 100644 index 00000000..c58bd644 --- /dev/null +++ b/packages/ui/src/Easing/service/EasingOutSineService.ts @@ -0,0 +1,15 @@ +/** + * @description Easing out sine function + * + * @param {number} t + * @param {number} b + * @param {number} c + * @param {number} d + * @return {number} + * @method + * @public + */ +export const execute = (t: number, b: number, c: number, d: number): number => +{ + return c * Math.sin(t / d * (Math.PI / 2)) + b; +}; \ No newline at end of file From ba1c04c97bf086b4fce1176c707dac543b4473fb Mon Sep 17 00:00:00 2001 From: ienaga Date: Wed, 24 Jul 2024 14:52:43 +0900 Subject: [PATCH 011/343] =?UTF-8?q?#154=20feat:=20@next2d/ui=E3=81=AE?= =?UTF-8?q?=E7=A7=BB=E8=A1=8C=E6=BA=96=E5=82=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/events/src/Event.ts | 2 +- packages/events/src/EventDispatcher.ts | 161 ++++++------------ packages/events/src/EventUtil.ts | 72 ++++++++ packages/events/src/HTTPStatusEvent.ts | 8 +- packages/events/src/MouseEvent.ts | 2 +- .../interface/DisplayObjectContainerImpl.ts | 1 + .../events/src/interface/EventListenerImpl.ts | 6 + .../src/interface/URLRequestHeaderImpl.ts | 5 + packages/ui/src/Job.ts | 37 ++-- packages/ui/src/Tween.test.ts | 31 ++++ packages/ui/src/Tween.ts | 11 +- packages/ui/src/interface/ObjectImpl.ts | 3 + 12 files changed, 196 insertions(+), 143 deletions(-) create mode 100644 packages/events/src/EventUtil.ts create mode 100644 packages/events/src/interface/DisplayObjectContainerImpl.ts create mode 100644 packages/events/src/interface/EventListenerImpl.ts create mode 100644 packages/events/src/interface/URLRequestHeaderImpl.ts create mode 100644 packages/ui/src/Tween.test.ts create mode 100644 packages/ui/src/interface/ObjectImpl.ts diff --git a/packages/events/src/Event.ts b/packages/events/src/Event.ts index ec98db91..5194cef8 100644 --- a/packages/events/src/Event.ts +++ b/packages/events/src/Event.ts @@ -1,5 +1,5 @@ import { EventPhase } from "./EventPhase"; -import type { EventDispatcherImpl } from "@next2d/interface"; +import type { EventDispatcherImpl } from "./interface/EventDispatcherImpl"; /** * Event クラスのメソッドは、イベントリスナー関数で使用してイベントオブジェクトの動作に影響を与えることができます。 diff --git a/packages/events/src/EventDispatcher.ts b/packages/events/src/EventDispatcher.ts index 3e087e3f..9ad79b5b 100644 --- a/packages/events/src/EventDispatcher.ts +++ b/packages/events/src/EventDispatcher.ts @@ -1,18 +1,12 @@ import { Event } from "./Event"; import { EventPhase } from "./EventPhase"; -import type { Player } from "@next2d/core"; -import type { EventListenerImpl } from "@next2d/interface"; -import type { DisplayObjectContainer } from "@next2d/display"; +import type { EventListenerImpl } from "./interface/EventListenerImpl"; +import type { EventDispatcherImpl } from "./interface/EventDispatcherImpl"; import { - $setCurrentLoaderInfo, - $currentPlayer -} from "@next2d/util"; -import { - $getMap, - $poolMap, + $broadcastEvents, $getArray, $poolArray -} from "@next2d/share"; +} from "./EventUtil"; /** * @description EventDispatcher クラスは、イベントを送出するすべてのクラスの基本クラスです。 @@ -115,10 +109,7 @@ export class EventDispatcher priority: number = 0 ): void { - const player: Player = $currentPlayer(); - let events: EventListenerImpl[]; - let isBroadcast: boolean = false; type = `${type}`; switch (type) { @@ -133,15 +124,13 @@ export class EventDispatcher case "keyDown": case "keyUp": - if (!player.broadcastEvents.size - || !player.broadcastEvents.has(type) + if (!$broadcastEvents.size + || !$broadcastEvents.has(type) ) { - player.broadcastEvents.set(type, $getArray()); + $broadcastEvents.set(type, $getArray()); } - events = player.broadcastEvents.get(type) || $getArray(); - - isBroadcast = true; + events = $broadcastEvents.get(type) as NonNullable; break; @@ -150,14 +139,14 @@ export class EventDispatcher // init if (!this._$events) { - this._$events = $getMap(); + this._$events = new Map(); } if (!this._$events.size || !this._$events.has(type)) { this._$events.set(type, $getArray()); } - events = this._$events.get(type) || $getArray(); + events = this._$events.get(type) as NonNullable; break; @@ -176,10 +165,12 @@ export class EventDispatcher continue; } - if (event.listener === listener) { - length = idx; + if (event.listener !== listener) { + continue; } + length = idx; + break; } // add or overwrite @@ -210,20 +201,6 @@ export class EventDispatcher }); } - - // set new event - if (isBroadcast) { - - player.broadcastEvents.set(type, events); - - } else { - - if (!this._$events) { - this._$events = $getMap(); - } - - this._$events.set(type, events); - } } /** @@ -247,49 +224,44 @@ export class EventDispatcher case Event.DEACTIVATE: case "keyDown": case "keyUp": - { - const player = $currentPlayer(); - - if (player && player.broadcastEvents.size - && player.broadcastEvents.has(event.type) - ) { + if ($broadcastEvents.size + && $broadcastEvents.has(event.type) + ) { - const events: EventListenerImpl[] = player.broadcastEvents.get(event.type) as NonNullable; - for (let idx: number = 0; idx < events.length; ++idx) { + const events = $broadcastEvents.get(event.type) as NonNullable; + for (let idx: number = 0; idx < events.length; ++idx) { - const obj: EventListenerImpl = events[idx]; - if (obj.target !== this) { - continue; - } + const obj: EventListenerImpl = events[idx]; + if (obj.target !== this) { + continue; + } - // start target - event.eventPhase = EventPhase.AT_TARGET; + // start target + event.eventPhase = EventPhase.AT_TARGET; - // event execute - event.currentTarget = obj.target; + // event execute + event.currentTarget = obj.target; - try { + try { - event.listener = obj.listener; - obj.listener.call(null, event); + event.listener = obj.listener; + obj.listener.call(null, event); - } catch (e) { + } catch (e) { - console.error(e); + console.error(e); - return false; + return false; - } } - - return true; } + + return true; } break; default: { - let events: EventListenerImpl[] | null = null; if (this._$events && this._$events.size @@ -309,14 +281,14 @@ export class EventDispatcher const parentEvents = $getArray(); if ("parent" in this) { - let parent: DisplayObjectContainer | null = this.parent as NonNullable; + let parent = this.parent as EventDispatcherImpl | null; while (parent) { if (parent.hasEventListener(event.type)) { - const events: EventListenerImpl[] | void = parent._$events - ? parent._$events.get(event.type) - : undefined; + const events: EventListenerImpl[] | null = parent._$events && parent._$events.has(event.type) + ? parent._$events.get(event.type) as NonNullable + : null; if (events) { parentEvents.push(events); @@ -359,9 +331,6 @@ export class EventDispatcher // event execute event.currentTarget = obj.target; - $setCurrentLoaderInfo( - obj.target.loaderInfo - ); try { @@ -409,11 +378,6 @@ export class EventDispatcher // event execute event.currentTarget = obj.target; - - $setCurrentLoaderInfo( - obj.target.loaderInfo - ); - try { event.listener = obj.listener; @@ -457,10 +421,6 @@ export class EventDispatcher // event execute event.currentTarget = obj.target; - $setCurrentLoaderInfo( - obj.target.loaderInfo - ); - try { event.listener = obj.listener; @@ -528,14 +488,11 @@ export class EventDispatcher case "keyDown": case "keyUp": { - const player = $currentPlayer(); - - if (player - && player.broadcastEvents.size - && player.broadcastEvents.has(type) + if ($broadcastEvents.size + && $broadcastEvents.has(type) ) { - const events: EventListenerImpl[] = player.broadcastEvents.get(type) || $getArray(); + const events: EventListenerImpl[] = $broadcastEvents.get(type) || $getArray(); for (let idx: number = 0; idx < events.length; idx++) { if (events[idx].target === this) { @@ -579,8 +536,6 @@ export class EventDispatcher return; } - const player: Player = $currentPlayer(); - let events: EventListenerImpl[] | null = null; let isBroadcast: boolean = false; @@ -595,13 +550,8 @@ export class EventDispatcher case Event.DEACTIVATE: case "keyDown": case "keyUp": - isBroadcast = true; - - if (player) { - events = player.broadcastEvents.get(type) || $getArray(); - } - + events = $broadcastEvents.get(type) || $getArray(); break; default: @@ -638,7 +588,7 @@ export class EventDispatcher if (isBroadcast) { - player.broadcastEvents.delete(type); + $broadcastEvents.delete(type); } else { @@ -649,7 +599,6 @@ export class EventDispatcher this._$events.delete(type); if (!this._$events.size) { - $poolMap(this._$events); this._$events = null; } @@ -681,12 +630,12 @@ export class EventDispatcher if (isBroadcast) { - player.broadcastEvents.set(type, events); + $broadcastEvents.set(type, events); } else { if (!this._$events) { - this._$events = $getMap(); + this._$events = new Map(); } this._$events.set(type, events); @@ -714,8 +663,6 @@ export class EventDispatcher return; } - const player = $currentPlayer(); - let events: EventListenerImpl[] | null = null; let isBroadcast: boolean = false; @@ -730,13 +677,8 @@ export class EventDispatcher case Event.DEACTIVATE: case "keyDown": case "keyUp": - isBroadcast = true; - - if (player) { - events = player.broadcastEvents.get(type) || $getArray(); - } - + events = $broadcastEvents.get(type) || $getArray(); break; default: @@ -772,7 +714,7 @@ export class EventDispatcher if (isBroadcast) { - player.broadcastEvents.delete(type); + $broadcastEvents.delete(type); } else { @@ -783,7 +725,6 @@ export class EventDispatcher this._$events.delete(type); if (!this._$events.size) { - $poolMap(this._$events); this._$events = null; } } @@ -814,12 +755,12 @@ export class EventDispatcher if (isBroadcast) { - player.broadcastEvents.set(type, results); + $broadcastEvents.set(type, results); } else { if (!this._$events) { - this._$events = $getMap(); + this._$events = new Map(); } this._$events.set(type, results); @@ -847,7 +788,7 @@ export class EventDispatcher if ("parent" in this) { - let parent: DisplayObjectContainer | null = this.parent as NonNullable; + let parent = this.parent as EventDispatcherImpl | null; while (parent) { if (parent.hasEventListener(type)) { diff --git a/packages/events/src/EventUtil.ts b/packages/events/src/EventUtil.ts new file mode 100644 index 00000000..4283822a --- /dev/null +++ b/packages/events/src/EventUtil.ts @@ -0,0 +1,72 @@ +import type { EventListenerImpl } from "./interface/EventListenerImpl"; + +/** + * @type {Map} + * @private + */ +export const $broadcastEvents: Map = new Map(); + +/** + * @type {array} + * @private + */ +const $array: any[] = []; + +/** + * @return {array} + * @method + * @private + */ +export const $getArray = (): any[] => +{ + return $array.length + ? $array.pop() + : []; +}; + +/** + * @return {void} + * @method + * @private + */ +export const $poolArray = (array: any[]): void => +{ + if (10 > $array.length) { + array.length = 0; + $array.push(array); + } +}; + +/** + * @type {Event} + * @private + */ +let $activeEvent: PointerEvent | null = null; + +/** + * @description アクティブなイベントオブジェクを返却 + * Returns the active event object + * + * @return {PointerEvent | null} + * @default null + * @method + * @protected + */ +export const $getEvent = (): PointerEvent | null => +{ + return $activeEvent; +}; + +/** + * @description アクティブなイベントオブジェクをセット + * Set the active event object + * + * @param {PointerEvent | null} event + * @return {void} + * @method + * @protected + */ +export const $setEvent = (event: PointerEvent | null = null): void => +{ + $activeEvent = event; +}; diff --git a/packages/events/src/HTTPStatusEvent.ts b/packages/events/src/HTTPStatusEvent.ts index 7ffafdd2..b465142a 100644 --- a/packages/events/src/HTTPStatusEvent.ts +++ b/packages/events/src/HTTPStatusEvent.ts @@ -1,5 +1,5 @@ import { Event } from "./Event"; -import type { URLRequestHeader } from "@next2d/net"; +import type { URLRequestHeaderImpl } from "./interface/URLRequestHeaderImpl"; /** * ネットワーク要求が HTTP ステータスコードを返すと、アプリケーションによって HTTPStatusEvent オブジェクトが送出されます。 @@ -13,7 +13,7 @@ import type { URLRequestHeader } from "@next2d/net"; export class HTTPStatusEvent extends Event { private readonly _$status: number; - private readonly _$responseHeaders: URLRequestHeader[]; + private readonly _$responseHeaders: URLRequestHeaderImpl[]; private readonly _$responseURL: string; /** @@ -30,7 +30,7 @@ export class HTTPStatusEvent extends Event constructor ( type: string, bubbles: boolean = false, cancelable: boolean = false, status: number = 0, response_url: string = "", - response_headers: URLRequestHeader[] = [] + response_headers: URLRequestHeaderImpl[] = [] ) { super(type, bubbles, cancelable); @@ -141,7 +141,7 @@ export class HTTPStatusEvent extends Event * @readonly * @public */ - get responseHeaders (): URLRequestHeader[] + get responseHeaders (): URLRequestHeaderImpl[] { return this._$responseHeaders; } diff --git a/packages/events/src/MouseEvent.ts b/packages/events/src/MouseEvent.ts index 1da46719..a7c7eede 100644 --- a/packages/events/src/MouseEvent.ts +++ b/packages/events/src/MouseEvent.ts @@ -1,5 +1,5 @@ import { Event } from "./Event"; -import { $getEvent } from "@next2d/util"; +import { $getEvent } from "./EventUtil"; /** * MouseEvent オブジェクトは、マウスイベントが発生するたびにイベントフローに送出されます。 diff --git a/packages/events/src/interface/DisplayObjectContainerImpl.ts b/packages/events/src/interface/DisplayObjectContainerImpl.ts new file mode 100644 index 00000000..7d036b8a --- /dev/null +++ b/packages/events/src/interface/DisplayObjectContainerImpl.ts @@ -0,0 +1 @@ +export interface DisplayObjectContainerImpl { \ No newline at end of file diff --git a/packages/events/src/interface/EventListenerImpl.ts b/packages/events/src/interface/EventListenerImpl.ts new file mode 100644 index 00000000..2e1c9cfe --- /dev/null +++ b/packages/events/src/interface/EventListenerImpl.ts @@ -0,0 +1,6 @@ +export interface EventListenerImpl { + listener: Function; + priority: number; + useCapture: boolean; + target: any; +} \ No newline at end of file diff --git a/packages/events/src/interface/URLRequestHeaderImpl.ts b/packages/events/src/interface/URLRequestHeaderImpl.ts new file mode 100644 index 00000000..efbdd5c9 --- /dev/null +++ b/packages/events/src/interface/URLRequestHeaderImpl.ts @@ -0,0 +1,5 @@ +export interface URLRequestHeaderImpl +{ + name: string; + value: string; +} \ No newline at end of file diff --git a/packages/ui/src/Job.ts b/packages/ui/src/Job.ts index 900b5ba4..5463b4a1 100644 --- a/packages/ui/src/Job.ts +++ b/packages/ui/src/Job.ts @@ -1,13 +1,9 @@ import { Easing } from "./Easing"; +import type { ObjectImpl } from "./interface/ObjectImpl"; import { EventDispatcher, Event } from "@next2d/events"; -import { - $setTimeout, - $performance, - $cancelAnimationFrame -} from "@next2d/share"; /** * @class @@ -44,7 +40,7 @@ export class Job extends EventDispatcher */ constructor ( target: any, - from: any = null, to: any = null, + from: ObjectImpl, to: ObjectImpl, delay: number = 0, duration: number = 1, ease: Function | null = null ) { @@ -147,7 +143,7 @@ export class Job extends EventDispatcher * Returns the string representation of the specified class. * * @return {string} - * @default [class Job] + * @default "[class Job]" * @method * @static */ @@ -161,7 +157,7 @@ export class Job extends EventDispatcher * Returns the space name of the specified class. * * @return {string} - * @default next2d.ui.Job + * @default "next2d.ui.Job" * @const * @static */ @@ -175,7 +171,7 @@ export class Job extends EventDispatcher * Returns the string representation of the specified object. * * @return {string} - * @default [object Job] + * @default "[object Job]" * @method * @public */ @@ -189,7 +185,7 @@ export class Job extends EventDispatcher * Returns the space name of the specified object. * * @return {string} - * @default next2d.ui.Job + * @default "next2d.ui.Job" * @const * @public */ @@ -244,28 +240,26 @@ export class Job extends EventDispatcher /** * @member {object} - * @default null * @public */ - get from (): any + get from (): ObjectImpl { return this._$from; } - set from (from: any) + set from (from: ObjectImpl) { this._$from = from; } /** * @member {object} - * @default null * @public */ - get to (): any + get to (): ObjectImpl { return this._$to; } - set to (to: any) + set to (to: ObjectImpl) { this._$to = to; } @@ -307,7 +301,7 @@ export class Job extends EventDispatcher // setup this._$stopFlag = false; - this._$startTime = $performance.now(); + this._$startTime = performance.now(); this._$names = this._$entries(this._$from); @@ -346,14 +340,14 @@ export class Job extends EventDispatcher start (): void { if (this._$timerId) { - $cancelAnimationFrame(this._$timerId); + cancelAnimationFrame(this._$timerId); } this._$forceStop = false; if (this._$delay) { - $setTimeout((): void => + setTimeout((): void => { this.initialize(); }, this._$delay * 1000); @@ -372,12 +366,11 @@ export class Job extends EventDispatcher stop (): void { if (this._$timerId) { - $cancelAnimationFrame(this._$timerId); + cancelAnimationFrame(this._$timerId); } if (this.hasEventListener(Event.STOP)) { this.dispatchEvent(new Event(Event.STOP)); - this.removeAllEventListener(Event.STOP); } this._$names = null; @@ -401,7 +394,7 @@ export class Job extends EventDispatcher } // update current time - this._$currentTime = ($performance.now() - this._$startTime) * 0.001; + this._$currentTime = (performance.now() - this._$startTime) * 0.001; this._$updateProperty( this._$target, this._$from, this._$to, this._$names diff --git a/packages/ui/src/Tween.test.ts b/packages/ui/src/Tween.test.ts new file mode 100644 index 00000000..9bebb032 --- /dev/null +++ b/packages/ui/src/Tween.test.ts @@ -0,0 +1,31 @@ +import { Tween } from "./Tween"; +import { describe, expect, it } from "vitest"; + +describe("Tween.js toString test", function() +{ + it("toString test success", function() + { + expect(new Tween().toString()).toBe("[object Tween]"); + }); +}); + +describe("Tween.js static toString test", function() +{ + it("static toString test", function() + { + expect(Tween.toString()).toBe("[class Tween]"); + }); +}); + +describe("Tween.js namespace test", function() +{ + it("namespace test public", function() + { + expect(new Tween().namespace).toBe("next2d.ui.Tween"); + }); + + it("namespace test static", function() + { + expect(Tween.namespace).toBe("next2d.ui.Tween"); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Tween.ts b/packages/ui/src/Tween.ts index 480ccf4a..ddd8b34b 100644 --- a/packages/ui/src/Tween.ts +++ b/packages/ui/src/Tween.ts @@ -1,4 +1,5 @@ import { Job } from "./Job"; +import type { ObjectImpl } from "./interface/ObjectImpl"; /** * @class @@ -11,7 +12,7 @@ export class Tween * Returns the string representation of the specified class. * * @return {string} - * @default [class Tween] + * @default "[class Tween]" * @method * @static */ @@ -25,7 +26,7 @@ export class Tween * Returns the space name of the specified class. * * @return {string} - * @default next2d.ui.Tween + * @default "next2d.ui.Tween" * @const * @static */ @@ -39,7 +40,7 @@ export class Tween * Returns the string representation of the specified object. * * @return {string} - * @default [object Tween] + * @default "[object Tween]" * @method * @public */ @@ -53,7 +54,7 @@ export class Tween * Returns the space name of the specified object. * * @return {string} - * @default next2d.ui.Tween + * @default "next2d.ui.Tween" * @const * @public */ @@ -77,7 +78,7 @@ export class Tween * @static */ static add ( - target: any, from: any, to: any, + target: any, from: ObjectImpl, to: ObjectImpl, delay: number = 0, duration: number = 1, ease: Function | null = null ): Job { diff --git a/packages/ui/src/interface/ObjectImpl.ts b/packages/ui/src/interface/ObjectImpl.ts new file mode 100644 index 00000000..1ed02c39 --- /dev/null +++ b/packages/ui/src/interface/ObjectImpl.ts @@ -0,0 +1,3 @@ +export interface ObjectImpl { + [key: string]: { value: number | ObjectImpl } +} \ No newline at end of file From 586a2fbe4faa79019a4d946654407c9280002d6c Mon Sep 17 00:00:00 2001 From: ienaga Date: Wed, 24 Jul 2024 21:52:19 +0900 Subject: [PATCH 012/343] =?UTF-8?q?#154=20feat:=20ui=E3=83=91=E3=83=83?= =?UTF-8?q?=E3=82=B1=E3=83=BC=E3=82=B8=E3=82=92=E7=A7=BB=E6=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/UI.ts | 2 - packages/interface/src/UIImpl.ts | 2 - packages/ui/package.json | 3 +- .../service/EasingInBackService.test.ts | 4 +- .../service/EasingInBounceService.test.ts | 4 +- .../service/EasingInCircService.test.ts | 4 +- .../service/EasingInCubicService.test.ts | 4 +- .../service/EasingInElasticService.test.ts | 4 +- .../service/EasingInExpoService.test.ts | 4 +- .../service/EasingInOutBackService.test.ts | 4 +- .../service/EasingInOutBounceService.test.ts | 4 +- .../service/EasingInOutCircService.test.ts | 4 +- .../service/EasingInOutCubicService.test.ts | 4 +- .../service/EasingInOutElasticService.test.ts | 4 +- .../service/EasingInOutExpoService.test.ts | 4 +- .../service/EasingInOutQuadService.test.ts | 4 +- .../service/EasingInOutQuartService.test.ts | 4 +- .../service/EasingInOutQuintService.test.ts | 4 +- .../service/EasingInOutSineService.test.ts | 4 +- .../service/EasingInQuadService.test.ts | 4 +- .../service/EasingInQuartService.test.ts | 4 +- .../service/EasingInQuintService.test.ts | 4 +- .../service/EasingInSineService.test.ts | 4 +- .../service/EasingLinearService.test.ts | 4 +- .../service/EasingOutBackService.test.ts | 4 +- .../service/EasingOutBounceService.test.ts | 4 +- .../service/EasingOutCircService.test.ts | 4 +- .../service/EasingOutCubicService.test.ts | 4 +- .../service/EasingOutElasticService.test.ts | 4 +- .../service/EasingOutExpoService.test.ts | 4 +- .../service/EasingOutQuadService.test.ts | 4 +- .../service/EasingOutQuartService.test.ts | 4 +- .../service/EasingOutQuintService.test.ts | 4 +- .../service/EasingOutSineService.test.ts | 4 +- packages/ui/src/Job.test.ts | 31 ++ packages/ui/src/Job.ts | 296 ++++++++---------- packages/ui/src/Job/JobEntriesService.test.ts | 80 +++++ packages/ui/src/Job/JobEntriesService.ts | 24 ++ packages/ui/src/Job/JobUpdateFrameService.ts | 57 ++++ .../src/Job/JobUpdatePropertyService.test.ts | 64 ++++ .../ui/src/Job/JobUpdatePropertyService.ts | 66 ++++ packages/ui/src/index.ts | 1 - .../ui/src/interface/EntriesObjectImpl.ts | 4 + packages/ui/src/interface/ObjectImpl.ts | 2 +- 44 files changed, 527 insertions(+), 229 deletions(-) create mode 100644 packages/ui/src/Job.test.ts create mode 100644 packages/ui/src/Job/JobEntriesService.test.ts create mode 100644 packages/ui/src/Job/JobEntriesService.ts create mode 100644 packages/ui/src/Job/JobUpdateFrameService.ts create mode 100644 packages/ui/src/Job/JobUpdatePropertyService.test.ts create mode 100644 packages/ui/src/Job/JobUpdatePropertyService.ts create mode 100644 packages/ui/src/interface/EntriesObjectImpl.ts diff --git a/packages/core/src/UI.ts b/packages/core/src/UI.ts index f55ca260..a370862d 100644 --- a/packages/core/src/UI.ts +++ b/packages/core/src/UI.ts @@ -1,13 +1,11 @@ import { UIImpl } from "@next2d/interface"; import { Easing, - Job, Tween } from "@next2d/ui"; const ui: UIImpl = { Easing, - Job, Tween }; diff --git a/packages/interface/src/UIImpl.ts b/packages/interface/src/UIImpl.ts index e459df28..c32a9506 100644 --- a/packages/interface/src/UIImpl.ts +++ b/packages/interface/src/UIImpl.ts @@ -1,11 +1,9 @@ import { Easing, - Job, Tween } from "@next2d/ui"; export interface UIImpl { Easing: typeof Easing; - Job: typeof Job; Tween: typeof Tween; } \ No newline at end of file diff --git a/packages/ui/package.json b/packages/ui/package.json index 35b879f5..6119fc66 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -26,7 +26,6 @@ "url": "git+https://github.com/Next2D/Player.git" }, "peerDependencies": { - "@next2d/events": "file:../events", - "@next2d/share": "file:../share" + "@next2d/events": "file:../events" } } diff --git a/packages/ui/src/Easing/service/EasingInBackService.test.ts b/packages/ui/src/Easing/service/EasingInBackService.test.ts index 1f0995b5..db53ee37 100644 --- a/packages/ui/src/Easing/service/EasingInBackService.test.ts +++ b/packages/ui/src/Easing/service/EasingInBackService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inCubic method test", function() + it("inCubic method test", () => { expect(Easing.inCirc(0.1, 0.5, 0.5, 1)).toBe(0.5025062814466901); }); diff --git a/packages/ui/src/Easing/service/EasingInBounceService.test.ts b/packages/ui/src/Easing/service/EasingInBounceService.test.ts index cdaa82d6..1d81c078 100644 --- a/packages/ui/src/Easing/service/EasingInBounceService.test.ts +++ b/packages/ui/src/Easing/service/EasingInBounceService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inBounce method test", function() + it("inBounce method test", () => { expect(Easing.inBounce(0.1, 0.5, 0.5, 1)).toBe(0.5059375); }); diff --git a/packages/ui/src/Easing/service/EasingInCircService.test.ts b/packages/ui/src/Easing/service/EasingInCircService.test.ts index 1f41d58d..7af705af 100644 --- a/packages/ui/src/Easing/service/EasingInCircService.test.ts +++ b/packages/ui/src/Easing/service/EasingInCircService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inBack method test", function() + it("inBack method test", () => { expect(Easing.inBack(0.1, 0.5, 0.5, 1)).toBe(0.49284289); }); diff --git a/packages/ui/src/Easing/service/EasingInCubicService.test.ts b/packages/ui/src/Easing/service/EasingInCubicService.test.ts index 4b35f5f6..009df901 100644 --- a/packages/ui/src/Easing/service/EasingInCubicService.test.ts +++ b/packages/ui/src/Easing/service/EasingInCubicService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inCubic method test", function() + it("inCubic method test", () => { expect(Easing.inCubic(0.1, 0.5, 0.5, 1)).toBe(0.5005); }); diff --git a/packages/ui/src/Easing/service/EasingInElasticService.test.ts b/packages/ui/src/Easing/service/EasingInElasticService.test.ts index 4ff621b8..7301764e 100644 --- a/packages/ui/src/Easing/service/EasingInElasticService.test.ts +++ b/packages/ui/src/Easing/service/EasingInElasticService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inElastic method test", function() + it("inElastic method test", () => { expect(Easing.inElastic(0.1, 0.5, 0.5, 1)).toBe(0.5009765625); }); diff --git a/packages/ui/src/Easing/service/EasingInExpoService.test.ts b/packages/ui/src/Easing/service/EasingInExpoService.test.ts index 2b9c0afd..4f1d9957 100644 --- a/packages/ui/src/Easing/service/EasingInExpoService.test.ts +++ b/packages/ui/src/Easing/service/EasingInExpoService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inExpo method test", function() + it("inExpo method test", () => { expect(Easing.inExpo(0.1, 0.5, 0.5, 1)).toBe(0.5009765625); }); diff --git a/packages/ui/src/Easing/service/EasingInOutBackService.test.ts b/packages/ui/src/Easing/service/EasingInOutBackService.test.ts index 68f58142..e65b306f 100644 --- a/packages/ui/src/Easing/service/EasingInOutBackService.test.ts +++ b/packages/ui/src/Easing/service/EasingInOutBackService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inOutBack method test", function() + it("inOutBack method test", () => { expect(Easing.inOutBack(0.1, 0.5, 0.5, 1)).toBe(0.481240724); }); diff --git a/packages/ui/src/Easing/service/EasingInOutBounceService.test.ts b/packages/ui/src/Easing/service/EasingInOutBounceService.test.ts index 67a0a8f7..9d38bd59 100644 --- a/packages/ui/src/Easing/service/EasingInOutBounceService.test.ts +++ b/packages/ui/src/Easing/service/EasingInOutBounceService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inOutBounce method test", function() + it("inOutBounce method test", () => { expect(Easing.inOutBounce(0.1, 0.5, 0.5, 1)).toBe(0.515); }); diff --git a/packages/ui/src/Easing/service/EasingInOutCircService.test.ts b/packages/ui/src/Easing/service/EasingInOutCircService.test.ts index d525da59..5365e622 100644 --- a/packages/ui/src/Easing/service/EasingInOutCircService.test.ts +++ b/packages/ui/src/Easing/service/EasingInOutCircService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inOutCirc method test", function() + it("inOutCirc method test", () => { expect(Easing.inOutCirc(0.1, 0.5, 0.5, 1)).toBe(0.5003126955570227); }); diff --git a/packages/ui/src/Easing/service/EasingInOutCubicService.test.ts b/packages/ui/src/Easing/service/EasingInOutCubicService.test.ts index eae10a52..7073f8e9 100644 --- a/packages/ui/src/Easing/service/EasingInOutCubicService.test.ts +++ b/packages/ui/src/Easing/service/EasingInOutCubicService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inOutCubic method test", function() + it("inOutCubic method test", () => { expect(Easing.inOutCubic(0.1, 0.5, 0.5, 1)).toBe(0.502); }); diff --git a/packages/ui/src/Easing/service/EasingInOutElasticService.test.ts b/packages/ui/src/Easing/service/EasingInOutElasticService.test.ts index ba4c45d7..508f8cc3 100644 --- a/packages/ui/src/Easing/service/EasingInOutElasticService.test.ts +++ b/packages/ui/src/Easing/service/EasingInOutElasticService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inOutElastic method test", function() + it("inOutElastic method test", () => { expect(Easing.inOutElastic(0.1, 0.5, 0.5, 1)).toBe(0.5001695782985028); }); diff --git a/packages/ui/src/Easing/service/EasingInOutExpoService.test.ts b/packages/ui/src/Easing/service/EasingInOutExpoService.test.ts index e823f6f5..836186f8 100644 --- a/packages/ui/src/Easing/service/EasingInOutExpoService.test.ts +++ b/packages/ui/src/Easing/service/EasingInOutExpoService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inOutExpo method test", function() + it("inOutExpo method test", () => { expect(Easing.inOutExpo(0.1, 0.5, 0.5, 1)).toBe(0.5009765625); }); diff --git a/packages/ui/src/Easing/service/EasingInOutQuadService.test.ts b/packages/ui/src/Easing/service/EasingInOutQuadService.test.ts index f7f8f19e..b3299861 100644 --- a/packages/ui/src/Easing/service/EasingInOutQuadService.test.ts +++ b/packages/ui/src/Easing/service/EasingInOutQuadService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inOutQuad method test", function() + it("inOutQuad method test", () => { expect(Easing.inOutQuad(0.1, 0.5, 0.5, 1)).toBe(0.51); }); diff --git a/packages/ui/src/Easing/service/EasingInOutQuartService.test.ts b/packages/ui/src/Easing/service/EasingInOutQuartService.test.ts index 3d2b446f..c55815e6 100644 --- a/packages/ui/src/Easing/service/EasingInOutQuartService.test.ts +++ b/packages/ui/src/Easing/service/EasingInOutQuartService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inOutQuart method test", function() + it("inOutQuart method test", () => { expect(Easing.inOutQuart(0.1, 0.5, 0.5, 1)).toBe(0.5004); }); diff --git a/packages/ui/src/Easing/service/EasingInOutQuintService.test.ts b/packages/ui/src/Easing/service/EasingInOutQuintService.test.ts index 9d81bd9f..c457b049 100644 --- a/packages/ui/src/Easing/service/EasingInOutQuintService.test.ts +++ b/packages/ui/src/Easing/service/EasingInOutQuintService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inOutQuint method test", function() + it("inOutQuint method test", () => { expect(Easing.inOutQuint(0.1, 0.5, 0.5, 1)).toBe(0.50008); }); diff --git a/packages/ui/src/Easing/service/EasingInOutSineService.test.ts b/packages/ui/src/Easing/service/EasingInOutSineService.test.ts index c4302c8b..d2397bf5 100644 --- a/packages/ui/src/Easing/service/EasingInOutSineService.test.ts +++ b/packages/ui/src/Easing/service/EasingInOutSineService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inOutSine method test", function() + it("inOutSine method test", () => { expect(Easing.inOutSine(0.1, 0.5, 0.5, 1)).toBe(0.5122358709262116); }); diff --git a/packages/ui/src/Easing/service/EasingInQuadService.test.ts b/packages/ui/src/Easing/service/EasingInQuadService.test.ts index 8bd6200e..ff46a417 100644 --- a/packages/ui/src/Easing/service/EasingInQuadService.test.ts +++ b/packages/ui/src/Easing/service/EasingInQuadService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inQuad method test", function() + it("inQuad method test", () => { expect(Easing.inQuad(0.1, 0.5, 0.5, 1)).toBe(0.505); }); diff --git a/packages/ui/src/Easing/service/EasingInQuartService.test.ts b/packages/ui/src/Easing/service/EasingInQuartService.test.ts index 61e2d30b..397f3ccf 100644 --- a/packages/ui/src/Easing/service/EasingInQuartService.test.ts +++ b/packages/ui/src/Easing/service/EasingInQuartService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inQuart method test", function() + it("inQuart method test", () => { expect(Easing.inQuart(0.1, 0.5, 0.5, 1)).toBe(0.50005); }); diff --git a/packages/ui/src/Easing/service/EasingInQuintService.test.ts b/packages/ui/src/Easing/service/EasingInQuintService.test.ts index d9de6aa9..c7643fd5 100644 --- a/packages/ui/src/Easing/service/EasingInQuintService.test.ts +++ b/packages/ui/src/Easing/service/EasingInQuintService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inQuint method test", function() + it("inQuint method test", () => { expect(Easing.inQuint(0.1, 0.5, 0.5, 1)).toBe(0.500005); }); diff --git a/packages/ui/src/Easing/service/EasingInSineService.test.ts b/packages/ui/src/Easing/service/EasingInSineService.test.ts index a683b222..894aa1cd 100644 --- a/packages/ui/src/Easing/service/EasingInSineService.test.ts +++ b/packages/ui/src/Easing/service/EasingInSineService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("inSine method test", function() + it("inSine method test", () => { expect(Easing.inSine(0.1, 0.5, 0.5, 1)).toBe(0.5061558297024311); }); diff --git a/packages/ui/src/Easing/service/EasingLinearService.test.ts b/packages/ui/src/Easing/service/EasingLinearService.test.ts index d12627d1..fd423166 100644 --- a/packages/ui/src/Easing/service/EasingLinearService.test.ts +++ b/packages/ui/src/Easing/service/EasingLinearService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("linear method test", function() + it("linear method test", () => { expect(Easing.linear(0.1, 0.5, 0.5, 1)).toBe(0.55); }); diff --git a/packages/ui/src/Easing/service/EasingOutBackService.test.ts b/packages/ui/src/Easing/service/EasingOutBackService.test.ts index a5cffc8e..720db6fc 100644 --- a/packages/ui/src/Easing/service/EasingOutBackService.test.ts +++ b/packages/ui/src/Easing/service/EasingOutBackService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("outBack method test", function() + it("outBack method test", () => { expect(Easing.outBack(0.1, 0.5, 0.5, 1)).toBe(0.7044139899999999); }); diff --git a/packages/ui/src/Easing/service/EasingOutBounceService.test.ts b/packages/ui/src/Easing/service/EasingOutBounceService.test.ts index dd3abd8d..d9f8bab7 100644 --- a/packages/ui/src/Easing/service/EasingOutBounceService.test.ts +++ b/packages/ui/src/Easing/service/EasingOutBounceService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("outBounce method test", function() + it("outBounce method test", () => { expect(Easing.outBounce(0.1, 0.5, 0.5, 1)).toBe(0.5378125); }); diff --git a/packages/ui/src/Easing/service/EasingOutCircService.test.ts b/packages/ui/src/Easing/service/EasingOutCircService.test.ts index 932eca70..91454a67 100644 --- a/packages/ui/src/Easing/service/EasingOutCircService.test.ts +++ b/packages/ui/src/Easing/service/EasingOutCircService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("outCirc method test", function() + it("outCirc method test", () => { expect(Easing.outCirc(0.1, 0.5, 0.5, 1)).toBe(0.7179449471770336); }); diff --git a/packages/ui/src/Easing/service/EasingOutCubicService.test.ts b/packages/ui/src/Easing/service/EasingOutCubicService.test.ts index 4e56d057..4b6c880d 100644 --- a/packages/ui/src/Easing/service/EasingOutCubicService.test.ts +++ b/packages/ui/src/Easing/service/EasingOutCubicService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("outCubic method test", function() + it("outCubic method test", () => { expect(Easing.outCubic(0.1, 0.5, 0.5, 1)).toBe(0.6355); }); diff --git a/packages/ui/src/Easing/service/EasingOutElasticService.test.ts b/packages/ui/src/Easing/service/EasingOutElasticService.test.ts index 43ad301c..39351c4d 100644 --- a/packages/ui/src/Easing/service/EasingOutElasticService.test.ts +++ b/packages/ui/src/Easing/service/EasingOutElasticService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("outElastic method test", function() + it("outElastic method test", () => { expect(Easing.outElastic(0.1, 0.5, 0.5, 1)).toBe(1.125); }); diff --git a/packages/ui/src/Easing/service/EasingOutExpoService.test.ts b/packages/ui/src/Easing/service/EasingOutExpoService.test.ts index a5a24dd1..884f8661 100644 --- a/packages/ui/src/Easing/service/EasingOutExpoService.test.ts +++ b/packages/ui/src/Easing/service/EasingOutExpoService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("outExpo method test", function() + it("outExpo method test", () => { expect(Easing.outExpo(0.1, 0.5, 0.5, 1)).toBe(0.75); }); diff --git a/packages/ui/src/Easing/service/EasingOutQuadService.test.ts b/packages/ui/src/Easing/service/EasingOutQuadService.test.ts index 391615f2..664b2333 100644 --- a/packages/ui/src/Easing/service/EasingOutQuadService.test.ts +++ b/packages/ui/src/Easing/service/EasingOutQuadService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("outQuad method test", function() + it("outQuad method test", () => { expect(Easing.outQuad(0.1, 0.5, 0.5, 1)).toBe(0.595); }); diff --git a/packages/ui/src/Easing/service/EasingOutQuartService.test.ts b/packages/ui/src/Easing/service/EasingOutQuartService.test.ts index 00d05171..95ca9656 100644 --- a/packages/ui/src/Easing/service/EasingOutQuartService.test.ts +++ b/packages/ui/src/Easing/service/EasingOutQuartService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("outQuart method test", function() + it("outQuart method test", () => { expect(Easing.outQuart(0.1, 0.5, 0.5, 1)).toBe(0.6719499999999999); }); diff --git a/packages/ui/src/Easing/service/EasingOutQuintService.test.ts b/packages/ui/src/Easing/service/EasingOutQuintService.test.ts index 2db94f77..d77121b5 100644 --- a/packages/ui/src/Easing/service/EasingOutQuintService.test.ts +++ b/packages/ui/src/Easing/service/EasingOutQuintService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("outQuint method test", function() + it("outQuint method test", () => { expect(Easing.outQuint(0.1, 0.5, 0.5, 1)).toBe(0.7047549999999999); }); diff --git a/packages/ui/src/Easing/service/EasingOutSineService.test.ts b/packages/ui/src/Easing/service/EasingOutSineService.test.ts index 49f350bf..cf4eb974 100644 --- a/packages/ui/src/Easing/service/EasingOutSineService.test.ts +++ b/packages/ui/src/Easing/service/EasingOutSineService.test.ts @@ -1,9 +1,9 @@ import { Easing } from "../../Easing"; import { describe, expect, it } from "vitest"; -describe("Easing.js method test", function() +describe("Easing.js method test", () => { - it("outSine method test", function() + it("outSine method test", () => { expect(Easing.outSine(0.1, 0.5, 0.5, 1)).toBe(0.5782172325201155); }); diff --git a/packages/ui/src/Job.test.ts b/packages/ui/src/Job.test.ts new file mode 100644 index 00000000..cf3c7621 --- /dev/null +++ b/packages/ui/src/Job.test.ts @@ -0,0 +1,31 @@ +import { Job } from "./Job"; +import { describe, expect, it } from "vitest"; + +describe("Job.js toString test", function() +{ + it("toString test success", function() + { + expect(new Job({}, { "name": 0 }, { "name": 1 }).toString()).toBe("[object Job]"); + }); +}); + +describe("Job.js static toString test", function() +{ + it("static toString test", function() + { + expect(Job.toString()).toBe("[class Job]"); + }); +}); + +describe("Job.js namespace test", function() +{ + it("namespace test public", function() + { + expect(new Job({}, { "name": 0 }, { "name": 1 }).namespace).toBe("next2d.ui.Job"); + }); + + it("namespace test static", function() + { + expect(Job.namespace).toBe("next2d.ui.Job"); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Job.ts b/packages/ui/src/Job.ts index 5463b4a1..7c6790a9 100644 --- a/packages/ui/src/Job.ts +++ b/packages/ui/src/Job.ts @@ -1,5 +1,8 @@ -import { Easing } from "./Easing"; import type { ObjectImpl } from "./interface/ObjectImpl"; +import type { EntriesObjectImpl } from "./interface/EntriesObjectImpl"; +import { Easing } from "./Easing"; +import { execute as jobEntriesService } from "./Job/JobEntriesService"; +import { execute as jobUpdateFrameService } from "./Job/JobUpdateFrameService"; import { EventDispatcher, Event @@ -16,12 +19,11 @@ export class Job extends EventDispatcher private _$delay: number; private _$duration: number; private _$ease: Function; - private _$from: any; - private _$names: any[] | null; + private _$from: ObjectImpl; + private _$to: ObjectImpl; + private _$entries: EntriesObjectImpl[] | null; private _$startTime: number; private _$stopFlag: boolean; - private _$forceStop: boolean; - private _$to: any; private _$currentTime: number; private _$timerId: number; // eslint-disable-next-line no-use-before-define @@ -86,7 +88,7 @@ export class Job extends EventDispatcher * @default null * @private */ - this._$names = null; + this._$entries = null; /** * @type {number} @@ -102,13 +104,6 @@ export class Job extends EventDispatcher */ this._$stopFlag = false; - /** - * @type {boolean} - * @default false - * @private - */ - this._$forceStop = false; - /** * @type {object} * @default null @@ -125,10 +120,10 @@ export class Job extends EventDispatcher /** * @type {number} - * @default 0 + * @default -1 * @private */ - this._$timerId = 0; + this._$timerId = -1; /** * @type {Job} @@ -195,6 +190,10 @@ export class Job extends EventDispatcher } /** + * @description イージングの計算関数を返します。 + * Returns the calculation function of the easing. + * + * @see Easing * @member {function} * @default Easing.linear * @public @@ -205,12 +204,13 @@ export class Job extends EventDispatcher } set ease (ease: Function) { - if (typeof ease === "function") { - this._$ease = ease; - } + this._$ease = ease; } /** + * @description イージングの開始までの遅延時間を返します。 + * Returns the delay time until the start of the easing. + * * @member {number} * @default 0 * @public @@ -225,6 +225,9 @@ export class Job extends EventDispatcher } /** + * @description イージング完了時間を返します。 + * Returns the easing completion time. + * * @member {number} * @default 1 * @public @@ -239,7 +242,11 @@ export class Job extends EventDispatcher } /** + * @description イージングの開始オブジェクトを返します。 + * Returns the start object of the easing. + * * @member {object} + * @default null * @public */ get from (): ObjectImpl @@ -252,7 +259,11 @@ export class Job extends EventDispatcher } /** + * @description イージングの終了オブジェクトを返します。 + * Returns the end object of the easing. + * * @member {object} + * @default null * @public */ get to (): ObjectImpl @@ -265,7 +276,28 @@ export class Job extends EventDispatcher } /** + * @description イージングの現在時間を返します。 + * Returns the current time of the easing. + * + * @member {number} + * @default 0 + * @public + */ + get currentTime (): number + { + return this._$currentTime; + } + set currentTime (time: number) + { + this._$currentTime = time; + } + + /** + * @description イージングの対象オブジェクトを返します(読み取り専用) + * Returns the target object of the easing (read-only) + * * @member {object} + * @default null * @readonly * @public */ @@ -275,198 +307,144 @@ export class Job extends EventDispatcher } /** - * @description 指定したjobを次に開始します。nullで解消 - * Starts the next specified job, resolved by null + * @description イージングのエントリーオブジェクトを返します。 + * Returns the entry object of the easing. * - * @member {Job | null} + * @member {array | null} * @default null + * @readonly * @public */ - chain (job: Job | null): Job | null + get entries (): EntriesObjectImpl[] | null { - this._$nextJob = job; - return job; + return this._$entries; } /** - * @return {void} - * @method + * @description イージングの次のjobを返します。 + * Returns the next job of the easing. + * + * @member {Job | null} + * @default null + * @readonly * @public */ - initialize (): void + get nextJob (): Job | null { - if (this._$forceStop) { - return ; - } - - // setup - this._$stopFlag = false; - this._$startTime = performance.now(); - - this._$names = this._$entries(this._$from); - - // start - this._$update(); + return this._$nextJob; } /** - * @param {object} object - * @return {array} - * @method - * @private + * @description イージングの強制停止フラグを返します。 + * Returns the forced stop flag of the easing. + * + * @member {boolean} + * @default false + * @readonly + * @public */ - _$entries (object: any): any[] + get stopFlag (): boolean { - const entries: any[] = Object.entries(object); - - for (let idx = 0; idx < entries.length; ++idx) { - - const values = entries[idx]; - - const value: any = values[1]; - if (value && typeof value === "object") { - values[1] = this._$entries(value); - } - } - - return entries; + return this._$stopFlag; } /** - * @return {void} - * @method + * @description イージングの開始時間を返します。 + * Returns the start time of the easing. + * + * @member {number} + * @default 0 + * @readonly * @public */ - start (): void + get startTime (): number { - if (this._$timerId) { - cancelAnimationFrame(this._$timerId); - } - - this._$forceStop = false; - - if (this._$delay) { - - setTimeout((): void => - { - this.initialize(); - }, this._$delay * 1000); - - return ; - } - - this.initialize(); + return this._$startTime; } /** - * @return {void} + * @description 指定したjobを次に開始します。nullで解消 + * Starts the next specified job, resolved by null + * + * @return {Job | null} * @method * @public */ - stop (): void + chain (job: Job | null): Job | null { - if (this._$timerId) { - cancelAnimationFrame(this._$timerId); - } - - if (this.hasEventListener(Event.STOP)) { - this.dispatchEvent(new Event(Event.STOP)); - } - - this._$names = null; - this._$forceStop = true; - this._$stopFlag = true; + this._$nextJob = job; + return job; } /** + * @description イージングを開始します。 + * Starts the easing. + * * @return {void} * @method - * @private + * @public */ - _$update (): void + start (): void { - if (this._$stopFlag) { - return ; - } + // stop job + cancelAnimationFrame(this._$timerId); - if (!this._$names) { - return this.stop(); - } + // reset + this._$stopFlag = false; - // update current time - this._$currentTime = (performance.now() - this._$startTime) * 0.001; + /** + * @description イージングの起動関数 + * Easing boot function + * + * @return {void} + * @method + * @private + */ + const boot = (): void => + { + if (this._$stopFlag) { + return ; + } - this._$updateProperty( - this._$target, this._$from, this._$to, this._$names - ); + // create entries + this._$entries = jobEntriesService(this._$from); + if (!this._$entries) { + return ; + } - if (this.hasEventListener(Event.UPDATE)) { - this.dispatchEvent(new Event(Event.UPDATE)); - } + // setup + this._$startTime = performance.now(); - if (this._$currentTime >= this._$duration) { - if (this.hasEventListener(Event.COMPLETE)) { - this.dispatchEvent(new Event(Event.COMPLETE)); - } + // start + this._$timerId = jobUpdateFrameService(this, this._$startTime); + }; - if (this._$nextJob) { - this._$nextJob.start(); - } + // delayed start + if (this._$delay) { + setTimeout(boot, this._$delay * 1000); } else { - this._$timerId = requestAnimationFrame(() => { - this._$update(); - }); + boot(); } } /** - * @param {object} target - * @param {object} from - * @param {object} to - * @param {array} names + * @description イージングを停止します。 + * Stops the easing. + * * @return {void} * @method - * @private + * @public */ - _$updateProperty (target: any, from: any, to: any, names: any[]): void + stop (): void { - for (let idx = 0; idx < names.length; ++idx) { - - const values = names[idx]; + cancelAnimationFrame(this._$timerId); - const name = values[0]; - if (name === "__proto__" - || name === "constructor" - || name === "prototype" - ) { - continue; - } - - const value = values[1]; - if (value && typeof value === "object") { - this._$updateProperty(target[name], from[name], to[name], value); - continue; - } - - if (!(name in target)) { - continue; - } - - // update - const fromValue = from[name]; - if (this._$duration > this._$currentTime) { - - target[name] = this._$ease( - this._$currentTime, - fromValue, to[name] - fromValue, - this._$duration - ); - - } else { - - target[name] = to[name]; - - } + if (this.hasEventListener(Event.STOP)) { + this.dispatchEvent(new Event(Event.STOP)); } + + // reset + this._$entries = null; + this._$stopFlag = true; } -} +} \ No newline at end of file diff --git a/packages/ui/src/Job/JobEntriesService.test.ts b/packages/ui/src/Job/JobEntriesService.test.ts new file mode 100644 index 00000000..5fbe28be --- /dev/null +++ b/packages/ui/src/Job/JobEntriesService.test.ts @@ -0,0 +1,80 @@ +import type { EntriesObjectImpl } from "../interface/EntriesObjectImpl"; +import { execute } from "./JobEntriesService"; +import { describe, expect, it } from "vitest"; + +describe("JobEntriesService.js method test", () => +{ + it("test case1", () => + { + const entries = execute({ "x": 100, "y": 200 }); + expect(entries.length).toBe(2); + expect(entries[0].name).toBe("x"); + expect(entries[0].value).toBe(100); + expect(entries[1].name).toBe("y"); + expect(entries[1].value).toBe(200); + }); + + it("test case2", () => + { + const entries = execute({ + "x": 100, + "y": 200, + "matrix": { + "a": 1, + "b": 2 + } + }); + + expect(entries.length).toBe(3); + expect(entries[0].name).toBe("x"); + expect(entries[0].value).toBe(100); + expect(entries[1].name).toBe("y"); + expect(entries[1].value).toBe(200); + + const matrix = entries[2].value; + expect(matrix[0].name).toBe("a"); + expect(matrix[0].value).toBe(1); + expect(matrix[1].name).toBe("b"); + expect(matrix[1].value).toBe(2); + }); + + it("test case2", () => + { + const entries = execute({ + "x": 100, + "y": 200, + "transform": { + "matrix": { + "a": 1, + "b": 2 + }, + "color": { + "red": 255, + "green": 255 + } + } + + }); + + expect(entries.length).toBe(3); + expect(entries[0].name).toBe("x"); + expect(entries[0].value).toBe(100); + expect(entries[1].name).toBe("y"); + expect(entries[1].value).toBe(200); + + const transform = entries[2].value as EntriesObjectImpl[]; + expect(transform.length).toBe(2); + + const matrix = transform[0].value; + expect(matrix[0].name).toBe("a"); + expect(matrix[0].value).toBe(1); + expect(matrix[1].name).toBe("b"); + expect(matrix[1].value).toBe(2); + + const color = transform[1].value; + expect(color[0].name).toBe("red"); + expect(color[0].value).toBe(255); + expect(color[1].name).toBe("green"); + expect(color[1].value).toBe(255); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Job/JobEntriesService.ts b/packages/ui/src/Job/JobEntriesService.ts new file mode 100644 index 00000000..75415950 --- /dev/null +++ b/packages/ui/src/Job/JobEntriesService.ts @@ -0,0 +1,24 @@ +import type { EntriesObjectImpl } from "../interface/EntriesObjectImpl"; +import type { ObjectImpl } from "../interface/ObjectImpl"; + +/** + * @description Tweenの開始/終了のオブジェクトを配列に変換 + * Convert tween start/end objects to arrays + * + * @param {object} object + * @return {array} + * @method + * @private + */ +export const execute = (object: ObjectImpl): EntriesObjectImpl[] => +{ + const entries: EntriesObjectImpl[] = []; + for (const [name, value] of Object.entries(object)) + { + entries.push({ + "name": name, + "value": typeof value === "number" ? value : execute(value) + }); + } + return entries; +}; \ No newline at end of file diff --git a/packages/ui/src/Job/JobUpdateFrameService.ts b/packages/ui/src/Job/JobUpdateFrameService.ts new file mode 100644 index 00000000..7634ff68 --- /dev/null +++ b/packages/ui/src/Job/JobUpdateFrameService.ts @@ -0,0 +1,57 @@ +import type { EntriesObjectImpl } from "../interface/EntriesObjectImpl"; +import type { Job } from "../Job"; +import { execute as jobUpdatePropertyService } from "./JobUpdatePropertyService"; +import { Event } from "@next2d/events"; + +/** + * @description 繰り返しのアップデート処理関数 + * Update process function + * + * @param {Job} job + * @param {number} timestamp + * @return {array} + * @method + * @private + */ +export const execute = (job: Job, timestamp: number): number => +{ + if (job.stopFlag) { + return -1; + } + + // update current time + job.currentTime = (timestamp - job.startTime) * 0.001; + + // update property + jobUpdatePropertyService( + job, job.target, + job.from, job.to, + job.entries as EntriesObjectImpl[] + ); + + // complete logic + if (job.currentTime >= job.duration) { + + // complete event + if (job.hasEventListener(Event.COMPLETE)) { + job.dispatchEvent(new Event(Event.COMPLETE)); + } + + // next job + if (job.nextJob) { + job.nextJob.start(); + } + + return -1; + } + + // update event + if (job.hasEventListener(Event.UPDATE)) { + job.dispatchEvent(new Event(Event.UPDATE)); + } + + return requestAnimationFrame((timestamp: number): void => + { + execute(job, timestamp); + }); +}; \ No newline at end of file diff --git a/packages/ui/src/Job/JobUpdatePropertyService.test.ts b/packages/ui/src/Job/JobUpdatePropertyService.test.ts new file mode 100644 index 00000000..d3e68269 --- /dev/null +++ b/packages/ui/src/Job/JobUpdatePropertyService.test.ts @@ -0,0 +1,64 @@ +import { execute } from "./JobUpdatePropertyService"; +import { execute as jobEntriesService } from "./JobEntriesService"; +import { Job } from "../Job"; +import { describe, expect, it } from "vitest"; + +describe("JobUpdatePropertyService.js method test", () => +{ + it("test case1", () => + { + const target = { "a": 1, "b": 2 }; + const from = { "a": 0, "b": 0 }; + const to = { "a": 10, "b": 20 }; + const job = new Job(target, from, to); + const entries = jobEntriesService(from); + + execute(job, target, from, to, entries); + + expect(target.a).toBe(0); + expect(target.b).toBe(0); + }); + + it("test case2", () => + { + const target = { "a": 1, "b": 2 }; + const from = { "a": 0, "b": 0 }; + const to = { "a": 10, "b": 20 }; + const job = new Job(target, from, to); + const entries = jobEntriesService(from); + + job.duration = -1; + + execute(job, target, from, to, entries); + expect(target.a).toBe(10); + expect(target.b).toBe(20); + }); + + it("test case3", () => + { + const target = { + "a": 1, + "b": 2, + "color": { + "red": 128 + } + }; + const from = { "a": 0, "b": 0, "color": { "red": 0 } }; + const to = { "a": 10, "b": 20, "color": { "red": 255 } }; + const job = new Job(target, from, to); + const entries = jobEntriesService(from); + + execute(job, target, from, to, entries); + + expect(target.a).toBe(0); + expect(target.b).toBe(0); + expect(target.color.red).toBe(0); + + job.duration = -1; + + execute(job, target, from, to, entries); + expect(target.a).toBe(10); + expect(target.b).toBe(20); + expect(target.color.red).toBe(255); + }); +}); \ No newline at end of file diff --git a/packages/ui/src/Job/JobUpdatePropertyService.ts b/packages/ui/src/Job/JobUpdatePropertyService.ts new file mode 100644 index 00000000..ca95ff9e --- /dev/null +++ b/packages/ui/src/Job/JobUpdatePropertyService.ts @@ -0,0 +1,66 @@ +import type { EntriesObjectImpl } from "../interface/EntriesObjectImpl"; +import type { ObjectImpl } from "../interface/ObjectImpl"; +import type { Job } from "../Job"; + +/** + * @description fromのオブジェクトのプロパティを元に、targetのプロパティの値を更新 + * Update the value of the target property based on the properties of the from object + * + * @param {Job} job + * @param {object} target + * @param {object} from + * @param {object} to + * @param {array} entries + * @return {void} + * @method + * @private + */ +export const execute = ( + job: Job, + target: any, + from: ObjectImpl, + to: ObjectImpl, + entries: EntriesObjectImpl[] +): void => { + + for (let idx = 0; idx < entries.length; ++idx) { + + const entry = entries[idx]; + if (!entry) { + continue; + } + + const name = entry.name; + if (!(name in target) || !(name in to)) { + continue; + } + + if (typeof entry.value !== "number") { + execute( + job, + target[name], + from[name] as ObjectImpl, + to[name] as ObjectImpl, + entry.value as EntriesObjectImpl[] + ); + continue; + } + + // update + const fromValue = from[name] as number; + if (job.duration > job.currentTime) { + + target[name] = job.ease( + job.currentTime, + fromValue, to[name] as number - fromValue, + job.duration + ); + + } else { + + // Easing end + target[name] = to[name] as number; + + } + } +}; \ No newline at end of file diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 59e47a36..738ff93b 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -1,3 +1,2 @@ export * from "./Easing"; -export * from "./Job"; export * from "./Tween"; \ No newline at end of file diff --git a/packages/ui/src/interface/EntriesObjectImpl.ts b/packages/ui/src/interface/EntriesObjectImpl.ts new file mode 100644 index 00000000..c1eb1a01 --- /dev/null +++ b/packages/ui/src/interface/EntriesObjectImpl.ts @@ -0,0 +1,4 @@ +export interface EntriesObjectImpl { + name: string; + value: number | EntriesObjectImpl[]; +} \ No newline at end of file diff --git a/packages/ui/src/interface/ObjectImpl.ts b/packages/ui/src/interface/ObjectImpl.ts index 1ed02c39..a3f38954 100644 --- a/packages/ui/src/interface/ObjectImpl.ts +++ b/packages/ui/src/interface/ObjectImpl.ts @@ -1,3 +1,3 @@ export interface ObjectImpl { - [key: string]: { value: number | ObjectImpl } + [key: string]: number | ObjectImpl } \ No newline at end of file From 4c41faf85f630934094e09f75128c7f153db8009 Mon Sep 17 00:00:00 2001 From: ienaga Date: Wed, 24 Jul 2024 21:58:14 +0900 Subject: [PATCH 013/343] =?UTF-8?q?#154=20delete:=20Event=E3=83=91?= =?UTF-8?q?=E3=83=83=E3=82=B1=E3=83=BC=E3=82=B8=E3=81=AE=E4=B8=8D=E8=A6=81?= =?UTF-8?q?=E3=81=AA=E3=82=A4=E3=83=B3=E3=82=BF=E3=83=BC=E3=83=95=E3=82=A7?= =?UTF-8?q?=E3=83=BC=E3=82=B9=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/events/src/interface/DisplayObjectContainerImpl.ts | 1 - 1 file changed, 1 deletion(-) delete mode 100644 packages/events/src/interface/DisplayObjectContainerImpl.ts diff --git a/packages/events/src/interface/DisplayObjectContainerImpl.ts b/packages/events/src/interface/DisplayObjectContainerImpl.ts deleted file mode 100644 index 7d036b8a..00000000 --- a/packages/events/src/interface/DisplayObjectContainerImpl.ts +++ /dev/null @@ -1 +0,0 @@ -export interface DisplayObjectContainerImpl { \ No newline at end of file From fa8cd89a7f182a606ede79210fbeee24083c2ce6 Mon Sep 17 00:00:00 2001 From: ienaga Date: Thu, 25 Jul 2024 08:32:02 +0900 Subject: [PATCH 014/343] =?UTF-8?q?#154=20feat:=20Event=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E3=82=92=E7=A7=BB=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/Net.ts | 10 +- packages/events/package.json | 8 - packages/events/src/Event.test.ts | 148 ++++++++++++++++++ packages/events/src/Event.ts | 128 +++++---------- .../Event/EventFormatToStringService.test.ts | 13 ++ .../src/Event/EventFormatToStringService.ts | 31 ++++ packages/events/src/EventPhase.test.ts | 52 ++++++ packages/events/src/EventPhase.ts | 15 +- packages/events/src/FocusEvent.test.ts | 47 ++++++ packages/events/src/FocusEvent.ts | 26 ++- packages/events/src/HTTPStatusEvent.test.ts | 39 +++++ packages/events/src/HTTPStatusEvent.ts | 20 +-- packages/events/src/IOErrorEvent.test.ts | 47 ++++++ packages/events/src/IOErrorEvent.ts | 16 +- packages/events/src/MouseEvent.test.ts | 76 +++++++++ packages/events/src/MouseEvent.ts | 40 ++--- packages/events/src/ProgressEvent.test.ts | 40 +++++ packages/events/src/ProgressEvent.ts | 20 +-- packages/events/src/VideoEvent.test.ts | 66 ++++++++ packages/events/src/VideoEvent.ts | 26 +-- .../src/interface/EventDispatcherImpl.ts | 5 +- packages/events/src/interface/EventImpl.ts | 2 + packages/interface/src/NetImpl.ts | 6 +- packages/net/package.json | 4 +- packages/net/src/URLRequest.ts | 40 ++--- packages/net/src/URLRequestHeader.ts | 123 --------------- packages/net/src/index.ts | 3 +- .../src/interface/URLLoaderDataFormatImpl.ts | 1 + .../net/src/interface/URLRequestHeaderImpl.ts | 5 + .../net/src/interface/URLRequestMethodImpl.ts | 1 + 30 files changed, 714 insertions(+), 344 deletions(-) create mode 100644 packages/events/src/Event.test.ts create mode 100644 packages/events/src/Event/EventFormatToStringService.test.ts create mode 100644 packages/events/src/Event/EventFormatToStringService.ts create mode 100644 packages/events/src/EventPhase.test.ts create mode 100644 packages/events/src/FocusEvent.test.ts create mode 100644 packages/events/src/HTTPStatusEvent.test.ts create mode 100644 packages/events/src/IOErrorEvent.test.ts create mode 100644 packages/events/src/MouseEvent.test.ts create mode 100644 packages/events/src/ProgressEvent.test.ts create mode 100644 packages/events/src/VideoEvent.test.ts create mode 100644 packages/events/src/interface/EventImpl.ts delete mode 100644 packages/net/src/URLRequestHeader.ts create mode 100644 packages/net/src/interface/URLLoaderDataFormatImpl.ts create mode 100644 packages/net/src/interface/URLRequestHeaderImpl.ts create mode 100644 packages/net/src/interface/URLRequestMethodImpl.ts diff --git a/packages/core/src/Net.ts b/packages/core/src/Net.ts index a71595b6..05d530da 100644 --- a/packages/core/src/Net.ts +++ b/packages/core/src/Net.ts @@ -1,12 +1,8 @@ -import { NetImpl } from "@next2d/interface"; -import { - URLRequest, - URLRequestHeader -} from "@next2d/net"; +import type { NetImpl } from "@next2d/interface"; +import { URLRequest } from "@next2d/net"; const net: NetImpl = { - URLRequest, - URLRequestHeader + URLRequest }; Object.entries(net).forEach(([key, NetClass]) => diff --git a/packages/events/package.json b/packages/events/package.json index 0091c87d..fc26dae2 100644 --- a/packages/events/package.json +++ b/packages/events/package.json @@ -24,13 +24,5 @@ "repository": { "type": "git", "url": "git+https://github.com/Next2D/Player.git" - }, - "peerDependencies": { - "@next2d/interface": "file:../interface", - "@next2d/display": "file:../display", - "@next2d/core": "file:../core", - "@next2d/util": "file:../util", - "@next2d/net": "file:../net", - "@next2d/share": "file:../share" } } diff --git a/packages/events/src/Event.test.ts b/packages/events/src/Event.test.ts new file mode 100644 index 00000000..c3a0192e --- /dev/null +++ b/packages/events/src/Event.test.ts @@ -0,0 +1,148 @@ +import { Event } from "./Event"; +import { describe, expect, it } from "vitest"; + +describe("Event.js toString test", function() +{ + it("toString test case1", function() + { + const event = new Event("test"); + expect(event.toString()) + .toBe("[Event type=\"test\" bubbles=false cancelable=false eventPhase=2]"); + }); +}); + +describe("Event.js static toString test", function() +{ + it("static toString test", function() + { + expect(Event.toString()).toBe("[class Event]"); + }); +}); + +describe("Event.js namespace test", function() +{ + it("namespace test public", function() + { + const event = new Event("test"); + expect(event.namespace).toBe("next2d.events.Event"); + }); + + it("namespace test static", function() + { + expect(Event.namespace).toBe("next2d.events.Event"); + }); +}); + +describe("Event.js property test", function() +{ + + it("ACTIVATE test", () => + { + expect(Event.ACTIVATE).toBe("activate"); + }); + + it("ADDED test", () => + { + expect(Event.ADDED).toBe("added"); + }); + + it("ADDED_TO_STAGE test", () => + { + expect(Event.ADDED_TO_STAGE).toBe("addedToStage"); + }); + + it("CHANGE test", () => + { + expect(Event.CHANGE).toBe("change"); + }); + + it("COMPLETE test", () => + { + expect(Event.COMPLETE).toBe("complete"); + }); + + it("DEACTIVATE test", () => + { + expect(Event.DEACTIVATE).toBe("deactivate"); + }); + + it("ENTER_FRAME test", () => + { + expect(Event.ENTER_FRAME).toBe("enterFrame"); + }); + + it("EXIT_FRAME test", () => + { + expect(Event.EXIT_FRAME).toBe("exitFrame"); + }); + + it("FRAME_CONSTRUCTED test", () => + { + expect(Event.FRAME_CONSTRUCTED).toBe("frameConstructed"); + }); + + it("FRAME_LABEL test", () => + { + expect(Event.FRAME_LABEL).toBe("frameLabel"); + }); + + it("INIT test", () => + { + expect(Event.INIT).toBe("init"); + }); + + it("LOAD test", () => + { + expect(Event.LOAD).toBe("load"); + }); + + it("MOUSE_LEAVE test", () => + { + expect(Event.MOUSE_LEAVE).toBe("mouseLeave"); + }); + + it("REMOVED test", () => + { + expect(Event.REMOVED).toBe("removed"); + }); + + it("REMOVED_FROM_STAGE test", () => + { + expect(Event.REMOVED_FROM_STAGE).toBe("removedFromStage"); + }); + + it("RENDER test", () => + { + expect(Event.RENDER).toBe("render"); + }); + + it("RESIZE test", () => + { + expect(Event.RESIZE).toBe("resize"); + }); + + it("SCROLL test", () => + { + expect(Event.SCROLL).toBe("scroll"); + }); + + it("OPEN test", () => + { + expect(Event.OPEN).toBe("open"); + }); + + it("STOP test", () => + { + expect(Event.STOP).toBe("stop"); + }); + + it("SOUND_COMPLETE test", () => + { + expect(Event.SOUND_COMPLETE).toBe("soundComplete"); + }); + + it("UPDATE test", () => + { + expect(Event.UPDATE).toBe("update"); + }); +}); \ No newline at end of file diff --git a/packages/events/src/Event.ts b/packages/events/src/Event.ts index 5194cef8..2328aba1 100644 --- a/packages/events/src/Event.ts +++ b/packages/events/src/Event.ts @@ -1,20 +1,21 @@ import { EventPhase } from "./EventPhase"; import type { EventDispatcherImpl } from "./interface/EventDispatcherImpl"; +import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; /** - * Event クラスのメソッドは、イベントリスナー関数で使用してイベントオブジェクトの動作に影響を与えることができます。 - * 一部のイベントにはデフォルトの動作が関連付けられています。 - * 例えば、doubleClick イベントには、イベント時にマウスポインター位置の単語がハイライト表示されるというデフォルトの動作が関連付けられています。 - * イベントリスナーで preventDefault() メソッドを呼び出してこの動作をキャンセルできます。 - * また、stopPropagation() メソッドまたは stopImmediatePropagation() メソッドを呼び出すと、 - * 現在のイベントリスナーを、イベントを処理する最後のイベントリスナーにすることができます。 + * @description Event クラスのメソッドは、イベントリスナー関数で使用してイベントオブジェクトの動作に影響を与えることができます。 + * 一部のイベントにはデフォルトの動作が関連付けられています。 + * 例えば、doubleClick イベントには、イベント時にマウスポインター位置の単語がハイライト表示されるというデフォルトの動作が関連付けられています。 + * イベントリスナーで preventDefault() メソッドを呼び出してこの動作をキャンセルできます。 + * また、stopPropagation() メソッドまたは stopImmediatePropagation() メソッドを呼び出すと、 + * 現在のイベントリスナーを、イベントを処理する最後のイベントリスナーにすることができます。 * - * The methods of the Event class can be used in event listener functions to affect the behavior of the event object. - * Some events have an associated default behavior. For example, - * the doubleClick event has an associated default behavior that highlights the word under the mouse pointer at the time of the event. - * Your event listener can cancel this behavior by calling the preventDefault() method. - * You can also make the current event listener the last one to process - * an event by calling the stopPropagation() or stopImmediatePropagation() method. + * The methods of the Event class can be used in event listener functions to affect the behavior of the event object. + * Some events have an associated default behavior. For example, + * the doubleClick event has an associated default behavior that highlights the word under the mouse pointer at the time of the event. + * Your event listener can cancel this behavior by calling the preventDefault() method. + * You can also make the current event listener the last one to process + * an event by calling the stopPropagation() or stopImmediatePropagation() method. * * @class * @memberOf next2d.events @@ -77,7 +78,7 @@ export class Event this._$currentTarget = null; /** - * @type {number} + * @type {number} * @default EventPhase.AT_TARGET * @private */ @@ -109,8 +110,8 @@ export class Event * 指定されたクラスのストリングを返します。 * Returns the string representation of the specified class. * - * @return {string} - * @default [class Event] + * @return {string} + * @default "[class Event]" * @method * @static */ @@ -124,7 +125,7 @@ export class Event * Returns the space name of the specified class. * * @member {string} - * @default next2d.events.Event + * @default "next2d.events.Event" * @const * @static */ @@ -143,7 +144,7 @@ export class Event */ toString (): string { - return this.formatToString("Event", "type", "bubbles", "cancelable", "eventPhase"); + return eventFormatToStringService(this, "Event", "type", "bubbles", "cancelable", "eventPhase"); } /** @@ -151,7 +152,7 @@ export class Event * Returns the space name of the specified object. * * @member {string} - * @default next2d.events.Event + * @default "next2d.events.Event" * @const * @public */ @@ -165,8 +166,7 @@ export class Event * The ACTIVATE constant defines the value * of the type property of an activate event object. * - * @return {string} - * @default activate + * @return {string} * @const * @static */ @@ -180,8 +180,7 @@ export class Event * The Event.ADDED constant defines the value * of the type property of an added event object. * - * @return {string} - * @default added + * @return {string} * @const * @static */ @@ -195,8 +194,7 @@ export class Event * The Event.ADDED_TO_STAGE constant defines the value * of the type property of an addedToStage event object. * - * @return {string} - * @default addedToStage + * @return {string} * @const * @static */ @@ -210,8 +208,7 @@ export class Event * The Event.CHANGE constant defines the value * of the type property of a change event object. * - * @return {string} - * @default change + * @return {string} * @const * @static */ @@ -225,8 +222,7 @@ export class Event * The Event.COMPLETE constant defines the value * of the type property of a complete event object. * - * @return {string} - * @default complete + * @return {string} * @const * @static */ @@ -240,8 +236,7 @@ export class Event * The Event.DEACTIVATE constant defines the value * of the type property of a deactivate event object. * - * @return {string} - * @default deactivate + * @return {string} * @const * @static */ @@ -255,8 +250,7 @@ export class Event * The Event.ENTER_FRAME constant defines the value * of the type property of an enterFrame event object. * - * @return {string} - * @default enterFrame + * @return {string} * @const * @static */ @@ -270,8 +264,7 @@ export class Event * The Event.EXIT_FRAME constant defines the value * of the type property of an exitFrame event object. * - * @return {string} - * @default exitFrame + * @return {string} * @const * @static */ @@ -285,8 +278,7 @@ export class Event * The Event.FRAME_CONSTRUCTED constant defines the value * of the type property of an frameConstructed event object. * - * @return {string} - * @default frameConstructed + * @return {string} * @const * @static */ @@ -300,8 +292,7 @@ export class Event * The Event.FRAME_LABEL constant defines the value * of the type property of an frameLabel event object. * - * @return {string} - * @default frameLabel + * @return {string} * @const * @static */ @@ -315,8 +306,7 @@ export class Event * The Event.INIT constant defines the value * of the type property of an init event object. * - * @return {string} - * @default frameConstructed + * @return {string} * @const * @static */ @@ -330,8 +320,7 @@ export class Event * The Event.LOAD constant defines the value * of the type property of an load event object. * - * @return {string} - * @default frameConstructed + * @return {string} * @const * @static */ @@ -345,8 +334,7 @@ export class Event * The Event.MOUSE_LEAVE constant defines the value * of the type property of a mouseLeave event object. * - * @return {string} - * @default mouseLeave + * @return {string} * @const * @static */ @@ -360,8 +348,7 @@ export class Event * The Event.REMOVED constant defines the value * of the type property of a removed event object. * - * @return {string} - * @default removed + * @return {string} * @const * @static */ @@ -375,8 +362,7 @@ export class Event * The Event.REMOVED_FROM_STAGE constant defines the value * of the type property of a removedFromStage event object. * - * @return {string} - * @default removedFromStage + * @return {string} * @const * @static */ @@ -392,7 +378,6 @@ export class Event * of the type property of a render event object. * * @return {string} - * @default render * @const * @static */ @@ -408,7 +393,6 @@ export class Event * of the type property of a resize event object. * * @return {string} - * @default resize * @const * @static */ @@ -424,7 +408,6 @@ export class Event * of the type property of a render event object. * * @return {string} - * @default scroll * @const * @static */ @@ -440,7 +423,6 @@ export class Event * of the type property of a render event object. * * @return {string} - * @default open * @const * @static */ @@ -456,7 +438,6 @@ export class Event * of the type property of a render event object. * * @return {string} - * @default stop * @const * @static */ @@ -471,7 +452,6 @@ export class Event * of the type property of a soundComplete event object. * * @return {string} - * @default render * @const * @static */ @@ -487,7 +467,6 @@ export class Event * of the type property of a render event object. * * @return {string} - * @default update * @const * @static */ @@ -501,6 +480,7 @@ export class Event * Indicates whether an event is a bubbling event. * * @member {boolean} + * @default false * @readonly * @public */ @@ -515,6 +495,7 @@ export class Event * with the event can be prevented. * * @member {boolean} + * @default false * @readonly * @public */ @@ -529,6 +510,7 @@ export class Event * with an event listener. * * @member {EventDispatcher|null} + * @default null * @public */ get currentTarget (): EventDispatcherImpl @@ -545,6 +527,7 @@ export class Event * The current phase in the event flow. * * @member {number} + * @default EventPhase.AT_TARGET * @public */ get eventPhase (): number @@ -561,6 +544,7 @@ export class Event * Function currently being called. * * @member {function} + * @default null * @public */ get listener (): Function | null @@ -601,40 +585,6 @@ export class Event return this._$type; } - /** - * @description カスタム ActionScript 3.0 Event クラスに - * toString() メソッドを実装するためのユーティリティ関数です。 - * A utility function for implementing the toString() method - * in custom ActionScript 3.0 Event classes. - * - * @return {string} - * @method - * @public - */ - formatToString (...args: string[]): string - { - let str = `[${args[0]}`; - - for (let idx:number = 1; idx < args.length; ++idx) { - - // eslint-disable-next-line prefer-rest-params - const name = args[idx]; - - str += ` ${name}=`; - - // @ts-ignore - const value = this[name]; - if (typeof value === "string") { - str += `"${value}"`; - } else { - str += `${value}`; - } - - } - - return `${str}]`; - } - /** * @description イベントフローの現在のノードおよび後続するノードで、 * イベントリスナーが処理されないようにします。 diff --git a/packages/events/src/Event/EventFormatToStringService.test.ts b/packages/events/src/Event/EventFormatToStringService.test.ts new file mode 100644 index 00000000..754c0a7a --- /dev/null +++ b/packages/events/src/Event/EventFormatToStringService.test.ts @@ -0,0 +1,13 @@ +import { Event } from "../Event"; +import { execute } from "./EventFormatToStringService"; +import { describe, expect, it } from "vitest"; + +describe("EventFormatToStringService.js toString test", function() +{ + it("toString test case", function() + { + const event = new Event("test"); + expect(execute(event, "Event", "type", "bubbles", "cancelable", "eventPhase")) + .toBe("[Event type=\"test\" bubbles=false cancelable=false eventPhase=2]"); + }); +}); diff --git a/packages/events/src/Event/EventFormatToStringService.ts b/packages/events/src/Event/EventFormatToStringService.ts new file mode 100644 index 00000000..fe97624b --- /dev/null +++ b/packages/events/src/Event/EventFormatToStringService.ts @@ -0,0 +1,31 @@ +import { EventImpl } from "../interface/EventImpl"; + +/** + * @description toString() メソッドを実装するためのユーティリティ関数 + * Utility functions to implement the toString() method + * + * @param {Event} event + * @param {array} args + * @return {string} + * @method + * @protected + */ +export const execute = (event: EventImpl, ...args: string[]): string => +{ + let str = `[${args[0]}`; + for (let idx = 1; idx < args.length; ++idx) { + + const name = args[idx]; + if (!(name in event)) { + continue; + } + + str += ` ${name}=`; + + const value = event[name]; + str += typeof value === "string" + ? `"${value}"` + : `${value}`; + } + return `${str}]`; +}; \ No newline at end of file diff --git a/packages/events/src/EventPhase.test.ts b/packages/events/src/EventPhase.test.ts new file mode 100644 index 00000000..d2845240 --- /dev/null +++ b/packages/events/src/EventPhase.test.ts @@ -0,0 +1,52 @@ +import { EventPhase } from "./EventPhase"; +import { describe, expect, it } from "vitest"; + +describe("EventPhase.js toString test", () => +{ + it("toString test case1", () => + { + const eventPhase = new EventPhase(); + expect(eventPhase.toString()).toBe("[object EventPhase]"); + }); + +}); + +describe("EventPhase.js static toString test", () => +{ + it("static toString test", () => + { + expect(EventPhase.toString()).toBe("[class EventPhase]"); + }); +}); + +describe("EventPhase.js namespace test", () => +{ + it("namespace test public", () => + { + const eventPhase = new EventPhase(); + expect(eventPhase.namespace).toBe("next2d.events.EventPhase"); + }); + + it("namespace test static", () => + { + expect(EventPhase.namespace).toBe("next2d.events.EventPhase"); + }); +}); + +describe("EventPhase.js property test", () => +{ + it("CAPTURING_PHASE test", () => + { + expect(EventPhase.CAPTURING_PHASE).toBe(1); + }); + + it("AT_TARGET test", () => + { + expect(EventPhase.AT_TARGET).toBe(2); + }); + + it("BUBBLING_PHASE test", () => + { + expect(EventPhase.BUBBLING_PHASE).toBe(3); + }); +}); \ No newline at end of file diff --git a/packages/events/src/EventPhase.ts b/packages/events/src/EventPhase.ts index a67b1c64..1c03698f 100644 --- a/packages/events/src/EventPhase.ts +++ b/packages/events/src/EventPhase.ts @@ -1,7 +1,6 @@ /** - * EventPhase クラスは、Event クラスの eventPhase プロパティの値を提供します。 - * - * The EventPhase class provides values for the eventPhase property of the Event class. + * @description EventPhase クラスは、Event クラスの eventPhase プロパティの値を提供します。 + * The EventPhase class provides values for the eventPhase property of the Event class. * * @class * @memberOf next2d.events @@ -13,7 +12,7 @@ export class EventPhase * Returns the string representation of the specified class. * * @return {string} - * @default [class EventPhase] + * @default "[class EventPhase]" * @method * @static */ @@ -27,7 +26,7 @@ export class EventPhase * Returns the space name of the specified class. * * @member {string} - * @default next2d.events.EventPhase + * @default "next2d.events.EventPhase" * @const * @static */ @@ -40,8 +39,8 @@ export class EventPhase * @description 指定されたオブジェクトのストリングを返します。 * Returns the string representation of the specified object. * - * @return {string} - * @default [object EventPhase] + * @return {string} + * @default "[object EventPhase]" * @method * @public */ @@ -55,7 +54,7 @@ export class EventPhase * Returns the space name of the specified object. * * @member {string} - * @default next2d.events.EventPhase + * @default "next2d.events.EventPhase" * @const * @public */ diff --git a/packages/events/src/FocusEvent.test.ts b/packages/events/src/FocusEvent.test.ts new file mode 100644 index 00000000..7c464780 --- /dev/null +++ b/packages/events/src/FocusEvent.test.ts @@ -0,0 +1,47 @@ +import { FocusEvent } from "./FocusEvent"; +import { describe, expect, it } from "vitest"; + +describe("FocusEvent.js static toString test", () => +{ + it("static toString test", () => + { + expect(FocusEvent.toString()).toBe("[class FocusEvent]"); + }); +}); + +describe("FocusEvent.js toString test", () => +{ + // toString + it("toString test success", () => + { + const focusEvent = new FocusEvent("focusIn"); + expect(focusEvent.toString()).toBe("[FocusEvent type=\"focusIn\" bubbles=true cancelable=false eventPhase=2]"); + }); +}); + +describe("FocusEvent.js namespace test", () => +{ + it("namespace test public", () => + { + const object = new FocusEvent("test"); + expect(object.namespace).toBe("next2d.events.FocusEvent"); + }); + + it("namespace test static", () => + { + expect(FocusEvent.namespace).toBe("next2d.events.FocusEvent"); + }); +}); + +describe("FocusEvent.js property test", () => +{ + it("FOCUS_IN test", () => + { + expect(FocusEvent.FOCUS_IN).toBe("focusIn"); + }); + + it("FOCUS_OUT test", () => + { + expect(FocusEvent.FOCUS_OUT).toBe("focusOut"); + }); +}); \ No newline at end of file diff --git a/packages/events/src/FocusEvent.ts b/packages/events/src/FocusEvent.ts index 85181b1b..e2c58a6d 100644 --- a/packages/events/src/FocusEvent.ts +++ b/packages/events/src/FocusEvent.ts @@ -1,18 +1,14 @@ import { Event } from "./Event"; +import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; /** - * FocusEvent オブジェクトは、ユーザーが表示リストの1つのオブジェクトから - * 別のオブジェクトにフォーカスを変更したときにオブジェクトによって送出されます。 - * 次の2種類のフォーカスイベントがあります。 + * @description FocusEvent オブジェクトは、ユーザーが表示リストの1つのオブジェクトから + * 別のオブジェクトにフォーカスを変更したときにオブジェクトによって送出されます。 + * 次の2種類のフォーカスイベントがあります。 * - * An object dispatches a FocusEvent object when the user changes - * the focus from one object in the display list to another. - * There are two types of focus events: - * - *
    - *
  • FocusEvent.FOCUS_IN
  • - *
  • FocusEvent.FOCUS_OUT
  • - *
+ * An object dispatches a FocusEvent object when the user changes + * the focus from one object in the display list to another. + * There are two types of focus events: * * @class * @memberOf next2d.events @@ -38,7 +34,7 @@ export class FocusEvent extends Event * Returns the string representation of the specified class. * * @return {string} - * @default [class FocusEvent] + * @default "[class FocusEvent]" * @method * @static */ @@ -52,7 +48,7 @@ export class FocusEvent extends Event * Returns the space name of the specified class. * * @member {string} - * @default next2d.events.FocusEvent + * @default "next2d.events.FocusEvent" * @const * @static */ @@ -71,7 +67,7 @@ export class FocusEvent extends Event */ toString (): string { - return this.formatToString( + return eventFormatToStringService(this, "FocusEvent", "type", "bubbles", "cancelable", "eventPhase" ); } @@ -81,7 +77,7 @@ export class FocusEvent extends Event * Returns the space name of the specified object. * * @member {string} - * @default next2d.events.FocusEvent + * @default "next2d.events.FocusEvent" * @const * @public */ diff --git a/packages/events/src/HTTPStatusEvent.test.ts b/packages/events/src/HTTPStatusEvent.test.ts new file mode 100644 index 00000000..42097944 --- /dev/null +++ b/packages/events/src/HTTPStatusEvent.test.ts @@ -0,0 +1,39 @@ +import { HTTPStatusEvent } from "./HTTPStatusEvent"; +import { describe, expect, it } from "vitest"; + +describe("HTTPStatusEvent.js toString test", () => +{ + it("toString test case1", () => + { + const httpStatusEvent = new HTTPStatusEvent(""); + expect(httpStatusEvent.toString()).toBe("[HTTPStatusEvent type=\"\" bubbles=false cancelable=false eventPhase=2 status=0 responseURL=\"\"]"); + }); + + it("toString test case2", () => + { + const httpStatusEvent = new HTTPStatusEvent("type", true, false, 200, "url"); + expect(httpStatusEvent.toString()).toBe("[HTTPStatusEvent type=\"type\" bubbles=true cancelable=false eventPhase=2 status=200 responseURL=\"url\"]"); + }); +}); + +describe("HTTPStatusEvent.js static toString test", () => +{ + it("static toString test", () => + { + expect(HTTPStatusEvent.toString()).toBe("[class HTTPStatusEvent]"); + }); +}); + +describe("HTTPStatusEvent.js namespace test", () => +{ + it("namespace test public", () => + { + const object = new HTTPStatusEvent("test"); + expect(object.namespace).toBe("next2d.events.HTTPStatusEvent"); + }); + + it("namespace test static", () => + { + expect(HTTPStatusEvent.namespace).toBe("next2d.events.HTTPStatusEvent"); + }); +}); \ No newline at end of file diff --git a/packages/events/src/HTTPStatusEvent.ts b/packages/events/src/HTTPStatusEvent.ts index b465142a..62a56d74 100644 --- a/packages/events/src/HTTPStatusEvent.ts +++ b/packages/events/src/HTTPStatusEvent.ts @@ -1,10 +1,10 @@ import { Event } from "./Event"; import type { URLRequestHeaderImpl } from "./interface/URLRequestHeaderImpl"; +import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; /** - * ネットワーク要求が HTTP ステータスコードを返すと、アプリケーションによって HTTPStatusEvent オブジェクトが送出されます。 - * - * The application dispatches HTTPStatusEvent objects when a network request returns an HTTP status code. + * @description ネットワーク要求が HTTP ステータスコードを返すと、アプリケーションによって HTTPStatusEvent オブジェクトが送出されます。 + * The application dispatches HTTPStatusEvent objects when a network request returns an HTTP status code. * * @class * @memberOf next2d.events @@ -58,11 +58,11 @@ export class HTTPStatusEvent extends Event } /** - * 指定されたクラスのストリングを返します。 - * Returns the string representation of the specified class. + * @description 指定されたクラスのストリングを返します。 + * Returns the string representation of the specified class. * * @return {string} - * @default [class HTTPStatusEvent] + * @default "[class HTTPStatusEvent]" * @method * @static */ @@ -76,7 +76,7 @@ export class HTTPStatusEvent extends Event * Returns the space name of the specified class. * * @member {string} - * @default next2d.events.HTTPStatusEvent + * @default "next2d.events.HTTPStatusEvent" * @const * @static */ @@ -95,7 +95,7 @@ export class HTTPStatusEvent extends Event */ toString (): string { - return this.formatToString( + return eventFormatToStringService(this, "HTTPStatusEvent", "type", "bubbles", "cancelable", "eventPhase", "status", "responseURL" @@ -107,7 +107,7 @@ export class HTTPStatusEvent extends Event * Returns the space name of the specified object. * * @member {string} - * @default next2d.events.HTTPStatusEvent + * @default "next2d.events.HTTPStatusEvent" * @const * @public */ @@ -123,7 +123,7 @@ export class HTTPStatusEvent extends Event * of the type property of a httpStatus event object. * * @return {string} - * @default httpStatus + * @default "httpStatus" * @const * @static */ diff --git a/packages/events/src/IOErrorEvent.test.ts b/packages/events/src/IOErrorEvent.test.ts new file mode 100644 index 00000000..4dc71219 --- /dev/null +++ b/packages/events/src/IOErrorEvent.test.ts @@ -0,0 +1,47 @@ +import { IOErrorEvent } from "./IOErrorEvent"; +import { describe, expect, it } from "vitest"; + +describe("IOErrorEvent.js toString test", () => +{ + // toString + it("toString test case1", () => + { + const ioErrorEvent = new IOErrorEvent(""); + expect(ioErrorEvent.toString()).toBe("[IOErrorEvent type=\"\" bubbles=false cancelable=false eventPhase=2 text=\"\"]"); + }); + + it("toString test case2", () => + { + const ioErrorEvent = new IOErrorEvent("ioError", false, false, "IOErrorEvent"); + expect(ioErrorEvent.toString()).toBe("[IOErrorEvent type=\"ioError\" bubbles=false cancelable=false eventPhase=2 text=\"IOErrorEvent\"]"); + }); +}); + +describe("IOErrorEvent.js static toString test", () => +{ + it("static toString test", () => + { + expect(IOErrorEvent.toString()).toBe("[class IOErrorEvent]"); + }); +}); + +describe("IOErrorEvent.js namespace test", () => +{ + it("namespace test public", () => + { + const ioErrorEvent = new IOErrorEvent("test"); + expect(ioErrorEvent.namespace).toBe("next2d.events.IOErrorEvent"); + }); + + it("namespace test static", () => + { + expect(IOErrorEvent.namespace).toBe("next2d.events.IOErrorEvent"); + }); +}); + +describe("IOErrorEvent.js property test", () => +{ + it("IO_ERROR test", function () { + expect(IOErrorEvent.IO_ERROR).toBe("ioError"); + }); +}); \ No newline at end of file diff --git a/packages/events/src/IOErrorEvent.ts b/packages/events/src/IOErrorEvent.ts index feb2f110..7867a5bd 100644 --- a/packages/events/src/IOErrorEvent.ts +++ b/packages/events/src/IOErrorEvent.ts @@ -1,9 +1,9 @@ import { Event } from "./Event"; +import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; /** - * IOErrorEvent オブジェクトは、エラーが発生して入力操作または出力操作が失敗したときに送出されます。 - * - * An IOErrorEvent object is dispatched when an error causes input or output operations to fail. + * @description IOErrorEvent オブジェクトは、エラーが発生して入力操作または出力操作が失敗したときに送出されます。 + * An IOErrorEvent object is dispatched when an error causes input or output operations to fail. * * @class * @memberOf next2d.events @@ -44,7 +44,7 @@ export class IOErrorEvent extends Event * Returns the string representation of the specified class. * * @return {string} - * @default [class IOErrorEvent] + * @default "[class IOErrorEvent]" * @method * @static */ @@ -58,7 +58,7 @@ export class IOErrorEvent extends Event * Returns the space name of the specified class. * * @member {string} - * @default next2d.events.IOErrorEvent + * @default "next2d.events.IOErrorEvent" * @const * @static */ @@ -77,7 +77,7 @@ export class IOErrorEvent extends Event */ toString (): string { - return this.formatToString( + return eventFormatToStringService(this, "IOErrorEvent", "type", "bubbles", "cancelable", "eventPhase", "text" @@ -89,7 +89,7 @@ export class IOErrorEvent extends Event * Returns the space name of the specified object. * * @member {string} - * @default next2d.events.IOErrorEvent + * @default "next2d.events.IOErrorEvent" * @const * @public */ @@ -103,7 +103,7 @@ export class IOErrorEvent extends Event * Defines the value of the type property of an ioError event object. * * @return {string} - * @default ioError + * @default "ioError" * @const * @static */ diff --git a/packages/events/src/MouseEvent.test.ts b/packages/events/src/MouseEvent.test.ts new file mode 100644 index 00000000..b1c2aaf2 --- /dev/null +++ b/packages/events/src/MouseEvent.test.ts @@ -0,0 +1,76 @@ +import { MouseEvent } from "./MouseEvent"; +import { describe, expect, it } from "vitest"; + +describe("MouseEvent.js static toString test", () => +{ + it("static toString test", () => + { + expect(MouseEvent.toString()).toBe("[class MouseEvent]"); + }); +}); + +describe("MouseEvent.js namespace test", () => +{ + it("namespace test public", () => + { + const mouseEvent = new MouseEvent("test"); + expect(mouseEvent.namespace).toBe("next2d.events.MouseEvent"); + }); + + it("namespace test static", () => + { + expect(MouseEvent.namespace).toBe("next2d.events.MouseEvent"); + }); +}); + +describe("MouseEvent.js property test", () => +{ + it("CLICK test", () => + { + expect(MouseEvent.CLICK).toBe("click"); + }); + + it("DOUBLE_CLICK test", () => + { + expect(MouseEvent.DOUBLE_CLICK).toBe("dblclick"); + }); + + it("MOUSE_DOWN test", () => + { + expect(MouseEvent.MOUSE_DOWN).toBe("mouseDown"); + }); + + it("MOUSE_MOVE test", () => + { + expect(MouseEvent.MOUSE_MOVE).toBe("mouseMove"); + }); + + it("MOUSE_OUT test", () => + { + expect(MouseEvent.MOUSE_OUT).toBe("mouseOut"); + }); + + it("MOUSE_OVER test", () => + { + expect(MouseEvent.MOUSE_OVER).toBe("mouseOver"); + }); + + it("MOUSE_UP test", () => + { + expect(MouseEvent.MOUSE_UP).toBe("mouseUp"); + }); + + it("MOUSE_WHEEL test", () => { + expect(MouseEvent.MOUSE_WHEEL).toBe("mouseWheel"); + }); + + it("ROLL_OUT test", () => + { + expect(MouseEvent.ROLL_OUT).toBe("rollOut"); + }); + + it("ROLL_OVER test", () => + { + expect(MouseEvent.ROLL_OVER).toBe("rollOver"); + }); +}); \ No newline at end of file diff --git a/packages/events/src/MouseEvent.ts b/packages/events/src/MouseEvent.ts index a7c7eede..e6fdd6ec 100644 --- a/packages/events/src/MouseEvent.ts +++ b/packages/events/src/MouseEvent.ts @@ -1,13 +1,13 @@ import { Event } from "./Event"; import { $getEvent } from "./EventUtil"; +import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; /** - * MouseEvent オブジェクトは、マウスイベントが発生するたびにイベントフローに送出されます。 - * 通常、マウスイベントは、マウスやトラックボールなど、ポインターを使用したユーザー入力デバイスによって生成されます。 - * - * A MouseEvent object is dispatched into the event flow whenever mouse events occur. - * A mouse event is usually generated by a user input device, - * such as a mouse or a trackball, that uses a pointer. + * @description MouseEvent オブジェクトは、マウスイベントが発生するたびにイベントフローに送出されます。 + * 通常、マウスイベントは、マウスやトラックボールなど、ポインターを使用したユーザー入力デバイスによって生成されます。 + * A MouseEvent object is dispatched into the event flow whenever mouse events occur. + * A mouse event is usually generated by a user input device, + * such as a mouse or a trackball, that uses a pointer. * * @class * @memberOf next2d.events @@ -52,7 +52,7 @@ export class MouseEvent extends Event * Returns the string representation of the specified class. * * @return {string} - * @default [class MouseEvent] + * @default "[class MouseEvent]" * @method * @static */ @@ -66,7 +66,7 @@ export class MouseEvent extends Event * Returns the space name of the specified class. * * @member {string} - * @default next2d.events.MouseEvent + * @default "next2d.events.MouseEvent" * @const * @static */ @@ -85,7 +85,7 @@ export class MouseEvent extends Event */ toString (): string { - return this.formatToString( + return eventFormatToStringService(this, "MouseEvent", "type", "bubbles", "cancelable", "eventPhase", "localX", "localY", "stageX", "stageY", @@ -99,7 +99,7 @@ export class MouseEvent extends Event * Returns the space name of the specified object. * * @member {string} - * @default next2d.events.MouseEvent + * @default "next2d.events.MouseEvent" * @const * @public */ @@ -113,7 +113,7 @@ export class MouseEvent extends Event * Defines the value of the type property of a click event object. * * @return {string} - * @default click + * @default "click" * @const * @static */ @@ -127,7 +127,7 @@ export class MouseEvent extends Event * Defines the value of the type property of a dblclick event object. * * @return {string} - * @default dblclick + * @default "dblclick" * @const * @static */ @@ -141,7 +141,7 @@ export class MouseEvent extends Event * Defines the value of the type property of a mouseDown event object. * * @return {string} - * @default mouseDown + * @default "mouseDown" * @const * @static */ @@ -155,7 +155,7 @@ export class MouseEvent extends Event * Defines the value of the type property of a mouseMove event object. * * @return {string} - * @default mouseMove + * @default "mouseMove" * @const * @static */ @@ -169,7 +169,7 @@ export class MouseEvent extends Event * Defines the value of the type property of a mouseOut event object. * * @return {string} - * @default mouseOut + * @default "mouseOut" * @const * @static */ @@ -183,7 +183,7 @@ export class MouseEvent extends Event * Defines the value of the type property of a mouseOver event object. * * @return {string} - * @default mouseOver + * @default "mouseOver" * @const * @static */ @@ -197,7 +197,7 @@ export class MouseEvent extends Event * Defines the value of the type property of a mouseUp event object. * * @return {string} - * @default mouseUp + * @default "mouseUp" * @const * @static */ @@ -211,7 +211,7 @@ export class MouseEvent extends Event * Defines the value of the type property of a mouseWheel event object. * * @return {string} - * @default mouseWheel + * @default "mouseWheel" * @const * @static */ @@ -225,7 +225,7 @@ export class MouseEvent extends Event * Defines the value of the type property of a rollOut event object. * * @return {string} - * @default rollOut + * @default "rollOut" * @const * @static */ @@ -239,7 +239,7 @@ export class MouseEvent extends Event * Defines the value of the type property of a rollOver event object. * * @return {string} - * @default rollOver + * @default "rollOver" * @const * @static */ diff --git a/packages/events/src/ProgressEvent.test.ts b/packages/events/src/ProgressEvent.test.ts new file mode 100644 index 00000000..02a06c28 --- /dev/null +++ b/packages/events/src/ProgressEvent.test.ts @@ -0,0 +1,40 @@ +import { ProgressEvent } from "./ProgressEvent"; +import { describe, expect, it } from "vitest"; + +describe("ProgressEvent.js toString test", () => +{ + it("toString test success", () => + { + const progressEvent = new ProgressEvent(""); + expect(progressEvent.toString()).toBe("[ProgressEvent type=\"\" bubbles=false cancelable=false eventPhase=2 bytesLoaded=0 bytesTotal=0]"); + }); +}); + +describe("ProgressEvent.js static toString test", () => +{ + it("static toString test", () => + { + expect(ProgressEvent.toString()).toBe("[class ProgressEvent]"); + }); +}); + +describe("ProgressEvent.js namespace test", () => +{ + it("namespace test public", () => + { + const object = new ProgressEvent("test"); + expect(object.namespace).toBe("next2d.events.ProgressEvent"); + }); + + it("namespace test static", () => + { + expect(ProgressEvent.namespace).toBe("next2d.events.ProgressEvent"); + }); +}); + +describe("ProgressEvent.js property test", () => +{ + it("PROGRESS test", () => { + expect(ProgressEvent.PROGRESS).toBe("progress"); + }); +}); \ No newline at end of file diff --git a/packages/events/src/ProgressEvent.ts b/packages/events/src/ProgressEvent.ts index b038254c..443cf066 100644 --- a/packages/events/src/ProgressEvent.ts +++ b/packages/events/src/ProgressEvent.ts @@ -1,11 +1,11 @@ import { Event } from "./Event"; +import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; /** - * ProgressEvent オブジェクトは、ロード処理が開始されたとき、またはソケットがデータを受信したときに送出されます。 - * これらのイベントは通常、JSON ファイル、イメージまたはデータがアプリケーションにロードされるときに生成されます。 - * - * A ProgressEvent object is dispatched when a load operation has begun or a socket has received data. - * These events are usually generated when JSON files, images or data are loaded into an application. + * @description ProgressEvent オブジェクトは、ロード処理が開始されたとき、またはソケットがデータを受信したときに送出されます。 + * これらのイベントは通常、JSON ファイル、イメージまたはデータがアプリケーションにロードされるときに生成されます。 + * A ProgressEvent object is dispatched when a load operation has begun or a socket has received data. + * These events are usually generated when JSON files, images or data are loaded into an application. * * @class * @memberOf next2d.events @@ -53,7 +53,7 @@ export class ProgressEvent extends Event * Returns the string representation of the specified class. * * @return {string} - * @default [class ProgressEvent] + * @default "[class ProgressEvent]" * @method * @static */ @@ -67,7 +67,7 @@ export class ProgressEvent extends Event * Returns the space name of the specified class. * * @member {string} - * @default next2d.events.ProgressEvent + * @default "next2d.events.ProgressEvent" * @const * @static */ @@ -86,7 +86,7 @@ export class ProgressEvent extends Event */ toString (): string { - return this.formatToString( + return eventFormatToStringService(this, "ProgressEvent", "type", "bubbles", "cancelable", "eventPhase", "bytesLoaded", "bytesTotal" @@ -98,7 +98,7 @@ export class ProgressEvent extends Event * Returns the space name of the specified object. * * @member {string} - * @default next2d.events.ProgressEvent + * @default "next2d.events.ProgressEvent" * @const * @public */ @@ -112,7 +112,7 @@ export class ProgressEvent extends Event * Defines the value of the type property of a progress event object. * * @return {string} - * @default progress + * @default "progress" * @const * @static */ diff --git a/packages/events/src/VideoEvent.test.ts b/packages/events/src/VideoEvent.test.ts new file mode 100644 index 00000000..21fbff9a --- /dev/null +++ b/packages/events/src/VideoEvent.test.ts @@ -0,0 +1,66 @@ +import { VideoEvent } from "./VideoEvent"; +import { describe, expect, it } from "vitest"; + +describe("VideoEvent.js toString test", () => +{ + it("toString test success", () => + { + const videoEvent = new VideoEvent(""); + expect(videoEvent.toString()).toBe("[VideoEvent type=\"\" bubbles=false cancelable=false eventPhase=2 bytesLoaded=0 bytesTotal=0]"); + }); +}); + +describe("VideoEvent.js static toString test", () => +{ + it("static toString test", () => + { + expect(VideoEvent.toString()).toBe("[class VideoEvent]"); + }); +}); + +describe("VideoEvent.js namespace test", () => +{ + it("namespace test public", () => + { + const videoEvent = new VideoEvent("test"); + expect(videoEvent.namespace).toBe("next2d.events.VideoEvent"); + }); + + it("namespace test static", () => + { + expect(VideoEvent.namespace).toBe("next2d.events.VideoEvent"); + }); +}); + +describe("VideoEvent.js property test", () => +{ + it("PLAY_START test", () => + { + expect(VideoEvent.PLAY_START).toBe("playStart"); + }); + + it("PLAY test", () => + { + expect(VideoEvent.PLAY).toBe("play"); + }); + + it("PROGRESS test", () => + { + expect(VideoEvent.PROGRESS).toBe("progress"); + }); + + it("PLAY_END test", () => + { + expect(VideoEvent.PLAY_END).toBe("playEnd"); + }); + + it("PAUSE test", () => + { + expect(VideoEvent.PAUSE).toBe("pause"); + }); + + it("SEEK test", () => + { + expect(VideoEvent.SEEK).toBe("seek"); + }); +}); \ No newline at end of file diff --git a/packages/events/src/VideoEvent.ts b/packages/events/src/VideoEvent.ts index 2dd4b6a7..72d73ff3 100644 --- a/packages/events/src/VideoEvent.ts +++ b/packages/events/src/VideoEvent.ts @@ -1,9 +1,9 @@ import { Event } from "./Event"; +import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; /** - * ビデオを再生または停止すると、VideoEvent オブジェクトを送出します。 - * - * When a video is played or stopped, it sends out a VideoEvent object. + * @description ビデオを再生または停止すると、VideoEvent オブジェクトを送出します。 + * When a video is played or stopped, it sends out a VideoEvent object. * * @class * @memberOf next2d.events @@ -51,7 +51,7 @@ export class VideoEvent extends Event * Returns the string representation of the specified class. * * @return {string} - * @default [class VideoEvent] + * @default "[class VideoEvent]" * @method * @static */ @@ -65,7 +65,7 @@ export class VideoEvent extends Event * Returns the space name of the specified class. * * @member {string} - * @default next2d.events.VideoEvent + * @default "next2d.events.VideoEvent" * @const * @static */ @@ -84,7 +84,7 @@ export class VideoEvent extends Event */ toString (): string { - return this.formatToString( + return eventFormatToStringService(this, "VideoEvent", "type", "bubbles", "cancelable", "eventPhase", "bytesLoaded", "bytesTotal" @@ -96,7 +96,7 @@ export class VideoEvent extends Event * Returns the space name of the specified object. * * @member {string} - * @default next2d.events.VideoEvent + * @default "next2d.events.VideoEvent" * @const * @public */ @@ -110,7 +110,7 @@ export class VideoEvent extends Event * Defines the value of the type property of a progress event object. * * @return {string} - * @default progress + * @default "progress" * @const * @static */ @@ -124,7 +124,7 @@ export class VideoEvent extends Event * Defines the value of the type property of a play event object. * * @return {string} - * @default play + * @default "play" * @const * @static */ @@ -138,7 +138,7 @@ export class VideoEvent extends Event * Defines the value of the type property of a playStart event object. * * @return {string} - * @default playStart + * @default "playStart" * @const * @static */ @@ -152,7 +152,7 @@ export class VideoEvent extends Event * Defines the value of the type property of a playEnd event object. * * @return {string} - * @default playEnd + * @default "playEnd" * @const * @static */ @@ -166,7 +166,7 @@ export class VideoEvent extends Event * Defines the value of the type property of a pause event object. * * @return {string} - * @default pause + * @default "pause" * @const * @static */ @@ -180,7 +180,7 @@ export class VideoEvent extends Event * Defines the value of the type property of a seek event object. * * @return {string} - * @default seek + * @default "seek" * @const * @static */ diff --git a/packages/events/src/interface/EventDispatcherImpl.ts b/packages/events/src/interface/EventDispatcherImpl.ts index 8674f35f..b93109ee 100644 --- a/packages/events/src/interface/EventDispatcherImpl.ts +++ b/packages/events/src/interface/EventDispatcherImpl.ts @@ -1,3 +1,2 @@ -import { EventDispatcher } from "../EventDispatcher"; - -export type EventDispatcherImpl = T; +import type { EventDispatcher } from "../EventDispatcher"; +export type EventDispatcherImpl = T; \ No newline at end of file diff --git a/packages/events/src/interface/EventImpl.ts b/packages/events/src/interface/EventImpl.ts new file mode 100644 index 00000000..4e13165a --- /dev/null +++ b/packages/events/src/interface/EventImpl.ts @@ -0,0 +1,2 @@ +import type { Event } from "../Event"; +export type EventImpl = T; \ No newline at end of file diff --git a/packages/interface/src/NetImpl.ts b/packages/interface/src/NetImpl.ts index 5a65a341..5baa5c41 100644 --- a/packages/interface/src/NetImpl.ts +++ b/packages/interface/src/NetImpl.ts @@ -1,9 +1,5 @@ -import { - URLRequest, - URLRequestHeader -} from "@next2d/net"; +import { URLRequest } from "@next2d/net"; export interface NetImpl { URLRequest: typeof URLRequest; - URLRequestHeader: typeof URLRequestHeader; } \ No newline at end of file diff --git a/packages/net/package.json b/packages/net/package.json index f27c595f..321d0c10 100644 --- a/packages/net/package.json +++ b/packages/net/package.json @@ -26,9 +26,7 @@ "url": "git+https://github.com/Next2D/Player.git" }, "peerDependencies": { - "@next2d/interface": "file:../interface", "@next2d/core": "file:../core", - "@next2d/util": "file:../util", - "@next2d/share": "file:../share" + "@next2d/util": "file:../util" } } diff --git a/packages/net/src/URLRequest.ts b/packages/net/src/URLRequest.ts index 9f3980fb..3b346547 100644 --- a/packages/net/src/URLRequest.ts +++ b/packages/net/src/URLRequest.ts @@ -1,11 +1,8 @@ -import { URLRequestHeader } from "./URLRequestHeader"; -import type { - URLRequestMethodImpl, - URLLoaderDataFormatImpl -} from "@next2d/interface"; +import type { URLRequestHeaderImpl } from "./interface/URLRequestHeaderImpl"; +import type { URLLoaderDataFormatImpl } from "./interface/URLLoaderDataFormatImpl"; +import type { URLRequestMethodImpl } from "./interface/URLRequestMethodImpl"; import type { Player } from "@next2d/core"; import { $currentPlayer } from "@next2d/util"; -import { $getArray } from "@next2d/share"; /** * URLRequestクラスは、外部へのリクエストを管理するクラスです @@ -20,7 +17,7 @@ export class URLRequest private _$contentType: string; private _$data: string; private _$method: URLRequestMethodImpl; - private readonly _$requestHeaders: URLRequestHeader[]; + private readonly _$requestHeaders: URLRequestHeaderImpl[]; private _$responseDataFormat: URLLoaderDataFormatImpl; private _$withCredentials: boolean; @@ -64,7 +61,7 @@ export class URLRequest * @type {array} * @private */ - this._$requestHeaders = $getArray(); + this._$requestHeaders = []; /** * @type {string} @@ -86,7 +83,7 @@ export class URLRequest * Returns the string representation of the specified class. * * @return {string} - * @default [class URLRequest] + * @default "[class URLRequest]" * @method * @static */ @@ -100,7 +97,7 @@ export class URLRequest * Returns the space name of the specified class. * * @return {string} - * @default next2d.net.URLRequest + * @default "next2d.net.URLRequest" * @const * @static */ @@ -114,7 +111,7 @@ export class URLRequest * Returns the string representation of the specified object. * * @return {string} - * @default [object URLRequest] + * @default "[object URLRequest]" * @method * @public */ @@ -128,7 +125,7 @@ export class URLRequest * Returns the space name of the specified object. * * @return {string} - * @default next2d.net.URLRequest + * @default "next2d.net.URLRequest" * @const * @public */ @@ -142,7 +139,7 @@ export class URLRequest * The MIME content type of the content in the the data property. * * @member {string} - * @default application/json + * @default "application/json" * @public */ get contentType (): string @@ -158,7 +155,7 @@ export class URLRequest * @description URL リクエストで送信されるデータを含むオブジェクトです。 * An object containing data to be transmitted with the URL request. * - * @member {string} + * @member {any} * @public */ get data (): any @@ -191,14 +188,14 @@ export class URLRequest * @description HTTP リクエストヘッダーの配列が HTTP リクエストに追加されます。 * The array of HTTP request headers to be appended to the HTTP request. * - * @member {URLRequestHeader[]} + * @member {URLRequestHeaderImpl[]} * @public */ - get requestHeaders (): URLRequestHeader[] + get requestHeaders (): URLRequestHeaderImpl[] { return this._$requestHeaders; } - set requestHeaders (request_headers: URLRequestHeader[]) + set requestHeaders (request_headers: URLRequestHeaderImpl[]) { this._$requestHeaders.length = 0; this._$requestHeaders.push(...request_headers); @@ -276,10 +273,13 @@ export class URLRequest * @readonly * @public */ - get headers (): URLRequestHeader[] + get headers (): URLRequestHeaderImpl[] { - const headers = $getArray(); - headers.push(new URLRequestHeader("Content-Type", `${this._$contentType}`)); + const headers = []; + headers.push({ + "name": "Content-Type", + "value": this._$contentType + }); if (this._$requestHeaders.length) { headers.push(...this._$requestHeaders); } diff --git a/packages/net/src/URLRequestHeader.ts b/packages/net/src/URLRequestHeader.ts deleted file mode 100644 index 4fe7b24f..00000000 --- a/packages/net/src/URLRequestHeader.ts +++ /dev/null @@ -1,123 +0,0 @@ -/** - * URLRequestHeader オブジェクトは 1 つの HTTP のリクエストヘッダーをカプセル化し、名前と値のペアを構成します。 - * URLRequestHeader オブジェクトは URLRequest クラスの requestHeaders プロパティで使用されます。 - * - * A URLRequestHeader object encapsulates a single HTTP request header and consists of a name/value pair. - * URLRequestHeader objects are used in the requestHeaders property of the URLRequest class. - * - * @class - * @memberOf next2d.net - */ -export class URLRequestHeader -{ - private readonly _$name: string; - private readonly _$value: string; - - /** - * @param {string} [name=""] - * @param {string} [value=""] - * - * @constructor - * @public - */ - constructor (name: string = "", value: string = "") - { - /** - * @type {string} - * @default "" - * @private - */ - this._$name = `${name}`; - - /** - * @type {string} - * @default "" - * @private - */ - this._$value = `${value}`; - } - - /** - * @description 指定されたクラスのストリングを返します。 - * Returns the string representation of the specified class. - * - * @return {string} - * @default [class URLRequestHeader] - * @method - * @static - */ - static toString (): string - { - return "[class URLRequestHeader]"; - } - - /** - * @description 指定されたクラスの空間名を返します。 - * Returns the space name of the specified class. - * - * @return {string} - * @default next2d.net.URLRequestHeader - * @const - * @static - */ - static get namespace (): string - { - return "next2d.net.URLRequestHeader"; - } - - /** - * @description 指定されたオブジェクトのストリングを返します。 - * Returns the string representation of the specified object. - * - * @return {string} - * @default [object URLRequestHeader] - * @method - * @public - */ - toString (): string - { - return "[object URLRequestHeader]"; - } - - /** - * @description 指定されたオブジェクトの空間名を返します。 - * Returns the space name of the specified object. - * - * @return {string} - * @default next2d.net.URLRequestHeader - * @const - * @public - */ - get namespace (): string - { - return "next2d.net.URLRequestHeader"; - } - - /** - * @description HTTP リクエストヘッダー名(Content-Type や SOAPAction など)です。 - * An HTTP request header name (such as Content-Type or SOAPAction). - * - * @member {string} - * @default "" - * @readonly - * @public - */ - get name (): string - { - return this._$name; - } - - /** - * @description name プロパティに関連付けられた値(text/plain など)です。 - * The value associated with the name property (such as text/plain). - * - * @member {string} - * @default "" - * @readonly - * @public - */ - get value (): string - { - return this._$value; - } -} diff --git a/packages/net/src/index.ts b/packages/net/src/index.ts index 2d36afc6..eb9aa41f 100644 --- a/packages/net/src/index.ts +++ b/packages/net/src/index.ts @@ -1,2 +1 @@ -export * from "./URLRequest"; -export * from "./URLRequestHeader"; \ No newline at end of file +export * from "./URLRequest"; \ No newline at end of file diff --git a/packages/net/src/interface/URLLoaderDataFormatImpl.ts b/packages/net/src/interface/URLLoaderDataFormatImpl.ts new file mode 100644 index 00000000..af72978d --- /dev/null +++ b/packages/net/src/interface/URLLoaderDataFormatImpl.ts @@ -0,0 +1 @@ +export type URLLoaderDataFormatImpl = "json" | "arraybuffer" | "text"; \ No newline at end of file diff --git a/packages/net/src/interface/URLRequestHeaderImpl.ts b/packages/net/src/interface/URLRequestHeaderImpl.ts new file mode 100644 index 00000000..efbdd5c9 --- /dev/null +++ b/packages/net/src/interface/URLRequestHeaderImpl.ts @@ -0,0 +1,5 @@ +export interface URLRequestHeaderImpl +{ + name: string; + value: string; +} \ No newline at end of file diff --git a/packages/net/src/interface/URLRequestMethodImpl.ts b/packages/net/src/interface/URLRequestMethodImpl.ts new file mode 100644 index 00000000..866e2360 --- /dev/null +++ b/packages/net/src/interface/URLRequestMethodImpl.ts @@ -0,0 +1 @@ +export type URLRequestMethodImpl = "DELETE" | "GET" | "HEAD" | "OPTIONS" | "POST" | "PUT"; \ No newline at end of file From dc84f858e8a71ccb75b63553323ec12e9751aaac Mon Sep 17 00:00:00 2001 From: ienaga Date: Thu, 25 Jul 2024 20:24:41 +0900 Subject: [PATCH 015/343] =?UTF-8?q?#154=20feat:=20Event=E3=83=91=E3=83=83?= =?UTF-8?q?=E3=82=B1=E3=83=BC=E3=82=B8=E3=82=92=E7=A7=BB=E6=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next2d/events/EventDispatcherTest.ts | 446 ------------ packages/events/src/EventDispatcher.test.ts | 34 + packages/events/src/EventDispatcher.ts | 656 +----------------- ...tDispatcherAddEventListenerService.test.ts | 138 ++++ .../EventDispatcherAddEventListenerService.ts | 129 ++++ ...ventDispatcherDispatchEventService.test.ts | 343 +++++++++ .../EventDispatcherDispatchEventService.ts | 278 ++++++++ ...tDispatcherHasEventListenerService.test.ts | 35 + .../EventDispatcherHasEventListenerService.ts | 51 ++ ...tcherRemoveAllEventListenerService.test.ts | 28 + ...DispatcherRemoveAllEventListenerService.ts | 122 ++++ ...spatcherRemoveEventListenerService.test.ts | 150 ++++ ...entDispatcherRemoveEventListenerService.ts | 119 ++++ .../EventDispatcherWillTriggerService.test.ts | 64 ++ .../EventDispatcherWillTriggerService.ts | 36 + 15 files changed, 1553 insertions(+), 1076 deletions(-) create mode 100644 packages/events/src/EventDispatcher.test.ts create mode 100644 packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.test.ts create mode 100644 packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.ts create mode 100644 packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.test.ts create mode 100644 packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.ts create mode 100644 packages/events/src/EventDispatcher/EventDispatcherHasEventListenerService.test.ts create mode 100644 packages/events/src/EventDispatcher/EventDispatcherHasEventListenerService.ts create mode 100644 packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.test.ts create mode 100644 packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.ts create mode 100644 packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.test.ts create mode 100644 packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.ts create mode 100644 packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.test.ts create mode 100644 packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.ts diff --git a/__tests__/next2d/events/EventDispatcherTest.ts b/__tests__/next2d/events/EventDispatcherTest.ts index 2187c18b..25a65ab8 100644 --- a/__tests__/next2d/events/EventDispatcherTest.ts +++ b/__tests__/next2d/events/EventDispatcherTest.ts @@ -6,396 +6,6 @@ import { Sprite } from "../../../packages/display/src/Sprite"; import { Stage } from "../../../packages/display/src/Stage"; import { EventPhase } from "../../../packages/events/src/EventPhase"; -describe("EventDispatcher.js toString test", function() -{ - - // toString - it("toString test success", () => - { - const object = new EventDispatcher(); - expect(object.toString()).toBe("[object EventDispatcher]"); - }); - -}); - -describe("EventDispatcher.js static toString test", function() -{ - - it("static toString test", function() - { - expect(EventDispatcher.toString()).toBe("[class EventDispatcher]"); - }); - -}); - -describe("EventDispatcher.js namespace test", function() -{ - - it("namespace test public", function() - { - const object = new EventDispatcher(); - expect(object.namespace).toBe("next2d.events.EventDispatcher"); - }); - - it("namespace test static", function() - { - expect(EventDispatcher.namespace).toBe("next2d.events.EventDispatcher"); - }); - -}); - -describe("EventDispatcher.js addEventListener test", function() -{ - // addEventListener - it("addEventListener test success case1", () => - { - const di = new EventDispatcher(); - - di.addEventListener("test", () => { return "OK" }); - di.addEventListener("test", () => { return "NG" }); - - if (!di._$events) { - throw new Error("addEventListener test success case1"); - } - - const events = di._$events.get("test"); - if (!events) { - throw new Error("the events is none."); - } - - expect(events.length).toBe(2); - expect(events[0].listener()).toBe("OK"); - expect(events[1].listener()).toBe("NG"); - }); - - it("addEventListener test success case2", () => - { - const di = new EventDispatcher(); - - di.addEventListener("test", () => { return "NG" }, false, 50); - di.addEventListener("test", () => { return "OK" }, false, 100); - - if (!di._$events) { - throw new Error("addEventListener test success case1"); - } - - const events = di._$events.get("test"); - if (!events) { - throw new Error("the events is none."); - } - - expect(events.length).toBe(2); - expect(events[0].listener()).toBe("OK"); - expect(events[1].listener()).toBe("NG"); - }); - - it("addEventListener test success case3", () => - { - const di = new EventDispatcher(); - - di.addEventListener("123", () => { return "NG" }, false, 50); - di.addEventListener("123", () => { return "OK" }, false, 100); - - if (!di._$events) { - throw new Error("addEventListener test success case1"); - } - - const events = di._$events.get("123"); - if (!events) { - throw new Error("the events is none."); - } - - expect(events.length).toBe(2); - expect(events[0].listener()).toBe("OK"); - expect(events[1].listener()).toBe("NG"); - }); - - it("addEventListener test valid case1", () => - { - const di = new EventDispatcher(); - - // @ts-ignore - di.addEventListener("test", {}); - // @ts-ignore - di.addEventListener("test", []); - di.addEventListener("test", () => { return "OK" }); - - if (!di._$events) { - throw new Error("addEventListener test success case1"); - } - - const events = di._$events.get("test"); - if (!events) { - throw new Error("the events is none."); - } - - expect(events.length).toBe(3); - expect(events[2].listener()).toBe("OK"); - }); - - it("addEventListener test duplicate case1", () => - { - const di = new EventDispatcher(); - - const a = () => { return "OK" }; - - di.addEventListener("test", a); - di.addEventListener("test", a); - - if (!di._$events) { - throw new Error("addEventListener test success case1"); - } - - const events = di._$events.get("test"); - if (!events) { - throw new Error("the events is none."); - } - - expect(events.length).toBe(1); - expect(events[0].listener()).toBe("OK"); - }); - - it("addEventListener test duplicate case2", () => - { - const di = new EventDispatcher(); - - let name = null - di.addEventListener("test", () => { name = "ok" }); - di.addEventListener("test", () => { name = "ng" }); - - if (!di._$events) { - throw new Error("addEventListener test success case1"); - } - - const events = di._$events.get("test"); - if (!events) { - throw new Error("the events is none."); - } - - expect(events.length).toBe(2); - di.dispatchEvent(new Event("test")); - expect(name).toBe("ng"); - }); - - it("addEventListener test duplicate case4", () => - { - const mc1 = new MovieClip(); - mc1.name = "mc1"; - - const mc2 = new MovieClip(); - mc2.name = "mc2"; - - const player = $currentPlayer(); - player.broadcastEvents.clear(); - - let name = null - const a = (e: any) => { name = e.currentTarget.name }; - - mc1.addEventListener(Event.ENTER_FRAME, a); - mc2.addEventListener(Event.ENTER_FRAME, a); - - const events = player.broadcastEvents.get(Event.ENTER_FRAME); - if (!events) { - throw new Error("events none"); - } - - expect(events.length).toBe(2); - - mc1.dispatchEvent(new Event(Event.ENTER_FRAME)) - expect(name).toBe("mc1"); - - mc2.dispatchEvent(new Event(Event.ENTER_FRAME)) - expect(name).toBe("mc2"); - - // end - mc1.removeEventListener(Event.ENTER_FRAME, a); - mc2.removeEventListener(Event.ENTER_FRAME, a); - - }); - -}); - -describe("EventDispatcher.js hasEventListener test", function() -{ - - // hasEventListener - it("hasEventListener test success", () => - { - const di = new EventDispatcher(); - - di.addEventListener("test1", () => { return "OK" }); - di.addEventListener("test3", () => { return "NG" }); - - expect(di.hasEventListener("test1")).toBe(true); - expect(di.hasEventListener("test2")).toBe(false); - expect(di.hasEventListener("test3")).toBe(true); - expect(di.hasEventListener("test4")).toBe(false); - - }); - - // メソッドが所属する EventDispatcher インスタンスについてのみリスナーが登録されているか - it("hasEventListener test success case2", () => - { - const doc1 = new MovieClip(); - const doc2 = new MovieClip(); - const doc3 = new MovieClip(); - doc1.addChild(doc2); - doc2.addChild(doc3); - - doc2.addEventListener(Event.ENTER_FRAME, () => { return "OK" }); - - expect(doc1.hasEventListener(Event.ENTER_FRAME)).toBe(false); - expect(doc2.hasEventListener(Event.ENTER_FRAME)).toBe(true); - expect(doc3.hasEventListener(Event.ENTER_FRAME)).toBe(false); - - }); -}); - -describe("EventDispatcher.js removeEventListener test", function() -{ - - // removeEventListener - it("removeEventListener test success case1", () => - { - const di = new EventDispatcher(); - - const test1 = () => { return "OK1" }; - const test2 = () => { return "OK2" }; - const test3 = () => { return "OK3" }; - - di.addEventListener("test", test1, false, 10); - di.addEventListener("test", test2, false, 20); - di.addEventListener("test", test3, false, 30); - - di.removeEventListener("test", test2); - - if (!di._$events) { - throw new Error("addEventListener test success case1"); - } - - const events = di._$events.get("test"); - if (!events) { - throw new Error("the events is none."); - } - - expect(events.length).toBe(2); - expect(events[0].listener()).toBe("OK3"); - expect(events[1].listener()).toBe("OK1"); - }); - - it("removeEventListener test success case2", () => - { - const di = new EventDispatcher(); - - const a = () => { return "ok" }; - const b = () => { return "no" }; - - di.addEventListener("test", a); - di.addEventListener("test", b); - - if (!di._$events) { - throw new Error("addEventListener test success case1"); - } - - const events = di._$events.get("test"); - if (!events) { - throw new Error("the events is none."); - } - - expect(events.length).toBe(2); - - di.removeEventListener("test", a); - - expect(di._$events.has("test")).toBe(true); - expect(events.length).toBe(1); - }); - - it("removeEventListener test success case3", () => - { - const di = new EventDispatcher(); - - const a = () => { return "yes" }; - const b = () => { return "no" }; - - di.addEventListener("test", a, true); - di.addEventListener("test", b, false); - - if (!di._$events) { - throw new Error("addEventListener test success case1"); - } - - const events = di._$events.get("test"); - if (!events) { - throw new Error("the events is none."); - } - - expect(events.length).toBe(2); - - di.removeEventListener("test", b, true); - di.removeEventListener("test", a, true); - - expect(events.length).toBe(1); - expect(events[0].listener().toString()).toBe("no"); - }); - - it("removeEventListener test success case4", () => - { - const di = new EventDispatcher(); - - const a = () => { return "ok" }; - const b = () => { return "no" }; - - di.addEventListener("test", a, true); - di.addEventListener("test", b, false); - - if (!di._$events) { - throw new Error("addEventListener test success case1"); - } - - const events = di._$events.get("test"); - if (!events) { - throw new Error("the events is none."); - } - - expect(events.length).toBe(2); - - di.removeEventListener("test", a, false); - di.removeEventListener("test", b, true); - - expect(events.length).toBe(2); - expect(events[0].listener().toString()).toBe("ok"); - expect(events[1].listener().toString()).toBe("no"); - }); - - it("removeEventListener test success case5", () => - { - const player = $currentPlayer(); - player.broadcastEvents.clear(); - - const mc1 = new MovieClip(); - const mc2 = new MovieClip(); - - const a = () => { return undefined }; - - mc1.addEventListener(Event.ENTER_FRAME, a); - mc2.addEventListener(Event.ENTER_FRAME, a); - - const events = player.broadcastEvents.get(Event.ENTER_FRAME); - if (!events) { - throw new Error("events none"); - } - - expect(events.length).toBe(2); - - mc1.removeEventListener(Event.ENTER_FRAME, a); - expect(events.length).toBe(1); - - mc2.removeEventListener(Event.ENTER_FRAME, a); - expect(player.broadcastEvents.has(Event.ENTER_FRAME)).toBe(false); - }); - -}); - describe("EventDispatcher.js dispatchEvent test", function() { @@ -688,59 +298,3 @@ describe("EventDispatcher.js dispatchEvent test", function() }); -describe("EventDispatcher.js willTrigger test", function() -{ - - // hasEventListener - it("willTrigger test success case1", () => - { - const container = new Sprite(); - - const s1 = container.addChild(new Sprite()); - const s2 = container.addChild(new Sprite()); - const s3 = s2.addChild(new Sprite()); - - s2.addEventListener("test", () => {}); - - expect(s1.willTrigger("test")).toBe(false); - expect(s2.willTrigger("test")).toBe(true); - expect(s3.willTrigger("test")).toBe(true); - - }); - - // hasEventListener - it("willTrigger test success case2", () => - { - const container = new Sprite(); - - const s1 = container.addChild(new Sprite()); - const s2 = s1.addChild(new Sprite()); - const s3 = s2.addChild(new Sprite()); - - s1.addEventListener("test", () => {}); - - expect(s1.willTrigger("test")).toBe(true); - expect(s2.willTrigger("test")).toBe(true); - expect(s3.willTrigger("test")).toBe(true); - - }); - -}); - -describe("EventDispatcher.js removeAllEventListener test", function() -{ - - // hasEventListener - it("removeAllEventListener test success case1", () => - { - const sprite = new Sprite(); - sprite.addEventListener("test", () => {}); - sprite.addEventListener("test", () => {}); - sprite.addEventListener("test", () => {}); - - expect(sprite.hasEventListener("test")).toBe(true); - sprite.removeAllEventListener("test"); - expect(sprite.hasEventListener("test")).toBe(false); - }); - -}); diff --git a/packages/events/src/EventDispatcher.test.ts b/packages/events/src/EventDispatcher.test.ts new file mode 100644 index 00000000..068ab164 --- /dev/null +++ b/packages/events/src/EventDispatcher.test.ts @@ -0,0 +1,34 @@ +import { EventDispatcher } from "./EventDispatcher"; +import { describe, expect, it } from "vitest"; + +describe("EventDispatcher.js toString test", function() +{ + // toString + it("toString test success", () => + { + const eventDispatcher = new EventDispatcher(); + expect(eventDispatcher.toString()).toBe("[object EventDispatcher]"); + }); +}); + +describe("EventDispatcher.js static toString test", function() +{ + it("static toString test", function() + { + expect(EventDispatcher.toString()).toBe("[class EventDispatcher]"); + }); +}); + +describe("EventDispatcher.js namespace test", function() +{ + it("namespace test public", function() + { + const eventDispatcher = new EventDispatcher(); + expect(eventDispatcher.namespace).toBe("next2d.events.EventDispatcher"); + }); + + it("namespace test static", function() + { + expect(EventDispatcher.namespace).toBe("next2d.events.EventDispatcher"); + }); +}); \ No newline at end of file diff --git a/packages/events/src/EventDispatcher.ts b/packages/events/src/EventDispatcher.ts index 9ad79b5b..6988ea29 100644 --- a/packages/events/src/EventDispatcher.ts +++ b/packages/events/src/EventDispatcher.ts @@ -1,12 +1,11 @@ -import { Event } from "./Event"; -import { EventPhase } from "./EventPhase"; import type { EventListenerImpl } from "./interface/EventListenerImpl"; -import type { EventDispatcherImpl } from "./interface/EventDispatcherImpl"; -import { - $broadcastEvents, - $getArray, - $poolArray -} from "./EventUtil"; +import { Event } from "./Event"; +import { execute as eventDispatcherAddEventListenerService } from "./EventDispatcher/EventDispatcherAddEventListenerService"; +import { execute as eventDispatcherHasEventListenerService } from "./EventDispatcher/EventDispatcherHasEventListenerService"; +import { execute as eventDispatcherRemoveEventListenerService } from "./EventDispatcher/EventDispatcherRemoveEventListenerService"; +import { execute as eventDispatcherRemoveAllEventListenerService } from "./EventDispatcher/EventDispatcherRemoveAllEventListenerService"; +import { execute as eventDispatcherWillTriggerService } from "./EventDispatcher/EventDispatcherWillTriggerService"; +import { execute as eventDispatcherDispatchEventService } from "./EventDispatcher/EventDispatcherDispatchEventService"; /** * @description EventDispatcher クラスは、イベントを送出するすべてのクラスの基本クラスです。 @@ -38,7 +37,7 @@ export class EventDispatcher * Returns the string representation of the specified class. * * @return {string} - * @default [class EventDispatcher] + * @default "[class EventDispatcher]" * @method * @static */ @@ -108,99 +107,9 @@ export class EventDispatcher use_capture: boolean = false, priority: number = 0 ): void { - - let events: EventListenerImpl[]; - - type = `${type}`; - switch (type) { - - // broadcast event - case Event.ENTER_FRAME: - case Event.EXIT_FRAME: - case Event.FRAME_CONSTRUCTED: - case Event.RENDER: - case Event.ACTIVATE: - case Event.DEACTIVATE: - case "keyDown": - case "keyUp": - - if (!$broadcastEvents.size - || !$broadcastEvents.has(type) - ) { - $broadcastEvents.set(type, $getArray()); - } - - events = $broadcastEvents.get(type) as NonNullable; - - break; - - // normal event - default: - - // init - if (!this._$events) { - this._$events = new Map(); - } - - if (!this._$events.size || !this._$events.has(type)) { - this._$events.set(type, $getArray()); - } - - events = this._$events.get(type) as NonNullable; - - break; - - } - - // duplicate check - let length: number = events.length; - for (let idx: number = 0; idx < length; ++idx) { - - const event: EventListenerImpl = events[idx]; - if (use_capture !== event.useCapture) { - continue; - } - - if (event.target !== this) { - continue; - } - - if (event.listener !== listener) { - continue; - } - - length = idx; - break; - } - - // add or overwrite - events[length] = { - "listener": listener, - "priority": priority, - "useCapture": use_capture, - "target": this - }; - - if (events.length > 1) { - - // sort(DESC) - events.sort(function (a: EventListenerImpl, b: EventListenerImpl) - { - switch (true) { - - case a.priority > b.priority: - return -1; - - case a.priority < b.priority: - return 1; - - default: - return 0; - - } - }); - - } + eventDispatcherAddEventListenerService( + this, type, listener, use_capture, priority + ); } /** @@ -214,255 +123,7 @@ export class EventDispatcher */ dispatchEvent (event: Event): boolean { - switch (event.type) { - - case Event.ENTER_FRAME: - case Event.EXIT_FRAME: - case Event.FRAME_CONSTRUCTED: - case Event.RENDER: - case Event.ACTIVATE: - case Event.DEACTIVATE: - case "keyDown": - case "keyUp": - if ($broadcastEvents.size - && $broadcastEvents.has(event.type) - ) { - - const events = $broadcastEvents.get(event.type) as NonNullable; - for (let idx: number = 0; idx < events.length; ++idx) { - - const obj: EventListenerImpl = events[idx]; - if (obj.target !== this) { - continue; - } - - // start target - event.eventPhase = EventPhase.AT_TARGET; - - // event execute - event.currentTarget = obj.target; - - try { - - event.listener = obj.listener; - obj.listener.call(null, event); - - } catch (e) { - - console.error(e); - - return false; - - } - } - - return true; - } - break; - - default: - { - let events: EventListenerImpl[] | null = null; - if (this._$events - && this._$events.size - && this._$events.has(event.type) - ) { - events = this._$events.get(event.type) as NonNullable; - if (events) { - events = events.slice(0); - } - } - - if (!events) { - events = $getArray(); - } - - // parent - const parentEvents = $getArray(); - if ("parent" in this) { - - let parent = this.parent as EventDispatcherImpl | null; - while (parent) { - - if (parent.hasEventListener(event.type)) { - - const events: EventListenerImpl[] | null = parent._$events && parent._$events.has(event.type) - ? parent._$events.get(event.type) as NonNullable - : null; - - if (events) { - parentEvents.push(events); - } - } - - parent = parent.parent; - - } - - } - - event.target = this; - if (events.length || parentEvents.length) { - - // start capture - event.eventPhase = EventPhase.CAPTURING_PHASE; - - // stage => parent... end - if (parentEvents.length) { - - switch (true) { - - case event._$stopImmediatePropagation: - case event._$stopPropagation: - break; - - default: - - parentEvents.reverse(); - for (let idx: number = 0; idx < parentEvents.length; ++idx) { - - const targets: EventListenerImpl[] = parentEvents[idx]; - for (let idx: number = 0; idx < targets.length; ++idx) { - - const obj: EventListenerImpl = targets[idx]; - if (!obj.useCapture) { - continue; - } - - // event execute - event.currentTarget = obj.target; - - try { - - event.listener = obj.listener; - obj.listener.call(null, event); - - } catch (e) { - - console.error(e); - - return false; - } - - if (event._$stopImmediatePropagation) { - break; - } - - } - - if (event._$stopImmediatePropagation) { - break; - } - - } - parentEvents.reverse(); - - break; - } - - } - - // start target - event.eventPhase = EventPhase.AT_TARGET; - if (!event._$stopImmediatePropagation - && !event._$stopPropagation - ) { - - const length: number = events.length; - for (let idx: number = 0; idx < length; ++idx) { - - const obj: EventListenerImpl = events[idx]; - if (obj.useCapture) { - continue; - } - - // event execute - event.currentTarget = obj.target; - try { - - event.listener = obj.listener; - obj.listener.call(null, event); - - } catch (e) { - - console.error(e); - - return false; - } - - if (event._$stopImmediatePropagation) { - break; - } - - } - } - - // start bubbling - event.eventPhase = EventPhase.BUBBLING_PHASE; - switch (true) { - - case event._$stopImmediatePropagation: - case event._$stopPropagation: - case !event.bubbles: - break; - - default: - - // this => parent... => stage end - for (let idx: number = 0; idx < parentEvents.length; ++idx) { - - const targets: EventListenerImpl[] = parentEvents[idx]; - for (let idx: number = 0; idx < targets.length; ++idx) { - - const obj: EventListenerImpl = targets[idx]; - if (obj.useCapture) { - continue; - } - - // event execute - event.currentTarget = obj.target; - try { - - event.listener = obj.listener; - obj.listener.call(null, event); - - } catch (e) { - - console.error(e); - - return false; - } - - if (event._$stopImmediatePropagation) { - break; - } - } - - if (event._$stopImmediatePropagation) { - break; - } - - } - - break; - - } - - $poolArray(events); - $poolArray(parentEvents); - - return true; - - } - - $poolArray(events); - $poolArray(parentEvents); - } - break; - - } - - return false; + return eventDispatcherDispatchEventService(this, event); } /** @@ -476,39 +137,7 @@ export class EventDispatcher */ hasEventListener (type: string): boolean { - type = `${type}`; - switch (type) { - - case Event.ENTER_FRAME: - case Event.EXIT_FRAME: - case Event.FRAME_CONSTRUCTED: - case Event.RENDER: - case Event.ACTIVATE: - case Event.DEACTIVATE: - case "keyDown": - case "keyUp": - { - if ($broadcastEvents.size - && $broadcastEvents.has(type) - ) { - - const events: EventListenerImpl[] = $broadcastEvents.get(type) || $getArray(); - - for (let idx: number = 0; idx < events.length; idx++) { - if (events[idx].target === this) { - return true; - } - } - } - return false; - } - - default: - return !!(this._$events - && this._$events.size - && this._$events.has(type)); - - } + return eventDispatcherHasEventListenerService(this, type); } /** @@ -516,139 +145,28 @@ export class EventDispatcher * Removes a listener from the EventDispatcher object. * * @param {string} type - * @param {function} [listener = null] + * @param {function} listener * @param {boolean} [use_capture = false] * @return {void} * @method * @public */ removeEventListener ( - type: string, listener: Function | null, + type: string, + listener: Function, use_capture: boolean = false ): void { - - if (!listener) { - return; - } - - type = `${type}`; - if (!this.hasEventListener(type)) { - return; - } - - let events: EventListenerImpl[] | null = null; - - let isBroadcast: boolean = false; - - switch (type) { - - case Event.ENTER_FRAME: - case Event.EXIT_FRAME: - case Event.FRAME_CONSTRUCTED: - case Event.RENDER: - case Event.ACTIVATE: - case Event.DEACTIVATE: - case "keyDown": - case "keyUp": - isBroadcast = true; - events = $broadcastEvents.get(type) || $getArray(); - break; - - default: - if (this._$events - && this._$events.size - && this._$events.has(type) - ) { - events = this._$events.get(type) || $getArray(); - } - - break; - - } - - if (!events) { - return ; - } - - // remove listener - for (let idx: number = 0; idx < events.length; ++idx) { - - // event object - const obj: EventListenerImpl = events[idx]; - if (use_capture === obj.useCapture - && obj.listener === listener - ) { - events.splice(idx, 1); - break; - } - - } - - if (!events.length) { - - if (isBroadcast) { - - $broadcastEvents.delete(type); - - } else { - - if (!this._$events) { - return ; - } - - this._$events.delete(type); - - if (!this._$events.size) { - this._$events = null; - } - - } - - return ; - } - - if (events.length > 1) { - - // event sort(DESC) - events.sort(function (a: EventListenerImpl, b: EventListenerImpl) - { - switch (true) { - - case a.priority > b.priority: - return -1; - - case a.priority < b.priority: - return 1; - - default: - return 0; - - } - }); - - } - - if (isBroadcast) { - - $broadcastEvents.set(type, events); - - } else { - - if (!this._$events) { - this._$events = new Map(); - } - - this._$events.set(type, events); - - } + eventDispatcherRemoveEventListenerService( + this, type, listener, use_capture + ); } /** * @description EventDispatcherオブジェクトから指定したタイプのリスナーを全て削除します。 * Removes all listeners of the specified type from the EventDispatcher object. * - * @param {string} type - * @param {boolean} [use_capture=false] + * @param {string} type + * @param {boolean} [use_capture=false] * @return {void} * @method * @public @@ -657,114 +175,9 @@ export class EventDispatcher type: string, use_capture: boolean = false ): void { - - type = `${type}`; - if (!this.hasEventListener(type)) { - return; - } - - let events: EventListenerImpl[] | null = null; - - let isBroadcast: boolean = false; - - switch (type) { - - case Event.ENTER_FRAME: - case Event.EXIT_FRAME: - case Event.FRAME_CONSTRUCTED: - case Event.RENDER: - case Event.ACTIVATE: - case Event.DEACTIVATE: - case "keyDown": - case "keyUp": - isBroadcast = true; - events = $broadcastEvents.get(type) || $getArray(); - break; - - default: - if (this._$events - && this._$events.size - && this._$events.has(type) - ) { - events = this._$events.get(type) || $getArray(); - } - - break; - - } - - if (!events) { - return ; - } - - // remove listener - const results: EventListenerImpl[] = $getArray(); - - for (let idx = 0; idx < events.length; ++idx) { - - // event object - const obj: EventListenerImpl = events[idx]; - if (use_capture !== obj.useCapture) { - results.push(obj); - } - - } - - if (!results.length) { - - if (isBroadcast) { - - $broadcastEvents.delete(type); - - } else { - - if (!this._$events) { - return ; - } - - this._$events.delete(type); - - if (!this._$events.size) { - this._$events = null; - } - } - - return ; - } - - if (results.length > 1) { - - // event sort (DESC) - results.sort(function (a: EventListenerImpl, b: EventListenerImpl) - { - switch (true) { - - case a.priority > b.priority: - return -1; - - case a.priority < b.priority: - return 1; - - default: - return 0; - - } - }); - - } - - if (isBroadcast) { - - $broadcastEvents.set(type, results); - - } else { - - if (!this._$events) { - this._$events = new Map(); - } - - this._$events.set(type, results); - } + eventDispatcherRemoveAllEventListenerService( + this, type, use_capture + ); } /** @@ -775,30 +188,13 @@ export class EventDispatcher * with this EventDispatcher object or * any of its ancestors for the specified event type. * - * @param {string} type + * @param {string} type * @return {boolean} * @method * @public */ willTrigger (type: string): boolean { - if (this.hasEventListener(type)) { - return true; - } - - if ("parent" in this) { - - let parent = this.parent as EventDispatcherImpl | null; - while (parent) { - - if (parent.hasEventListener(type)) { - return true; - } - - parent = parent.parent; - } - } - - return false; + return eventDispatcherWillTriggerService(this, type); } } \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.test.ts b/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.test.ts new file mode 100644 index 00000000..96945adc --- /dev/null +++ b/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.test.ts @@ -0,0 +1,138 @@ +import { Event } from "../Event"; +import { EventDispatcher } from "../EventDispatcher"; +import { $broadcastEvents } from "../EventUtil"; +import { describe, expect, it } from "vitest"; + +describe("EventDispatcher.js addEventListener test", () => +{ + // addEventListener + it("addEventListener test success case1", () => + { + const eventDispatcher = new EventDispatcher(); + + eventDispatcher.addEventListener("test", () => { return "OK" }); + eventDispatcher.addEventListener("test", () => { return "NG" }); + + if (!eventDispatcher._$events) { + throw new Error("addEventListener test success case1"); + } + + const events = eventDispatcher._$events.get("test"); + if (!events) { + throw new Error("the events is none."); + } + + expect(events.length).toBe(2); + expect(events[0].listener()).toBe("OK"); + expect(events[1].listener()).toBe("NG"); + }); + + it("addEventListener test success case2", () => + { + const eventDispatcher = new EventDispatcher(); + + eventDispatcher.addEventListener("test", () => { return "NG" }, false, 50); + eventDispatcher.addEventListener("test", () => { return "OK" }, false, 100); + + if (!eventDispatcher._$events) { + throw new Error("addEventListener test success case1"); + } + + const events = eventDispatcher._$events.get("test"); + if (!events) { + throw new Error("the events is none."); + } + + expect(events.length).toBe(2); + expect(events[0].listener()).toBe("OK"); + expect(events[1].listener()).toBe("NG"); + }); + + it("addEventListener test success case3", () => + { + const eventDispatcher = new EventDispatcher(); + + eventDispatcher.addEventListener("123", () => { return "NG" }, false, 50); + eventDispatcher.addEventListener("123", () => { return "OK" }, false, 100); + + if (!eventDispatcher._$events) { + throw new Error("addEventListener test success case1"); + } + + const events = eventDispatcher._$events.get("123"); + if (!events) { + throw new Error("the events is none."); + } + + expect(events.length).toBe(2); + expect(events[0].listener()).toBe("OK"); + expect(events[1].listener()).toBe("NG"); + }); + + it("addEventListener test duplicate case1", () => + { + const eventDispatcher = new EventDispatcher(); + + const a = () => { return "OK" }; + + eventDispatcher.addEventListener("test", a); + eventDispatcher.addEventListener("test", a); + + if (!eventDispatcher._$events) { + throw new Error("addEventListener test success case1"); + } + + const events = eventDispatcher._$events.get("test"); + if (!events) { + throw new Error("the events is none."); + } + + expect(events.length).toBe(1); + expect(events[0].listener()).toBe("OK"); + }); + + it("addEventListener test duplicate case2", () => + { + const eventDispatcher = new EventDispatcher(); + + let name = ""; + eventDispatcher.addEventListener("test", () => { name = "ok" }); + eventDispatcher.addEventListener("test", () => { name = "ng" }); + + if (!eventDispatcher._$events) { + throw new Error("addEventListener test success case1"); + } + + const events = eventDispatcher._$events.get("test"); + if (!events) { + throw new Error("the events is none."); + } + + expect(events.length).toBe(2); + eventDispatcher.dispatchEvent(new Event("test")); + expect(name).toBe("ng"); + }); + + it("addEventListener test duplicate case4", () => + { + const eventDispatcher1 = new EventDispatcher(); + const eventDispatcher2 = new EventDispatcher(); + + let target = null; + const enterFrame = (event: Event) => { target = event.currentTarget }; + + $broadcastEvents.clear(); + expect($broadcastEvents.size).toBe(0); + eventDispatcher1.addEventListener(Event.ENTER_FRAME, enterFrame); + eventDispatcher2.addEventListener(Event.ENTER_FRAME, enterFrame); + + expect($broadcastEvents.size).toBe(1); + expect($broadcastEvents.get(Event.ENTER_FRAME)?.length).toBe(2); + + eventDispatcher1.dispatchEvent(new Event(Event.ENTER_FRAME)); + expect(target).toBe(eventDispatcher1); + + eventDispatcher2.dispatchEvent(new Event(Event.ENTER_FRAME)); + expect(target).toBe(eventDispatcher2); + }); +}); \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.ts b/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.ts new file mode 100644 index 00000000..d6080eff --- /dev/null +++ b/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.ts @@ -0,0 +1,129 @@ +import type { EventListenerImpl } from "../interface/EventListenerImpl"; +import type { EventDispatcherImpl } from "../interface/EventDispatcherImpl"; +import { Event } from "../Event"; +import { + $broadcastEvents, + $getArray +} from "../EventUtil"; + +/** + * @description 指定イベントに関数を登録、既に登録されている場合は上書。 + * Register a function in the specified event, or overwrite if already registered. + * + * @param {EventDispatcher} scope + * @param {string} type + * @param {Function} listener + * @param {boolean} [use_capture = false] + * @param {number} [priority = 0] + * @method + * @protected + */ +export const execute = ( + scope: EventDispatcherImpl, + type: string, + listener: Function, + use_capture: boolean = false, + priority: number = 0 +): void => { + + let events: EventListenerImpl[]; + switch (type) { + + // broadcast event + case Event.ENTER_FRAME: + case Event.EXIT_FRAME: + case Event.FRAME_CONSTRUCTED: + case Event.RENDER: + case Event.ACTIVATE: + case Event.DEACTIVATE: + case "keyDown": + case "keyUp": + + if (!$broadcastEvents.size + || !$broadcastEvents.has(type) + ) { + $broadcastEvents.set(type, $getArray()); + } + + events = $broadcastEvents.get(type) as NonNullable; + + break; + + // normal event + default: + + // init + if (!scope._$events) { + scope._$events = new Map(); + } + + if (!scope._$events.size || !scope._$events.has(type)) { + scope._$events.set(type, $getArray()); + } + + events = scope._$events.get(type) as NonNullable; + + break; + + } + + // duplicate check + const length: number = events.length; + let index = 0; + for ( ; index < length; ++index) { + + const event: EventListenerImpl = events[index]; + if (use_capture !== event.useCapture) { + continue; + } + + if (event.target !== scope) { + continue; + } + + if (event.listener !== listener) { + continue; + } + + break; + } + + // add or overwrite + if (length === index) { + // add + events.push({ + "listener": listener, + "priority": priority, + "useCapture": use_capture, + "target": scope + }); + } else { + // overwrite + const event: EventListenerImpl = events[index]; + event.listener = listener; + event.priority = priority; + event.useCapture = use_capture; + event.target = scope; + } + + if (events.length > 1) { + + // sort(DESC) + events.sort((a: EventListenerImpl, b: EventListenerImpl): number => + { + switch (true) { + + case a.priority > b.priority: + return -1; + + case a.priority < b.priority: + return 1; + + default: + return 0; + + } + }); + + } +}; \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.test.ts b/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.test.ts new file mode 100644 index 00000000..fd667ad1 --- /dev/null +++ b/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.test.ts @@ -0,0 +1,343 @@ +import { Event } from "../Event"; +import { EventDispatcher } from "../EventDispatcher"; +import { EventPhase } from "../EventPhase"; +import { $broadcastEvents } from "../EventUtil"; +import { describe, expect, it } from "vitest"; + +describe("EventDispatcher.js dispatchEvent test", function() +{ + it("dispatchEvent test case1", () => + { + const eventDispatcher = new EventDispatcher(); + + let result = ""; + const test1 = () => { result += "O" }; + const test2 = () => { result += "K" }; + const test3 = () => { result += "!" }; + + eventDispatcher.addEventListener("test", test1); + eventDispatcher.addEventListener("test", test2); + eventDispatcher.addEventListener("test", test3); + + eventDispatcher.dispatchEvent(new Event("test")); + + expect(result).toBe("OK!"); + }); + + it("dispatchEvent test case2", () => + { + const eventDispatcher = new EventDispatcher(); + + let result = ""; + const test1 = () => { result += "!" }; + const test2 = () => { result += "K" }; + const test3 = () => { result += "O" }; + + eventDispatcher.addEventListener("test", test2, false, 20); + eventDispatcher.addEventListener("test", test1, false, 10); + eventDispatcher.addEventListener("test", test3, false, 30); + + eventDispatcher.dispatchEvent(new Event("test")); + + expect(result).toBe("OK!"); + }); + + it("dispatchEvent test case3", () => + { + class Parent extends EventDispatcher {} + + const parent = new Parent(); + class Child extends EventDispatcher + { + private _$parent: Parent; + constructor (src: Parent) + { + super(); + + this._$parent = src; + } + get parent () + { + return this._$parent; + } + } + const child = new Child(parent); + + let result = ""; + const test = () => { result = "capture" }; + + parent.addEventListener("test", test, true); + parent.dispatchEvent(new Event("test")); + expect(result).toBe(""); + + child.dispatchEvent(new Event("test")); + expect(result).toBe("capture"); + }); + + it("dispatchEvent test case4", () => + { + class Parent extends EventDispatcher {} + + const parent = new Parent(); + class Child extends EventDispatcher + { + private _$parent: Parent; + constructor (src: Parent) + { + super(); + + this._$parent = src; + } + get parent () + { + return this._$parent; + } + } + const child = new Child(parent); + + let result = ""; + const test = () => { result = "parent" }; + + parent.addEventListener("test", test); + + child.dispatchEvent(new Event("test")); + expect(result).toBe(""); + + parent.dispatchEvent(new Event("test")); + expect(result).toBe("parent"); + }); + + it("dispatchEvent test case5", () => + { + class Parent extends EventDispatcher {} + + const parent = new Parent(); + class Child extends EventDispatcher + { + private _$parent: Parent; + constructor (src: Parent) + { + super(); + + this._$parent = src; + } + get parent () + { + return this._$parent; + } + } + const child = new Child(parent); + + let result = ""; + const test1 = () => { result += "cap" }; + const test2 = () => { result += "ture" }; + + parent.addEventListener("test", test1, true); + child.addEventListener("test", test2); + + child.dispatchEvent(new Event("test")); + expect(result).toBe("capture"); + }); + + it("dispatchEvent test case6", () => + { + class Parent extends EventDispatcher {} + + const parent = new Parent(); + class Child extends EventDispatcher + { + private _$parent: Parent; + constructor (src: Parent) + { + super(); + + this._$parent = src; + } + get parent () + { + return this._$parent; + } + } + const child = new Child(parent); + + let result = ""; + const test1 = () => { result += "cap" }; + const test2 = () => { result += "ture" }; + const test3 = () => { result += " and bubble" }; + + parent.addEventListener("test", test1, true); + parent.addEventListener("test", test3); + + child.addEventListener("test", test2); + child.dispatchEvent(new Event("test", true)); + + expect(result).toBe("capture and bubble"); + }); + + // stopImmediatePropagation + it("dispatchEvent stopImmediatePropagation test case1", () => + { + class Mock extends EventDispatcher + { + // eslint-disable-next-line no-use-before-define + private _$parent: Mock | null; + public name: string; + constructor (src: Mock | null = null) + { + super(); + + this._$parent = src; + + this.name = ""; + } + get parent (): Mock | null + { + return this._$parent; + } + + } + + const stage = new Mock(); + stage.name = "stage"; + + const sprite_a = new Mock(stage); + sprite_a.name = "A"; + + const sprite_b = new Mock(sprite_a); + sprite_b.name = "B"; + + const sprite_c = new Mock(sprite_b); + sprite_c.name = "C"; + + let result = ""; + const EventRemovedFunc = (event: Event): void => + { + result += event.currentTarget.name; + + // ターゲットフェーズに到達した + if (event.eventPhase === EventPhase.AT_TARGET) { + event.stopImmediatePropagation(); + } + }; + + // event + stage.addEventListener(Event.REMOVED, EventRemovedFunc, true); + stage.addEventListener(Event.REMOVED, EventRemovedFunc, false); + sprite_a.addEventListener(Event.REMOVED, EventRemovedFunc, true); + sprite_a.addEventListener(Event.REMOVED, EventRemovedFunc, false); + sprite_b.addEventListener(Event.REMOVED, EventRemovedFunc, true); + sprite_b.addEventListener(Event.REMOVED, EventRemovedFunc, false); + sprite_c.addEventListener(Event.REMOVED, EventRemovedFunc, true); + sprite_c.addEventListener(Event.REMOVED, EventRemovedFunc, false); + + sprite_c.dispatchEvent(new Event(Event.REMOVED, true)); + expect(result).toBe("stageABC"); + }); + + // stopPropagation + it("dispatchEvent stopImmediatePropagation test case2", () => + { + class Mock extends EventDispatcher + { + // eslint-disable-next-line no-use-before-define + private _$parent: Mock | null; + public name: string; + constructor (src: Mock | null = null) + { + super(); + + this._$parent = src; + + this.name = ""; + } + get parent (): Mock | null + { + return this._$parent; + } + + } + + const stage = new Mock(); + stage.name = "stage1"; + + const sprite_a = new Mock(stage); + sprite_a.name = "A"; + + const sprite_b = new Mock(sprite_a); + sprite_b.name = "B"; + + const sprite_c = new Mock(sprite_b); + sprite_c.name = "C"; + + let resultCaseA = ""; + const EventRemovedFuncA = (e: any) => + { + + resultCaseA += e.currentTarget.name; + + // ターゲットフェーズに到達した + if (e.eventPhase === EventPhase.AT_TARGET) { + // イベント通知の伝達を終了する + e.stopPropagation(); + } + }; + + let resultCaseB = ""; + const EventRemovedFuncB = (e: any) => + { + resultCaseB += e.currentTarget.name; + }; + + // A + stage.addEventListener(Event.REMOVED, EventRemovedFuncA, true); + stage.addEventListener(Event.REMOVED, EventRemovedFuncA, false); + sprite_a.addEventListener(Event.REMOVED, EventRemovedFuncA, true); + sprite_a.addEventListener(Event.REMOVED, EventRemovedFuncA, false); + sprite_b.addEventListener(Event.REMOVED, EventRemovedFuncA, true); + sprite_b.addEventListener(Event.REMOVED, EventRemovedFuncA, false); + sprite_c.addEventListener(Event.REMOVED, EventRemovedFuncA, true); + sprite_c.addEventListener(Event.REMOVED, EventRemovedFuncA, false); + + // B + stage.addEventListener(Event.REMOVED, EventRemovedFuncB, true); + stage.addEventListener(Event.REMOVED, EventRemovedFuncB, false); + sprite_a.addEventListener(Event.REMOVED, EventRemovedFuncB, true); + sprite_a.addEventListener(Event.REMOVED, EventRemovedFuncB, false); + sprite_b.addEventListener(Event.REMOVED, EventRemovedFuncB, true); + sprite_b.addEventListener(Event.REMOVED, EventRemovedFuncB, false); + sprite_c.addEventListener(Event.REMOVED, EventRemovedFuncB, true); + sprite_c.addEventListener(Event.REMOVED, EventRemovedFuncB, false); + + // execute + sprite_c.dispatchEvent(new Event(Event.REMOVED, true)); + + expect(resultCaseA).toBe("stage1ABC"); + expect(resultCaseB).toBe("stage1ABC"); + + }); + + it("dispatchEvent test single dispatchEvent", () => + { + const eventDispatcher1 = new EventDispatcher(); + const eventDispatcher2 = new EventDispatcher(); + + $broadcastEvents.clear(); + expect($broadcastEvents.size).toBe(0); + + let result = ""; + eventDispatcher1.addEventListener(Event.ENTER_FRAME, () => + { + result += "eventDispatcher1"; + }); + + eventDispatcher2.addEventListener(Event.ENTER_FRAME, () => + { + result += "eventDispatcher2"; + }); + + expect($broadcastEvents.size).toBe(1); + eventDispatcher1.dispatchEvent(new Event(Event.ENTER_FRAME)); + expect(result).toBe("eventDispatcher1"); + }); + +}); \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.ts b/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.ts new file mode 100644 index 00000000..2ba5e333 --- /dev/null +++ b/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.ts @@ -0,0 +1,278 @@ +import type { EventImpl } from "../interface/EventImpl"; +import type { EventDispatcherImpl } from "../interface/EventDispatcherImpl"; +import type { EventListenerImpl } from "../interface/EventListenerImpl"; +import { Event } from "../Event"; +import { EventPhase } from "../EventPhase"; +import { + $broadcastEvents, + $getArray, + $poolArray +} from "../EventUtil"; + +/** + * @description 指定のイベントを実行します。 + * Executes the specified event. + * + * @param {EventDispatcher} scope + * @param {Event} event + * @return {boolean} + * @method + * @protected + */ +export const execute = ( + scope: EventDispatcherImpl, + event: EventImpl +): boolean => { + + switch (event.type) { + + case Event.ENTER_FRAME: + case Event.EXIT_FRAME: + case Event.FRAME_CONSTRUCTED: + case Event.RENDER: + case Event.ACTIVATE: + case Event.DEACTIVATE: + case "keyDown": + case "keyUp": + { + if (!$broadcastEvents.size + || !$broadcastEvents.has(event.type) + ) { + return false; + } + + const events = $broadcastEvents.get(event.type) as NonNullable; + if (!events.length) { + return false; + } + + for (let idx = 0; idx < events.length; ++idx) { + + const object: EventListenerImpl = events[idx]; + if (object.target !== scope) { + continue; + } + + // start target + event.eventPhase = EventPhase.AT_TARGET; + + // event execute + event.currentTarget = object.target; + + try { + + event.listener = object.listener; + object.listener.call(null, event); + + } catch (e) { + + console.error(e); + + return false; + + } + } + } + return true; + + default: + { + let currentEvents: EventListenerImpl[] | null = null; + if (scope._$events + && scope._$events.size + && scope._$events.has(event.type) + ) { + const events = scope._$events.get(event.type); + if (events) { + currentEvents = events.slice(0); + } + } + + // parent + const parentEvents = $getArray(); + if ("parent" in scope) { + + let parent = scope.parent as EventDispatcherImpl | null; + while (parent) { + + if (parent.hasEventListener(event.type)) { + + const events: EventListenerImpl[] | null = parent._$events && parent._$events.has(event.type) + ? parent._$events.get(event.type) as NonNullable + : null; + + if (events) { + parentEvents.push(events); + } + } + + parent = parent.parent; + + } + + } + + if (!currentEvents && !parentEvents.length) { + if (currentEvents) { + $poolArray(currentEvents); + } + $poolArray(parentEvents); + return false; + } + + event.target = scope; + + // stage => child... end + if (parentEvents.length) { + + // start capture + event.eventPhase = EventPhase.CAPTURING_PHASE; + + switch (true) { + + case event._$stopImmediatePropagation: + case event._$stopPropagation: + break; + + default: + for (let idx = parentEvents.length - 1; idx > -1; --idx) { + + const events: EventListenerImpl[] = parentEvents[idx]; + for (let idx: number = 0; idx < events.length; ++idx) { + + const object: EventListenerImpl = events[idx]; + if (!object.useCapture) { + continue; + } + + // event execute + event.currentTarget = object.target; + + try { + + event.listener = object.listener; + object.listener.call(null, event); + + } catch (e) { + + console.error(e); + + return false; + } + + if (event._$stopImmediatePropagation) { + break; + } + + } + + if (event._$stopImmediatePropagation) { + break; + } + + } + break; + } + + } + + if (currentEvents + && !event._$stopImmediatePropagation + && !event._$stopPropagation + ) { + + // start target + event.eventPhase = EventPhase.AT_TARGET; + + for (let idx: number = 0; idx < currentEvents.length; ++idx) { + + const object: EventListenerImpl = currentEvents[idx]; + if (object.useCapture) { + continue; + } + + // event execute + event.currentTarget = object.target; + try { + + event.listener = object.listener; + object.listener.call(null, event); + + } catch (e) { + + console.error(e); + + return false; + } + + if (event._$stopImmediatePropagation) { + break; + } + + } + + $poolArray(currentEvents); + } + + if (parentEvents.length) { + + // start bubbling + event.eventPhase = EventPhase.BUBBLING_PHASE; + + switch (true) { + + case event._$stopImmediatePropagation: + case event._$stopPropagation: + case !event.bubbles: + break; + + default: + + // this => parent... => stage end + for (let idx: number = 0; idx < parentEvents.length; ++idx) { + + const events: EventListenerImpl[] = parentEvents[idx]; + for (let idx: number = 0; idx < events.length; ++idx) { + + const object: EventListenerImpl = events[idx]; + if (object.useCapture) { + continue; + } + + // event execute + event.currentTarget = object.target; + + try { + + event.listener = object.listener; + object.listener.call(null, event); + + } catch (e) { + + console.error(e); + + return false; + } + + if (event._$stopImmediatePropagation) { + break; + } + } + + if (event._$stopImmediatePropagation) { + break; + } + + } + + break; + + } + + $poolArray(parentEvents); + } + } + return true; + + } +}; \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherHasEventListenerService.test.ts b/packages/events/src/EventDispatcher/EventDispatcherHasEventListenerService.test.ts new file mode 100644 index 00000000..10a7caf3 --- /dev/null +++ b/packages/events/src/EventDispatcher/EventDispatcherHasEventListenerService.test.ts @@ -0,0 +1,35 @@ +import { Event } from "../Event"; +import { EventDispatcher } from "../EventDispatcher"; +import { describe, expect, it } from "vitest"; + +describe("EventDispatcher.js hasEventListener test", () => +{ + it("hasEventListener test case1", () => + { + const eventDispatcher = new EventDispatcher(); + + eventDispatcher.addEventListener("test1", () => { return "OK" }); + eventDispatcher.addEventListener("test3", () => { return "NG" }); + + expect(eventDispatcher.hasEventListener("test1")).toBe(true); + expect(eventDispatcher.hasEventListener("test2")).toBe(false); + expect(eventDispatcher.hasEventListener("test3")).toBe(true); + expect(eventDispatcher.hasEventListener("test4")).toBe(false); + + }); + + // メソッドが所属する EventDispatcher インスタンスについてのみリスナーが登録されているか + it("hasEventListener test case2", () => + { + const eventDispatcher1 = new EventDispatcher(); + const eventDispatcher2 = new EventDispatcher(); + const eventDispatcher3 = new EventDispatcher(); + + eventDispatcher2.addEventListener(Event.ENTER_FRAME, () => { return "OK" }); + + expect(eventDispatcher1.hasEventListener(Event.ENTER_FRAME)).toBe(false); + expect(eventDispatcher2.hasEventListener(Event.ENTER_FRAME)).toBe(true); + expect(eventDispatcher3.hasEventListener(Event.ENTER_FRAME)).toBe(false); + + }); +}); \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherHasEventListenerService.ts b/packages/events/src/EventDispatcher/EventDispatcherHasEventListenerService.ts new file mode 100644 index 00000000..aa352ed9 --- /dev/null +++ b/packages/events/src/EventDispatcher/EventDispatcherHasEventListenerService.ts @@ -0,0 +1,51 @@ +import type { EventListenerImpl } from "../interface/EventListenerImpl"; +import type { EventDispatcherImpl } from "../interface/EventDispatcherImpl"; +import { Event } from "../Event"; +import { $broadcastEvents } from "../EventUtil"; + +/** + * @description 指定イベントが登録されているかを返却。 + * Returns whether the specified event is registered. + * + * @param {EventDispatcher} scope + * @param {string} type + * @return {boolean} + * @method + * @protected + */ +export const execute = ( + scope: EventDispatcherImpl, + type: string +): boolean => { + + switch (type) { + + case Event.ENTER_FRAME: + case Event.EXIT_FRAME: + case Event.FRAME_CONSTRUCTED: + case Event.RENDER: + case Event.ACTIVATE: + case Event.DEACTIVATE: + case "keyDown": + case "keyUp": + { + if ($broadcastEvents.size + && $broadcastEvents.has(type) + ) { + const events: EventListenerImpl[] = $broadcastEvents.get(type) as NonNullable; + for (let idx: number = 0; idx < events.length; idx++) { + if (events[idx].target === scope) { + return true; + } + } + } + return false; + } + + default: + return !!(scope._$events + && scope._$events.size + && scope._$events.has(type)); + + } +}; \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.test.ts b/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.test.ts new file mode 100644 index 00000000..e05fcd3c --- /dev/null +++ b/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.test.ts @@ -0,0 +1,28 @@ +import { Event } from "../Event"; +import { EventDispatcher } from "../EventDispatcher"; +import { describe, expect, it } from "vitest"; + +describe("EventDispatcher.js removeAllEventListener test", function() +{ + it("removeAllEventListener test case1", () => + { + const eventDispatcher = new EventDispatcher(); + eventDispatcher.addEventListener("test", () => {}); + eventDispatcher.addEventListener("test", () => {}); + eventDispatcher.addEventListener("test", () => {}); + + expect(eventDispatcher.hasEventListener("test")).toBe(true); + eventDispatcher.removeAllEventListener("test"); + expect(eventDispatcher.hasEventListener("test")).toBe(false); + }); + + it("removeAllEventListener test case2", () => + { + const eventDispatcher = new EventDispatcher(); + eventDispatcher.addEventListener(Event.ENTER_FRAME, () => {}); + + expect(eventDispatcher.hasEventListener(Event.ENTER_FRAME)).toBe(true); + eventDispatcher.removeAllEventListener(Event.ENTER_FRAME); + expect(eventDispatcher.hasEventListener(Event.ENTER_FRAME)).toBe(false); + }); +}); diff --git a/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.ts b/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.ts new file mode 100644 index 00000000..7991376f --- /dev/null +++ b/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.ts @@ -0,0 +1,122 @@ +import type { EventDispatcherImpl } from "../interface/EventDispatcherImpl"; +import type { EventListenerImpl } from "../interface/EventListenerImpl"; +import { Event } from "../Event"; +import { + $broadcastEvents, + $getArray, + $poolArray +} from "../EventUtil"; + +/** + * @description イベントリスナーを全て削除。 + * Remove all event listeners. + * + * @param {EventDispatcher} scope + * @param {string} type + * @param {boolean} use_capture + * @return {void} + * @method + * @protected + */ +export const execute = ( + scope: EventDispatcherImpl, + type: string, + use_capture: boolean = false +): void => { + + let events: EventListenerImpl[]; + switch (type) { + + case Event.ENTER_FRAME: + case Event.EXIT_FRAME: + case Event.FRAME_CONSTRUCTED: + case Event.RENDER: + case Event.ACTIVATE: + case Event.DEACTIVATE: + case "keyDown": + case "keyUp": + if (!$broadcastEvents.size + || !$broadcastEvents.has(type) + ) { + return ; + } + events = $broadcastEvents.get(type) as NonNullable; + break; + + default: + if (!scope._$events + || !scope._$events.size + || !scope._$events.has(type) + ) { + return ; + } + events = scope._$events.get(type) as NonNullable; + break; + + } + + if (!events) { + return ; + } + + // remove listener + const results: EventListenerImpl[] = $getArray(); + for (let idx = 0; idx < events.length; ++idx) { + + // event object + const obj: EventListenerImpl = events[idx]; + if (use_capture === obj.useCapture) { + continue; + } + + results.push(obj); + } + + if (!results.length) { + + if ($broadcastEvents.has(type)) { + $broadcastEvents.delete(type); + } + + if (scope._$events && scope._$events.has(type)) { + scope._$events.delete(type); + if (!scope._$events.size) { + scope._$events = null; + } + } + + $poolArray(results); + $poolArray(events); + + return ; + } + + if (results.length > 1) { + + // event sort (DESC) + results.sort(function (a: EventListenerImpl, b: EventListenerImpl) + { + switch (true) { + + case a.priority > b.priority: + return -1; + + case a.priority < b.priority: + return 1; + + default: + return 0; + + } + }); + + } + + if ($broadcastEvents.has(type)) { + $broadcastEvents.set(type, results); + } else { + scope._$events.set(type, results); + } + + $poolArray(events); +}; \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.test.ts b/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.test.ts new file mode 100644 index 00000000..08f9d91b --- /dev/null +++ b/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.test.ts @@ -0,0 +1,150 @@ +import { Event } from "../Event"; +import { $broadcastEvents } from "../EventUtil"; +import { EventDispatcher } from "../EventDispatcher"; +import { EventListenerImpl } from "../interface/EventListenerImpl"; +import { describe, expect, it } from "vitest"; + +describe("EventDispatcher.js removeEventListener test", function() +{ + it("removeEventListener test case1", () => + { + const eventDispatcher = new EventDispatcher(); + + const test1 = () => { return "OK1" }; + const test2 = () => { return "OK2" }; + const test3 = () => { return "OK3" }; + + eventDispatcher.addEventListener("test", test1, false, 10); + eventDispatcher.addEventListener("test", test2, false, 20); + eventDispatcher.addEventListener("test", test3, false, 30); + + eventDispatcher.removeEventListener("test", test2); + + if (!eventDispatcher._$events) { + throw new Error("addEventListener test success case1"); + } + + const events = eventDispatcher._$events.get("test"); + if (!events) { + throw new Error("the events is none."); + } + + expect(events.length).toBe(2); + expect(events[0].listener()).toBe("OK3"); + expect(events[1].listener()).toBe("OK1"); + }); + + it("removeEventListener test case2", () => + { + const eventDispatcher = new EventDispatcher(); + + const a = () => { return "ok" }; + const b = () => { return "no" }; + + eventDispatcher.addEventListener("test", a); + eventDispatcher.addEventListener("test", b); + + if (!eventDispatcher._$events) { + throw new Error("addEventListener test success case1"); + } + + const events = eventDispatcher._$events.get("test"); + if (!events) { + throw new Error("the events is none."); + } + + expect(events.length).toBe(2); + + eventDispatcher.removeEventListener("test", a); + + expect(eventDispatcher._$events.has("test")).toBe(true); + expect(events.length).toBe(1); + }); + + it("removeEventListener test case3", () => + { + const eventDispatcher = new EventDispatcher(); + + const a = () => { return "yes" }; + const b = () => { return "no" }; + + eventDispatcher.addEventListener("test", a, true); + eventDispatcher.addEventListener("test", b, false); + + if (!eventDispatcher._$events) { + throw new Error("addEventListener test success case1"); + } + + const events = eventDispatcher._$events.get("test"); + if (!events) { + throw new Error("the events is none."); + } + + expect(events.length).toBe(2); + + eventDispatcher.removeEventListener("test", b, true); + eventDispatcher.removeEventListener("test", a, true); + + expect(events.length).toBe(1); + expect(events[0].listener().toString()).toBe("no"); + }); + + it("removeEventListener test case4", () => + { + const eventDispatcher = new EventDispatcher(); + + const a = () => { return "ok" }; + const b = () => { return "no" }; + + eventDispatcher.addEventListener("test", a, true); + eventDispatcher.addEventListener("test", b, false); + + if (!eventDispatcher._$events) { + throw new Error("addEventListener test success case1"); + } + + const events = eventDispatcher._$events.get("test"); + if (!events) { + throw new Error("the events is none."); + } + + expect(events.length).toBe(2); + + eventDispatcher.removeEventListener("test", a, false); + eventDispatcher.removeEventListener("test", b, true); + + expect(events.length).toBe(2); + expect(events[0].listener().toString()).toBe("ok"); + expect(events[1].listener().toString()).toBe("no"); + }); + + it("removeEventListener test case5", () => + { + const eventDispatcher1 = new EventDispatcher(); + const eventDispatcher2 = new EventDispatcher(); + + const a = () => { return undefined }; + + $broadcastEvents.clear(); + expect($broadcastEvents.size).toBe(0); + expect($broadcastEvents.has(Event.ENTER_FRAME)).toBe(false); + + eventDispatcher1.addEventListener(Event.ENTER_FRAME, a); + eventDispatcher2.addEventListener(Event.ENTER_FRAME, a); + + expect($broadcastEvents.size).toBe(1); + expect($broadcastEvents.has(Event.ENTER_FRAME)).toBe(true); + + const events = $broadcastEvents.get(Event.ENTER_FRAME) as NonNullable; + expect(events.length).toBe(2); + + eventDispatcher1.removeEventListener(Event.ENTER_FRAME, a); + expect(events.length).toBe(1); + expect($broadcastEvents.has(Event.ENTER_FRAME)).toBe(true); + + eventDispatcher2.removeEventListener(Event.ENTER_FRAME, a); + expect(events.length).toBe(0); + expect($broadcastEvents.has(Event.ENTER_FRAME)).toBe(false); + }); + +}); \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.ts b/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.ts new file mode 100644 index 00000000..511168bd --- /dev/null +++ b/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.ts @@ -0,0 +1,119 @@ +import type { EventDispatcherImpl } from "../interface/EventDispatcherImpl"; +import type { EventListenerImpl } from "../interface/EventListenerImpl"; +import { Event } from "../Event"; +import { + $broadcastEvents, + $poolArray +} from "../EventUtil"; + +/** + * @description イベントリスナーを削除。 + * Remove the event listener. + * + * @param {EventDispatcher} scope + * @param {string} type + * @param {Function} listener + * @param {boolean} [use_capture = false] + * @return {void} + * @method + * @protected + */ +export const execute = ( + scope: EventDispatcherImpl, + type: string, + listener: Function, + use_capture: boolean = false +): void => { + + let events: EventListenerImpl[]; + switch (type) { + + case Event.ENTER_FRAME: + case Event.EXIT_FRAME: + case Event.FRAME_CONSTRUCTED: + case Event.RENDER: + case Event.ACTIVATE: + case Event.DEACTIVATE: + case "keyDown": + case "keyUp": + if (!$broadcastEvents.size + || !$broadcastEvents.has(type) + ) { + return ; + } + events = $broadcastEvents.get(type) as NonNullable; + break; + + default: + if (!scope._$events + || !scope._$events.size + || !scope._$events.has(type) + ) { + return ; + } + events = scope._$events.get(type) as NonNullable; + break; + + } + + if (!events) { + return ; + } + + // remove listener + for (let idx = 0; idx < events.length; ++idx) { + + // event object + const object: EventListenerImpl = events[idx]; + if (use_capture !== object.useCapture) { + continue ; + } + + if (object.listener !== listener) { + continue ; + } + + // delete if match + events.splice(idx, 1); + + break; + } + + if (!events.length) { + + if ($broadcastEvents.has(type)) { + $broadcastEvents.delete(type); + } + + if (scope._$events && scope._$events.has(type)) { + scope._$events.delete(type); + if (!scope._$events.size) { + scope._$events = null; + } + } + + $poolArray(events); + return ; + } + + if (events.length > 1) { + + // event sort(DESC) + events.sort(function (a: EventListenerImpl, b: EventListenerImpl) + { + switch (true) { + + case a.priority > b.priority: + return -1; + + case a.priority < b.priority: + return 1; + + default: + return 0; + + } + }); + + } +}; \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.test.ts b/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.test.ts new file mode 100644 index 00000000..177be0ff --- /dev/null +++ b/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.test.ts @@ -0,0 +1,64 @@ +import { EventDispatcher } from "../EventDispatcher"; +import { describe, expect, it } from "vitest"; + +describe("EventDispatcher.js willTrigger test", function() +{ + it("willTrigger test success case1", () => + { + class Parent extends EventDispatcher {} + const parent2 = new Parent(); + + const parent1 = new Parent(); + class Child extends EventDispatcher + { + private _$parent: Parent; + constructor (src: Parent) + { + super(); + + this._$parent = src; + } + get parent () + { + return this._$parent; + } + } + const child = new Child(parent1); + + parent1.addEventListener("test", () => {}); + + expect(parent2.willTrigger("test")).toBe(false); + expect(parent1.willTrigger("test")).toBe(true); + expect(child.willTrigger("test")).toBe(true); + }); + + it("willTrigger test success case2", () => + { + class Parent extends EventDispatcher {} + + const parent = new Parent(); + class Child extends EventDispatcher + { + private _$parent: Parent; + constructor (src: Parent) + { + super(); + + this._$parent = src; + } + get parent () + { + return this._$parent; + } + } + const child1 = new Child(parent); + const child2 = new Child(parent); + + parent.addEventListener("test", () => {}); + + expect(parent.willTrigger("test")).toBe(true); + expect(child1.willTrigger("test")).toBe(true); + expect(child2.willTrigger("test")).toBe(true); + + }); +}); \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.ts b/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.ts new file mode 100644 index 00000000..26192c84 --- /dev/null +++ b/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.ts @@ -0,0 +1,36 @@ +import type { EventDispatcherImpl } from "../interface/EventDispatcherImpl"; + +/** + * @description 先祖も含めてイベントリスナーが登録されているかどうかを判定。 + * Determine whether an event listener is registered, including ancestors. + * + * @param {EventDispatcher} scope + * @param {string} type + * @return {boolean} + * @method + * @protected + */ +export const execute = ( + scope: EventDispatcherImpl, + type: string +): boolean => { + + if (scope.hasEventListener(type)) { + return true; + } + + if ("parent" in scope) { + + let parent = scope.parent as EventDispatcherImpl | null; + while (parent) { + + if (parent.hasEventListener(type)) { + return true; + } + + parent = parent.parent; + } + } + + return false; +}; \ No newline at end of file From 5f3ec92efee5ee6c322b7d0c47e0f74f59dc5077 Mon Sep 17 00:00:00 2001 From: ienaga Date: Thu, 25 Jul 2024 23:32:27 +0900 Subject: [PATCH 016/343] =?UTF-8?q?#154=20Feat:=20Net=E3=83=91=E3=83=83?= =?UTF-8?q?=E3=82=B1=E3=83=BC=E3=82=B8=E3=82=92=E7=A7=BB=E6=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next2d/events/EventDispatcherTest.ts | 300 ------------------ __tests__/next2d/events/EventPhaseTest.ts | 57 ---- __tests__/next2d/events/EventTest.ts | 122 ------- __tests__/next2d/events/FocusEventTest.ts | 54 ---- .../next2d/events/HTTPStatusEventTest.ts | 44 --- __tests__/next2d/events/IOErrorEventTest.ts | 53 ---- __tests__/next2d/events/MouseEventTest.ts | 81 ----- __tests__/next2d/events/ProgressEventTest.ts | 46 --- __tests__/next2d/events/VideoEventTest.ts | 72 ----- packages/media/src/Sound.ts | 19 +- packages/media/src/SoundMixer.ts | 24 +- packages/media/src/SoundTransform.test.ts | 67 ++++ packages/media/src/SoundTransform.ts | 26 +- packages/net/package.json | 4 - packages/net/src/URLRequest.test.ts | 94 ++++++ packages/net/src/URLRequest.ts | 27 +- 16 files changed, 200 insertions(+), 890 deletions(-) delete mode 100644 __tests__/next2d/events/EventDispatcherTest.ts delete mode 100644 __tests__/next2d/events/EventPhaseTest.ts delete mode 100644 __tests__/next2d/events/EventTest.ts delete mode 100644 __tests__/next2d/events/FocusEventTest.ts delete mode 100644 __tests__/next2d/events/HTTPStatusEventTest.ts delete mode 100644 __tests__/next2d/events/IOErrorEventTest.ts delete mode 100644 __tests__/next2d/events/MouseEventTest.ts delete mode 100644 __tests__/next2d/events/ProgressEventTest.ts delete mode 100644 __tests__/next2d/events/VideoEventTest.ts create mode 100644 packages/media/src/SoundTransform.test.ts create mode 100644 packages/net/src/URLRequest.test.ts diff --git a/__tests__/next2d/events/EventDispatcherTest.ts b/__tests__/next2d/events/EventDispatcherTest.ts deleted file mode 100644 index 25a65ab8..00000000 --- a/__tests__/next2d/events/EventDispatcherTest.ts +++ /dev/null @@ -1,300 +0,0 @@ -import { $currentPlayer } from "../../../packages/util/src/Util"; -import { Event } from "../../../packages/events/src/Event"; -import { EventDispatcher } from "../../../packages/events/src/EventDispatcher"; -import { MovieClip } from "../../../packages/display/src/MovieClip"; -import { Sprite } from "../../../packages/display/src/Sprite"; -import { Stage } from "../../../packages/display/src/Stage"; -import { EventPhase } from "../../../packages/events/src/EventPhase"; - -describe("EventDispatcher.js dispatchEvent test", function() -{ - - // dispatchEvent - it("dispatchEvent test success case1", () => - { - const di = new EventDispatcher(); - - let s = ""; - const test1 = () => { s += "O" }; - const test2 = () => { s += "K" }; - const test3 = () => { s += "!" }; - - di.addEventListener("test", test1); - di.addEventListener("test", test2); - di.addEventListener("test", test3); - - di.dispatchEvent(new Event("test")); - - expect(s).toBe("OK!"); - }); - - it("dispatchEvent test success case2", () => - { - - const di = new EventDispatcher(); - - let s = ""; - const test1 = () => { return s += "!" }; - const test2 = () => { return s += "K" }; - const test3 = () => { return s += "O" }; - - di.addEventListener("test", test2, false, 20); - di.addEventListener("test", test1, false, 10); - di.addEventListener("test", test3, false, 30); - - di.dispatchEvent(new Event("test")); - - expect(s).toBe("OK!"); - }); - - it("dispatchEvent test success capture case1", () => - { - const mc = new MovieClip(); - - let s = ""; - const test = () => { return s = "capture" }; - - mc.addEventListener("test", test, true); - expect(s).toBe(""); - - const sprite = new Sprite(); - mc.addChild(sprite); - - sprite.dispatchEvent(new Event("test")); - expect(s).toBe("capture"); - }); - - it("dispatchEvent test success capture case2", () => - { - const mc = new MovieClip(); - - let s = ""; - const test = () => { return s = "capture" }; - - mc.addEventListener("test", test); - - const sprite = new Sprite(); - mc.addChild(sprite); - - sprite.dispatchEvent(new Event("test")); - expect(s).toBe(""); - }); - - it("dispatchEvent test success capture case2", () => - { - const mc = new MovieClip(); - - let s = ""; - const test1 = () => { return s += "cap" }; - const test2 = () => { return s += "ture" }; - - mc.addEventListener("test", test1, true); - - const sprite = new Sprite(); - sprite.addEventListener("test", test2); - mc.addChild(sprite); - - sprite.dispatchEvent(new Event("test")); - expect(s).toBe("capture"); - }); - - it("dispatchEvent test success capture and bubble case1", () => - { - const mc = new MovieClip(); - - let s = ""; - const test1 = () => { return s += "cap" }; - const test2 = () => { return s += "ture" }; - const test3 = () => { return s += " and bubble" }; - - mc.addEventListener("test", test1, true); - mc.addEventListener("test", test3); - - const sprite = new Sprite(); - sprite.addEventListener("test", test2); - mc.addChild(sprite); - - sprite.dispatchEvent(new Event("test", true)); - - expect(s).toBe("capture and bubble"); - }); - - // stopImmediatePropagation - it("dispatchEvent stopImmediatePropagation test case1", () => - { - const stage = new Stage(); - stage.name = "stage"; - - const root = new MovieClip(); - stage.addChild(root); - - const sprite_a = new Sprite(); - sprite_a.name = "A"; - stage.addChild(sprite_a); - - const sprite_b = new Sprite(); - sprite_b.name = "B"; - sprite_a.addChild(sprite_b); - - const sprite_c = new Sprite(); - sprite_c.name = "C"; - sprite_b.addChild(sprite_c); - - let str = ""; - const EventRemovedFunc = (e: any) => - { - str += e.currentTarget.name; - - // ターゲットフェーズに到達した - if (e.eventPhase === EventPhase.AT_TARGET) { - e.stopImmediatePropagation(); - } - } - - // event - stage.addEventListener(Event.REMOVED, EventRemovedFunc, true); - stage.addEventListener(Event.REMOVED, EventRemovedFunc, false); - sprite_a.addEventListener(Event.REMOVED, EventRemovedFunc, true); - sprite_a.addEventListener(Event.REMOVED, EventRemovedFunc, false); - sprite_b.addEventListener(Event.REMOVED, EventRemovedFunc, true); - sprite_b.addEventListener(Event.REMOVED, EventRemovedFunc, false); - sprite_c.addEventListener(Event.REMOVED, EventRemovedFunc, true); - sprite_c.addEventListener(Event.REMOVED, EventRemovedFunc, false); - - sprite_c.parent.removeChild(sprite_c); - - expect(str).toBe("stageABC"); - }); - - // stopPropagation - it("dispatchEvent stopImmediatePropagation test case2", () => - { - const stage = new Stage(); - stage.name = "stage1"; - - const root = new MovieClip(); - stage.addChild(root); - - const sprite_a = new Sprite(); - sprite_a.name = "A"; - stage.addChild(sprite_a); - - const sprite_b = new Sprite(); - sprite_b.name = "B"; - sprite_a.addChild(sprite_b); - - const sprite_c = new Sprite(); - sprite_c.name = "C"; - sprite_b.addChild(sprite_c); - - let strA = ""; - const EventRemovedFuncA = (e: any) => - { - - strA += e.currentTarget.name; - - // ターゲットフェーズに到達した - if (e.eventPhase === EventPhase.AT_TARGET) { - // イベント通知の伝達を終了する - e.stopPropagation(); - } - } - - let strB = ""; - const EventRemovedFuncB = (e: any) => - { - strB += e.currentTarget.name; - } - - // A - stage.addEventListener(Event.REMOVED, EventRemovedFuncA, true); - stage.addEventListener(Event.REMOVED, EventRemovedFuncA, false); - sprite_a.addEventListener(Event.REMOVED, EventRemovedFuncA, true); - sprite_a.addEventListener(Event.REMOVED, EventRemovedFuncA, false); - sprite_b.addEventListener(Event.REMOVED, EventRemovedFuncA, true); - sprite_b.addEventListener(Event.REMOVED, EventRemovedFuncA, false); - sprite_c.addEventListener(Event.REMOVED, EventRemovedFuncA, true); - sprite_c.addEventListener(Event.REMOVED, EventRemovedFuncA, false); - - // B - stage.addEventListener(Event.REMOVED, EventRemovedFuncB, true); - stage.addEventListener(Event.REMOVED, EventRemovedFuncB, false); - sprite_a.addEventListener(Event.REMOVED, EventRemovedFuncB, true); - sprite_a.addEventListener(Event.REMOVED, EventRemovedFuncB, false); - sprite_b.addEventListener(Event.REMOVED, EventRemovedFuncB, true); - sprite_b.addEventListener(Event.REMOVED, EventRemovedFuncB, false); - sprite_c.addEventListener(Event.REMOVED, EventRemovedFuncB, true); - sprite_c.addEventListener(Event.REMOVED, EventRemovedFuncB, false); - - // execute - sprite_c.parent.removeChild(sprite_c); - - expect(strA).toBe("stage1ABC"); - expect(strB).toBe("stage1ABC"); - - }); - - // stopPropagation - it("dispatchEvent stopImmediatePropagation test case3", () => - { - - let strA = ""; - const sprite1 = new Sprite(); - sprite1.addEventListener(Event.ADDED_TO_STAGE, () => - { - strA = "ADDED_TO_STAGE"; - }, true); - - let strB = ""; - sprite1.addEventListener(Event.REMOVED_FROM_STAGE, () => - { - strB = "REMOVED_FROM_STAGE"; - }, true); - - const sprite2 = new Sprite(); - sprite1.addChild(sprite2); - sprite1.removeChild(sprite2); - - expect(strA).toBe(""); - expect(strB).toBe(""); - - const stage = new Stage(); - const root = new MovieClip(); - stage.addChild(root); - - root.addChild(sprite1); - sprite1.addChild(sprite2); - sprite1.removeChild(sprite2); - - expect(strA).toBe("ADDED_TO_STAGE"); - expect(strB).toBe("REMOVED_FROM_STAGE"); - - }); - - it("dispatchEvent test single dispatchEvent", () => - { - const player = $currentPlayer(); - player.broadcastEvents.clear(); - - const stage = new Stage(); - - const mc = new MovieClip(); - stage.addChild(mc); - - let log = ""; - mc.addEventListener(Event.ENTER_FRAME, () => - { - log += "MovieClip"; - }); - - stage.addEventListener(Event.ENTER_FRAME, () => - { - log += "Stage"; - }); - - mc.dispatchEvent(new Event(Event.ENTER_FRAME)); - expect(log).toBe("MovieClip"); - }); - -}); - diff --git a/__tests__/next2d/events/EventPhaseTest.ts b/__tests__/next2d/events/EventPhaseTest.ts deleted file mode 100644 index 7d9538c5..00000000 --- a/__tests__/next2d/events/EventPhaseTest.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { EventPhase } from "../../../packages/events/src/EventPhase"; - -describe("EventPhase.js toString test", () => -{ - it("toString test success", () => - { - let object = new EventPhase(); - expect(object.toString()).toBe("[object EventPhase]"); - }); - -}); - -describe("EventPhase.js static toString test", () => -{ - - it("static toString test", () => - { - expect(EventPhase.toString()).toBe("[class EventPhase]"); - }); - -}); - -describe("EventPhase.js namespace test", () => -{ - - it("namespace test public", () => - { - const object = new EventPhase(); - expect(object.namespace).toBe("next2d.events.EventPhase"); - }); - - it("namespace test static", () => - { - expect(EventPhase.namespace).toBe("next2d.events.EventPhase"); - }); - -}); - -describe("EventPhase.js property test", () => -{ - - it("CAPTURING_PHASE test", () => - { - expect(EventPhase.CAPTURING_PHASE).toBe(1); - }); - - it("AT_TARGET test", () => - { - expect(EventPhase.AT_TARGET).toBe(2); - }); - - it("BUBBLING_PHASE test", () => - { - expect(EventPhase.BUBBLING_PHASE).toBe(3); - }); - -}); \ No newline at end of file diff --git a/__tests__/next2d/events/EventTest.ts b/__tests__/next2d/events/EventTest.ts deleted file mode 100644 index 92c140f6..00000000 --- a/__tests__/next2d/events/EventTest.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { Event } from "../../../packages/events/src/Event"; - -describe("Event.js toString test", function() -{ - it("toString test success", function() - { - const object = new Event("test"); - expect(object.toString()) - .toBe("[Event type=\"test\" bubbles=false cancelable=false eventPhase=2]"); - }); - -}); - -describe("Event.js static toString test", function() -{ - - it("static toString test", function() - { - expect(Event.toString()).toBe("[class Event]"); - }); - -}); - -describe("Event.js namespace test", function() -{ - - it("namespace test public", function() - { - const object = new Event("test"); - expect(object.namespace).toBe("next2d.events.Event"); - }); - - it("namespace test static", function() - { - expect(Event.namespace).toBe("next2d.events.Event"); - }); - -}); - -describe("Event.js property test", function() -{ - - it("ACTIVATE test", () => - { - expect(Event.ACTIVATE).toBe("activate"); - }); - - it("ADDED test", () => - { - expect(Event.ADDED).toBe("added"); - }); - - it("ADDED_TO_STAGE test", () => - { - expect(Event.ADDED_TO_STAGE).toBe("addedToStage"); - }); - - it("COMPLETE test", () => - { - expect(Event.COMPLETE).toBe("complete"); - }); - - it("DEACTIVATE test", () => - { - expect(Event.DEACTIVATE).toBe("deactivate"); - }); - - it("ENTER_FRAME test", () => - { - expect(Event.ENTER_FRAME).toBe("enterFrame"); - }); - - it("EXIT_FRAME test", () => - { - expect(Event.EXIT_FRAME).toBe("exitFrame"); - }); - - it("FRAME_CONSTRUCTED test", () => - { - expect(Event.FRAME_CONSTRUCTED).toBe("frameConstructed"); - }); - - it("INIT test", () => - { - expect(Event.INIT).toBe("init"); - }); - - it("MOUSE_LEAVE test", () => - { - expect(Event.MOUSE_LEAVE).toBe("mouseLeave"); - }); - - it("REMOVED test", () => - { - expect(Event.REMOVED).toBe("removed"); - }); - - it("REMOVED_FROM_STAGE test", () => - { - expect(Event.REMOVED_FROM_STAGE).toBe("removedFromStage"); - }); - - it("RENDER test", () => - { - expect(Event.RENDER).toBe("render"); - }); - - it("SOUND_COMPLETE test", () => - { - expect(Event.SOUND_COMPLETE).toBe("soundComplete"); - }); - - it("FRAME_CONSTRUCTED test", () => - { - expect(Event.FRAME_CONSTRUCTED).toBe("frameConstructed"); - }); - - it("FRAME_LABEL test", () => - { - expect(Event.FRAME_LABEL).toBe("frameLabel"); - }); -}); \ No newline at end of file diff --git a/__tests__/next2d/events/FocusEventTest.ts b/__tests__/next2d/events/FocusEventTest.ts deleted file mode 100644 index 8df1fb61..00000000 --- a/__tests__/next2d/events/FocusEventTest.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { FocusEvent } from "../../../packages/events/src/FocusEvent"; - -describe("FocusEvent.js static toString test", () => -{ - - it("static toString test", () => - { - expect(FocusEvent.toString()).toBe("[class FocusEvent]"); - }); - -}); - -describe("FocusEvent.js toString test", () => -{ - // toString - it("toString test success", () => - { - let event = new FocusEvent("focusIn"); - expect(event.toString()).toBe("[FocusEvent type=\"focusIn\" bubbles=true cancelable=false eventPhase=2]"); - }); - -}); - -describe("FocusEvent.js namespace test", () => -{ - - it("namespace test public", () => - { - const object = new FocusEvent("test"); - expect(object.namespace).toBe("next2d.events.FocusEvent"); - }); - - it("namespace test static", () => - { - expect(FocusEvent.namespace).toBe("next2d.events.FocusEvent"); - }); - -}); - -describe("FocusEvent.js property test", () => -{ - - it("FOCUS_IN test", () => - { - expect(FocusEvent.FOCUS_IN).toBe("focusIn"); - }); - - it("FOCUS_OUT test", () => - { - expect(FocusEvent.FOCUS_OUT).toBe("focusOut"); - }); - -}); - diff --git a/__tests__/next2d/events/HTTPStatusEventTest.ts b/__tests__/next2d/events/HTTPStatusEventTest.ts deleted file mode 100644 index 900afa99..00000000 --- a/__tests__/next2d/events/HTTPStatusEventTest.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { HTTPStatusEvent } from "../../../packages/events/src/HTTPStatusEvent"; - - -describe("HTTPStatusEvent.js toString test", () => -{ - it("toString test1 success", () => - { - let event = new HTTPStatusEvent(""); - expect(event.toString()).toBe("[HTTPStatusEvent type=\"\" bubbles=false cancelable=false eventPhase=2 status=0 responseURL=\"\"]"); - }); - - it("toString test2 success", () => - { - let event = new HTTPStatusEvent("type", true, false, 200, "url"); - expect(event.toString()).toBe("[HTTPStatusEvent type=\"type\" bubbles=true cancelable=false eventPhase=2 status=200 responseURL=\"url\"]"); - }); - -}); - -describe("HTTPStatusEvent.js static toString test", () => -{ - - it("static toString test", () => - { - expect(HTTPStatusEvent.toString()).toBe("[class HTTPStatusEvent]"); - }); - -}); - -describe("HTTPStatusEvent.js namespace test", () => -{ - - it("namespace test public", () => - { - const object = new HTTPStatusEvent("test"); - expect(object.namespace).toBe("next2d.events.HTTPStatusEvent"); - }); - - it("namespace test static", () => - { - expect(HTTPStatusEvent.namespace).toBe("next2d.events.HTTPStatusEvent"); - }); - -}); \ No newline at end of file diff --git a/__tests__/next2d/events/IOErrorEventTest.ts b/__tests__/next2d/events/IOErrorEventTest.ts deleted file mode 100644 index aa67d9f5..00000000 --- a/__tests__/next2d/events/IOErrorEventTest.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { IOErrorEvent } from "../../../packages/events/src/IOErrorEvent"; - -describe("IOErrorEvent.js toString test", () => -{ - // toString - it("toString test1 success", () => - { - let event = new IOErrorEvent(""); - expect(event.toString()).toBe("[IOErrorEvent type=\"\" bubbles=false cancelable=false eventPhase=2 text=\"\"]"); - }); - - it("toString test2 success", () => - { - let event = new IOErrorEvent("ioError", false, false, "IOErrorEvent"); - expect(event.toString()).toBe("[IOErrorEvent type=\"ioError\" bubbles=false cancelable=false eventPhase=2 text=\"IOErrorEvent\"]"); - }); - -}); - -describe("IOErrorEvent.js static toString test", () => -{ - - it("static toString test", () => - { - expect(IOErrorEvent.toString()).toBe("[class IOErrorEvent]"); - }); - -}); - -describe("IOErrorEvent.js namespace test", () => -{ - - it("namespace test public", () => - { - const object = new IOErrorEvent("test"); - expect(object.namespace).toBe("next2d.events.IOErrorEvent"); - }); - - it("namespace test static", () => - { - expect(IOErrorEvent.namespace).toBe("next2d.events.IOErrorEvent"); - }); - -}); - -describe("IOErrorEvent.js property test", () => -{ - - it("IO_ERROR test", function () { - expect(IOErrorEvent.IO_ERROR).toBe("ioError"); - }); - -}); \ No newline at end of file diff --git a/__tests__/next2d/events/MouseEventTest.ts b/__tests__/next2d/events/MouseEventTest.ts deleted file mode 100644 index 5cf8db8c..00000000 --- a/__tests__/next2d/events/MouseEventTest.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { MouseEvent } from "../../../packages/events/src/MouseEvent"; - -describe("MouseEvent.js static toString test", () => -{ - - it("static toString test", () => - { - expect(MouseEvent.toString()).toBe("[class MouseEvent]"); - }); - -}); - -describe("MouseEvent.js namespace test", () => -{ - - it("namespace test public", () => - { - const object = new MouseEvent("test"); - expect(object.namespace).toBe("next2d.events.MouseEvent"); - }); - - it("namespace test static", () => - { - expect(MouseEvent.namespace).toBe("next2d.events.MouseEvent"); - }); - -}); - -describe("MouseEvent.js property test", () => -{ - - it("CLICK test", () => - { - expect(MouseEvent.CLICK).toBe("click"); - }); - - it("DOUBLE_CLICK test", () => - { - expect(MouseEvent.DOUBLE_CLICK).toBe("dblclick"); - }); - - it("MOUSE_DOWN test", () => - { - expect(MouseEvent.MOUSE_DOWN).toBe("mouseDown"); - }); - - it("MOUSE_MOVE test", () => - { - expect(MouseEvent.MOUSE_MOVE).toBe("mouseMove"); - }); - - it("MOUSE_OUT test", () => - { - expect(MouseEvent.MOUSE_OUT).toBe("mouseOut"); - }); - - it("MOUSE_OVER test", () => - { - expect(MouseEvent.MOUSE_OVER).toBe("mouseOver"); - }); - - it("MOUSE_UP test", () => - { - expect(MouseEvent.MOUSE_UP).toBe("mouseUp"); - }); - - it("MOUSE_WHEEL test", () =>{ - expect(MouseEvent.MOUSE_WHEEL).toBe("mouseWheel"); - }); - - it("ROLL_OUT test", () => - { - expect(MouseEvent.ROLL_OUT).toBe("rollOut"); - }); - - it("ROLL_OVER test", () => - { - expect(MouseEvent.ROLL_OVER).toBe("rollOver"); - }); - -}); \ No newline at end of file diff --git a/__tests__/next2d/events/ProgressEventTest.ts b/__tests__/next2d/events/ProgressEventTest.ts deleted file mode 100644 index d3c6df29..00000000 --- a/__tests__/next2d/events/ProgressEventTest.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { ProgressEvent } from "../../../packages/events/src/ProgressEvent"; - -describe("ProgressEvent.js toString test", () => -{ - it("toString test success", () => - { - let event = new ProgressEvent(""); - expect(event.toString()).toBe("[ProgressEvent type=\"\" bubbles=false cancelable=false eventPhase=2 bytesLoaded=0 bytesTotal=0]"); - }); - -}); - -describe("ProgressEvent.js static toString test", () => -{ - - it("static toString test", () => - { - expect(ProgressEvent.toString()).toBe("[class ProgressEvent]"); - }); - -}); - -describe("ProgressEvent.js namespace test", () => -{ - - it("namespace test public", () => - { - const object = new ProgressEvent("test"); - expect(object.namespace).toBe("next2d.events.ProgressEvent"); - }); - - it("namespace test static", () => - { - expect(ProgressEvent.namespace).toBe("next2d.events.ProgressEvent"); - }); - -}); - -describe("ProgressEvent.js property test", () => -{ - - it("PROGRESS test", () => { - expect(ProgressEvent.PROGRESS).toBe("progress"); - }); - -}); \ No newline at end of file diff --git a/__tests__/next2d/events/VideoEventTest.ts b/__tests__/next2d/events/VideoEventTest.ts deleted file mode 100644 index 327b37c3..00000000 --- a/__tests__/next2d/events/VideoEventTest.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { VideoEvent } from "../../../packages/events/src/VideoEvent"; - -describe("VideoEvent.js toString test", () => -{ - it("toString test success", () => - { - let event = new VideoEvent(""); - expect(event.toString()).toBe("[VideoEvent type=\"\" bubbles=false cancelable=false eventPhase=2 bytesLoaded=0 bytesTotal=0]"); - }); - -}); - -describe("VideoEvent.js static toString test", () => -{ - - it("static toString test", () => - { - expect(VideoEvent.toString()).toBe("[class VideoEvent]"); - }); - -}); - -describe("VideoEvent.js namespace test", () => -{ - - it("namespace test public", () => - { - const object = new VideoEvent("test"); - expect(object.namespace).toBe("next2d.events.VideoEvent"); - }); - - it("namespace test static", () => - { - expect(VideoEvent.namespace).toBe("next2d.events.VideoEvent"); - }); - -}); - -describe("VideoEvent.js property test", () => -{ - - it("PLAY_START test", () => - { - expect(VideoEvent.PLAY_START).toBe("playStart"); - }); - - it("PLAY test", () => - { - expect(VideoEvent.PLAY).toBe("play"); - }); - - it("PROGRESS test", () => - { - expect(VideoEvent.PROGRESS).toBe("progress"); - }); - - it("PLAY_END test", () => - { - expect(VideoEvent.PLAY_END).toBe("playEnd"); - }); - - it("PAUSE test", () => - { - expect(VideoEvent.PAUSE).toBe("pause"); - }); - - it("SEEK test", () => - { - expect(VideoEvent.SEEK).toBe("seek"); - }); - -}); \ No newline at end of file diff --git a/packages/media/src/Sound.ts b/packages/media/src/Sound.ts index c388fa97..75a3a54d 100644 --- a/packages/media/src/Sound.ts +++ b/packages/media/src/Sound.ts @@ -32,12 +32,11 @@ import { } from "@next2d/util"; /** - * Sound クラスを使用すると、アプリケーション内のサウンドを処理することができます。 - * Sound クラスを使用すると、Sound オブジェクトの作成や、外部 MP3 ファイルのオブジェクトへのロードと再生ができます。 - * - * The Sound class lets you work with sound in an application. - * The Sound class lets you create a Sound object, - * load and play an external MP3 file into that object. + * @description Sound クラスを使用すると、アプリケーション内のサウンドを処理することができます。 + * Sound クラスを使用すると、Sound オブジェクトの作成や、外部 MP3 ファイルのオブジェクトへのロードと再生ができます。 + * The Sound class lets you work with sound in an application. + * The Sound class lets you create a Sound object, + * load and play an external MP3 file into that object. * * @class * @memberOf next2d.media @@ -148,7 +147,7 @@ export class Sound extends EventDispatcher * Returns the string representation of the specified class. * * @return {string} - * @default [class Sound] + * @default "[class Sound]" * @method * @static */ @@ -162,7 +161,7 @@ export class Sound extends EventDispatcher * Returns the space name of the specified class. * * @return {string} - * @default next2d.media.Sound + * @default "next2d.media.Sound" * @const * @static */ @@ -176,7 +175,7 @@ export class Sound extends EventDispatcher * Returns the string representation of the specified object. * * @return {string} - * @default [object Sound] + * @default "[object Sound]" * @method * @public */ @@ -190,7 +189,7 @@ export class Sound extends EventDispatcher * Returns the space name of the specified object. * * @return {string} - * @default next2d.media.Sound + * @default "next2d.media.Sound" * @const * @public */ diff --git a/packages/media/src/SoundMixer.ts b/packages/media/src/SoundMixer.ts index 02e749d1..aa874b60 100644 --- a/packages/media/src/SoundMixer.ts +++ b/packages/media/src/SoundMixer.ts @@ -11,6 +11,12 @@ import { $Math } from "@next2d/share"; +/** + * @type {number} + * @private + */ +let $volume: number = 1; + /** * SoundMixer クラスには、静的プロパティやアプリケーションのグローバルサウンドコントロールのメソッドが含まれます。 * SoundMixer クラスは、アプリケーションの埋め込みおよびストリーミングサウンド、及び、Video クラスの音声を制御します。 @@ -25,7 +31,7 @@ export class SoundMixer * Returns the string representation of the specified class. * * @return {string} - * @default [class SoundMixer] + * @default "[class SoundMixer]" * @method * @static */ @@ -39,7 +45,7 @@ export class SoundMixer * Returns the space name of the specified class. * * @return {string} - * @default next2d.media.SoundMixer + * @default "next2d.media.SoundMixer" * @const * @static */ @@ -53,7 +59,7 @@ export class SoundMixer * Returns the string representation of the specified object. * * @return {string} - * @default [object SoundMixer] + * @default "[object SoundMixer]" * @method * @public */ @@ -67,7 +73,7 @@ export class SoundMixer * Returns the space name of the specified object. * * @return {string} - * @default next2d.media.SoundMixer + * @default "next2d.media.SoundMixer" * @const * @public */ @@ -86,13 +92,11 @@ export class SoundMixer */ static get volume (): number { - return $getSoundMixerVolume(); + return $volume; } static set volume (volume: number) { - $setSoundMixerVolume($clamp(volume, 0, 1, 1)); - - const soundMixerVolume = $getSoundMixerVolume(); + $volume = Math.min(Math.max(0, volume), 1); const player: Player = $currentPlayer(); @@ -107,7 +111,7 @@ export class SoundMixer if (source._$gainNode) { source._$gainNode.gain.value = $Math.min( - soundMixerVolume, + $volume, source._$volume ); } @@ -122,7 +126,7 @@ export class SoundMixer if (video._$video) { video._$video.volume = $Math.min( - soundMixerVolume, + $volume, video.volume ); } diff --git a/packages/media/src/SoundTransform.test.ts b/packages/media/src/SoundTransform.test.ts new file mode 100644 index 00000000..93927add --- /dev/null +++ b/packages/media/src/SoundTransform.test.ts @@ -0,0 +1,67 @@ +import { SoundTransform } from "./SoundTransform"; +import { describe, expect, it } from "vitest"; + +describe("SoundTransform.js namespace test", () => +{ + it("namespace test public", () => + { + const soundTransform = new SoundTransform(); + expect(soundTransform.namespace).toBe("next2d.media.SoundTransform"); + }); + + it("namespace test static", () => + { + expect(SoundTransform.namespace).toBe("next2d.media.SoundTransform"); + }); +}); + +describe("SoundTransform.js toString test", () => +{ + it("toString test success", () => + { + expect(new SoundTransform().toString()).toBe("[object SoundTransform]"); + }); +}); + +describe("SoundTransform.js static toString test", () => +{ + it("static toString test", () => + { + expect(SoundTransform.toString()).toBe("[class SoundTransform]"); + }); +}); + +describe("SoundTransform.js property test", () => +{ + it("volume test case1", () => + { + const soundTransform = new SoundTransform(); + expect(soundTransform.volume).toBe(1); + }); + + it("volume test case2", () => + { + const soundTransform = new SoundTransform(); + soundTransform.volume = 100; + expect(soundTransform.volume).toBe(1); + }); + + it("volume test case3", () => + { + const soundTransform = new SoundTransform(); + soundTransform.volume = -32; + expect(soundTransform.volume).toBe(0); + }); + + it("volume test case4", () => + { + const soundTransform = new SoundTransform(100); + expect(soundTransform.volume).toBe(1); + }); + + it("volume test case5", () => + { + const soundTransform = new SoundTransform(-32); + expect(soundTransform.volume).toBe(0); + }); +}); \ No newline at end of file diff --git a/packages/media/src/SoundTransform.ts b/packages/media/src/SoundTransform.ts index 5fc7fafb..7961dec6 100644 --- a/packages/media/src/SoundTransform.ts +++ b/packages/media/src/SoundTransform.ts @@ -1,9 +1,6 @@ -import { $clamp } from "@next2d/share"; - /** - * SoundTransform クラスにはボリュームとループのプロパティが含まれます。 - * - * The SoundTransform class contains properties for volume and loop. + * @description SoundTransform クラスにはボリュームとループのプロパティが含まれます。 + * The SoundTransform class contains properties for volume and loop. * * @class * @memberOf next2d.media @@ -28,17 +25,14 @@ export class SoundTransform * @private */ this._$volume = 1; + this.volume = volume; /** * @type {boolean} * @default false * @private */ - this._$loop = false; - - // setup - this.volume = volume; - this.loop = loop; + this._$loop = !!loop; } /** @@ -46,7 +40,7 @@ export class SoundTransform * Returns the string representation of the specified class. * * @return {string} - * @default [class SoundTransform] + * @default "[class SoundTransform]" * @method * @static */ @@ -60,7 +54,7 @@ export class SoundTransform * Returns the space name of the specified class. * * @return {string} - * @default next2d.media.SoundTransform + * @default "next2d.media.SoundTransform" * @const * @static */ @@ -74,7 +68,7 @@ export class SoundTransform * Returns the string representation of the specified object. * * @return {string} - * @default [object SoundTransform] + * @default "[object SoundTransform]" * @method * @public */ @@ -88,7 +82,7 @@ export class SoundTransform * Returns the space name of the specified object. * * @return {string} - * @default next2d.media.SoundTransform + * @default "next2d.media.SoundTransform" * @const * @public */ @@ -111,7 +105,7 @@ export class SoundTransform } set loop (loop: boolean) { - this._$loop = loop; + this._$loop = !!loop; } /** @@ -128,6 +122,6 @@ export class SoundTransform } set volume (volume: number) { - this._$volume = $clamp(+volume, 0, 1, 0); + this._$volume = Math.min(Math.max(0, volume), 1); } } diff --git a/packages/net/package.json b/packages/net/package.json index 321d0c10..0aa025a6 100644 --- a/packages/net/package.json +++ b/packages/net/package.json @@ -24,9 +24,5 @@ "repository": { "type": "git", "url": "git+https://github.com/Next2D/Player.git" - }, - "peerDependencies": { - "@next2d/core": "file:../core", - "@next2d/util": "file:../util" } } diff --git a/packages/net/src/URLRequest.test.ts b/packages/net/src/URLRequest.test.ts new file mode 100644 index 00000000..54bd0c22 --- /dev/null +++ b/packages/net/src/URLRequest.test.ts @@ -0,0 +1,94 @@ +import { URLRequest } from "./URLRequest"; +import { describe, expect, it } from "vitest"; + +describe("URLRequest.js toString test", () => +{ + it("toString test success", () => + { + expect(new URLRequest().toString()).toBe("[object URLRequest]"); + }); +}); + +describe("URLRequest.js static toString test", () => +{ + it("static toString test", () => + { + expect(`${URLRequest}`).toBe("[class URLRequest]"); + }); +}); + +describe("URLRequest.js namespace test", () => +{ + it("namespace test public", () => + { + const object = new URLRequest(); + expect(object.namespace).toBe("next2d.net.URLRequest"); + }); + + it("namespace test static", () => + { + expect(URLRequest.namespace).toBe("next2d.net.URLRequest"); + }); +}); + +describe("URLRequest.js properties test", () => +{ + it("contentType case1", () => + { + const urlRequest = new URLRequest(); + expect(urlRequest.contentType).toBe("application/json"); + urlRequest.contentType = "text/html; charset=utf-8"; + expect(urlRequest.contentType).toBe("text/html; charset=utf-8"); + }); + + it("data test case1", () => + { + const urlRequest = new URLRequest(); + expect(urlRequest.data).toBe(null); + urlRequest.data = "data"; + expect(urlRequest.data).toBe("data"); + }); + + it("data test case2", () => + { + const urlRequest = new URLRequest(); + expect(urlRequest.data).toBe(null); + urlRequest.data = 0; + expect(urlRequest.data).toBe(0); + }); + + it("method test case1", () => + { + const urlRequest = new URLRequest(); + expect(urlRequest.method).toBe("GET"); + urlRequest.method = "POST"; + expect(urlRequest.method).toBe("POST"); + }); + + it("requestHeaders test case1", () => + { + const urlRequest = new URLRequest(); + expect(urlRequest.requestHeaders.length).toBe(0); + + urlRequest.requestHeaders = [{ + "name": "test", + "value": "aaa" + }]; + + expect(urlRequest.requestHeaders.length).toBe(1); + for (let i = 0; urlRequest.requestHeaders.length > i; i++) { + const requestHeader = urlRequest.requestHeaders[i]; + expect(requestHeader.name).toBe("test"); + expect(requestHeader.value).toBe("aaa"); + } + }); + + it("url test case1", () => + { + const urlRequest = new URLRequest(); + expect(urlRequest.url).toBe(""); + urlRequest.url = "http://test.com"; + expect(urlRequest.url).toBe("http://test.com"); + }); + +}); diff --git a/packages/net/src/URLRequest.ts b/packages/net/src/URLRequest.ts index 3b346547..5f78aa98 100644 --- a/packages/net/src/URLRequest.ts +++ b/packages/net/src/URLRequest.ts @@ -1,12 +1,10 @@ import type { URLRequestHeaderImpl } from "./interface/URLRequestHeaderImpl"; import type { URLLoaderDataFormatImpl } from "./interface/URLLoaderDataFormatImpl"; import type { URLRequestMethodImpl } from "./interface/URLRequestMethodImpl"; -import type { Player } from "@next2d/core"; -import { $currentPlayer } from "@next2d/util"; /** - * URLRequestクラスは、外部へのリクエストを管理するクラスです - * The URLRequest class is a class that manages external requests + * @description URLRequestクラスは、外部へのリクエストを管理するクラスです + * The URLRequest class is a class that manages external requests * * @class * @memberOf next2d.net @@ -15,7 +13,7 @@ export class URLRequest { private _$url: string; private _$contentType: string; - private _$data: string; + private _$data: any; private _$method: URLRequestMethodImpl; private readonly _$requestHeaders: URLRequestHeaderImpl[]; private _$responseDataFormat: URLLoaderDataFormatImpl; @@ -44,11 +42,11 @@ export class URLRequest this._$contentType = "application/json"; /** - * @type {string} - * @default "" + * @type {any} + * @default null * @private */ - this._$data = ""; + this._$data = null; /** * @type {string} @@ -210,19 +208,6 @@ export class URLRequest */ get url (): string { - if (this._$url && this._$url.indexOf("//") === -1) { - - const urls: string [] = this._$url.split("/"); - if (urls[0] === "" || urls[0] === ".") { - urls.shift(); - } - - const player: Player = $currentPlayer(); - if (player) { - return `${player.base}${urls.join("/")}`; - } - } - return this._$url; } set url (url: string) From 52ca1c550bc13034c49ed30603b5b3af4510169b Mon Sep 17 00:00:00 2001 From: ienaga Date: Fri, 26 Jul 2024 09:11:44 +0900 Subject: [PATCH 017/343] =?UTF-8?q?#154=20feat:=20WebGL=E3=81=AE=E3=83=91?= =?UTF-8?q?=E3=83=83=E3=82=B1=E3=83=BC=E3=82=B8=E3=82=92=E7=A7=BB=E8=A1=8C?= =?UTF-8?q?(WIP)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/webgl/package.json | 3 - packages/webgl/src/BezierConverter.ts | 4 +- packages/webgl/src/CanvasGradientToWebGL.ts | 2 +- packages/webgl/src/CanvasToWebGLContext.ts | 67 ++-- .../webgl/src/CanvasToWebGLContextBlend.ts | 50 ++- .../webgl/src/CanvasToWebGLContextGrid.ts | 13 +- .../webgl/src/CanvasToWebGLContextMask.ts | 4 +- .../webgl/src/CanvasToWebGLContextPath.ts | 2 +- .../webgl/src/CanvasToWebGLContextStyle.ts | 9 +- packages/webgl/src/ColorBufferPool.ts | 15 +- packages/webgl/src/Const.ts | 16 - packages/webgl/src/FrameBufferManager.ts | 11 +- packages/webgl/src/StencilBufferPool.ts | 4 +- packages/webgl/src/TextureManager.ts | 2 +- .../webgl/src/VertexArrayObjectManager.ts | 4 +- packages/webgl/src/WebGLFillMeshGenerator.ts | 7 +- .../webgl/src/WebGLStrokeMeshGenerator.ts | 13 +- packages/webgl/src/WebGLUtil.ts | 310 ++++++++++++++++++ .../webgl/src/shader/CanvasToWebGLShader.ts | 6 +- .../webgl/src/shader/GradientLUTGenerator.ts | 9 +- .../webgl/src/shader/WebGLShaderInstance.ts | 1 - .../webgl/src/shader/WebGLShaderUniform.ts | 13 +- .../FragmentShaderSourceGradientLUT.ts | 6 +- .../FragmentShaderSourceConvolutionFilter.ts | 7 +- .../filter/FragmentShaderSourceFilter.ts | 5 +- .../variants/BlendShaderVariantCollection.ts | 5 +- .../variants/FilterShaderVariantCollection.ts | 10 +- .../GradientLUTShaderVariantCollection.ts | 8 +- .../GradientShapeShaderVariantCollection.ts | 3 +- .../variants/ShapeShaderVariantCollection.ts | 3 +- 30 files changed, 431 insertions(+), 181 deletions(-) delete mode 100644 packages/webgl/src/Const.ts create mode 100644 packages/webgl/src/WebGLUtil.ts diff --git a/packages/webgl/package.json b/packages/webgl/package.json index d25f75cb..ff929d6c 100644 --- a/packages/webgl/package.json +++ b/packages/webgl/package.json @@ -24,8 +24,5 @@ "repository": { "type": "git", "url": "git+https://github.com/Next2D/Player.git" - }, - "peerDependencies": { - "@next2d/share": "file:../share" } } diff --git a/packages/webgl/src/BezierConverter.ts b/packages/webgl/src/BezierConverter.ts index d3d5f38d..cc899048 100644 --- a/packages/webgl/src/BezierConverter.ts +++ b/packages/webgl/src/BezierConverter.ts @@ -1,5 +1,3 @@ -import { $Float32Array } from "@next2d/share"; - /** * @class */ @@ -13,7 +11,7 @@ export class BezierConverter */ constructor () { - this._$bezierConverterBuffer = new $Float32Array(32); + this._$bezierConverterBuffer = new Float32Array(32); } /** diff --git a/packages/webgl/src/CanvasGradientToWebGL.ts b/packages/webgl/src/CanvasGradientToWebGL.ts index 19ad0489..486e270a 100644 --- a/packages/webgl/src/CanvasGradientToWebGL.ts +++ b/packages/webgl/src/CanvasGradientToWebGL.ts @@ -7,7 +7,7 @@ import { $clamp, $poolInt32Array4, $poolFloat32Array6 -} from "@next2d/share"; +} from "./WebGLUtil"; /** * @class diff --git a/packages/webgl/src/CanvasToWebGLContext.ts b/packages/webgl/src/CanvasToWebGLContext.ts index d39e0627..8c69b8c9 100644 --- a/packages/webgl/src/CanvasToWebGLContext.ts +++ b/packages/webgl/src/CanvasToWebGLContext.ts @@ -10,7 +10,6 @@ import { CanvasToWebGLContextBlend } from "./CanvasToWebGLContextBlend"; import { CanvasPatternToWebGL } from "./CanvasPatternToWebGL"; import { CanvasGradientToWebGL } from "./CanvasGradientToWebGL"; import { WebGLFillMeshGenerator } from "./WebGLFillMeshGenerator"; -import { $setRenderSize } from "./Const"; import type { CanvasToWebGLShader } from "./shader/CanvasToWebGLShader"; import type { GradientShapeShaderVariantCollection } from "./shader/variants/GradientShapeShaderVariantCollection"; import type { ShapeShaderVariantCollection } from "./shader/variants/ShapeShaderVariantCollection"; @@ -29,16 +28,14 @@ import type { CapsStyleImpl } from "./interface/CapsStyleImpl"; import type { JointStyleImpl } from "./interface/JointStyleImpl"; import type { CachePositionImpl } from "./interface/CachePositionImpl"; import { - $Math, + $setRenderSize, $getFloat32Array9, $getArray, $clamp, $poolArray, $inverseMatrix, - $poolFloat32Array9, - $poolBoundsObject, - $getBoundsObject -} from "@next2d/share"; + $poolFloat32Array9 +} from "./WebGLUtil"; /** * @class @@ -98,7 +95,7 @@ export class CanvasToWebGLContext * @type {number} * @private */ - const samples: number = $Math.min( + const samples: number = Math.min( sample, gl.getParameter(gl.MAX_SAMPLES) ); @@ -107,7 +104,7 @@ export class CanvasToWebGLContext * @type {number} * @private */ - this._$maxTextureSize = $Math.min(8192, + this._$maxTextureSize = Math.min(8192, gl.getParameter(gl.MAX_TEXTURE_SIZE) ) - 2; @@ -121,7 +118,12 @@ export class CanvasToWebGLContext * @type {BoundsImpl} * @private */ - this._$cacheBounds = $getBoundsObject(); + this._$cacheBounds = { + "xMin": 0, + "yMin": 0, + "xMax": 0, + "yMax": 0 + }; /** * @type {Float32Array} @@ -296,7 +298,12 @@ export class CanvasToWebGLContext * @type {object} * @private */ - this._$maskBounds = $getBoundsObject(0, 0, 0, 0); + this._$maskBounds = { + "xMin": 0, + "yMin": 0, + "xMax": 0, + "yMax": 0 + }; /** * @type {object} @@ -575,7 +582,7 @@ export class CanvasToWebGLContext */ _$getTextureScale (width: number, height: number): number { - const maxSize = $Math.max(width, height); + const maxSize = Math.max(width, height); if (maxSize > this._$maxTextureSize) { return this._$maxTextureSize / maxSize; } @@ -1462,10 +1469,10 @@ export class CanvasToWebGLContext return false; } - this._$maskBounds.xMin = $Math.max(0, $Math.min(this._$maskBounds.xMin, x)); - this._$maskBounds.yMin = $Math.max(0, $Math.min(this._$maskBounds.yMin, y)); - this._$maskBounds.xMax = $Math.min(currentAttachment.width, $Math.min(this._$maskBounds.xMax, width)); - this._$maskBounds.yMax = $Math.min(currentAttachment.height, $Math.min(this._$maskBounds.yMax, height)); + this._$maskBounds.xMin = Math.max(0, Math.min(this._$maskBounds.xMin, x)); + this._$maskBounds.yMin = Math.max(0, Math.min(this._$maskBounds.yMin, y)); + this._$maskBounds.xMax = Math.min(currentAttachment.width, Math.min(this._$maskBounds.xMax, width)); + this._$maskBounds.yMax = Math.min(currentAttachment.height, Math.min(this._$maskBounds.yMax, height)); return true; } @@ -1550,9 +1557,9 @@ export class CanvasToWebGLContext const strokeStyle: Float32Array|CanvasGradientToWebGL|CanvasPatternToWebGL = this.strokeStyle; - let face: number = $Math.sign(matrix[0] * matrix[4]); + let face: number = Math.sign(matrix[0] * matrix[4]); if (face > 0 && matrix[1] !== 0 && matrix[3] !== 0) { - face = -$Math.sign(matrix[1] * matrix[3]); + face = -Math.sign(matrix[1] * matrix[3]); } let lineWidth: number = this.lineWidth * 0.5; @@ -1560,17 +1567,17 @@ export class CanvasToWebGLContext let scaleY: number; if (this._$grid.enabled) { // lineWidth *= $getSameScaleBase(); - scaleX = $Math.abs(this._$grid.ancestorMatrixA + this._$grid.ancestorMatrixD); - scaleY = $Math.abs(this._$grid.ancestorMatrixB + this._$grid.ancestorMatrixE); + scaleX = Math.abs(this._$grid.ancestorMatrixA + this._$grid.ancestorMatrixD); + scaleY = Math.abs(this._$grid.ancestorMatrixB + this._$grid.ancestorMatrixE); } else { - scaleX = $Math.abs(matrix[0] + matrix[3]); - scaleY = $Math.abs(matrix[1] + matrix[4]); + scaleX = Math.abs(matrix[0] + matrix[3]); + scaleY = Math.abs(matrix[1] + matrix[4]); } - const scaleMin: number = $Math.min(scaleX, scaleY); - const scaleMax: number = $Math.max(scaleX, scaleY); - lineWidth *= scaleMax * (1 - 0.3 * $Math.cos($Math.PI * 0.5 * (scaleMin / scaleMax))); - lineWidth = $Math.max(1, lineWidth); + const scaleMin: number = Math.min(scaleX, scaleY); + const scaleMax: number = Math.max(scaleX, scaleY); + lineWidth *= scaleMax * (1 - 0.3 * Math.cos(Math.PI * 0.5 * (scaleMin / scaleMax))); + lineWidth = Math.max(1, lineWidth); const hasGrid: boolean = this._$grid.enabled; @@ -1903,7 +1910,7 @@ export class CanvasToWebGLContext .textureManager .bind0(texture, true); - const halfBlur: number = $Math.ceil(blur * 0.5); + const halfBlur: number = Math.ceil(blur * 0.5); const fraction: number = 1 - (halfBlur - blur * 0.5); const samples: number = 1 + blur; @@ -2267,11 +2274,7 @@ export class CanvasToWebGLContext */ _$endLayer (): void { - const bounds: BoundsImpl | void = this._$positions.pop(); - if (bounds) { - $poolBoundsObject(bounds); - } - + this._$positions.pop(); this._$isLayer = !!this._$blends.pop(); } @@ -2340,7 +2343,7 @@ export class CanvasToWebGLContext */ textureScale (width: number, height: number): number { - const maxSize = $Math.max(width, height); + const maxSize = Math.max(width, height); if (maxSize > this._$maxTextureSize) { return this._$maxTextureSize / maxSize; } diff --git a/packages/webgl/src/CanvasToWebGLContextBlend.ts b/packages/webgl/src/CanvasToWebGLContextBlend.ts index bac6c241..5282ece6 100644 --- a/packages/webgl/src/CanvasToWebGLContextBlend.ts +++ b/packages/webgl/src/CanvasToWebGLContextBlend.ts @@ -7,11 +7,7 @@ import type { BlendShaderVariantCollection } from "./shader/variants/BlendShader import type { BlendModeImpl } from "./interface/BlendModeImpl"; import type { AttachmentImpl } from "./interface/AttachmentImpl"; import type { CachePositionImpl } from "./interface/CachePositionImpl"; -import { - $Math, - $Number, - $inverseMatrix -} from "@next2d/share"; +import { $inverseMatrix } from "./WebGLUtil"; /** * @class @@ -481,8 +477,8 @@ export class CanvasToWebGLContextBlend withCT, ct0, ct1, ct2, ct3, ct4, ct5, ct6, ct7 ); - const width: number = $Math.abs(x_max - x_min); - const height: number = $Math.abs(y_max - y_min); + const width: number = Math.abs(x_max - x_min); + const height: number = Math.abs(y_max - y_min); this._$gl.enable(this._$gl.SCISSOR_TEST); this._$gl.scissor(x_min, render_height - (y_min + height), width, height); @@ -578,37 +574,37 @@ export class CanvasToWebGLContextBlend const y2: number = +(left * b + bottom * d + ty); const y3: number = +(left * b + top * d + ty); - const no: number = $Number.MAX_VALUE; - const xMin: number = +$Math.min($Math.min($Math.min($Math.min( no, x0), x1), x2), x3); - const xMax: number = +$Math.max($Math.max($Math.max($Math.max(-no, x0), x1), x2), x3); - const yMin: number = +$Math.min($Math.min($Math.min($Math.min( no, y0), y1), y2), y3); - const yMax: number = +$Math.max($Math.max($Math.max($Math.max(-no, y0), y1), y2), y3); + const no: number = Number.MAX_VALUE; + const xMin: number = +Math.min(Math.min(Math.min(Math.min( no, x0), x1), x2), x3); + const xMax: number = +Math.max(Math.max(Math.max(Math.max(-no, x0), x1), x2), x3); + const yMin: number = +Math.min(Math.min(Math.min(Math.min( no, y0), y1), y2), y3); + const yMax: number = +Math.max(Math.max(Math.max(Math.max(-no, y0), y1), y2), y3); - const sx: number = $Math.max(0, xMin); - const sy: number = $Math.max(0, yMin); - const sw: number = $Math.min($Math.max(0, renderWidth - sx), $Math.ceil($Math.abs(xMax - xMin))); - const sh: number = $Math.min($Math.max(0, renderHeight - sy), $Math.ceil($Math.abs(yMax - yMin))); + const sx: number = Math.max(0, xMin); + const sy: number = Math.max(0, yMin); + const sw: number = Math.min(Math.max(0, renderWidth - sx), Math.ceil(Math.abs(xMax - xMin))); + const sh: number = Math.min(Math.max(0, renderHeight - sy), Math.ceil(Math.abs(yMax - yMin))); if (!sw || !sh) { return ; } this._$gl.enable(this._$gl.SCISSOR_TEST); - this._$gl.scissor(sx, $Math.max(0, renderHeight - (sy + sh)), sw + 1, sh + 1); + this._$gl.scissor(sx, Math.max(0, renderHeight - (sy + sh)), sw + 1, sh + 1); } else { - const sx: number = $Math.max(0, x + tx); - const sy: number = $Math.max(0, y + ty); - const sw: number = $Math.min($Math.max(0, renderWidth - sx), w); - const sh: number = $Math.min($Math.max(0, renderHeight - sy), h); + const sx: number = Math.max(0, x + tx); + const sy: number = Math.max(0, y + ty); + const sw: number = Math.min(Math.max(0, renderWidth - sx), w); + const sh: number = Math.min(Math.max(0, renderHeight - sy), h); if (!sw || !sh) { return ; } this._$gl.enable(this._$gl.SCISSOR_TEST); - this._$gl.scissor(sx, $Math.max(0, renderHeight - (sy + sh)), sw + 1, sh + 1); + this._$gl.scissor(sx, Math.max(0, renderHeight - (sy + sh)), sw + 1, sh + 1); } this.toOperation(operation); @@ -620,10 +616,10 @@ export class CanvasToWebGLContextBlend default: { - const sx: number = $Math.max(0, x + matrix[6]); - const sy: number = $Math.max(0, y + matrix[7]); - const sw: number = $Math.min($Math.max(0, renderWidth - sx), w); - const sh: number = $Math.min($Math.max(0, renderHeight - sy), h); + const sx: number = Math.max(0, x + matrix[6]); + const sy: number = Math.max(0, y + matrix[7]); + const sw: number = Math.min(Math.max(0, renderWidth - sx), w); + const sh: number = Math.min(Math.max(0, renderHeight - sy), h); if (!sw || !sh) { return ; @@ -667,7 +663,7 @@ export class CanvasToWebGLContextBlend ); this._$gl.enable(this._$gl.SCISSOR_TEST); - this._$gl.scissor(sx, $Math.max(0, renderHeight - (sy + sh)), sw, sh); + this._$gl.scissor(sx, Math.max(0, renderHeight - (sy + sh)), sw, sh); this.toOneZero(); shader._$drawImage(); diff --git a/packages/webgl/src/CanvasToWebGLContextGrid.ts b/packages/webgl/src/CanvasToWebGLContextGrid.ts index 4ae654a1..73a3e3e7 100644 --- a/packages/webgl/src/CanvasToWebGLContextGrid.ts +++ b/packages/webgl/src/CanvasToWebGLContextGrid.ts @@ -1,6 +1,5 @@ import type { BoundsImpl } from "./interface/BoundsImpl"; import type { GridImpl } from "./interface/GridImpl"; -import { $Math } from "@next2d/share"; /** * @class @@ -301,8 +300,8 @@ export class CanvasToWebGLContextGrid const gridWidth: number = grid.w; const gridHeight: number = grid.h; - const sameWidth: number = $Math.abs($Math.ceil(boundsWidth * same_scale)); - const sameHeight: number = $Math.abs($Math.ceil(boundsHeight * same_scale)); + const sameWidth: number = Math.abs(Math.ceil(boundsWidth * same_scale)); + const sameHeight: number = Math.abs(Math.ceil(boundsHeight * same_scale)); // 等倍サイズでの正規化grid const minXST: number = gridWidth > 0 ? (grid.x - bounds.xMin) / boundsWidth : 0.00001; @@ -318,14 +317,14 @@ export class CanvasToWebGLContextGrid if (minXPQ >= maxXPQ) { const m: number = minXST / (minXST + (1 - maxXST)); - minXPQ = $Math.max(m - 0.00001, 0); - maxXPQ = $Math.min(m + 0.00001, 1); + minXPQ = Math.max(m - 0.00001, 0); + maxXPQ = Math.min(m + 0.00001, 1); } if (minYPQ >= maxYPQ) { const m: number = minYST / (minYST + (1 - maxYST)); - minYPQ = $Math.max(m - 0.00001, 0); - maxYPQ = $Math.min(m + 0.00001, 1); + minYPQ = Math.max(m - 0.00001, 0); + maxYPQ = Math.min(m + 0.00001, 1); } this.enabled = true; diff --git a/packages/webgl/src/CanvasToWebGLContextMask.ts b/packages/webgl/src/CanvasToWebGLContextMask.ts index e3cabd8f..29485e33 100644 --- a/packages/webgl/src/CanvasToWebGLContextMask.ts +++ b/packages/webgl/src/CanvasToWebGLContextMask.ts @@ -1,4 +1,3 @@ -import { WebGLFillMeshGenerator } from "./WebGLFillMeshGenerator"; import type { CanvasToWebGLContext } from "./CanvasToWebGLContext"; import type { ShapeShaderVariantCollection } from "./shader/variants/ShapeShaderVariantCollection"; import type { CanvasToWebGLShader } from "./shader/CanvasToWebGLShader"; @@ -6,7 +5,8 @@ import type { WebGLShaderUniform } from "./shader/WebGLShaderUniform"; import type { AttachmentImpl } from "./interface/AttachmentImpl"; import type { ClipObjectImpl } from "./interface/ClipObjectImpl"; import type { IndexRangeImpl } from "./interface/IndexRangeImpl"; -import { $poolArray } from "@next2d/share"; +import { WebGLFillMeshGenerator } from "./WebGLFillMeshGenerator"; +import { $poolArray } from "./WebGLUtil"; /** * @class diff --git a/packages/webgl/src/CanvasToWebGLContextPath.ts b/packages/webgl/src/CanvasToWebGLContextPath.ts index 93d034e7..f0e4703a 100644 --- a/packages/webgl/src/CanvasToWebGLContextPath.ts +++ b/packages/webgl/src/CanvasToWebGLContextPath.ts @@ -3,7 +3,7 @@ import type { VerticesImpl } from "./interface/VerticesImpl"; import { $getArray, $poolArray -} from "@next2d/share"; +} from "./WebGLUtil"; /** * @class diff --git a/packages/webgl/src/CanvasToWebGLContextStyle.ts b/packages/webgl/src/CanvasToWebGLContextStyle.ts index 2a14f3fe..f735b1c1 100644 --- a/packages/webgl/src/CanvasToWebGLContextStyle.ts +++ b/packages/webgl/src/CanvasToWebGLContextStyle.ts @@ -4,9 +4,8 @@ import type { CapsStyleImpl } from "./interface/CapsStyleImpl"; import type { JointStyleImpl } from "./interface/JointStyleImpl"; import { $getFloat32Array4, - $poolFloat32Array4, - $Float32Array -} from "@next2d/share"; + $poolFloat32Array4 +} from "./WebGLUtil"; /** * @class @@ -100,7 +99,7 @@ export class CanvasToWebGLContextStyle } set fillStyle (style: Float32Array|CanvasGradientToWebGL|CanvasPatternToWebGL) { - if (this._$fillStyle instanceof $Float32Array) { + if (this._$fillStyle instanceof Float32Array) { $poolFloat32Array4(this._$fillStyle); } this._$fillStyle = style; @@ -116,7 +115,7 @@ export class CanvasToWebGLContextStyle } set strokeStyle (style: Float32Array|CanvasGradientToWebGL|CanvasPatternToWebGL) { - if (this._$strokeStyle instanceof $Float32Array) { + if (this._$strokeStyle instanceof Float32Array) { $poolFloat32Array4(this._$strokeStyle); } this._$strokeStyle = style; diff --git a/packages/webgl/src/ColorBufferPool.ts b/packages/webgl/src/ColorBufferPool.ts index ca8d83d4..2927ef74 100644 --- a/packages/webgl/src/ColorBufferPool.ts +++ b/packages/webgl/src/ColorBufferPool.ts @@ -1,8 +1,7 @@ import { $getArray, - $Math, $upperPowerOfTwo -} from "@next2d/share"; +} from "./WebGLUtil"; /** * @class @@ -103,8 +102,8 @@ export class ColorBufferPool ): WebGLRenderbuffer { // 128以下で描画崩れが発生する場合がある?ため、256を最小サイズにする - width = $Math.max(256, $upperPowerOfTwo(width)); - height = $Math.max(256, $upperPowerOfTwo(height)); + width = Math.max(256, $upperPowerOfTwo(width)); + height = Math.max(256, $upperPowerOfTwo(height)); const colorBuffer: WebGLRenderbuffer = this._$getColorBuffer(width * height); @@ -117,8 +116,8 @@ export class ColorBufferPool || colorBuffer.samples !== samples ) { - width = $Math.max(width, colorBuffer.width); - height = $Math.max(height, colorBuffer.height); + width = Math.max(width, colorBuffer.width); + height = Math.max(height, colorBuffer.height); colorBuffer.samples = samples; colorBuffer.width = width; @@ -173,8 +172,8 @@ export class ColorBufferPool let ng: number = -1; let ok: number = this._$objectPool.length; - while ($Math.abs(ok - ng) > 1) { - const mid: number = $Math.floor((ok + ng) / 2); + while (Math.abs(ok - ng) > 1) { + const mid: number = Math.floor((ok + ng) / 2); if (area <= this._$objectPool[mid].area) { ok = mid; } else { diff --git a/packages/webgl/src/Const.ts b/packages/webgl/src/Const.ts deleted file mode 100644 index 64a7a362..00000000 --- a/packages/webgl/src/Const.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @type {number} - * @public - */ -export let $RENDER_SIZE: number = 2048; - -/** - * @param {number} size - * @return {void} - * @method - * @public - */ -export const $setRenderSize = (size: number): void => -{ - $RENDER_SIZE = Math.min(4096, size / 2); -}; \ No newline at end of file diff --git a/packages/webgl/src/FrameBufferManager.ts b/packages/webgl/src/FrameBufferManager.ts index 07bdbf4d..5f5a0816 100644 --- a/packages/webgl/src/FrameBufferManager.ts +++ b/packages/webgl/src/FrameBufferManager.ts @@ -1,8 +1,7 @@ import { TextureManager } from "./TextureManager"; import { StencilBufferPool } from "./StencilBufferPool"; import { ColorBufferPool } from "./ColorBufferPool"; -import { $Math } from "@next2d/share"; -import { $RENDER_SIZE } from "./Const"; +import { $RENDER_SIZE } from "./WebGLUtil"; import type { AttachmentImpl } from "./interface/AttachmentImpl"; import type { CachePositionImpl } from "./interface/CachePositionImpl"; @@ -506,10 +505,10 @@ export class FrameBufferManager this._$gl.TEXTURE_2D, texture, 0 ); - const x0: number = $Math.max(0, position.x - 1); - const y0: number = $Math.max(0, position.y - 1); - const x1: number = $Math.min($RENDER_SIZE, position.x + position.w + 1); - const y1: number = $Math.min($RENDER_SIZE, position.y + position.h + 1); + const x0: number = Math.max(0, position.x - 1); + const y0: number = Math.max(0, position.y - 1); + const x1: number = Math.min($RENDER_SIZE, position.x + position.w + 1); + const y1: number = Math.min($RENDER_SIZE, position.y + position.h + 1); this._$gl.blitFramebuffer( x0, y0, x1, y1, diff --git a/packages/webgl/src/StencilBufferPool.ts b/packages/webgl/src/StencilBufferPool.ts index 582b40d7..47fea134 100644 --- a/packages/webgl/src/StencilBufferPool.ts +++ b/packages/webgl/src/StencilBufferPool.ts @@ -1,5 +1,3 @@ -import { $getArray } from "@next2d/share"; - /** * @class */ @@ -27,7 +25,7 @@ export class StencilBufferPool * @type {array} * @private */ - this._$objectPool = $getArray(); + this._$objectPool = []; /** * @type {number} diff --git a/packages/webgl/src/TextureManager.ts b/packages/webgl/src/TextureManager.ts index f64f8281..0589f941 100644 --- a/packages/webgl/src/TextureManager.ts +++ b/packages/webgl/src/TextureManager.ts @@ -1,4 +1,4 @@ -import { $RENDER_SIZE } from "./Const"; +import { $RENDER_SIZE } from "./WebGLUtil"; import type { CachePositionImpl } from "./interface/CachePositionImpl"; import type { GridImpl } from "./interface/GridImpl"; diff --git a/packages/webgl/src/VertexArrayObjectManager.ts b/packages/webgl/src/VertexArrayObjectManager.ts index 8caf8a78..5ae171c0 100644 --- a/packages/webgl/src/VertexArrayObjectManager.ts +++ b/packages/webgl/src/VertexArrayObjectManager.ts @@ -5,9 +5,7 @@ import type { StrokeMethImpl } from "./interface/StrokeMethImpl"; import type { CapsStyleImpl } from "./interface/CapsStyleImpl"; import type { JointStyleImpl } from "./interface/JointStyleImpl"; import type { WebGLShaderInstance } from "./shader/WebGLShaderInstance"; -import { - $upperPowerOfTwo -} from "@next2d/share"; +import { $upperPowerOfTwo } from "./WebGLUtil"; /** * @class diff --git a/packages/webgl/src/WebGLFillMeshGenerator.ts b/packages/webgl/src/WebGLFillMeshGenerator.ts index fa00f54c..64293c89 100644 --- a/packages/webgl/src/WebGLFillMeshGenerator.ts +++ b/packages/webgl/src/WebGLFillMeshGenerator.ts @@ -1,9 +1,6 @@ import type { FillMeshImpl } from "./interface/FillMeshImpl"; import type { IndexRangeImpl } from "./interface/IndexRangeImpl"; -import { - $Float32Array, - $getArray -} from "@next2d/share"; +import { $getArray } from "./WebGLUtil"; /** * @class @@ -37,7 +34,7 @@ export class WebGLFillMeshGenerator vertexBufferLen += (vertices[idx].length / 3 - 2) * 12; } - this._$vertexBufferData = new $Float32Array(vertexBufferLen); + this._$vertexBufferData = new Float32Array(vertexBufferLen); this._$indexRanges = $getArray(); this._$currentIndex = 0; diff --git a/packages/webgl/src/WebGLStrokeMeshGenerator.ts b/packages/webgl/src/WebGLStrokeMeshGenerator.ts index 48c9286e..1508d89e 100644 --- a/packages/webgl/src/WebGLStrokeMeshGenerator.ts +++ b/packages/webgl/src/WebGLStrokeMeshGenerator.ts @@ -1,11 +1,6 @@ import type { StrokeMethImpl } from "./interface/StrokeMethImpl"; import type { JointStyleImpl } from "./interface/JointStyleImpl"; import type { CapsStyleImpl } from "./interface/CapsStyleImpl"; -import { - $Float32Array, - $Int16Array, - $Math -} from "@next2d/share"; /** * @class @@ -33,7 +28,7 @@ export class WebGLStrokeMeshGenerator line_join: JointStyleImpl ): StrokeMethImpl { - this._$vertexBufferData = this._$vertexBufferData || new $Float32Array(1024); + this._$vertexBufferData = this._$vertexBufferData || new Float32Array(1024); this._$vertexBufferPos = 0; this._$indexBufferData = this._$indexBufferData || new Int16Array(256); @@ -68,7 +63,7 @@ export class WebGLStrokeMeshGenerator static _$expandVertexBufferIfNeeded (delta_length: number): void { if (this._$vertexBufferPos + delta_length > this._$vertexBufferData.length) { - const biggerBuffer: Float32Array = new $Float32Array(this._$vertexBufferData.length * 2); + const biggerBuffer: Float32Array = new Float32Array(this._$vertexBufferData.length * 2); biggerBuffer.set(this._$vertexBufferData); this._$vertexBufferData = biggerBuffer; } @@ -84,7 +79,7 @@ export class WebGLStrokeMeshGenerator static _$expandIndexBufferIfNeeded(delta_length: number): void { if (this._$indexBufferPos + delta_length > this._$indexBufferData.length) { - const biggerBuffer: Int16Array = new $Int16Array(this._$indexBufferData.length * 2); + const biggerBuffer: Int16Array = new Int16Array(this._$indexBufferData.length * 2); biggerBuffer.set(this._$indexBufferData); this._$indexBufferData = biggerBuffer; } @@ -306,7 +301,7 @@ export class WebGLStrokeMeshGenerator const bx: number = x3 - x2; const by: number = y3 - y2; const det: number = this._$cross(ax, ay, bx, by); - if ($Math.abs(det) < 0.0001) { + if (Math.abs(det) < 0.0001) { return ; } diff --git a/packages/webgl/src/WebGLUtil.ts b/packages/webgl/src/WebGLUtil.ts new file mode 100644 index 00000000..fb9c8031 --- /dev/null +++ b/packages/webgl/src/WebGLUtil.ts @@ -0,0 +1,310 @@ +/** + * @type {number} + * @public + */ +export let $RENDER_SIZE: number = 2048; + +/** + * @param {number} size + * @return {void} + * @method + * @public + */ +export const $setRenderSize = (size: number): void => +{ + $RENDER_SIZE = Math.min(4096, size / 2); +}; + +/** + * @type {number} + */ +let programId: number = 0; + +/** + * @return {number} + * @method + * @public + */ +export const $getProgramId = (): number => +{ + return programId++; +}; + +/** + * @param {number} value + * @param {number} min + * @param {number} max + * @param {number} [default_value=null] + * @return {number} + * @method + * @public + */ +export const $clamp = ( + value: number, + min: number, max: number, + default_value: number | null = null +): number => { + + const number: number = +value; + + return isNaN(number) && default_value !== null + ? default_value + : Math.min(Math.max(min, isNaN(number) ? 0 : number), max); +}; + +/** + * @type {array} + * @private + */ +const $arrays: any[] = []; + +/** + * @param {array} args + * @return {array} + * @method + * @public + */ +export const $getArray = (...args: any[]): any[] => +{ + const array: any[] = $arrays.pop() || []; + if (args.length) { + array.push(...args); + } + return array; +}; + +/** + * @param {array} array + * @return {void} + * @method + * @public + */ +export const $poolArray = (array: any[] | null = null): void => +{ + if (!array) { + return ; + } + + if (array.length) { + array.length = 0; + } + + $arrays.push(array); +}; + +/** + * @param {number} v + * @return {number} + * @method + * @public + */ +export const $upperPowerOfTwo = (v: number): number => +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + return v; +}; + +/** + * @type {Float32Array[]} + * @private + */ +const $float32Array4: Float32Array[] = []; + +/** + * @param {number} [f0=0] + * @param {number} [f1=0] + * @param {number} [f2=0] + * @param {number} [f3=0] + * @return {Float32Array} + * @method + * @public + */ +export const $getFloat32Array4 = ( + f0: number = 0, f1: number = 0, + f2: number = 0, f3: number = 0 +): Float32Array => { + + const array: Float32Array = $float32Array4.pop() || new Float32Array(4); + + array[0] = f0; + array[1] = f1; + array[2] = f2; + array[3] = f3; + + return array; +}; + +/** + * @param {Float32Array} array + * @return {void} + * @method + * @public + */ +export const $poolFloat32Array4 = (array: Float32Array): void => +{ + $float32Array4.push(array); +}; + +/** + * @type {Float32Array[]} + * @private + */ +const $float32Array9: Float32Array[] = []; + +/** + * @param {number} [f0=0] + * @param {number} [f1=0] + * @param {number} [f2=0] + * @param {number} [f3=0] + * @param {number} [f4=0] + * @param {number} [f5=0] + * @param {number} [f6=0] + * @param {number} [f7=0] + * @param {number} [f8=0] + * @return {Float32Array} + * @method + * @static + */ +export const $getFloat32Array9 = ( + f0: number = 0, f1: number = 0, f2: number = 0, + f3: number = 0, f4: number = 0, f5: number = 0, + f6: number = 0, f7: number = 0, f8: number = 0 +): Float32Array => { + + const array: Float32Array = $float32Array9.pop() || new Float32Array(9); + + array[0] = f0; + array[1] = f1; + array[2] = f2; + array[3] = f3; + array[4] = f4; + array[5] = f5; + array[6] = f6; + array[7] = f7; + array[8] = f8; + + return array; +}; + +/** + * @param {Float32Array} array + * @return {void} + * @method + * @static + */ +export const $poolFloat32Array9 = (array: Float32Array): void => +{ + $float32Array9.push(array); +}; + +/** + * @param {Float32Array} m + * @returns {Float32Array} + * @method + * @static + */ +export const $inverseMatrix = (m: Float32Array): Float32Array => +{ + const rdet: number = 1 / (m[0] * m[4] - m[3] * m[1]); + const tx: number = m[3] * m[7] - m[4] * m[6]; + const ty: number = m[1] * m[6] - m[0] * m[7]; + + return $getFloat32Array9( + m[4] * rdet, 0 - m[1] * rdet, 0, + 0 - m[3] * rdet, m[0] * rdet, 0, + tx * rdet, ty * rdet, 1 + ); +}; + +/** + * @type {Float32Array[]} + * @private + */ +const $float32Array6: Float32Array[] = []; + +/** + * @param {number} [f0=0] + * @param {number} [f1=0] + * @param {number} [f2=0] + * @param {number} [f3=0] + * @param {number} [f4=0] + * @param {number} [f5=0] + * @return {Float32Array} + * @method + * @static + */ +export const $getFloat32Array6 = ( + f0: number = 0, f1: number = 0, + f2: number = 0, f3: number = 0, + f4: number = 0, f5: number = 0 +): Float32Array => { + + const array: Float32Array = $float32Array6.pop() || new Float32Array(6); + + array[0] = f0; + array[1] = f1; + array[2] = f2; + array[3] = f3; + array[4] = f4; + array[5] = f5; + + return array; +}; + +/** + * @param {Float32Array} array + * @return {void} + * @method + * @static + */ +export const $poolFloat32Array6 = (array: Float32Array): void => +{ + $float32Array6.push(array); +}; + +/** + * @type {Int32Array[]} + * @private + */ +const $int32Array4: Int32Array[] = []; + +/** + * @param {number} [f0=0] + * @param {number} [f1=0] + * @param {number} [f2=0] + * @param {number} [f3=0] + * @return {Float32Array} + * @method + * @static + */ +export const $getInt32Array4 = ( + f0: number = 0, f1: number = 0, + f2: number = 0, f3: number = 0 +): Int32Array => { + + const array: Int32Array = $int32Array4.pop() || new Int32Array(4); + + array[0] = f0; + array[1] = f1; + array[2] = f2; + array[3] = f3; + + return array; +}; + +/** + * @param {Float32Array} array + * @return {void} + * @method + * @static + */ +export const $poolInt32Array4 = (array: Int32Array): void => +{ + $int32Array4.push(array); +}; \ No newline at end of file diff --git a/packages/webgl/src/shader/CanvasToWebGLShader.ts b/packages/webgl/src/shader/CanvasToWebGLShader.ts index 3ab553a1..1383b1e8 100644 --- a/packages/webgl/src/shader/CanvasToWebGLShader.ts +++ b/packages/webgl/src/shader/CanvasToWebGLShader.ts @@ -1,9 +1,9 @@ -import { WebGLShaderUniform } from "./WebGLShaderUniform"; -import { WebGLShaderInstance } from "./WebGLShaderInstance"; import type { CanvasToWebGLContext } from "../CanvasToWebGLContext"; import type { CanvasToWebGLShaderList } from "./CanvasToWebGLShaderList"; import type { IndexRangeImpl } from "../interface/IndexRangeImpl"; -import { $getProgramId } from "@next2d/share"; +import { WebGLShaderUniform } from "./WebGLShaderUniform"; +import { WebGLShaderInstance } from "./WebGLShaderInstance"; +import { $getProgramId } from "../WebGLUtil"; /** * @class diff --git a/packages/webgl/src/shader/GradientLUTGenerator.ts b/packages/webgl/src/shader/GradientLUTGenerator.ts index 7c0ba445..504236f6 100644 --- a/packages/webgl/src/shader/GradientLUTGenerator.ts +++ b/packages/webgl/src/shader/GradientLUTGenerator.ts @@ -3,7 +3,6 @@ import type { GradientLUTShaderVariantCollection } from "./variants/GradientLUTS import type { CanvasToWebGLShader } from "./CanvasToWebGLShader"; import type { WebGLShaderUniform } from "./WebGLShaderUniform"; import type { AttachmentImpl } from "../interface/AttachmentImpl"; -import { $Math } from "@next2d/share"; /** * @class @@ -49,7 +48,7 @@ export class GradientLUTGenerator * @type {number} * @private */ - this._$maxLength = $Math.floor(gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS) * 0.75); + this._$maxLength = Math.floor(gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS) * 0.75); /** * @type {Float32Array} @@ -65,7 +64,7 @@ export class GradientLUTGenerator for (let i: number = 0; i < 256; i++) { const t: number = i / 255; - this._$rgbToLinearTable[i] = $Math.pow(t, 2.23333333); + this._$rgbToLinearTable[i] = Math.pow(t, 2.23333333); this._$rgbIdentityTable[i] = t; } } @@ -108,7 +107,7 @@ export class GradientLUTGenerator for (let begin: number = 0; begin < stopsLength; begin += this._$maxLength - 1) { - const end: number = $Math.min(begin + this._$maxLength, stopsLength); + const end: number = Math.min(begin + this._$maxLength, stopsLength); const shader: CanvasToWebGLShader = variants .getGradientLUTShader(end - begin, is_linear_space); @@ -168,7 +167,7 @@ export class GradientLUTGenerator for (let begin: number = 0; begin < stopsLength; begin += this._$maxLength - 1) { - const end: number = $Math.min(begin + this._$maxLength, stopsLength); + const end: number = Math.min(begin + this._$maxLength, stopsLength); const shader: CanvasToWebGLShader = variants .getGradientLUTShader(end - begin, false); diff --git a/packages/webgl/src/shader/WebGLShaderInstance.ts b/packages/webgl/src/shader/WebGLShaderInstance.ts index a310306c..71f3cdf6 100644 --- a/packages/webgl/src/shader/WebGLShaderInstance.ts +++ b/packages/webgl/src/shader/WebGLShaderInstance.ts @@ -7,7 +7,6 @@ export class WebGLShaderInstance private _$count: number; /** - * @param {WebGL2RenderingContext} gl * @constructor * @public */ diff --git a/packages/webgl/src/shader/WebGLShaderUniform.ts b/packages/webgl/src/shader/WebGLShaderUniform.ts index e3728ffa..c813552b 100644 --- a/packages/webgl/src/shader/WebGLShaderUniform.ts +++ b/packages/webgl/src/shader/WebGLShaderUniform.ts @@ -1,9 +1,4 @@ import type { UniformDataImpl } from "../interface/UniformDataImpl"; -import { - $getMap, - $Float32Array, - $Int32Array -} from "@next2d/share"; /** * @class @@ -38,7 +33,7 @@ export class WebGLShaderUniform * @type {Map} * @private */ - this._$map = $getMap(); + this._$map = new Map(); const activeUniforms: number = this._$gl.getProgramParameter(program, this._$gl.ACTIVE_UNIFORMS); for (let i: number = 0; i < activeUniforms; i++) { @@ -64,13 +59,13 @@ export class WebGLShaderUniform // 可能な限りFloat32Arrayに値をパックして転送するようにする case this._$gl.FLOAT_VEC4: data.method = this._$gl.uniform4fv.bind(this._$gl, location); - data.array = new $Float32Array(4 * info.size); + data.array = new Float32Array(4 * info.size); data.assign = -1; break; case this._$gl.INT_VEC4: data.method = this._$gl.uniform4iv.bind(this._$gl, location); - data.array = new $Int32Array(4 * info.size); + data.array = new Int32Array(4 * info.size); data.assign = -1; break; @@ -78,7 +73,7 @@ export class WebGLShaderUniform // sampler2Dは一度だけ設定するようにする case this._$gl.SAMPLER_2D: data.method = this._$gl.uniform1iv.bind(this._$gl, location); - data.array = new $Int32Array(info.size); + data.array = new Int32Array(info.size); data.assign = 1; break; diff --git a/packages/webgl/src/shader/fragment/FragmentShaderSourceGradientLUT.ts b/packages/webgl/src/shader/fragment/FragmentShaderSourceGradientLUT.ts index 98d93561..19209645 100644 --- a/packages/webgl/src/shader/fragment/FragmentShaderSourceGradientLUT.ts +++ b/packages/webgl/src/shader/fragment/FragmentShaderSourceGradientLUT.ts @@ -1,5 +1,3 @@ -import { $Math } from "@next2d/share"; - /** * @class */ @@ -24,8 +22,8 @@ export class FragmentShaderSourceGradientLUT const i0: number = i - 1; const i1: number = i; - const t0: string = `u_mediump[${stops_length + $Math.floor(i0 / 4)}][${i0 % 4}]`; - const t1: string = `u_mediump[${stops_length + $Math.floor(i1 / 4)}][${i1 % 4}]`; + const t0: string = `u_mediump[${stops_length + Math.floor(i0 / 4)}][${i0 % 4}]`; + const t1: string = `u_mediump[${stops_length + Math.floor(i1 / 4)}][${i1 % 4}]`; const c0: string = `u_mediump[${i0}]`; const c1: string = `u_mediump[${i1}]`; diff --git a/packages/webgl/src/shader/fragment/filter/FragmentShaderSourceConvolutionFilter.ts b/packages/webgl/src/shader/fragment/filter/FragmentShaderSourceConvolutionFilter.ts index aa1760cc..31a96da3 100644 --- a/packages/webgl/src/shader/fragment/filter/FragmentShaderSourceConvolutionFilter.ts +++ b/packages/webgl/src/shader/fragment/filter/FragmentShaderSourceConvolutionFilter.ts @@ -1,5 +1,4 @@ import { FragmentShaderLibrary } from "../FragmentShaderLibrary"; -import { $Math } from "@next2d/share"; /** * @class @@ -22,15 +21,15 @@ export class FragmentShaderSourceConvolutionFilter preserve_alpha: boolean, clamp: boolean ): string { - const halfX: number = $Math.floor(x * 0.5); - const halfY: number = $Math.floor(y * 0.5); + const halfX: number = Math.floor(x * 0.5); + const halfY: number = Math.floor(y * 0.5); const size: number = x * y; let matrixStatement: string = ""; const matrixIndex: number = clamp ? 1 : 2; for (let idx: number = 0; idx < size; ++idx) { - const index: number = matrixIndex + $Math.floor(idx / 4); + const index: number = matrixIndex + Math.floor(idx / 4); const component: number = idx % 4; diff --git a/packages/webgl/src/shader/fragment/filter/FragmentShaderSourceFilter.ts b/packages/webgl/src/shader/fragment/filter/FragmentShaderSourceFilter.ts index bd041fa2..2006defc 100644 --- a/packages/webgl/src/shader/fragment/filter/FragmentShaderSourceFilter.ts +++ b/packages/webgl/src/shader/fragment/filter/FragmentShaderSourceFilter.ts @@ -1,4 +1,3 @@ -import { $Math } from "@next2d/share"; import { FragmentShaderLibrary } from "../FragmentShaderLibrary"; /** @@ -187,7 +186,7 @@ void main() { */ static STATEMENT_GLOW_STRENGTH (offset: number): string { - const index: number = $Math.floor(offset / 4); + const index: number = Math.floor(offset / 4); const component: number = offset % 4; return ` float strength = u_mediump[${index}][${component}]; @@ -294,7 +293,7 @@ void main() { */ static STATEMENT_BEVEL_STRENGTH (offset: number): string { - const index: number = $Math.floor(offset / 4); + const index: number = Math.floor(offset / 4); const component: number = offset % 4; return ` diff --git a/packages/webgl/src/shader/variants/BlendShaderVariantCollection.ts b/packages/webgl/src/shader/variants/BlendShaderVariantCollection.ts index d62ab538..a61a7cbf 100644 --- a/packages/webgl/src/shader/variants/BlendShaderVariantCollection.ts +++ b/packages/webgl/src/shader/variants/BlendShaderVariantCollection.ts @@ -5,8 +5,7 @@ import { FragmentShaderSourceBlend } from "../fragment/FragmentShaderSourceBlend import type { CanvasToWebGLContext } from "../../CanvasToWebGLContext"; import type { WebGLShaderUniform } from "../WebGLShaderUniform"; import type { WebGLShaderInstance } from "../WebGLShaderInstance"; -import { $getMap } from "@next2d/share"; -import { $RENDER_SIZE } from "../../Const"; +import { $RENDER_SIZE } from "../../WebGLUtil"; /** * @class @@ -41,7 +40,7 @@ export class BlendShaderVariantCollection * @type {Map} * @private */ - this._$collection = $getMap(); + this._$collection = new Map(); } /** diff --git a/packages/webgl/src/shader/variants/FilterShaderVariantCollection.ts b/packages/webgl/src/shader/variants/FilterShaderVariantCollection.ts index 8fa7f292..4ad97ec0 100644 --- a/packages/webgl/src/shader/variants/FilterShaderVariantCollection.ts +++ b/packages/webgl/src/shader/variants/FilterShaderVariantCollection.ts @@ -7,10 +7,6 @@ import { FragmentShaderSourceConvolutionFilter } from "../fragment/filter/Fragme import { FragmentShaderSourceDisplacementMapFilter } from "../fragment/filter/FragmentShaderSourceDisplacementMapFilter"; import type { WebGLShaderUniform } from "../WebGLShaderUniform"; import type { CanvasToWebGLContext } from "../../CanvasToWebGLContext"; -import { - $Math, - $getMap -} from "@next2d/share"; /** * @class @@ -45,7 +41,7 @@ export class FilterShaderVariantCollection * @type {Map} * @private */ - this._$collection = $getMap(); + this._$collection = new Map(); } /** @@ -121,7 +117,7 @@ export class FilterShaderVariantCollection mediumpLength += is_glow ? 4 : 8; } - mediumpLength = $Math.ceil(mediumpLength / 4); + mediumpLength = Math.ceil(mediumpLength / 4); const shader: CanvasToWebGLShader = new CanvasToWebGLShader( this._$gl, this._$context, @@ -193,7 +189,7 @@ export class FilterShaderVariantCollection } } - const mediumpLength: number = (clamp ? 1 : 2) + $Math.ceil(x * y / 4); + const mediumpLength: number = (clamp ? 1 : 2) + Math.ceil(x * y / 4); const shader: CanvasToWebGLShader = new CanvasToWebGLShader( this._$gl, this._$context, diff --git a/packages/webgl/src/shader/variants/GradientLUTShaderVariantCollection.ts b/packages/webgl/src/shader/variants/GradientLUTShaderVariantCollection.ts index b5d07923..5b13cc1c 100644 --- a/packages/webgl/src/shader/variants/GradientLUTShaderVariantCollection.ts +++ b/packages/webgl/src/shader/variants/GradientLUTShaderVariantCollection.ts @@ -3,10 +3,6 @@ import { FragmentShaderSourceGradientLUT } from "../fragment/FragmentShaderSourc import { CanvasToWebGLShader } from "../CanvasToWebGLShader"; import type { CanvasToWebGLContext } from "../../CanvasToWebGLContext"; import type { WebGLShaderUniform } from "../WebGLShaderUniform"; -import { - $Math, - $getMap -} from "@next2d/share"; /** * @class @@ -41,7 +37,7 @@ export class GradientLUTShaderVariantCollection * @type {Map} * @private */ - this._$collection = $getMap(); + this._$collection = new Map(); } /** @@ -67,7 +63,7 @@ export class GradientLUTShaderVariantCollection } } - const mediumpLength: number = $Math.ceil(stops_length * 5 / 4); + const mediumpLength: number = Math.ceil(stops_length * 5 / 4); const shader: CanvasToWebGLShader = new CanvasToWebGLShader( this._$gl, this._$context, diff --git a/packages/webgl/src/shader/variants/GradientShapeShaderVariantCollection.ts b/packages/webgl/src/shader/variants/GradientShapeShaderVariantCollection.ts index 0e9da6d6..8cf4b7fa 100644 --- a/packages/webgl/src/shader/variants/GradientShapeShaderVariantCollection.ts +++ b/packages/webgl/src/shader/variants/GradientShapeShaderVariantCollection.ts @@ -5,7 +5,6 @@ import { FragmentShaderSourceGradient } from "../fragment/FragmentShaderSourceGr import type { CanvasToWebGLContext } from "../../CanvasToWebGLContext"; import type { WebGLShaderUniform } from "../WebGLShaderUniform"; import type { CanvasToWebGLContextGrid } from "../../CanvasToWebGLContextGrid"; -import { $getMap } from "@next2d/share"; /** * @class @@ -40,7 +39,7 @@ export class GradientShapeShaderVariantCollection * @type {Map} * @private */ - this._$collection = $getMap(); + this._$collection = new Map(); } /** diff --git a/packages/webgl/src/shader/variants/ShapeShaderVariantCollection.ts b/packages/webgl/src/shader/variants/ShapeShaderVariantCollection.ts index ea8a5722..2826c797 100644 --- a/packages/webgl/src/shader/variants/ShapeShaderVariantCollection.ts +++ b/packages/webgl/src/shader/variants/ShapeShaderVariantCollection.ts @@ -5,7 +5,6 @@ import { FragmentShaderSource } from "../fragment/FragmentShaderSource"; import type { WebGLShaderUniform } from "../WebGLShaderUniform"; import type { CanvasToWebGLContext } from "../../CanvasToWebGLContext"; import type { CanvasToWebGLContextGrid } from "../../CanvasToWebGLContextGrid"; -import { $getMap } from "@next2d/share"; /** * @class @@ -40,7 +39,7 @@ export class ShapeShaderVariantCollection * @type {Map} * @private */ - this._$collection = $getMap(); + this._$collection = new Map(); } /** From aefdcfefa9a583467bd516ce743708d4d35380b0 Mon Sep 17 00:00:00 2001 From: ienaga Date: Fri, 26 Jul 2024 09:13:41 +0900 Subject: [PATCH 018/343] =?UTF-8?q?#154=20update:=20Lint=E3=81=AE=E8=A8=AD?= =?UTF-8?q?=E5=AE=9A=E3=82=92=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tsconfig.eslint.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index 142f4c2f..f500aeac 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -8,6 +8,7 @@ ], "exclude": [ "node_modules", - "dist" + "dist", + "src/**/*.test.ts", ] } \ No newline at end of file From 9ce0f3dc682cc93cba42b3d436300737f2ac38de Mon Sep 17 00:00:00 2001 From: ienaga Date: Fri, 26 Jul 2024 09:15:49 +0900 Subject: [PATCH 019/343] =?UTF-8?q?#154=20update:=20Lint=E3=81=AE=E8=A8=AD?= =?UTF-8?q?=E5=AE=9A=E3=82=92=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tsconfig.eslint.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index f500aeac..04f5001b 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -9,6 +9,8 @@ "exclude": [ "node_modules", "dist", + "worker/**/*.test.ts", + "packages/**/*.test.ts", "src/**/*.test.ts", ] } \ No newline at end of file From e646f4daf65b0725b8d9eba66858feee455441a8 Mon Sep 17 00:00:00 2001 From: ienaga Date: Fri, 26 Jul 2024 10:09:19 +0900 Subject: [PATCH 020/343] =?UTF-8?q?#154=20update:=20Lint=E3=81=AE=E8=A8=AD?= =?UTF-8?q?=E5=AE=9A=E3=82=92=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tsconfig.eslint.json | 16 ---------------- tsconfig.json | 3 ++- 2 files changed, 2 insertions(+), 17 deletions(-) delete mode 100644 tsconfig.eslint.json diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json deleted file mode 100644 index 04f5001b..00000000 --- a/tsconfig.eslint.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": [ - "src/**/*.ts", - "packages/**/*.ts", - "worker/**/*.ts", - ".eslintrc.js" - ], - "exclude": [ - "node_modules", - "dist", - "worker/**/*.test.ts", - "packages/**/*.test.ts", - "src/**/*.test.ts", - ] -} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index f8fbb82b..63c706a7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -42,6 +42,7 @@ "worker", "scripts", "__tests__", - "dist" + "dist", + "*.test.ts", ] } \ No newline at end of file From bcffd2ee3566808081cfd102487da69aa4c5e30a Mon Sep 17 00:00:00 2001 From: ienaga Date: Fri, 26 Jul 2024 11:28:43 +0900 Subject: [PATCH 021/343] =?UTF-8?q?#154=20update:=20Lint=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintignore | 4 +++- packages/media/src/SoundMixer.ts | 14 +++----------- tsconfig.json | 1 + 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/.eslintignore b/.eslintignore index f295a90b..fe7b6492 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,7 @@ **/node_modules/* dist +build json @types -.github \ No newline at end of file +.github +*.test.ts \ No newline at end of file diff --git a/packages/media/src/SoundMixer.ts b/packages/media/src/SoundMixer.ts index aa874b60..4ff13c10 100644 --- a/packages/media/src/SoundMixer.ts +++ b/packages/media/src/SoundMixer.ts @@ -1,15 +1,7 @@ import type { Sound } from "./Sound"; import type { Video } from "./Video"; import type { Player } from "@next2d/core"; -import { - $currentPlayer, - $getSoundMixerVolume, - $setSoundMixerVolume -} from "@next2d/util"; -import { - $clamp, - $Math -} from "@next2d/share"; +import { $currentPlayer } from "@next2d/util"; /** * @type {number} @@ -110,7 +102,7 @@ export class SoundMixer const source: AudioBufferSourceNode = sound._$sources[idx]; if (source._$gainNode) { - source._$gainNode.gain.value = $Math.min( + source._$gainNode.gain.value = Math.min( $volume, source._$volume ); @@ -125,7 +117,7 @@ export class SoundMixer const video: Video = videos[idx]; if (video._$video) { - video._$video.volume = $Math.min( + video._$video.volume = Math.min( $volume, video.volume ); diff --git a/tsconfig.json b/tsconfig.json index 63c706a7..3604fd60 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -39,6 +39,7 @@ "exclude": [ "node_modules", "**/dist/**", + "**/build/**", "worker", "scripts", "__tests__", From 350aa242b0279bb38971bf47f58610ce61813241 Mon Sep 17 00:00:00 2001 From: ienaga Date: Sat, 27 Jul 2024 16:07:32 +0900 Subject: [PATCH 022/343] =?UTF-8?q?#154=20media=E3=83=91=E3=83=83=E3=82=B1?= =?UTF-8?q?=E3=83=BC=E3=82=B8=E3=81=AE=E7=A7=BB=E8=A1=8C(WIP)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- @types/window.d.ts | 10 +- common/Util.ts | 96 +++ common/interface/AjaxEventImpl.ts | 5 + common/interface/AjaxOptionImpl.ts | 14 + common/interface/URLLoaderDataFormatImpl.ts | 1 + common/interface/URLRequestHeaderImpl.ts | 5 + common/interface/URLRequestMethodImpl.ts | 1 + jingle.mp3 | Bin 0 -> 110758 bytes package-lock.json | 578 ++-------------- package.json | 1 - packages/events/src/EventDispatcher.ts | 4 +- packages/events/src/VideoEvent.test.ts | 7 +- packages/events/src/VideoEvent.ts | 83 +-- packages/media/package.json | 4 - packages/media/src/MediaUtil.ts | 78 +++ packages/media/src/Sound.test.ts | 31 + packages/media/src/Sound.ts | 569 +++++----------- .../media/src/Sound/SoundDecodeService.ts | 39 ++ .../src/Sound/SoundEndedEventService.test.ts | 48 ++ .../media/src/Sound/SoundEndedEventService.ts | 27 + .../Sound/SoundLoadStartEventService.test.ts | 70 ++ .../src/Sound/SoundLoadStartEventService.ts | 29 + .../Sound/SoundLoadendEventService.test.ts | 76 +++ .../src/Sound/SoundLoadendEventService.ts | 48 ++ .../Sound/SoundProgressEventService.test.ts | 40 ++ .../src/Sound/SoundProgressEventService.ts | 22 + packages/media/src/SoundMixer.test.ts | 32 + packages/media/src/SoundMixer.ts | 70 +- .../SoundMixer/SoundMixerStopAllService.ts | 41 ++ .../SoundMixerUpdateVolumeService.ts | 46 ++ packages/media/src/SoundTransform.ts | 7 +- packages/media/src/Video.ts | 633 ++++++------------ .../Video/VideoCanplaythroughEventService.ts | 34 + .../src/Video/VideoCreateElementService.ts | 47 ++ .../media/src/Video/VideoEndedEventService.ts | 25 + .../Video/VideoLoadedmetadataEventService.ts | 26 + .../media/src/Video/VideoPlayEventService.ts | 30 + .../src/Video/VideoProgressEventService.ts | 21 + packages/media/src/interface/BoundsImpl.ts | 6 + packages/media/src/interface/SoundTagImpl.ts | 6 + packages/util/src/Util.ts | 5 +- src/index.ts | 14 + vite.config.ts | 3 +- 43 files changed, 1395 insertions(+), 1537 deletions(-) create mode 100644 common/Util.ts create mode 100644 common/interface/AjaxEventImpl.ts create mode 100644 common/interface/AjaxOptionImpl.ts create mode 100644 common/interface/URLLoaderDataFormatImpl.ts create mode 100644 common/interface/URLRequestHeaderImpl.ts create mode 100644 common/interface/URLRequestMethodImpl.ts create mode 100644 jingle.mp3 create mode 100644 packages/media/src/MediaUtil.ts create mode 100644 packages/media/src/Sound.test.ts create mode 100644 packages/media/src/Sound/SoundDecodeService.ts create mode 100644 packages/media/src/Sound/SoundEndedEventService.test.ts create mode 100644 packages/media/src/Sound/SoundEndedEventService.ts create mode 100644 packages/media/src/Sound/SoundLoadStartEventService.test.ts create mode 100644 packages/media/src/Sound/SoundLoadStartEventService.ts create mode 100644 packages/media/src/Sound/SoundLoadendEventService.test.ts create mode 100644 packages/media/src/Sound/SoundLoadendEventService.ts create mode 100644 packages/media/src/Sound/SoundProgressEventService.test.ts create mode 100644 packages/media/src/Sound/SoundProgressEventService.ts create mode 100644 packages/media/src/SoundMixer.test.ts create mode 100644 packages/media/src/SoundMixer/SoundMixerStopAllService.ts create mode 100644 packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.ts create mode 100644 packages/media/src/Video/VideoCanplaythroughEventService.ts create mode 100644 packages/media/src/Video/VideoCreateElementService.ts create mode 100644 packages/media/src/Video/VideoEndedEventService.ts create mode 100644 packages/media/src/Video/VideoLoadedmetadataEventService.ts create mode 100644 packages/media/src/Video/VideoPlayEventService.ts create mode 100644 packages/media/src/Video/VideoProgressEventService.ts create mode 100644 packages/media/src/interface/BoundsImpl.ts create mode 100644 packages/media/src/interface/SoundTagImpl.ts diff --git a/@types/window.d.ts b/@types/window.d.ts index ad8e3041..9540f433 100644 --- a/@types/window.d.ts +++ b/@types/window.d.ts @@ -1,5 +1,5 @@ -import { Next2D } from "../src/Next2D"; -import { IndexRangeImpl } from "@next2d/interface"; +import type { Next2D } from "../src/Next2D"; +import type { IndexRangeImpl } from "@next2d/interface"; declare global { @@ -70,10 +70,4 @@ declare global { indexRanges: IndexRangeImpl[]; indexCount: number; } - - // eslint-disable-next-line no-unused-vars - interface AudioBufferSourceNode { - _$gainNode: GainNode | null; - _$volume: number; - } } \ No newline at end of file diff --git a/common/Util.ts b/common/Util.ts new file mode 100644 index 00000000..32ad7809 --- /dev/null +++ b/common/Util.ts @@ -0,0 +1,96 @@ +import type { AjaxOptionImpl } from "./interface/AjaxOptionImpl"; + +/** + * @param {number} value + * @param {number} min + * @param {number} max + * @param {number} [default_value=null] + * @return {number} + * @method + * @static + */ +export const $clamp = ( + value: number, + min: number, max: number, + default_value: number|null = null +): number => { + + const number: number = +value; + + return isNaN(number) && default_value !== null + ? default_value + : Math.min(Math.max(min, isNaN(number) ? 0 : number), max); +}; + +/** + * @param {object} option + * @return {void} + * @method + * @public + */ +export const $ajax = (option: AjaxOptionImpl): void => +{ + // get or post + let postData: string | null = null; + switch (option.method.toUpperCase()) { + + case "GET": + if (option.data) { + const urls = option.url.split("?"); + + urls[1] = urls.length === 1 + ? option.data.toString() + : `${urls[1]}&${option.data.toString()}`; + + option.url = urls.join("?"); + } + break; + + case "PUT": + case "POST": + if (option.data) { + postData = option.data.toString(); + } + break; + + default: + break; + + } + + // start + const xmlHttpRequest = new XMLHttpRequest(); + + // init + xmlHttpRequest.open(option.method, option.url, true); + + // set mimeType + xmlHttpRequest.responseType = option.format; + + // use cookie + xmlHttpRequest.withCredentials = option.withCredentials; + + // add event + if (option.event) { + const keys: string[] = Object.keys(option.event); + for (let idx = 0; idx < keys.length; ++idx) { + + const name: string = keys[idx]; + + // @ts-ignore + xmlHttpRequest.addEventListener(name, option.event[name]); + } + } + + // set request header + for (let idx: number = 0; idx < option.headers.length; ++idx) { + const header = option.headers[idx]; + if (!header) { + continue; + } + xmlHttpRequest.setRequestHeader(header.name, header.value); + } + + xmlHttpRequest.send(postData); +}; + diff --git a/common/interface/AjaxEventImpl.ts b/common/interface/AjaxEventImpl.ts new file mode 100644 index 00000000..6cd6ce28 --- /dev/null +++ b/common/interface/AjaxEventImpl.ts @@ -0,0 +1,5 @@ +export interface AjaxEventImpl { + loadstart?: Function; + progress?: Function; + loadend?: Function; +} \ No newline at end of file diff --git a/common/interface/AjaxOptionImpl.ts b/common/interface/AjaxOptionImpl.ts new file mode 100644 index 00000000..e431eb1f --- /dev/null +++ b/common/interface/AjaxOptionImpl.ts @@ -0,0 +1,14 @@ +import type { URLRequestMethodImpl } from "./URLRequestMethodImpl"; +import type { URLLoaderDataFormatImpl } from "./URLLoaderDataFormatImpl"; +import type { AjaxEventImpl } from "./AjaxEventImpl"; +import type { URLRequestHeaderImpl } from "./URLRequestHeaderImpl"; + +export interface AjaxOptionImpl { + url: string; + format: URLLoaderDataFormatImpl; + method: URLRequestMethodImpl; + withCredentials: boolean; + headers: URLRequestHeaderImpl[]; + data?: any; + event?: AjaxEventImpl; +} \ No newline at end of file diff --git a/common/interface/URLLoaderDataFormatImpl.ts b/common/interface/URLLoaderDataFormatImpl.ts new file mode 100644 index 00000000..af72978d --- /dev/null +++ b/common/interface/URLLoaderDataFormatImpl.ts @@ -0,0 +1 @@ +export type URLLoaderDataFormatImpl = "json" | "arraybuffer" | "text"; \ No newline at end of file diff --git a/common/interface/URLRequestHeaderImpl.ts b/common/interface/URLRequestHeaderImpl.ts new file mode 100644 index 00000000..efbdd5c9 --- /dev/null +++ b/common/interface/URLRequestHeaderImpl.ts @@ -0,0 +1,5 @@ +export interface URLRequestHeaderImpl +{ + name: string; + value: string; +} \ No newline at end of file diff --git a/common/interface/URLRequestMethodImpl.ts b/common/interface/URLRequestMethodImpl.ts new file mode 100644 index 00000000..866e2360 --- /dev/null +++ b/common/interface/URLRequestMethodImpl.ts @@ -0,0 +1 @@ +export type URLRequestMethodImpl = "DELETE" | "GET" | "HEAD" | "OPTIONS" | "POST" | "PUT"; \ No newline at end of file diff --git a/jingle.mp3 b/jingle.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..179a0796d2c14f215c26a5dc620ad9a78c46c6f3 GIT binary patch literal 110758 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

uvS}7nr1CwUdx!^yiEF2#8MJ=p<&NrH<5T} zL{&#hi`J(_=tz8Mc7y}%pbO>jfooZfnh0uEXplhq4y$ADHFBXg5aA`e%<6*7^p~C*Eu@%>#A!`n0}^lk zgC}t{y~&@wS~m@V4kI4iM-2AQ-L$=|w2Bxoo8ITphs+hT$|*oYR>ZG={`v^ot8NJ1 ztsUnNuFLyiAtuNgnHY;rN9poo&}b1|V~SOI%5RzDcGyB~i%!homsfLO;Hpb}hMJAk zTH|BrkeCO9<`Nw0p*aX#3zZ2^=g_6l0Pt_gR;*Y(`-0Z$ks-v~EvoYaeMy)Sv; zPbF{v?H7uR>|U1+zC1cue9na5HG0xoeqCvEcQ7=?YMkc-Qr5W^Dkp3h5kUq`~!{({tpuC3RWz%YKEGEQ-bA+5KjdaFL1X%KAXg&qW|ZZlN@ zY_t?11p(?Mrd(lb5ox|m(|cKD?ljM1Lz1o@vAoVw-TQf^YR;IB@P@vsCKcDv#vxyx zHvFnak|I$1j3}032#ShI<$B3S$dVd63)jviW1XB3CBN^U3%G-#$5`PRKc(NWMB#q$ z7mK#Y(PCD2_>-a##nIvq~vg@oNw63EiMb~*Iv0>pqqBh~ioHuLU$ zZ?>>$-eC+@(r*e0;RaU=6*dGx`opdbWj4%-J0a6$zRsgRi8K{Xx@R54ziZ3w$R<6Eo38d2k^l zm(rPjuTsGQS(fo&TQb)(d;7S1JhTI$QLp*MDD%({C8tt}GnCOm@peixsoJV@!3x^; z!!C!7^!Jq!AQy_KN+4 zKEF13RMKKnut!Ues~v)cdNv>&Oh~6^G&&Zf^4vgkjgmnIcFjJ53M)H7J*mgt6P z_n^ZvwsoA;ehe^vJJizOtPVf5^2yO(PRIVNa|fhXGtsBm7&(7DxV`48WiilZTK>x` zY~i0}mwGt&ey4lt*;Jyd-8E^@!u?$SVgW8C%_H(e>sHX{w+9`@xoeDn_1W;CjrgcX|LogHK_jhbzhbfAy16$^PCDNpY+goEZFr!NAj1;p@$o;b_9Z<_*7u2*;(-&jnK(hSV#+#Dnz(#oKYBp~30v zvPU``0F`I5=U4c1>&LwoWRDtF6y+}~PzobI!5J{##_rNKAnQo!a?OQ*;+0HP8O&C` z4kH=R^1vCeA4%)muOvrDE!(8&zMi5JTm4*4KM;1P%!s&CNq^1HOa?>z(f6CCPp_tc zGl)S-HGPRSMGgD_x=Jxli{i!^po*`n&HZKVY_Y)Ctmi==GYB*uuxSpHX)?7&I zL%UT=WJKCG7r{fHv!)68TkcjXCov#tY>Ji3xlWqHl^j*NF}Ivn6>> zEXmcRQyc{&7JcMYP+kq(Op3#WbirZ>+{4G6E1mFpR-KW4{qdx#cVbR`o>^b;rhOmh z%nBpQJ>xC)wX2I{& zweNE%Pn$J={j9|T9}?T)s5oU<(P}BJj8=O()h8i_fAdb=HhN`z#r9KT$Bglk`rR!d z>xcfR_q#8|tU(tINrkvnDxD9tR|k9FpX`|~Z&ZB#p#|LC@gM9$P32e>{c~ZybKM&Q zoj?v!VNEzm5jE2&Q)R_fS1!ye$WBS%bVqyTxoIpxmYEFw;SD2X#`1&>Q!&R82HX|E zJ_HzeL2l+ghYEw9jr95om4oq@<$>GH+cUucrZAjMUaF3&L0pdq{nu8i)I$#a|Ic=X z>yhYT>CAdsg>xvcNvy%W&m@{Q0#JX1$CywQT!!fc&9&Iy8vT>L2*)|Ms4PVBv7W!Tg zH0+mNzi|E`6idj&6)v0~OWQp#p)y{I6J>kmze#Zzk0V16rDU~

^cN(7nMTeI>JT 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 literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json index 67108d11..2045b7db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,6 @@ "htmlparser2": "^9.1.0" }, "devDependencies": { - "@types/jest": "^29.5.12", "@types/node": "^20.14.11", "@typescript-eslint/eslint-plugin": "^7.16.1", "@typescript-eslint/parser": "^7.16.1", @@ -62,124 +61,6 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -717,50 +598,6 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -866,10 +703,6 @@ "resolved": "packages/webgl", "link": true }, - "node_modules/@next2d/webpack-worker-loader-plugin": { - "resolved": "packages/webpack-worker-loader-plugin", - "link": true - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1132,13 +965,6 @@ "win32" ] }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -1146,90 +972,28 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "29.5.12", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", - "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, "node_modules/@types/node": { - "version": "20.14.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", - "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "version": "20.14.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.12.tgz", + "integrity": "sha512-r7wNXakLeSsGT0H1AU863vS2wa5wBOK4bWMjZz2wj+8nBx+m5PeIn0k8AloSLpRuiwdRQZwarZqHE4FNArPuJQ==", "dev": true, "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", - "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz", + "integrity": "sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/type-utils": "7.16.1", - "@typescript-eslint/utils": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", + "@typescript-eslint/scope-manager": "7.17.0", + "@typescript-eslint/type-utils": "7.17.0", + "@typescript-eslint/utils": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -1253,16 +1017,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", - "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.17.0.tgz", + "integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", + "@typescript-eslint/scope-manager": "7.17.0", + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/typescript-estree": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0", "debug": "^4.3.4" }, "engines": { @@ -1282,14 +1046,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", - "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz", + "integrity": "sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1" + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1300,14 +1064,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", - "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz", + "integrity": "sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.16.1", - "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/typescript-estree": "7.17.0", + "@typescript-eslint/utils": "7.17.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -1328,9 +1092,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", - "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.17.0.tgz", + "integrity": "sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==", "dev": true, "license": "MIT", "engines": { @@ -1342,14 +1106,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", - "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz", + "integrity": "sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1371,16 +1135,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", - "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.17.0.tgz", + "integrity": "sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1" + "@typescript-eslint/scope-manager": "7.17.0", + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/typescript-estree": "7.17.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1394,13 +1158,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", - "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz", + "integrity": "sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/types": "7.17.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -1728,22 +1492,6 @@ "node": ">= 16" } }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1885,16 +1633,6 @@ "node": ">=0.4.0" } }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -2280,23 +2018,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2586,13 +2307,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -2819,94 +2533,6 @@ "dev": true, "license": "ISC" }, - "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -3381,9 +3007,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.4.40", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz", + "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==", "dev": true, "funding": [ { @@ -3419,34 +3045,6 @@ "node": ">= 0.8.0" } }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -3492,13 +3090,6 @@ ], "license": "MIT" }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -3707,29 +3298,6 @@ "node": ">=0.10.0" } }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -3929,9 +3497,9 @@ } }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "license": "Apache-2.0", "bin": { @@ -3981,9 +3549,9 @@ } }, "node_modules/vite": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", - "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz", + "integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==", "dev": true, "license": "MIT", "dependencies": { @@ -4325,15 +3893,7 @@ "packages/events": { "name": "@next2d/events", "version": "*", - "license": "MIT", - "peerDependencies": { - "@next2d/core": "file:../core", - "@next2d/display": "file:../display", - "@next2d/interface": "file:../interface", - "@next2d/net": "file:../net", - "@next2d/share": "file:../share", - "@next2d/util": "file:../util" - } + "license": "MIT" }, "packages/filters": { "name": "@next2d/filters", @@ -4347,15 +3907,7 @@ "packages/geom": { "name": "@next2d/geom", "version": "*", - "license": "MIT", - "peerDependencies": { - "@next2d/core": "file:../core", - "@next2d/display": "file:../display", - "@next2d/filters": "file:../filters", - "@next2d/interface": "file:../interface", - "@next2d/share": "file:../share", - "@next2d/util": "file:../util" - } + "license": "MIT" }, "packages/interface": { "name": "@next2d/interface", @@ -4386,13 +3938,7 @@ "packages/net": { "name": "@next2d/net", "version": "*", - "license": "MIT", - "peerDependencies": { - "@next2d/core": "file:../core", - "@next2d/interface": "file:../interface", - "@next2d/share": "file:../share", - "@next2d/util": "file:../util" - } + "license": "MIT" }, "packages/share": { "name": "@next2d/share", @@ -4415,8 +3961,7 @@ "version": "*", "license": "MIT", "peerDependencies": { - "@next2d/events": "file:../events", - "@next2d/share": "file:../share" + "@next2d/events": "file:../events" } }, "packages/util": { @@ -4437,13 +3982,6 @@ "packages/webgl": { "name": "@next2d/webgl", "version": "*", - "license": "MIT", - "peerDependencies": { - "@next2d/share": "file:../share" - } - }, - "packages/webpack-worker-loader-plugin": { - "name": "@next2d/webpack-worker-loader-plugin", "license": "MIT" } } diff --git a/package.json b/package.json index d880111d..6a3b1ec8 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ "htmlparser2": "^9.1.0" }, "devDependencies": { - "@types/jest": "^29.5.12", "@types/node": "^20.14.11", "@typescript-eslint/eslint-plugin": "^7.16.1", "@typescript-eslint/parser": "^7.16.1", diff --git a/packages/events/src/EventDispatcher.ts b/packages/events/src/EventDispatcher.ts index 6988ea29..67b922ec 100644 --- a/packages/events/src/EventDispatcher.ts +++ b/packages/events/src/EventDispatcher.ts @@ -1,5 +1,5 @@ import type { EventListenerImpl } from "./interface/EventListenerImpl"; -import { Event } from "./Event"; +import type { EventImpl } from "./interface/EventImpl"; import { execute as eventDispatcherAddEventListenerService } from "./EventDispatcher/EventDispatcherAddEventListenerService"; import { execute as eventDispatcherHasEventListenerService } from "./EventDispatcher/EventDispatcherHasEventListenerService"; import { execute as eventDispatcherRemoveEventListenerService } from "./EventDispatcher/EventDispatcherRemoveEventListenerService"; @@ -121,7 +121,7 @@ export class EventDispatcher * @method * @public */ - dispatchEvent (event: Event): boolean + dispatchEvent (event: EventImpl): boolean { return eventDispatcherDispatchEventService(this, event); } diff --git a/packages/events/src/VideoEvent.test.ts b/packages/events/src/VideoEvent.test.ts index 21fbff9a..93f3eae1 100644 --- a/packages/events/src/VideoEvent.test.ts +++ b/packages/events/src/VideoEvent.test.ts @@ -6,7 +6,7 @@ describe("VideoEvent.js toString test", () => it("toString test success", () => { const videoEvent = new VideoEvent(""); - expect(videoEvent.toString()).toBe("[VideoEvent type=\"\" bubbles=false cancelable=false eventPhase=2 bytesLoaded=0 bytesTotal=0]"); + expect(videoEvent.toString()).toBe("[VideoEvent type=\"\" bubbles=false cancelable=false eventPhase=2]"); }); }); @@ -44,11 +44,6 @@ describe("VideoEvent.js property test", () => expect(VideoEvent.PLAY).toBe("play"); }); - it("PROGRESS test", () => - { - expect(VideoEvent.PROGRESS).toBe("progress"); - }); - it("PLAY_END test", () => { expect(VideoEvent.PLAY_END).toBe("playEnd"); diff --git a/packages/events/src/VideoEvent.ts b/packages/events/src/VideoEvent.ts index 72d73ff3..5aac3a55 100644 --- a/packages/events/src/VideoEvent.ts +++ b/packages/events/src/VideoEvent.ts @@ -11,41 +11,6 @@ import { execute as eventFormatToStringService } from "./Event/EventFormatToStri */ export class VideoEvent extends Event { - private readonly _$bytesLoaded: number; - private readonly _$bytesTotal: number; - - /** - * @param {string} type - * @param {boolean} [bubbles=true] - * @param {boolean} [cancelable=false] - * @param {number} [bytes_loaded=0] - * @param {number} [bytes_total=0] - * - * @constructor - * @public - */ - constructor ( - type: string, bubbles: boolean = false, cancelable: boolean = false, - bytes_loaded: number = 0, bytes_total: number = 0 - ) { - - super(type, bubbles, cancelable); - - /** - * @type {number} - * @default 0 - * @private - */ - this._$bytesLoaded = bytes_loaded | 0; - - /** - * @type {number} - * @default 0 - * @private - */ - this._$bytesTotal = bytes_total | 0; - } - /** * 指定されたクラスのストリングを返します。 * Returns the string representation of the specified class. @@ -86,8 +51,7 @@ export class VideoEvent extends Event { return eventFormatToStringService(this, "VideoEvent", - "type", "bubbles", "cancelable", - "eventPhase", "bytesLoaded", "bytesTotal" + "type", "bubbles", "cancelable", "eventPhase" ); } @@ -105,26 +69,12 @@ export class VideoEvent extends Event return "next2d.events.VideoEvent"; } - /** - * @description progress イベントオブジェクトの type プロパティ値を定義します。 - * Defines the value of the type property of a progress event object. - * - * @return {string} - * @default "progress" - * @const - * @static - */ - static get PROGRESS (): string - { - return "progress"; - } - /** * @description play イベントオブジェクトの type プロパティ値を定義します。 * Defines the value of the type property of a play event object. * * @return {string} - * @default "play" + * @default play * @const * @static */ @@ -188,33 +138,4 @@ export class VideoEvent extends Event { return "seek"; } - - /** - * @description リスナーがイベントを処理しているときに読み込まれたアイテム数またはバイト数です。 - * The number of items or bytes loaded when the listener processes the event. - * - * @return {number} - * @default 0 - * @readonly - * @public - */ - get bytesLoaded (): number - { - return this._$bytesLoaded; - } - - /** - * @description 読み込みプロセスが成功した場合に読み込まれるアイテムまたはバイトの総数です。 - * The total number of items or bytes that will be loaded - * if the loading process succeeds. - * - * @return {number} - * @default 0 - * @readonly - * @public - */ - get bytesTotal (): number - { - return this._$bytesTotal; - } } \ No newline at end of file diff --git a/packages/media/package.json b/packages/media/package.json index b7e3b56c..f9da2531 100644 --- a/packages/media/package.json +++ b/packages/media/package.json @@ -29,10 +29,6 @@ "@next2d/events": "file:../events", "@next2d/net": "file:../net", "@next2d/display": "file:../display", - "@next2d/interface": "file:../interface", - "@next2d/core": "file:../core", - "@next2d/share": "file:../share", - "@next2d/util": "file:../util", "@next2d/geom": "file:../geom", "@next2d/webgl": "file:../webgl" } diff --git a/packages/media/src/MediaUtil.ts b/packages/media/src/MediaUtil.ts new file mode 100644 index 00000000..0daeacf7 --- /dev/null +++ b/packages/media/src/MediaUtil.ts @@ -0,0 +1,78 @@ +import type { Sound } from "./Sound"; +import type { Video } from "./Video"; + +/** + * @type {AudioContext} + * @static + */ +export const $audioContext: AudioContext | null = "AudioContext" in window ? new AudioContext() : null; + +/** + * @type {number} + * @private + */ +let $volume: number = 1; + +/** + * @description 音量を返却 + * Returns the volume. + * + * @return {number} + * @method + * @public + */ +export const $getVolume = (): number => +{ + return $volume; +}; + +/** + * @description 音量を設定 + * Set the volume. + * + * @param {number} volume + * @method + * @public + */ +export const $setVolume = (volume: number): void => +{ + $volume = volume; +}; + +/** + * @type {Sound[]} + * @private + */ +const $sounds: Sound[] = []; + +/** + * @description 再生中のサウンドを返却 + * Returns the sound being played. + * + * @returns {Sound[]} + * @method + * @public + */ +export const $getSounds = (): Sound[] => +{ + return $sounds; +}; + +/** + * @type {Video[]} + * @private + */ +const $videos: Video[] = []; + +/** + * @description 再生中のビデオを返却 + * Returns the video being played. + * + * @returns {Video[]} + * @method + * @public + */ +export const $getVideos = (): Video[] => +{ + return $videos; +}; \ No newline at end of file diff --git a/packages/media/src/Sound.test.ts b/packages/media/src/Sound.test.ts new file mode 100644 index 00000000..fd84afb6 --- /dev/null +++ b/packages/media/src/Sound.test.ts @@ -0,0 +1,31 @@ +import { Sound } from "./Sound"; +import { describe, expect, it } from "vitest"; + +describe("Sound.js namespace test", () => +{ + it("namespace test public", () => + { + expect(new Sound().namespace).toBe("next2d.media.Sound"); + }); + + it("namespace test static", () => + { + expect(Sound.namespace).toBe("next2d.media.Sound"); + }); +}); + +describe("Sound.js toString test", () => +{ + it("toString test success", () => + { + expect(new Sound().toString()).toBe("[object Sound]"); + }); +}); + +describe("Sound.js static toString test", () => +{ + it("static toString test", () => + { + expect(Sound.toString()).toBe("[class Sound]"); + }); +}); \ No newline at end of file diff --git a/packages/media/src/Sound.ts b/packages/media/src/Sound.ts index 75a3a54d..47e1452d 100644 --- a/packages/media/src/Sound.ts +++ b/packages/media/src/Sound.ts @@ -1,35 +1,23 @@ -import { SoundMixer } from "./SoundMixer"; +import type { SoundTagImpl } from "./interface/SoundTagImpl"; import { URLRequest } from "@next2d/net"; -import { Player } from "@next2d/core"; -import { - EventDispatcher, - Event as Next2DEvent, - IOErrorEvent, - ProgressEvent as Next2DProgressEvent -} from "@next2d/events"; -import type { - DisplayObjectContainer, - LoaderInfo -} from "@next2d/display"; -import type { - SoundTagImpl, - SoundCharacterImpl, - Character -} from "@next2d/interface"; +import { SoundMixer } from "./SoundMixer"; +import { execute as soundLoadStartEventService } from "./Sound/SoundLoadStartEventService"; +import { execute as soundProgressEventService } from "./Sound/SoundProgressEventService"; +import { execute as soundLoadendEventService } from "./Sound/SoundLoadendEventService"; +import { execute as soundEndedEventService } from "./Sound/SoundEndedEventService"; +import { execute as soundDecodeService } from "./Sound/SoundDecodeService"; import { - $Math, - $performance, - $requestAnimationFrame, $clamp, - $getArray -} from "@next2d/share"; + $ajax +} from "../../../common/Util"; +import { + Event, + EventDispatcher +} from "@next2d/events"; import { - $ajax, $audioContext, - $audios, - $currentPlayer, - $decodeAudioData -} from "@next2d/util"; + $getSounds +} from "./MediaUtil"; /** * @description Sound クラスを使用すると、アプリケーション内のサウンドを処理することができます。 @@ -44,68 +32,23 @@ import { */ export class Sound extends EventDispatcher { - public readonly _$sources: AudioBufferSourceNode[]; - private _$bytesLoaded: number; - private _$bytesTotal: number; + private _$source: AudioBufferSourceNode | null; + private _$gain: GainNode | null; + private _$audioBuffer: AudioBuffer | null; private _$volume: number; private _$currentCount: number; private _$src: string; private _$loopCount: number; private _$stopFlag: boolean; - public _$character: Character | null; - public _$audioBuffer: AudioBuffer | null; - public _$arrayBuffer: ArrayBuffer | null; - + /** * @constructor * @public */ constructor () { - super(); - /** - * @type {number} - * @default 0 - * @private - */ - this._$bytesLoaded = 0; - - /** - * @type {number} - * @default 0 - * @private - */ - this._$bytesTotal = 0; - - /** - * @type {AudioBuffer} - * @default null - * @private - */ - this._$arrayBuffer = null; - - /** - * @type {Uint8Array} - * @default null - * @private - */ - this._$audioBuffer = null; - - /** - * @type {object} - * @default null - * @private - */ - this._$character = null; - - /** - * @type {array} - * @private - */ - this._$sources = $getArray(); - /** * @type {number} * @default 1 @@ -140,6 +83,27 @@ export class Sound extends EventDispatcher * @private */ this._$src = ""; + + /** + * @type {AudioBufferSourceNode} + * @default null + * @private + */ + this._$source = null; + + /** + * @type {GainNode} + * @default null + * @private + */ + this._$gain = null; + + /** + * @type {AudioBuffer} + * @default null + * @private + */ + this._$audioBuffer = null; } /** @@ -198,34 +162,6 @@ export class Sound extends EventDispatcher return "next2d.media.Sound"; } - /** - * @description 既にアプリケーションにロードされているデータのバイト数です。 - * The number of bytes of data that have been loaded into the application. - * - * @member {number} - * @default 0 - * @readonly - * @public - */ - get bytesLoaded (): number - { - return this._$bytesLoaded; - } - - /** - * @description アプリケーションにロードされるファイルの総バイト数。 - * The total size in bytes of the file being loaded into the application. - * - * @member {number} - * @default 0 - * @readonly - * @public - */ - get bytesTotal (): number - { - return this._$bytesTotal; - } - /** * @description ループ回数の設定 * Loop count setting. @@ -257,6 +193,9 @@ export class Sound extends EventDispatcher } set src (url: string) { + if (this._$src === url) { + return ; + } this.load(new URLRequest(url)); } @@ -274,179 +213,98 @@ export class Sound extends EventDispatcher } set volume (volume: number) { - this._$volume = $Math.min( - SoundMixer.volume, - $clamp(volume, 0, 1, 1) - ); - - const length: number = this._$sources.length; - if (length && $audioContext) { - for (let idx: number = 0; idx < length; ++idx) { - - const source: AudioBufferSourceNode = this._$sources[idx]; - - if (source._$gainNode) { - source._$gainNode.gain.value = this._$volume; - source._$volume = this._$volume; - } - } + this._$volume = $clamp(volume, 0, 1, 1); + if (this._$gain) { + this._$gain.gain.value = this._$volume; } } /** - * @description Sound クラスを複製します。 - * Duplicate the Sound class. + * @description サウンドがループするかどうかを示します。 + * Indicates whether the sound loops. * - * @return {Sound} - * @method + * @member {boolean} + * @readonly * @public */ - clone (): Sound + get canLoop (): boolean { - const sound = new Sound(); - sound.volume = this.volume; - - sound._$loopCount = this._$loopCount; - - if (this._$character) { - sound._$character = this._$character; - } else { - sound._$audioBuffer = this._$audioBuffer; - } - - return sound; + return !this._$stopFlag && this._$loopCount >= this._$currentCount; } /** - * @description 指定した URL から外部 MP3 ファイルのロードを開始します。 - * Initiates loading of an external MP3 file from the specified URL. + * @description AudioBuffer + * AudioBuffer * - * @param {URLRequest} request - * @return {void} - * @method + * @member {AudioBuffer} + * @default null * @public */ - load (request: URLRequest): void + get audioBuffer (): AudioBuffer | null { - this._$src = request.url; - - $ajax({ - "format": "arraybuffer", - "url": request.url, - "method": request.method, - "data": request.data, - "headers": request.headers, - "withCredentials": request.withCredentials, - "event": { - "loadstart": (event: ProgressEvent) => - { - this._$loadStart(event); - }, - "progress": (event: ProgressEvent) => - { - this._$progress(event); - }, - "loadend": (event: ProgressEvent) => - { - this._$loadEnd(event); - } - } - }); + return this._$audioBuffer; } - - /** - * @param {ProgressEvent} event - * @return {void} - * @method - * @private - */ - _$loadStart (event: ProgressEvent): void + set audioBuffer (audio_buffer: AudioBuffer | null) { - this._$bytesLoaded = event.loaded; - this._$bytesTotal = event.total; - - if (this.willTrigger(Next2DEvent.OPEN)) { - this.dispatchEvent(new Next2DEvent(Next2DEvent.OPEN)); - } - - if (this.willTrigger(Next2DProgressEvent.PROGRESS)) { - this.dispatchEvent(new Next2DProgressEvent( - Next2DProgressEvent.PROGRESS, false, false, - event.loaded, event.total - )); - } + this._$audioBuffer = audio_buffer; } /** - * @param {ProgressEvent} event - * @return {void} + * @description Sound クラスを複製します。 + * Duplicate the Sound class. + * + * @return {Sound} * @method - * @private + * @public */ - _$progress (event: ProgressEvent): void + clone (): Sound { - this._$bytesLoaded = event.loaded; - this._$bytesTotal = event.total; - - if (this.willTrigger(Next2DProgressEvent.PROGRESS)) { - this.dispatchEvent(new Next2DProgressEvent( - Next2DProgressEvent.PROGRESS, false, false, - event.loaded, event.total - )); - } + const sound = new Sound(); + sound.volume = this._$volume; + sound.loopCount = this._$loopCount; + sound.audioBuffer = this._$audioBuffer; + return sound; } /** - * @param {ProgressEvent} event - * @return {void} + * @description 指定した URL から外部 MP3 ファイルのロードを開始します。 + * Initiates loading of an external MP3 file from the specified URL. + * + * @param {URLRequest} request + * @return {Promise} * @method - * @private + * @public */ - _$loadEnd (event: ProgressEvent): void + load (request: URLRequest): Promise { - this._$bytesLoaded = event.loaded; - this._$bytesTotal = event.total; - - if (this.willTrigger(Next2DProgressEvent.PROGRESS)) { - this.dispatchEvent(new Next2DProgressEvent( - Next2DProgressEvent.PROGRESS, false, false, - event.loaded, event.total - )); - } - - const target: any = event.target; - if (!target) { - throw new Error("the Sound target is null."); - } - - if (199 < target.status && 400 > target.status) { - - this._$arrayBuffer = target.response; + this._$src = request.url; - if ($audioContext) { - $decodeAudioData(this) - .then((sound) => + return new Promise((resolve): void => + { + $ajax({ + "format": "arraybuffer", + "url": request.url, + "method": request.method, + "data": request.data, + "headers": request.headers, + "withCredentials": request.withCredentials, + "event": { + "loadstart": (event: ProgressEvent): void => { - if (sound.hasEventListener(Next2DEvent.INIT) - || sound.hasEventListener(Next2DEvent.COMPLETE) - ) { - const player: Player = $currentPlayer(); - player._$loaders.push(sound); - } - }); - } else { - $audios.push(this); - } - - } else { - - if (this.willTrigger(IOErrorEvent.IO_ERROR)) { - this.dispatchEvent(new IOErrorEvent( - IOErrorEvent.IO_ERROR, false, false, target.statusText - )); - } - - } + soundLoadStartEventService(this, event); + }, + "progress": (event: ProgressEvent): void => + { + soundProgressEventService(this, event); + }, + "loadend": async (event: ProgressEvent): Promise => + { + await soundLoadendEventService(this, event); + resolve(); + } + } + }); + }); } /** @@ -460,37 +318,33 @@ export class Sound extends EventDispatcher */ play (start_time: number = 0): void { - const buffer: AudioBuffer | null = this._$character - ? this._$character.audioBuffer - : this._$audioBuffer; - - // execute - if (!$audioContext || !buffer) { - - const now: number = $performance.now(); - const wait = () => - { - const buffer = this._$character - ? this._$character.audioBuffer - : this._$audioBuffer; - - if (buffer !== null && $audioContext !== null) { - const offset = ($performance.now() - now) / 1000; - this._$createBufferSource(start_time, offset); - return ; - } - - $requestAnimationFrame(wait); + if (!this._$audioBuffer || !$audioContext) { + return ; + } - }; + this._$gain = $audioContext.createGain(); + this._$gain.connect($audioContext.destination); + this._$gain.gain.value = Math.min(SoundMixer.volume, this._$volume); - $requestAnimationFrame(wait); + this._$source = $audioContext.createBufferSource(); + this._$source.addEventListener("ended", (): void => + { + soundEndedEventService(this); + }); - } else { + this._$source.buffer = this._$audioBuffer; + this._$source.connect(this._$gain); + this._$source.start(start_time); - this._$createBufferSource(start_time); + this._$stopFlag = false; + this._$currentCount++; + const sounds = $getSounds(); + const index = sounds.indexOf(this); + if (index > -1) { + sounds.splice(index, 1); } + sounds.push(this); } /** @@ -504,33 +358,23 @@ export class Sound extends EventDispatcher stop (): void { this._$stopFlag = true; - const length: number = this._$sources.length; - if (length) { - - const player = $currentPlayer(); - if ($audioContext) { - - for (let idx: number = 0; idx < length; ++idx) { - - const source: AudioBufferSourceNode = this._$sources[idx]; - - if (source._$gainNode) { - source._$gainNode.gain.value = 0; - source._$gainNode.disconnect(); - source._$gainNode = null; - } + this._$currentCount = 0; - source.onended = null; - source.disconnect(); - } - } + if (this._$source) { + this._$source.disconnect(); + this._$source = null; + } - player._$sources.splice( - player._$sources.indexOf(this), 1 - ); + if (this._$gain) { + this._$gain.gain.value = 0; + this._$gain.disconnect(); + this._$gain = null; + } - this._$currentCount = 0; - this._$sources.length = 0; + const sounds = $getSounds(); + const index = sounds.indexOf(this); + if (index > -1) { + sounds.splice(index, 1); } } @@ -541,141 +385,36 @@ export class Sound extends EventDispatcher * @method * @private */ - _$build ( + async _$build ( tag: SoundTagImpl, - parent: DisplayObjectContainer - ) { + parent: any + ): Promise { - const loaderInfo: LoaderInfo | null = parent.loaderInfo; + const loaderInfo: any = parent.loaderInfo; if (!loaderInfo || !loaderInfo._$data) { throw new Error("the loaderInfo or data is null."); } - this._$character = loaderInfo + const character = loaderInfo ._$data .characters[tag.characterId]; - if (!this._$character) { + if (!character) { throw new Error("character is null."); } - // load AudioBuffer - if (!this._$character.audioBuffer) { - if ($audioContext) { - $decodeAudioData(this) - .then((sound) => - { - if (sound.hasEventListener(Next2DEvent.INIT) - || sound.hasEventListener(Next2DEvent.COMPLETE) - ) { - const player: Player = $currentPlayer(); - player._$loaders.push(sound); - } - }); - } else { - $audios.push(this); - } - } - this._$loopCount = tag.loopCount | 0; - this._$volume = $Math.min(SoundMixer.volume, tag.volume); - } + this._$volume = Math.min(SoundMixer.volume, tag.volume); - /** - * @param {number} [start_time=0] - * @param {number} [offset=0] - * @return {void} - * @method - * @private - */ - _$createBufferSource (start_time = 0, offset = 0) - { - if (!$audioContext) { - throw new Error("the Audio Context is null."); - } - - // setup - const source: AudioBufferSourceNode = $audioContext.createBufferSource(); - - source.onended = (event: Event): void => - { - return this._$endEventHandler(event); - }; - - // main - source.buffer = this._$character - ? this._$character.audioBuffer - : this._$audioBuffer; - - source._$gainNode = $audioContext.createGain(); - source._$gainNode.connect($audioContext.destination); - - const volume = $Math.min(SoundMixer.volume, this._$volume); - - source._$gainNode.gain.value = volume; - source._$volume = volume; - - source.connect(source._$gainNode); - source.start(start_time | 0, offset); - - const player = $currentPlayer(); - if (player._$sources.indexOf(this) === -1) { - player._$sources.push(this); - } - - this._$sources.push(source); - - this._$stopFlag = false; - } - - /** - * @param {Event} event - * @return {void} - * @method - * @private - */ - _$endEventHandler (event: Event): void - { - const source: any = event.target; - - this._$sources.splice( - this._$sources.indexOf(source), 1 - ); - - if (!this._$stopFlag && this._$loopCount > this._$currentCount) { - - this._$createBufferSource(); - - this._$currentCount++; - - } else { - - this._$currentCount = 0; - - if ($audioContext) { - - if (source._$gainNode) { - source._$gainNode.gain.value = 0; - source._$gainNode.disconnect(); - source._$gainNode = null; + // load AudioBuffer + if (!character.audioBuffer) { + const audioBuffer = await soundDecodeService(character.buffer.buffer); + if (audioBuffer) { + this._$audioBuffer = character.audioBuffer = audioBuffer; + if (this.hasEventListener(Event.COMPLETE)) { + this.dispatchEvent(new Event(Event.COMPLETE)); } - - // Firefoxにて、disconnectした時にonendedが呼び出されるのを回避 - source.onended = null; - source.disconnect(); - } - - if (!this._$sources.length) { - const player = $currentPlayer(); - player._$sources.splice( - player._$sources.indexOf(this), 1 - ); } - - if (this.willTrigger(Next2DEvent.SOUND_COMPLETE)) { - this.dispatchEvent(new Next2DEvent(Next2DEvent.SOUND_COMPLETE)); - } - } } -} +} \ No newline at end of file diff --git a/packages/media/src/Sound/SoundDecodeService.ts b/packages/media/src/Sound/SoundDecodeService.ts new file mode 100644 index 00000000..ef663ee7 --- /dev/null +++ b/packages/media/src/Sound/SoundDecodeService.ts @@ -0,0 +1,39 @@ +import { $audioContext } from "../MediaUtil"; + +/** + * @description ArrayBufferをデコードしてAudioBufferを返却 + * Decode Uint8Array and return AudioBuffer. + * + * @param {ArrayBuffer} array_buffer + * @return {AudioBuffer | void} + * @method + * @public + */ +export const execute = async (array_buffer: ArrayBuffer): Promise => +{ + if (!$audioContext) { + return ; + } + + try { + + return await $audioContext.decodeAudioData(array_buffer); + + } catch (error) { + + const buffer = new Uint8Array(array_buffer); + let idx: number = 0; + for ( ; idx > buffer.byteLength; ) { + + idx = buffer.indexOf(0xff, idx); + + if (idx === -1 || (buffer[idx + 1] & 0xe0) === 0xe0) { + break; + } + + ++idx; + } + + return await execute(buffer.subarray(idx).buffer); + } +}; \ No newline at end of file diff --git a/packages/media/src/Sound/SoundEndedEventService.test.ts b/packages/media/src/Sound/SoundEndedEventService.test.ts new file mode 100644 index 00000000..cdfc60db --- /dev/null +++ b/packages/media/src/Sound/SoundEndedEventService.test.ts @@ -0,0 +1,48 @@ +import { Sound } from "../Sound"; +import { Event } from "@next2d/events"; +import { execute } from "./SoundEndedEventService"; +import { describe, expect, it, vi } from "vitest"; + +describe("SoundEndedEventService.js namespace test", () => +{ + it("namespace test case1", () => + { + let state = ""; + const MockSound = vi.fn().mockImplementation(() => + { + return { + "canLoop": true, + "play": vi.fn(() => { state = "play" }), + "stop": vi.fn(), + "hasEventListener": vi.fn(), + "dispatchEvent": vi.fn() + } as unknown as Sound; + }); + + expect(state).toBe(""); + execute(new MockSound()); + expect(state).toBe("play"); + }); + + it("namespace test case2", () => + { + let state = ""; + let type = ""; + const MockSound = vi.fn().mockImplementation(() => + { + return { + "canLoop": false, + "play": vi.fn(), + "stop": vi.fn(() => { state = "stop" }), + "willTrigger": vi.fn(() => true), + "dispatchEvent": vi.fn((event: Event) => { type = event.type }) + } as unknown as Sound; + }); + + expect(type).toBe(""); + expect(state).toBe(""); + execute(new MockSound()); + expect(state).toBe("stop"); + expect(type).toBe(Event.SOUND_COMPLETE); + }); +}); \ No newline at end of file diff --git a/packages/media/src/Sound/SoundEndedEventService.ts b/packages/media/src/Sound/SoundEndedEventService.ts new file mode 100644 index 00000000..7da33026 --- /dev/null +++ b/packages/media/src/Sound/SoundEndedEventService.ts @@ -0,0 +1,27 @@ +import type { Sound } from "../Sound"; +import { Event } from "@next2d/events"; + +/** + * @description サウンドデータの再生終了時のイベント実行関数 + * Event execution function when sound data playback ends + * + * @param {Sound} sound + * @return {void} + * @method + * @public + */ +export const execute = (sound: Sound): void => +{ + if (sound.canLoop) { + + sound.play(); + + } else { + + sound.stop(); + + if (sound.willTrigger(Event.SOUND_COMPLETE)) { + sound.dispatchEvent(new Event(Event.SOUND_COMPLETE)); + } + } +}; \ No newline at end of file diff --git a/packages/media/src/Sound/SoundLoadStartEventService.test.ts b/packages/media/src/Sound/SoundLoadStartEventService.test.ts new file mode 100644 index 00000000..6e60c599 --- /dev/null +++ b/packages/media/src/Sound/SoundLoadStartEventService.test.ts @@ -0,0 +1,70 @@ +import { Sound } from "../Sound"; +import { execute } from "./SoundLoadStartEventService"; +import { + Event, + ProgressEvent as Next2DProgressEvent +} from "@next2d/events"; +import { describe, expect, it, vi } from "vitest"; + +describe("SoundLoadStartEventService.js namespace test", () => +{ + it("namespace open event test case1", () => + { + const sound = new Sound(); + + let openState = ""; + sound.addEventListener(Event.OPEN, (event: Event): void => + { + openState = event.type; + }); + + expect(openState).toBe(""); + + // mock event + const MockEvent = vi.fn().mockImplementation(() => + { + return { + "loaded": 1, + "total": 10 + } as unknown as ProgressEvent; + }); + + execute(sound, new MockEvent()); + + expect(openState).toBe(Event.OPEN); + + }); + + it("namespace progress event test case1", () => + { + const sound = new Sound(); + + let openState = ""; + let loaded = 0; + let total = 0; + sound.addEventListener(Next2DProgressEvent.PROGRESS, (event: Next2DProgressEvent): void => + { + openState = event.type; + loaded = event.bytesLoaded; + total = event.bytesTotal; + }); + + expect(openState).toBe(""); + expect(loaded).toBe(0); + expect(total).toBe(0); + + // mock event + const MockEvent = vi.fn().mockImplementation(() => + { + return { + "loaded": 1, + "total": 10 + } as unknown as ProgressEvent; + }); + + execute(sound, new MockEvent()); + + expect(openState).toBe(Next2DProgressEvent.PROGRESS); + + }); +}); \ No newline at end of file diff --git a/packages/media/src/Sound/SoundLoadStartEventService.ts b/packages/media/src/Sound/SoundLoadStartEventService.ts new file mode 100644 index 00000000..396e1b94 --- /dev/null +++ b/packages/media/src/Sound/SoundLoadStartEventService.ts @@ -0,0 +1,29 @@ +import type { Sound } from "../Sound"; +import { + Event, + ProgressEvent as Next2DProgressEvent +} from "@next2d/events"; + +/** + * @description サウンドの読み込みが開始イベントの実行関数 + * Execution function of the sound loading start event + * + * @param {Sound} sound + * @param {ProgressEvent} event + * @return {void} + * @method + * @public + */ +export const execute = (sound: Sound, event: ProgressEvent): void => +{ + if (sound.willTrigger(Event.OPEN)) { + sound.dispatchEvent(new Event(Event.OPEN)); + } + + if (sound.willTrigger(Next2DProgressEvent.PROGRESS)) { + sound.dispatchEvent(new Next2DProgressEvent( + Next2DProgressEvent.PROGRESS, false, false, + event.loaded, event.total + )); + } +}; \ No newline at end of file diff --git a/packages/media/src/Sound/SoundLoadendEventService.test.ts b/packages/media/src/Sound/SoundLoadendEventService.test.ts new file mode 100644 index 00000000..369228c0 --- /dev/null +++ b/packages/media/src/Sound/SoundLoadendEventService.test.ts @@ -0,0 +1,76 @@ +import { Sound } from "../Sound"; +import { execute } from "./SoundLoadendEventService"; +import { + IOErrorEvent, + ProgressEvent as Next2DProgressEvent +} from "@next2d/events"; +import { describe, expect, it, vi } from "vitest"; + +describe("SoundLoadendEventService.js namespace test", () => +{ + it("namespace progress event test case1", () => + { + const sound = new Sound(); + + let openState = ""; + let loaded = 0; + let total = 0; + sound.addEventListener(Next2DProgressEvent.PROGRESS, (event: Next2DProgressEvent): void => + { + openState = event.type; + loaded = event.bytesLoaded; + total = event.bytesTotal; + }); + + expect(openState).toBe(""); + expect(loaded).toBe(0); + expect(total).toBe(0); + + // mock event + const MockEvent = vi.fn().mockImplementation(() => + { + return { + "target": { + "status": 200, + "statusText": "OK" + }, + "loaded": 1, + "total": 10 + } as unknown as ProgressEvent; + }); + + execute(sound, new MockEvent()); + + expect(openState).toBe(Next2DProgressEvent.PROGRESS); + }); + + it("namespace progress event test case2", () => + { + const sound = new Sound(); + + let openState = ""; + sound.addEventListener(IOErrorEvent.IO_ERROR, (event: IOErrorEvent): void => + { + openState = event.type; + }); + + expect(openState).toBe(""); + + // mock event + const MockEvent = vi.fn().mockImplementation(() => + { + return { + "target": { + "status": 404, + "statusText": "Not Found" + }, + "loaded": 1, + "total": 10 + } as unknown as ProgressEvent; + }); + + execute(sound, new MockEvent()); + + expect(openState).toBe(IOErrorEvent.IO_ERROR); + }); +}); \ No newline at end of file diff --git a/packages/media/src/Sound/SoundLoadendEventService.ts b/packages/media/src/Sound/SoundLoadendEventService.ts new file mode 100644 index 00000000..314741bd --- /dev/null +++ b/packages/media/src/Sound/SoundLoadendEventService.ts @@ -0,0 +1,48 @@ +import type { Sound } from "../Sound"; +import { execute as soundDecodeService } from "./SoundDecodeService"; +import { + Event, + ProgressEvent as Next2DProgressEvent, + IOErrorEvent +} from "@next2d/events"; + +/** + * @description サウンドデータのローディング中のイベント実行関数 + * Event execution function during sound data loading + * + * @param {Sound} sound + * @param {ProgressEvent} event + * @return {Promise} + * @method + * @public + */ +export const execute = async (sound: Sound, event: ProgressEvent): Promise => +{ + const target = event.target as XMLHttpRequest; + if (!target) { + return ; + } + + if (sound.willTrigger(Next2DProgressEvent.PROGRESS)) { + sound.dispatchEvent(new Next2DProgressEvent( + Next2DProgressEvent.PROGRESS, false, false, + event.loaded, event.total + )); + } + + if (199 < target.status && 400 > target.status) { + const audioBuffer = await soundDecodeService(target.response); + if (audioBuffer) { + sound.audioBuffer = audioBuffer; + if (sound.willTrigger(Event.COMPLETE)) { + sound.dispatchEvent(new Event(Event.COMPLETE)); + } + } + } else { + if (sound.willTrigger(IOErrorEvent.IO_ERROR)) { + sound.dispatchEvent(new IOErrorEvent( + IOErrorEvent.IO_ERROR, false, false, target.statusText + )); + } + } +}; \ No newline at end of file diff --git a/packages/media/src/Sound/SoundProgressEventService.test.ts b/packages/media/src/Sound/SoundProgressEventService.test.ts new file mode 100644 index 00000000..82776954 --- /dev/null +++ b/packages/media/src/Sound/SoundProgressEventService.test.ts @@ -0,0 +1,40 @@ +import { Sound } from "../Sound"; +import { execute } from "./SoundProgressEventService"; +import { ProgressEvent as Next2DProgressEvent } from "@next2d/events"; +import { describe, expect, it, vi } from "vitest"; + +describe("SoundProgressEventService.js namespace test", () => +{ + it("namespace progress event test case1", () => + { + const sound = new Sound(); + + let openState = ""; + let loaded = 0; + let total = 0; + sound.addEventListener(Next2DProgressEvent.PROGRESS, (event: Next2DProgressEvent): void => + { + openState = event.type; + loaded = event.bytesLoaded; + total = event.bytesTotal; + }); + + expect(openState).toBe(""); + expect(loaded).toBe(0); + expect(total).toBe(0); + + // mock event + const MockEvent = vi.fn().mockImplementation(() => + { + return { + "loaded": 1, + "total": 10 + } as unknown as ProgressEvent; + }); + + execute(sound, new MockEvent()); + + expect(openState).toBe(Next2DProgressEvent.PROGRESS); + + }); +}); \ No newline at end of file diff --git a/packages/media/src/Sound/SoundProgressEventService.ts b/packages/media/src/Sound/SoundProgressEventService.ts new file mode 100644 index 00000000..d88a01db --- /dev/null +++ b/packages/media/src/Sound/SoundProgressEventService.ts @@ -0,0 +1,22 @@ +import type { Sound } from "../Sound"; +import { ProgressEvent as Next2DProgressEvent } from "@next2d/events"; + +/** + * @description サウンドデータのローディング中のイベント実行関数 + * Event execution function during sound data loading + * + * @param {Sound} sound + * @param {ProgressEvent} event + * @return {void} + * @method + * @public + */ +export const execute = (sound: Sound, event: ProgressEvent): void => +{ + if (sound.willTrigger(Next2DProgressEvent.PROGRESS)) { + sound.dispatchEvent(new Next2DProgressEvent( + Next2DProgressEvent.PROGRESS, false, false, + event.loaded, event.total + )); + } +}; \ No newline at end of file diff --git a/packages/media/src/SoundMixer.test.ts b/packages/media/src/SoundMixer.test.ts new file mode 100644 index 00000000..df67497c --- /dev/null +++ b/packages/media/src/SoundMixer.test.ts @@ -0,0 +1,32 @@ +import { SoundMixer } from "./SoundMixer"; +import { describe, expect, it } from "vitest"; + +describe("SoundMixer.js namespace test", () => +{ + it("namespace test public", () => + { + const soundMixer = new SoundMixer(); + expect(soundMixer.namespace).toBe("next2d.media.SoundMixer"); + }); + + it("namespace test static", () => + { + expect(SoundMixer.namespace).toBe("next2d.media.SoundMixer"); + }); +}); + +describe("SoundMixer.js toString test", () => +{ + it("toString test success", () => + { + expect(new SoundMixer().toString()).toBe("[object SoundMixer]"); + }); +}); + +describe("SoundMixer.js static toString test", () => +{ + it("static toString test", () => + { + expect(SoundMixer.toString()).toBe("[class SoundMixer]"); + }); +}); \ No newline at end of file diff --git a/packages/media/src/SoundMixer.ts b/packages/media/src/SoundMixer.ts index 4ff13c10..956fd38f 100644 --- a/packages/media/src/SoundMixer.ts +++ b/packages/media/src/SoundMixer.ts @@ -1,13 +1,6 @@ -import type { Sound } from "./Sound"; -import type { Video } from "./Video"; -import type { Player } from "@next2d/core"; -import { $currentPlayer } from "@next2d/util"; - -/** - * @type {number} - * @private - */ -let $volume: number = 1; +import { execute as soundMixerUpdateVolumeService } from "./SoundMixer/SoundMixerUpdateVolumeService"; +import { execute as soundMixerStopAllService } from "./SoundMixer/SoundMixerStopAllService"; +import { $getVolume } from "./MediaUtil"; /** * SoundMixer クラスには、静的プロパティやアプリケーションのグローバルサウンドコントロールのメソッドが含まれます。 @@ -84,46 +77,11 @@ export class SoundMixer */ static get volume (): number { - return $volume; + return $getVolume(); } static set volume (volume: number) { - $volume = Math.min(Math.max(0, volume), 1); - - const player: Player = $currentPlayer(); - - const sounds: Sound[] = player._$sources; - for (let idx: number = 0; idx < sounds.length; ++idx) { - - const sound: Sound = sounds[idx]; - - for (let idx: number = 0; idx < sound._$sources.length; ++idx) { - - const source: AudioBufferSourceNode = sound._$sources[idx]; - - if (source._$gainNode) { - source._$gainNode.gain.value = Math.min( - $volume, - source._$volume - ); - } - - } - } - - const videos: Video[] = player._$videos; - for (let idx: number = 0; idx < videos.length; ++idx) { - - const video: Video = videos[idx]; - - if (video._$video) { - video._$video.volume = Math.min( - $volume, - video.volume - ); - } - } - + soundMixerUpdateVolumeService(volume); } /** @@ -136,20 +94,6 @@ export class SoundMixer */ static stopAll (): void { - const player: Player = $currentPlayer(); - - // sounds - const sources: Sound[] = player._$sources; - for (let idx: number = 0; idx < sources.length; ++idx) { - sources[idx].stop(); - } - - const videos = player._$videos; - for (let idx: number = 0; idx < videos.length; ++idx) { - videos[idx].pause(); - } - - player._$sources.length = 0; - player._$videos.length = 0; + soundMixerStopAllService(); } -} +} \ No newline at end of file diff --git a/packages/media/src/SoundMixer/SoundMixerStopAllService.ts b/packages/media/src/SoundMixer/SoundMixerStopAllService.ts new file mode 100644 index 00000000..02e36c9f --- /dev/null +++ b/packages/media/src/SoundMixer/SoundMixerStopAllService.ts @@ -0,0 +1,41 @@ +import type { Sound } from "../Sound"; +import type { Video } from "../Video"; +import { + $getSounds, + $getVideos +} from "../MediaUtil"; + +/** + * @description 再生中のサウンドとビデオの全ての再生を停止 + * Stops all playing sounds and videos. + * + * @return {void} + * @method + * @public + */ +export const execute = (): void => +{ + // sounds + const sounds: Sound[] = $getSounds(); + for (let idx: number = 0; idx < sounds.length; ++idx) { + const sound = sounds[idx]; + if (!sound) { + continue; + } + sound.stop(); + } + + // videos + const videos: Video[] = $getVideos(); + for (let idx: number = 0; idx < videos.length; ++idx) { + const video: Video = videos[idx]; + if (!video) { + continue; + } + video.pause(); + } + + // reset + sounds.length = 0; + videos.length = 0; +}; \ No newline at end of file diff --git a/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.ts b/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.ts new file mode 100644 index 00000000..74f7b6ea --- /dev/null +++ b/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.ts @@ -0,0 +1,46 @@ +import type { Sound } from "../Sound"; +import type { Video } from "../Video"; +import { $clamp } from "../../../../common/Util"; +import { + $setVolume, + $getSounds, + $getVideos +} from "../MediaUtil"; + +/** + * @description 再生中のサウンドとビデオの全ての音量を更新 + * Updates the volume of all playing sounds and videos. + * + * @param {number} volume + * @method + * @public + */ +export const execute = (volume: number): void => +{ + volume = $clamp(volume, 0, 1, 1); + + // update volume + $setVolume(volume); + + const sounds: Sound[] = $getSounds(); + for (let idx: number = 0; idx < sounds.length; ++idx) { + + const sound: Sound = sounds[idx]; + if (!sound) { + continue; + } + + sound.volume = Math.min(volume, sound.volume); + } + + const videos: Video[] = $getVideos(); + for (let idx: number = 0; idx < videos.length; ++idx) { + + const video: Video = videos[idx]; + if (!video) { + continue; + } + + video.volume = Math.min(volume, video.volume); + } +}; \ No newline at end of file diff --git a/packages/media/src/SoundTransform.ts b/packages/media/src/SoundTransform.ts index 7961dec6..a77ee4e4 100644 --- a/packages/media/src/SoundTransform.ts +++ b/packages/media/src/SoundTransform.ts @@ -1,3 +1,5 @@ +import { $clamp } from "../../../common/Util"; + /** * @description SoundTransform クラスにはボリュームとループのプロパティが含まれます。 * The SoundTransform class contains properties for volume and loop. @@ -24,8 +26,7 @@ export class SoundTransform * @default 1 * @private */ - this._$volume = 1; - this.volume = volume; + this._$volume = $clamp(volume, 0, 1, 1); /** * @type {boolean} @@ -122,6 +123,6 @@ export class SoundTransform } set volume (volume: number) { - this._$volume = Math.min(Math.max(0, volume), 1); + this._$volume = $clamp(volume, 0, 1); } } diff --git a/packages/media/src/Video.ts b/packages/media/src/Video.ts index e95e7af8..e951e373 100644 --- a/packages/media/src/Video.ts +++ b/packages/media/src/Video.ts @@ -1,61 +1,19 @@ import { SoundMixer } from "./SoundMixer"; import { DisplayObject } from "@next2d/display"; import { VideoEvent } from "@next2d/events"; -import type { Player } from "@next2d/core"; -import type { - BoundsImpl, - VideoCharacterImpl, - DictionaryTagImpl, - ParentImpl, - AttachmentImpl, - FilterArrayImpl, - BlendModeImpl, - PlayerHitObjectImpl, - PropertyVideoMessageImpl, - Character, - CachePositionImpl -} from "@next2d/interface"; -import type { - CanvasToWebGLContext, - FrameBufferManager -} from "@next2d/webgl"; -import { - $document, - $audioContext, - $currentPlayer, - $isTouch, - $rendererWorker -} from "@next2d/util"; -import { - $Math, - $cancelAnimationFrame, - $requestAnimationFrame, - $getBoundsObject, - $boundsMatrix, - $clamp, - $multiplicationMatrix, - $poolFloat32Array6, - $MATRIX_ARRAY_IDENTITY, - $OffscreenCanvas, - $multiplicationColor, - $poolFloat32Array8, - $Infinity, - $poolBoundsObject, - $getArray, - $Number, - $poolArray, - $cacheStore, - $getFloat32Array6 -} from "@next2d/share"; +import type { BoundsImpl } from "./interface/BoundsImpl"; +import { $clamp } from "../../../common/Util"; +import { execute as videoCreateElementService } from "./Video/VideoCreateElementService"; +import { execute as videoPlayEventService } from "./Video/VideoPlayEventService"; +import { $getVideos } from "./MediaUtil"; /** - * サーバーまたはローカルに保存された録画済みビデオファイルを再生する Video オブジェクトです。 - * ビデオストリームを再生するには、attachNetStream() を使用して、ビデオを Video オブジェクトに関連付けます。 - * 次に、addChild() を使用して、Video オブジェクトを表示リストに追加します。 - * - * A Video object that plays a recorded video file stored on a server or locally. - * To play a video stream, use attachNetStream() to attach the video to the Video object. - * Then, add the Video object to the display list using addChild(). + * @description サーバーまたはローカルに保存された録画済みビデオファイルを再生する Video オブジェクトです。 + * ビデオストリームを再生するには、attachNetStream() を使用して、ビデオを Video オブジェクトに関連付けます。 + * 次に、addChild() を使用して、Video オブジェクトを表示リストに追加します。 + * A Video object that plays a recorded video file stored on a server or locally. + * To play a video stream, use attachNetStream() to attach the video to the Video object. + * Then, add the Video object to the display list using addChild(). * * @class * @memberOf next2d.media @@ -67,16 +25,16 @@ export class Video extends DisplayObject private _$loop: boolean; private _$autoPlay: boolean; private readonly _$bounds: BoundsImpl; - private _$bytesLoaded: number; - private _$bytesTotal: number; private _$timerId: number; - public _$video: HTMLVideoElement | null; + private _$videoElement: HTMLVideoElement | null; private _$stop: boolean; private _$volume: number; private _$ready: boolean; - private _$context: OffscreenCanvasRenderingContext2D | null; private _$cacheKeys: string[]; private readonly _$cacheParams: number[]; + private _$duration: number; + private _$currentTime: number; + private _$src: string; /** * @param {number} [width = 0] @@ -111,24 +69,36 @@ export class Video extends DisplayObject this._$autoPlay = true; /** - * @type {object} + * @type {number} + * @default 0 * @private */ - this._$bounds = $getBoundsObject(0, width, 0, height); + this._$duration = 0; /** * @type {number} * @default 0 * @private */ - this._$bytesLoaded = 0; + this._$currentTime = 0; /** - * @type {number} - * @default 0 + * @type {string} + * @default "" + * @private + */ + this._$src = ""; + + /** + * @type {object} * @private */ - this._$bytesTotal = 0; + this._$bounds = { + "xMin": 0, + "xMax": width, + "yMin": 0, + "yMax": height + }; /** * @type {number} @@ -142,7 +112,7 @@ export class Video extends DisplayObject * @default null * @private */ - this._$video = null; + this._$videoElement = null; /** * @type {boolean} @@ -165,24 +135,17 @@ export class Video extends DisplayObject */ this._$volume = 1; - /** - * @type {CanvasRenderingContext2D} - * @default null - * @private - */ - this._$context = null; - /** * @type {array} * @private */ - this._$cacheKeys = $getArray(); + this._$cacheKeys = []; /** * @type {array} * @private */ - this._$cacheParams = $getArray(0, 0, 0); + this._$cacheParams = [0, 0, 0]; } /** @@ -190,7 +153,7 @@ export class Video extends DisplayObject * Returns the string representation of the specified class. * * @return {string} - * @default [class Video] + * @default "[class Video]" * @method * @static */ @@ -204,7 +167,7 @@ export class Video extends DisplayObject * Returns the space name of the specified class. * * @return {string} - * @default next2d.media.Video + * @default "next2d.media.Video" * @const * @static */ @@ -218,7 +181,7 @@ export class Video extends DisplayObject * Returns the string representation of the specified object. * * @return {string} - * @default [object Video] + * @default "[object Video]" * @method * @public */ @@ -232,7 +195,7 @@ export class Video extends DisplayObject * Returns the space name of the specified object. * * @return {string} - * @default next2d.media.Video + * @default "next2d.media.Video" * @const * @public */ @@ -241,46 +204,21 @@ export class Video extends DisplayObject return "next2d.media.Video"; } - /** - * @description 既にアプリケーションにロードされているデータのバイト数です。 - * The number of bytes of data that have been loaded into the application. - * - * @member {number} - * @default 0 - * @readonly - * @public - */ - get bytesLoaded (): number - { - return this._$bytesLoaded; - } - - /** - * @description アプリケーションにロードされるファイルの総バイト数。 - * The total size in bytes of the file being loaded into the application. - * - * @member {number} - * @default 0 - * @readonly - * @public - */ - get bytesTotal (): number - { - return this._$bytesTotal; - } - /** * @description 現在のキーフレーム * Current keyframe * * * @member {number} - * @readonly * @public */ get currentTime (): number { - return this._$video ? this._$video.currentTime : 0; + return this._$currentTime; + } + set currentTime (current_time: number) + { + this._$currentTime = Math.min(this._$duration, current_time); } /** @@ -288,12 +226,15 @@ export class Video extends DisplayObject * Total number of keyframes * * @member {number} - * @readonly * @public */ get duration (): number { - return this._$video ? this._$video.duration : 0; + return this._$duration; + } + set duration (duration: number) + { + this._$duration = duration; } /** @@ -358,16 +299,23 @@ export class Video extends DisplayObject */ get src (): string { - return this._$video ? this._$video.src : ""; + return this._$src; } set src (src: string) { - if (!this._$video) { - this._$video = this._$initializeVideo(); + if (this._$src === src) { + return ; } - this._$video.src = src; - this._$video.load(); + // reset + this._$cacheKeys.length = 0; + this._$currentTime = 0; + + this._$videoElement = null; + this._$videoElement = videoCreateElementService(this, this._$bounds); + + this._$src = this._$videoElement.src = src; + this._$videoElement.load(); } /** @@ -381,7 +329,7 @@ export class Video extends DisplayObject */ get videoHeight (): number { - return this._$video ? this._$video.videoHeight : this._$bounds.yMax; + return this._$bounds.yMax; } /** @@ -395,7 +343,7 @@ export class Video extends DisplayObject */ get videoWidth (): number { - return this._$video ? this._$video.videoWidth : this._$bounds.xMax; + return this._$bounds.xMax; } /** @@ -412,13 +360,13 @@ export class Video extends DisplayObject } set volume (volume: number) { - this._$volume = $clamp($Math.min( + this._$volume = $clamp(Math.min( SoundMixer.volume, volume ), 0, 1, 1); - if (this._$video) { - this._$video.volume = this._$volume; + if (this._$videoElement) { + this._$videoElement.volume = this._$volume; } } @@ -433,14 +381,17 @@ export class Video extends DisplayObject */ clear (): void { - if (this._$video) { - this._$video.pause(); + if (this._$videoElement) { + this._$videoElement.pause(); } // reset - this._$video = null; - this._$bounds.xMax = 0; - this._$bounds.yMax = 0; + this._$currentTime = 0; + this._$duration = 0; + this._$volume = 0; + this._$videoElement = null; + this._$bounds.xMax = 0; + this._$bounds.yMax = 0; this._$doChanged(); } @@ -455,25 +406,22 @@ export class Video extends DisplayObject */ pause (): void { - if (this._$video && !this._$stop) { + if (this._$videoElement && !this._$stop) { this._$stop = true; - this._$video.pause(); + this._$videoElement.pause(); - $cancelAnimationFrame(this._$timerId); - this._$timerId = -1; + cancelAnimationFrame(this._$timerId); - if (this.hasEventListener(VideoEvent.PAUSE)) { - this.dispatchEvent(new VideoEvent( - VideoEvent.PAUSE, false, false, - this._$bytesLoaded, this._$bytesTotal - )); + if (this.willTrigger(VideoEvent.PAUSE)) { + this.dispatchEvent(new VideoEvent(VideoEvent.PAUSE)); } - const player: Player = $currentPlayer(); - player._$videos.splice( - player._$videos.indexOf(this), 1 - ); + const videos = $getVideos(); + const index = videos.indexOf(this); + if (index > -1) { + videos.splice(index, 1); + } } } @@ -485,35 +433,28 @@ export class Video extends DisplayObject * @method * @public */ - play (): void + async play (): Promise { - if (this._$video && this._$stop) { + if (this._$videoElement && this._$stop) { this._$stop = false; - this._$video.volume = $Math.min(this._$volume, SoundMixer.volume); - this - ._$video - .play() - .then(() => - { - this._$timerId = $requestAnimationFrame(() => - { - this._$update(); - }); - - if (this.hasEventListener(VideoEvent.PLAY)) { - this.dispatchEvent(new VideoEvent( - VideoEvent.PLAY, false, false, - this._$bytesLoaded, this._$bytesTotal - )); - } - - const player = $currentPlayer(); - if (player._$videos.indexOf(this) === -1) { - player._$videos.push(this); - } - }); + this._$videoElement.volume = this._$volume; + await this._$videoElement.play(); + + this._$timerId = videoPlayEventService(this); + + if (this.hasEventListener(VideoEvent.PLAY_START)) { + this.dispatchEvent(new VideoEvent(VideoEvent.PLAY_START)); + } + + const videos = $getVideos(); + const index = videos.indexOf(this); + if (index > -1) { + videos.splice(index, 1); + } + + videos.push(this); } } @@ -528,180 +469,12 @@ export class Video extends DisplayObject */ seek (offset: number): void { - if (this._$video) { - this._$video.currentTime = $Math.min(this._$video.duration, offset); - - if (this.hasEventListener(VideoEvent.SEEK)) { - this.dispatchEvent(new VideoEvent( - VideoEvent.SEEK, false, false, - this._$bytesLoaded, this._$bytesTotal - )); - } - } - } - - /** - * @return {void} - * @method - * @private - */ - _$update (): void - { - const player: Player = $currentPlayer(); - if (!this.stage || !this._$video) { + if (this._$videoElement) { + this._$currentTime = this._$videoElement.currentTime = Math.min(this._$duration, offset); - if (this._$video) { - this._$video.pause(); + if (this.willTrigger(VideoEvent.SEEK)) { + this.dispatchEvent(new VideoEvent(VideoEvent.SEEK)); } - - $cancelAnimationFrame(this._$timerId); - this._$timerId = -1; - - player._$videos.splice( - player._$videos.indexOf(this), 1 - ); - - return ; - } - - if ($rendererWorker) { - this._$postProperty(); - } - - // update - this._$bytesLoaded = this._$video.currentTime; - if (this._$video.currentTime) { - - if (this.hasEventListener(VideoEvent.PROGRESS)) { - this.dispatchEvent(new VideoEvent( - VideoEvent.PROGRESS, false, false, - this._$bytesLoaded, this._$bytesTotal - )); - } - - this._$doChanged(); - } - - this._$timerId = $requestAnimationFrame(() => - { - this._$update(); - }); - } - - /** - * @return {Promise} - * @method - * @private - */ - async _$start (): Promise - { - if (!this._$video) { - return ; - } - - this._$bounds.xMax = this._$video.videoWidth; - this._$bounds.yMax = this._$video.videoHeight; - this._$bytesTotal = this._$video.duration; - - // init play and stop, reset - if (!this._$ready) { - await this._$video.play(); - this._$video.pause(); - this._$video.currentTime = 0; - this._$ready = true; - } - - if (this._$autoPlay) { - - this._$stop = false; - - const player = $currentPlayer(); - if (player._$videos.indexOf(this) === -1) { - player._$videos.push(this); - } - - if (this.hasEventListener(VideoEvent.PLAY_START)) { - this.dispatchEvent(new VideoEvent( - VideoEvent.PLAY_START, false, false, - this._$bytesLoaded, this._$bytesTotal - )); - } - - this._$timerId = $requestAnimationFrame(() => - { - this._$update(); - }); - - this._$doChanged(); - } - - this._$createContext(); - } - - /** - * @return {HTMLVideoElement} - * @method - * @private - */ - _$initializeVideo (): HTMLVideoElement - { - // clear cache key - this._$cacheKeys.length = 0; - - const video = $document.createElement("video"); - - video.autoplay = false; - video.crossOrigin = "anonymous"; - - if (!$audioContext) { - video.muted = true; - } - - if ($isTouch) { - video.setAttribute("playsinline", ""); - } - - video.addEventListener("canplaythrough", async (): Promise => - { - await this._$start(); - }); - - video.addEventListener("ended", () => - { - if (this._$loop) { - video.currentTime = 0; - return ; - } - - if (this.hasEventListener(VideoEvent.PLAY_END)) { - this.dispatchEvent(new VideoEvent( - VideoEvent.PLAY_END, false, false, - this._$bytesLoaded, this._$bytesTotal - )); - } - - $cancelAnimationFrame(this._$timerId); - - this._$timerId = -1; - - }); - - return video; - } - - /** - * @return {void} - * @method - * @private - */ - _$createContext (): void - { - if ($rendererWorker) { - const canvas = new $OffscreenCanvas( - this._$bounds.xMax, - this._$bounds.yMax - ); - this._$context = canvas.getContext("2d"); } } @@ -725,18 +498,18 @@ export class Video extends DisplayObject this._$bounds.xMax = character.bounds.xMax; this._$bounds.yMax = character.bounds.yMax; - if (!this._$video) { - this._$video = this._$initializeVideo(); + if (!this._$videoElement) { + this._$videoElement = videoCreateElementService(this); } - this._$video.src = URL.createObjectURL(new Blob( + this._$videvideoElemento.src = URL.createObjectURL(new Blob( [character._$buffer], { "type": "video/mp4" } )); // setup - this._$video.volume = $Math.min(character.volume, SoundMixer.volume); - this._$video.load(); + this._$videoElement.volume = Math.min(character.volume, SoundMixer.volume); + this._$videoElement.load(); if ($rendererWorker && this._$stage) { this._$createWorkerInstance(); @@ -830,7 +603,7 @@ export class Video extends DisplayObject color_transform: Float32Array ): void { - if (!this._$visible || !this._$video || !this._$ready) { + if (!this._$visible || !this._$videoElement || !this._$ready) { return ; } @@ -869,8 +642,8 @@ export class Video extends DisplayObject const yMin = +bounds.yMin; $poolBoundsObject(bounds); - const width: number = $Math.ceil($Math.abs(xMax - xMin)); - const height: number = $Math.ceil($Math.abs(yMax - yMin)); + const width: number = Math.ceil(Math.abs(xMax - xMin)); + const height: number = Math.ceil(Math.abs(yMax - yMin)); switch (true) { case width === 0: @@ -886,7 +659,7 @@ export class Video extends DisplayObject } - let xScale: number = +$Math.sqrt( + let xScale: number = +Math.sqrt( multiMatrix[0] * multiMatrix[0] + multiMatrix[1] * multiMatrix[1] ); @@ -899,7 +672,7 @@ export class Video extends DisplayObject xScale = +xScale.toFixed(4); } - let yScale: number = +$Math.sqrt( + let yScale: number = +Math.sqrt( multiMatrix[2] * multiMatrix[2] + multiMatrix[3] * multiMatrix[3] ); @@ -964,8 +737,8 @@ export class Video extends DisplayObject context.cachePosition = $cacheStore.get(this._$cacheKeys); if (!context.cachePosition) { - const width: number = $Math.ceil($Math.abs(this._$bounds.xMax - this._$bounds.xMin)); - const height: number = $Math.ceil($Math.abs(this._$bounds.yMax - this._$bounds.yMin)); + const width: number = Math.ceil(Math.abs(this._$bounds.xMax - this._$bounds.xMin)); + const height: number = Math.ceil(Math.abs(this._$bounds.yMax - this._$bounds.yMin)); const position: CachePositionImpl = manager .createCachePosition(width, height); @@ -975,7 +748,7 @@ export class Video extends DisplayObject } const texture: WebGLTexture = manager.createTextureFromVideo( - this._$video, this._$smoothing + this._$videoElement, this._$smoothing ); let offsetX: number = 0; @@ -1132,8 +905,8 @@ export class Video extends DisplayObject $poolBoundsObject(bounds); $poolBoundsObject(baseBounds); - const width: number = $Math.ceil($Math.abs(xMax - xMin)); - const height: number = $Math.ceil($Math.abs(yMax - yMin)); + const width: number = Math.ceil(Math.abs(xMax - xMin)); + const height: number = Math.ceil(Math.abs(yMax - yMin)); context.setTransform(1, 0, 0, 1, xMin, yMin); context.beginPath(); @@ -1183,85 +956,85 @@ export class Video extends DisplayObject ); } - /** - * @return {void} - * @method - * @private - */ - _$createWorkerInstance (): void - { - if (!$rendererWorker || this._$created) { - return ; - } - this._$created = true; - - const message: PropertyVideoMessageImpl = { - "command": "createVideo", - "buffer": new Float32Array(0), - "instanceId": this._$instanceId, - "parentId": this._$parent ? this._$parent._$instanceId : -1, - "smoothing": this._$smoothing, - "xMin": this._$bounds.xMin, - "yMin": this._$bounds.yMin, - "xMax": this._$bounds.xMax, - "yMax": this._$bounds.yMax - }; - - if (this._$characterId > -1) { - message.characterId = this._$characterId; - } - - if (this._$loaderInfo) { - message.loaderInfoId = this._$loaderInfo._$id; - } - - if (this._$scale9Grid) { - message.grid = { - "x": this._$scale9Grid.x, - "y": this._$scale9Grid.y, - "w": this._$scale9Grid.width, - "h": this._$scale9Grid.height - }; - } - - $rendererWorker.postMessage(message); - } - - /** - * @return {void} - * @method - * @private - */ - _$postProperty (): void - { - if (!$rendererWorker) { - return ; - } - - const message: PropertyVideoMessageImpl = this._$createMessage(); - message.smoothing = this._$smoothing; - - const options = $getArray(); - const context = this._$context; - if (context && this._$video) { - - message.xMin = this._$bounds.xMin; - message.yMin = this._$bounds.yMin; - message.xMax = this._$bounds.xMax; - message.yMax = this._$bounds.yMax; - - context.drawImage(this._$video, 0, 0); - - const imageBitmap = context.canvas.transferToImageBitmap(); - message.imageBitmap = imageBitmap; - options.push(imageBitmap); - } - - $rendererWorker.postMessage(message, options); - - $poolArray(options); - - this._$posted = true; - this._$updated = false; - } + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$createWorkerInstance (): void + // { + // if (!$rendererWorker || this._$created) { + // return ; + // } + // this._$created = true; + + // const message: PropertyVideoMessageImpl = { + // "command": "createVideo", + // "buffer": new Float32Array(0), + // "instanceId": this._$instanceId, + // "parentId": this._$parent ? this._$parent._$instanceId : -1, + // "smoothing": this._$smoothing, + // "xMin": this._$bounds.xMin, + // "yMin": this._$bounds.yMin, + // "xMax": this._$bounds.xMax, + // "yMax": this._$bounds.yMax + // }; + + // if (this._$characterId > -1) { + // message.characterId = this._$characterId; + // } + + // if (this._$loaderInfo) { + // message.loaderInfoId = this._$loaderInfo._$id; + // } + + // if (this._$scale9Grid) { + // message.grid = { + // "x": this._$scale9Grid.x, + // "y": this._$scale9Grid.y, + // "w": this._$scale9Grid.width, + // "h": this._$scale9Grid.height + // }; + // } + + // $rendererWorker.postMessage(message); + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$postProperty (): void + // { + // if (!$rendererWorker) { + // return ; + // } + + // const message: PropertyVideoMessageImpl = this._$createMessage(); + // message.smoothing = this._$smoothing; + + // const options = $getArray(); + // const context = this._$context; + // if (context && this._$video) { + + // message.xMin = this._$bounds.xMin; + // message.yMin = this._$bounds.yMin; + // message.xMax = this._$bounds.xMax; + // message.yMax = this._$bounds.yMax; + + // context.drawImage(this._$video, 0, 0); + + // const imageBitmap = context.canvas.transferToImageBitmap(); + // message.imageBitmap = imageBitmap; + // options.push(imageBitmap); + // } + + // $rendererWorker.postMessage(message, options); + + // $poolArray(options); + + // this._$posted = true; + // this._$updated = false; + // } } diff --git a/packages/media/src/Video/VideoCanplaythroughEventService.ts b/packages/media/src/Video/VideoCanplaythroughEventService.ts new file mode 100644 index 00000000..29622288 --- /dev/null +++ b/packages/media/src/Video/VideoCanplaythroughEventService.ts @@ -0,0 +1,34 @@ +import type { Video } from "../Video"; +import { Event } from "@next2d/events"; + +/** + * @description 再生可能処理 + * Playable processing + * + * @param {Video} video + * @param {HTMLVideoElement} element + * @return {Promise} + * @method + * @protected + */ +export const execute = async ( + video: Video, + element: HTMLVideoElement +): Promise => { + + if (video.autoPlay) { + + await video.play(); + + } else { + await element.play(); + element.pause(); + element.currentTime = 0; + } + + video._$doChanged(); + + if (video.willTrigger(Event.COMPLETE)) { + video.dispatchEvent(new Event(Event.COMPLETE)); + } +}; \ No newline at end of file diff --git a/packages/media/src/Video/VideoCreateElementService.ts b/packages/media/src/Video/VideoCreateElementService.ts new file mode 100644 index 00000000..94dd3c54 --- /dev/null +++ b/packages/media/src/Video/VideoCreateElementService.ts @@ -0,0 +1,47 @@ +import type { BoundsImpl } from "../interface/BoundsImpl"; +import type { Video } from "../Video"; +import { execute as videoCanplaythroughEventService } from "./VideoCanplaythroughEventService"; +import { execute as videoLoadedmetadataEventService } from "./VideoLoadedmetadataEventService"; +import { execute as videoProgressEventService } from "./VideoProgressEventService"; +import { execute as videoEndedEventService } from "./VideoEndedEventService"; + +/** + * @description HTMLVideoElementを作成して、各種イベントを設定する + * Create an HTMLVideoElement and set various events + * + * @param {Video} video + * @return {HTMLVideoElement} + * @method + * @protected + */ +export const execute = (video: Video, bounds: BoundsImpl): HTMLVideoElement => +{ + const element = document.createElement("video"); + element.autoplay = false; + element.crossOrigin = "anonymous"; + + // Required for iOS + element.setAttribute("playsinline", ""); + + element.addEventListener("loadedmetadata", (): void => + { + videoLoadedmetadataEventService(video, element, bounds); + }, { "once": true }); + + element.addEventListener("progress", (event: ProgressEvent): void => + { + videoProgressEventService(video, event); + }); + + element.addEventListener("canplaythrough", async (): Promise => + { + await videoCanplaythroughEventService(video, element); + }, { "once": true }); + + element.addEventListener("ended", (): void => + { + videoEndedEventService(video); + }); + + return element; +}; \ No newline at end of file diff --git a/packages/media/src/Video/VideoEndedEventService.ts b/packages/media/src/Video/VideoEndedEventService.ts new file mode 100644 index 00000000..eeb6bb22 --- /dev/null +++ b/packages/media/src/Video/VideoEndedEventService.ts @@ -0,0 +1,25 @@ +import type { Video } from "../Video"; +import { VideoEvent } from "@next2d/events"; + +/** + * @description ビデオが最終フレームに達したときの処理 + * Processing when the video reaches the last frame + * + * @param {Video} video + * @return {void} + * @method + * @protected + */ +export const execute = (video: Video): void => +{ + if (video.willTrigger(VideoEvent.PLAY_END)) { + video.dispatchEvent(new VideoEvent(VideoEvent.PLAY_END)); + } + + if (video.loop) { + video.currentTime = 0; + return ; + } + + video.pause(); +}; \ No newline at end of file diff --git a/packages/media/src/Video/VideoLoadedmetadataEventService.ts b/packages/media/src/Video/VideoLoadedmetadataEventService.ts new file mode 100644 index 00000000..fea1b73d --- /dev/null +++ b/packages/media/src/Video/VideoLoadedmetadataEventService.ts @@ -0,0 +1,26 @@ +import type { BoundsImpl } from "../interface/BoundsImpl"; +import type { Video } from "../Video"; + +/** + * @description Videoオブジェクトの幅と高さを更新する + * Update the width and height of the Video object + * + * @param {HTMLVideoElement} element + * @param {object} bounds + * @return {void} + * @method + * @protected + */ +export const execute = ( + video: Video, + element: HTMLVideoElement, + bounds: BoundsImpl +): void => { + + // update metadata + video.currentTime = 0; + video.duration = element.duration; + + bounds.xMax = element.videoWidth; + bounds.yMax = element.videoHeight; +}; \ No newline at end of file diff --git a/packages/media/src/Video/VideoPlayEventService.ts b/packages/media/src/Video/VideoPlayEventService.ts new file mode 100644 index 00000000..b5d2da21 --- /dev/null +++ b/packages/media/src/Video/VideoPlayEventService.ts @@ -0,0 +1,30 @@ +import type { Video } from "../Video"; +import { VideoEvent } from "@next2d/events"; + +/** + * @description ビデオ再生中のイベント処理関数 + * Event processing function during video playback + * + * @param {Video} video + * @return {void} + * @method + * @protected + */ +export const execute = (video: Video): number => +{ + if (!video.stage) { + video.pause(); + return -1; + } + + if (video.willTrigger(VideoEvent.PLAY)) { + video.dispatchEvent(new VideoEvent(VideoEvent.PLAY)); + } + + video._$doChanged(); + + return requestAnimationFrame(() => + { + execute(video); + }); +}; \ No newline at end of file diff --git a/packages/media/src/Video/VideoProgressEventService.ts b/packages/media/src/Video/VideoProgressEventService.ts new file mode 100644 index 00000000..3de4a008 --- /dev/null +++ b/packages/media/src/Video/VideoProgressEventService.ts @@ -0,0 +1,21 @@ +import type { Video } from "../Video"; +import { ProgressEvent as Next2DProgressEvent } from "@next2d/events"; + +/** + * @description ビデオ読み込み中の進捗状態の確認イベント処理関数 + * Event processing function to check the progress status of video loading + * + * @param {Video} video + * @return {void} + * @method + * @protected + */ +export const execute = (video: Video, event: ProgressEvent): void => +{ + if (video.willTrigger(Next2DProgressEvent.PROGRESS)) { + video.dispatchEvent(new Next2DProgressEvent( + Next2DProgressEvent.PROGRESS, + false, false, event.loaded, event.total + )); + } +}; \ No newline at end of file diff --git a/packages/media/src/interface/BoundsImpl.ts b/packages/media/src/interface/BoundsImpl.ts new file mode 100644 index 00000000..7af56a28 --- /dev/null +++ b/packages/media/src/interface/BoundsImpl.ts @@ -0,0 +1,6 @@ +export interface BoundsImpl { + xMin: number; + xMax: number; + yMin: number; + yMax: number; +} \ No newline at end of file diff --git a/packages/media/src/interface/SoundTagImpl.ts b/packages/media/src/interface/SoundTagImpl.ts new file mode 100644 index 00000000..1f87f809 --- /dev/null +++ b/packages/media/src/interface/SoundTagImpl.ts @@ -0,0 +1,6 @@ +export interface SoundTagImpl { + characterId: number; + volume: number; + autoPlay: boolean; + loopCount: number; +} \ No newline at end of file diff --git a/packages/util/src/Util.ts b/packages/util/src/Util.ts index e6fd77c2..ec5747ba 100644 --- a/packages/util/src/Util.ts +++ b/packages/util/src/Util.ts @@ -1,4 +1,3 @@ -import { URLRequestHeader } from "@next2d/net"; import { Player } from "@next2d/core"; import { Event as Next2DEvent } from "@next2d/events"; import { @@ -938,7 +937,7 @@ export const $ajax = (option: AjaxOptionImpl) => // set request header for (let idx: number = 0; idx < option.headers.length; ++idx) { - const header: URLRequestHeader = option.headers[idx]; + const header = option.headers[idx]; xmlHttpRequest.setRequestHeader(header.name, header.value); } @@ -951,7 +950,7 @@ export const $ajax = (option: AjaxOptionImpl) => */ export const $headerToArray = (header: string) => { - const results: URLRequestHeader[] = $getArray(); + const results = $getArray(); if (header) { const headers = header.trim().split("\n"); diff --git a/src/index.ts b/src/index.ts index 77df967c..8214bb93 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,12 @@ import { } from "@next2d/util"; import { Next2D } from "@next2d/core"; +/** + * @type {NodeJS.Timeout} + * @private + */ +let $resizeTimerId: NodeJS.Timeout; + if (!("next2d" in window)) { console.log("%c Next2D Player %c 1.18.12 %c https://next2d.app", @@ -13,6 +19,14 @@ if (!("next2d" in window)) { "color: #fff; background: #4bc729", ""); + window.addEventListener("resize", (): void => + { + clearTimeout($resizeTimerId); + $resizeTimerId = setTimeout(() => { + // TODO: resize event + }, 300); + }); + window.next2d = new Next2D([new Promise((resolve) => { if (document.readyState === "loading") { diff --git a/vite.config.ts b/vite.config.ts index bfb3b8b5..b4abe774 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -4,6 +4,7 @@ import { defineConfig } from "vite"; import path from "path"; +console.log(path.resolve(process.cwd(), "./")); export default defineConfig({ "server": { @@ -23,7 +24,7 @@ export default defineConfig({ }, "resolve": { "alias": { - "@": path.resolve(process.cwd(), "./src/js") + "@": path.resolve(process.cwd(), "/") } }, "test": { From 66be7b3aecc96ef8c56286828b92b82bd7f810e1 Mon Sep 17 00:00:00 2001 From: ienaga Date: Sat, 27 Jul 2024 19:16:15 +0900 Subject: [PATCH 023/343] =?UTF-8?q?#154=20feat:=20package.json=E3=80=81=20?= =?UTF-8?q?test:=20UnitTest=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/Util.ts | 5 +- jingle.mp3 | Bin 110758 -> 0 bytes package-lock.json | 160 +++++++++--------- package.json | 16 +- packages/media/src/Sound.ts | 2 +- .../SoundMixerStopAllService.test.ts | 47 +++++ .../SoundMixerUpdateVolumeService.test.ts | 54 ++++++ .../SoundMixerUpdateVolumeService.ts | 4 +- packages/media/src/Video.ts | 3 + .../VideoCanplaythroughEventService.test.ts | 93 ++++++++++ 10 files changed, 289 insertions(+), 95 deletions(-) delete mode 100644 jingle.mp3 create mode 100644 packages/media/src/SoundMixer/SoundMixerStopAllService.test.ts create mode 100644 packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.test.ts create mode 100644 packages/media/src/Video/VideoCanplaythroughEventService.test.ts diff --git a/common/Util.ts b/common/Util.ts index 32ad7809..f6020577 100644 --- a/common/Util.ts +++ b/common/Util.ts @@ -11,8 +11,9 @@ import type { AjaxOptionImpl } from "./interface/AjaxOptionImpl"; */ export const $clamp = ( value: number, - min: number, max: number, - default_value: number|null = null + min: number, + max: number, + default_value: number | null = null ): number => { const number: number = +value; diff --git a/jingle.mp3 b/jingle.mp3 deleted file mode 100644 index 179a0796d2c14f215c26a5dc620ad9a78c46c6f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110758 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

uvS}7nr1CwUdx!^yiEF2#8MJ=p<&NrH<5T} zL{&#hi`J(_=tz8Mc7y}%pbO>jfooZfnh0uEXplhq4y$ADHFBXg5aA`e%<6*7^p~C*Eu@%>#A!`n0}^lk zgC}t{y~&@wS~m@V4kI4iM-2AQ-L$=|w2Bxoo8ITphs+hT$|*oYR>ZG={`v^ot8NJ1 ztsUnNuFLyiAtuNgnHY;rN9poo&}b1|V~SOI%5RzDcGyB~i%!homsfLO;Hpb}hMJAk zTH|BrkeCO9<`Nw0p*aX#3zZ2^=g_6l0Pt_gR;*Y(`-0Z$ks-v~EvoYaeMy)Sv; zPbF{v?H7uR>|U1+zC1cue9na5HG0xoeqCvEcQ7=?YMkc-Qr5W^Dkp3h5kUq`~!{({tpuC3RWz%YKEGEQ-bA+5KjdaFL1X%KAXg&qW|ZZlN@ zY_t?11p(?Mrd(lb5ox|m(|cKD?ljM1Lz1o@vAoVw-TQf^YR;IB@P@vsCKcDv#vxyx zHvFnak|I$1j3}032#ShI<$B3S$dVd63)jviW1XB3CBN^U3%G-#$5`PRKc(NWMB#q$ z7mK#Y(PCD2_>-a##nIvq~vg@oNw63EiMb~*Iv0>pqqBh~ioHuLU$ zZ?>>$-eC+@(r*e0;RaU=6*dGx`opdbWj4%-J0a6$zRsgRi8K{Xx@R54ziZ3w$R<6Eo38d2k^l zm(rPjuTsGQS(fo&TQb)(d;7S1JhTI$QLp*MDD%({C8tt}GnCOm@peixsoJV@!3x^; z!!C!7^!Jq!AQy_KN+4 zKEF13RMKKnut!Ues~v)cdNv>&Oh~6^G&&Zf^4vgkjgmnIcFjJ53M)H7J*mgt6P z_n^ZvwsoA;ehe^vJJizOtPVf5^2yO(PRIVNa|fhXGtsBm7&(7DxV`48WiilZTK>x` zY~i0}mwGt&ey4lt*;Jyd-8E^@!u?$SVgW8C%_H(e>sHX{w+9`@xoeDn_1W;CjrgcX|LogHK_jhbzhbfAy16$^PCDNpY+goEZFr!NAj1;p@$o;b_9Z<_*7u2*;(-&jnK(hSV#+#Dnz(#oKYBp~30v zvPU``0F`I5=U4c1>&LwoWRDtF6y+}~PzobI!5J{##_rNKAnQo!a?OQ*;+0HP8O&C` z4kH=R^1vCeA4%)muOvrDE!(8&zMi5JTm4*4KM;1P%!s&CNq^1HOa?>z(f6CCPp_tc zGl)S-HGPRSMGgD_x=Jxli{i!^po*`n&HZKVY_Y)Ctmi==GYB*uuxSpHX)?7&I zL%UT=WJKCG7r{fHv!)68TkcjXCov#tY>Ji3xlWqHl^j*NF}Ivn6>> zEXmcRQyc{&7JcMYP+kq(Op3#WbirZ>+{4G6E1mFpR-KW4{qdx#cVbR`o>^b;rhOmh z%nBpQJ>xC)wX2I{& zweNE%Pn$J={j9|T9}?T)s5oU<(P}BJj8=O()h8i_fAdb=HhN`z#r9KT$Bglk`rR!d z>xcfR_q#8|tU(tINrkvnDxD9tR|k9FpX`|~Z&ZB#p#|LC@gM9$P32e>{c~ZybKM&Q zoj?v!VNEzm5jE2&Q)R_fS1!ye$WBS%bVqyTxoIpxmYEFw;SD2X#`1&>Q!&R82HX|E zJ_HzeL2l+ghYEw9jr95om4oq@<$>GH+cUucrZAjMUaF3&L0pdq{nu8i)I$#a|Ic=X z>yhYT>CAdsg>xvcNvy%W&m@{Q0#JX1$CywQT!!fc&9&Iy8vT>L2*)|Ms4PVBv7W!Tg zH0+mNzi|E`6idj&6)v0~OWQp#p)y{I6J>kmze#Zzk0V16rDU~

^cN(7nMTeI>JT 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 diff --git a/package-lock.json b/package-lock.json index 2045b7db..0e5d8189 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,17 +15,17 @@ "htmlparser2": "^9.1.0" }, "devDependencies": { - "@types/node": "^20.14.11", - "@typescript-eslint/eslint-plugin": "^7.16.1", - "@typescript-eslint/parser": "^7.16.1", - "@vitest/web-worker": "^2.0.3", - "eslint": "^8.52.0", + "@types/node": "^20.14.12", + "@typescript-eslint/eslint-plugin": "^7.17.0", + "@typescript-eslint/parser": "^7.17.0", + "@vitest/web-worker": "^2.0.4", + "eslint": "^8.57.0", "eslint-plugin-unused-imports": "^3.2.0", "fflate": "^0.8.2", "jsdom": "^24.1.1", - "typescript": "^5.5.3", - "vite": "^5.3.4", - "vitest": "^2.0.3" + "typescript": "^5.5.4", + "vite": "^5.3.5", + "vitest": "^2.0.4" }, "funding": { "type": "github", @@ -742,9 +742,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", - "integrity": "sha512-JlPfZ/C7yn5S5p0yKk7uhHTTnFlvTgLetl2VxqE518QgyM7C9bSfFTYvB/Q/ftkq0RIPY4ySxTz+/wKJ/dXC0w==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.1.tgz", + "integrity": "sha512-XzqSg714++M+FXhHfXpS1tDnNZNpgxxuGZWlRG/jSj+VEPmZ0yg6jV4E0AL3uyBKxO8mO3xtOsP5mQ+XLfrlww==", "cpu": [ "arm" ], @@ -756,9 +756,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.0.tgz", - "integrity": "sha512-RDxUSY8D1tWYfn00DDi5myxKgOk6RvWPxhmWexcICt/MEC6yEMr4HNCu1sXXYLw8iAsg0D44NuU+qNq7zVWCrw==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.1.tgz", + "integrity": "sha512-thFUbkHteM20BGShD6P08aungq4irbIZKUNbG70LN8RkO7YztcGPiKTTGZS7Kw+x5h8hOXs0i4OaHwFxlpQN6A==", "cpu": [ "arm64" ], @@ -770,9 +770,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.0.tgz", - "integrity": "sha512-emvKHL4B15x6nlNTBMtIaC9tLPRpeA5jMvRLXVbl/W9Ie7HhkrE7KQjvgS9uxgatL1HmHWDXk5TTS4IaNJxbAA==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.1.tgz", + "integrity": "sha512-8o6eqeFZzVLia2hKPUZk4jdE3zW7LCcZr+MD18tXkgBBid3lssGVAYuox8x6YHoEPDdDa9ixTaStcmx88lio5Q==", "cpu": [ "arm64" ], @@ -784,9 +784,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.0.tgz", - "integrity": "sha512-fO28cWA1dC57qCd+D0rfLC4VPbh6EOJXrreBmFLWPGI9dpMlER2YwSPZzSGfq11XgcEpPukPTfEVFtw2q2nYJg==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.1.tgz", + "integrity": "sha512-4T42heKsnbjkn7ovYiAdDVRRWZLU9Kmhdt6HafZxFcUdpjlBlxj4wDrt1yFWLk7G4+E+8p2C9tcmSu0KA6auGA==", "cpu": [ "x64" ], @@ -798,9 +798,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.0.tgz", - "integrity": "sha512-2Rn36Ubxdv32NUcfm0wB1tgKqkQuft00PtM23VqLuCUR4N5jcNWDoV5iBC9jeGdgS38WK66ElncprqgMUOyomw==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.1.tgz", + "integrity": "sha512-MXg1xp+e5GhZ3Vit1gGEyoC+dyQUBy2JgVQ+3hUrD9wZMkUw/ywgkpK7oZgnB6kPpGrxJ41clkPPnsknuD6M2Q==", "cpu": [ "arm" ], @@ -812,9 +812,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.0.tgz", - "integrity": "sha512-gJuzIVdq/X1ZA2bHeCGCISe0VWqCoNT8BvkQ+BfsixXwTOndhtLUpOg0A1Fcx/+eA6ei6rMBzlOz4JzmiDw7JQ==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.1.tgz", + "integrity": "sha512-DZNLwIY4ftPSRVkJEaxYkq7u2zel7aah57HESuNkUnz+3bZHxwkCUkrfS2IWC1sxK6F2QNIR0Qr/YXw7nkF3Pw==", "cpu": [ "arm" ], @@ -826,9 +826,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.0.tgz", - "integrity": "sha512-0EkX2HYPkSADo9cfeGFoQ7R0/wTKb7q6DdwI4Yn/ULFE1wuRRCHybxpl2goQrx4c/yzK3I8OlgtBu4xvted0ug==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.1.tgz", + "integrity": "sha512-C7evongnjyxdngSDRRSQv5GvyfISizgtk9RM+z2biV5kY6S/NF/wta7K+DanmktC5DkuaJQgoKGf7KUDmA7RUw==", "cpu": [ "arm64" ], @@ -840,9 +840,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.0.tgz", - "integrity": "sha512-GlIQRj9px52ISomIOEUq/IojLZqzkvRpdP3cLgIE1wUWaiU5Takwlzpz002q0Nxxr1y2ZgxC2obWxjr13lvxNQ==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.1.tgz", + "integrity": "sha512-89tFWqxfxLLHkAthAcrTs9etAoBFRduNfWdl2xUs/yLV+7XDrJ5yuXMHptNqf1Zw0UCA3cAutkAiAokYCkaPtw==", "cpu": [ "arm64" ], @@ -854,9 +854,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.0.tgz", - "integrity": "sha512-N6cFJzssruDLUOKfEKeovCKiHcdwVYOT1Hs6dovDQ61+Y9n3Ek4zXvtghPPelt6U0AH4aDGnDLb83uiJMkWYzQ==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.1.tgz", + "integrity": "sha512-PromGeV50sq+YfaisG8W3fd+Cl6mnOOiNv2qKKqKCpiiEke2KiKVyDqG/Mb9GWKbYMHj5a01fq/qlUR28PFhCQ==", "cpu": [ "ppc64" ], @@ -868,9 +868,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.0.tgz", - "integrity": "sha512-2DnD3mkS2uuam/alF+I7M84koGwvn3ZVD7uG+LEWpyzo/bq8+kKnus2EVCkcvh6PlNB8QPNFOz6fWd5N8o1CYg==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.1.tgz", + "integrity": "sha512-/1BmHYh+iz0cNCP0oHCuF8CSiNj0JOGf0jRlSo3L/FAyZyG2rGBuKpkZVH9YF+x58r1jgWxvm1aRg3DHrLDt6A==", "cpu": [ "riscv64" ], @@ -882,9 +882,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.0.tgz", - "integrity": "sha512-D6pkaF7OpE7lzlTOFCB2m3Ngzu2ykw40Nka9WmKGUOTS3xcIieHe82slQlNq69sVB04ch73thKYIWz/Ian8DUA==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.1.tgz", + "integrity": "sha512-0cYP5rGkQWRZKy9/HtsWVStLXzCF3cCBTRI+qRL8Z+wkYlqN7zrSYm6FuY5Kd5ysS5aH0q5lVgb/WbG4jqXN1Q==", "cpu": [ "s390x" ], @@ -896,9 +896,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.0.tgz", - "integrity": "sha512-HBndjQLP8OsdJNSxpNIN0einbDmRFg9+UQeZV1eiYupIRuZsDEoeGU43NQsS34Pp166DtwQOnpcbV/zQxM+rWA==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.1.tgz", + "integrity": "sha512-XUXeI9eM8rMP8aGvii/aOOiMvTs7xlCosq9xCjcqI9+5hBxtjDpD+7Abm1ZhVIFE1J2h2VIg0t2DX/gjespC2Q==", "cpu": [ "x64" ], @@ -910,9 +910,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.0.tgz", - "integrity": "sha512-HxfbvfCKJe/RMYJJn0a12eiOI9OOtAUF4G6ozrFUK95BNyoJaSiBjIOHjZskTUffUrB84IPKkFG9H9nEvJGW6A==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.1.tgz", + "integrity": "sha512-V7cBw/cKXMfEVhpSvVZhC+iGifD6U1zJ4tbibjjN+Xi3blSXaj/rJynAkCFFQfoG6VZrAiP7uGVzL440Q6Me2Q==", "cpu": [ "x64" ], @@ -924,9 +924,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.0.tgz", - "integrity": "sha512-HxDMKIhmcguGTiP5TsLNolwBUK3nGGUEoV/BO9ldUBoMLBssvh4J0X8pf11i1fTV7WShWItB1bKAKjX4RQeYmg==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.1.tgz", + "integrity": "sha512-88brja2vldW/76jWATlBqHEoGjJLRnP0WOEKAUbMcXaAZnemNhlAHSyj4jIwMoP2T750LE9lblvD4e2jXleZsA==", "cpu": [ "arm64" ], @@ -938,9 +938,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.0.tgz", - "integrity": "sha512-xItlIAZZaiG/u0wooGzRsx11rokP4qyc/79LkAOdznGRAbOFc+SfEdfUOszG1odsHNgwippUJavag/+W/Etc6Q==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.1.tgz", + "integrity": "sha512-LdxxcqRVSXi6k6JUrTah1rHuaupoeuiv38du8Mt4r4IPer3kwlTo+RuvfE8KzZ/tL6BhaPlzJ3835i6CxrFIRQ==", "cpu": [ "ia32" ], @@ -952,9 +952,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.0.tgz", - "integrity": "sha512-xNo5fV5ycvCCKqiZcpB65VMR11NJB+StnxHz20jdqRAktfdfzhgjTiJ2doTDQE/7dqGaV5I7ZGqKpgph6lCIag==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.1.tgz", + "integrity": "sha512-2bIrL28PcK3YCqD9anGxDxamxdiJAxA+l7fWIwM5o8UqNy1t3d1NdAweO2XhA0KTDJ5aH1FsuiT5+7VhtHliXg==", "cpu": [ "x64" ], @@ -1582,9 +1582,9 @@ } }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dev": true, "license": "MIT", "dependencies": { @@ -3136,9 +3136,9 @@ } }, "node_modules/rollup": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", - "integrity": "sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.1.tgz", + "integrity": "sha512-K5vziVlg7hTpYfFBI+91zHBEMo6jafYXpkMlqZjg7/zhIG9iHqazBf4xz9AVdjS9BruRn280ROqLI7G3OFRIlw==", "dev": true, "license": "MIT", "dependencies": { @@ -3152,22 +3152,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.19.0", - "@rollup/rollup-android-arm64": "4.19.0", - "@rollup/rollup-darwin-arm64": "4.19.0", - "@rollup/rollup-darwin-x64": "4.19.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", - "@rollup/rollup-linux-arm-musleabihf": "4.19.0", - "@rollup/rollup-linux-arm64-gnu": "4.19.0", - "@rollup/rollup-linux-arm64-musl": "4.19.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", - "@rollup/rollup-linux-riscv64-gnu": "4.19.0", - "@rollup/rollup-linux-s390x-gnu": "4.19.0", - "@rollup/rollup-linux-x64-gnu": "4.19.0", - "@rollup/rollup-linux-x64-musl": "4.19.0", - "@rollup/rollup-win32-arm64-msvc": "4.19.0", - "@rollup/rollup-win32-ia32-msvc": "4.19.0", - "@rollup/rollup-win32-x64-msvc": "4.19.0", + "@rollup/rollup-android-arm-eabi": "4.19.1", + "@rollup/rollup-android-arm64": "4.19.1", + "@rollup/rollup-darwin-arm64": "4.19.1", + "@rollup/rollup-darwin-x64": "4.19.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.19.1", + "@rollup/rollup-linux-arm-musleabihf": "4.19.1", + "@rollup/rollup-linux-arm64-gnu": "4.19.1", + "@rollup/rollup-linux-arm64-musl": "4.19.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.19.1", + "@rollup/rollup-linux-riscv64-gnu": "4.19.1", + "@rollup/rollup-linux-s390x-gnu": "4.19.1", + "@rollup/rollup-linux-x64-gnu": "4.19.1", + "@rollup/rollup-linux-x64-musl": "4.19.1", + "@rollup/rollup-win32-arm64-msvc": "4.19.1", + "@rollup/rollup-win32-ia32-msvc": "4.19.1", + "@rollup/rollup-win32-x64-msvc": "4.19.1", "fsevents": "~2.3.2" } }, @@ -3924,14 +3924,10 @@ "version": "*", "license": "MIT", "peerDependencies": { - "@next2d/core": "file:../core", "@next2d/display": "file:../display", "@next2d/events": "file:../events", "@next2d/geom": "file:../geom", - "@next2d/interface": "file:../interface", "@next2d/net": "file:../net", - "@next2d/share": "file:../share", - "@next2d/util": "file:../util", "@next2d/webgl": "file:../webgl" } }, diff --git a/package.json b/package.json index 6a3b1ec8..907ea07a 100644 --- a/package.json +++ b/package.json @@ -45,17 +45,17 @@ "htmlparser2": "^9.1.0" }, "devDependencies": { - "@types/node": "^20.14.11", - "@typescript-eslint/eslint-plugin": "^7.16.1", - "@typescript-eslint/parser": "^7.16.1", - "@vitest/web-worker": "^2.0.3", - "eslint": "^8.52.0", + "@types/node": "^20.14.12", + "@typescript-eslint/eslint-plugin": "^7.17.0", + "@typescript-eslint/parser": "^7.17.0", + "@vitest/web-worker": "^2.0.4", + "eslint": "^8.57.0", "eslint-plugin-unused-imports": "^3.2.0", "fflate": "^0.8.2", "jsdom": "^24.1.1", - "typescript": "^5.5.3", - "vite": "^5.3.4", - "vitest": "^2.0.3" + "typescript": "^5.5.4", + "vite": "^5.3.5", + "vitest": "^2.0.4" }, "peerDependencies": { "@next2d/core": "file:packages/core", diff --git a/packages/media/src/Sound.ts b/packages/media/src/Sound.ts index 47e1452d..05ddf4bf 100644 --- a/packages/media/src/Sound.ts +++ b/packages/media/src/Sound.ts @@ -40,7 +40,7 @@ export class Sound extends EventDispatcher private _$src: string; private _$loopCount: number; private _$stopFlag: boolean; - + /** * @constructor * @public diff --git a/packages/media/src/SoundMixer/SoundMixerStopAllService.test.ts b/packages/media/src/SoundMixer/SoundMixerStopAllService.test.ts new file mode 100644 index 00000000..8e109023 --- /dev/null +++ b/packages/media/src/SoundMixer/SoundMixerStopAllService.test.ts @@ -0,0 +1,47 @@ +import type { Video } from "../Video"; +import type { Sound } from "../Sound"; +import { $getSounds, $getVideos } from "../MediaUtil"; +import { execute } from "./SoundMixerStopAllService"; +import { describe, expect, it, vi } from "vitest"; + +describe("SoundMixerStopAllService.js namespace test", () => +{ + it("namespace test case1", () => + { + let soundState = ""; + const MockSound = vi.fn().mockImplementation(() => + { + return { + "stop": vi.fn(() => { soundState = "stop" }) + } as unknown as Sound; + }); + + const sounds = $getSounds(); + sounds.push(new MockSound()); + + let videoState = ""; + const MockVideo = vi.fn().mockImplementation(() => + { + return { + "pause": vi.fn(() => { videoState = "pause" }) + } as unknown as Video; + }); + + const videos = $getVideos(); + videos.push(new MockVideo()); + + // before + expect(soundState).toBe(""); + expect(videoState).toBe(""); + expect(sounds.length).toBe(1); + expect(videos.length).toBe(1); + + execute(); + + // after + expect(soundState).toBe("stop"); + expect(videoState).toBe("pause"); + expect(sounds.length).toBe(0); + expect(videos.length).toBe(0); + }); +}); \ No newline at end of file diff --git a/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.test.ts b/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.test.ts new file mode 100644 index 00000000..5d41f255 --- /dev/null +++ b/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.test.ts @@ -0,0 +1,54 @@ +import type { Video } from "../Video"; +import type { Sound } from "../Sound"; +import { SoundMixer } from "../SoundMixer"; +import { $getSounds, $getVideos } from "../MediaUtil"; +import { execute } from "./SoundMixerUpdateVolumeService"; +import { describe, expect, it, vi } from "vitest"; + +describe("SoundMixerUpdateVolumeService.js namespace test", () => +{ + it("namespace test case1", () => + { + const MockSound = vi.fn().mockImplementation(() => + { + return { + "volume": 1 + } as unknown as Sound; + }); + + const mockSound = new MockSound(); + const sounds = $getSounds(); + sounds.push(mockSound); + + const MockVideo = vi.fn().mockImplementation(() => + { + return { + "volume": 1 + } as unknown as Video; + }); + + const mockVideo = new MockVideo(); + const videos = $getVideos(); + videos.push(mockVideo); + + // before + expect(mockSound.volume).toBe(1); + expect(mockVideo.volume).toBe(1); + expect(SoundMixer.volume).toBe(1); + + execute(0.5); + expect(mockSound.volume).toBe(0.5); + expect(mockVideo.volume).toBe(0.5); + expect(SoundMixer.volume).toBe(0.5); + + execute(-0.5); + expect(mockSound.volume).toBe(0); + expect(mockVideo.volume).toBe(0); + expect(SoundMixer.volume).toBe(0); + + execute(3); + expect(mockSound.volume).toBe(1); + expect(mockVideo.volume).toBe(1); + expect(SoundMixer.volume).toBe(1); + }); +}); \ No newline at end of file diff --git a/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.ts b/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.ts index 74f7b6ea..dda384e2 100644 --- a/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.ts +++ b/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.ts @@ -30,7 +30,7 @@ export const execute = (volume: number): void => continue; } - sound.volume = Math.min(volume, sound.volume); + sound.volume = volume; } const videos: Video[] = $getVideos(); @@ -41,6 +41,6 @@ export const execute = (volume: number): void => continue; } - video.volume = Math.min(volume, video.volume); + video.volume = volume; } }; \ No newline at end of file diff --git a/packages/media/src/Video.ts b/packages/media/src/Video.ts index e951e373..52468415 100644 --- a/packages/media/src/Video.ts +++ b/packages/media/src/Video.ts @@ -385,7 +385,10 @@ export class Video extends DisplayObject this._$videoElement.pause(); } + cancelAnimationFrame(this._$timerId); + // reset + this._$stop = true; this._$currentTime = 0; this._$duration = 0; this._$volume = 0; diff --git a/packages/media/src/Video/VideoCanplaythroughEventService.test.ts b/packages/media/src/Video/VideoCanplaythroughEventService.test.ts new file mode 100644 index 00000000..c023a891 --- /dev/null +++ b/packages/media/src/Video/VideoCanplaythroughEventService.test.ts @@ -0,0 +1,93 @@ +import type { Video } from "../Video"; +import { Event } from "@next2d/events"; +import { execute } from "./VideoCanplaythroughEventService"; +import { describe, expect, it, vi } from "vitest"; + +describe("SoundMixerUpdateVolumeService.js namespace test", () => +{ + it("namespace test case1", async () => + { + let playState = "stop"; + let eventState = ""; + let state = ""; + const MockVideo = vi.fn().mockImplementation(() => + { + return { + "autoPlay": true, + "play": vi.fn(() => { playState = "play" }), + "_$doChanged": vi.fn(() => { state = "changed" }), + "willTrigger": vi.fn(() => true), + "dispatchEvent": vi.fn(() => { eventState = Event.COMPLETE }) + } as unknown as Video; + }); + + const MockHTMLVideoElement = vi.fn().mockImplementation(() => + { + return { + "play": vi.fn().mockResolvedValue(true), + "pause": vi.fn(), + "currentTime": 0 + } as unknown as HTMLVideoElement; + }); + + const mockVideo = new MockVideo(); + const mockElement = new MockHTMLVideoElement(); + + // before + expect(playState).toBe("stop"); + expect(eventState).toBe(""); + expect(state).toBe(""); + + await execute(mockVideo, mockElement); + + // after + expect(playState).toBe("play"); + expect(eventState).toBe(Event.COMPLETE); + expect(state).toBe("changed"); + }); + + it("namespace test case2", async () => + { + let eventState = ""; + let state = ""; + const MockVideo = vi.fn().mockImplementation(() => + { + return { + "autoPlay": false, + "_$doChanged": vi.fn(() => { state = "changed" }), + "willTrigger": vi.fn(() => true), + "dispatchEvent": vi.fn(() => { eventState = Event.COMPLETE }) + } as unknown as Video; + }); + + let playState = "stop"; + let pauseState = ""; + const MockHTMLVideoElement = vi.fn().mockImplementation(() => + { + return { + "play": vi.fn(() => { playState = "play" }), + "pause": vi.fn(() => { pauseState = "pause" }), + "currentTime": 100 + } as unknown as HTMLVideoElement; + }); + + const mockVideo = new MockVideo(); + const mockElement = new MockHTMLVideoElement(); + + // before + expect(playState).toBe("stop"); + expect(eventState).toBe(""); + expect(pauseState).toBe(""); + expect(mockElement.currentTime).toBe(100); + expect(state).toBe(""); + + await execute(mockVideo, mockElement); + + // after + expect(playState).toBe("play"); + expect(eventState).toBe(Event.COMPLETE); + expect(pauseState).toBe("pause"); + expect(mockElement.currentTime).toBe(0); + expect(state).toBe("changed"); + }); +}); \ No newline at end of file From cdeca530c4e29a3280671b129ff05aba4352be28 Mon Sep 17 00:00:00 2001 From: ienaga Date: Sat, 27 Jul 2024 19:36:02 +0900 Subject: [PATCH 024/343] =?UTF-8?q?#154=20test:=20UnitTest=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/events/src/Event.test.ts | 16 +++++------ .../Event/EventFormatToStringService.test.ts | 4 +-- packages/events/src/EventDispatcher.test.ts | 12 ++++----- ...ventDispatcherDispatchEventService.test.ts | 2 +- ...tcherRemoveAllEventListenerService.test.ts | 12 ++++----- ...spatcherRemoveEventListenerService.test.ts | 2 +- .../EventDispatcherWillTriggerService.test.ts | 8 +++--- .../src/Sound/SoundEndedEventService.test.ts | 6 ++--- .../Sound/SoundLoadStartEventService.test.ts | 6 ++--- .../Sound/SoundLoadendEventService.test.ts | 6 ++--- .../Sound/SoundProgressEventService.test.ts | 4 +-- .../SoundMixerStopAllService.test.ts | 4 +-- .../SoundMixerUpdateVolumeService.test.ts | 4 +-- .../VideoCanplaythroughEventService.test.ts | 6 ++--- .../Video/VideoCreateElementService.test.ts | 27 +++++++++++++++++++ .../src/Video/VideoCreateElementService.ts | 1 + .../Video/VideoLoadedmetadataEventService.ts | 1 + packages/ui/src/Job/JobEntriesService.test.ts | 8 +++--- packages/ui/src/Job/JobUpdateFrameService.ts | 10 +++---- .../src/Job/JobUpdatePropertyService.test.ts | 8 +++--- 20 files changed, 88 insertions(+), 59 deletions(-) create mode 100644 packages/media/src/Video/VideoCreateElementService.test.ts diff --git a/packages/events/src/Event.test.ts b/packages/events/src/Event.test.ts index c3a0192e..af4d38bf 100644 --- a/packages/events/src/Event.test.ts +++ b/packages/events/src/Event.test.ts @@ -1,9 +1,9 @@ import { Event } from "./Event"; import { describe, expect, it } from "vitest"; -describe("Event.js toString test", function() +describe("Event.js toString test", () => { - it("toString test case1", function() + it("toString test case1", () => { const event = new Event("test"); expect(event.toString()) @@ -11,29 +11,29 @@ describe("Event.js toString test", function() }); }); -describe("Event.js static toString test", function() +describe("Event.js static toString test", () => { - it("static toString test", function() + it("static toString test", () => { expect(Event.toString()).toBe("[class Event]"); }); }); -describe("Event.js namespace test", function() +describe("Event.js namespace test", () => { - it("namespace test public", function() + it("namespace test public", () => { const event = new Event("test"); expect(event.namespace).toBe("next2d.events.Event"); }); - it("namespace test static", function() + it("namespace test static", () => { expect(Event.namespace).toBe("next2d.events.Event"); }); }); -describe("Event.js property test", function() +describe("Event.js property test", () => { it("ACTIVATE test", () => diff --git a/packages/events/src/Event/EventFormatToStringService.test.ts b/packages/events/src/Event/EventFormatToStringService.test.ts index 754c0a7a..6ef6fb53 100644 --- a/packages/events/src/Event/EventFormatToStringService.test.ts +++ b/packages/events/src/Event/EventFormatToStringService.test.ts @@ -2,9 +2,9 @@ import { Event } from "../Event"; import { execute } from "./EventFormatToStringService"; import { describe, expect, it } from "vitest"; -describe("EventFormatToStringService.js toString test", function() +describe("EventFormatToStringService.js toString test", () => { - it("toString test case", function() + it("toString test case", () => { const event = new Event("test"); expect(execute(event, "Event", "type", "bubbles", "cancelable", "eventPhase")) diff --git a/packages/events/src/EventDispatcher.test.ts b/packages/events/src/EventDispatcher.test.ts index 068ab164..96042ffb 100644 --- a/packages/events/src/EventDispatcher.test.ts +++ b/packages/events/src/EventDispatcher.test.ts @@ -1,7 +1,7 @@ import { EventDispatcher } from "./EventDispatcher"; import { describe, expect, it } from "vitest"; -describe("EventDispatcher.js toString test", function() +describe("EventDispatcher.js toString test", () => { // toString it("toString test success", () => @@ -11,23 +11,23 @@ describe("EventDispatcher.js toString test", function() }); }); -describe("EventDispatcher.js static toString test", function() +describe("EventDispatcher.js static toString test", () => { - it("static toString test", function() + it("static toString test", () => { expect(EventDispatcher.toString()).toBe("[class EventDispatcher]"); }); }); -describe("EventDispatcher.js namespace test", function() +describe("EventDispatcher.js namespace test", () => { - it("namespace test public", function() + it("namespace test public", () => { const eventDispatcher = new EventDispatcher(); expect(eventDispatcher.namespace).toBe("next2d.events.EventDispatcher"); }); - it("namespace test static", function() + it("namespace test static", () => { expect(EventDispatcher.namespace).toBe("next2d.events.EventDispatcher"); }); diff --git a/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.test.ts b/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.test.ts index fd667ad1..63da07fc 100644 --- a/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.test.ts +++ b/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.test.ts @@ -4,7 +4,7 @@ import { EventPhase } from "../EventPhase"; import { $broadcastEvents } from "../EventUtil"; import { describe, expect, it } from "vitest"; -describe("EventDispatcher.js dispatchEvent test", function() +describe("EventDispatcher.js dispatchEvent test", () => { it("dispatchEvent test case1", () => { diff --git a/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.test.ts b/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.test.ts index e05fcd3c..67956cd6 100644 --- a/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.test.ts +++ b/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.test.ts @@ -1,15 +1,15 @@ import { Event } from "../Event"; import { EventDispatcher } from "../EventDispatcher"; -import { describe, expect, it } from "vitest"; +import { describe, expect, it, vi } from "vitest"; -describe("EventDispatcher.js removeAllEventListener test", function() +describe("EventDispatcher.js removeAllEventListener test", () => { it("removeAllEventListener test case1", () => { const eventDispatcher = new EventDispatcher(); - eventDispatcher.addEventListener("test", () => {}); - eventDispatcher.addEventListener("test", () => {}); - eventDispatcher.addEventListener("test", () => {}); + eventDispatcher.addEventListener("test", vi.fn()); + eventDispatcher.addEventListener("test", vi.fn()); + eventDispatcher.addEventListener("test", vi.fn()); expect(eventDispatcher.hasEventListener("test")).toBe(true); eventDispatcher.removeAllEventListener("test"); @@ -19,7 +19,7 @@ describe("EventDispatcher.js removeAllEventListener test", function() it("removeAllEventListener test case2", () => { const eventDispatcher = new EventDispatcher(); - eventDispatcher.addEventListener(Event.ENTER_FRAME, () => {}); + eventDispatcher.addEventListener(Event.ENTER_FRAME, vi.fn()); expect(eventDispatcher.hasEventListener(Event.ENTER_FRAME)).toBe(true); eventDispatcher.removeAllEventListener(Event.ENTER_FRAME); diff --git a/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.test.ts b/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.test.ts index 08f9d91b..287ca90d 100644 --- a/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.test.ts +++ b/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.test.ts @@ -4,7 +4,7 @@ import { EventDispatcher } from "../EventDispatcher"; import { EventListenerImpl } from "../interface/EventListenerImpl"; import { describe, expect, it } from "vitest"; -describe("EventDispatcher.js removeEventListener test", function() +describe("EventDispatcher.js removeEventListener test", () => { it("removeEventListener test case1", () => { diff --git a/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.test.ts b/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.test.ts index 177be0ff..6383367c 100644 --- a/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.test.ts +++ b/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.test.ts @@ -1,7 +1,7 @@ import { EventDispatcher } from "../EventDispatcher"; -import { describe, expect, it } from "vitest"; +import { describe, expect, it, vi } from "vitest"; -describe("EventDispatcher.js willTrigger test", function() +describe("EventDispatcher.js willTrigger test", () => { it("willTrigger test success case1", () => { @@ -25,7 +25,7 @@ describe("EventDispatcher.js willTrigger test", function() } const child = new Child(parent1); - parent1.addEventListener("test", () => {}); + parent1.addEventListener("test", vi.fn()); expect(parent2.willTrigger("test")).toBe(false); expect(parent1.willTrigger("test")).toBe(true); @@ -54,7 +54,7 @@ describe("EventDispatcher.js willTrigger test", function() const child1 = new Child(parent); const child2 = new Child(parent); - parent.addEventListener("test", () => {}); + parent.addEventListener("test", vi.fn()); expect(parent.willTrigger("test")).toBe(true); expect(child1.willTrigger("test")).toBe(true); diff --git a/packages/media/src/Sound/SoundEndedEventService.test.ts b/packages/media/src/Sound/SoundEndedEventService.test.ts index cdfc60db..c3fec39d 100644 --- a/packages/media/src/Sound/SoundEndedEventService.test.ts +++ b/packages/media/src/Sound/SoundEndedEventService.test.ts @@ -3,9 +3,9 @@ import { Event } from "@next2d/events"; import { execute } from "./SoundEndedEventService"; import { describe, expect, it, vi } from "vitest"; -describe("SoundEndedEventService.js namespace test", () => +describe("SoundEndedEventService.js test", () => { - it("namespace test case1", () => + it("execute test case1", () => { let state = ""; const MockSound = vi.fn().mockImplementation(() => @@ -24,7 +24,7 @@ describe("SoundEndedEventService.js namespace test", () => expect(state).toBe("play"); }); - it("namespace test case2", () => + it("execute test case2", () => { let state = ""; let type = ""; diff --git a/packages/media/src/Sound/SoundLoadStartEventService.test.ts b/packages/media/src/Sound/SoundLoadStartEventService.test.ts index 6e60c599..63c98786 100644 --- a/packages/media/src/Sound/SoundLoadStartEventService.test.ts +++ b/packages/media/src/Sound/SoundLoadStartEventService.test.ts @@ -6,9 +6,9 @@ import { } from "@next2d/events"; import { describe, expect, it, vi } from "vitest"; -describe("SoundLoadStartEventService.js namespace test", () => +describe("SoundLoadStartEventService.js test", () => { - it("namespace open event test case1", () => + it("execute test case1", () => { const sound = new Sound(); @@ -35,7 +35,7 @@ describe("SoundLoadStartEventService.js namespace test", () => }); - it("namespace progress event test case1", () => + it("execute test case2", () => { const sound = new Sound(); diff --git a/packages/media/src/Sound/SoundLoadendEventService.test.ts b/packages/media/src/Sound/SoundLoadendEventService.test.ts index 369228c0..1f841162 100644 --- a/packages/media/src/Sound/SoundLoadendEventService.test.ts +++ b/packages/media/src/Sound/SoundLoadendEventService.test.ts @@ -6,9 +6,9 @@ import { } from "@next2d/events"; import { describe, expect, it, vi } from "vitest"; -describe("SoundLoadendEventService.js namespace test", () => +describe("SoundLoadendEventService.js test", () => { - it("namespace progress event test case1", () => + it("execute test case1", () => { const sound = new Sound(); @@ -44,7 +44,7 @@ describe("SoundLoadendEventService.js namespace test", () => expect(openState).toBe(Next2DProgressEvent.PROGRESS); }); - it("namespace progress event test case2", () => + it("execute test case2", () => { const sound = new Sound(); diff --git a/packages/media/src/Sound/SoundProgressEventService.test.ts b/packages/media/src/Sound/SoundProgressEventService.test.ts index 82776954..67d145b4 100644 --- a/packages/media/src/Sound/SoundProgressEventService.test.ts +++ b/packages/media/src/Sound/SoundProgressEventService.test.ts @@ -3,9 +3,9 @@ import { execute } from "./SoundProgressEventService"; import { ProgressEvent as Next2DProgressEvent } from "@next2d/events"; import { describe, expect, it, vi } from "vitest"; -describe("SoundProgressEventService.js namespace test", () => +describe("SoundProgressEventService.js test", () => { - it("namespace progress event test case1", () => + it("execute test case1", () => { const sound = new Sound(); diff --git a/packages/media/src/SoundMixer/SoundMixerStopAllService.test.ts b/packages/media/src/SoundMixer/SoundMixerStopAllService.test.ts index 8e109023..701ee8d9 100644 --- a/packages/media/src/SoundMixer/SoundMixerStopAllService.test.ts +++ b/packages/media/src/SoundMixer/SoundMixerStopAllService.test.ts @@ -4,9 +4,9 @@ import { $getSounds, $getVideos } from "../MediaUtil"; import { execute } from "./SoundMixerStopAllService"; import { describe, expect, it, vi } from "vitest"; -describe("SoundMixerStopAllService.js namespace test", () => +describe("SoundMixerStopAllService.js test", () => { - it("namespace test case1", () => + it("execute test case1", () => { let soundState = ""; const MockSound = vi.fn().mockImplementation(() => diff --git a/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.test.ts b/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.test.ts index 5d41f255..6111e5d8 100644 --- a/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.test.ts +++ b/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.test.ts @@ -5,9 +5,9 @@ import { $getSounds, $getVideos } from "../MediaUtil"; import { execute } from "./SoundMixerUpdateVolumeService"; import { describe, expect, it, vi } from "vitest"; -describe("SoundMixerUpdateVolumeService.js namespace test", () => +describe("SoundMixerUpdateVolumeService.js test", () => { - it("namespace test case1", () => + it("execute test case1", () => { const MockSound = vi.fn().mockImplementation(() => { diff --git a/packages/media/src/Video/VideoCanplaythroughEventService.test.ts b/packages/media/src/Video/VideoCanplaythroughEventService.test.ts index c023a891..45ff88ea 100644 --- a/packages/media/src/Video/VideoCanplaythroughEventService.test.ts +++ b/packages/media/src/Video/VideoCanplaythroughEventService.test.ts @@ -3,9 +3,9 @@ import { Event } from "@next2d/events"; import { execute } from "./VideoCanplaythroughEventService"; import { describe, expect, it, vi } from "vitest"; -describe("SoundMixerUpdateVolumeService.js namespace test", () => +describe("VideoCanplaythroughEventService.js test", () => { - it("namespace test case1", async () => + it("execute test case1", async () => { let playState = "stop"; let eventState = ""; @@ -46,7 +46,7 @@ describe("SoundMixerUpdateVolumeService.js namespace test", () => expect(state).toBe("changed"); }); - it("namespace test case2", async () => + it("execute test case2", async () => { let eventState = ""; let state = ""; diff --git a/packages/media/src/Video/VideoCreateElementService.test.ts b/packages/media/src/Video/VideoCreateElementService.test.ts new file mode 100644 index 00000000..2b889833 --- /dev/null +++ b/packages/media/src/Video/VideoCreateElementService.test.ts @@ -0,0 +1,27 @@ +import type { Video } from "../Video"; +import { Event } from "@next2d/events"; +import { execute } from "./VideoCreateElementService"; +import { describe, expect, it, vi } from "vitest"; + +describe("VideoCreateElementService.js test", () => +{ + it("execute test case1", () => + { + const MockVideo = vi.fn().mockImplementation(() => + { + return {} as unknown as Video; + }); + + const bounds = { + "xMin": 0, + "yMin": 0, + "xMax": 0, + "yMax": 0 + }; + const element = execute(new MockVideo(), bounds); + + expect(element.autoplay).toBe(false); + expect(element.crossOrigin).toBe("anonymous"); + expect(element.getAttribute("playsinline")).toBe(""); + }); +}); \ No newline at end of file diff --git a/packages/media/src/Video/VideoCreateElementService.ts b/packages/media/src/Video/VideoCreateElementService.ts index 94dd3c54..d97792a7 100644 --- a/packages/media/src/Video/VideoCreateElementService.ts +++ b/packages/media/src/Video/VideoCreateElementService.ts @@ -10,6 +10,7 @@ import { execute as videoEndedEventService } from "./VideoEndedEventService"; * Create an HTMLVideoElement and set various events * * @param {Video} video + * @param {object} bounds * @return {HTMLVideoElement} * @method * @protected diff --git a/packages/media/src/Video/VideoLoadedmetadataEventService.ts b/packages/media/src/Video/VideoLoadedmetadataEventService.ts index fea1b73d..9f6dd2b5 100644 --- a/packages/media/src/Video/VideoLoadedmetadataEventService.ts +++ b/packages/media/src/Video/VideoLoadedmetadataEventService.ts @@ -5,6 +5,7 @@ import type { Video } from "../Video"; * @description Videoオブジェクトの幅と高さを更新する * Update the width and height of the Video object * + * @param {Video} video * @param {HTMLVideoElement} element * @param {object} bounds * @return {void} diff --git a/packages/ui/src/Job/JobEntriesService.test.ts b/packages/ui/src/Job/JobEntriesService.test.ts index 5fbe28be..7d83f8d5 100644 --- a/packages/ui/src/Job/JobEntriesService.test.ts +++ b/packages/ui/src/Job/JobEntriesService.test.ts @@ -2,9 +2,9 @@ import type { EntriesObjectImpl } from "../interface/EntriesObjectImpl"; import { execute } from "./JobEntriesService"; import { describe, expect, it } from "vitest"; -describe("JobEntriesService.js method test", () => +describe("JobEntriesService.js test", () => { - it("test case1", () => + it("execute test case1", () => { const entries = execute({ "x": 100, "y": 200 }); expect(entries.length).toBe(2); @@ -14,7 +14,7 @@ describe("JobEntriesService.js method test", () => expect(entries[1].value).toBe(200); }); - it("test case2", () => + it("execute test case2", () => { const entries = execute({ "x": 100, @@ -38,7 +38,7 @@ describe("JobEntriesService.js method test", () => expect(matrix[1].value).toBe(2); }); - it("test case2", () => + it("execute test case3", () => { const entries = execute({ "x": 100, diff --git a/packages/ui/src/Job/JobUpdateFrameService.ts b/packages/ui/src/Job/JobUpdateFrameService.ts index 7634ff68..956e9326 100644 --- a/packages/ui/src/Job/JobUpdateFrameService.ts +++ b/packages/ui/src/Job/JobUpdateFrameService.ts @@ -29,6 +29,11 @@ export const execute = (job: Job, timestamp: number): number => job.entries as EntriesObjectImpl[] ); + // update event + if (job.hasEventListener(Event.UPDATE)) { + job.dispatchEvent(new Event(Event.UPDATE)); + } + // complete logic if (job.currentTime >= job.duration) { @@ -45,11 +50,6 @@ export const execute = (job: Job, timestamp: number): number => return -1; } - // update event - if (job.hasEventListener(Event.UPDATE)) { - job.dispatchEvent(new Event(Event.UPDATE)); - } - return requestAnimationFrame((timestamp: number): void => { execute(job, timestamp); diff --git a/packages/ui/src/Job/JobUpdatePropertyService.test.ts b/packages/ui/src/Job/JobUpdatePropertyService.test.ts index d3e68269..951c477d 100644 --- a/packages/ui/src/Job/JobUpdatePropertyService.test.ts +++ b/packages/ui/src/Job/JobUpdatePropertyService.test.ts @@ -3,9 +3,9 @@ import { execute as jobEntriesService } from "./JobEntriesService"; import { Job } from "../Job"; import { describe, expect, it } from "vitest"; -describe("JobUpdatePropertyService.js method test", () => +describe("JobUpdatePropertyService.js test", () => { - it("test case1", () => + it("execute test case1", () => { const target = { "a": 1, "b": 2 }; const from = { "a": 0, "b": 0 }; @@ -19,7 +19,7 @@ describe("JobUpdatePropertyService.js method test", () => expect(target.b).toBe(0); }); - it("test case2", () => + it("execute test case2", () => { const target = { "a": 1, "b": 2 }; const from = { "a": 0, "b": 0 }; @@ -34,7 +34,7 @@ describe("JobUpdatePropertyService.js method test", () => expect(target.b).toBe(20); }); - it("test case3", () => + it("execute test case3", () => { const target = { "a": 1, From ae413a3d27dfeda1f42a1260811d9acfecd45314 Mon Sep 17 00:00:00 2001 From: ienaga Date: Sat, 27 Jul 2024 20:28:57 +0900 Subject: [PATCH 025/343] =?UTF-8?q?#154=20test:=20UnitTest=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sound/SoundLoadStartEventService.test.ts | 4 +- .../Sound/SoundProgressEventService.test.ts | 2 + .../Video/VideoCreateElementService.test.ts | 1 - .../src/Video/VideoEndedEventService.test.ts | 63 +++++++++++++++++++ .../VideoLoadedmetadataEventService.test.ts | 52 +++++++++++++++ .../src/Video/VideoPlayEventService.test.ts | 39 ++++++++++++ .../Video/VideoProgressEventService.test.ts | 47 ++++++++++++++ 7 files changed, 205 insertions(+), 3 deletions(-) create mode 100644 packages/media/src/Video/VideoEndedEventService.test.ts create mode 100644 packages/media/src/Video/VideoLoadedmetadataEventService.test.ts create mode 100644 packages/media/src/Video/VideoPlayEventService.test.ts create mode 100644 packages/media/src/Video/VideoProgressEventService.test.ts diff --git a/packages/media/src/Sound/SoundLoadStartEventService.test.ts b/packages/media/src/Sound/SoundLoadStartEventService.test.ts index 63c98786..225801d7 100644 --- a/packages/media/src/Sound/SoundLoadStartEventService.test.ts +++ b/packages/media/src/Sound/SoundLoadStartEventService.test.ts @@ -32,7 +32,6 @@ describe("SoundLoadStartEventService.js test", () => execute(sound, new MockEvent()); expect(openState).toBe(Event.OPEN); - }); it("execute test case2", () => @@ -65,6 +64,7 @@ describe("SoundLoadStartEventService.js test", () => execute(sound, new MockEvent()); expect(openState).toBe(Next2DProgressEvent.PROGRESS); - + expect(loaded).toBe(1); + expect(total).toBe(10); }); }); \ No newline at end of file diff --git a/packages/media/src/Sound/SoundProgressEventService.test.ts b/packages/media/src/Sound/SoundProgressEventService.test.ts index 67d145b4..3850975b 100644 --- a/packages/media/src/Sound/SoundProgressEventService.test.ts +++ b/packages/media/src/Sound/SoundProgressEventService.test.ts @@ -35,6 +35,8 @@ describe("SoundProgressEventService.js test", () => execute(sound, new MockEvent()); expect(openState).toBe(Next2DProgressEvent.PROGRESS); + expect(loaded).toBe(1); + expect(total).toBe(10); }); }); \ No newline at end of file diff --git a/packages/media/src/Video/VideoCreateElementService.test.ts b/packages/media/src/Video/VideoCreateElementService.test.ts index 2b889833..5c8b1a2e 100644 --- a/packages/media/src/Video/VideoCreateElementService.test.ts +++ b/packages/media/src/Video/VideoCreateElementService.test.ts @@ -1,5 +1,4 @@ import type { Video } from "../Video"; -import { Event } from "@next2d/events"; import { execute } from "./VideoCreateElementService"; import { describe, expect, it, vi } from "vitest"; diff --git a/packages/media/src/Video/VideoEndedEventService.test.ts b/packages/media/src/Video/VideoEndedEventService.test.ts new file mode 100644 index 00000000..0e08c132 --- /dev/null +++ b/packages/media/src/Video/VideoEndedEventService.test.ts @@ -0,0 +1,63 @@ +import type { Video } from "../Video"; +import { VideoEvent } from "@next2d/events"; +import { execute } from "./VideoEndedEventService"; +import { describe, expect, it, vi } from "vitest"; + +describe("VideoEndedEventService.js test", () => +{ + it("execute test case1", () => + { + let eventType = ""; + let pauseState = ""; + const MockVideo = vi.fn().mockImplementation(() => + { + return { + "willTrigger": vi.fn(() => true), + "dispatchEvent": vi.fn((event: VideoEvent) => { eventType = event.type }), + "loop": true, + "pause": vi.fn(() => { pauseState = "pause" }), + "currentTime": 100 + } as unknown as Video; + }); + + expect(eventType).toBe(""); + expect(pauseState).toBe(""); + + const mockVideo = new MockVideo(); + expect(mockVideo.currentTime).toBe(100); + + execute(mockVideo); + + expect(eventType).toBe(VideoEvent.PLAY_END); + expect(pauseState).toBe(""); + expect(mockVideo.currentTime).toBe(0); + }); + + it("execute test case2", () => + { + let eventType = ""; + let pauseState = ""; + const MockVideo = vi.fn().mockImplementation(() => + { + return { + "willTrigger": vi.fn(() => true), + "dispatchEvent": vi.fn((event: VideoEvent) => { eventType = event.type }), + "loop": false, + "pause": vi.fn(() => { pauseState = "pause" }), + "currentTime": 100 + } as unknown as Video; + }); + + expect(eventType).toBe(""); + expect(pauseState).toBe(""); + + const mockVideo = new MockVideo(); + expect(mockVideo.currentTime).toBe(100); + + execute(mockVideo); + + expect(eventType).toBe(VideoEvent.PLAY_END); + expect(pauseState).toBe("pause"); + expect(mockVideo.currentTime).toBe(100); + }); +}); \ No newline at end of file diff --git a/packages/media/src/Video/VideoLoadedmetadataEventService.test.ts b/packages/media/src/Video/VideoLoadedmetadataEventService.test.ts new file mode 100644 index 00000000..c33c9156 --- /dev/null +++ b/packages/media/src/Video/VideoLoadedmetadataEventService.test.ts @@ -0,0 +1,52 @@ +import type { Video } from "../Video"; +import { execute } from "./VideoLoadedmetadataEventService"; +import { describe, expect, it, vi } from "vitest"; + +describe("VideoLoadedmetadataEventService.js test", () => +{ + it("execute test case1", () => + { + const MockVideo = vi.fn().mockImplementation(() => + { + return { + "currentTime": 100, + "duration": 0 + } as unknown as Video; + }); + + const mockVideo = new MockVideo(); + expect(mockVideo.currentTime).toBe(100); + expect(mockVideo.duration).toBe(0); + + const MockHTMLVideoElement = vi.fn().mockImplementation(() => + { + return { + "duration": 100, + "videoWidth": 200, + "videoHeight": 300 + } as unknown as HTMLVideoElement; + }); + + const mockElement = new MockHTMLVideoElement(); + expect(mockElement.duration).toBe(100); + expect(mockElement.videoWidth).toBe(200); + expect(mockElement.videoHeight).toBe(300); + + const bounds = { + "xMin": 0, + "yMin": 0, + "xMax": 0, + "yMax": 0 + }; + expect(bounds.xMax).toBe(0); + expect(bounds.yMax).toBe(0); + + execute(mockVideo, mockElement, bounds); + + // after + expect(mockVideo.currentTime).toBe(0); + expect(mockVideo.duration).toBe(100); + expect(bounds.xMax).toBe(200); + expect(bounds.yMax).toBe(300); + }); +}); \ No newline at end of file diff --git a/packages/media/src/Video/VideoPlayEventService.test.ts b/packages/media/src/Video/VideoPlayEventService.test.ts new file mode 100644 index 00000000..5a32d72a --- /dev/null +++ b/packages/media/src/Video/VideoPlayEventService.test.ts @@ -0,0 +1,39 @@ +import type { Video } from "../Video"; +import { VideoEvent } from "@next2d/events"; +import { execute } from "./VideoPlayEventService"; +import { describe, expect, it, vi } from "vitest"; + +describe("VideoPlayEventService.js test", () => +{ + it("execute test case1", () => + { + let pauseState = ""; + let eventState = ""; + let state = ""; + const MockVideo = vi.fn().mockImplementation(() => + { + return { + "stage": true, + "pause": vi.fn(() => { pauseState = "pause" }), + "willTrigger": vi.fn(() => true), + "dispatchEvent": vi.fn((event: VideoEvent) => { eventState = event.type }), + "_$doChanged": vi.fn(() => { state = "doChanged" }) + } as unknown as Video; + }); + + const mockVideo = new MockVideo(); + expect(pauseState).toBe(""); + expect(eventState).toBe(""); + expect(state).toBe(""); + + cancelAnimationFrame(execute(mockVideo)); + + expect(state).toBe("doChanged"); + expect(pauseState).toBe(""); + expect(eventState).toBe(VideoEvent.PLAY); + + mockVideo.stage = false; + cancelAnimationFrame(execute(mockVideo)); + expect(pauseState).toBe("pause"); + }); +}); \ No newline at end of file diff --git a/packages/media/src/Video/VideoProgressEventService.test.ts b/packages/media/src/Video/VideoProgressEventService.test.ts new file mode 100644 index 00000000..7589f979 --- /dev/null +++ b/packages/media/src/Video/VideoProgressEventService.test.ts @@ -0,0 +1,47 @@ +import type { Video } from "../Video"; +import { + VideoEvent, + ProgressEvent as Next2DProgressEvent +} from "@next2d/events"; +import { execute } from "./VideoProgressEventService"; +import { describe, expect, it, vi } from "vitest"; + +describe("VideoProgressEventService.js test", () => +{ + it("execute test case1", () => + { + let eventState = ""; + let loaded = 0; + let total = 0; + const MockVideo = vi.fn().mockImplementation(() => + { + return { + "willTrigger": vi.fn(() => true), + "dispatchEvent": vi.fn((event: Next2DProgressEvent) => + { + eventState = event.type; + loaded = event.bytesLoaded; + total = event.bytesTotal; + }) + } as unknown as Video; + }); + + const MockProgressEvent = vi.fn().mockImplementation(() => + { + return { + "loaded": 10, + "total": 20 + } as unknown as ProgressEvent; + }); + + expect(eventState).toBe(""); + expect(loaded).toBe(0); + expect(total).toBe(0); + + execute(new MockVideo(), new MockProgressEvent()); + + expect(eventState).toBe(Next2DProgressEvent.PROGRESS); + expect(loaded).toBe(10); + expect(total).toBe(20); + }); +}); \ No newline at end of file From 4225381bdf9e6c7d3ac9abc4062548432d5b5f8c Mon Sep 17 00:00:00 2001 From: ienaga Date: Sat, 27 Jul 2024 23:34:03 +0900 Subject: [PATCH 026/343] =?UTF-8?q?#154=20feat:=20=E3=83=87=E3=82=A3?= =?UTF-8?q?=E3=83=AC=E3=82=AF=E3=83=88=E3=83=AA=E6=A7=8B=E6=88=90=E3=82=92?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/Util.ts | 97 ---------------- packages/geom/src/ColorTransform.ts | 73 ++---------- packages/geom/src/GeomUtil.ts | 106 ++++++++++++++++++ packages/geom/src/Matrix.ts | 69 ++---------- packages/geom/src/Transform.ts | 6 +- packages/media/src/MediaUtil.ts | 96 ++++++++++++++++ packages/media/src/Sound.ts | 6 +- .../SoundMixerUpdateVolumeService.ts | 2 +- packages/media/src/SoundTransform.ts | 2 +- packages/media/src/Video.ts | 6 +- .../media/src}/interface/AjaxEventImpl.ts | 0 .../media/src}/interface/AjaxOptionImpl.ts | 0 .../src}/interface/URLLoaderDataFormatImpl.ts | 0 .../src}/interface/URLRequestHeaderImpl.ts | 0 .../src}/interface/URLRequestMethodImpl.ts | 0 15 files changed, 233 insertions(+), 230 deletions(-) delete mode 100644 common/Util.ts create mode 100644 packages/geom/src/GeomUtil.ts rename {common => packages/media/src}/interface/AjaxEventImpl.ts (100%) rename {common => packages/media/src}/interface/AjaxOptionImpl.ts (100%) rename {common => packages/media/src}/interface/URLLoaderDataFormatImpl.ts (100%) rename {common => packages/media/src}/interface/URLRequestHeaderImpl.ts (100%) rename {common => packages/media/src}/interface/URLRequestMethodImpl.ts (100%) diff --git a/common/Util.ts b/common/Util.ts deleted file mode 100644 index f6020577..00000000 --- a/common/Util.ts +++ /dev/null @@ -1,97 +0,0 @@ -import type { AjaxOptionImpl } from "./interface/AjaxOptionImpl"; - -/** - * @param {number} value - * @param {number} min - * @param {number} max - * @param {number} [default_value=null] - * @return {number} - * @method - * @static - */ -export const $clamp = ( - value: number, - min: number, - max: number, - default_value: number | null = null -): number => { - - const number: number = +value; - - return isNaN(number) && default_value !== null - ? default_value - : Math.min(Math.max(min, isNaN(number) ? 0 : number), max); -}; - -/** - * @param {object} option - * @return {void} - * @method - * @public - */ -export const $ajax = (option: AjaxOptionImpl): void => -{ - // get or post - let postData: string | null = null; - switch (option.method.toUpperCase()) { - - case "GET": - if (option.data) { - const urls = option.url.split("?"); - - urls[1] = urls.length === 1 - ? option.data.toString() - : `${urls[1]}&${option.data.toString()}`; - - option.url = urls.join("?"); - } - break; - - case "PUT": - case "POST": - if (option.data) { - postData = option.data.toString(); - } - break; - - default: - break; - - } - - // start - const xmlHttpRequest = new XMLHttpRequest(); - - // init - xmlHttpRequest.open(option.method, option.url, true); - - // set mimeType - xmlHttpRequest.responseType = option.format; - - // use cookie - xmlHttpRequest.withCredentials = option.withCredentials; - - // add event - if (option.event) { - const keys: string[] = Object.keys(option.event); - for (let idx = 0; idx < keys.length; ++idx) { - - const name: string = keys[idx]; - - // @ts-ignore - xmlHttpRequest.addEventListener(name, option.event[name]); - } - } - - // set request header - for (let idx: number = 0; idx < option.headers.length; ++idx) { - const header = option.headers[idx]; - if (!header) { - continue; - } - xmlHttpRequest.setRequestHeader(header.name, header.value); - } - - xmlHttpRequest.send(postData); -}; - diff --git a/packages/geom/src/ColorTransform.ts b/packages/geom/src/ColorTransform.ts index 9a65d296..5c6ce2ef 100644 --- a/packages/geom/src/ColorTransform.ts +++ b/packages/geom/src/ColorTransform.ts @@ -1,60 +1,8 @@ import { execute as colorTransformConcatService } from "../src/ColorTransform/service/ColorTransformConcatService"; - -/** - * @type {Float32Array[]} - * @private - */ -const $objectPool: Float32Array[] = []; - -/** - * @description オブジェクトプールから Float32Array オブジェクトを取得します。 - * Get a Float32Array object from the object pool. - * - * @param {number} [f0=0] - * @param {number} [f1=0] - * @param {number} [f2=0] - * @param {number} [f3=0] - * @param {number} [f4=0] - * @param {number} [f5=0] - * @param {number} [f6=0] - * @param {number} [f7=0] - * @return {Float32Array} - * @method - * @private - */ -const $getFloat32Array = ( - f0: number = 1, f1: number = 1, - f2: number = 1, f3: number = 1, - f4: number = 0, f5: number = 0, - f6: number = 0, f7: number = 0 -): Float32Array => { - - const array: Float32Array = $objectPool.pop() || new Float32Array(8); - - array[0] = f0; - array[1] = f1; - array[2] = f2; - array[3] = f3; - array[4] = f4; - array[5] = f5; - array[6] = f6; - array[7] = f7; - - return array; -}; - -/** - * @description 再利用する為に、オブジェクトプールに Float32Array オブジェクトを追加します。 - * Add a Float32Array object to the object pool for reuse. - * - * @param {Float32Array} array - * @method - * @private - */ -const $poolFloat32Array = (array: Float32Array): void => -{ - $objectPool.push(array); -}; +import { + $getFloat32Array8, + $poolFloat32Array8 +} from "./GeomUtil"; /** * @description ColorTransform クラスを使用すると、表示オブジェクトのカラー値を調整することができます。 @@ -110,7 +58,7 @@ export class ColorTransform * @type {Float32Array} * @private */ - this._$colorTransform = $getFloat32Array( + this._$colorTransform = $getFloat32Array8( red_multiplier, green_multiplier, blue_multiplier, alpha_multiplier, red_offset, green_offset, blue_offset, alpha_offset ); @@ -350,7 +298,7 @@ export class ColorTransform */ _$multiplication (a: Float32Array, b: Float32Array): Float32Array { - return $getFloat32Array( + return $getFloat32Array8( a[0] * b[0], a[1] * b[1], a[2] * b[2], @@ -373,15 +321,12 @@ export class ColorTransform } /** - * @param {Float32Array} buffer + * @param {Float32Array} array * @method * @private */ - _$poolBuffer (buffer: Float32Array): void + _$poolBuffer (array: Float32Array): void { - if ($objectPool.length > 10) { - return ; - } - $poolFloat32Array(buffer); + $poolFloat32Array8(array); } } diff --git a/packages/geom/src/GeomUtil.ts b/packages/geom/src/GeomUtil.ts new file mode 100644 index 00000000..ddad581a --- /dev/null +++ b/packages/geom/src/GeomUtil.ts @@ -0,0 +1,106 @@ +/** + * @type {Float32Array[]} + * @private + */ +const $objectPool6: Float32Array[] = []; + +/** + * @description オブジェクトプールから Float32Array オブジェクトを取得します。 + * Get a Float32Array object from the object pool. + * + * @param {number} [f0=0] + * @param {number} [f1=0] + * @param {number} [f2=0] + * @param {number} [f3=0] + * @param {number} [f4=0] + * @param {number} [f5=0] + * @return {Float32Array} + * @method + * @private + */ +export const $getFloat32Array6 = ( + f0: number = 1, f1: number = 0, + f2: number = 0, f3: number = 1, + f4: number = 0, f5: number = 0 +): Float32Array => { + + const array: Float32Array = $objectPool6.pop() || new Float32Array(6); + + array[0] = f0; + array[1] = f1; + array[2] = f2; + array[3] = f3; + array[4] = f4; + array[5] = f5; + + return array; +}; + +/** + * @description 再利用する為に、オブジェクトプールに Float32Array オブジェクトを追加します。 + * Add a Float32Array object to the object pool for reuse. + * + * @param {Float32Array} array + * @method + * @private + */ +export const $poolFloat32Array6 = (array: Float32Array): void => +{ + $objectPool6.push(array); +}; + +/** + * @type {Float32Array[]} + * @private + */ +const $objectPool8: Float32Array[] = []; + +/** + * @description オブジェクトプールから Float32Array オブジェクトを取得します。 + * Get a Float32Array object from the object pool. + * + * @param {number} [f0=0] + * @param {number} [f1=0] + * @param {number} [f2=0] + * @param {number} [f3=0] + * @param {number} [f4=0] + * @param {number} [f5=0] + * @param {number} [f6=0] + * @param {number} [f7=0] + * @return {Float32Array} + * @method + * @private + */ +export const $getFloat32Array8 = ( + f0: number = 1, f1: number = 1, + f2: number = 1, f3: number = 1, + f4: number = 0, f5: number = 0, + f6: number = 0, f7: number = 0 +): Float32Array => { + + const array: Float32Array = $objectPool8.pop() || new Float32Array(8); + + array[0] = f0; + array[1] = f1; + array[2] = f2; + array[3] = f3; + array[4] = f4; + array[5] = f5; + array[6] = f6; + array[7] = f7; + + return array; +}; + +/** + * @description 再利用する為に、オブジェクトプールに Float32Array オブジェクトを追加します。 + * Add a Float32Array object to the object pool for reuse. + * + * @param {Float32Array} array + * @method + * @private + */ +export const $poolFloat32Array8 = (array: Float32Array): void => +{ + $objectPool8.push(array); +}; \ No newline at end of file diff --git a/packages/geom/src/Matrix.ts b/packages/geom/src/Matrix.ts index ae49e5cc..6a5b8ef6 100644 --- a/packages/geom/src/Matrix.ts +++ b/packages/geom/src/Matrix.ts @@ -12,57 +12,10 @@ import { execute as matrixScaleService } from "../src/Matrix/service/MatrixScale import { execute as matrixSetToService } from "../src/Matrix/service/MatrixSetToService"; import { execute as matrixTransformPointService } from "../src/Matrix/service/MatrixTransformPointService"; import { execute as matrixTranslateService } from "../src/Matrix/service/MatrixTranslateService"; - -/** - * @type {Float32Array[]} - * @private - */ -const $objectPool: Float32Array[] = []; - -/** - * @description オブジェクトプールから Float32Array オブジェクトを取得します。 - * Get a Float32Array object from the object pool. - * - * @param {number} [f0=0] - * @param {number} [f1=0] - * @param {number} [f2=0] - * @param {number} [f3=0] - * @param {number} [f4=0] - * @param {number} [f5=0] - * @return {Float32Array} - * @method - * @private - */ -const $getFloat32Array = ( - f0: number = 1, f1: number = 0, - f2: number = 0, f3: number = 1, - f4: number = 0, f5: number = 0 -): Float32Array => { - - const array: Float32Array = $objectPool.pop() || new Float32Array(6); - - array[0] = f0; - array[1] = f1; - array[2] = f2; - array[3] = f3; - array[4] = f4; - array[5] = f5; - - return array; -}; - -/** - * @description 再利用する為に、オブジェクトプールに Float32Array オブジェクトを追加します。 - * Add a Float32Array object to the object pool for reuse. - * - * @param {Float32Array} array - * @method - * @private - */ -const $poolFloat32Array = (array: Float32Array): void => -{ - $objectPool.push(array); -}; +import { + $getFloat32Array6, + $poolFloat32Array6 +} from "./GeomUtil"; /** * @description Matrix クラスは、2 つの座標空間の間におけるポイントのマッピング方法を決定する変換マトリックスを表します。 @@ -103,7 +56,7 @@ export class Matrix * @type {Float32Array} * @private */ - this._$matrix = $getFloat32Array(a, b, c, d, tx, ty); + this._$matrix = $getFloat32Array6(a, b, c, d, tx, ty); } /** @@ -497,7 +450,7 @@ export class Matrix */ _$multiplication (a: Float32Array, b: Float32Array): Float32Array { - return $getFloat32Array( + return $getFloat32Array6( a[0] * b[0] + a[2] * b[1], a[1] * b[0] + a[3] * b[1], a[0] * b[2] + a[2] * b[3], @@ -506,16 +459,14 @@ export class Matrix a[1] * b[4] + a[3] * b[5] + a[5] ); } + /** - * @param {Float32Array} buffer + * @param {Float32Array} array * @method * @private */ - _$poolBuffer (buffer: Float32Array): void + _$poolBuffer (array: Float32Array): void { - if ($objectPool.length > 10) { - return ; - } - $poolFloat32Array(buffer); + $poolFloat32Array6(array); } } diff --git a/packages/geom/src/Transform.ts b/packages/geom/src/Transform.ts index 39428dab..a8357fa3 100644 --- a/packages/geom/src/Transform.ts +++ b/packages/geom/src/Transform.ts @@ -354,8 +354,10 @@ export class Transform } /** - * matrix プロパティから取得される Matrix の Matrix._$matrix と同じ値を返しますが、matrix プロパティと異なり Matrix を複製しません。 - * 返される値は一時的に使用することのみできます。返される値の要素を直接更新してはいけません。返される値をプール(Util.$poolFloat32Array)してはいけません。 + * @description matrix プロパティから取得される Matrix の Matrix._$matrix と同じ値を返しますが、matrix プロパティと異なり Matrix を複製しません。 + * 返される値は一時的に使用することのみできます。返される値の要素を直接更新してはいけません。 + * Returns the same value as Matrix._$matrix of Matrix obtained from the matrix property, but unlike the matrix property, does not duplicate Matrix. + * The returned value may only be used temporarily. Elements of the returned value must not be updated directly. * * @return {Float32Array} * @method diff --git a/packages/media/src/MediaUtil.ts b/packages/media/src/MediaUtil.ts index 0daeacf7..f3943132 100644 --- a/packages/media/src/MediaUtil.ts +++ b/packages/media/src/MediaUtil.ts @@ -1,5 +1,6 @@ import type { Sound } from "./Sound"; import type { Video } from "./Video"; +import type { AjaxOptionImpl } from "./interface/AjaxOptionImpl"; /** * @type {AudioContext} @@ -7,6 +8,101 @@ import type { Video } from "./Video"; */ export const $audioContext: AudioContext | null = "AudioContext" in window ? new AudioContext() : null; +/** + * @param {object} option + * @return {void} + * @method + * @public + */ +export const $ajax = (option: AjaxOptionImpl): void => +{ + // get or post + let postData: string | null = null; + switch (option.method.toUpperCase()) { + + case "GET": + if (option.data) { + const urls = option.url.split("?"); + + urls[1] = urls.length === 1 + ? option.data.toString() + : `${urls[1]}&${option.data.toString()}`; + + option.url = urls.join("?"); + } + break; + + case "PUT": + case "POST": + if (option.data) { + postData = option.data.toString(); + } + break; + + default: + break; + + } + + // start + const xmlHttpRequest = new XMLHttpRequest(); + + // init + xmlHttpRequest.open(option.method, option.url, true); + + // set mimeType + xmlHttpRequest.responseType = option.format; + + // use cookie + xmlHttpRequest.withCredentials = option.withCredentials; + + // add event + if (option.event) { + const keys: string[] = Object.keys(option.event); + for (let idx = 0; idx < keys.length; ++idx) { + + const name: string = keys[idx]; + + // @ts-ignore + xmlHttpRequest.addEventListener(name, option.event[name]); + } + } + + // set request header + for (let idx: number = 0; idx < option.headers.length; ++idx) { + const header = option.headers[idx]; + if (!header) { + continue; + } + xmlHttpRequest.setRequestHeader(header.name, header.value); + } + + xmlHttpRequest.send(postData); +}; + +/** + * @param {number} value + * @param {number} min + * @param {number} max + * @param {number} [default_value=null] + * @return {number} + * @method + * @static + */ +export const $clamp = ( + value: number, + min: number, + max: number, + default_value: number | null = null +): number => { + + const number: number = +value; + + return isNaN(number) && default_value !== null + ? default_value + : Math.min(Math.max(min, isNaN(number) ? 0 : number), max); +}; + /** * @type {number} * @private diff --git a/packages/media/src/Sound.ts b/packages/media/src/Sound.ts index 05ddf4bf..30011da1 100644 --- a/packages/media/src/Sound.ts +++ b/packages/media/src/Sound.ts @@ -6,15 +6,13 @@ import { execute as soundProgressEventService } from "./Sound/SoundProgressEvent import { execute as soundLoadendEventService } from "./Sound/SoundLoadendEventService"; import { execute as soundEndedEventService } from "./Sound/SoundEndedEventService"; import { execute as soundDecodeService } from "./Sound/SoundDecodeService"; -import { - $clamp, - $ajax -} from "../../../common/Util"; import { Event, EventDispatcher } from "@next2d/events"; import { + $clamp, + $ajax, $audioContext, $getSounds } from "./MediaUtil"; diff --git a/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.ts b/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.ts index dda384e2..25cafe76 100644 --- a/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.ts +++ b/packages/media/src/SoundMixer/SoundMixerUpdateVolumeService.ts @@ -1,7 +1,7 @@ import type { Sound } from "../Sound"; import type { Video } from "../Video"; -import { $clamp } from "../../../../common/Util"; import { + $clamp, $setVolume, $getSounds, $getVideos diff --git a/packages/media/src/SoundTransform.ts b/packages/media/src/SoundTransform.ts index a77ee4e4..ee4319de 100644 --- a/packages/media/src/SoundTransform.ts +++ b/packages/media/src/SoundTransform.ts @@ -1,4 +1,4 @@ -import { $clamp } from "../../../common/Util"; +import { $clamp } from "./MediaUtil"; /** * @description SoundTransform クラスにはボリュームとループのプロパティが含まれます。 diff --git a/packages/media/src/Video.ts b/packages/media/src/Video.ts index 52468415..c137bd95 100644 --- a/packages/media/src/Video.ts +++ b/packages/media/src/Video.ts @@ -2,10 +2,12 @@ import { SoundMixer } from "./SoundMixer"; import { DisplayObject } from "@next2d/display"; import { VideoEvent } from "@next2d/events"; import type { BoundsImpl } from "./interface/BoundsImpl"; -import { $clamp } from "../../../common/Util"; import { execute as videoCreateElementService } from "./Video/VideoCreateElementService"; import { execute as videoPlayEventService } from "./Video/VideoPlayEventService"; -import { $getVideos } from "./MediaUtil"; +import { + $clamp, + $getVideos +} from "./MediaUtil"; /** * @description サーバーまたはローカルに保存された録画済みビデオファイルを再生する Video オブジェクトです。 diff --git a/common/interface/AjaxEventImpl.ts b/packages/media/src/interface/AjaxEventImpl.ts similarity index 100% rename from common/interface/AjaxEventImpl.ts rename to packages/media/src/interface/AjaxEventImpl.ts diff --git a/common/interface/AjaxOptionImpl.ts b/packages/media/src/interface/AjaxOptionImpl.ts similarity index 100% rename from common/interface/AjaxOptionImpl.ts rename to packages/media/src/interface/AjaxOptionImpl.ts diff --git a/common/interface/URLLoaderDataFormatImpl.ts b/packages/media/src/interface/URLLoaderDataFormatImpl.ts similarity index 100% rename from common/interface/URLLoaderDataFormatImpl.ts rename to packages/media/src/interface/URLLoaderDataFormatImpl.ts diff --git a/common/interface/URLRequestHeaderImpl.ts b/packages/media/src/interface/URLRequestHeaderImpl.ts similarity index 100% rename from common/interface/URLRequestHeaderImpl.ts rename to packages/media/src/interface/URLRequestHeaderImpl.ts diff --git a/common/interface/URLRequestMethodImpl.ts b/packages/media/src/interface/URLRequestMethodImpl.ts similarity index 100% rename from common/interface/URLRequestMethodImpl.ts rename to packages/media/src/interface/URLRequestMethodImpl.ts From 289d6554ff4d7a2d7b1dfe24d02c8400d08cb014 Mon Sep 17 00:00:00 2001 From: ienaga Date: Sun, 28 Jul 2024 14:27:16 +0900 Subject: [PATCH 027/343] =?UTF-8?q?#154=20add:=20cache=E3=83=91=E3=83=83?= =?UTF-8?q?=E3=82=B1=E3=83=BC=E3=82=B8=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/publish.yml | 12 +- packages/cache/LICENSE | 21 ++ packages/cache/README.md | 11 + packages/cache/package.json | 28 +++ packages/cache/src/CacheStore.ts | 178 ++++++++++++++++ .../CacheStore/CacheStoreDestroyService.ts | 36 ++++ .../CacheStoreGenerateKeysService.ts | 46 +++++ .../src/CacheStore/CacheStoreGetService.ts | 28 +++ .../src/CacheStore/CacheStoreHasService.ts | 19 ++ .../CacheStore/CacheStoreRemoveByIdService.ts | 29 +++ .../src/CacheStore/CacheStoreRemoveService.ts | 36 ++++ .../src/CacheStore/CacheStoreResetService.ts | 29 +++ .../src/CacheStore/CacheStoreSetService.ts | 55 +++++ packages/cache/src/CacheUtil.ts | 39 ++++ packages/cache/src/index.ts | 1 + packages/core/package.json | 5 +- packages/core/src/CoreUtil.ts | 22 ++ packages/core/src/Display.ts | 2 +- packages/core/src/Events.ts | 2 +- packages/core/src/Filters.ts | 2 +- packages/core/src/Geom.ts | 2 +- packages/core/src/Media.ts | 2 +- packages/core/src/Net.ts | 2 +- packages/core/src/Next2D.ts | 192 ++++-------------- .../core/src/Next2D/CreateRootMovieClip.ts | 40 ++++ packages/core/src/Next2D/LoadService.ts | 96 +++++++++ packages/core/src/Player.ts | 148 ++------------ packages/core/src/Text.ts | 2 +- packages/core/src/UI.ts | 2 +- packages/core/src/interface/DisplayImpl.ts | 32 +++ packages/core/src/interface/EventsImpl.ts | 23 +++ packages/core/src/interface/FiltersImpl.ts | 23 +++ packages/core/src/interface/GeomImpl.ts | 15 ++ packages/core/src/interface/MediaImpl.ts | 13 ++ packages/core/src/interface/NetImpl.ts | 5 + .../core/src/interface/PlayerOptionsImpl.ts | 8 + packages/core/src/interface/StageDataImpl.ts | 6 + packages/core/src/interface/TextImpl.ts | 5 + packages/core/src/interface/UIImpl.ts | 9 + packages/interface/src/TextImpl.ts | 2 +- packages/webgl/src/index.ts | 1 - src/index.js | 29 --- src/index.ts | 38 +--- worker/renderer/src/index.ts | 14 +- 44 files changed, 936 insertions(+), 374 deletions(-) create mode 100644 packages/cache/LICENSE create mode 100644 packages/cache/README.md create mode 100644 packages/cache/package.json create mode 100644 packages/cache/src/CacheStore.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreDestroyService.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreGenerateKeysService.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreGetService.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreHasService.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreRemoveByIdService.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreRemoveService.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreResetService.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreSetService.ts create mode 100644 packages/cache/src/CacheUtil.ts create mode 100644 packages/cache/src/index.ts create mode 100644 packages/core/src/CoreUtil.ts create mode 100644 packages/core/src/Next2D/CreateRootMovieClip.ts create mode 100644 packages/core/src/Next2D/LoadService.ts create mode 100644 packages/core/src/interface/DisplayImpl.ts create mode 100644 packages/core/src/interface/EventsImpl.ts create mode 100644 packages/core/src/interface/FiltersImpl.ts create mode 100644 packages/core/src/interface/GeomImpl.ts create mode 100644 packages/core/src/interface/MediaImpl.ts create mode 100644 packages/core/src/interface/NetImpl.ts create mode 100644 packages/core/src/interface/PlayerOptionsImpl.ts create mode 100644 packages/core/src/interface/StageDataImpl.ts create mode 100644 packages/core/src/interface/TextImpl.ts create mode 100644 packages/core/src/interface/UIImpl.ts delete mode 100644 src/index.js diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0b215b67..952bd03a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -21,6 +21,9 @@ jobs: - run: cd ~/work/player/player/dist/src && npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} + - run: cd ~/work/player/player/dist/packages/cache && npm publish --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} - run: cd ~/work/player/player/dist/packages/core && npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} @@ -36,27 +39,18 @@ jobs: - run: cd ~/work/player/player/dist/packages/geom && npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} - - run: cd ~/work/player/player/dist/packages/interface && npm publish --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} - run: cd ~/work/player/player/dist/packages/media && npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} - run: cd ~/work/player/player/dist/packages/net && npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} - - run: cd ~/work/player/player/dist/packages/share && npm publish --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} - run: cd ~/work/player/player/dist/packages/text && npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} - run: cd ~/work/player/player/dist/packages/ui && npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} - - run: cd ~/work/player/player/dist/packages/util && npm publish --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} - run: cd ~/work/player/player/dist/packages/webgl && npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} diff --git a/packages/cache/LICENSE b/packages/cache/LICENSE new file mode 100644 index 00000000..a536abed --- /dev/null +++ b/packages/cache/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Next2D + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/cache/README.md b/packages/cache/README.md new file mode 100644 index 00000000..d30f7f1a --- /dev/null +++ b/packages/cache/README.md @@ -0,0 +1,11 @@ +@next2d/cache +============= + +## Installation + +``` +npm install @next2d/cache +``` + +## License +This project is licensed under the [MIT License](https://opensource.org/licenses/MIT) - see the [LICENSE](LICENSE) file for details. diff --git a/packages/cache/package.json b/packages/cache/package.json new file mode 100644 index 00000000..fc82f44c --- /dev/null +++ b/packages/cache/package.json @@ -0,0 +1,28 @@ +{ + "name": "@next2d/cache", + "version": "*", + "description": "Next2D Cache Packages", + "author": "Toshiyuki Ienaga (https://github.com/ienaga/)", + "license": "MIT", + "homepage": "https://next2d.app", + "bugs": "https://github.com/Next2D/Player/issues", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist" + ], + "exports": { + ".": { + "import": "./src/index.js", + "require": "./src/index.js" + } + }, + "keywords": [ + "Next2D", + "Next2D Cache" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/Next2D/Player.git" + } +} diff --git a/packages/cache/src/CacheStore.ts b/packages/cache/src/CacheStore.ts new file mode 100644 index 00000000..278e06a0 --- /dev/null +++ b/packages/cache/src/CacheStore.ts @@ -0,0 +1,178 @@ +import { execute as cacheStoreResetService } from "./CacheStore/CacheStoreResetService"; +import { execute as cacheStoreDestroyService } from "./CacheStore/CacheStoreDestroyService"; +import { execute as cacheStoreRemoveService } from "./CacheStore/CacheStoreRemoveService"; +import { execute as cacheStoreRemoveByIdService } from "./CacheStore/CacheStoreRemoveByIdService"; +import { execute as cacheStoreGetService } from "./CacheStore/CacheStoreGetService"; +import { execute as cacheStoreSetService } from "./CacheStore/CacheStoreSetService"; +import { execute as cacheStoreHasService } from "./CacheStore/CacheStoreHasService"; +import { execute as cacheStoreGenerateKeysService } from "./CacheStore/CacheStoreGenerateKeysService"; + +/** + * @description キャッシュ管理クラス + * Cache management class + * + * @class + * @private + */ +class CacheStore +{ + private readonly _$pool: HTMLCanvasElement[]; + private readonly _$store: Map; + + /** + * @constructor + */ + constructor () + { + /** + * @type {array} + * @private + */ + this._$pool = []; + + /** + * @type {Map} + * @private + */ + this._$store = new Map(); + } + + /** + * @description 登録された全てのキャッシュをリセット・破棄する + * Reset and destroy all registered caches + * + * @return {void} + * @method + * @public + */ + reset (): void + { + cacheStoreResetService(this, this._$store); + } + + /** + * @description 指定のオブジェクトを破棄する + * Destroy the specified object + * + * @param {object} [object=null] + * @return {void} + * @method + * @public + */ + destroy (object: any = null): void + { + cacheStoreDestroyService(this._$pool, object); + } + + /** + * @description HTMLCanvasElementを返却 + * Returns HTMLCanvasElement + * + * @return {HTMLCanvasElement} + * @method + * @public + */ + getCanvas (): HTMLCanvasElement + { + return this._$pool.pop() || document.createElement("canvas"); + } + + /** + * @description HTMLCanvasElementを再利用する為に、内部配列にプール + * Pool in an internal array to reuse HTMLCanvasElement + * + * @param {string} id + * @param {string} type + * @returns {void} + * @method + * @public + */ + remove (id: string, type: string): void + { + cacheStoreRemoveService(this._$store, id, type); + } + + /** + * @description 指定IDのキャッシュを削除する + * Delete the cache for the specified ID + * + * @param {string} id + * @returns {void} + * @method + * @public + */ + removeCache (id: string): void + { + cacheStoreRemoveByIdService(this, this._$store, id); + } + + /** + * @description 指定のキーのキャッシュデータを返却 + * Returns the cache data for the specified key + * + * @param {array} keys + * @return {*} + * @method + * @public + */ + get (keys: string[]): any + { + return cacheStoreGetService(this._$store, keys); + } + + /** + * @description キャッシュストアにデータをセット + * Set data in the cache store + * + * @param {array} keys + * @param {*} value + * @return {void} + * @method + * @public + */ + set (keys: string[], value: any = null): void + { + cacheStoreSetService( + this, this._$store, keys, value + ); + } + + /** + * @description 指定キーのキャッシュが存在するかどうか + * Whether the specified key cache exists + * + * @param {array} keys + * @return {boolean} + * @method + * @public + */ + has (keys: string[]): boolean + { + return cacheStoreHasService(this._$store, keys); + } + + /** + * @description キャッシュストアのキーを生成 + * Generate cache store keys + * + * @param {string} unique_key + * @param {array} keys + * @param {array} [scales=null] + * @param {Float32Array} [color=null] + * @return {void} + * @method + * @public + */ + generateKeys ( + unique_key: string, + keys: string[], + scales: number[] | null = null, + color: Float32Array | null = null + ): void { + cacheStoreGenerateKeysService( + unique_key, keys, scales, color + ); + } +} + +export const $cacheStore = new CacheStore(); \ No newline at end of file diff --git a/packages/cache/src/CacheStore/CacheStoreDestroyService.ts b/packages/cache/src/CacheStore/CacheStoreDestroyService.ts new file mode 100644 index 00000000..0239e487 --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreDestroyService.ts @@ -0,0 +1,36 @@ +/** + * @description 破棄するHTMLCanvasElementをプールに保管 + * Store the HTMLCanvasElement to be destroyed in the pool + * + * @param {HTMLCanvasElement[]} pool + * @param {object} object + * @return {void} + * @method + * @public + */ +export const execute = ( + pool: HTMLCanvasElement[], + object: any +): void => { + + if (!object || typeof object !== "object") { + return ; + } + + if ("canvas" in object + && object instanceof CanvasRenderingContext2D + ) { + + const canvas: HTMLCanvasElement = object.canvas; + const width: number = canvas.width; + const height: number = canvas.height; + + object.clearRect(0, 0, width + 1, height + 1); + + // canvas reset + canvas.width = canvas.height = 1; + + // pool + pool.push(canvas); + } +}; \ No newline at end of file diff --git a/packages/cache/src/CacheStore/CacheStoreGenerateKeysService.ts b/packages/cache/src/CacheStore/CacheStoreGenerateKeysService.ts new file mode 100644 index 00000000..a0c57730 --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreGenerateKeysService.ts @@ -0,0 +1,46 @@ +/** + * @description キャッシュストアのキーを生成 + * Generate cache store keys + * + * @param {string} unique_key + * @param {array} keys + * @param {array} [scales=null] + * @param {Float32Array} [color=null] + * @return {void} + * @method + * @public + */ +export const execute = ( + unique_key: string, + keys: string[], + scales: number[] | null = null, + color: Float32Array | null = null +): void => { + + let str: string = ""; + if (scales && scales.length) { + str += scales.join("_"); + } + + // color + if (color && color.length) { + str += color[7] === 0 ? "" : `_${color[7]}`; + } + + if (str) { + let hash = 0; + const length: number = str.length; + for (let idx: number = 0; idx < length; idx++) { + + const chr: number = str.charCodeAt(idx); + + hash = (hash << 5) - hash + chr; + hash |= 0; + } + keys[1] = `${hash}`; + } else { + keys[1] = "0"; + } + + keys[0] = `${unique_key}`; +}; \ No newline at end of file diff --git a/packages/cache/src/CacheStore/CacheStoreGetService.ts b/packages/cache/src/CacheStore/CacheStoreGetService.ts new file mode 100644 index 00000000..0c7830ce --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreGetService.ts @@ -0,0 +1,28 @@ +/** + * @description 指定のキーからデータを取得 + * Get data from the specified key + * + * @param {Map} data_store + * @param {array} keys + * @return {*} + * @method +* @public +*/ +export const execute = ( + data_store: Map>, + keys: string[] +): any => { + + const id: string = keys[0]; + if (!data_store.has(id)) { + return null; + } + + const type: string = keys[1]; + const data = data_store.get(id) as NonNullable>; + if (!data.has(type)) { + return null; + } + + return data.get(type); +}; \ No newline at end of file diff --git a/packages/cache/src/CacheStore/CacheStoreHasService.ts b/packages/cache/src/CacheStore/CacheStoreHasService.ts new file mode 100644 index 00000000..3fc8c101 --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreHasService.ts @@ -0,0 +1,19 @@ +/** + * @description 指定キーのキャッシュが存在するかどうか + * Whether the specified key cache exists + * + * @param {Map} data_store + * @param {array} keys + * @return {boolean} + * @method + * @public + */ +export const execute = ( + data_store: Map>, + keys: string[] +): boolean => { + const id: string = keys[0]; + return !data_store.has(id) + ? false + : (data_store.get(id) as NonNullable>).has(keys[1]); +}; \ No newline at end of file diff --git a/packages/cache/src/CacheStore/CacheStoreRemoveByIdService.ts b/packages/cache/src/CacheStore/CacheStoreRemoveByIdService.ts new file mode 100644 index 00000000..51fc4bb7 --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreRemoveByIdService.ts @@ -0,0 +1,29 @@ +import type { CacheStore } from "../CacheStore"; +import { $poolMap } from "../CacheUtil"; + +/** + * @description 指定IDのキャッシュを削除する + * Delete the cache for the specified ID + * + * @param {CacheStore} cache_store + * @param {Map} data_store + * @param {string} id + */ +export const execute = ( + cache_store: CacheStore, + data_store: Map>, + id: string +): void => { + + if (!data_store.has(id)) { + return ; + } + + const data = data_store.get(id) as NonNullable>; + for (const value of data.values()) { + cache_store.destroy(value); + } + + data_store.delete(id); + $poolMap(data); +}; \ No newline at end of file diff --git a/packages/cache/src/CacheStore/CacheStoreRemoveService.ts b/packages/cache/src/CacheStore/CacheStoreRemoveService.ts new file mode 100644 index 00000000..f2b97b63 --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreRemoveService.ts @@ -0,0 +1,36 @@ +import { $poolMap } from "../CacheUtil"; + +/** + * @description キャッシュストアから指定したキャッシュを削除 + * Remove the specified cache from the cache store + * + * @param {Map} data_store + * @param {string} id + * @param {string} type + * @return {void} + * @method + * @public + */ +export const execute = ( + data_store: Map>, + id: string, + type: string +): void => { + + if (!data_store.has(id)) { + return ; + } + + const data: Map = data_store.get(id) as NonNullable>; + if (!data.has(type)) { + return ; + } + + // delete key + data.delete(type); + + if (!data.size) { + $poolMap(data); + data_store.delete(id); + } +}; \ No newline at end of file diff --git a/packages/cache/src/CacheStore/CacheStoreResetService.ts b/packages/cache/src/CacheStore/CacheStoreResetService.ts new file mode 100644 index 00000000..88717364 --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreResetService.ts @@ -0,0 +1,29 @@ +import type { CacheStore } from "../CacheStore"; +import { $poolMap } from "../CacheUtil"; + +/** + * @description キャッシュストアを全てリセット + * Reset all cache stores + * + * @param {CacheStore} cache_store + * @param {Map} data_store + * @return {void} + * @method + * @public + */ +export const execute = ( + cache_store: CacheStore, + data_store: Map> +): void => { + + for (const data of data_store.values()) { + + for (const value of data.values()) { + cache_store.destroy(value); + } + + $poolMap(data); + } + + data_store.clear(); +}; \ No newline at end of file diff --git a/packages/cache/src/CacheStore/CacheStoreSetService.ts b/packages/cache/src/CacheStore/CacheStoreSetService.ts new file mode 100644 index 00000000..062ebb43 --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreSetService.ts @@ -0,0 +1,55 @@ +import type { CacheStore } from "../CacheStore"; +import { + $getMap, + $poolMap +} from "../CacheUtil"; + +/** + * @description キャッシュストアにデータをセット + * Set data in the cache store + * + * @param {CacheStore} cache_store + * @param {Map} data_store + * @param {array} keys + * @param {*} value + * @return {void} + * @method + * @public + */ +export const execute = ( + cache_store: CacheStore, + data_store: Map>, + keys: string[], + value: any = null +): void => { + + const id: string = keys[0]; + const type: string = keys[1]; + + // init + if (!data_store.has(id)) { + data_store.set(id, $getMap()); + } + + const data = data_store.get(id) as NonNullable>; + if (value === null) { + + if (!data.has(type)) { + return ; + } + + cache_store.destroy(data.get(type)); + + data.delete(type); + + if (!data.size) { + data_store.delete(id); + $poolMap(data); + } + + return ; + } + + // set cache + data.set(type, value); +}; \ No newline at end of file diff --git a/packages/cache/src/CacheUtil.ts b/packages/cache/src/CacheUtil.ts new file mode 100644 index 00000000..96656f83 --- /dev/null +++ b/packages/cache/src/CacheUtil.ts @@ -0,0 +1,39 @@ +/** + * @description 使用済みになったMapオブジェクトをプール + * Pool Map objects that are no longer in use. + * + * @type {Map[]} + * @const + * @static + */ +export const $maps: Map[] = []; + +/** + * @description Mapオブジェクトをプール + * Pool Map object. + * + * @param {Map} map + * @return void + * @method + * @static + */ +export const $poolMap = (map: Map): void => +{ + if (map.size) { + map.clear(); + } + $maps.push(map); +}; + +/** + * @description プールしたMapオブジェクト、もしくは新規のMapを返却 + * Returns a pooled Map object or a new Map. + * + * @return {Map} + * @method + * @static + */ +export const $getMap = (): Map => +{ + return $maps.pop() || new Map(); +}; \ No newline at end of file diff --git a/packages/cache/src/index.ts b/packages/cache/src/index.ts new file mode 100644 index 00000000..97e2dffd --- /dev/null +++ b/packages/cache/src/index.ts @@ -0,0 +1 @@ +export * from "./CacheStore"; \ No newline at end of file diff --git a/packages/core/package.json b/packages/core/package.json index 0b0be264..28dd5bed 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -26,16 +26,13 @@ "url": "git+https://github.com/Next2D/Player.git" }, "peerDependencies": { - "@next2d/interface": "file:../interface", "@next2d/webgl": "file:../webgl", "@next2d/display": "file:../display", "@next2d/core": "file:../core", "@next2d/net": "file:../net", - "@next2d/share": "file:../share", "@next2d/events": "file:../events", "@next2d/media": "file:../media", "@next2d/text": "file:../text", - "@next2d/geom": "file:../geom", - "@next2d/util": "file:../util" + "@next2d/geom": "file:../geom" } } diff --git a/packages/core/src/CoreUtil.ts b/packages/core/src/CoreUtil.ts new file mode 100644 index 00000000..d1c98c23 --- /dev/null +++ b/packages/core/src/CoreUtil.ts @@ -0,0 +1,22 @@ +/** + * @param {number} value + * @param {number} min + * @param {number} max + * @param {number} [default_value=null] + * @return {number} + * @method + * @static + */ +export const $clamp = ( + value: number, + min: number, + max: number, + default_value: number | null = null +): number => { + + const number: number = +value; + + return isNaN(number) && default_value !== null + ? default_value + : Math.min(Math.max(min, isNaN(number) ? 0 : number), max); +}; \ No newline at end of file diff --git a/packages/core/src/Display.ts b/packages/core/src/Display.ts index 4c6a99e8..2ceea93e 100644 --- a/packages/core/src/Display.ts +++ b/packages/core/src/Display.ts @@ -1,4 +1,4 @@ -import type { DisplayImpl } from "@next2d/interface"; +import type { DisplayImpl } from "./interface/DisplayImpl"; import { DisplayObject, InteractiveObject, diff --git a/packages/core/src/Events.ts b/packages/core/src/Events.ts index de7b63d2..4971f0e9 100644 --- a/packages/core/src/Events.ts +++ b/packages/core/src/Events.ts @@ -1,4 +1,4 @@ -import { EventsImpl } from "@next2d/interface"; +import type { EventsImpl } from "./interface/EventsImpl"; import { Event, EventDispatcher, diff --git a/packages/core/src/Filters.ts b/packages/core/src/Filters.ts index 306ee19c..ae1b69ef 100644 --- a/packages/core/src/Filters.ts +++ b/packages/core/src/Filters.ts @@ -1,4 +1,4 @@ -import type { FiltersImpl } from "@next2d/interface"; +import type { FiltersImpl } from "./interface/FiltersImpl"; import { BevelFilter, BlurFilter, diff --git a/packages/core/src/Geom.ts b/packages/core/src/Geom.ts index 08d31ade..7f8d9913 100644 --- a/packages/core/src/Geom.ts +++ b/packages/core/src/Geom.ts @@ -1,4 +1,4 @@ -import { GeomImpl } from "@next2d/interface"; +import type { GeomImpl } from "./interface/GeomImpl"; import { ColorTransform, Matrix, diff --git a/packages/core/src/Media.ts b/packages/core/src/Media.ts index c97f7480..f83dafc4 100644 --- a/packages/core/src/Media.ts +++ b/packages/core/src/Media.ts @@ -1,4 +1,4 @@ -import { MediaImpl } from "@next2d/interface"; +import type { MediaImpl } from "./interface/MediaImpl"; import { Sound, SoundMixer, diff --git a/packages/core/src/Net.ts b/packages/core/src/Net.ts index 05d530da..5b216388 100644 --- a/packages/core/src/Net.ts +++ b/packages/core/src/Net.ts @@ -1,4 +1,4 @@ -import type { NetImpl } from "@next2d/interface"; +import type { NetImpl } from "./interface/NetImpl"; import { URLRequest } from "@next2d/net"; const net: NetImpl = { diff --git a/packages/core/src/Next2D.ts b/packages/core/src/Next2D.ts index 5df11d66..b8076cdd 100644 --- a/packages/core/src/Next2D.ts +++ b/packages/core/src/Next2D.ts @@ -1,3 +1,13 @@ +import type { DisplayImpl } from "./interface/DisplayImpl"; +import type { EventsImpl } from "./interface/EventsImpl"; +import type { FiltersImpl } from "./interface/FiltersImpl"; +import type { GeomImpl } from "./interface/GeomImpl"; +import type { MediaImpl } from "./interface/MediaImpl"; +import type { NetImpl } from "./interface/NetImpl"; +import type { TextImpl } from "./interface/TextImpl"; +import type { UIImpl } from "./interface/UIImpl"; +import type { PlayerOptionsImpl } from "./interface/PlayerOptionsImpl"; +import type { Sprite } from "@next2d/display"; import { events } from "./Events"; import { display } from "./Display"; import { filters } from "./Filters"; @@ -6,43 +16,20 @@ import { media } from "./Media"; import { net } from "./Net"; import { text } from "./Text"; import { ui } from "./UI"; -import { Player } from "@next2d/core"; -import { URLRequest } from "@next2d/net"; -import { - Loader, - Sprite, - LoaderInfo -} from "@next2d/display"; -import { - Event, - IOErrorEvent -} from "@next2d/events"; -import { - PlayerOptionsImpl, - DisplayImpl, - EventsImpl, - FiltersImpl, - GeomImpl, - MediaImpl, - NetImpl, - TextImpl, - UIImpl, - StageDataImpl -} from "@next2d/interface"; -import { - $clamp, - $poolArray -} from "@next2d/share"; +import { Player } from "./Player"; +import { execute as loadService } from "./Next2D/LoadService"; +import { execute as createRootMovieClip } from "./Next2D/CreateRootMovieClip"; /** - * playerの起動管理クラス - * player startup management class + * @description playerの起動管理クラス + * player startup management class + * * @class + * @public */ export class Next2D { - private readonly _$promises: Promise[]; - private readonly _$player: Player; + public readonly player: Player; public readonly display: DisplayImpl; public readonly events: EventsImpl; public readonly filters: FiltersImpl; @@ -51,24 +38,19 @@ export class Next2D public readonly net: NetImpl; public readonly text: TextImpl; public readonly ui: UIImpl; + private readonly _$promise: Promise; /** * @constructor * @public */ - constructor (promises: Promise[]) + constructor () { - /** - * @type {array} - * @private - */ - this._$promises = promises; - /** * @type {Player} * @private */ - this._$player = new Player(); + this.player = new Player(); /** * @type {DisplayImpl} @@ -117,16 +99,19 @@ export class Next2D * @public */ this.ui = ui; - } - /** - * @member {Player} - * @readonly - * @return {Player} - */ - get player (): Player - { - return this._$player; + /** + * @type {Promise} + * @private + */ + this._$promise = new Promise((resolve): void => + { + if (document.readyState === "loading") { + window.addEventListener("DOMContentLoaded", (): void => resolve(), { "once": true }); + } else { + resolve(); + } + }); } /** @@ -146,85 +131,10 @@ export class Next2D * @method * @public */ - load (url: string, options: PlayerOptionsImpl): void + async load (url: string, options: PlayerOptionsImpl): Promise { - Promise - .all(this._$promises) - .then(() => - { - $poolArray(this._$promises); - - if (url === "develop") { - const path: string = location - .search - .slice(1) - .split("&")[0]; - - if (!path) { - return ; - } - url = `${location.origin}/${path}`; - } - - if (!url) { - return ; - } - - if (url.charAt(1) === "/") { - url = url.slice(1); - } - - // base set - if ((!options || !("base" in options)) && url.indexOf("//") > -1) { - this._$player.base = url; - } - - this._$player.setOptions(options); - this._$player._$initialize(); - - const loader: Loader = new Loader(); - - loader - .contentLoaderInfo - .addEventListener(IOErrorEvent.IO_ERROR, (event: IOErrorEvent) => - { - if (event.target) { - event.target.removeEventListener(IOErrorEvent.IO_ERROR, event.listener); - } - alert("Error: " + event.text); - }); - - loader - .contentLoaderInfo - .addEventListener(Event.COMPLETE, (event: Event) => - { - const loaderInfo: LoaderInfo = event.target as NonNullable; - const player: Player = this._$player; - - loaderInfo - .removeEventListener(Event.COMPLETE, event.listener); - - if (loaderInfo._$data) { - - const stage: StageDataImpl = loaderInfo._$data.stage; - - player.bgColor = stage.bgColor; - player._$setBackgroundColor(stage.bgColor); - - player.stage.addChild(loaderInfo.content); - - player.width = stage.width; - player.height = stage.height; - - // set fps fixed logic - player.stage._$frameRate = $clamp(+stage.fps, 1, 60, 60); - } - - player._$resize(); - }); - - loader.load(new URLRequest(url)); - }); + await this._$promise; + await loadService(this.player, url, options); } /** @@ -240,28 +150,14 @@ export class Next2D * @public */ async createRootMovieClip ( - width: number = 240, height: number = 240, - fps: number = 24, options: PlayerOptionsImpl|null = null + width: number = 240, + height: number = 240, + fps: number = 24, + options: PlayerOptionsImpl | null = null ): Promise { - - await Promise.all(this._$promises); - $poolArray(this._$promises); - - const player: Player = this._$player; - - // setup - player.width = width | 0; - player.height = height | 0; - player.mode = "create"; - player.stage._$frameRate = fps | 0; - player.setOptions(options); - player._$initialize(); - - const root: Sprite = player.stage.addChild(new Sprite()); - - player._$loadStatus = Player.LOAD_END; - player.play(); - - return root; + await this._$promise; + return await createRootMovieClip( + this.player, width, height, fps, options + ); } } diff --git a/packages/core/src/Next2D/CreateRootMovieClip.ts b/packages/core/src/Next2D/CreateRootMovieClip.ts new file mode 100644 index 00000000..3a90abe3 --- /dev/null +++ b/packages/core/src/Next2D/CreateRootMovieClip.ts @@ -0,0 +1,40 @@ +import type { PlayerOptionsImpl } from "../interface/PlayerOptionsImpl"; +import { Sprite } from "@next2d/display"; +import { Player } from "../Player"; + +/** + * @description RootのMovieClipを作成します。 + * Create a MovieClip for Root. + * + * @param {Player} player + * @param {number} width + * @param {number} height + * @param {number} fps + * @param {object} options + * @return {Promise} + * @method + * @protected + */ +export const execute = async ( + player: Player, + width: number = 240, + height: number = 240, + fps: number = 24, + options: PlayerOptionsImpl | null = null +): Promise => { + + // setup + player.width = width | 0; + player.height = height | 0; + player.mode = "create"; + player.stage._$frameRate = fps | 0; + player.setOptions(options); + player._$initialize(); + + const root: Sprite = player.stage.addChild(new Sprite()); + + player._$loadStatus = Player.LOAD_END; + player.play(); + + return root; +}; \ No newline at end of file diff --git a/packages/core/src/Next2D/LoadService.ts b/packages/core/src/Next2D/LoadService.ts new file mode 100644 index 00000000..6679e6ce --- /dev/null +++ b/packages/core/src/Next2D/LoadService.ts @@ -0,0 +1,96 @@ +import type { PlayerOptionsImpl } from "../interface/PlayerOptionsImpl"; +import type { StageDataImpl } from "../interface/StageDataImpl"; +import type { Player } from "../Player"; +import { URLRequest } from "@next2d/net"; +import { $clamp } from "../CoreUtil"; +import { + Event, + IOErrorEvent +} from "@next2d/events"; +import { + Loader, + LoaderInfo +} from "@next2d/display"; + +/** + * @description 指定のURLからJSONファイルを読み込みます。 + * Reads a JSON file from the specified URL. + * + * @param {string} url + * @param {PlayerOptionsImpl} options + * @return {Promise} + * @method + * @protected + */ +export const execute = (player: Player, url: string, options: PlayerOptionsImpl): Promise => +{ + return new Promise((resolve: Function) => + { + if (url === "develop") { + const path: string = location + .search + .slice(1) + .split("&")[0]; + + if (!path) { + return ; + } + url = `${location.origin}/${path}`; + } + + if (!url) { + return ; + } + + if (url.charAt(1) === "/") { + url = url.slice(1); + } + + player.setOptions(options); + player._$initialize(); + + const loader: Loader = new Loader(); + + loader + .contentLoaderInfo + .addEventListener(IOErrorEvent.IO_ERROR, (event: IOErrorEvent): void => + { + alert("Error: " + event.text); + resolve(); + }); + + loader + .contentLoaderInfo + .addEventListener(Event.COMPLETE, (event: Event): void => + { + const loaderInfo: LoaderInfo = event.target as NonNullable; + + if (event.listener) { + loaderInfo + .removeEventListener(Event.COMPLETE, event.listener); + } + + if (loaderInfo._$data) { + + const stage: StageDataImpl = loaderInfo._$data.stage; + + player.bgColor = stage.bgColor; + player._$setBackgroundColor(stage.bgColor); + + player.stage.addChild(loaderInfo.content); + + player.width = stage.width; + player.height = stage.height; + + // set fps fixed logic + player.stage._$frameRate = $clamp(+stage.fps, 1, 60, 60); + } + + player._$resize(); + + resolve(); + }); + + loader.load(new URLRequest(url)); + }); +}; \ No newline at end of file diff --git a/packages/core/src/Player.ts b/packages/core/src/Player.ts index 9a80e9c8..1f999cb4 100644 --- a/packages/core/src/Player.ts +++ b/packages/core/src/Player.ts @@ -9,8 +9,6 @@ import { EventPhase } from "@next2d/events"; import { - Video, - Sound, SoundMixer } from "@next2d/media"; import { @@ -73,7 +71,6 @@ import { $doUpdated, $isUpdated, $getArray, - $getFloat32Array6, $getMap, $uintToRGBA, $toColorInt, @@ -83,15 +80,24 @@ import { $clamp, $devicePixelRatio, $setDevicePixelRatio, - $cacheStore, - CacheStore + $cacheStore } from "@next2d/share"; +// @ts-ignore +import RendererWorker from "../../../worker/renderer/src/index?worker&inline"; + +/** + * @type {Worker} + * @private + */ +const worker: Worker = new RendererWorker(); + /** - * 描画のイベントや設定やコントロールの管理クラス - * Management classes for drawing events, settings and controls + * @description Next2Dの描画、イベント、設定、コントロールの管理クラスです。 + * This class manages Next2D drawings, events, settings, and controls. * * @class + * @public */ export class Player { @@ -107,8 +113,6 @@ export class Player public _$state: "up" | "down"; public _$attachment: AttachmentImpl | null; public _$textField: TextField | null; - public readonly _$videos: Video[]; - public readonly _$sources: Sound[]; private _$mode: PlayerModeImpl; private _$context: CanvasToWebGLContext|null; private _$rollOverObject: DisplayObjectImpl | null; @@ -126,7 +130,6 @@ export class Player private _$optionHeight: number; private _$tagId: string; private _$bgColor: string; - private _$base: string; private _$fullScreen: boolean; private _$timerId: number; private _$loadId: number; @@ -138,7 +141,6 @@ export class Player private readonly _$hitObject: PlayerHitObjectImpl; private readonly _$ratio: number; private readonly _$matrix: Float32Array; - private readonly _$broadcastEvents: Map; private readonly _$quality: StageQualityImpl; private readonly _$canvas: HTMLCanvasElement; @@ -286,7 +288,7 @@ export class Player * @type {Float32Array} * @private */ - this._$matrix = $getFloat32Array6(1, 0, 0, 1, 0, 0); // fixed size 6 + this._$matrix = new Float32Array([1, 0, 0, 1, 0, 0]); /** * @type {number} @@ -344,12 +346,6 @@ export class Player */ this._$deltaY = 0; - /** - * @type {Map} - * @private - */ - this._$broadcastEvents = $getMap(); - /** * @type {number} * @default 0 @@ -378,13 +374,6 @@ export class Player */ this._$bgColor = "transparent"; - /** - * @type {string} - * @default "" - * @private - */ - this._$base = ""; - /** * @type {boolean} * @default false @@ -399,18 +388,6 @@ export class Player */ this._$quality = "high"; - /** - * @type {array} - * @private - */ - this._$sources = $getArray(); - - /** - * @type {array} - * @private - */ - this._$videos = $getArray(); - /** * @type {TextField} * @default null @@ -489,16 +466,6 @@ export class Player return 2; } - /** - * @return {CacheStore} - * @readonly - * @public - */ - get cacheStore (): CacheStore - { - return $cacheStore; - } - /** * @type {HTMLCanvasElement} * @readonly @@ -509,16 +476,6 @@ export class Player return this._$canvas; } - /** - * @return {Map} - * @readonly - * @public - */ - get broadcastEvents (): Map - { - return this._$broadcastEvents; - } - /** * @member {CanvasToWebGLContext|null} * @default null @@ -533,46 +490,6 @@ export class Player this._$context = context; } - /** - * @member {string} - * @default "" - * @public - */ - get base (): string - { - return this._$base; - } - set base (base: string) - { - if (base.indexOf("//") === -1) { - - const urls = base.split("/"); - if (urls[0] === "" || urls[0] === ".") { - urls.shift(); - } - urls.pop(); - - this._$base = `${location.origin}/`; - if (urls.length) { - this._$base += `${urls.join("/")}/`; - } - - } else { - - if (base.indexOf("?") === -1) { - - this._$base = base.slice(-1) === "/" ? base : `${base}/`; - - } else { - - const path = base.split("?")[0]; - this._$base = path.slice(-1) === "/" ? path : `${path}/`; - - } - - } - } - /** * @return {Stage} * @readonly @@ -784,7 +701,6 @@ export class Player this._$optionWidth = options.width || this._$optionWidth; this._$optionHeight = options.height || this._$optionHeight; this._$tagId = options.tagId || this._$tagId; - this.base = options.base || this._$base; this._$bgColor = options.bgColor || this._$bgColor; this._$fullScreen = !!options.fullScreen; } @@ -1142,36 +1058,6 @@ export class Player } - /** - * @return {void} - * @method - * @private - */ - const loadWebAudio = (): void => - { - this._$canvas.removeEventListener($MOUSE_UP, loadWebAudio); - this._$canvas.removeEventListener($TOUCH_END, loadWebAudio); - - if (!$audioContext) { - $loadAudioData(); - - for (let idx = 0; idx < this._$videos.length; ++idx) { - const video: Video = this._$videos[idx]; - if (!video._$video) { - continue; - } - - video._$video.muted = false; - } - } - }; - - // @ts-ignore - this._$canvas.addEventListener($TOUCH_END, loadWebAudio); - - // @ts-ignore - this._$canvas.addEventListener($MOUSE_UP, loadWebAudio); - // @ts-ignore this._$canvas.addEventListener($TOUCH_START, (event: TouchEvent) => { @@ -1641,12 +1527,6 @@ export class Player this._$pointerCheck(); } - } else { - - if (this._$videos.length && !$rendererWorker) { - this._$draw(); - } - } // next frame diff --git a/packages/core/src/Text.ts b/packages/core/src/Text.ts index 56facf35..2d27bd7c 100644 --- a/packages/core/src/Text.ts +++ b/packages/core/src/Text.ts @@ -1,4 +1,4 @@ -import { TextImpl } from "@next2d/interface"; +import type { TextImpl } from "./interface/TextImpl"; import { TextFormat } from "@next2d/text"; const text: TextImpl = { diff --git a/packages/core/src/UI.ts b/packages/core/src/UI.ts index a370862d..07eefcdc 100644 --- a/packages/core/src/UI.ts +++ b/packages/core/src/UI.ts @@ -1,4 +1,4 @@ -import { UIImpl } from "@next2d/interface"; +import type { UIImpl } from "./interface/UIImpl"; import { Easing, Tween diff --git a/packages/core/src/interface/DisplayImpl.ts b/packages/core/src/interface/DisplayImpl.ts new file mode 100644 index 00000000..8f4369ca --- /dev/null +++ b/packages/core/src/interface/DisplayImpl.ts @@ -0,0 +1,32 @@ +import type { + DisplayObject, + InteractiveObject, + DisplayObjectContainer, + BitmapData, + BlendMode, + FrameLabel, + Graphics, + Loader, + LoaderInfo, + MovieClip, + Shape, + Sprite, + Stage, + TextField +} from "@next2d/display"; +export interface DisplayImpl { + DisplayObject: typeof DisplayObject; + InteractiveObject: typeof InteractiveObject; + DisplayObjectContainer: typeof DisplayObjectContainer; + BitmapData: typeof BitmapData; + BlendMode: typeof BlendMode; + FrameLabel: typeof FrameLabel; + Graphics: typeof Graphics; + Loader: typeof Loader; + LoaderInfo: typeof LoaderInfo; + MovieClip: typeof MovieClip; + Shape: typeof Shape; + Sprite: typeof Sprite; + Stage: typeof Stage; + TextField: typeof TextField; +} diff --git a/packages/core/src/interface/EventsImpl.ts b/packages/core/src/interface/EventsImpl.ts new file mode 100644 index 00000000..fd690483 --- /dev/null +++ b/packages/core/src/interface/EventsImpl.ts @@ -0,0 +1,23 @@ +import type { + Event, + EventDispatcher, + EventPhase, + FocusEvent, + HTTPStatusEvent, + IOErrorEvent, + MouseEvent, + ProgressEvent, + VideoEvent +} from "@next2d/events"; + +export interface EventsImpl { + Event: typeof Event; + EventDispatcher: typeof EventDispatcher; + EventPhase: typeof EventPhase; + FocusEvent: typeof FocusEvent; + HTTPStatusEvent: typeof HTTPStatusEvent; + IOErrorEvent: typeof IOErrorEvent; + MouseEvent: typeof MouseEvent; + ProgressEvent: typeof ProgressEvent; + VideoEvent: typeof VideoEvent; +} \ No newline at end of file diff --git a/packages/core/src/interface/FiltersImpl.ts b/packages/core/src/interface/FiltersImpl.ts new file mode 100644 index 00000000..7e06a4d5 --- /dev/null +++ b/packages/core/src/interface/FiltersImpl.ts @@ -0,0 +1,23 @@ +import type { + BevelFilter, + BlurFilter, + ColorMatrixFilter, + ConvolutionFilter, + DisplacementMapFilter, + DropShadowFilter, + GlowFilter, + GradientBevelFilter, + GradientGlowFilter +} from "@next2d/filters"; + +export interface FiltersImpl { + BevelFilter: typeof BevelFilter; + BlurFilter: typeof BlurFilter; + ColorMatrixFilter: typeof ColorMatrixFilter; + ConvolutionFilter: typeof ConvolutionFilter; + DisplacementMapFilter: typeof DisplacementMapFilter; + DropShadowFilter: typeof DropShadowFilter; + GlowFilter: typeof GlowFilter; + GradientBevelFilter: typeof GradientBevelFilter; + GradientGlowFilter: typeof GradientGlowFilter; +} \ No newline at end of file diff --git a/packages/core/src/interface/GeomImpl.ts b/packages/core/src/interface/GeomImpl.ts new file mode 100644 index 00000000..b57956e9 --- /dev/null +++ b/packages/core/src/interface/GeomImpl.ts @@ -0,0 +1,15 @@ +import type { + ColorTransform, + Matrix, + Point, + Rectangle, + Transform +} from "@next2d/geom"; + +export interface GeomImpl { + ColorTransform: typeof ColorTransform; + Matrix: typeof Matrix; + Point: typeof Point; + Rectangle: typeof Rectangle; + Transform: typeof Transform; +} \ No newline at end of file diff --git a/packages/core/src/interface/MediaImpl.ts b/packages/core/src/interface/MediaImpl.ts new file mode 100644 index 00000000..417097dd --- /dev/null +++ b/packages/core/src/interface/MediaImpl.ts @@ -0,0 +1,13 @@ +import type { + Sound, + SoundMixer, + SoundTransform, + Video +} from "@next2d/media"; + +export interface MediaImpl { + Sound: typeof Sound; + SoundMixer: typeof SoundMixer; + SoundTransform: typeof SoundTransform; + Video: typeof Video; +} \ No newline at end of file diff --git a/packages/core/src/interface/NetImpl.ts b/packages/core/src/interface/NetImpl.ts new file mode 100644 index 00000000..1b257515 --- /dev/null +++ b/packages/core/src/interface/NetImpl.ts @@ -0,0 +1,5 @@ +import type { URLRequest } from "@next2d/net"; + +export interface NetImpl { + URLRequest: typeof URLRequest; +} \ No newline at end of file diff --git a/packages/core/src/interface/PlayerOptionsImpl.ts b/packages/core/src/interface/PlayerOptionsImpl.ts new file mode 100644 index 00000000..2f1d9ef9 --- /dev/null +++ b/packages/core/src/interface/PlayerOptionsImpl.ts @@ -0,0 +1,8 @@ +export interface PlayerOptionsImpl { + width?: number; + height?: number; + tagId?: string; + base?: string; + bgColor?: string; + fullScreen?: boolean; +} \ No newline at end of file diff --git a/packages/core/src/interface/StageDataImpl.ts b/packages/core/src/interface/StageDataImpl.ts new file mode 100644 index 00000000..1eab12a2 --- /dev/null +++ b/packages/core/src/interface/StageDataImpl.ts @@ -0,0 +1,6 @@ +export interface StageDataImpl { + width: number; + height: number; + fps: number + bgColor: string; +} \ No newline at end of file diff --git a/packages/core/src/interface/TextImpl.ts b/packages/core/src/interface/TextImpl.ts new file mode 100644 index 00000000..f299d84d --- /dev/null +++ b/packages/core/src/interface/TextImpl.ts @@ -0,0 +1,5 @@ +import type { TextFormat } from "@next2d/text"; + +export interface TextImpl { + TextFormat: typeof TextFormat; +} \ No newline at end of file diff --git a/packages/core/src/interface/UIImpl.ts b/packages/core/src/interface/UIImpl.ts new file mode 100644 index 00000000..6b42d472 --- /dev/null +++ b/packages/core/src/interface/UIImpl.ts @@ -0,0 +1,9 @@ +import type { + Easing, + Tween +} from "@next2d/ui"; + +export interface UIImpl { + Easing: typeof Easing; + Tween: typeof Tween; +} \ No newline at end of file diff --git a/packages/interface/src/TextImpl.ts b/packages/interface/src/TextImpl.ts index 37f6f16b..f299d84d 100644 --- a/packages/interface/src/TextImpl.ts +++ b/packages/interface/src/TextImpl.ts @@ -1,4 +1,4 @@ -import { TextFormat } from "@next2d/text"; +import type { TextFormat } from "@next2d/text"; export interface TextImpl { TextFormat: typeof TextFormat; diff --git a/packages/webgl/src/index.ts b/packages/webgl/src/index.ts index f79807ad..ee7e3c28 100644 --- a/packages/webgl/src/index.ts +++ b/packages/webgl/src/index.ts @@ -1,6 +1,5 @@ export * from "./CanvasGradientToWebGL"; export * from "./CanvasPatternToWebGL"; -export * from "./CanvasToWebGLContext"; export * from "./CanvasToWebGLContextPath"; export * from "./CanvasToWebGLContextStyle"; export * from "./FrameBufferManager"; \ No newline at end of file diff --git a/src/index.js b/src/index.js deleted file mode 100644 index aa35fc0c..00000000 --- a/src/index.js +++ /dev/null @@ -1,29 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var util_1 = require("@next2d/util"); -var core_1 = require("@next2d/core"); -if (!("next2d" in window)) { - console.log("%c Next2D Player %c 1.18.12 %c https://next2d.app", "color: #fff; background: #5f5f5f", "color: #fff; background: #4bc729", ""); - window.next2d = new core_1.Next2D([new Promise(function (resolve) { - if (document.readyState === "loading") { - var initialize_1 = function () { - window.removeEventListener("DOMContentLoaded", initialize_1); - (0, util_1.$initialize)() - .then(function () { - (0, util_1.$currentPlayer)() - ._$initializeCanvas(); - resolve(); - }); - }; - window.addEventListener("DOMContentLoaded", initialize_1); - } - else { - (0, util_1.$initialize)() - .then(function () { - (0, util_1.$currentPlayer)() - ._$initializeCanvas(); - resolve(); - }); - } - })]); -} diff --git a/src/index.ts b/src/index.ts index 8214bb93..524efa1e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,5 @@ "use strict"; -import { - $currentPlayer, - $initialize -} from "@next2d/util"; import { Next2D } from "@next2d/core"; /** @@ -27,37 +23,5 @@ if (!("next2d" in window)) { }, 300); }); - window.next2d = new Next2D([new Promise((resolve) => - { - if (document.readyState === "loading") { - - const initialize = (): void => - { - window.removeEventListener("DOMContentLoaded", initialize); - - $initialize() - .then((): void => - { - $currentPlayer() - ._$initializeCanvas(); - - resolve(); - }); - }; - - window.addEventListener("DOMContentLoaded", initialize); - - } else { - - $initialize() - .then((): void => - { - $currentPlayer() - ._$initializeCanvas(); - - resolve(); - }); - - } - })]); + window.next2d = new Next2D(); } \ No newline at end of file diff --git a/worker/renderer/src/index.ts b/worker/renderer/src/index.ts index b14809fd..5c68eec3 100644 --- a/worker/renderer/src/index.ts +++ b/worker/renderer/src/index.ts @@ -5,12 +5,20 @@ import { CommandController } from "./CommandController"; const command: CommandController = new CommandController(); /** + * @description OffscreenCanvasのメッセージイベント + * OffscreenCanvas message event + * + * @params {MessageEvent} event + * @return {void} + * @method * @public */ -self.addEventListener("message", async (event: MessageEvent) => +self.addEventListener("message", async (event: MessageEvent): Promise => { command.queue.push(event.data); if (command.state === "deactivate") { - command.execute(); + await command.execute(); } -}); \ No newline at end of file +}); + +export default {}; \ No newline at end of file From ec0e841ceb934c9055aa6d0be6507fcf6ec0828b Mon Sep 17 00:00:00 2001 From: ienaga Date: Sun, 28 Jul 2024 21:11:37 +0900 Subject: [PATCH 028/343] =?UTF-8?q?#154=20add:=20cache=E3=83=91=E3=83=83?= =?UTF-8?q?=E3=82=B1=E3=83=BC=E3=82=B8=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 29 ++++++++----- package.json | 3 +- packages/cache/src/CacheStore.ts | 2 +- .../CacheStoreDestroyService.test.ts | 43 +++++++++++++++++++ .../CacheStore/CacheStoreDestroyService.ts | 4 +- .../CacheStoreGenerateKeysService.test.ts | 41 ++++++++++++++++++ .../CacheStore/CacheStoreGetService.test.ts | 28 ++++++++++++ .../CacheStore/CacheStoreHasService.test.ts | 28 ++++++++++++ .../CacheStoreRemoveByIdService.test.ts | 22 ++++++++++ .../CacheStore/CacheStoreRemoveByIdService.ts | 2 +- .../CacheStoreRemoveService.test.ts | 22 ++++++++++ .../CacheStore/CacheStoreResetService.test.ts | 23 ++++++++++ .../CacheStore/CacheStoreSetService.test.ts | 20 +++++++++ packages/core/src/Player.ts | 9 ---- 14 files changed, 250 insertions(+), 26 deletions(-) create mode 100644 packages/cache/src/CacheStore/CacheStoreDestroyService.test.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreGenerateKeysService.test.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreGetService.test.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreHasService.test.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreRemoveByIdService.test.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreRemoveService.test.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreResetService.test.ts create mode 100644 packages/cache/src/CacheStore/CacheStoreSetService.test.ts diff --git a/package-lock.json b/package-lock.json index 0e5d8189..f829fc24 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "htmlparser2": "^9.1.0" }, "devDependencies": { - "@types/node": "^20.14.12", + "@types/node": "^22.0.0", "@typescript-eslint/eslint-plugin": "^7.17.0", "@typescript-eslint/parser": "^7.17.0", "@vitest/web-worker": "^2.0.4", @@ -32,6 +32,7 @@ "url": "https://github.com/sponsors/Next2D" }, "peerDependencies": { + "@next2d/cache": "file:packages/cache", "@next2d/core": "file:packages/core", "@next2d/display": "file:packages/display", "@next2d/events": "file:packages/events", @@ -651,6 +652,10 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@next2d/cache": { + "resolved": "packages/cache", + "link": true + }, "node_modules/@next2d/core": { "resolved": "packages/core", "link": true @@ -973,13 +978,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.14.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.12.tgz", - "integrity": "sha512-r7wNXakLeSsGT0H1AU863vS2wa5wBOK4bWMjZz2wj+8nBx+m5PeIn0k8AloSLpRuiwdRQZwarZqHE4FNArPuJQ==", + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.0.tgz", + "integrity": "sha512-VT7KSYudcPOzP5Q0wfbowyNLaVR8QWUdw+088uFWwfvpY6uCWaXpqV6ieLAu9WBcnTa7H4Z5RLK8I5t2FuOcqw==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.11.1" } }, "node_modules/@typescript-eslint/eslint-plugin": { @@ -3511,9 +3516,9 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz", + "integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==", "dev": true, "license": "MIT" }, @@ -3854,6 +3859,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "packages/cache": { + "name": "@next2d/cache", + "version": "*", + "license": "MIT" + }, "packages/core": { "name": "@next2d/core", "version": "*", @@ -3863,12 +3873,9 @@ "@next2d/display": "file:../display", "@next2d/events": "file:../events", "@next2d/geom": "file:../geom", - "@next2d/interface": "file:../interface", "@next2d/media": "file:../media", "@next2d/net": "file:../net", - "@next2d/share": "file:../share", "@next2d/text": "file:../text", - "@next2d/util": "file:../util", "@next2d/webgl": "file:../webgl" } }, diff --git a/package.json b/package.json index 907ea07a..714e8354 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "htmlparser2": "^9.1.0" }, "devDependencies": { - "@types/node": "^20.14.12", + "@types/node": "^22.0.0", "@typescript-eslint/eslint-plugin": "^7.17.0", "@typescript-eslint/parser": "^7.17.0", "@vitest/web-worker": "^2.0.4", @@ -58,6 +58,7 @@ "vitest": "^2.0.4" }, "peerDependencies": { + "@next2d/cache": "file:packages/cache", "@next2d/core": "file:packages/core", "@next2d/display": "file:packages/display", "@next2d/events": "file:packages/events", diff --git a/packages/cache/src/CacheStore.ts b/packages/cache/src/CacheStore.ts index 278e06a0..fe578d2c 100644 --- a/packages/cache/src/CacheStore.ts +++ b/packages/cache/src/CacheStore.ts @@ -14,7 +14,7 @@ import { execute as cacheStoreGenerateKeysService } from "./CacheStore/CacheStor * @class * @private */ -class CacheStore +export class CacheStore { private readonly _$pool: HTMLCanvasElement[]; private readonly _$store: Map; diff --git a/packages/cache/src/CacheStore/CacheStoreDestroyService.test.ts b/packages/cache/src/CacheStore/CacheStoreDestroyService.test.ts new file mode 100644 index 00000000..b103746e --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreDestroyService.test.ts @@ -0,0 +1,43 @@ +import { execute } from "./CacheStoreDestroyService"; +import { describe, expect, it, vi } from "vitest"; + +describe("CacheStoreDestroyService.js test", () => +{ + it("test case1", () => + { + const pool = []; + expect(pool.length).toBe(0); + + execute(pool, null); + expect(pool.length).toBe(0); + }); + + it("test case2", () => + { + let state = ""; + const MockContext = vi.fn().mockImplementation(() => + { + return { + "canvas": { + "width": 100, + "height": 200 + }, + "clearRect": vi.fn(() => { state = "clear" }) + } as unknown as CanvasRenderingContext2D; + }); + + const pool = []; + const mockContext = new MockContext(); + expect(pool.length).toBe(0); + expect(state).toBe(""); + expect(mockContext.canvas.width).toBe(100); + expect(mockContext.canvas.height).toBe(200); + + execute(pool, mockContext); + + expect(pool.length).toBe(1); + expect(state).toBe("clear"); + expect(mockContext.canvas.width).toBe(1); + expect(mockContext.canvas.height).toBe(1); + }); +}); diff --git a/packages/cache/src/CacheStore/CacheStoreDestroyService.ts b/packages/cache/src/CacheStore/CacheStoreDestroyService.ts index 0239e487..c1a948f9 100644 --- a/packages/cache/src/CacheStore/CacheStoreDestroyService.ts +++ b/packages/cache/src/CacheStore/CacheStoreDestroyService.ts @@ -17,9 +17,7 @@ export const execute = ( return ; } - if ("canvas" in object - && object instanceof CanvasRenderingContext2D - ) { + if ("canvas" in object) { const canvas: HTMLCanvasElement = object.canvas; const width: number = canvas.width; diff --git a/packages/cache/src/CacheStore/CacheStoreGenerateKeysService.test.ts b/packages/cache/src/CacheStore/CacheStoreGenerateKeysService.test.ts new file mode 100644 index 00000000..43adffbc --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreGenerateKeysService.test.ts @@ -0,0 +1,41 @@ +import { execute } from "./CacheStoreGenerateKeysService"; +import { describe, expect, it } from "vitest"; + +describe("CacheStoreGenerateKeysService.js test", () => +{ + it("test case1", () => + { + const keys = []; + expect(keys.length).toBe(0); + + execute("1", keys); + + expect(keys.length).toBe(2); + expect(keys[0]).toBe("1"); + expect(keys[1]).toBe("0"); + }); + + it("test case2", () => + { + const keys = []; + expect(keys.length).toBe(0); + + execute("2", keys, [0.25, 0.5]); + + expect(keys.length).toBe(2); + expect(keys[0]).toBe("2"); + expect(keys[1]).toBe("1409295737"); + }); + + it("test case3", () => + { + const keys = []; + expect(keys.length).toBe(0); + + execute("2", keys, [0.25, 0.5], new Float32Array([1,1,1,1,0,0,0,0.3])); + + expect(keys.length).toBe(2); + expect(keys[0]).toBe("2"); + expect(keys[1]).toBe("-837721580"); + }); +}); diff --git a/packages/cache/src/CacheStore/CacheStoreGetService.test.ts b/packages/cache/src/CacheStore/CacheStoreGetService.test.ts new file mode 100644 index 00000000..b7e1a82f --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreGetService.test.ts @@ -0,0 +1,28 @@ +import { execute } from "./CacheStoreGetService"; +import { describe, expect, it } from "vitest"; + +describe("CacheStoreGetService.js test", () => +{ + it("test case1", () => + { + const store = new Map(); + expect(execute(store, ["1", "0"])).toBe(null); + }); + + it("test case2", () => + { + const store = new Map(); + store.set("1", new Map()); + expect(execute(store, ["1", "0"])).toBe(null); + }); + + it("test case3", () => + { + const data = new Map(); + data.set("0", "test"); + + const store = new Map(); + store.set("1", data); + expect(execute(store, ["1", "0"])).toBe("test"); + }); +}); diff --git a/packages/cache/src/CacheStore/CacheStoreHasService.test.ts b/packages/cache/src/CacheStore/CacheStoreHasService.test.ts new file mode 100644 index 00000000..da277251 --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreHasService.test.ts @@ -0,0 +1,28 @@ +import { execute } from "./CacheStoreHasService"; +import { describe, expect, it } from "vitest"; + +describe("CacheStoreHasService.js test", () => +{ + it("test case1", () => + { + const store = new Map(); + expect(execute(store, ["1", "0"])).toBe(false); + }); + + it("test case2", () => + { + const store = new Map(); + store.set("1", new Map()); + expect(execute(store, ["1", "0"])).toBe(false); + }); + + it("test case3", () => + { + const data = new Map(); + data.set("0", "test"); + + const store = new Map(); + store.set("1", data); + expect(execute(store, ["1", "0"])).toBe(true); + }); +}); \ No newline at end of file diff --git a/packages/cache/src/CacheStore/CacheStoreRemoveByIdService.test.ts b/packages/cache/src/CacheStore/CacheStoreRemoveByIdService.test.ts new file mode 100644 index 00000000..e84781b6 --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreRemoveByIdService.test.ts @@ -0,0 +1,22 @@ +import { $cacheStore } from "../"; +import { execute } from "./CacheStoreRemoveByIdService"; +import { describe, expect, it } from "vitest"; + +describe("CacheStoreRemoveByIdService.js test", () => +{ + it("test case1", () => + { + const data = new Map(); + data.set("0", "test"); + + const store = new Map(); + store.set("1", data); + + expect(data.size).toBe(1); + expect(store.size).toBe(1); + + execute($cacheStore, store, "1"); + expect(data.size).toBe(0); + expect(store.size).toBe(0); + }); +}); \ No newline at end of file diff --git a/packages/cache/src/CacheStore/CacheStoreRemoveByIdService.ts b/packages/cache/src/CacheStore/CacheStoreRemoveByIdService.ts index 51fc4bb7..9a050513 100644 --- a/packages/cache/src/CacheStore/CacheStoreRemoveByIdService.ts +++ b/packages/cache/src/CacheStore/CacheStoreRemoveByIdService.ts @@ -1,4 +1,4 @@ -import type { CacheStore } from "../CacheStore"; +import { CacheStore } from "../CacheStore"; import { $poolMap } from "../CacheUtil"; /** diff --git a/packages/cache/src/CacheStore/CacheStoreRemoveService.test.ts b/packages/cache/src/CacheStore/CacheStoreRemoveService.test.ts new file mode 100644 index 00000000..55b40866 --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreRemoveService.test.ts @@ -0,0 +1,22 @@ +import { execute } from "./CacheStoreRemoveService"; +import { describe, expect, it } from "vitest"; + +describe("CacheStoreRemoveService.js test", () => +{ + it("test case1", () => + { + const data = new Map(); + data.set("0", "test"); + + const store = new Map(); + store.set("1", data); + + expect(data.size).toBe(1); + expect(store.size).toBe(1); + + execute(store, "1", "0"); + + expect(data.size).toBe(0); + expect(store.size).toBe(0); + }); +}); \ No newline at end of file diff --git a/packages/cache/src/CacheStore/CacheStoreResetService.test.ts b/packages/cache/src/CacheStore/CacheStoreResetService.test.ts new file mode 100644 index 00000000..211df993 --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreResetService.test.ts @@ -0,0 +1,23 @@ +import { execute } from "./CacheStoreResetService"; +import { describe, expect, it } from "vitest"; +import { $cacheStore } from "../"; + +describe("CacheStoreResetService.js test", () => +{ + it("test case1", () => + { + const data = new Map(); + data.set("0", "test"); + + const store = new Map(); + store.set("1", data); + + expect(data.size).toBe(1); + expect(store.size).toBe(1); + + execute($cacheStore, store); + + expect(data.size).toBe(0); + expect(store.size).toBe(0); + }); +}); \ No newline at end of file diff --git a/packages/cache/src/CacheStore/CacheStoreSetService.test.ts b/packages/cache/src/CacheStore/CacheStoreSetService.test.ts new file mode 100644 index 00000000..b7f7569b --- /dev/null +++ b/packages/cache/src/CacheStore/CacheStoreSetService.test.ts @@ -0,0 +1,20 @@ +import { $cacheStore } from "../"; +import { execute } from "./CacheStoreSetService"; +import { describe, expect, it } from "vitest"; + +describe("CacheStoreSetService.js test", () => +{ + it("test case1", () => + { + const store = new Map(); + expect(store.size).toBe(0); + + execute($cacheStore, store, ["1", "0"], "test"); + + expect(store.size).toBe(1); + + const data = store.get("1"); + expect(data.size).toBe(1); + expect(data.get("0")).toBe("test"); + }); +}); \ No newline at end of file diff --git a/packages/core/src/Player.ts b/packages/core/src/Player.ts index 1f999cb4..4b331ef0 100644 --- a/packages/core/src/Player.ts +++ b/packages/core/src/Player.ts @@ -83,15 +83,6 @@ import { $cacheStore } from "@next2d/share"; -// @ts-ignore -import RendererWorker from "../../../worker/renderer/src/index?worker&inline"; - -/** - * @type {Worker} - * @private - */ -const worker: Worker = new RendererWorker(); - /** * @description Next2Dの描画、イベント、設定、コントロールの管理クラスです。 * This class manages Next2D drawings, events, settings, and controls. From 72ac6ea9f20f750bde7a20b947dd113c160334b2 Mon Sep 17 00:00:00 2001 From: ienaga Date: Tue, 30 Jul 2024 15:08:06 +0900 Subject: [PATCH 029/343] =?UTF-8?q?#154=20core=E3=83=91=E3=83=83=E3=82=B1?= =?UTF-8?q?=E3=83=BC=E3=82=B8=E3=81=AE=E9=96=A2=E6=95=B0=E3=82=92=E7=B4=B0?= =?UTF-8?q?=E5=88=86=E5=8C=96(WIP)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 16 +- package.json | 4 +- packages/core/package.json | 11 +- packages/core/src/Canvas.ts | 15 + .../CanvasBootOffscreenCanvasService.test.ts | 20 + .../CanvasBootOffscreenCanvasService.ts | 27 + .../Canvas/CanvasInitializeService.test.ts | 27 + .../src/Canvas/CanvasInitializeService.ts | 27 + packages/core/src/CoreUtil.ts | 36 +- packages/core/src/Next2D.ts | 20 +- .../core/src/Next2D/CreateRootMovieClip.ts | 27 +- packages/core/src/Next2D/LoadService.ts | 29 +- packages/core/src/Player.ts | 3585 ++++++++--------- ...rApplyContainerElementStyleService.test.ts | 64 + ...PlayerApplyContainerElementStyleService.ts | 51 + ...layerCreateContainerElementService.test.ts | 13 + .../PlayerCreateContainerElementService.ts | 30 + .../PlayerLoadingAnimationService.test.ts | 13 + .../Player/PlayerLoadingAnimationService.ts | 37 + .../src/Player/PlayerResizeEventService.ts | 84 + .../Player/PlayerResizePostMessageService.ts | 47 + .../src/Player/PlayerResizeRegisterService.ts | 37 + packages/core/src/index.ts | 1 + .../core/src/interface/EventDispatcherImpl.ts | 3 + packages/core/src/interface/ParentImpl.ts | 3 + .../core/src/interface/PlayerHitObjectImpl.ts | 8 + packages/core/src/interface/PlayerModeImpl.ts | 1 + .../core/src/interface/ResizeMessageImpl.ts | 4 + packages/display/src/Stage.ts | 192 +- packages/interface/src/EventDispatcherImpl.ts | 2 +- packages/media/README.md | 4 +- packages/renderer/LICENSE | 21 + packages/renderer/README.md | 11 + packages/renderer/package.json | 31 + packages/renderer/src/CommandController.ts | 213 + packages/renderer/src/index.ts | 25 + packages/util/src/Util.ts | 12 +- src/index.ts | 15 - 38 files changed, 2548 insertions(+), 2218 deletions(-) create mode 100644 packages/core/src/Canvas.ts create mode 100644 packages/core/src/Canvas/CanvasBootOffscreenCanvasService.test.ts create mode 100644 packages/core/src/Canvas/CanvasBootOffscreenCanvasService.ts create mode 100644 packages/core/src/Canvas/CanvasInitializeService.test.ts create mode 100644 packages/core/src/Canvas/CanvasInitializeService.ts create mode 100644 packages/core/src/Player/PlayerApplyContainerElementStyleService.test.ts create mode 100644 packages/core/src/Player/PlayerApplyContainerElementStyleService.ts create mode 100644 packages/core/src/Player/PlayerCreateContainerElementService.test.ts create mode 100644 packages/core/src/Player/PlayerCreateContainerElementService.ts create mode 100644 packages/core/src/Player/PlayerLoadingAnimationService.test.ts create mode 100644 packages/core/src/Player/PlayerLoadingAnimationService.ts create mode 100644 packages/core/src/Player/PlayerResizeEventService.ts create mode 100644 packages/core/src/Player/PlayerResizePostMessageService.ts create mode 100644 packages/core/src/Player/PlayerResizeRegisterService.ts create mode 100644 packages/core/src/interface/EventDispatcherImpl.ts create mode 100644 packages/core/src/interface/ParentImpl.ts create mode 100644 packages/core/src/interface/PlayerHitObjectImpl.ts create mode 100644 packages/core/src/interface/PlayerModeImpl.ts create mode 100644 packages/core/src/interface/ResizeMessageImpl.ts create mode 100644 packages/renderer/LICENSE create mode 100644 packages/renderer/README.md create mode 100644 packages/renderer/package.json create mode 100644 packages/renderer/src/CommandController.ts create mode 100644 packages/renderer/src/index.ts diff --git a/package-lock.json b/package-lock.json index f829fc24..216cae80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,13 +38,11 @@ "@next2d/events": "file:packages/events", "@next2d/filters": "file:packages/filters", "@next2d/geom": "file:packages/geom", - "@next2d/interface": "file:packages/interface", "@next2d/media": "file:packages/media", "@next2d/net": "file:packages/net", - "@next2d/share": "file:packages/share", + "@next2d/renderer": "file:packages/renderer", "@next2d/text": "file:packages/text", "@next2d/ui": "file:packages/ui", - "@next2d/util": "file:packages/util", "@next2d/webgl": "file:packages/webgl" } }, @@ -688,6 +686,10 @@ "resolved": "packages/net", "link": true }, + "node_modules/@next2d/renderer": { + "resolved": "packages/renderer", + "link": true + }, "node_modules/@next2d/share": { "resolved": "packages/share", "link": true @@ -3943,6 +3945,14 @@ "version": "*", "license": "MIT" }, + "packages/renderer": { + "name": "@next2d/renderer", + "version": "*", + "license": "MIT", + "peerDependencies": { + "@next2d/webgl": "file:../webgl" + } + }, "packages/share": { "name": "@next2d/share", "version": "*", diff --git a/package.json b/package.json index 714e8354..22472f95 100644 --- a/package.json +++ b/package.json @@ -64,13 +64,11 @@ "@next2d/events": "file:packages/events", "@next2d/filters": "file:packages/filters", "@next2d/geom": "file:packages/geom", - "@next2d/interface": "file:packages/interface", "@next2d/media": "file:packages/media", "@next2d/net": "file:packages/net", - "@next2d/share": "file:packages/share", + "@next2d/renderer": "file:packages/renderer", "@next2d/text": "file:packages/text", "@next2d/ui": "file:packages/ui", - "@next2d/util": "file:packages/util", "@next2d/webgl": "file:packages/webgl" } } diff --git a/packages/core/package.json b/packages/core/package.json index 28dd5bed..e10e4556 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -26,13 +26,16 @@ "url": "git+https://github.com/Next2D/Player.git" }, "peerDependencies": { - "@next2d/webgl": "file:../webgl", - "@next2d/display": "file:../display", "@next2d/core": "file:../core", - "@next2d/net": "file:../net", + "@next2d/display": "file:../display", "@next2d/events": "file:../events", + "@next2d/filters": "file:../filters", + "@next2d/geom": "file:../geom", "@next2d/media": "file:../media", + "@next2d/net": "file:../net", + "@next2d/renderer": "file:../renderer", "@next2d/text": "file:../text", - "@next2d/geom": "file:../geom" + "@next2d/ui": "file:../ui", + "@next2d/webgl": "file:../webgl" } } diff --git a/packages/core/src/Canvas.ts b/packages/core/src/Canvas.ts new file mode 100644 index 00000000..4029a022 --- /dev/null +++ b/packages/core/src/Canvas.ts @@ -0,0 +1,15 @@ +import { $devicePixelRatio } from "./CoreUtil"; +import { execute as canvasInitializeService } from "./Canvas/CanvasInitializeService"; +import { execute as canvasBootOffscreenCanvasService } from "./Canvas/CanvasBootOffscreenCanvasService"; + +/** + * @type {HTMLCanvasElement} + * @public + */ +export const $canvas: HTMLCanvasElement = document.createElement("canvas"); + +// initial invoking function +canvasInitializeService($canvas, $devicePixelRatio); + +// Boot offscreen canvas +canvasBootOffscreenCanvasService($canvas, $devicePixelRatio); \ No newline at end of file diff --git a/packages/core/src/Canvas/CanvasBootOffscreenCanvasService.test.ts b/packages/core/src/Canvas/CanvasBootOffscreenCanvasService.test.ts new file mode 100644 index 00000000..321e7216 --- /dev/null +++ b/packages/core/src/Canvas/CanvasBootOffscreenCanvasService.test.ts @@ -0,0 +1,20 @@ +import { execute } from "./CanvasBootOffscreenCanvasService"; +import { describe, expect, it, vi } from "vitest"; + +describe("CanvasBootOffscreenCanvasService.js test", () => +{ + it("execute test case1", () => + { + let state = ""; + const MockCanvas = vi.fn().mockImplementation(() => + { + return { + "transferControlToOffscreen": vi.fn(() => { state = "ok" }) + } as unknown as HTMLCanvasElement; + }); + + expect(state).toBe(""); + execute(new MockCanvas(), 1); + expect(state).toBe("ok"); + }); +}); \ No newline at end of file diff --git a/packages/core/src/Canvas/CanvasBootOffscreenCanvasService.ts b/packages/core/src/Canvas/CanvasBootOffscreenCanvasService.ts new file mode 100644 index 00000000..fff340a7 --- /dev/null +++ b/packages/core/src/Canvas/CanvasBootOffscreenCanvasService.ts @@ -0,0 +1,27 @@ +import { $rendererWorker } from "../CoreUtil"; + +/** + * @description OffscreenCanvasを起動 + * Boot offscreen canvas + * + * @param {HTMLCanvasElement} canvas + * @param {number} ratio + * @return {void} + * @method + * @public + */ +export const execute = ( + canvas: HTMLCanvasElement, + ratio: number +): void => { + + const offscreenCanvas = canvas.transferControlToOffscreen(); + const buffer = new Float32Array([ratio]); + + // postMessage + $rendererWorker.postMessage({ + "command": "initialize", + "canvas": offscreenCanvas, + "buffer": buffer + }, [offscreenCanvas, buffer.buffer]); +}; \ No newline at end of file diff --git a/packages/core/src/Canvas/CanvasInitializeService.test.ts b/packages/core/src/Canvas/CanvasInitializeService.test.ts new file mode 100644 index 00000000..3773a743 --- /dev/null +++ b/packages/core/src/Canvas/CanvasInitializeService.test.ts @@ -0,0 +1,27 @@ +import { execute } from "./CanvasInitializeService"; +import { describe, expect, it } from "vitest"; + +describe("CanvasInitializeService.js test", () => +{ + it("execute test case1", () => + { + const canvas: HTMLCanvasElement = document.createElement("canvas"); + execute(canvas, 1); + expect(canvas.width).toBe(1); + expect(canvas.height).toBe(1); + expect(canvas.getAttribute("style")).toBe( + "-webkit-tap-highlight-color: rgba(0,0,0,0);backface-visibility: hidden;" + ); + }); + + it("execute test case2", () => + { + const canvas: HTMLCanvasElement = document.createElement("canvas"); + execute(canvas, 2); + expect(canvas.width).toBe(1); + expect(canvas.height).toBe(1); + expect(canvas.getAttribute("style")).toBe( + "-webkit-tap-highlight-color: rgba(0,0,0,0);backface-visibility: hidden;transform: scale(0.5);" + ); + }); +}); \ No newline at end of file diff --git a/packages/core/src/Canvas/CanvasInitializeService.ts b/packages/core/src/Canvas/CanvasInitializeService.ts new file mode 100644 index 00000000..8db14819 --- /dev/null +++ b/packages/core/src/Canvas/CanvasInitializeService.ts @@ -0,0 +1,27 @@ +/** + * @description canvasのスタイルの初期設定 + * Initial setting of canvas style + * + * @param {HTMLCanvasElement} canvas + * @return {void} + * @method + * @public + */ +export const execute = ( + canvas: HTMLCanvasElement, + ratio: number = 1 +): void => { + + // Set canvas style + let style: string = ""; + style += "-webkit-tap-highlight-color: rgba(0,0,0,0);"; + style += "backface-visibility: hidden;"; + + if (ratio > 1) { + style += `transform: scale(${1 / ratio});`; + } + + canvas.width = 1; + canvas.height = 1; + canvas.setAttribute("style", style); +}; \ No newline at end of file diff --git a/packages/core/src/CoreUtil.ts b/packages/core/src/CoreUtil.ts index d1c98c23..82f38aab 100644 --- a/packages/core/src/CoreUtil.ts +++ b/packages/core/src/CoreUtil.ts @@ -1,3 +1,36 @@ +/** + * @type {number} + * @const + */ +export const $LOAD_START: number = 1; + +/** + * @type {number} + * @const + */ +export const $LOAD_END: number = 2; + +/** + * @type {string} + * @const + */ +export const $PREFIX: string = "__next2d__"; + +/** + * @type {number} + * @const + */ +export const $devicePixelRatio: number = window.devicePixelRatio; + +// @ts-ignore +import RendererWorker from "@next2d/renderer?worker&inline"; + +/** + * @type {Worker} + * @public + */ +export const $rendererWorker: Worker = new RendererWorker(); + /** * @param {number} value * @param {number} min @@ -19,4 +52,5 @@ export const $clamp = ( return isNaN(number) && default_value !== null ? default_value : Math.min(Math.max(min, isNaN(number) ? 0 : number), max); -}; \ No newline at end of file +}; + diff --git a/packages/core/src/Next2D.ts b/packages/core/src/Next2D.ts index b8076cdd..606e944b 100644 --- a/packages/core/src/Next2D.ts +++ b/packages/core/src/Next2D.ts @@ -16,20 +16,18 @@ import { media } from "./Media"; import { net } from "./Net"; import { text } from "./Text"; import { ui } from "./UI"; -import { Player } from "./Player"; import { execute as loadService } from "./Next2D/LoadService"; import { execute as createRootMovieClip } from "./Next2D/CreateRootMovieClip"; /** - * @description playerの起動管理クラス - * player startup management class + * @description Next2Dの起動管理クラス + * Boot management class of Next2D * * @class * @public */ export class Next2D { - public readonly player: Player; public readonly display: DisplayImpl; public readonly events: EventsImpl; public readonly filters: FiltersImpl; @@ -46,12 +44,6 @@ export class Next2D */ constructor () { - /** - * @type {Player} - * @private - */ - this.player = new Player(); - /** * @type {DisplayImpl} * @public @@ -133,8 +125,8 @@ export class Next2D */ async load (url: string, options: PlayerOptionsImpl): Promise { - await this._$promise; - await loadService(this.player, url, options); + await Promise.all([this._$promise]); + await loadService(url, options); } /** @@ -155,9 +147,9 @@ export class Next2D fps: number = 24, options: PlayerOptionsImpl | null = null ): Promise { - await this._$promise; + await Promise.all([this._$promise]); return await createRootMovieClip( - this.player, width, height, fps, options + width, height, fps, options ); } } diff --git a/packages/core/src/Next2D/CreateRootMovieClip.ts b/packages/core/src/Next2D/CreateRootMovieClip.ts index 3a90abe3..c926c3ef 100644 --- a/packages/core/src/Next2D/CreateRootMovieClip.ts +++ b/packages/core/src/Next2D/CreateRootMovieClip.ts @@ -1,12 +1,12 @@ import type { PlayerOptionsImpl } from "../interface/PlayerOptionsImpl"; -import { Sprite } from "@next2d/display"; -import { Player } from "../Player"; +import { Sprite, $stage } from "@next2d/display"; +import { $player } from "../Player"; +import { $LOAD_END } from "../CoreUtil"; /** * @description RootのMovieClipを作成します。 * Create a MovieClip for Root. * - * @param {Player} player * @param {number} width * @param {number} height * @param {number} fps @@ -16,7 +16,6 @@ import { Player } from "../Player"; * @protected */ export const execute = async ( - player: Player, width: number = 240, height: number = 240, fps: number = 24, @@ -24,17 +23,19 @@ export const execute = async ( ): Promise => { // setup - player.width = width | 0; - player.height = height | 0; - player.mode = "create"; - player.stage._$frameRate = fps | 0; - player.setOptions(options); - player._$initialize(); + $player.mode = "create"; + $player.width = width | 0; + $player.height = height | 0; + $player.frameRate = fps | 0; - const root: Sprite = player.stage.addChild(new Sprite()); + $player + .setOptions(options) + .boot(); - player._$loadStatus = Player.LOAD_END; - player.play(); + const root: Sprite = $stage.addChild(new Sprite()); + + $player._$loadStatus = $LOAD_END; + $player.play(); return root; }; \ No newline at end of file diff --git a/packages/core/src/Next2D/LoadService.ts b/packages/core/src/Next2D/LoadService.ts index 6679e6ce..167b254a 100644 --- a/packages/core/src/Next2D/LoadService.ts +++ b/packages/core/src/Next2D/LoadService.ts @@ -1,7 +1,6 @@ import type { PlayerOptionsImpl } from "../interface/PlayerOptionsImpl"; import type { StageDataImpl } from "../interface/StageDataImpl"; -import type { Player } from "../Player"; -import { URLRequest } from "@next2d/net"; +import { $player } from "../Player"; import { $clamp } from "../CoreUtil"; import { Event, @@ -9,7 +8,8 @@ import { } from "@next2d/events"; import { Loader, - LoaderInfo + LoaderInfo, + $stage } from "@next2d/display"; /** @@ -22,7 +22,7 @@ import { * @method * @protected */ -export const execute = (player: Player, url: string, options: PlayerOptionsImpl): Promise => +export const execute = (url: string, options: PlayerOptionsImpl): Promise => { return new Promise((resolve: Function) => { @@ -46,8 +46,9 @@ export const execute = (player: Player, url: string, options: PlayerOptionsImpl) url = url.slice(1); } - player.setOptions(options); - player._$initialize(); + $player + .setOptions(options) + .boot(); const loader: Loader = new Loader(); @@ -74,23 +75,23 @@ export const execute = (player: Player, url: string, options: PlayerOptionsImpl) const stage: StageDataImpl = loaderInfo._$data.stage; - player.bgColor = stage.bgColor; - player._$setBackgroundColor(stage.bgColor); + $player.bgColor = stage.bgColor; + // $player._$setBackgroundColor(stage.bgColor); - player.stage.addChild(loaderInfo.content); + $stage.addChild(loaderInfo.content); - player.width = stage.width; - player.height = stage.height; + $player.width = stage.width; + $player.height = stage.height; // set fps fixed logic - player.stage._$frameRate = $clamp(+stage.fps, 1, 60, 60); + $player.frameRate = $clamp(+stage.fps, 1, 60, 60); } - player._$resize(); + // $player._$resize(); resolve(); }); - loader.load(new URLRequest(url)); + // loader.load(new URLRequest(url)); }); }; \ No newline at end of file diff --git a/packages/core/src/Player.ts b/packages/core/src/Player.ts index 4b331ef0..33c7401f 100644 --- a/packages/core/src/Player.ts +++ b/packages/core/src/Player.ts @@ -1,87 +1,25 @@ +import type { PlayerModeImpl } from "./interface/PlayerModeImpl"; +import type { EventDispatcherImpl } from "./interface/EventDispatcherImpl"; +// import type { ParentImpl } from "./interface/ParentImpl"; +// import type { PlayerHitObjectImpl } from "./interface/PlayerHitObjectImpl"; +import type { PlayerOptionsImpl } from "./interface/PlayerOptionsImpl"; +// import type { +// MovieClip, +// TextField +// } from "@next2d/display"; +import { SoundMixer } from "@next2d/media"; +import { $cacheStore } from "@next2d/cache"; import { - Stage, - MovieClip, - TextField -} from "@next2d/display"; -import { - Event as Next2DEvent, - MouseEvent as Next2DMouseEvent, - EventPhase -} from "@next2d/events"; -import { - SoundMixer -} from "@next2d/media"; -import { - CanvasToWebGLContext, - FrameBufferManager -} from "@next2d/webgl"; -import { - StageQualityImpl, - PlayerOptionsImpl, - PlayerHitObjectImpl, - PlayerModeImpl, - AttachmentImpl, - EventListenerImpl, - DisplayObjectImpl, - EventDispatcherImpl, - ParentImpl, - RGBAImpl, - PropertyMessageMapImpl -} from "@next2d/interface"; -import { - Point, - Rectangle -} from "@next2d/geom"; -import { - $document, - $window, - $rendererWorker, - $PREFIX, - $audioContext, - $TOUCH_START, - $TOUCH_MOVE, - $TOUCH_END, - $MOUSE_DOWN, - $MOUSE_MOVE, - $MOUSE_UP, - $MOUSE_WHEEL, - $DOUBLE_CLICK, - $MOUSE_LEAVE, - $loadAudioData, - $MATRIX_HIT_ARRAY_IDENTITY, - $hitContext, - $isTouch, - $dropTarget, - $dragRules, - $isSafari, - $getEvent, - $setEvent, - $setEventType, - $setCurrentLoaderInfo, - $getEventType, - $getRenderBufferArray, - $getRenderMessageObject, - $poolRenderMessageObject, - $textArea -} from "@next2d/util"; -import { - $Math, - $performance, - $COLOR_ARRAY_IDENTITY, - $doUpdated, - $isUpdated, - $getArray, - $getMap, - $uintToRGBA, - $toColorInt, - $requestAnimationFrame, - $cancelAnimationFrame, - $poolArray, - $clamp, $devicePixelRatio, - $setDevicePixelRatio, - $cacheStore -} from "@next2d/share"; + $LOAD_START, + $LOAD_END, + $PREFIX +} from "./CoreUtil"; +import { execute as playerCreateContainerElementService } from "./Player/PlayerCreateContainerElementService"; +import { execute as playerApplyContainerElementStyleService } from "./Player/PlayerApplyContainerElementStyleService"; +import { execute as playerLoadingAnimationService } from "./Player/PlayerLoadingAnimationService"; +import { execute as playerResizeEventService } from "./Player/PlayerResizeEventService"; +import { execute as playerResizeRegisterService } from "./Player/PlayerResizeRegisterService"; /** * @description Next2Dの描画、イベント、設定、コントロールの管理クラスです。 @@ -92,48 +30,41 @@ import { */ export class Player { - public _$stopFlag: boolean; - public _$actionOffset: number; - public _$actions: MovieClip[]; - public _$loaders: EventDispatcherImpl[]; - public _$sounds: Map; - public _$loadStatus: number; - public _$width: number; - public _$height: number; - public _$scale: number; - public _$state: "up" | "down"; - public _$attachment: AttachmentImpl | null; - public _$textField: TextField | null; + // private readonly _$actions: MovieClip[]; + private readonly _$loaders: EventDispatcherImpl[]; + // private readonly _$sounds: Map; + // private readonly _$hitObject: PlayerHitObjectImpl; + private readonly _$matrix: Float32Array; + private _$rendererWidth: number; + private _$rendererHeight: number; + private _$rendererScale: number; + private _$initialWidth: number; + private _$initialHeight: number; + private _$fixedWidth: number; + private _$fixedHeight: number; + private _$frameRate: number; + private _$stopFlag: boolean; + private _$loadStatus: number; + private _$scale: number; + // private _$state: "up" | "down"; + // private _$textField: TextField | null; private _$mode: PlayerModeImpl; - private _$context: CanvasToWebGLContext|null; - private _$rollOverObject: DisplayObjectImpl | null; - private _$mouseOverTarget: DisplayObjectImpl | null; - private _$startTime: number; - private _$fps: number; - private _$baseWidth: number; - private _$baseHeight: number; - private _$tx: number; - private _$ty: number; - private _$hitTestStart: boolean; - private _$stageX: number; - private _$stageY: number; - private _$optionWidth: number; - private _$optionHeight: number; + // private _$rollOverObject: EventDispatcherImpl | null; + // private _$mouseOverTarget: EventDispatcherImpl | null; + // private _$startTime: number; + // private _$fps: number; + // private _$hitTestStart: boolean; + // private _$stageX: number; + // private _$stageY: number; private _$tagId: string; private _$bgColor: string; private _$fullScreen: boolean; private _$timerId: number; private _$loadId: number; - private _$deltaX: number; - private _$deltaY: number; - private _$clickTarget: ParentImpl | null; - private _$actionProcess: boolean; - private readonly _$stage: Stage; - private readonly _$hitObject: PlayerHitObjectImpl; - private readonly _$ratio: number; - private readonly _$matrix: Float32Array; - private readonly _$quality: StageQualityImpl; - private readonly _$canvas: HTMLCanvasElement; + // private _$deltaX: number; + // private _$deltaY: number; + // private _$clickTarget: ParentImpl | null; + // private _$actionProcess: boolean; /** * @constructor @@ -141,76 +72,61 @@ export class Player */ constructor () { - // init - $setDevicePixelRatio(window.devicePixelRatio); - - /** - * @type {Stage} - * @private - */ - this._$stage = new Stage(); - this._$stage._$player = this; - /** * @type {string} * @private */ this._$mode = "loader"; - /** - * @type {number} - * @private - */ - this._$actionOffset = 0; - - /** - * @type {array} - * @private - */ - this._$actions = $getArray(); + // /** + // * @type {array} + // * @private + // */ + // this._$actions = []; /** * @type {array} * @public */ - this._$loaders = $getArray(); - - /** - * @type {Map} - * @private - */ - this._$sounds = $getMap(); - - /** - * @type {object} - * @private - */ - this._$hitObject = { - "x": 0, - "y": 0, - "pointer": "", - "hit": null - }; - - /** - * @type {DisplayObject} - * @default null - * @private - */ - this._$rollOverObject = null; - - /** - * @type {DisplayObject} - * @default null - * @private - */ - this._$mouseOverTarget = null; + this._$loaders = []; + + // /** + // * @type {Map} + // * @private + // */ + // this._$sounds = new Map(); + + // /** + // * @type {object} + // * @private + // */ + // this._$hitObject = { + // "x": 0, + // "y": 0, + // "pointer": "", + // "hit": null + // }; + + // /** + // * @type {DisplayObject} + // * @default null + // * @private + // */ + // this._$rollOverObject = null; + + // /** + // * @type {DisplayObject} + // * @default null + // * @private + // */ + // this._$mouseOverTarget = null; /** * @type {number} + * @default 60 * @private */ - this._$ratio = $devicePixelRatio; + this._$frameRate = 60; /** * @type {boolean} @@ -219,19 +135,19 @@ export class Player */ this._$stopFlag = true; - /** - * @type {number} - * @default 0 - * @private - */ - this._$startTime = 0; + // /** + // * @type {number} + // * @default 0 + // * @private + // */ + // this._$startTime = 0; - /** - * @type {number} - * @default 16 - * @private - */ - this._$fps = 16; + // /** + // * @type {number} + // * @default 16 + // * @private + // */ + // this._$fps = 16; /** * @type {number} @@ -240,116 +156,123 @@ export class Player */ this._$loadStatus = 0; - /** - * @type {number} - * @default 0 - * @private - */ - this._$width = 0; + // /** + // * @type {number} + // * @default 0 + // * @private + // */ + // this._$width = 0; - /** - * @type {number} - * @default 0 - * @private - */ - this._$height = 0; + // /** + // * @type {number} + // * @default 0 + // * @private + // */ + // this._$height = 0; /** * @type {number} * @default 0 * @private */ - this._$baseWidth = 0; + this._$initialWidth = 0; /** * @type {number} * @default 0 * @private */ - this._$baseHeight = 0; + this._$initialHeight = 0; /** * @type {number} * @default 1 * @private */ - this._$scale = 1; - - /** - * @type {Float32Array} - * @private - */ - this._$matrix = new Float32Array([1, 0, 0, 1, 0, 0]); - - /** - * @type {number} - * @default 0 - * @private - */ - this._$tx = 0; + this._$rendererWidth = 0; /** * @type {number} - * @default 0 - * @private - */ - this._$ty = 0; - - /** - * @type {string} - * @default up - * @private - */ - this._$state = "up"; - - /** - * @type {boolean} - * @default false + * @default 1 * @private */ - this._$hitTestStart = false; + this._$rendererHeight = 0; /** * @type {number} - * @default -1 + * @default 1 * @private */ - this._$stageX = -1; + this._$rendererScale = 1; /** * @type {number} - * @default -1 + * @default 1 * @private */ - this._$stageY = -1; + this._$scale = 1; /** - * @type {number} - * @default 0 + * @type {Float32Array} * @private */ - this._$deltaX = 0; + this._$matrix = new Float32Array([1, 0, 0, 1, 0, 0]); - /** - * @type {number} - * @default 0 - * @private - */ - this._$deltaY = 0; + // /** + // * @type {string} + // * @default up + // * @private + // */ + // this._$state = "up"; + + // /** + // * @type {boolean} + // * @default false + // * @private + // */ + // this._$hitTestStart = false; + + // /** + // * @type {number} + // * @default -1 + // * @private + // */ + // this._$stageX = -1; + + // /** + // * @type {number} + // * @default -1 + // * @private + // */ + // this._$stageY = -1; + + // /** + // * @type {number} + // * @default 0 + // * @private + // */ + // this._$deltaX = 0; + + // /** + // * @type {number} + // * @default 0 + // * @private + // */ + // this._$deltaY = 0; /** * @type {number} * @default 0 * @private */ - this._$optionWidth = 0; + this._$fixedWidth = 0; /** * @type {number} * @default 0 * @private */ - this._$optionHeight = 0; + this._$fixedHeight = 0; /** * @type {string} @@ -372,19 +295,12 @@ export class Player */ this._$fullScreen = false; - /** - * @type {string} - * @default high - * @private - */ - this._$quality = "high"; - - /** - * @type {TextField} - * @default null - * @private - */ - this._$textField = null; + // /** + // * @type {TextField} + // * @default null + // * @private + // */ + // this._$textField = null; /** * @type {number} @@ -400,118 +316,53 @@ export class Player */ this._$loadId = -1; - /** - * @type {CanvasToWebGLContext} - * @default null - * @private - */ - this._$context = null; - - /** - * @type {AttachmentImpl} - * @default null - * @private - */ - this._$attachment = null; - - /** - * @type {DisplayObject} - * @default null - * @private - */ - this._$clickTarget = null; - - /** - * @type {boolean} - * @default false - * @private - */ - this._$actionProcess = false; - - /** - * @type {HTMLCanvasElement} - * @private - */ - this._$canvas = $document.createElement("canvas"); - } - - /** - * @return {number} - * @default 1 - * @const - * @static - */ - static get LOAD_START (): number - { - return 1; - } - - /** - * @return {number} - * @default 2 - * @const - * @static - */ - static get LOAD_END (): number - { - return 2; - } - - /** - * @type {HTMLCanvasElement} - * @readonly - * @public - */ - get canvas (): HTMLCanvasElement - { - return this._$canvas; - } - - /** - * @member {CanvasToWebGLContext|null} - * @default null - * @public - */ - get context (): CanvasToWebGLContext|null - { - return this._$context; - } - set context (context: CanvasToWebGLContext|null) - { - this._$context = context; - } - - /** - * @return {Stage} - * @readonly - * @public - */ - get stage (): Stage - { - return this._$stage; + // /** + // * @type {DisplayObject} + // * @default null + // * @private + // */ + // this._$clickTarget = null; + + // /** + // * @type {boolean} + // * @default false + // * @private + // */ + // this._$actionProcess = false; } /** + * @description フルスクリーンモード時の画面全体を基準としたステージのx座標 + * The x-coordinate of the stage with the entire screen as the reference in full-screen mode + * * @member {number} + * @default 0 * @readonly * @public */ get x (): number { - return this._$tx; + return this._$matrix[5]; } /** + * @description フルスクリーンモード時の画面全体を基準としたステージのy座標 + * The y-coordinate of the stage with the entire screen as the reference in full-screen mode + * * @member {number} + * @default 0 * @readonly * @public */ get y (): number { - return this._$ty; + return this._$matrix[4]; } /** + * @description ステージ設定と画面表示のx拡大率 + * The x magnification of the stage setting and screen display + * * @member {number} * @readonly * @public @@ -522,6 +373,9 @@ export class Player } /** + * @description ステージ設定と画面表示のy拡大率 + * The y magnification of the stage setting and screen display + * * @member {number} * @readonly * @public @@ -532,6 +386,9 @@ export class Player } /** + * @description フルスクリーンモード時のステージサイズを基準としたステージのx座標 + * The x-coordinate of the stage with the stage size in full-screen mode as the reference + * * @member {number} * @readonly * @public @@ -542,6 +399,9 @@ export class Player } /** + * @description フルスクリーンモード時のステージサイズを基準としたステージのy座標 + * The y-coordinate of the stage with the stage size in full-screen mode as the reference + * * @member {number} * @readonly * @public @@ -552,7 +412,11 @@ export class Player } /** + * @description Playerの利用モード、load関数を利用している場合は "loader"、createRootMovieClip関数を利用している場合は "create" + * The usage mode of Player, "loader" if the load function is used, "create" if the createRootMovieClip function is used + * * @member {string} + * @default "loader" * @public */ get mode (): PlayerModeImpl @@ -565,39 +429,54 @@ export class Player } /** - * @return {string} - * @readonly + * @description canvasの描画領域の幅 + * The width of the drawing area of the canvas + * + * @member {number} + * @default 0 * @public */ - get contentElementId (): string + get rendererWidth (): number + { + return this._$rendererWidth; + } + set rendererWidth (renderer_width: number) { - return $PREFIX; + this._$rendererWidth = renderer_width | 0; } /** + * @description canvasの描画領域の高さ + * The height of the drawing area of the canvas + * * @member {number} + * @default 0 * @public */ - get width (): number + get rendererHeight (): number { - return this._$baseWidth; + return this._$rendererHeight; } - set width (width: number) + set rendererHeight (renderer_height: number) { - this._$baseWidth = width | 0; + this._$rendererHeight = renderer_height | 0; } /** + * @description canvasの描画領域の拡大率 + * The magnification of the drawing area of the canvas + * * @member {number} + * @default 1 * @public */ - get height (): number + get rendererScale (): number { - return this._$baseHeight; + return this._$rendererScale; } - set height (height: number) + set rendererScale (renderer_scale: number) { - this._$baseHeight = height | 0; + this._$rendererScale = renderer_scale; } /** @@ -613,6 +492,19 @@ export class Player this._$bgColor = `${bg_color}`; } + /** + * @member {number} + * @public + */ + get frameRate (): number + { + return this._$frameRate; + } + set frameRate (frame_rate: number) + { + this._$frameRate = frame_rate; + } + /** * @return {void} * @method @@ -620,24 +512,23 @@ export class Player */ play (): void { - if (this._$stopFlag) { - - this._$stopFlag = false; + if (!this._$stopFlag) { + return ; + } - if (this._$timerId > -1) { - $cancelAnimationFrame(this._$timerId); - } + this._$stopFlag = false; - this._$startTime = $performance.now(); + // if (this._$timerId > -1) { + // cancelAnimationFrame(this._$timerId); + // } - const frameRate: number = this._$stage._$frameRate; - this._$fps = 1000 / frameRate | 0; + // this._$fps = 1000 / this._$frameRate | 0; - this._$timerId = $requestAnimationFrame((timestamp: number) => - { - this._$run(timestamp); - }); - } + // this._$startTime = performance.now(); + // this._$timerId = requestAnimationFrame(async (timestamp: number): Promise => + // { + // await this._$run(timestamp); + // }); } /** @@ -648,7 +539,7 @@ export class Player stop (): void { if (this._$timerId > -1) { - $cancelAnimationFrame(this._$timerId); + cancelAnimationFrame(this._$timerId); } this._$stopFlag = true; @@ -657,11 +548,11 @@ export class Player SoundMixer.stopAll(); $cacheStore.reset(); - if ($rendererWorker) { - $rendererWorker.postMessage({ - "command": "stop" - }); - } + // if ($rendererWorker) { + // $rendererWorker.postMessage({ + // "command": "stop" + // }); + // } } /** @@ -683,39 +574,68 @@ export class Player /** * @param {object} [options=null] - * @return {void} + * @return {Player} * @public */ - setOptions (options: PlayerOptionsImpl | null = null): void + setOptions (options: PlayerOptionsImpl | null = null): Player { - if (options) { - this._$optionWidth = options.width || this._$optionWidth; - this._$optionHeight = options.height || this._$optionHeight; - this._$tagId = options.tagId || this._$tagId; - this._$bgColor = options.bgColor || this._$bgColor; - this._$fullScreen = !!options.fullScreen; + if (!options) { + return this; } + + this._$fixedWidth = options.width || this._$fixedWidth; + this._$fixedHeight = options.height || this._$fixedHeight; + this._$tagId = options.tagId || this._$tagId; + this._$bgColor = options.bgColor || this._$bgColor; + this._$fullScreen = !!options.fullScreen; + + return this; } /** - * @description NoCode Toolからのアクセスのみ - * Access from NoCode Tool only + * @description Playerの初期起動処理 + * Initial startup processing of Player * - * @param {MouseEvent} [event = null] * @return {void} * @method - * @private + * @public */ - _$loadWebAudio (event: MouseEvent | null = null): void + boot (): void { - if (event) { - // @ts-ignore - this._$canvas.removeEventListener($MOUSE_UP, this._$loadWebAudio); - } + // create element + const element = playerCreateContainerElementService(); - if (!$audioContext) { - $loadAudioData(); + // apply base style + playerApplyContainerElementStyleService( + element, this._$fixedWidth, this._$fixedHeight + ); + + this._$initialWidth = element.clientWidth; + this._$initialHeight = element.clientHeight; + + // start loading + playerLoadingAnimationService(element); + + // initialize worker + + + if (!this._$fixedWidth && !this._$fixedHeight) { + // register resize event + playerResizeRegisterService( + this, + this._$initialWidth, + this._$initialHeight, + this._$fullScreen + ); } + + // initialize resize + playerResizeEventService( + this, + this._$initialWidth, + this._$initialHeight, + this._$fullScreen + ); } /** @@ -725,7 +645,7 @@ export class Player */ _$updateLoadStatus (): void { - if (this._$loadStatus === Player.LOAD_END) { + if (this._$loadStatus === $LOAD_END) { if (this._$loadId > -1) { $cancelAnimationFrame(this._$loadId); } @@ -749,7 +669,7 @@ export class Player _$loaded (): void { const element: HTMLElement | null = $document - .getElementById(this.contentElementId); + .getElementById($PREFIX); if (element) { @@ -820,13 +740,12 @@ export class Player */ _$initialize (): void { - const contentElementId: string = this.contentElementId; if (!this._$tagId) { $document .body .insertAdjacentHTML( - "beforeend", `

` + "beforeend", `
` ); } else { @@ -837,11 +756,11 @@ export class Player return ; } - const div: HTMLElement | null = $document.getElementById(contentElementId); + const div: HTMLElement | null = $document.getElementById($PREFIX); if (!div) { const element: HTMLDivElement = $document.createElement("div"); - element.id = contentElementId; + element.id = $PREFIX; element.tabIndex = -1; container.appendChild(element); @@ -853,7 +772,7 @@ export class Player } - const element: HTMLElement | null = $document.getElementById(contentElementId); + const element: HTMLElement | null = $document.getElementById($PREFIX); if (!element) { throw new Error("the content element is null."); } @@ -864,17 +783,17 @@ export class Player this._$initStyle(element); this._$buildWait(); - const width: number = this._$optionWidth - ? this._$optionWidth + const width: number = this._$fixedWidth + ? this._$fixedWidth : parent.tagName === "BODY" - ? $window.innerWidth - : parent.offsetWidth; + ? window.innerWidth + : parent.clientWidth; - const height: number = this._$optionHeight - ? this._$optionHeight + const height: number = this._$fixedHeight + ? this._$fixedHeight : parent.tagName === "BODY" - ? $window.innerHeight - : parent.offsetHeight; + ? window.innerHeight + : parent.clientHeight; // set center if (this._$mode === "loader" && width && height) { @@ -885,7 +804,7 @@ export class Player } if (this._$mode === "loader") { - this._$loadStatus = Player.LOAD_START; + this._$loadStatus = $LOAD_START; this._$updateLoadStatus(); } else { this._$resize(); @@ -893,1654 +812,1404 @@ export class Player } } - /** - * @param {object} element - * @returns {void} - * @method - * @private - */ - _$initStyle (element: HTMLElement): void - { - const style: CSSStyleDeclaration = element.style; - - // set css - style.position = "relative"; - style.top = "0"; - style.left = "0"; - style.backgroundColor = "transparent"; - style.overflow = "hidden"; - style.padding = "0"; - style.margin = "0"; - style.userSelect = "none"; - style.outline = "none"; - - const width: number = this._$optionWidth; - const height: number = this._$optionHeight; + // /** + // * @returns {void} + // * @method + // * @private + // */ + // _$deleteNode (): void + // { + // const element: HTMLElement | null = $document.getElementById($PREFIX); + // if (element) { + // while (element.childNodes.length) { + // element.removeChild(element.childNodes[0]); + // } + // } + // } + + // // @ts-ignore + // this._$canvas.addEventListener($TOUCH_START, (event: TouchEvent) => + // { + // $setEvent(event); + // $setEventType($TOUCH_START); + + // // start position + // this._$hitTest(); + // }); + + // // @ts-ignore + // this._$canvas.addEventListener($TOUCH_MOVE, (event: TouchEvent) => + // { + // $setEvent(event); + // $setEventType($TOUCH_MOVE); + // this._$hitTest(); + // }); + + // // @ts-ignore + // this._$canvas.addEventListener($TOUCH_END, (event: TouchEvent) => + // { + // $setEvent(event); + // $setEventType($TOUCH_END); + // this._$hitTest(); + // }); + + // // @ts-ignore + // this._$canvas.addEventListener($TOUCH_MOVE, (event: TouchEvent) => + // { + // $setEvent(event); + // $setEventType($TOUCH_MOVE); + + // this._$hitTest(); + // }, { "passive": false }); + + // // @ts-ignore + // this._$canvas.addEventListener($MOUSE_DOWN, (event: MouseEvent) => + // { + // $setEvent(event); + // $setEventType($MOUSE_DOWN); + + // if (!event.button) { + // this._$hitTest(); + // } + // }); + + // // @ts-ignore + // this._$canvas.addEventListener($DOUBLE_CLICK, (event: MouseEvent) => + // { + // $setEvent(event); + // $setEventType($DOUBLE_CLICK); + + // if (!event.button) { + // this._$hitTest(); + // } + // }); + + // // @ts-ignore + // this._$canvas.addEventListener($MOUSE_LEAVE, (event: MouseEvent) => + // { + // $setEvent(event); + // $setEventType($MOUSE_LEAVE); + + // this._$hitTest(); + + // $setEvent(null); + // this._$stageX = -1; + // this._$stageY = -1; + // }); + + // // @ts-ignore + // this._$canvas.addEventListener($MOUSE_UP, (event: MouseEvent) => + // { + // $setEvent(event); + // $setEventType($MOUSE_UP); + + // if (!event.button) { + // this._$hitTest(); + // } + // }); + + // // @ts-ignore + // this._$canvas.addEventListener($MOUSE_MOVE, (event: MouseEvent) => + // { + // $setEvent(event); + // $setEventType($MOUSE_MOVE); + + // this._$hitTest(); + // }); + + // // @ts-ignore + // this._$canvas.addEventListener($MOUSE_WHEEL, (event: MouseEvent) => + // { + // if (!event.defaultPrevented) { + + // $setEvent(event); + // $setEventType($MOUSE_WHEEL); + + // this._$hitTest(); + // } + // }, { "passive": false }); + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$resize (): void + // { + // const div: HTMLElement | null = $document + // .getElementById($PREFIX); + + // if (div) { + + // const parent: HTMLElement | null = div.parentElement; + // if (!parent) { + // throw new Error("the parentElement is null."); + // } + + // const innerWidth: number = this._$fixedWidth + // ? this._$fixedWidth + // : parent.tagName === "BODY" + // ? window.innerWidth + // : parent.clientWidth; + + // const innerHeight: number = this._$fixedHeight + // ? this._$fixedHeight + // : parent.tagName === "BODY" + // ? window.innerHeight + // : parent.clientHeight; + + // const screenWidth: number = parent.tagName === "BODY" + // ? $window.innerWidth + // : parent.offsetWidth; + + // const scale: number = $Math.min( + // innerWidth / this._$baseWidth, + // innerHeight / this._$baseHeight + // );z + + // let width: number = this._$fullScreen + // ? innerWidth + // : this._$baseWidth * scale | 0; + + // let height: number = this._$fullScreen + // ? innerHeight + // : this._$baseHeight * scale | 0; + + // // div + // const style: CSSStyleDeclaration = div.style; + // style.width = `${width}px`; + // style.height = `${height}px`; + // style.top = "0"; + // style.left = this._$fullScreen + // ? "0" + // : `${screenWidth / 2 - width / 2}px`; + + // width *= $devicePixelRatio; + // height *= $devicePixelRatio; + + // // no resize + // if (this._$width === width && this._$height === height) { + // return ; + // } + + // // cache reset + // this._$stage._$doChanged(); + // $cacheStore.reset(); + + // // params + // this._$scale = scale; + // this._$width = width; + // this._$height = height; + + // const mScale: number = this._$scale * $devicePixelRatio; + // this._$matrix[0] = mScale; + // this._$matrix[3] = mScale; + + // if (this._$fullScreen) { + + // const tx = (width - + // this._$baseWidth + // * scale + // * $devicePixelRatio) / 2; + + // const ty = (height - + // this._$baseHeight + // * scale + // * $devicePixelRatio) / 2; + + // this._$matrix[4] = tx; + // this._$matrix[5] = ty; + + // } + + // // main canvas resize + // this._$resizeCanvas(width, height, mScale, this._$matrix[4], this._$matrix[5]); + + // if (div.children.length > 1) { + // div.children[1].dispatchEvent( + // new Event(`${$PREFIX}_blur`) + // ); + // } + // } + // } + + // /** + // * @description 表示用のcanvasを更新 + // * Update canvas for display + // * + // * @param {string} [background_color=transparent] + // * @return {void} + // * @method + // * @public + // */ + // _$setBackgroundColor (background_color: string = "transparent"): void + // { + // if ($rendererWorker) { + + // const buffer: Float32Array = $getRenderBufferArray(); + + // buffer[0] = background_color === "transparent" + // ? -1 + // : $toColorInt(background_color); + + // const message: PropertyMessageMapImpl = $getRenderMessageObject(); + // message.command = "setBackgroundColor"; + // message.buffer = buffer; - const parent: HTMLElement | null = element.parentElement; - if (!parent) { - throw new Error("the parentElement is null."); - } + // const options: ArrayBuffer[] = $getArray(buffer.buffer); - if (parent.tagName === "BODY") { - style.width = width ? `${width}px` : `${window.innerWidth}px`; - style.height = height ? `${height}px` : `${window.innerHeight}px`; - return ; - } + // $rendererWorker.postMessage(message, options); - style.width = width ? `${width}px` : `${parent.offsetWidth}px`; - style.height = height ? `${height}px` : `${parent.offsetHeight}px`; - } + // $poolRenderMessageObject(message); + // $poolArray(options); - /** - * @return {void} - * @method - * @private - */ - _$buildWait (): void - { - const element: HTMLElement | null = $document - .getElementById(this.contentElementId); + // } else { - if (element) { + // const context: CanvasToWebGLContext | null = this._$context; + // if (!context) { + // return ; + // } - const loadingId: string = `${this.contentElementId}_loading`; - - element.innerHTML = ``; + // if (background_color === "transparent") { + + // context._$setColor(0, 0, 0, 0); - const div: HTMLDivElement = $document.createElement("div"); - div.id = loadingId; + // } else { + + // const color: RGBAImpl = $uintToRGBA( + // $toColorInt(background_color) + // ); + + // context._$setColor( + // color.R / 255, + // color.G / 255, + // color.B / 255, + // 1 + // ); - element.appendChild(div); - } - } + // } + + // } + // } + + // /** + // * @param {Event} event + // * @return {boolean} + // * @method + // * @private + // */ + // _$dispatchEvent (event: Next2DEvent): boolean + // { + // if (this._$broadcastEvents.size + // && this._$broadcastEvents.has(event.type) + // ) { + + // // clone + // const events: EventListenerImpl[] = this + // ._$broadcastEvents + // .get(event.type) + // .slice(0); + + // // start target + // event.eventPhase = EventPhase.AT_TARGET; + + // for (let idx: number = 0; idx < events.length; ++idx) { + + // const obj: EventListenerImpl = events[idx]; + + // // event execute + // event.currentTarget = obj.target; + + // event.listener = obj.listener; + // obj.listener.call(null, event); + + // if (event._$stopImmediatePropagation) { + // break; + // } + + // } + + // $poolArray(events); + + // return true; + + // } + + // return false; + // } + + // /** + // * @param {number} timestamp + // * @return {void} + // * @method + // * @private + // */ + // async _$run (timestamp: number = 0): Promise + // { + // if (this._$stopFlag) { + // return ; + // } + + // // delay action + // this._$doAction(); + + // const delta: number = timestamp - this._$startTime; + // if (delta > this._$fps) { + + // // update + // this._$startTime = timestamp - delta % this._$fps; + + // // execute + // this._$action(); + + // // start sound + // if (this._$sounds.size) { + // for (const movieClip of this._$sounds.values()) { + // movieClip._$soundPlay(); + // } + // this._$sounds.clear(); + // } + + // // draw + // this._$draw(); + + // // draw event + // if (!$isTouch + // && !this._$hitTestStart + // && this._$state === "up" + // && this._$stageX > -1 + // && this._$stageY > -1 + // && $getEvent() + // ) { + // this._$pointerCheck(); + // } + + // } + + // // next frame + // this._$timerId = requestAnimationFrame((timestamp: number) => + // { + // this._$run(timestamp); + // }); + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$pointerCheck (): void + // { + // const stageX: number = this._$stageX; + // const stageY: number = this._$stageY; + + // // setup + // this._$hitObject.x = stageX; + // this._$hitObject.y = stageY; + // this._$hitObject.pointer = ""; + // this._$hitObject.hit = null; + + // // reset + // $hitContext.setTransform(1, 0, 0, 1, 0, 0); + // $hitContext.beginPath(); + + // // hit test + // $MATRIX_HIT_ARRAY_IDENTITY[4] = this.tx; + // $MATRIX_HIT_ARRAY_IDENTITY[5] = this.ty; + // this._$stage._$mouseHit( + // $hitContext, $MATRIX_HIT_ARRAY_IDENTITY, + // this._$hitObject, true + // ); + + // // change state + // // params + // let instance: DisplayObjectImpl = null; + // let target: DisplayObjectImpl = null; + // let canPointerText: boolean = false; + // let canPointer: boolean = false; + + // // execute + // if (this._$hitObject.hit) { + + // instance = this._$hitObject.hit; + + // // (1) mouseOut + // if (this._$mouseOverTarget + // && this._$mouseOverTarget !== instance + // ) { + + // const outInstance: DisplayObjectImpl = this._$mouseOverTarget; + + // if (outInstance.willTrigger(Next2DMouseEvent.MOUSE_OUT)) { + // outInstance.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.MOUSE_OUT, true, false + // )); + // } + + // } + + // // rollOut and rollOver + // if (this._$rollOverObject !== instance) { + + // let hitParent = null; + // if (this._$rollOverObject) { + + // // (2) prev object rollOut + // target = this._$rollOverObject; + + // if (target.willTrigger(Next2DMouseEvent.ROLL_OUT)) { + // target.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.ROLL_OUT, false, false + // )); + // } + + // // rollOver flag instance + // hitParent = target._$parent; + // while (hitParent && hitParent._$root !== hitParent) { + + // if (hitParent === instance) { + // break; + // } + + // if (hitParent._$mouseEnabled + // && hitParent._$outCheck(stageX, stageY) + // ) { + + // let isUpperLayer = false; + // let check = instance; + // while (check && check._$root !== check) { + + // if (check !== hitParent) { + // check = check._$parent; + // continue; + // } - /** - * @returns {void} - * @method - * @private - */ - _$deleteNode (): void - { - const element: HTMLElement | null = $document.getElementById(this.contentElementId); - if (element) { - while (element.childNodes.length) { - element.removeChild(element.childNodes[0]); - } - } - } + // isUpperLayer = true; - /** - * @return {void} - * @private - */ - _$initializeCanvas (): void - { - // main canvas - this._$canvas.width = 1; - this._$canvas.height = 1; + // break; + // } - if ($rendererWorker) { + // if (!isUpperLayer && hitParent._$parent === instance._$parent + // && hitParent._$index > instance._$index + // ) { + // isUpperLayer = true; + // } - const offscreenCanvas: OffscreenCanvas = this - ._$canvas - .transferControlToOffscreen(); + // if (isUpperLayer) { + // break; + // } - const buffer: Float32Array = $getRenderBufferArray(); + // } - let index: number = 0; - buffer[index++] = this._$stage._$instanceId; - buffer[index++] = +$isSafari; - buffer[index++] = $devicePixelRatio; - buffer[index++] = this._$getSamples(); + // if (hitParent.willTrigger(Next2DMouseEvent.ROLL_OUT)) { + // hitParent.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.ROLL_OUT, false, false + // )); + // } - const options: ArrayBuffer[] = $getArray(offscreenCanvas, buffer.buffer); - $rendererWorker.postMessage({ - "command": "initialize", - "canvas": offscreenCanvas, - "buffer": buffer - }, options); + // hitParent = hitParent._$parent; - $poolArray(options); + // } + // } - } else { - // create gl context - const gl: WebGL2RenderingContext | null = this._$canvas.getContext("webgl2", { - "stencil": true, - "premultipliedAlpha": true, - "antialias": false, - "depth": false, - "preserveDrawingBuffer": true - }); + // // (3) current object rollOver + // target = instance; + // for (;;) { - if (gl) { + // if (target.willTrigger(Next2DMouseEvent.ROLL_OVER)) { + // target.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.ROLL_OVER, false, false + // )); + // } - this._$context = new CanvasToWebGLContext( - gl, this._$getSamples() - ); + // target = target._$parent; + // if (!target || target === hitParent + // || target.stage === target + // ) { + // break; + // } - $cacheStore.context = this._$context; + // } - } else { - alert("WebGL setting is off. Please turn the setting on."); - } + // } - } + // this._$rollOverObject = instance; - // @ts-ignore - this._$canvas.addEventListener($TOUCH_START, (event: TouchEvent) => - { - $setEvent(event); - $setEventType($TOUCH_START); + // // (4) mouseOver + // switch (true) { - // start position - this._$hitTest(); - }); + // case this._$mouseOverTarget === null: + // case this._$mouseOverTarget !== instance: - // @ts-ignore - this._$canvas.addEventListener($TOUCH_MOVE, (event: TouchEvent) => - { - $setEvent(event); - $setEventType($TOUCH_MOVE); - this._$hitTest(); - }); + // if (instance && instance.willTrigger(Next2DMouseEvent.MOUSE_OVER)) { + // instance.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.MOUSE_OVER, true, false + // )); + // } - // @ts-ignore - this._$canvas.addEventListener($TOUCH_END, (event: TouchEvent) => - { - $setEvent(event); - $setEventType($TOUCH_END); - this._$hitTest(); - }); + // // set target + // this._$mouseOverTarget = instance; + // break; - // @ts-ignore - this._$canvas.addEventListener($TOUCH_MOVE, (event: TouchEvent) => - { - $setEvent(event); - $setEventType($TOUCH_MOVE); + // } - this._$hitTest(); - }, { "passive": false }); + // // click reset + // if (this._$state === "up") { + // this._$clickTarget = null; + // } - // @ts-ignore - this._$canvas.addEventListener($MOUSE_DOWN, (event: MouseEvent) => - { - $setEvent(event); - $setEventType($MOUSE_DOWN); + // // PC + // if (!$isTouch && this._$state === "up") { - if (!event.button) { - this._$hitTest(); - } - }); + // target = instance; + // while (target && target.root !== target) { - // @ts-ignore - this._$canvas.addEventListener($DOUBLE_CLICK, (event: MouseEvent) => - { - $setEvent(event); - $setEventType($DOUBLE_CLICK); + // if ("_$text" in target) { + // if (target.type === "input") { + // canPointerText = true; + // break; + // } + // } - if (!event.button) { - this._$hitTest(); - } - }); + // if ("buttonMode" in target && target.buttonMode) { + // canPointer = true; + // break; + // } - // @ts-ignore - this._$canvas.addEventListener($MOUSE_LEAVE, (event: MouseEvent) => - { - $setEvent(event); - $setEventType($MOUSE_LEAVE); + // target = target._$parent; - this._$hitTest(); + // } - $setEvent(null); - this._$stageX = -1; - this._$stageY = -1; - }); + // } - // @ts-ignore - this._$canvas.addEventListener($MOUSE_UP, (event: MouseEvent) => - { - $setEvent(event); - $setEventType($MOUSE_UP); + // } else { - if (!event.button) { - this._$hitTest(); - } - }); + // // (1) mouseOut + // if (this._$mouseOverTarget) { - // @ts-ignore - this._$canvas.addEventListener($MOUSE_MOVE, (event: MouseEvent) => - { - $setEvent(event); - $setEventType($MOUSE_MOVE); + // instance = this._$mouseOverTarget; - this._$hitTest(); - }); + // if (instance.willTrigger(Next2DMouseEvent.MOUSE_OUT)) { + // instance.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.MOUSE_OUT, true, false + // )); + // } + // } - // @ts-ignore - this._$canvas.addEventListener($MOUSE_WHEEL, (event: MouseEvent) => - { - if (!event.defaultPrevented) { + // // (2) rollOut + // if (this._$rollOverObject) { - $setEvent(event); - $setEventType($MOUSE_WHEEL); + // target = this._$rollOverObject; - this._$hitTest(); - } - }, { "passive": false }); - - // set css - let style: string = ""; - style += "position: absolute;"; - style += "top: 0;"; - style += "left: 0;"; - style += "-webkit-tap-highlight-color: rgba(0,0,0,0);"; - style += "backface-visibility: hidden;"; - style += "transform-origin: 0 0;"; - - if ($devicePixelRatio !== 1) { - style += `transform: scale(${1 / $devicePixelRatio});`; - } + // // parent target + // while (target && target.root !== target) { - this._$canvas.setAttribute("style", style); - } + // if (target.willTrigger(Next2DMouseEvent.ROLL_OUT)) { + // target.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.ROLL_OUT, false, false + // )); + // } - /** - * @return {void} - * @method - * @private - */ - _$resize (): void - { - const div: HTMLElement | null = $document - .getElementById(this.contentElementId); - - if (div) { - - const parent: HTMLElement | null = div.parentElement; - if (!parent) { - throw new Error("the parentElement is null."); - } - - const innerWidth: number = this._$optionWidth - ? this._$optionWidth - : parent.tagName === "BODY" - ? $window.innerWidth - : parent.offsetWidth - ? parent.offsetWidth - : parseFloat(parent.style.width); - - const innerHeight: number = this._$optionHeight - ? this._$optionHeight - : parent.tagName === "BODY" - ? $window.innerHeight - : parent.offsetHeight - ? parent.offsetHeight - : parseFloat(parent.style.height); - - const screenWidth: number = parent.tagName === "BODY" - ? $window.innerWidth - : parent.offsetWidth; - - const scale: number = $Math.min( - innerWidth / this._$baseWidth, - innerHeight / this._$baseHeight - ); - - let width: number = this._$fullScreen - ? innerWidth - : this._$baseWidth * scale | 0; - - let height: number = this._$fullScreen - ? innerHeight - : this._$baseHeight * scale | 0; - - // div - const style: CSSStyleDeclaration = div.style; - style.width = `${width}px`; - style.height = `${height}px`; - style.top = "0"; - style.left = this._$fullScreen - ? "0" - : `${screenWidth / 2 - width / 2}px`; - - width *= $devicePixelRatio; - height *= $devicePixelRatio; + // target = target._$parent; - // no resize - if (this._$width === width && this._$height === height) { - return ; - } - - // cache reset - this._$stage._$doChanged(); - $cacheStore.reset(); - - // params - this._$scale = scale; - this._$width = width; - this._$height = height; + // } - const mScale: number = this._$scale * this._$ratio; - this._$matrix[0] = mScale; - this._$matrix[3] = mScale; + // } - if (this._$fullScreen) { + // // reset + // this._$rollOverObject = null; + // this._$mouseOverTarget = null; + // } - this._$tx = (width - - this._$baseWidth - * scale - * $devicePixelRatio) / 2; + // // change cursor + // switch (true) { - this._$ty = (height - - this._$baseHeight - * scale - * $devicePixelRatio) / 2; - - this._$matrix[4] = this._$tx; - this._$matrix[5] = this._$ty; - - } + // case canPointerText: + // this._$canvas.style.cursor = "text"; + // break; - // main canvas resize - this._$resizeCanvas(width, height, mScale, this._$tx, this._$ty); + // case canPointer: + // this._$canvas.style.cursor = "pointer"; + // break; - if (this._$ratio > 1 && $devicePixelRatio > 1) { - this._$canvas.style.transform = `scale(${1 / this._$ratio})`; - } - - if (div.children.length > 1) { - div.children[1].dispatchEvent( - new Event(`${$PREFIX}_blur`) - ); - } - } - } + // case !$isTouch && this._$state === "up": + // this._$canvas.style.cursor = "auto"; + // break; - /** - * @description 表示用のcanvasを更新 - * Update canvas for display - * - * @param {string} [background_color=transparent] - * @return {void} - * @method - * @public - */ - _$setBackgroundColor (background_color: string = "transparent"): void - { - if ($rendererWorker) { + // } - const buffer: Float32Array = $getRenderBufferArray(); + // if (this._$actions.length > 1) { + // this._$doAction(); + // } + // } - buffer[0] = background_color === "transparent" - ? -1 - : $toColorInt(background_color); + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$action (): void + // { - const message: PropertyMessageMapImpl = $getRenderMessageObject(); - message.command = "setBackgroundColor"; - message.buffer = buffer; + // if (this._$stopFlag) { + // return ; + // } - const options: ArrayBuffer[] = $getArray(buffer.buffer); + // let loaders = null; - $rendererWorker.postMessage(message, options); + // const length = this._$loaders.length; + // if (length) { - $poolRenderMessageObject(message); - $poolArray(options); + // // clone + // loaders = this._$loaders.slice(0); - } else { + // // array reset + // this._$loaders.length = 0; - const context: CanvasToWebGLContext | null = this._$context; - if (!context) { - return ; - } + // for (let idx = 0; idx < length; ++idx) { - if (background_color === "transparent") { + // const loader = loaders[idx]; - context._$setColor(0, 0, 0, 0); + // // first action + // if ("content" in loader) { + // loader.content._$prepareActions(); + // } + // } + // } - } else { + // // next frame + // this._$stage._$nextFrame(); - const color: RGBAImpl = $uintToRGBA( - $toColorInt(background_color) - ); + // // enter frame event + // if (this._$broadcastEvents.has(Next2DEvent.ENTER_FRAME)) { + // this._$dispatchEvent(new Next2DEvent(Next2DEvent.ENTER_FRAME)); + // } - context._$setColor( - color.R / 255, - color.G / 255, - color.B / 255, - 1 - ); + // // constructed event + // if (this._$broadcastEvents.has(Next2DEvent.FRAME_CONSTRUCTED)) { + // this._$dispatchEvent(new Next2DEvent(Next2DEvent.FRAME_CONSTRUCTED)); + // } + + // // execute frame action + // this._$doAction(); - } + // // exit event + // if (this._$broadcastEvents.has(Next2DEvent.EXIT_FRAME)) { + // this._$dispatchEvent(new Next2DEvent(Next2DEvent.EXIT_FRAME)); + // } - } - } + // // render event + // if (this._$stage._$invalidate) { - /** - * @param {number} width - * @param {number} height - * @param {number} scale - * @param {number} [tx = 0] - * @param {number} [ty = 0] - * @return {void} - * @method - * @private - */ - _$resizeCanvas ( - width: number, height: number, - scale: number, tx: number = 0, ty: number = 0 - ): void { + // // reset + // this._$stage._$invalidate = false; - if ($rendererWorker) { + // // execute render event + // this._$dispatchEvent(new Next2DEvent(Next2DEvent.RENDER)); + + // } - const buffer: Float32Array = $getRenderBufferArray(); + // // loader events + // if (loaders) { + + // for (let idx: number = 0; idx < loaders.length; ++idx) { + + // const loader = loaders[idx]; + + // // init event + // if (loader.hasEventListener(Next2DEvent.INIT)) { + // loader.dispatchEvent(new Next2DEvent(Next2DEvent.INIT)); + // } + + // // complete event + // if (loader.hasEventListener(Next2DEvent.COMPLETE)) { + // loader.dispatchEvent(new Next2DEvent(Next2DEvent.COMPLETE)); + // } + + // } + + // // pool + // $poolArray(loaders); + // } + + // // execute frame action + // this._$doAction(); + // } + + // /** + // * @returns void + // * @private + // */ + // _$draw (): void + // { + // if (!this._$width || !this._$height) { + // return ; + // } + + // if (!this._$stage._$isUpdated()) { + // return ; + // } + + // if ($rendererWorker) { + // $rendererWorker.postMessage({ + // "command": "draw" + // }); + // } + + // const context: CanvasToWebGLContext | null = this._$context; + // if (!context) { + // return ; + // } + + // // reset + // context.reset(); + // context.setTransform(1, 0, 0, 1, 0, 0); + // context.clearRect(0, 0, this._$width, this._$height); + // context.beginPath(); + + // this._$stage._$draw( + // context, + // this._$matrix, + // $COLOR_ARRAY_IDENTITY + // ); + + // // stage end + // this._$stage._$updated = false; + + // context.drawInstacedArray(); + // context + // .frameBuffer + // .transferToMainTexture(); + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$doAction (): void + // { + // while (this._$actions.length) { + + // this._$actionProcess = true; + + // // target object + // const mc: MovieClip | void = this._$actions.pop(); + // if (!mc) { + // continue; + // } + + // mc._$canAction = false; + // mc._$actionOffset = 0; + // mc._$actionLimit = 0; + + // const frame: number = mc._$currentFrame; + // if (!mc._$actions.has(frame)) { + // continue; + // } + + // const actions: Function[] | void = mc._$actions.get(frame); + // if (!actions) { + // continue; + // } + + // mc._$actionProcess = true; + // for (let idx: number = 0; idx < actions.length; ++idx) { + // $setCurrentLoaderInfo(mc._$loaderInfo); + // actions[idx].apply(mc); + // } + // mc._$actionProcess = false; + + // // adjustment + // if (mc._$frameCache.size) { + // mc._$currentFrame = mc._$frameCache.get("nextFrame"); + // mc._$clearChildren(); + + // mc._$stopFlag = mc._$frameCache.get("stopFlag"); + // mc._$isPlaying = mc._$frameCache.get("isPlaying"); + // mc._$frameCache.clear(); + // } + + // } + + // this._$actionProcess = false; + // $setCurrentLoaderInfo(null); + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$hitTest (): void + // { + // if (this._$stopFlag) { + // return ; + // } + + // // setup + // const event: MouseEvent | TouchEvent | Event | null = $getEvent(); + // if (!event) { + // return ; + // } + + // // update flags + // this._$hitTestStart = true; + // $doUpdated(false); + + // // params + // let instance: DisplayObjectImpl | null = null; + // let target: DisplayObjectImpl | null = null; + + // let x = $window.scrollX; + // let y = $window.scrollY; + + // const div: HTMLElement | null = $document + // .getElementById($PREFIX); + + // if (div) { + // const rect: DOMRect = div.getBoundingClientRect(); + // x += rect.left; + // y += rect.top; + // } + + // let pageX: number = 0; + // let pageY: number = 0; + // if ("changedTouches" in event) { + // const changedTouche: Touch = event.changedTouches[0]; + // pageX = changedTouche.pageX; + // pageY = changedTouche.pageY; + // } else if ("pageX" in event) { + // pageX = event.pageX; + // pageY = event.pageY; + // } + + // // drop point + // const stageX: number = (pageX - x) / this._$scale; + // const stageY: number = (pageY - y) / this._$scale; + + // // update + // this._$stageX = stageX; + // this._$stageY = stageY; + + // // setup + // this._$hitObject.x = stageX; + // this._$hitObject.y = stageY; + // this._$hitObject.pointer = ""; + // this._$hitObject.hit = null; + + // // reset + // $hitContext.setTransform(1, 0, 0, 1, 0, 0); + // $hitContext.beginPath(); + + // // hit test + // $MATRIX_HIT_ARRAY_IDENTITY[4] = this.tx; + // $MATRIX_HIT_ARRAY_IDENTITY[5] = this.ty; + // this._$stage._$mouseHit( + // $hitContext, $MATRIX_HIT_ARRAY_IDENTITY, + // this._$hitObject, true + // ); + + // // stop event + // if (this._$hitObject.hit) { + // event.preventDefault(); + // } + + // // change state + // let canPointerText: boolean = false; + // let staticPointer: boolean = false; + // let canPointer: boolean = false; + + // const eventType: string = $getEventType(); + // switch (eventType) { + + // case $TOUCH_MOVE: + // case $MOUSE_MOVE: + + // if ($dropTarget) { + + // const point: Point = $dropTarget._$dragMousePoint(); + + // let dragX: number = point.x; + // let dragY: number = point.y; + + // if (!$dragRules.lock) { + // dragX += $dragRules.position.x; + // dragY += $dragRules.position.y; + // } + + // const bounds: Rectangle | null = $dragRules.bounds; + // if (bounds) { + // dragX = $clamp(dragX, bounds.left, bounds.right); + // dragY = $clamp(dragY, bounds.top, bounds.bottom); + // } + + // // set move xy + // $dropTarget.x = dragX; + // $dropTarget.y = dragY; + + // } + + // if (this._$clickTarget + // && "_$text" in this._$clickTarget + // && this._$clickTarget.scrollEnabled + // && this._$clickTarget.selectIndex === -1 + // ) { + + // const deltaX: number = this._$deltaX - pageX; + // const deltaY: number = this._$deltaY - pageY; + + // // @ts-ignore + // this._$clickTarget.scrollX += deltaX / (this._$clickTarget.textWidth / this._$clickTarget.width); + + // // @ts-ignore + // this._$clickTarget.scrollY += deltaY / (this._$clickTarget.textHeight / this._$clickTarget.height); + // } + + // this._$deltaX = pageX; + // this._$deltaY = pageY; + // break; + + // case $TOUCH_START: + // case $MOUSE_DOWN: + // this._$deltaX = pageX; + // this._$deltaY = pageY; + // this._$state = "down"; + // canPointer = this._$canvas.style.cursor === "pointer"; + // staticPointer = true; + // break; + + // case $TOUCH_END: + // case $MOUSE_UP: + // case $DOUBLE_CLICK: + // this._$deltaX = 0; + // this._$deltaY = 0; + // this._$state = "up"; + // break; + + // } + + // // execute + // switch (true) { + + // case this._$hitObject.hit === null: + // case eventType === $MOUSE_LEAVE: + + // // (1) mouseOut + // if (this._$mouseOverTarget) { + + // instance = this._$mouseOverTarget; + // if (instance.willTrigger(Next2DMouseEvent.MOUSE_OUT)) { + // instance.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.MOUSE_OUT, true, false + // )); + // } + + // } + + // // (2) rollOut + // if (this._$rollOverObject) { + + // target = this._$rollOverObject; + + // // parent target + // while (target && target.root !== target) { + + // if (target.willTrigger(Next2DMouseEvent.ROLL_OUT)) { + // target.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.ROLL_OUT, false, false + // )); + // } + + // target = target._$parent; + + // } + + // } + + // // reset + // this._$rollOverObject = null; + // this._$mouseOverTarget = null; + + // // stage event + // switch (eventType) { + + // case $MOUSE_WHEEL: + // if (this._$stage.hasEventListener(Next2DMouseEvent.MOUSE_WHEEL)) { + // this._$stage.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.MOUSE_WHEEL, true, false + // )); + // } + // break; + + // case $TOUCH_START: + // case $MOUSE_DOWN: + // if (this._$textField && "focus" in this._$textField) { + // this._$textField.focus = false; + // this._$textField = null; + // } + + // if (this._$stage.hasEventListener(Next2DMouseEvent.MOUSE_DOWN)) { + // this._$stage.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.MOUSE_DOWN, true, false + // )); + // } + // break; + + // case $TOUCH_END: + // case $MOUSE_UP: + + // if (this._$stage.hasEventListener(Next2DMouseEvent.CLICK)) { + // this._$stage.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.CLICK, true, false + // )); + // } + + // if (this._$stage.hasEventListener(Next2DMouseEvent.MOUSE_UP)) { + // this._$stage.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.MOUSE_UP, true, false + // )); + // } + + // break; + + // case $TOUCH_MOVE: + // case $MOUSE_MOVE: + // if (this._$stage.hasEventListener(Next2DMouseEvent.MOUSE_MOVE)) { + // this._$stage.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.MOUSE_MOVE, true, false + // )); + // } + // break; + + // case $DOUBLE_CLICK: + // if (this._$stage.hasEventListener(Next2DMouseEvent.DOUBLE_CLICK)) { + // this._$stage.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.DOUBLE_CLICK, true, false + // )); + // } + // break; - let index: number = 0; - buffer[index++] = width; - buffer[index++] = height; - buffer[index++] = scale; - buffer[index++] = tx; - buffer[index++] = ty; + // } - const message: PropertyMessageMapImpl = $getRenderMessageObject(); - const options: ArrayBuffer[] = $getArray(buffer.buffer); + // break; - message.command = "resize"; - message.buffer = buffer; - $rendererWorker.postMessage(message, options); + // default: + + // instance = this._$hitObject.hit; + // switch (eventType) { + + // // move event + // case $TOUCH_MOVE: + // case $MOUSE_MOVE: + + // // (1) mouseMove + // if (instance.willTrigger(Next2DMouseEvent.MOUSE_MOVE)) { + // instance.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.MOUSE_MOVE, true, false + // )); + // } - // reset - $poolRenderMessageObject(message); - $poolArray(options); + // // (2) mouseOut + // if (this._$mouseOverTarget + // && this._$mouseOverTarget !== instance + // ) { - } else { + // const outInstance: DisplayObjectImpl = this._$mouseOverTarget; + + // if (outInstance.willTrigger(Next2DMouseEvent.MOUSE_OUT)) { + // outInstance.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.MOUSE_OUT, true, false + // )); + // } + + // } + + // // rollOut and rollOver + // if (this._$rollOverObject !== instance) { + + // let hitParent: DisplayObjectImpl | null = null; + // if (this._$rollOverObject) { + + // // (3) prev object rollOut + // target = this._$rollOverObject; + + // if (target.willTrigger(Next2DMouseEvent.ROLL_OUT)) { + // target.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.ROLL_OUT, false, false + // )); + // } + + // // rollOver flag instance + // hitParent = target._$parent; + // while (hitParent && hitParent._$root !== hitParent) { + + // if (hitParent === instance) { + // break; + // } + + // if (hitParent._$mouseEnabled + // && hitParent._$outCheck(stageX, stageY) + // ) { + + // let isUpperLayer: boolean = false; + // let check: DisplayObjectImpl | null = instance; + // while (check && check._$root !== check) { + + // if (check !== hitParent) { + // check = check._$parent; + // continue; + // } + + // isUpperLayer = true; + + // break; + // } + + // if (!isUpperLayer && hitParent._$parent === instance._$parent + // && hitParent._$index > instance._$index + // ) { + // isUpperLayer = true; + // } + + // if (isUpperLayer) { + // break; + // } + + // } + + // if (hitParent.willTrigger(Next2DMouseEvent.ROLL_OUT)) { + // hitParent.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.ROLL_OUT, false, false + // )); + // } + + // hitParent = hitParent._$parent; + + // } + // } + + // // (4) current object rollOver + // target = instance; + // for (;;) { + + // if (target.willTrigger(Next2DMouseEvent.ROLL_OVER)) { + // target.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.ROLL_OVER, false, false + // )); + // } + + // target = target._$parent; + // if (!target || target === hitParent + // || target.stage === target + // ) { + // break; + // } + + // } + + // } + + // this._$rollOverObject = instance; + + // // (5) mouseOver + // switch (true) { + + // case this._$mouseOverTarget === null: + // case this._$mouseOverTarget !== instance: + + // if (instance.willTrigger(Next2DMouseEvent.MOUSE_OVER)) { + // instance.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.MOUSE_OVER, true, false + // )); + // } + + // // set target + // this._$mouseOverTarget = instance; + // break; + + // } + + // // click reset + // if (this._$state === "up") { + // this._$clickTarget = null; + // } else { + // if (this._$textField) { + // this._$textField._$setIndex( + // stageX - $MATRIX_HIT_ARRAY_IDENTITY[4], + // stageY - $MATRIX_HIT_ARRAY_IDENTITY[5] + // ); + // } + // } + + // break; + + // // down event + // case $TOUCH_START: + // case $MOUSE_DOWN: + + // if (this._$textField + // && instance !== this._$textField + // ) { + // this._$textField.focus = false; + // this._$textField = null; + // } + + // // TextField focus out + // if ("_$text" in instance) { + // instance.focus = true; + // instance._$setIndex( + // stageX - $MATRIX_HIT_ARRAY_IDENTITY[4], + // stageY - $MATRIX_HIT_ARRAY_IDENTITY[5] + // ); + // this._$textField = instance; + + // // move text area element + // $textArea.style.left = `${pageX}px`; + // $textArea.style.top = `${pageY}px`; + // } + + // // (3) mouseDown + // if (instance.willTrigger(Next2DMouseEvent.MOUSE_DOWN)) { + // instance.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.MOUSE_DOWN, true, false + // )); + // } - const context: CanvasToWebGLContext | null = this._$context; - if (!context) { // unit test - return ; - } + // // (4) click + // this._$clickTarget = instance; + + // break; + + // // up event + // case $TOUCH_END: + // case $MOUSE_UP: + + // // (1) mouseUp + // if (instance.willTrigger(Next2DMouseEvent.MOUSE_UP)) { + // instance.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.MOUSE_UP, true, false + // )); + // } - context.clearInstacedArray(); + // // (2) click + // if (this._$clickTarget === instance) { + + // if (instance.willTrigger(Next2DMouseEvent.CLICK)) { + // instance.dispatchEvent(new Next2DMouseEvent( + // Next2DMouseEvent.CLICK, true, false + // )); + // } - this._$canvas.width = width; - this._$canvas.height = height; + // } - context._$gl.viewport(0, 0, width, height); + // // reset + // this._$clickTarget = null; - const manager: FrameBufferManager = context.frameBuffer; - if (this._$attachment) { - manager.unbind(); - manager.releaseAttachment(this._$attachment, true); - } + // break; - this._$attachment = manager - .createCacheAttachment(width, height, true); + // case $MOUSE_WHEEL: + // if (instance.willTrigger(Next2DMouseEvent.MOUSE_WHEEL)) { + // instance.dispatchEvent( + // new Next2DMouseEvent(Next2DMouseEvent.MOUSE_WHEEL) + // ); + // } - // update cache max size - context.setMaxSize(width, height); + // if (instance.scrollEnabled) { + // if ("deltaX" in event) { + // // @ts-ignore + // instance.scrollX += event.deltaX / (instance.textWidth / instance.width); + // } + + // if ("deltaY" in event) { + // // @ts-ignore + // instance.scrollY += event.deltaY / (instance.textHeight / instance.height); + // } + // } - context._$bind(this._$attachment); - } - } + // break; + + // case $DOUBLE_CLICK: + // if (instance.willTrigger(Next2DMouseEvent.DOUBLE_CLICK)) { + // instance.dispatchEvent( + // new Next2DMouseEvent(Next2DMouseEvent.DOUBLE_CLICK) + // ); + // } + // break; - /** - * @return {number} - * @method - * @private - */ - _$getSamples (): number - { - switch (this._$quality) { + // default: + // break; - case "high": - return 4; + // } - case "medium": - return 2; + // // PC + // if (!staticPointer) { - default: - return 0; + // if (!$isTouch && this._$state === "up") { - } - } + // target = instance; + // while (target && target.root !== target) { - /** - * @param {Event} event - * @return {boolean} - * @method - * @private - */ - _$dispatchEvent (event: Next2DEvent): boolean - { - if (this._$broadcastEvents.size - && this._$broadcastEvents.has(event.type) - ) { + // if ("_$text" in target) { - // clone - const events: EventListenerImpl[] = this - ._$broadcastEvents - .get(event.type) - .slice(0); + // if (target.type === "input") { + // canPointerText = true; + // break; + // } - // start target - event.eventPhase = EventPhase.AT_TARGET; + // } else { - for (let idx: number = 0; idx < events.length; ++idx) { + // if (target._$buttonMode) { + // canPointer = true; + // break; + // } - const obj: EventListenerImpl = events[idx]; + // } - // event execute - event.currentTarget = obj.target; + // target = target._$parent; - event.listener = obj.listener; - obj.listener.call(null, event); + // } + // } + // } + // break; - if (event._$stopImmediatePropagation) { - break; - } + // } - } + // // change cursor + // switch (true) { - $poolArray(events); + // case canPointerText: + // this._$canvas.style.cursor = "text"; + // break; - return true; + // case canPointer: + // this._$canvas.style.cursor = "pointer"; + // break; - } + // case !$isTouch && this._$state === "up": + // this._$canvas.style.cursor = "auto"; + // break; - return false; - } + // } - /** - * @param {number} timestamp - * @return {void} - * @method - * @private - */ - _$run (timestamp: number = 0): void - { - if (this._$stopFlag) { - return ; - } + // // execute action + // if (!this._$actionProcess && this._$actions.length > 1) { + // this._$doAction(); + // } - // delay action - this._$doAction(); + // if ($isUpdated()) { - const delta: number = timestamp - this._$startTime; - if (delta > this._$fps) { + // // action script + // this._$stage._$prepareActions(); + // if (!this._$actionProcess) { + // this._$doAction(); + // } - // update - this._$startTime = timestamp - delta % this._$fps; + // } - // execute - this._$action(); - - // start sound - if (this._$sounds.size) { - for (const movieClip of this._$sounds.values()) { - movieClip._$soundPlay(); - } - this._$sounds.clear(); - } - - // draw - this._$draw(); - - // draw event - if (!$isTouch - && !this._$hitTestStart - && this._$state === "up" - && this._$stageX > -1 - && this._$stageY > -1 - && $getEvent() - ) { - this._$pointerCheck(); - } - - } - - // next frame - this._$timerId = $requestAnimationFrame((timestamp: number) => - { - this._$run(timestamp); - }); - } - - /** - * @return {void} - * @method - * @private - */ - _$pointerCheck (): void - { - const stageX: number = this._$stageX; - const stageY: number = this._$stageY; - - // setup - this._$hitObject.x = stageX; - this._$hitObject.y = stageY; - this._$hitObject.pointer = ""; - this._$hitObject.hit = null; - - // reset - $hitContext.setTransform(1, 0, 0, 1, 0, 0); - $hitContext.beginPath(); - - // hit test - $MATRIX_HIT_ARRAY_IDENTITY[4] = this._$tx / this._$scale / $devicePixelRatio; - $MATRIX_HIT_ARRAY_IDENTITY[5] = this._$ty / this._$scale / $devicePixelRatio; - this._$stage._$mouseHit( - $hitContext, $MATRIX_HIT_ARRAY_IDENTITY, - this._$hitObject, true - ); - - // change state - // params - let instance: DisplayObjectImpl = null; - let target: DisplayObjectImpl = null; - let canPointerText: boolean = false; - let canPointer: boolean = false; - - // execute - if (this._$hitObject.hit) { - - instance = this._$hitObject.hit; - - // (1) mouseOut - if (this._$mouseOverTarget - && this._$mouseOverTarget !== instance - ) { - - const outInstance: DisplayObjectImpl = this._$mouseOverTarget; - - if (outInstance.willTrigger(Next2DMouseEvent.MOUSE_OUT)) { - outInstance.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.MOUSE_OUT, true, false - )); - } - - } - - // rollOut and rollOver - if (this._$rollOverObject !== instance) { - - let hitParent = null; - if (this._$rollOverObject) { - - // (2) prev object rollOut - target = this._$rollOverObject; - - if (target.willTrigger(Next2DMouseEvent.ROLL_OUT)) { - target.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.ROLL_OUT, false, false - )); - } - - // rollOver flag instance - hitParent = target._$parent; - while (hitParent && hitParent._$root !== hitParent) { - - if (hitParent === instance) { - break; - } - - if (hitParent._$mouseEnabled - && hitParent._$outCheck(stageX, stageY) - ) { - - let isUpperLayer = false; - let check = instance; - while (check && check._$root !== check) { - - if (check !== hitParent) { - check = check._$parent; - continue; - } - - isUpperLayer = true; - - break; - } - - if (!isUpperLayer && hitParent._$parent === instance._$parent - && hitParent._$index > instance._$index - ) { - isUpperLayer = true; - } - - if (isUpperLayer) { - break; - } - - } - - if (hitParent.willTrigger(Next2DMouseEvent.ROLL_OUT)) { - hitParent.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.ROLL_OUT, false, false - )); - } - - hitParent = hitParent._$parent; - - } - } - - // (3) current object rollOver - target = instance; - for (;;) { - - if (target.willTrigger(Next2DMouseEvent.ROLL_OVER)) { - target.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.ROLL_OVER, false, false - )); - } - - target = target._$parent; - if (!target || target === hitParent - || target.stage === target - ) { - break; - } - - } - - } - - this._$rollOverObject = instance; - - // (4) mouseOver - switch (true) { - - case this._$mouseOverTarget === null: - case this._$mouseOverTarget !== instance: - - if (instance && instance.willTrigger(Next2DMouseEvent.MOUSE_OVER)) { - instance.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.MOUSE_OVER, true, false - )); - } - - // set target - this._$mouseOverTarget = instance; - break; - - } - - // click reset - if (this._$state === "up") { - this._$clickTarget = null; - } - - // PC - if (!$isTouch && this._$state === "up") { - - target = instance; - while (target && target.root !== target) { - - if ("_$text" in target) { - if (target.type === "input") { - canPointerText = true; - break; - } - } - - if ("buttonMode" in target && target.buttonMode) { - canPointer = true; - break; - } - - target = target._$parent; - - } - - } - - } else { - - // (1) mouseOut - if (this._$mouseOverTarget) { - - instance = this._$mouseOverTarget; - - if (instance.willTrigger(Next2DMouseEvent.MOUSE_OUT)) { - instance.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.MOUSE_OUT, true, false - )); - } - } - - // (2) rollOut - if (this._$rollOverObject) { - - target = this._$rollOverObject; - - // parent target - while (target && target.root !== target) { - - if (target.willTrigger(Next2DMouseEvent.ROLL_OUT)) { - target.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.ROLL_OUT, false, false - )); - } - - target = target._$parent; - - } - - } - - // reset - this._$rollOverObject = null; - this._$mouseOverTarget = null; - } - - // change cursor - switch (true) { - - case canPointerText: - this._$canvas.style.cursor = "text"; - break; - - case canPointer: - this._$canvas.style.cursor = "pointer"; - break; - - case !$isTouch && this._$state === "up": - this._$canvas.style.cursor = "auto"; - break; - - } - - if (this._$actions.length > 1) { - this._$doAction(); - } - } - - /** - * @return {void} - * @method - * @private - */ - _$action (): void - { - - if (this._$stopFlag) { - return ; - } - - let loaders = null; - - const length = this._$loaders.length; - if (length) { - - // clone - loaders = this._$loaders.slice(0); - - // array reset - this._$loaders.length = 0; - - for (let idx = 0; idx < length; ++idx) { - - const loader = loaders[idx]; - - // first action - if ("content" in loader) { - loader.content._$prepareActions(); - } - } - } - - // next frame - this._$stage._$nextFrame(); - - // enter frame event - if (this._$broadcastEvents.has(Next2DEvent.ENTER_FRAME)) { - this._$dispatchEvent(new Next2DEvent(Next2DEvent.ENTER_FRAME)); - } - - // constructed event - if (this._$broadcastEvents.has(Next2DEvent.FRAME_CONSTRUCTED)) { - this._$dispatchEvent(new Next2DEvent(Next2DEvent.FRAME_CONSTRUCTED)); - } - - // execute frame action - this._$doAction(); - - // exit event - if (this._$broadcastEvents.has(Next2DEvent.EXIT_FRAME)) { - this._$dispatchEvent(new Next2DEvent(Next2DEvent.EXIT_FRAME)); - } - - // render event - if (this._$stage._$invalidate) { - - // reset - this._$stage._$invalidate = false; - - // execute render event - this._$dispatchEvent(new Next2DEvent(Next2DEvent.RENDER)); - - } - - // loader events - if (loaders) { - - for (let idx: number = 0; idx < loaders.length; ++idx) { - - const loader = loaders[idx]; - - // init event - if (loader.hasEventListener(Next2DEvent.INIT)) { - loader.dispatchEvent(new Next2DEvent(Next2DEvent.INIT)); - } - - // complete event - if (loader.hasEventListener(Next2DEvent.COMPLETE)) { - loader.dispatchEvent(new Next2DEvent(Next2DEvent.COMPLETE)); - } - - } - - // pool - $poolArray(loaders); - } - - // execute frame action - this._$doAction(); - } - - /** - * @returns void - * @private - */ - _$draw (): void - { - if (!this._$width || !this._$height) { - return ; - } - - if (!this._$stage._$isUpdated()) { - return ; - } - - if ($rendererWorker) { - $rendererWorker.postMessage({ - "command": "draw" - }); - } - - const context: CanvasToWebGLContext | null = this._$context; - if (!context) { - return ; - } - - // reset - context.reset(); - context.setTransform(1, 0, 0, 1, 0, 0); - context.clearRect(0, 0, this._$width, this._$height); - context.beginPath(); - - this._$stage._$draw( - context, - this._$matrix, - $COLOR_ARRAY_IDENTITY - ); - - // stage end - this._$stage._$updated = false; - - context.drawInstacedArray(); - context - .frameBuffer - .transferToMainTexture(); - } - - /** - * @return {void} - * @method - * @private - */ - _$doAction (): void - { - while (this._$actions.length) { - - this._$actionProcess = true; - - // target object - const mc: MovieClip | void = this._$actions.pop(); - if (!mc) { - continue; - } - - mc._$canAction = false; - mc._$actionOffset = 0; - mc._$actionLimit = 0; - - const frame: number = mc._$currentFrame; - if (!mc._$actions.has(frame)) { - continue; - } - - const actions: Function[] | void = mc._$actions.get(frame); - if (!actions) { - continue; - } - - mc._$actionProcess = true; - for (let idx: number = 0; idx < actions.length; ++idx) { - $setCurrentLoaderInfo(mc._$loaderInfo); - actions[idx].apply(mc); - } - mc._$actionProcess = false; - - // adjustment - if (mc._$frameCache.size) { - mc._$currentFrame = mc._$frameCache.get("nextFrame"); - mc._$clearChildren(); - - mc._$stopFlag = mc._$frameCache.get("stopFlag"); - mc._$isPlaying = mc._$frameCache.get("isPlaying"); - mc._$frameCache.clear(); - } - - } - - this._$actionProcess = false; - $setCurrentLoaderInfo(null); - } - - /** - * @return {void} - * @method - * @private - */ - _$hitTest (): void - { - if (this._$stopFlag) { - return ; - } - - // setup - const event: MouseEvent | TouchEvent | Event | null = $getEvent(); - if (!event) { - return ; - } - - // update flags - this._$hitTestStart = true; - $doUpdated(false); - - // params - let instance: DisplayObjectImpl | null = null; - let target: DisplayObjectImpl | null = null; - - let x = $window.scrollX; - let y = $window.scrollY; - - const div: HTMLElement | null = $document - .getElementById(this.contentElementId); - - if (div) { - const rect: DOMRect = div.getBoundingClientRect(); - x += rect.left; - y += rect.top; - } - - let pageX: number = 0; - let pageY: number = 0; - if ("changedTouches" in event) { - const changedTouche: Touch = event.changedTouches[0]; - pageX = changedTouche.pageX; - pageY = changedTouche.pageY; - } else if ("pageX" in event) { - pageX = event.pageX; - pageY = event.pageY; - } - - // drop point - const stageX: number = (pageX - x) / this._$scale; - const stageY: number = (pageY - y) / this._$scale; - - // update - this._$stageX = stageX; - this._$stageY = stageY; - - // setup - this._$hitObject.x = stageX; - this._$hitObject.y = stageY; - this._$hitObject.pointer = ""; - this._$hitObject.hit = null; - - // reset - $hitContext.setTransform(1, 0, 0, 1, 0, 0); - $hitContext.beginPath(); - - // hit test - $MATRIX_HIT_ARRAY_IDENTITY[4] = this._$tx / this._$scale / $devicePixelRatio; - $MATRIX_HIT_ARRAY_IDENTITY[5] = this._$ty / this._$scale / $devicePixelRatio; - this._$stage._$mouseHit( - $hitContext, $MATRIX_HIT_ARRAY_IDENTITY, - this._$hitObject, true - ); - - // stop event - if (this._$hitObject.hit) { - event.preventDefault(); - } - - // change state - let canPointerText: boolean = false; - let staticPointer: boolean = false; - let canPointer: boolean = false; - - const eventType: string = $getEventType(); - switch (eventType) { - - case $TOUCH_MOVE: - case $MOUSE_MOVE: - - if ($dropTarget) { - - const point: Point = $dropTarget._$dragMousePoint(); - - let dragX: number = point.x; - let dragY: number = point.y; - - if (!$dragRules.lock) { - dragX += $dragRules.position.x; - dragY += $dragRules.position.y; - } - - const bounds: Rectangle | null = $dragRules.bounds; - if (bounds) { - dragX = $clamp(dragX, bounds.left, bounds.right); - dragY = $clamp(dragY, bounds.top, bounds.bottom); - } - - // set move xy - $dropTarget.x = dragX; - $dropTarget.y = dragY; - - } - - if (this._$clickTarget - && "_$text" in this._$clickTarget - && this._$clickTarget.scrollEnabled - && this._$clickTarget.selectIndex === -1 - ) { - - const deltaX: number = this._$deltaX - pageX; - const deltaY: number = this._$deltaY - pageY; - - // @ts-ignore - this._$clickTarget.scrollX += deltaX / (this._$clickTarget.textWidth / this._$clickTarget.width); - - // @ts-ignore - this._$clickTarget.scrollY += deltaY / (this._$clickTarget.textHeight / this._$clickTarget.height); - } - - this._$deltaX = pageX; - this._$deltaY = pageY; - break; - - case $TOUCH_START: - case $MOUSE_DOWN: - this._$deltaX = pageX; - this._$deltaY = pageY; - this._$state = "down"; - canPointer = this._$canvas.style.cursor === "pointer"; - staticPointer = true; - break; - - case $TOUCH_END: - case $MOUSE_UP: - case $DOUBLE_CLICK: - this._$deltaX = 0; - this._$deltaY = 0; - this._$state = "up"; - break; - - } - - // execute - switch (true) { - - case this._$hitObject.hit === null: - case eventType === $MOUSE_LEAVE: - - // (1) mouseOut - if (this._$mouseOverTarget) { - - instance = this._$mouseOverTarget; - if (instance.willTrigger(Next2DMouseEvent.MOUSE_OUT)) { - instance.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.MOUSE_OUT, true, false - )); - } - - } - - // (2) rollOut - if (this._$rollOverObject) { - - target = this._$rollOverObject; - - // parent target - while (target && target.root !== target) { - - if (target.willTrigger(Next2DMouseEvent.ROLL_OUT)) { - target.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.ROLL_OUT, false, false - )); - } - - target = target._$parent; - - } - - } - - // reset - this._$rollOverObject = null; - this._$mouseOverTarget = null; - - // stage event - switch (eventType) { - - case $MOUSE_WHEEL: - if (this._$stage.hasEventListener(Next2DMouseEvent.MOUSE_WHEEL)) { - this._$stage.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.MOUSE_WHEEL, true, false - )); - } - break; - - case $TOUCH_START: - case $MOUSE_DOWN: - if (this._$textField && "focus" in this._$textField) { - this._$textField.focus = false; - this._$textField = null; - } - - if (this._$stage.hasEventListener(Next2DMouseEvent.MOUSE_DOWN)) { - this._$stage.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.MOUSE_DOWN, true, false - )); - } - break; - - case $TOUCH_END: - case $MOUSE_UP: - - if (this._$stage.hasEventListener(Next2DMouseEvent.CLICK)) { - this._$stage.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.CLICK, true, false - )); - } - - if (this._$stage.hasEventListener(Next2DMouseEvent.MOUSE_UP)) { - this._$stage.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.MOUSE_UP, true, false - )); - } - - break; - - case $TOUCH_MOVE: - case $MOUSE_MOVE: - if (this._$stage.hasEventListener(Next2DMouseEvent.MOUSE_MOVE)) { - this._$stage.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.MOUSE_MOVE, true, false - )); - } - break; - - case $DOUBLE_CLICK: - if (this._$stage.hasEventListener(Next2DMouseEvent.DOUBLE_CLICK)) { - this._$stage.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.DOUBLE_CLICK, true, false - )); - } - break; - - } - - break; - - default: - - instance = this._$hitObject.hit; - switch (eventType) { - - // move event - case $TOUCH_MOVE: - case $MOUSE_MOVE: - - // (1) mouseMove - if (instance.willTrigger(Next2DMouseEvent.MOUSE_MOVE)) { - instance.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.MOUSE_MOVE, true, false - )); - } - - // (2) mouseOut - if (this._$mouseOverTarget - && this._$mouseOverTarget !== instance - ) { - - const outInstance: DisplayObjectImpl = this._$mouseOverTarget; - - if (outInstance.willTrigger(Next2DMouseEvent.MOUSE_OUT)) { - outInstance.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.MOUSE_OUT, true, false - )); - } - - } - - // rollOut and rollOver - if (this._$rollOverObject !== instance) { - - let hitParent: DisplayObjectImpl | null = null; - if (this._$rollOverObject) { - - // (3) prev object rollOut - target = this._$rollOverObject; - - if (target.willTrigger(Next2DMouseEvent.ROLL_OUT)) { - target.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.ROLL_OUT, false, false - )); - } - - // rollOver flag instance - hitParent = target._$parent; - while (hitParent && hitParent._$root !== hitParent) { - - if (hitParent === instance) { - break; - } - - if (hitParent._$mouseEnabled - && hitParent._$outCheck(stageX, stageY) - ) { - - let isUpperLayer: boolean = false; - let check: DisplayObjectImpl | null = instance; - while (check && check._$root !== check) { - - if (check !== hitParent) { - check = check._$parent; - continue; - } - - isUpperLayer = true; - - break; - } - - if (!isUpperLayer && hitParent._$parent === instance._$parent - && hitParent._$index > instance._$index - ) { - isUpperLayer = true; - } - - if (isUpperLayer) { - break; - } - - } - - if (hitParent.willTrigger(Next2DMouseEvent.ROLL_OUT)) { - hitParent.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.ROLL_OUT, false, false - )); - } - - hitParent = hitParent._$parent; - - } - } - - // (4) current object rollOver - target = instance; - for (;;) { - - if (target.willTrigger(Next2DMouseEvent.ROLL_OVER)) { - target.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.ROLL_OVER, false, false - )); - } - - target = target._$parent; - if (!target || target === hitParent - || target.stage === target - ) { - break; - } - - } - - } - - this._$rollOverObject = instance; - - // (5) mouseOver - switch (true) { - - case this._$mouseOverTarget === null: - case this._$mouseOverTarget !== instance: - - if (instance.willTrigger(Next2DMouseEvent.MOUSE_OVER)) { - instance.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.MOUSE_OVER, true, false - )); - } - - // set target - this._$mouseOverTarget = instance; - break; - - } - - // click reset - if (this._$state === "up") { - this._$clickTarget = null; - } else { - if (this._$textField) { - this._$textField._$setIndex( - stageX - $MATRIX_HIT_ARRAY_IDENTITY[4], - stageY - $MATRIX_HIT_ARRAY_IDENTITY[5] - ); - } - } - - break; - - // down event - case $TOUCH_START: - case $MOUSE_DOWN: - - if (this._$textField - && instance !== this._$textField - ) { - this._$textField.focus = false; - this._$textField = null; - } - - // TextField focus out - if ("_$text" in instance) { - instance.focus = true; - instance._$setIndex( - stageX - $MATRIX_HIT_ARRAY_IDENTITY[4], - stageY - $MATRIX_HIT_ARRAY_IDENTITY[5] - ); - this._$textField = instance; - - // move text area element - $textArea.style.left = `${pageX}px`; - $textArea.style.top = `${pageY}px`; - } - - // (3) mouseDown - if (instance.willTrigger(Next2DMouseEvent.MOUSE_DOWN)) { - instance.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.MOUSE_DOWN, true, false - )); - } - - // (4) click - this._$clickTarget = instance; - - break; - - // up event - case $TOUCH_END: - case $MOUSE_UP: - - // (1) mouseUp - if (instance.willTrigger(Next2DMouseEvent.MOUSE_UP)) { - instance.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.MOUSE_UP, true, false - )); - } - - // (2) click - if (this._$clickTarget === instance) { - - if (instance.willTrigger(Next2DMouseEvent.CLICK)) { - instance.dispatchEvent(new Next2DMouseEvent( - Next2DMouseEvent.CLICK, true, false - )); - } - - } - - // reset - this._$clickTarget = null; - - break; - - case $MOUSE_WHEEL: - if (instance.willTrigger(Next2DMouseEvent.MOUSE_WHEEL)) { - instance.dispatchEvent( - new Next2DMouseEvent(Next2DMouseEvent.MOUSE_WHEEL) - ); - } - - if (instance.scrollEnabled) { - if ("deltaX" in event) { - // @ts-ignore - instance.scrollX += event.deltaX / (instance.textWidth / instance.width); - } - - if ("deltaY" in event) { - // @ts-ignore - instance.scrollY += event.deltaY / (instance.textHeight / instance.height); - } - } - - break; - - case $DOUBLE_CLICK: - if (instance.willTrigger(Next2DMouseEvent.DOUBLE_CLICK)) { - instance.dispatchEvent( - new Next2DMouseEvent(Next2DMouseEvent.DOUBLE_CLICK) - ); - } - break; - - default: - break; - - } - - // PC - if (!staticPointer) { - - if (!$isTouch && this._$state === "up") { - - target = instance; - while (target && target.root !== target) { - - if ("_$text" in target) { - - if (target.type === "input") { - canPointerText = true; - break; - } - - } else { - - if (target._$buttonMode) { - canPointer = true; - break; - } - - } - - target = target._$parent; - - } - } - } - break; - - } - - // change cursor - switch (true) { - - case canPointerText: - this._$canvas.style.cursor = "text"; - break; - - case canPointer: - this._$canvas.style.cursor = "pointer"; - break; - - case !$isTouch && this._$state === "up": - this._$canvas.style.cursor = "auto"; - break; - - } - - // execute action - if (!this._$actionProcess && this._$actions.length > 1) { - this._$doAction(); - } - - if ($isUpdated()) { - - // action script - this._$stage._$prepareActions(); - if (!this._$actionProcess) { - this._$doAction(); - } - - } - - this._$hitTestStart = false; - } + // this._$hitTestStart = false; + // } } + +export const $player = new Player(); \ No newline at end of file diff --git a/packages/core/src/Player/PlayerApplyContainerElementStyleService.test.ts b/packages/core/src/Player/PlayerApplyContainerElementStyleService.test.ts new file mode 100644 index 00000000..697ba45f --- /dev/null +++ b/packages/core/src/Player/PlayerApplyContainerElementStyleService.test.ts @@ -0,0 +1,64 @@ +import { execute } from "./PlayerApplyContainerElementStyleService"; +import { describe, expect, it } from "vitest"; + +describe("PlayerApplyContainerElementStyleService.js test", () => +{ + it("execute test case1", () => + { + try { + + execute(document.createElement("div")); + + } catch (error) { + + expect(error.message).toBe("parent element is null."); + + } + }); + + it("execute test case2", () => + { + const div = document.createElement("div"); + + const parent = document.createElement("div"); + parent.appendChild(div); + + expect(div.style.display).toBe(""); + expect(div.style.alignItems).toBe(""); + expect(div.style.justifyContent).toBe(""); + expect(div.style.backgroundColor).toBe(""); + expect(div.style.overflow).toBe(""); + expect(div.style.padding).toBe(""); + expect(div.style.margin).toBe(""); + expect(div.style.userSelect).toBe(""); + expect(div.style.outline).toBe(""); + + execute(div); + + expect(div.style.display).toBe("flex"); + expect(div.style.alignItems).toBe("center"); + expect(div.style.justifyContent).toBe("center"); + expect(div.style.backgroundColor).toBe("transparent"); + expect(div.style.overflow).toBe("hidden"); + expect(div.style.padding).toBe("0px"); + expect(div.style.margin).toBe("0px"); + expect(div.style.userSelect).toBe("none"); + expect(div.style.outline).toBe("none"); + }); + + it("execute test case3", () => + { + const div = document.createElement("div"); + + const parent = document.createElement("div"); + parent.appendChild(div); + + expect(div.style.width).toBe(""); + expect(div.style.height).toBe(""); + + execute(div, 100, 200); + + expect(div.style.width).toBe("100px"); + expect(div.style.height).toBe("200px"); + }); +}); \ No newline at end of file diff --git a/packages/core/src/Player/PlayerApplyContainerElementStyleService.ts b/packages/core/src/Player/PlayerApplyContainerElementStyleService.ts new file mode 100644 index 00000000..71ae5bb9 --- /dev/null +++ b/packages/core/src/Player/PlayerApplyContainerElementStyleService.ts @@ -0,0 +1,51 @@ +/** + * @description コンテナのelementにベースのスタイルを適用 + * Apply base style to container element + * + * @param {HTMLDivElement} element + * @param {number} [fixed_width=0] + * @param {number} [fixed_height=0] + * @return {void} + * @method + * @public + */ +export const execute = ( + element: HTMLDivElement, + fixed_width: number = 0, + fixed_height: number = 0 +): void => { + + let style = ""; + + style += "display:flex;"; + style += "align-items:center;"; + style += "justify-content:center;"; + style += "background-color:transparent;"; + style += "overflow:hidden;"; + style += "padding:0;"; + style += "margin:0;"; + style += "user-select:none;"; + style += "outline:none;"; + + if (fixed_width && fixed_height) { + // fixed size + style += `width:${fixed_width}px;`; + style += `height:${fixed_height}px;`; + } else { + const parent = element.parentElement; + if (!parent) { + throw new Error("parent element is null."); + } + + if (parent.tagName === "BODY") { + // If the parent is BODY, adjust to window size. + style += `width:${window.innerWidth}px;`; + style += `height:${window.innerHeight}px;`; + } else { + style += `width:${parent.clientWidth}px;`; + style += `height:${parent.clientHeight}px;`; + } + } + + element.setAttribute("style", style); +}; \ No newline at end of file diff --git a/packages/core/src/Player/PlayerCreateContainerElementService.test.ts b/packages/core/src/Player/PlayerCreateContainerElementService.test.ts new file mode 100644 index 00000000..1ee8fd79 --- /dev/null +++ b/packages/core/src/Player/PlayerCreateContainerElementService.test.ts @@ -0,0 +1,13 @@ +import { execute } from "./PlayerCreateContainerElementService"; +import { $PREFIX } from "../CoreUtil"; +import { describe, expect, it } from "vitest"; + +describe("PlayerCreateContainerElementService.js test", () => +{ + it("execute test case1", () => + { + const div = execute(); + expect(div.id).toBe($PREFIX); + expect(div.tabIndex).toBe(-1); + }); +}); \ No newline at end of file diff --git a/packages/core/src/Player/PlayerCreateContainerElementService.ts b/packages/core/src/Player/PlayerCreateContainerElementService.ts new file mode 100644 index 00000000..faaaec3b --- /dev/null +++ b/packages/core/src/Player/PlayerCreateContainerElementService.ts @@ -0,0 +1,30 @@ +import { $PREFIX } from "../CoreUtil"; + +/** + * @description コンテナとなるElementを作成して返却 + * Create and return an Element that serves as a container + * + * @param {string} [tag_id=""] + * @return {HTMLDivElement} + * @method + * @protected + */ +export const execute = (tag_id: string = ""): HTMLDivElement => +{ + const div: HTMLDivElement = document.createElement("div"); + div.id = $PREFIX; + div.tabIndex = -1; + + if (!tag_id) { + document.body.appendChild(div); + } else { + const element: HTMLElement | null = document.getElementById(tag_id); + if (!element) { + alert(`Element not found with tag ID: ${tag_id}`); + return div; + } + element.appendChild(div); + } + + return div; +}; \ No newline at end of file diff --git a/packages/core/src/Player/PlayerLoadingAnimationService.test.ts b/packages/core/src/Player/PlayerLoadingAnimationService.test.ts new file mode 100644 index 00000000..1caf37b5 --- /dev/null +++ b/packages/core/src/Player/PlayerLoadingAnimationService.test.ts @@ -0,0 +1,13 @@ +import { execute } from "./PlayerLoadingAnimationService"; +import { describe, expect, it } from "vitest"; + +describe("PlayerLoadingAnimationService.js test", () => +{ + it("execute test case1", () => + { + const div = document.createElement("div"); + expect(div.children.length).toBe(0); + execute(div); + expect(div.children.length).toBe(2); + }); +}); \ No newline at end of file diff --git a/packages/core/src/Player/PlayerLoadingAnimationService.ts b/packages/core/src/Player/PlayerLoadingAnimationService.ts new file mode 100644 index 00000000..a2dc3cdc --- /dev/null +++ b/packages/core/src/Player/PlayerLoadingAnimationService.ts @@ -0,0 +1,37 @@ +import { $PREFIX } from "../CoreUtil"; + +/** + * @description ローディングアニメーションを登録 + * Register loading animation + * + * @param {HTMLDivElement} element + * @return {void} + * @method + * @public + */ +export const execute = (element: HTMLDivElement): void => +{ + const loadingId: string = `${$PREFIX}_loading`; + + element.innerHTML = ` +
`; + +}; \ No newline at end of file diff --git a/packages/core/src/Player/PlayerResizeEventService.ts b/packages/core/src/Player/PlayerResizeEventService.ts new file mode 100644 index 00000000..117d4931 --- /dev/null +++ b/packages/core/src/Player/PlayerResizeEventService.ts @@ -0,0 +1,84 @@ +import type { Player } from "../Player"; +import { execute as playerResizePostMessageService } from "./PlayerResizePostMessageService"; +import { + $PREFIX, + $devicePixelRatio +} from "../CoreUtil"; + +/** + * @description 画面リサイズ時にcanvasのリサイズを行う + * Resize the canvas when resizing the screen + * + * @param {Player} player + * @param {number} initial_width + * @param {number} initial_height + * @param {boolean} full_screen + * @return {void} + * @method + * @protected + */ +export const execute = ( + player: Player, + initial_width: number, + initial_height: number, + full_screen: boolean +): void => { + + const element: HTMLElement | null = document + .getElementById($PREFIX); + + if (!element) { + return ; + } + + const parent: HTMLElement = element.parentElement as HTMLElement; + if (!parent) { + return ; + } + + const screenWidth: number = full_screen || parent.tagName === "BODY" + ? window.innerWidth + : parent.clientWidth; + + const screenHeight: number = full_screen || parent.tagName === "BODY" + ? window.innerHeight + : parent.clientHeight; + + const style = element.style; + style.width = `${screenWidth}px`; + style.height = `${screenHeight}px`; + + const scale: number = Math.min( + screenWidth / initial_width, + screenHeight / initial_height + ); + + const width: number = full_screen + ? window.innerWidth * $devicePixelRatio + : initial_width * scale * $devicePixelRatio | 0; + + const height: number = full_screen + ? window.innerHeight * $devicePixelRatio + : initial_height * scale * $devicePixelRatio | 0; + + // 同じサイズの場合は、ここれで終了 + if (width === player.rendererWidth + && height === player.rendererHeight + ) { + return ; + } + + // update + player.rendererScale = scale; + player.rendererWidth = width; + player.rendererHeight = height; + + // worker postMessage + playerResizePostMessageService(player); + + if (element.children.length > 1) { + element.children[1].dispatchEvent( + new Event(`${$PREFIX}_blur`) + ); + } +}; \ No newline at end of file diff --git a/packages/core/src/Player/PlayerResizePostMessageService.ts b/packages/core/src/Player/PlayerResizePostMessageService.ts new file mode 100644 index 00000000..d5950a8f --- /dev/null +++ b/packages/core/src/Player/PlayerResizePostMessageService.ts @@ -0,0 +1,47 @@ +import type { Player } from "../Player"; +import type { ResizeMessageImpl } from "../interface/ResizeMessageImpl"; +import { $rendererWorker } from "../CoreUtil"; + +/** + * @description リサイズメッセージ + * Resize message + * + * @type {ResizeMessageImpl} + * @private + */ +const message: ResizeMessageImpl = { + "command": "resize", + "buffer": null +}; + +/** + * @description Transferableオブジェクト + * Transferable object + * + * @type {Transferable[]} + * @private + */ +const options: Transferable[] = []; + +/** + * @description 画面リサイズ情報をworkerに送る + * Send screen resize information to worker + * + * @param {Player} player + * @return {void} + * @method + * @protected + */ +export const execute = (player: Player): void => +{ + // postMessage + message.buffer = new Float32Array([ + player.rendererScale, + player.rendererWidth, + player.rendererHeight + ]); + + options[0] = message.buffer.buffer; + + $rendererWorker.postMessage(message, options); +}; \ No newline at end of file diff --git a/packages/core/src/Player/PlayerResizeRegisterService.ts b/packages/core/src/Player/PlayerResizeRegisterService.ts new file mode 100644 index 00000000..06f9bd7f --- /dev/null +++ b/packages/core/src/Player/PlayerResizeRegisterService.ts @@ -0,0 +1,37 @@ +import type { Player } from "../Player"; +import { execute as playerResizeEventService } from "./PlayerResizeEventService"; + +/** + * @type {number} + * @private + */ +let timerId: number = -1; + +/** + * @description 画面リサイズのイベントを登録 + * Register screen resize event + * + * @return {void} + * @method + * @protected + */ +export const execute = ( + player: Player, + initial_width: number, + initial_height: number, + full_screen: boolean +): void => { + window.addEventListener("resize", (): void => + { + cancelAnimationFrame(timerId); + timerId = requestAnimationFrame((): void => + { + playerResizeEventService( + player, + initial_width, + initial_height, + full_screen + ); + }); + }); +}; \ No newline at end of file diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 3b3647ac..675bb776 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,2 +1,3 @@ +export * from "./Canvas"; export * from "./Player"; export * from "./Next2D"; \ No newline at end of file diff --git a/packages/core/src/interface/EventDispatcherImpl.ts b/packages/core/src/interface/EventDispatcherImpl.ts new file mode 100644 index 00000000..eef088b3 --- /dev/null +++ b/packages/core/src/interface/EventDispatcherImpl.ts @@ -0,0 +1,3 @@ +import type { EventDispatcher } from "@next2d/events"; + +export type EventDispatcherImpl = T; diff --git a/packages/core/src/interface/ParentImpl.ts b/packages/core/src/interface/ParentImpl.ts new file mode 100644 index 00000000..2567c608 --- /dev/null +++ b/packages/core/src/interface/ParentImpl.ts @@ -0,0 +1,3 @@ +import { DisplayObjectContainer } from "@next2d/display"; + +export type ParentImpl = T; \ No newline at end of file diff --git a/packages/core/src/interface/PlayerHitObjectImpl.ts b/packages/core/src/interface/PlayerHitObjectImpl.ts new file mode 100644 index 00000000..b7fcd0aa --- /dev/null +++ b/packages/core/src/interface/PlayerHitObjectImpl.ts @@ -0,0 +1,8 @@ +import { DisplayObjectImpl } from "./DisplayObjectImpl"; + +export interface PlayerHitObjectImpl { + x: number; + y: number; + pointer: string; + hit: DisplayObjectImpl|null; +} \ No newline at end of file diff --git a/packages/core/src/interface/PlayerModeImpl.ts b/packages/core/src/interface/PlayerModeImpl.ts new file mode 100644 index 00000000..a72252f5 --- /dev/null +++ b/packages/core/src/interface/PlayerModeImpl.ts @@ -0,0 +1 @@ +export type PlayerModeImpl = "loader" | "create"; \ No newline at end of file diff --git a/packages/core/src/interface/ResizeMessageImpl.ts b/packages/core/src/interface/ResizeMessageImpl.ts new file mode 100644 index 00000000..0c3985f2 --- /dev/null +++ b/packages/core/src/interface/ResizeMessageImpl.ts @@ -0,0 +1,4 @@ +export interface ResizeMessageImpl { + command: string; + buffer: Float32Array | null; +} \ No newline at end of file diff --git a/packages/display/src/Stage.ts b/packages/display/src/Stage.ts index 90e92599..b9f75a74 100644 --- a/packages/display/src/Stage.ts +++ b/packages/display/src/Stage.ts @@ -1,16 +1,9 @@ import { DisplayObjectContainer } from "./DisplayObjectContainer"; -import type { Player } from "@next2d/core"; import type { DisplayObjectImpl } from "@next2d/interface"; -import { - $clamp, - $toColorInt, - $uintToRGBA, - $devicePixelRatio -} from "@next2d/share"; /** - * Stage クラスはメイン描画領域を表します。 - * The Stage class represents the main drawing area. + * @description Stage クラスはメイン描画領域を表します。 + * The Stage class represents the main drawing area. * * @class * @memberOf next2d.display @@ -18,10 +11,7 @@ import { */ export class Stage extends DisplayObjectContainer { - public _$player: Player | null; public _$invalidate: boolean; - private _$color: number; - public _$frameRate: number; /** * @constructor @@ -31,13 +21,6 @@ export class Stage extends DisplayObjectContainer { super(); - /** - * @type {Player} - * @default null - * @private - */ - this._$player = null; - /** * @type {Stage} * @private @@ -56,20 +39,6 @@ export class Stage extends DisplayObjectContainer * @private */ this._$invalidate = true; - - /** - * @type {number} - * @default 0xffffffff - * @private - */ - this._$color = 0xffffffff; - - /** - * @type {number} - * @default 60 - * @private - */ - this._$frameRate = 60; } /** @@ -77,7 +46,7 @@ export class Stage extends DisplayObjectContainer * Returns the string representation of the specified class. * * @return {string} - * @default [class Stage] + * @default "[class Stage]" * @method * @static */ @@ -91,7 +60,7 @@ export class Stage extends DisplayObjectContainer * Returns the space name of the specified class. * * @return {string} - * @default next2d.display.Stage + * @default "next2d.display.Stage" * @const * @static */ @@ -105,7 +74,7 @@ export class Stage extends DisplayObjectContainer * Returns the string representation of the specified object. * * @return {string} - * @default [object Stage] + * @default "[object Stage]" * @method * @public */ @@ -119,7 +88,7 @@ export class Stage extends DisplayObjectContainer * Returns the space name of the specified object. * * @return {string} - * @default next2d.display.Stage + * @default "next2d.display.Stage" * @const * @public */ @@ -128,153 +97,6 @@ export class Stage extends DisplayObjectContainer return "next2d.display.Stage"; } - /** - * @description 背景色です。 - * background color. - * - * @member {number} - * @public - */ - get color (): number - { - return this._$color; - } - set color (color: number) - { - this._$color = $clamp($toColorInt(color), 0, 0xffffff, 0xffffff); - const player: Player | null = this._$player; - if (player && player.context) { - const rgba = $uintToRGBA(this._$color); - player - .context - ._$setColor( - rgba.R / 255, - rgba.G / 255, - rgba.B / 255, - rgba.A / 255 - ); - } - } - - /** - * @description ステージのフレームレートを取得または設定します。 - * Gets and sets the frame rate of the stage. - * - * @member {number} - * @public - */ - get frameRate () - { - return this._$frameRate; - } - set frameRate (frame_rate) - { - this._$frameRate = $clamp(+frame_rate, 1, 60, 60); - if (this._$player && !this._$player._$stopFlag) { - this._$player.stop(); - this._$player.play(); - } - } - - /** - * @description Player オブジェクトを返します。 - * Returns a Player object. - * - * @member {Player} - * @readonly - * @public - */ - get player (): Player | null - { - return this._$player; - } - - /** - * @description 現在のCanvasの高さをピクセル単位で指定します。 - * Specifies the height of the current Canvas in pixels. - * - * @member {number} - * @readonly - * @public - */ - get canvasHeight (): number - { - return this._$player - ? this._$player._$height / $devicePixelRatio - : 0; - } - - /** - * @description 現在のCanvasの幅をピクセル単位で指定します。 - * Specifies the width of the current Canvas in pixels. - * - * @member {number} - * @readonly - * @public - */ - get canvasWidth (): number - { - return this._$player - ? this._$player._$width / $devicePixelRatio - : 0; - } - - /** - * @description 現在のStageの高さをピクセル単位で指定します。 - * Specifies the height of the current Stage in pixels. - * - * @member {number} - * @readonly - * @public - */ - get currentStageHeight (): number - { - return this._$player - ? this._$player.height * this._$player._$scale - : 0; - } - - /** - * @description 現在のStageの幅をピクセル単位で指定します。 - * Specifies the width of the current Stage in pixels. - * - * @member {number} - * @readonly - * @public - */ - get currentStageWidth (): number - { - return this._$player - ? this._$player.width * this._$player._$scale - : 0; - } - - /** - * @description 初期設定したステージの高さをピクセル単位で指定します。 - * Specifies the height of the initially set stage in pixels. - * - * @member {number} - * @readonly - * @public - */ - get stageHeight (): number - { - return this._$player ? this._$player.height : 0; - } - - /** - * @description 初期設定したステージの幅をピクセル単位で指定します。 - * Specifies the width of the initially set stage in pixels. - * - * @member {number} - * @readonly - * @public - */ - get stageWidth (): number - { - return this._$player ? this._$player.width : 0; - } - /** * @description 表示リストをレンダリングする必要のある次の機会に、 * 表示オブジェクトに警告するようランタイムに通知します。 @@ -310,3 +132,5 @@ export class Stage extends DisplayObjectContainer return super._$addChild(child); } } + +export const $stage = new Stage(); \ No newline at end of file diff --git a/packages/interface/src/EventDispatcherImpl.ts b/packages/interface/src/EventDispatcherImpl.ts index cfb3100d..eef088b3 100644 --- a/packages/interface/src/EventDispatcherImpl.ts +++ b/packages/interface/src/EventDispatcherImpl.ts @@ -1,3 +1,3 @@ -import { EventDispatcher } from "@next2d/events"; +import type { EventDispatcher } from "@next2d/events"; export type EventDispatcherImpl = T; diff --git a/packages/media/README.md b/packages/media/README.md index 11a622fb..14d387bf 100644 --- a/packages/media/README.md +++ b/packages/media/README.md @@ -1,10 +1,10 @@ -@next2d/media +@next2d/renderer ============= ## Installation ``` -npm install @next2d/media +npm install @next2d/renderer ``` ## License diff --git a/packages/renderer/LICENSE b/packages/renderer/LICENSE new file mode 100644 index 00000000..a536abed --- /dev/null +++ b/packages/renderer/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Next2D + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/renderer/README.md b/packages/renderer/README.md new file mode 100644 index 00000000..14d387bf --- /dev/null +++ b/packages/renderer/README.md @@ -0,0 +1,11 @@ +@next2d/renderer +============= + +## Installation + +``` +npm install @next2d/renderer +``` + +## License +This project is licensed under the [MIT License](https://opensource.org/licenses/MIT) - see the [LICENSE](LICENSE) file for details. diff --git a/packages/renderer/package.json b/packages/renderer/package.json new file mode 100644 index 00000000..3bdedc08 --- /dev/null +++ b/packages/renderer/package.json @@ -0,0 +1,31 @@ +{ + "name": "@next2d/renderer", + "version": "*", + "description": "Next2D Renderer Packages", + "author": "Toshiyuki Ienaga (https://github.com/ienaga/)", + "license": "MIT", + "homepage": "https://next2d.app", + "bugs": "https://github.com/Next2D/Player/issues", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist" + ], + "exports": { + ".": { + "import": "./src/index.js", + "require": "./src/index.js" + } + }, + "keywords": [ + "Next2D", + "Next2D Renderer" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/Next2D/Player.git" + }, + "peerDependencies": { + "@next2d/webgl": "file:../webgl" + } +} diff --git a/packages/renderer/src/CommandController.ts b/packages/renderer/src/CommandController.ts new file mode 100644 index 00000000..d51982e5 --- /dev/null +++ b/packages/renderer/src/CommandController.ts @@ -0,0 +1,213 @@ +// import { $renderPlayer } from "./RenderGlobal"; +// import { +// $MATRIX_ARRAY_IDENTITY, +// $COLOR_ARRAY_IDENTITY, +// $OffscreenCanvas, +// $cacheStore +// } from "@next2d/share"; +import type { PropertyMessageMapImpl } from "./interface/PropertyMessageMapImpl"; +import type { RenderDisplayObjectImpl } from "./interface/RenderDisplayObjectImpl"; + +/** + * @class + */ +export class CommandController +{ + public state: string; + public queue: PropertyMessageMapImpl[]; + private readonly _$options: ArrayBuffer[]; + + /** + * @constructor + * @public + */ + constructor () + { + /** + * @type {string} + * @default "deactivate" + * @public + */ + this.state = "deactivate"; + + /** + * @type {array} + * @public + */ + this.queue = []; + + /** + * @type {array} + * @private + */ + this._$options = []; + } + + /** + * @description 処理を実行 + * Execute process + * + * @return {void} + * @method + * @public + */ + async execute (): Promise + { + this.state = "active"; + + let returnBuffer = true; + while (this.queue.length) { + + const object: PropertyMessageMapImpl | void = this.queue.shift(); + if (!object) { + continue; + } + + returnBuffer = true; + switch (object.command) { + + // case "draw": + // $renderPlayer._$draw(); + // break; + + // case "setProperty": + // { + // const instances: Map> = $renderPlayer.instances; + // if (!instances.has(object.instanceId)) { + // continue; + // } + + // // instances.get(object.instanceId)._$update(object); + // } + // break; + + // case "setChildren": + // { + // returnBuffer = false; + + // const buffer: Float32Array = object.buffer; + + // const instances: Map> = $renderPlayer.instances; + // if (!instances.has(buffer[0])) { + // continue; + // } + + // const instance: RenderDisplayObjectImpl = instances.get(buffer[0]); + // instance._$doChanged(); + + // instance._$children = buffer.subarray(1); + // } + // break; + + // case "remove": + // { + // const instances: Map> = $renderPlayer.instances; + // if (!instances.has(object.instanceId)) { + // continue; + // } + + // instances.get(object.instanceId)._$remove(); + // instances.delete(object.instanceId); + // } + // break; + + // case "createShape": + // $renderPlayer._$createShape(object.buffer); + // break; + + // case "createDisplayObjectContainer": + + // $renderPlayer + // ._$createDisplayObjectContainer(object.buffer); + + // break; + + // case "createTextField": + // $renderPlayer._$createTextField(object); + // break; + + // case "createVideo": + // $renderPlayer._$createVideo(object); + // break; + + case "resize": + $renderPlayer._$resize(object.buffer); + break; + + case "initialize": + $renderPlayer._$initialize( + object.buffer, object.canvas + ); + break; + + case "setBackgroundColor": + $renderPlayer._$setBackgroundColor(object.buffer); + break; + + // case "stop": + // $renderPlayer.stop(); + // break; + + // case "removeCache": + // $cacheStore.removeCache(object.id); + // break; + + // case "bitmapDraw": + // { + // const instances: Map> = $renderPlayer.instances; + // if (!instances.has(object.sourceId)) { + // continue; + // } + + // const instance: RenderDisplayObjectImpl = instances.get(object.sourceId); + + // const canvas: OffscreenCanvas = new $OffscreenCanvas( + // object.width, + // object.height + // ); + + // $renderPlayer._$bitmapDraw( + // instance, + // object.matrix || $MATRIX_ARRAY_IDENTITY, + // object.colorTransform || $COLOR_ARRAY_IDENTITY, + // canvas + // ); + + // const imageBitmap: ImageBitmap = canvas.transferToImageBitmap(); + // globalThis.postMessage({ + // "command": "bitmapDraw", + // "sourceId": object.sourceId, + // "imageBitmap": imageBitmap + // // @ts-ignore + // }, [imageBitmap]); + + // } + // break; + + // default: + // if (object.command.indexOf("shapeRecodes") > -1) { + // returnBuffer = false; + // const instanceId: number = +object.command.split("@")[1]; + // $renderPlayer._$registerShapeRecodes(instanceId, object.buffer); + // } + // break; + + } + + if (object.buffer && returnBuffer) { + // this._$options.push(object.buffer.buffer); + + // globalThis.postMessage({ + // "command": "renderBuffer", + // "buffer": object.buffer + // // @ts-ignore + // }, this._$options); + + // reset + this._$options.length = 0; + } + } + + this.state = "deactivate"; + } +} \ No newline at end of file diff --git a/packages/renderer/src/index.ts b/packages/renderer/src/index.ts new file mode 100644 index 00000000..98826cab --- /dev/null +++ b/packages/renderer/src/index.ts @@ -0,0 +1,25 @@ +"use strict"; + +// import { CommandController } from "./CommandController"; + +// const command: CommandController = new CommandController(); + +/** + * @description OffscreenCanvasのメッセージイベント + * OffscreenCanvas message event + * + * @params {MessageEvent} event + * @return {void} + * @method + * @public + */ +self.addEventListener("message", async (event: MessageEvent): Promise => +{ + console.log(event.data); + // command.queue.push(event.data); + // if (command.state === "deactivate") { + // await command.execute(); + // } +}); + +export default {}; \ No newline at end of file diff --git a/packages/util/src/Util.ts b/packages/util/src/Util.ts index ec5747ba..674f481b 100644 --- a/packages/util/src/Util.ts +++ b/packages/util/src/Util.ts @@ -865,12 +865,12 @@ const $resizeExecute = (): void => /** * added resize event */ -$window.addEventListener("resize", (): void => -{ - $clearTimeout($resizeTimerId); - // @ts-ignore - $resizeTimerId = $setTimeout($resizeExecute, 300); -}); +// $window.addEventListener("resize", (): void => +// { +// $clearTimeout($resizeTimerId); +// // @ts-ignore +// $resizeTimerId = $setTimeout($resizeExecute, 300); +// }); /** * @param {AjaxOptionImpl} option diff --git a/src/index.ts b/src/index.ts index 524efa1e..aca33077 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,26 +2,11 @@ import { Next2D } from "@next2d/core"; -/** - * @type {NodeJS.Timeout} - * @private - */ -let $resizeTimerId: NodeJS.Timeout; - if (!("next2d" in window)) { - console.log("%c Next2D Player %c 1.18.12 %c https://next2d.app", "color: #fff; background: #5f5f5f", "color: #fff; background: #4bc729", ""); - window.addEventListener("resize", (): void => - { - clearTimeout($resizeTimerId); - $resizeTimerId = setTimeout(() => { - // TODO: resize event - }, 300); - }); - window.next2d = new Next2D(); } \ No newline at end of file From fbacb7a6062b35f8c037a7da15c25c6c50a32a6d Mon Sep 17 00:00:00 2001 From: ienaga Date: Fri, 2 Aug 2024 09:49:19 +0900 Subject: [PATCH 030/343] =?UTF-8?q?#154=20display=E3=83=91=E3=83=83?= =?UTF-8?q?=E3=82=B1=E3=83=BC=E3=82=B8=E3=81=AE=E7=A7=BB=E6=A4=8D(WIP)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- @types/window.d.ts | 17 - packages/core/src/CoreUtil.ts | 44 +- packages/core/src/Display.ts | 12 +- .../core/src/Next2D/CreateRootMovieClip.ts | 4 +- packages/core/src/Next2D/LoadService.ts | 123 +- packages/core/src/Player.ts | 356 +- .../Player/PlayerResizePostMessageService.ts | 11 +- packages/core/src/interface/DisplayImpl.ts | 12 +- packages/display/src/BlendMode.test.ts | 107 + packages/display/src/BlendMode.ts | 58 +- packages/display/src/DisplayObject.ts | 4118 ++++++++--------- .../DisplayObjectGetPlaceObjectService.ts | 53 + .../DisplayObjectGetRawMatrixService.ts | 47 + .../display/src/DisplayObjectContainer.ts | 4047 ++++++++-------- packages/display/src/DisplayObjectUtil.ts | 289 ++ packages/display/src/FrameLabel.ts | 35 +- packages/display/src/InteractiveObject.ts | 14 +- packages/display/src/Loader.ts | 404 +- .../display/src/Loader/LoaderBuildService.ts | 35 + .../Loader/LoaderLoadEndEventService.test.ts | 93 + .../src/Loader/LoaderLoadEndEventService.ts | 57 + .../src/Loader/LoaderLoadJsonService.ts | 41 + .../LoaderLoadStartEventService.test.ts | 74 + .../src/Loader/LoaderLoadStartEventService.ts | 29 + .../Loader/LoaderProgressEventService.test.ts | 44 + .../src/Loader/LoaderProgressEventService.ts | 22 + .../display/src/Loader/ZlibInflateWorker.ts | 24 + packages/display/src/LoaderInfo.test.ts | 31 + packages/display/src/LoaderInfo.ts | 92 +- packages/display/src/index.ts | 6 +- .../display/src/interface/AjaxEventImpl.ts | 5 + .../display/src/interface/AjaxOptionImpl.ts | 14 + .../display/src/interface/BlendModeImpl.ts | 15 + packages/display/src/interface/Character.ts | 3 + .../display/src/interface/CharacterImpl.ts | 1 + .../src/interface/DictionaryTagImpl.ts | 7 + .../src/interface/DisplayObjectImpl.ts | 3 + .../display/src/interface/FilterArrayImpl.ts | 23 + .../src/interface/LoaderInfoDataImpl.ts | 8 + .../display/src/interface/LoopConfigImpl.ts | 9 + .../display/src/interface/LoopTypeImpl.ts | 5 + .../display/src/interface/NoCodeDataImpl.ts | 8 + packages/display/src/interface/ParentImpl.ts | 3 + .../display/src/interface/PlaceObjectImpl.ts | 15 + .../display/src/interface/StageDataImpl.ts | 6 + .../src/interface/SurfaceFilterImpl.ts | 14 + .../src/interface/URLLoaderDataFormatImpl.ts | 1 + .../src/interface/URLRequestHeaderImpl.ts | 5 + .../src/interface/URLRequestMethodImpl.ts | 1 + packages/geom/src/Matrix.ts | 13 + packages/interface/src/Character.ts | 2 +- packages/media/src/Sound.ts | 11 +- .../Sound/SoundLoadendEventService.test.ts | 2 +- .../src/Sound/SoundLoadendEventService.ts | 4 +- packages/renderer/package.json | 4 +- .../CommandInitializeContextService.test.ts | 67 + .../CommandInitializeContextService.ts | 48 + .../src/Command/CommandResizeService.ts | 77 + packages/renderer/src/CommandController.ts | 46 +- .../renderer/src/RendererDisplayObject.ts | 819 ++++ .../src/RendererDisplayObjectContainer.ts | 783 ++++ packages/renderer/src/RendererGraphics.ts | 1176 +++++ packages/renderer/src/RendererShape.ts | 152 + packages/renderer/src/RendererTextField.ts | 1031 +++++ packages/renderer/src/RendererUtil.ts | 140 + packages/renderer/src/RendererVideo.ts | 452 ++ packages/renderer/src/index.ts | 12 +- .../renderer/src/interface/BlendModeImpl.ts | 15 + packages/renderer/src/interface/GridImpl.ts | 6 + .../src/interface/PropertyMessageImpl.ts | 39 + .../src/interface/PropertyMessageMapImpl.ts | 3 + packages/{display => text}/src/TextField.ts | 0 packages/webgl/src/CanvasToWebGLContext.ts | 162 +- packages/webgl/src/WebGLUtil.ts | 20 + packages/webgl/src/index.ts | 1 + worker/unzip/UnzipWorker.min.js | 1 - worker/unzip/src/index.ts | 12 +- 77 files changed, 10572 insertions(+), 4971 deletions(-) create mode 100644 packages/display/src/BlendMode.test.ts create mode 100644 packages/display/src/DisplayObject/DisplayObjectGetPlaceObjectService.ts create mode 100644 packages/display/src/DisplayObject/DisplayObjectGetRawMatrixService.ts create mode 100644 packages/display/src/DisplayObjectUtil.ts create mode 100644 packages/display/src/Loader/LoaderBuildService.ts create mode 100644 packages/display/src/Loader/LoaderLoadEndEventService.test.ts create mode 100644 packages/display/src/Loader/LoaderLoadEndEventService.ts create mode 100644 packages/display/src/Loader/LoaderLoadJsonService.ts create mode 100644 packages/display/src/Loader/LoaderLoadStartEventService.test.ts create mode 100644 packages/display/src/Loader/LoaderLoadStartEventService.ts create mode 100644 packages/display/src/Loader/LoaderProgressEventService.test.ts create mode 100644 packages/display/src/Loader/LoaderProgressEventService.ts create mode 100644 packages/display/src/Loader/ZlibInflateWorker.ts create mode 100644 packages/display/src/LoaderInfo.test.ts create mode 100644 packages/display/src/interface/AjaxEventImpl.ts create mode 100644 packages/display/src/interface/AjaxOptionImpl.ts create mode 100644 packages/display/src/interface/BlendModeImpl.ts create mode 100644 packages/display/src/interface/Character.ts create mode 100644 packages/display/src/interface/CharacterImpl.ts create mode 100644 packages/display/src/interface/DictionaryTagImpl.ts create mode 100644 packages/display/src/interface/DisplayObjectImpl.ts create mode 100644 packages/display/src/interface/FilterArrayImpl.ts create mode 100644 packages/display/src/interface/LoaderInfoDataImpl.ts create mode 100644 packages/display/src/interface/LoopConfigImpl.ts create mode 100644 packages/display/src/interface/LoopTypeImpl.ts create mode 100644 packages/display/src/interface/NoCodeDataImpl.ts create mode 100644 packages/display/src/interface/ParentImpl.ts create mode 100644 packages/display/src/interface/PlaceObjectImpl.ts create mode 100644 packages/display/src/interface/StageDataImpl.ts create mode 100644 packages/display/src/interface/SurfaceFilterImpl.ts create mode 100644 packages/display/src/interface/URLLoaderDataFormatImpl.ts create mode 100644 packages/display/src/interface/URLRequestHeaderImpl.ts create mode 100644 packages/display/src/interface/URLRequestMethodImpl.ts create mode 100644 packages/renderer/src/Command/CommandInitializeContextService.test.ts create mode 100644 packages/renderer/src/Command/CommandInitializeContextService.ts create mode 100644 packages/renderer/src/Command/CommandResizeService.ts create mode 100644 packages/renderer/src/RendererDisplayObject.ts create mode 100644 packages/renderer/src/RendererDisplayObjectContainer.ts create mode 100644 packages/renderer/src/RendererGraphics.ts create mode 100644 packages/renderer/src/RendererShape.ts create mode 100644 packages/renderer/src/RendererTextField.ts create mode 100644 packages/renderer/src/RendererUtil.ts create mode 100644 packages/renderer/src/RendererVideo.ts create mode 100644 packages/renderer/src/interface/BlendModeImpl.ts create mode 100644 packages/renderer/src/interface/GridImpl.ts create mode 100644 packages/renderer/src/interface/PropertyMessageImpl.ts create mode 100644 packages/renderer/src/interface/PropertyMessageMapImpl.ts rename packages/{display => text}/src/TextField.ts (100%) delete mode 100644 worker/unzip/UnzipWorker.min.js diff --git a/@types/window.d.ts b/@types/window.d.ts index 9540f433..0a9c1852 100644 --- a/@types/window.d.ts +++ b/@types/window.d.ts @@ -6,25 +6,8 @@ declare global { // eslint-disable-next-line no-unused-vars const next2d: Next2D; - // eslint-disable-next-line no-unused-vars - interface Location { - search: string; - origin: string; - } - // eslint-disable-next-line no-unused-vars interface Window { - performance: Performance; - navigator: Navigator; - setTimeout: setTimeout; - Map: Map; - Number: Number; - Array: Array; - document: Document; - location: Location; - isNaN: isNaN; - Math: Math; - Event: Event; next2d?: Next2D; } diff --git a/packages/core/src/CoreUtil.ts b/packages/core/src/CoreUtil.ts index 82f38aab..4e656c59 100644 --- a/packages/core/src/CoreUtil.ts +++ b/packages/core/src/CoreUtil.ts @@ -1,3 +1,12 @@ +// @ts-ignore +import RendererWorker from "@next2d/renderer?worker&inline"; + +/** + * @type {Worker} + * @public + */ +export const $rendererWorker: Worker = new RendererWorker(); + /** * @type {number} * @const @@ -22,15 +31,6 @@ export const $PREFIX: string = "__next2d__"; */ export const $devicePixelRatio: number = window.devicePixelRatio; -// @ts-ignore -import RendererWorker from "@next2d/renderer?worker&inline"; - -/** - * @type {Worker} - * @public - */ -export const $rendererWorker: Worker = new RendererWorker(); - /** * @param {number} value * @param {number} min @@ -54,3 +54,29 @@ export const $clamp = ( : Math.min(Math.max(min, isNaN(number) ? 0 : number), max); }; +/** + * @type {number} + * @public + */ +export let $stageWidth: number = 0; + +/** + * @type {number} + * @public + */ +export let $stageHeight: number = 0; + +/** + * @description ステージサイズを設定 + * Set stage size + * + * @param {number} width + * @return {void} + * @method + * @public + */ +export const $setStageSize = (width: number, height: number): void => +{ + $stageWidth = width; + $stageHeight = height; +}; \ No newline at end of file diff --git a/packages/core/src/Display.ts b/packages/core/src/Display.ts index 2ceea93e..98d10c0d 100644 --- a/packages/core/src/Display.ts +++ b/packages/core/src/Display.ts @@ -1,33 +1,29 @@ import type { DisplayImpl } from "./interface/DisplayImpl"; import { - DisplayObject, - InteractiveObject, - DisplayObjectContainer, Sprite, MovieClip, BitmapData, BlendMode, + DisplayObject, FrameLabel, Graphics, + InteractiveObject, Loader, - LoaderInfo, Shape, Stage, TextField } from "@next2d/display"; const display: DisplayImpl = { - DisplayObject, - InteractiveObject, - DisplayObjectContainer, Sprite, MovieClip, BitmapData, BlendMode, + DisplayObject, FrameLabel, Graphics, + InteractiveObject, Loader, - LoaderInfo, Shape, Stage, TextField diff --git a/packages/core/src/Next2D/CreateRootMovieClip.ts b/packages/core/src/Next2D/CreateRootMovieClip.ts index c926c3ef..ea237fc1 100644 --- a/packages/core/src/Next2D/CreateRootMovieClip.ts +++ b/packages/core/src/Next2D/CreateRootMovieClip.ts @@ -28,9 +28,7 @@ export const execute = async ( $player.height = height | 0; $player.frameRate = fps | 0; - $player - .setOptions(options) - .boot(); + $player.boot(options); const root: Sprite = $stage.addChild(new Sprite()); diff --git a/packages/core/src/Next2D/LoadService.ts b/packages/core/src/Next2D/LoadService.ts index 167b254a..d027824e 100644 --- a/packages/core/src/Next2D/LoadService.ts +++ b/packages/core/src/Next2D/LoadService.ts @@ -2,13 +2,10 @@ import type { PlayerOptionsImpl } from "../interface/PlayerOptionsImpl"; import type { StageDataImpl } from "../interface/StageDataImpl"; import { $player } from "../Player"; import { $clamp } from "../CoreUtil"; -import { - Event, - IOErrorEvent -} from "@next2d/events"; +import { URLRequest } from "@next2d/net"; +import { IOErrorEvent } from "@next2d/events"; import { Loader, - LoaderInfo, $stage } from "@next2d/display"; @@ -22,76 +19,86 @@ import { * @method * @protected */ -export const execute = (url: string, options: PlayerOptionsImpl): Promise => +export const execute = async (url: string, options: PlayerOptionsImpl): Promise => { - return new Promise((resolve: Function) => - { - if (url === "develop") { - const path: string = location - .search - .slice(1) - .split("&")[0]; - - if (!path) { - return ; - } - url = `${location.origin}/${path}`; - } + if (url === "develop") { + const path: string = location + .search + .slice(1) + .split("&")[0]; - if (!url) { + if (!path) { return ; } + url = `${location.origin}/${path}`; + } - if (url.charAt(1) === "/") { - url = url.slice(1); - } + if (!url) { + return ; + } - $player - .setOptions(options) - .boot(); + if (url.charAt(1) === "/") { + url = url.slice(1); + } - const loader: Loader = new Loader(); + $player.boot(options); - loader - .contentLoaderInfo - .addEventListener(IOErrorEvent.IO_ERROR, (event: IOErrorEvent): void => - { - alert("Error: " + event.text); - resolve(); - }); + const loader: Loader = new Loader(); - loader - .contentLoaderInfo - .addEventListener(Event.COMPLETE, (event: Event): void => - { - const loaderInfo: LoaderInfo = event.target as NonNullable; + const loaderInfo = loader.contentLoaderInfo; + loaderInfo.addEventListener(IOErrorEvent.IO_ERROR, (event: IOErrorEvent): void => + { + alert("Error: " + event.text); + }); - if (event.listener) { - loaderInfo - .removeEventListener(Event.COMPLETE, event.listener); - } + // loader + // .contentLoaderInfo + // .addEventListener(Event.COMPLETE, (event: Event): void => + // { + // const loaderInfo: LoaderInfo = event.target as NonNullable; - if (loaderInfo._$data) { + // if (event.listener) { + // loaderInfo + // .removeEventListener(Event.COMPLETE, event.listener); + // } - const stage: StageDataImpl = loaderInfo._$data.stage; + // if (loaderInfo._$data) { - $player.bgColor = stage.bgColor; - // $player._$setBackgroundColor(stage.bgColor); + // const stage: StageDataImpl = loaderInfo._$data.stage; - $stage.addChild(loaderInfo.content); + // $player.bgColor = stage.bgColor; + // // $player._$setBackgroundColor(stage.bgColor); - $player.width = stage.width; - $player.height = stage.height; + // $stage.addChild(loaderInfo.content); - // set fps fixed logic - $player.frameRate = $clamp(+stage.fps, 1, 60, 60); - } + // $player.width = stage.width; + // $player.height = stage.height; - // $player._$resize(); + // // set fps fixed logic + // $player.frameRate = $clamp(+stage.fps, 1, 60, 60); + // } - resolve(); - }); + // // $player._$resize(); - // loader.load(new URLRequest(url)); - }); + // resolve(); + // }); + + await loader.load(new URLRequest(url)); + + if (!loaderInfo.data) { + return ; + } + + const stage: StageDataImpl = loaderInfo.data.stage; + + $player.bgColor = stage.bgColor; + // $player._$setBackgroundColor(stage.bgColor); + + $stage.addChild(loaderInfo.content); + + $player.rendererWidth = stage.width; + $player.rendererHeight = stage.height; + + // set fps fixed logic + $player.frameRate = $clamp(stage.fps, 1, 60, 60); }; \ No newline at end of file diff --git a/packages/core/src/Player.ts b/packages/core/src/Player.ts index 33c7401f..7e3a4ddc 100644 --- a/packages/core/src/Player.ts +++ b/packages/core/src/Player.ts @@ -479,6 +479,35 @@ export class Player this._$rendererScale = renderer_scale; } + /** + * @description フルスクリーンモードの設定 + * Full screen mode setting + * + * @member {boolean} + * @default false + * @public + */ + get fullScreen (): boolean + { + return this._$fullScreen; + } + set fullScreen (full_screen: boolean) + { + if (this._$fullScreen === full_screen) { + return ; + } + + this._$fullScreen = full_screen; + + // display resize + playerResizeEventService( + this, + this._$initialWidth, + this._$initialHeight, + this._$fullScreen + ); + } + /** * @member {string} * @public @@ -555,32 +584,32 @@ export class Player // } } - /** - * @param {string} id - * @return {void} - * @method - * @public - */ - removeCache (id: string): void - { - $cacheStore.removeCache(id); - if ($rendererWorker) { - $rendererWorker.postMessage({ - "command": "removeCache", - "id": id - }); - } - } + // /** + // * @param {string} id + // * @return {void} + // * @method + // * @public + // */ + // removeCache (id: string): void + // { + // $cacheStore.removeCache(id); + // if ($rendererWorker) { + // $rendererWorker.postMessage({ + // "command": "removeCache", + // "id": id + // }); + // } + // } /** * @param {object} [options=null] - * @return {Player} + * @return {void} * @public */ - setOptions (options: PlayerOptionsImpl | null = null): Player + setOptions (options: PlayerOptionsImpl | null = null): void { if (!options) { - return this; + return ; } this._$fixedWidth = options.width || this._$fixedWidth; @@ -588,8 +617,6 @@ export class Player this._$tagId = options.tagId || this._$tagId; this._$bgColor = options.bgColor || this._$bgColor; this._$fullScreen = !!options.fullScreen; - - return this; } /** @@ -600,8 +627,10 @@ export class Player * @method * @public */ - boot (): void + boot (options: PlayerOptionsImpl | null = null): void { + this.setOptions(options); + // create element const element = playerCreateContainerElementService(); @@ -616,9 +645,6 @@ export class Player // start loading playerLoadingAnimationService(element); - // initialize worker - - if (!this._$fixedWidth && !this._$fixedHeight) { // register resize event playerResizeRegisterService( @@ -638,179 +664,179 @@ export class Player ); } - /** - * @return {void} - * @method - * @private - */ - _$updateLoadStatus (): void - { - if (this._$loadStatus === $LOAD_END) { - if (this._$loadId > -1) { - $cancelAnimationFrame(this._$loadId); - } + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$updateLoadStatus (): void + // { + // if (this._$loadStatus === $LOAD_END) { + // if (this._$loadId > -1) { + // $cancelAnimationFrame(this._$loadId); + // } - this._$loadId = -1; - this._$loaded(); - return ; - } + // this._$loadId = -1; + // this._$loaded(); + // return ; + // } - this._$loadId = $requestAnimationFrame(() => - { - this._$updateLoadStatus(); - }); - } + // this._$loadId = $requestAnimationFrame(() => + // { + // this._$updateLoadStatus(); + // }); + // } - /** - * @return {void} - * @method - * @private - */ - _$loaded (): void - { - const element: HTMLElement | null = $document - .getElementById($PREFIX); + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$loaded (): void + // { + // const element: HTMLElement | null = $document + // .getElementById($PREFIX); - if (element) { + // if (element) { - // background color - this._$setBackgroundColor(this._$bgColor); + // // background color + // this._$setBackgroundColor(this._$bgColor); - // DOM - this._$deleteNode(); + // // DOM + // this._$deleteNode(); - // append canvas - element.appendChild(this._$canvas); - element.appendChild($textArea); + // // append canvas + // element.appendChild(this._$canvas); + // element.appendChild($textArea); - // stage init action - this._$stage._$prepareActions(); + // // stage init action + // this._$stage._$prepareActions(); - // constructed event - if (this._$broadcastEvents.has(Next2DEvent.FRAME_CONSTRUCTED)) { - this._$dispatchEvent(new Next2DEvent(Next2DEvent.FRAME_CONSTRUCTED)); - } + // // constructed event + // if (this._$broadcastEvents.has(Next2DEvent.FRAME_CONSTRUCTED)) { + // this._$dispatchEvent(new Next2DEvent(Next2DEvent.FRAME_CONSTRUCTED)); + // } - // frame1 action - this._$doAction(); + // // frame1 action + // this._$doAction(); - // exit event - if (this._$broadcastEvents.has(Next2DEvent.EXIT_FRAME)) { - this._$dispatchEvent(new Next2DEvent(Next2DEvent.EXIT_FRAME)); - } + // // exit event + // if (this._$broadcastEvents.has(Next2DEvent.EXIT_FRAME)) { + // this._$dispatchEvent(new Next2DEvent(Next2DEvent.EXIT_FRAME)); + // } - // loader events - const length: number = this._$loaders.length; - for (let idx: number = 0; idx < length; ++idx) { + // // loader events + // const length: number = this._$loaders.length; + // for (let idx: number = 0; idx < length; ++idx) { - const loader: EventDispatcherImpl = this._$loaders.shift(); + // const loader: EventDispatcherImpl = this._$loaders.shift(); - // init event - if (loader.hasEventListener(Next2DEvent.INIT)) { - loader.dispatchEvent(new Next2DEvent(Next2DEvent.INIT)); - } + // // init event + // if (loader.hasEventListener(Next2DEvent.INIT)) { + // loader.dispatchEvent(new Next2DEvent(Next2DEvent.INIT)); + // } - // complete event - if (loader.hasEventListener(Next2DEvent.COMPLETE)) { - loader.dispatchEvent(new Next2DEvent(Next2DEvent.COMPLETE)); - } - } + // // complete event + // if (loader.hasEventListener(Next2DEvent.COMPLETE)) { + // loader.dispatchEvent(new Next2DEvent(Next2DEvent.COMPLETE)); + // } + // } - // activate event - if (this._$broadcastEvents.has(Next2DEvent.ACTIVATE)) { - this._$dispatchEvent(new Next2DEvent(Next2DEvent.ACTIVATE)); - } + // // activate event + // if (this._$broadcastEvents.has(Next2DEvent.ACTIVATE)) { + // this._$dispatchEvent(new Next2DEvent(Next2DEvent.ACTIVATE)); + // } - // frame action - this._$doAction(); + // // frame action + // this._$doAction(); - // render - this._$draw(); + // // render + // this._$draw(); - // start - this.play(); - } + // // start + // this.play(); + // } - } + // } - /** - * @return {void} - * @method - * @private - */ - _$initialize (): void - { - if (!this._$tagId) { + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$initialize (): void + // { + // if (!this._$tagId) { - $document - .body - .insertAdjacentHTML( - "beforeend", `
` - ); + // $document + // .body + // .insertAdjacentHTML( + // "beforeend", `
` + // ); - } else { + // } else { - const container: HTMLElement | null = $document.getElementById(this._$tagId); - if (!container) { - alert("Not Found Tag ID:" + this._$tagId); - return ; - } + // const container: HTMLElement | null = $document.getElementById(this._$tagId); + // if (!container) { + // alert("Not Found Tag ID:" + this._$tagId); + // return ; + // } - const div: HTMLElement | null = $document.getElementById($PREFIX); - if (!div) { + // const div: HTMLElement | null = $document.getElementById($PREFIX); + // if (!div) { - const element: HTMLDivElement = $document.createElement("div"); - element.id = $PREFIX; - element.tabIndex = -1; - container.appendChild(element); + // const element: HTMLDivElement = $document.createElement("div"); + // element.id = $PREFIX; + // element.tabIndex = -1; + // container.appendChild(element); - } else { + // } else { - this._$deleteNode(); + // this._$deleteNode(); - } + // } - } + // } - const element: HTMLElement | null = $document.getElementById($PREFIX); - if (!element) { - throw new Error("the content element is null."); - } + // const element: HTMLElement | null = $document.getElementById($PREFIX); + // if (!element) { + // throw new Error("the content element is null."); + // } - const parent: HTMLElement | null = element.parentElement; - if (parent) { - - this._$initStyle(element); - this._$buildWait(); - - const width: number = this._$fixedWidth - ? this._$fixedWidth - : parent.tagName === "BODY" - ? window.innerWidth - : parent.clientWidth; - - const height: number = this._$fixedHeight - ? this._$fixedHeight - : parent.tagName === "BODY" - ? window.innerHeight - : parent.clientHeight; - - // set center - if (this._$mode === "loader" && width && height) { - this._$baseWidth = width; - this._$baseHeight = height; - this._$resize(); - } - } + // const parent: HTMLElement | null = element.parentElement; + // if (parent) { - if (this._$mode === "loader") { - this._$loadStatus = $LOAD_START; - this._$updateLoadStatus(); - } else { - this._$resize(); - this._$loaded(); - } - } + // this._$initStyle(element); + // this._$buildWait(); + + // const width: number = this._$fixedWidth + // ? this._$fixedWidth + // : parent.tagName === "BODY" + // ? window.innerWidth + // : parent.clientWidth; + + // const height: number = this._$fixedHeight + // ? this._$fixedHeight + // : parent.tagName === "BODY" + // ? window.innerHeight + // : parent.clientHeight; + + // // set center + // if (this._$mode === "loader" && width && height) { + // this._$baseWidth = width; + // this._$baseHeight = height; + // this._$resize(); + // } + // } + + // if (this._$mode === "loader") { + // this._$loadStatus = $LOAD_START; + // this._$updateLoadStatus(); + // } else { + // this._$resize(); + // this._$loaded(); + // } + // } // /** // * @returns {void} diff --git a/packages/core/src/Player/PlayerResizePostMessageService.ts b/packages/core/src/Player/PlayerResizePostMessageService.ts index d5950a8f..eaad7ce4 100644 --- a/packages/core/src/Player/PlayerResizePostMessageService.ts +++ b/packages/core/src/Player/PlayerResizePostMessageService.ts @@ -1,6 +1,10 @@ import type { Player } from "../Player"; import type { ResizeMessageImpl } from "../interface/ResizeMessageImpl"; -import { $rendererWorker } from "../CoreUtil"; +import { + $rendererWorker, + $stageWidth, + $stageHeight +} from "../CoreUtil"; /** * @description リサイズメッセージ @@ -38,7 +42,10 @@ export const execute = (player: Player): void => message.buffer = new Float32Array([ player.rendererScale, player.rendererWidth, - player.rendererHeight + player.rendererHeight, + $stageWidth, + $stageHeight, + player.fullScreen ? 1 : 0 ]); options[0] = message.buffer.buffer; diff --git a/packages/core/src/interface/DisplayImpl.ts b/packages/core/src/interface/DisplayImpl.ts index 8f4369ca..099ea16e 100644 --- a/packages/core/src/interface/DisplayImpl.ts +++ b/packages/core/src/interface/DisplayImpl.ts @@ -1,13 +1,11 @@ import type { - DisplayObject, - InteractiveObject, - DisplayObjectContainer, BitmapData, BlendMode, + DisplayObject, FrameLabel, Graphics, + InteractiveObject, Loader, - LoaderInfo, MovieClip, Shape, Sprite, @@ -15,15 +13,13 @@ import type { TextField } from "@next2d/display"; export interface DisplayImpl { - DisplayObject: typeof DisplayObject; - InteractiveObject: typeof InteractiveObject; - DisplayObjectContainer: typeof DisplayObjectContainer; BitmapData: typeof BitmapData; BlendMode: typeof BlendMode; + DisplayObject: typeof DisplayObject; FrameLabel: typeof FrameLabel; Graphics: typeof Graphics; + InteractiveObject: typeof InteractiveObject; Loader: typeof Loader; - LoaderInfo: typeof LoaderInfo; MovieClip: typeof MovieClip; Shape: typeof Shape; Sprite: typeof Sprite; diff --git a/packages/display/src/BlendMode.test.ts b/packages/display/src/BlendMode.test.ts new file mode 100644 index 00000000..c4bfd228 --- /dev/null +++ b/packages/display/src/BlendMode.test.ts @@ -0,0 +1,107 @@ +import { BlendMode } from "./BlendMode"; +import { describe, expect, it } from "vitest"; + +describe("BlendMode.js toString test", () => +{ + it("toString test case1", () => + { + const blendMode = new BlendMode(); + expect(blendMode.toString()) + .toBe("[object BlendMode]"); + }); +}); + +describe("BlendMode.js static toString test", () => +{ + it("static toString test", () => + { + expect(BlendMode.toString()).toBe("[class BlendMode]"); + }); +}); + +describe("BlendMode.js namespace test", () => +{ + it("namespace test public", () => + { + const blendMode = new BlendMode(); + expect(blendMode.namespace).toBe("next2d.display.BlendMode"); + }); + + it("namespace test static", () => + { + expect(BlendMode.namespace).toBe("next2d.display.BlendMode"); + }); +}); + +describe("BlendMode.js property test", () => +{ + it("ADD test", () => + { + expect(BlendMode.ADD).toBe("add"); + }); + + it("ALPHA test", () => + { + expect(BlendMode.ALPHA).toBe("alpha"); + }); + + it("DARKEN test", () => + { + expect(BlendMode.DARKEN).toBe("darken"); + }); + + it("DIFFERENCE test", () => + { + expect(BlendMode.DIFFERENCE).toBe("difference"); + }); + + it("ERASE test", () => + { + expect(BlendMode.ERASE).toBe("erase"); + }); + + it("HARDLIGHT test", () => + { + expect(BlendMode.HARDLIGHT).toBe("hardlight"); + }); + + it("INVERT test", () => + { + expect(BlendMode.INVERT).toBe("invert"); + }); + + it("LAYER test", () => + { + expect(BlendMode.LAYER).toBe("layer"); + }); + + it("LIGHTEN test", () => + { + expect(BlendMode.LIGHTEN).toBe("lighten"); + }); + + it("MULTIPLY test", () => + { + expect(BlendMode.MULTIPLY).toBe("multiply"); + }); + + it("NORMAL test", () => + { + expect(BlendMode.NORMAL).toBe("normal"); + }); + + it("OVERLAY test", () => + { + expect(BlendMode.OVERLAY).toBe("overlay"); + }); + + it("SCREEN test", () => + { + expect(BlendMode.SCREEN).toBe("screen"); + }); + + it("SUBTRACT test", () => + { + expect(BlendMode.SUBTRACT).toBe("subtract"); + }); +}); \ No newline at end of file diff --git a/packages/display/src/BlendMode.ts b/packages/display/src/BlendMode.ts index dc2effa9..74f6f93d 100644 --- a/packages/display/src/BlendMode.ts +++ b/packages/display/src/BlendMode.ts @@ -1,14 +1,8 @@ /** - * ブレンドモードの視覚効果のために定数値を提供するクラスです。 - * 全てのDisplayObjectに設定が可能です。 - * A class that provides constant values for visual blend mode effects. - * It can be set for all DisplayObjects. - * - * @example usage of BlendMode. - * // static BlendMode - * const {BlendMode, MovieClip} = next2d.display; - * const movieClip = new MovieClip(); - * movieClip.blendMode = BlendMode.ADD; + * @description ブレンドモードの視覚効果のために定数値を提供するクラスです。 + * 全てのDisplayObjectに設定が可能です。 + * A class that provides constant values for visual blend mode effects. + * It can be set for all DisplayObjects. * * @class * @memberOf next2d.display @@ -21,11 +15,11 @@ export class BlendMode * Returns the string representation of the specified class. * * @return {string} - * @default [class BlendMode] + * @default "[class BlendMode]" * @method * @static */ - static toString () + static toString (): string { return "[class BlendMode]"; } @@ -35,11 +29,11 @@ export class BlendMode * Returns the space name of the specified class. * * @return {string} - * @default next2d.display.BlendMode + * @default "next2d.display.BlendMode" * @const * @static */ - static get namespace () + static get namespace (): string { return "next2d.display.BlendMode"; } @@ -49,11 +43,11 @@ export class BlendMode * Returns the string representation of the specified object. * * @return {string} - * @default [object BlendMode] + * @default "[object BlendMode]" * @method * @public */ - toString () + toString (): string { return "[object BlendMode]"; } @@ -63,11 +57,11 @@ export class BlendMode * Returns the space name of the specified object. * * @return {string} - * @default next2d.display.BlendMode + * @default "next2d.display.BlendMode" * @const * @public */ - get namespace () + get namespace (): string { return "next2d.display.BlendMode"; } @@ -82,7 +76,7 @@ export class BlendMode * @const * @static */ - static get ADD () + static get ADD (): string { return "add"; } @@ -96,7 +90,7 @@ export class BlendMode * @const * @static */ - static get ALPHA () + static get ALPHA (): string { return "alpha"; } @@ -111,7 +105,7 @@ export class BlendMode * @const * @static */ - static get DARKEN () + static get DARKEN (): string { return "darken"; } @@ -126,7 +120,7 @@ export class BlendMode * @const * @static */ - static get DIFFERENCE () + static get DIFFERENCE (): string { return "difference"; } @@ -140,7 +134,7 @@ export class BlendMode * @const * @static */ - static get ERASE () + static get ERASE (): string { return "erase"; } @@ -154,7 +148,7 @@ export class BlendMode * @const * @static */ - static get HARDLIGHT () + static get HARDLIGHT (): string { return "hardlight"; } @@ -168,7 +162,7 @@ export class BlendMode * @const * @static */ - static get INVERT () + static get INVERT (): string { return "invert"; } @@ -182,7 +176,7 @@ export class BlendMode * @const * @static */ - static get LAYER () + static get LAYER (): string { return "layer"; } @@ -197,7 +191,7 @@ export class BlendMode * @const * @static */ - static get LIGHTEN () + static get LIGHTEN (): string { return "lighten"; } @@ -212,7 +206,7 @@ export class BlendMode * @const * @static */ - static get MULTIPLY () + static get MULTIPLY (): string { return "multiply"; } @@ -226,7 +220,7 @@ export class BlendMode * @const * @static */ - static get NORMAL () + static get NORMAL (): string { return "normal"; } @@ -240,7 +234,7 @@ export class BlendMode * @const * @static */ - static get OVERLAY () + static get OVERLAY (): string { return "overlay"; } @@ -255,7 +249,7 @@ export class BlendMode * @const * @static */ - static get SCREEN () + static get SCREEN (): string { return "screen"; } @@ -270,7 +264,7 @@ export class BlendMode * @const * @static */ - static get SUBTRACT () + static get SUBTRACT (): string { return "subtract"; } diff --git a/packages/display/src/DisplayObject.ts b/packages/display/src/DisplayObject.ts index 9983220a..f888c913 100644 --- a/packages/display/src/DisplayObject.ts +++ b/packages/display/src/DisplayObject.ts @@ -5,79 +5,31 @@ import { Event as Next2DEvent, EventDispatcher } from "@next2d/events"; +// import { +// Transform, +// Rectangle, +// Point, +// ColorTransform, +// Matrix +// } from "@next2d/geom"; +// import type { +// CanvasToWebGLContext, +// FrameBufferManager +// } from "@next2d/webgl"; import { - Transform, - Rectangle, - Point, - ColorTransform, - Matrix -} from "@next2d/geom"; -import type { - FilterArrayImpl, - BlendModeImpl, - ParentImpl, - PlaceObjectImpl, - BoundsImpl, - DictionaryTagImpl, - PropertyMessageMapImpl, - DisplayObjectImpl, - AttachmentImpl, - PropertyMessageImpl, - CachePositionImpl -} from "@next2d/interface"; -import type { - CanvasToWebGLContext, - FrameBufferManager -} from "@next2d/webgl"; -import { - $getEvent, - $getInstanceId, - $currentMousePoint, - $poolColorTransform, - $rendererWorker, - $poolMatrix, - $hitContext, - $variables, - $blendToNumber -} from "@next2d/util"; -import { - $doUpdated, - $clamp, - $getArray, - $boundsMatrix, - $Math, - $poolBoundsObject, - $Infinity, - $getBoundsObject, - $isNaN, - $Deg2Rad, - $Number, - $Rad2Deg, - $SHORT_INT_MIN, - $SHORT_INT_MAX, - $MATRIX_ARRAY_IDENTITY, - $multiplicationMatrix, - $poolFloat32Array6, - $getMap, - $poolMap, - $getFloat32Array6, - $devicePixelRatio, - $poolArray, - $cacheStore -} from "@next2d/share"; + $getInstanceId +} from "./DisplayObjectUtil"; /** - * DisplayObject クラスは、表示リストに含めることのできるすべてのオブジェクトに関する基本クラスです。 - * DisplayObject クラス自体は、画面上でのコンテンツの描画のための API を含みません。 - * そのため、DisplayObject クラスのカスタムサブクラスを作成する場合は、 - * Shape、Sprite、Bitmap、TextField または MovieClip など、 - * 画面上にコンテンツを描画する API を持つサブクラスの 1 つを拡張する必要があります。 + * @description DisplayObject クラスは、表示リストに含めることのできるすべてのオブジェクトに関する基本クラスです。 + * DisplayObject クラス自体は、画面上でのコンテンツの描画のための API を含みません。 + * そのため、DisplayObject クラスのカスタムサブクラスを作成する場合は、 + * Shape、Sprite、TextField または MovieClip など、画面上にコンテンツを描画する API を持つサブクラスの 1 つを拡張する必要があります。 * - * The DisplayObject class is the base class for all objects that can be placed on the display list. - * The DisplayObject class itself does not include any APIs for rendering content onscreen. - * For that reason, if you want create a custom subclass of the DisplayObject class, - * you will want to extend one of its subclasses that do have APIs for rendering content onscreen, - * such as the Shape, Sprite, Bitmap, TextField, or MovieClip class. + * The DisplayObject class is the base class for all objects that can be placed on the display list. + * The DisplayObject class itself does not include any APIs for rendering content onscreen. + * For that reason, if you want create a custom subclass of the DisplayObject class, + * you will want to extend one of its subclasses that do have APIs for rendering content onscreen, such as the Shape, Sprite, TextField, or MovieClip class. * * @class * @memberOf next2d.display @@ -85,7 +37,7 @@ import { */ export class DisplayObject extends EventDispatcher { - public readonly _$instanceId: number; + protected readonly _$instanceId: number; protected _$id: number; protected _$stage: Stage | null; protected _$parent: ParentImpl | null; @@ -93,13 +45,13 @@ export class DisplayObject extends EventDispatcher protected _$characterId: number; protected _$active: boolean; protected _$isMask: boolean; - public _$updated: boolean; + protected _$updated: boolean; protected _$added: boolean; protected _$addedStage: boolean; protected _$filters: FilterArrayImpl | null; protected _$blendMode: BlendModeImpl | null; protected _$transform: Transform; - public _$hitObject: Sprite | null; + protected _$hitObject: Sprite | null; protected _$isNext: boolean; protected _$created: boolean; protected _$posted: boolean; @@ -108,7 +60,7 @@ export class DisplayObject extends EventDispatcher protected _$mask: DisplayObjectImpl | null; protected _$visible: boolean; protected _$root: ParentImpl | null; - public _$loaderInfo: LoaderInfo | null; + protected _$loaderInfo: LoaderInfo | null; protected _$scaleX: number | null; protected _$scaleY: number | null; protected _$variables: Map | null; @@ -315,11 +267,11 @@ export class DisplayObject extends EventDispatcher */ this._$endFrame = 0; - /** - * @type {Transform} - * @private - */ - this._$transform = new Transform(this); + // /** + // * @type {Transform} + // * @private + // */ + // this._$transform = new Transform(this); /** * @type {Map} @@ -420,2013 +372,2013 @@ export class DisplayObject extends EventDispatcher } } - /** - * @description 使用するブレンドモードを指定する BlendMode クラスの値です。 - * A value from the BlendMode class that specifies which blend mode to use. - * - * @member {string} - * @default BlendMode.NORMAL - * @public - */ - get blendMode (): BlendModeImpl - { - // use cache - if (this._$blendMode) { - return this._$blendMode; - } - - const transform: Transform = this._$transform; - if (transform._$blendMode) { - - // cache - this._$blendMode = transform._$blendMode; - - return transform._$blendMode; - } - - const placeObject: PlaceObjectImpl | null = this._$placeObject || this._$getPlaceObject(); - if (placeObject && placeObject.blendMode) { - - // cache - this._$blendMode = placeObject.blendMode; - - return placeObject.blendMode; - } - - // cache - this._$blendMode = "normal"; - - return "normal"; - } - set blendMode (blend_mode: BlendModeImpl) - { - const transform: Transform = this._$transform; - if (!transform._$blendMode) { - transform._$transform(null, null, null, blend_mode); - } else { - transform._$blendMode = blend_mode; - this._$doChanged(); - $doUpdated(); - } - this._$blendMode = blend_mode; - } - - /** - * @description 表示オブジェクトに現在関連付けられている各フィルターオブジェクトが - * 格納されているインデックス付きの配列です。 - * An indexed array that contains each filter object - * currently associated with the display object. - * - * @member {array} - * @default {array} - * @public - */ - get filters (): FilterArrayImpl - { - // use cache - if (this._$filters) { - const filters: FilterArrayImpl = $getArray(); - for (let idx: number = 0; idx < this._$filters.length; ++idx) { - filters[idx] = this._$filters[idx].clone(); - } - return filters; - } - - const transform: Transform = this._$transform; - if (transform._$filters) { - - const clone: FilterArrayImpl = $getArray(); - const filters: FilterArrayImpl = $getArray(); - for (let idx: number = 0; idx < transform._$filters.length; ++idx) { - const filter = transform._$filters[idx]; - clone[idx] = filter.clone(); - filters[idx] = filter.clone(); - } - - // cache - this._$filters = clone; - - return filters; - } - - const placeObject: PlaceObjectImpl | null = this._$placeObject || this._$getPlaceObject(); - if (placeObject && placeObject.surfaceFilterList) { - - // create filter - if (!placeObject.filters) { - placeObject.filters = transform - ._$buildFilter(placeObject.surfaceFilterList); - } - - const clone: FilterArrayImpl = $getArray(); - - // @ts-ignore - const filters: FilterArrayImpl = $getArray(); - for (let idx: number = 0; idx < placeObject.filters.length; ++idx) { - const filter = placeObject.filters[idx]; - clone[idx] = filter.clone(); - filters[idx] = filter.clone(); - } - - // cache - this._$filters = clone; - - return filters; - } - - const filters: FilterArrayImpl = $getArray(); - - // cache - this._$filters = filters; - - return filters; - } - set filters (filters: FilterArrayImpl | null) - { - if (!filters) { - filters = $getArray(); - } - - this._$transform._$transform(null, null, filters); - this._$filters = filters; - } - - /** - * @description 表示オブジェクトの高さを示します(ピクセル単位)。 - * Indicates the height of the display object, in pixels. - * - * @member {number} - * @public - */ - get height (): number - { - const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" - ? this._$getBounds() as BoundsImpl - : $getBoundsObject(); - - const bounds: BoundsImpl = $boundsMatrix( - baseBounds, - this._$transform._$rawMatrix() - ); - $poolBoundsObject(baseBounds); - - const height: number = $Math.abs(bounds.yMax - bounds.yMin); - - // object pool - $poolBoundsObject(bounds); - - switch (height) { - - case 0: - case $Infinity: - case -$Infinity: - return 0; - - default: - return +height.toFixed(2); - - } - } - set height (height: number) - { - height = +height; - if (!$isNaN(height) && height > -1) { - - const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" - ? this._$getBounds() as BoundsImpl - : $getBoundsObject(); - - const rotation: number = this.rotation; - const bounds: BoundsImpl = rotation - ? $boundsMatrix(baseBounds, this._$transform._$rawMatrix()) - : baseBounds; - - if (rotation) { - $poolBoundsObject(baseBounds); - } - - const exHeight: number = $Math.abs(bounds.yMax - bounds.yMin); - $poolBoundsObject(bounds); - - switch (exHeight) { - - case 0: - case $Infinity: - case -$Infinity: - this.scaleY = 0; - break; - - default: - this.scaleY = height / exHeight; - break; - - } - } - } - - /** - * @description この表示オブジェクトが属するファイルの読み込み情報を含む LoaderInfo オブジェクトを返します。 - * Returns a LoaderInfo object containing information - * about loading the file to which this display object belongs. - * - * @member {LoaderInfo} - * @default null - * @readonly - * @public - */ - get loaderInfo (): LoaderInfo | null - { - return this._$loaderInfo; - } - - /** - * @description 呼び出し元の表示オブジェクトは、指定された mask オブジェクトによってマスクされます。 - * The calling display object is masked by the specified mask object. - * - * @member {DisplayObject|null} - * @public - */ - get mask (): DisplayObjectImpl | null - { - return this._$mask; - } - set mask (mask: DisplayObjectImpl | null) - { - if (mask === this._$mask) { - return ; - } - - // reset - if (this._$mask) { - if ($rendererWorker && this._$mask.stage) { - this._$mask._$removeWorkerInstance(); - } - - this._$mask._$isMask = false; - this._$mask = null; - } - - if (mask) { - if ($rendererWorker - && "_$createWorkerInstance" in mask - && typeof mask._$createWorkerInstance === "function" - ) { - mask._$createWorkerInstance(); - } - - mask._$isMask = true; - this._$mask = mask; - } - - this._$doChanged(); - } - - /** - * @description マウスまたはユーザー入力デバイスの x 軸の位置をピクセルで示します。 - * Indicates the x coordinate of the mouse or user input device position, in pixels. - * - * @member {number} - * @default 0 - * @readonly - * @public - */ - get mouseX (): number - { - return $getEvent() - ? this.globalToLocal($currentMousePoint()).x - : 0; - } - - /** - * @description マウスまたはユーザー入力デバイスの y 軸の位置をピクセルで示します。 - * Indicates the y coordinate of the mouse or user input device position, in pixels. - * - * @member {number} - * @default 0 - * @readonly - * @public - */ - get mouseY (): number - { - return $getEvent() - ? this.globalToLocal($currentMousePoint()).y - : 0; - } - - /** - * @description DisplayObject のインスタンス名を示します。 - * Indicates the instance name of the DisplayObject. - * - * @member {string} - * @public - */ - get name (): string - { - if (this._$name) { - return this._$name; - } - return `instance${this._$instanceId}`; - } - set name (name: string) - { - this._$name = `${name}`; - - const parent: ParentImpl | null = this._$parent; - if (parent && parent._$names) { - - parent._$names.clear(); - - const children: DisplayObjectImpl[] = parent._$getChildren(); - for (let idx: number = 0; idx < children.length; ++idx) { - const child: DisplayObjectImpl = children[idx]; - if (child._$name) { - parent._$names.set(child.name, child); - } - } - } - } - - /** - * @description この表示オブジェクトを含む DisplayObjectContainer オブジェクトを示します。 - * Indicates the DisplayObjectContainer object that contains this display object. - * - * @member {DisplayObjectContainer | null} - * @readonly - * @public - */ - get parent (): ParentImpl | null - { - return this._$parent; - } - - /** - * @description 読み込まれた SWF ファイル内の表示オブジェクトの場合、 - * root プロパティはその SWF ファイルが表す表示リストのツリー構造部分の一番上にある表示オブジェクトとなります。 - * For a display object in a loaded SWF file, - * the root property is the top-most display object - * in the portion of the display list's tree structure represented by that SWF file. - * - * @member {DisplayObject|null} - * @readonly - * @public - */ - get root (): ParentImpl - { - return this._$root; - } - - /** - * @description DisplayObject インスタンスの元の位置からの回転角を度単位で示します。 - * Indicates the rotation of the DisplayObject instance, - * in degrees, from its original orientation. - * - * @member {number} - * @public - */ - get rotation (): number - { - if (this._$rotation !== null) { - return this._$rotation; - } - - const matrix: Float32Array = this._$transform._$rawMatrix(); - return $Math.atan2(matrix[1], matrix[0]) * $Rad2Deg; - } - set rotation (rotation: number) - { - rotation = $clamp(rotation % 360, 0 - 360, 360, 0); - if (this._$rotation === rotation) { - return ; - } - - const transform: Transform = this._$transform; - - const hasMatrix: boolean = transform._$matrix !== null; - - const matrix: Matrix = hasMatrix - ? transform._$matrix as NonNullable - : transform.matrix; - - const scaleX: number = $Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b); - const scaleY: number = $Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d); - if (rotation === 0) { - - matrix.a = scaleX; - matrix.b = 0; - matrix.c = 0; - matrix.d = scaleY; - - } else { - - let radianX: number = $Math.atan2(matrix.b, matrix.a); - let radianY: number = $Math.atan2(0 - matrix.c, matrix.d); - - const radian: number = rotation * $Deg2Rad; - radianY = radianY + radian - radianX; - radianX = radian; - - matrix.b = scaleX * $Math.sin(radianX); - if (matrix.b === 1 || matrix.b === -1) { - matrix.a = 0; - } else { - matrix.a = scaleX * $Math.cos(radianX); - } - - matrix.c = -scaleY * $Math.sin(radianY); - if (matrix.c === 1 || matrix.c === -1) { - matrix.d = 0; - } else { - matrix.d = scaleY * $Math.cos(radianY); - } - } - - if (hasMatrix) { - this._$doChanged(); - $doUpdated(); - } else { - transform.matrix = matrix; - $poolMatrix(matrix); - } - - this._$rotation = rotation; - } - - /** - * @description 現在有効な拡大 / 縮小グリッドです。 - * The current scaling grid that is in effect. - * - * @member {Rectangle} - * @public - */ - get scale9Grid (): Rectangle | null - { - return this._$scale9Grid; - } - set scale9Grid (scale_9_grid: Rectangle | null) - { - if (this._$scale9Grid !== scale_9_grid) { - this._$scale9Grid = scale_9_grid; - this._$doChanged(); - $doUpdated(); - } - } - - /** - * @description 基準点から適用されるオブジェクトの水平スケール(パーセンテージ)を示します。 - * Indicates the horizontal scale (percentage) - * of the object as applied from the registration point. - * - * @member {number} - * @public - */ - get scaleX (): number - { - if (this._$scaleX !== null) { - return this._$scaleX; - } - - const matrix: Float32Array = this._$transform._$rawMatrix(); - - let xScale: number = $Math.sqrt( - matrix[0] * matrix[0] - + matrix[1] * matrix[1] - ); - if (!$Number.isInteger(xScale)) { - const value: string = xScale.toString(); - const index: number = value.indexOf("e"); - if (index !== -1) { - xScale = +value.slice(0, index); - } - xScale = +xScale.toFixed(4); - } - - return 0 > matrix[0] ? xScale * -1 : xScale; - } - set scaleX (scale_x: number) - { - scale_x = $clamp(+scale_x, - $SHORT_INT_MIN, $SHORT_INT_MAX - ); - - if (!$Number.isInteger(scale_x)) { - const value: string = scale_x.toString(); - const index: number = value.indexOf("e"); - if (index !== -1) { - scale_x = +value.slice(0, index); - } - scale_x = +scale_x.toFixed(4); - } - - if (this._$scaleX === scale_x) { - return ; - } - - const transform: Transform = this._$transform; - - const hasMatrix: boolean = transform._$matrix !== null; - - const matrix: Matrix = hasMatrix - ? transform._$matrix as NonNullable - : transform.matrix; - - if (matrix.b === 0 || $isNaN(matrix.b)) { - - matrix.a = scale_x; - - } else { - - let radianX = $Math.atan2(matrix.b, matrix.a); - if (radianX === -$Math.PI) { - radianX = 0; - } - - matrix.b = scale_x * $Math.sin(radianX); - matrix.a = scale_x * $Math.cos(radianX); - - } - - if (hasMatrix) { - this._$doChanged(); - $doUpdated(); - } else { - transform.matrix = matrix; - $poolMatrix(matrix); - } - - this._$scaleX = scale_x; - } - - /** - * @description 基準点から適用されるオブジェクトの垂直スケール(パーセンテージ)を示します。 - * IIndicates the vertical scale (percentage) - * of an object as applied from the registration point. - * - * @member {number} - * @public - */ - get scaleY (): number - { - if (this._$scaleY !== null) { - return this._$scaleY; - } - - const matrix: Float32Array = this._$transform._$rawMatrix(); - - let yScale: number = $Math.sqrt( - matrix[2] * matrix[2] - + matrix[3] * matrix[3] - ); - - if (!$Number.isInteger(yScale)) { - const value: string = yScale.toString(); - const index: number = value.indexOf("e"); - if (index !== -1) { - yScale = +value.slice(0, index); - } - yScale = +yScale.toFixed(4); - } - - return 0 > matrix[3] ? yScale * -1 : yScale; - } - set scaleY (scale_y: number) - { - scale_y = $clamp(+scale_y, - $SHORT_INT_MIN, $SHORT_INT_MAX - ); - - if (!$Number.isInteger(scale_y)) { - const value: string = scale_y.toString(); - const index: number = value.indexOf("e"); - if (index !== -1) { - scale_y = +value.slice(0, index); - } - scale_y = +scale_y.toFixed(4); - } - - if (this._$scaleY === scale_y) { - return ; - } - - const transform: Transform = this._$transform; - - const hasMatrix: boolean = transform._$matrix !== null; - - const matrix: Matrix = hasMatrix - ? transform._$matrix as NonNullable - : transform.matrix; - - if (matrix.c === 0 || $isNaN(matrix.c)) { + // /** + // * @description 使用するブレンドモードを指定する BlendMode クラスの値です。 + // * A value from the BlendMode class that specifies which blend mode to use. + // * + // * @member {string} + // * @default BlendMode.NORMAL + // * @public + // */ + // get blendMode (): BlendModeImpl + // { + // // use cache + // if (this._$blendMode) { + // return this._$blendMode; + // } + + // const transform: Transform = this._$transform; + // if (transform._$blendMode) { + + // // cache + // this._$blendMode = transform._$blendMode; + + // return transform._$blendMode; + // } + + // const placeObject: PlaceObjectImpl | null = this._$placeObject || this._$getPlaceObject(); + // if (placeObject && placeObject.blendMode) { + + // // cache + // this._$blendMode = placeObject.blendMode; + + // return placeObject.blendMode; + // } + + // // cache + // this._$blendMode = "normal"; + + // return "normal"; + // } + // set blendMode (blend_mode: BlendModeImpl) + // { + // const transform: Transform = this._$transform; + // if (!transform._$blendMode) { + // transform._$transform(null, null, null, blend_mode); + // } else { + // transform._$blendMode = blend_mode; + // this._$doChanged(); + // $doUpdated(); + // } + // this._$blendMode = blend_mode; + // } + + // /** + // * @description 表示オブジェクトに現在関連付けられている各フィルターオブジェクトが + // * 格納されているインデックス付きの配列です。 + // * An indexed array that contains each filter object + // * currently associated with the display object. + // * + // * @member {array} + // * @default {array} + // * @public + // */ + // get filters (): FilterArrayImpl + // { + // // use cache + // if (this._$filters) { + // const filters: FilterArrayImpl = $getArray(); + // for (let idx: number = 0; idx < this._$filters.length; ++idx) { + // filters[idx] = this._$filters[idx].clone(); + // } + // return filters; + // } + + // const transform: Transform = this._$transform; + // if (transform._$filters) { + + // const clone: FilterArrayImpl = $getArray(); + // const filters: FilterArrayImpl = $getArray(); + // for (let idx: number = 0; idx < transform._$filters.length; ++idx) { + // const filter = transform._$filters[idx]; + // clone[idx] = filter.clone(); + // filters[idx] = filter.clone(); + // } + + // // cache + // this._$filters = clone; + + // return filters; + // } + + // const placeObject: PlaceObjectImpl | null = this._$placeObject || this._$getPlaceObject(); + // if (placeObject && placeObject.surfaceFilterList) { + + // // create filter + // if (!placeObject.filters) { + // placeObject.filters = transform + // ._$buildFilter(placeObject.surfaceFilterList); + // } + + // const clone: FilterArrayImpl = $getArray(); + + // // @ts-ignore + // const filters: FilterArrayImpl = $getArray(); + // for (let idx: number = 0; idx < placeObject.filters.length; ++idx) { + // const filter = placeObject.filters[idx]; + // clone[idx] = filter.clone(); + // filters[idx] = filter.clone(); + // } + + // // cache + // this._$filters = clone; + + // return filters; + // } + + // const filters: FilterArrayImpl = $getArray(); + + // // cache + // this._$filters = filters; + + // return filters; + // } + // set filters (filters: FilterArrayImpl | null) + // { + // if (!filters) { + // filters = $getArray(); + // } + + // this._$transform._$transform(null, null, filters); + // this._$filters = filters; + // } + + // /** + // * @description 表示オブジェクトの高さを示します(ピクセル単位)。 + // * Indicates the height of the display object, in pixels. + // * + // * @member {number} + // * @public + // */ + // get height (): number + // { + // const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" + // ? this._$getBounds() as BoundsImpl + // : $getBoundsObject(); + + // const bounds: BoundsImpl = $boundsMatrix( + // baseBounds, + // this._$transform._$rawMatrix() + // ); + // $poolBoundsObject(baseBounds); + + // const height: number = $Math.abs(bounds.yMax - bounds.yMin); + + // // object pool + // $poolBoundsObject(bounds); + + // switch (height) { + + // case 0: + // case $Infinity: + // case -$Infinity: + // return 0; + + // default: + // return +height.toFixed(2); + + // } + // } + // set height (height: number) + // { + // height = +height; + // if (!$isNaN(height) && height > -1) { + + // const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" + // ? this._$getBounds() as BoundsImpl + // : $getBoundsObject(); + + // const rotation: number = this.rotation; + // const bounds: BoundsImpl = rotation + // ? $boundsMatrix(baseBounds, this._$transform._$rawMatrix()) + // : baseBounds; + + // if (rotation) { + // $poolBoundsObject(baseBounds); + // } + + // const exHeight: number = $Math.abs(bounds.yMax - bounds.yMin); + // $poolBoundsObject(bounds); + + // switch (exHeight) { + + // case 0: + // case $Infinity: + // case -$Infinity: + // this.scaleY = 0; + // break; + + // default: + // this.scaleY = height / exHeight; + // break; + + // } + // } + // } + + // /** + // * @description この表示オブジェクトが属するファイルの読み込み情報を含む LoaderInfo オブジェクトを返します。 + // * Returns a LoaderInfo object containing information + // * about loading the file to which this display object belongs. + // * + // * @member {LoaderInfo} + // * @default null + // * @readonly + // * @public + // */ + // get loaderInfo (): LoaderInfo | null + // { + // return this._$loaderInfo; + // } + + // /** + // * @description 呼び出し元の表示オブジェクトは、指定された mask オブジェクトによってマスクされます。 + // * The calling display object is masked by the specified mask object. + // * + // * @member {DisplayObject|null} + // * @public + // */ + // get mask (): DisplayObjectImpl | null + // { + // return this._$mask; + // } + // set mask (mask: DisplayObjectImpl | null) + // { + // if (mask === this._$mask) { + // return ; + // } + + // // reset + // if (this._$mask) { + // if ($rendererWorker && this._$mask.stage) { + // this._$mask._$removeWorkerInstance(); + // } + + // this._$mask._$isMask = false; + // this._$mask = null; + // } + + // if (mask) { + // if ($rendererWorker + // && "_$createWorkerInstance" in mask + // && typeof mask._$createWorkerInstance === "function" + // ) { + // mask._$createWorkerInstance(); + // } + + // mask._$isMask = true; + // this._$mask = mask; + // } + + // this._$doChanged(); + // } + + // /** + // * @description マウスまたはユーザー入力デバイスの x 軸の位置をピクセルで示します。 + // * Indicates the x coordinate of the mouse or user input device position, in pixels. + // * + // * @member {number} + // * @default 0 + // * @readonly + // * @public + // */ + // get mouseX (): number + // { + // return $getEvent() + // ? this.globalToLocal($currentMousePoint()).x + // : 0; + // } + + // /** + // * @description マウスまたはユーザー入力デバイスの y 軸の位置をピクセルで示します。 + // * Indicates the y coordinate of the mouse or user input device position, in pixels. + // * + // * @member {number} + // * @default 0 + // * @readonly + // * @public + // */ + // get mouseY (): number + // { + // return $getEvent() + // ? this.globalToLocal($currentMousePoint()).y + // : 0; + // } + + // /** + // * @description DisplayObject のインスタンス名を示します。 + // * Indicates the instance name of the DisplayObject. + // * + // * @member {string} + // * @public + // */ + // get name (): string + // { + // if (this._$name) { + // return this._$name; + // } + // return `instance${this._$instanceId}`; + // } + // set name (name: string) + // { + // this._$name = `${name}`; + + // const parent: ParentImpl | null = this._$parent; + // if (parent && parent._$names) { + + // parent._$names.clear(); + + // const children: DisplayObjectImpl[] = parent._$getChildren(); + // for (let idx: number = 0; idx < children.length; ++idx) { + // const child: DisplayObjectImpl = children[idx]; + // if (child._$name) { + // parent._$names.set(child.name, child); + // } + // } + // } + // } + + // /** + // * @description この表示オブジェクトを含む DisplayObjectContainer オブジェクトを示します。 + // * Indicates the DisplayObjectContainer object that contains this display object. + // * + // * @member {DisplayObjectContainer | null} + // * @readonly + // * @public + // */ + // get parent (): ParentImpl | null + // { + // return this._$parent; + // } + + // /** + // * @description 読み込まれた SWF ファイル内の表示オブジェクトの場合、 + // * root プロパティはその SWF ファイルが表す表示リストのツリー構造部分の一番上にある表示オブジェクトとなります。 + // * For a display object in a loaded SWF file, + // * the root property is the top-most display object + // * in the portion of the display list's tree structure represented by that SWF file. + // * + // * @member {DisplayObject|null} + // * @readonly + // * @public + // */ + // get root (): ParentImpl + // { + // return this._$root; + // } + + // /** + // * @description DisplayObject インスタンスの元の位置からの回転角を度単位で示します。 + // * Indicates the rotation of the DisplayObject instance, + // * in degrees, from its original orientation. + // * + // * @member {number} + // * @public + // */ + // get rotation (): number + // { + // if (this._$rotation !== null) { + // return this._$rotation; + // } + + // const matrix: Float32Array = this._$transform._$rawMatrix(); + // return $Math.atan2(matrix[1], matrix[0]) * $Rad2Deg; + // } + // set rotation (rotation: number) + // { + // rotation = $clamp(rotation % 360, 0 - 360, 360, 0); + // if (this._$rotation === rotation) { + // return ; + // } + + // const transform: Transform = this._$transform; + + // const hasMatrix: boolean = transform._$matrix !== null; + + // const matrix: Matrix = hasMatrix + // ? transform._$matrix as NonNullable + // : transform.matrix; + + // const scaleX: number = $Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b); + // const scaleY: number = $Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d); + // if (rotation === 0) { + + // matrix.a = scaleX; + // matrix.b = 0; + // matrix.c = 0; + // matrix.d = scaleY; + + // } else { + + // let radianX: number = $Math.atan2(matrix.b, matrix.a); + // let radianY: number = $Math.atan2(0 - matrix.c, matrix.d); + + // const radian: number = rotation * $Deg2Rad; + // radianY = radianY + radian - radianX; + // radianX = radian; + + // matrix.b = scaleX * $Math.sin(radianX); + // if (matrix.b === 1 || matrix.b === -1) { + // matrix.a = 0; + // } else { + // matrix.a = scaleX * $Math.cos(radianX); + // } + + // matrix.c = -scaleY * $Math.sin(radianY); + // if (matrix.c === 1 || matrix.c === -1) { + // matrix.d = 0; + // } else { + // matrix.d = scaleY * $Math.cos(radianY); + // } + // } + + // if (hasMatrix) { + // this._$doChanged(); + // $doUpdated(); + // } else { + // transform.matrix = matrix; + // $poolMatrix(matrix); + // } + + // this._$rotation = rotation; + // } + + // /** + // * @description 現在有効な拡大 / 縮小グリッドです。 + // * The current scaling grid that is in effect. + // * + // * @member {Rectangle} + // * @public + // */ + // get scale9Grid (): Rectangle | null + // { + // return this._$scale9Grid; + // } + // set scale9Grid (scale_9_grid: Rectangle | null) + // { + // if (this._$scale9Grid !== scale_9_grid) { + // this._$scale9Grid = scale_9_grid; + // this._$doChanged(); + // $doUpdated(); + // } + // } + + // /** + // * @description 基準点から適用されるオブジェクトの水平スケール(パーセンテージ)を示します。 + // * Indicates the horizontal scale (percentage) + // * of the object as applied from the registration point. + // * + // * @member {number} + // * @public + // */ + // get scaleX (): number + // { + // if (this._$scaleX !== null) { + // return this._$scaleX; + // } + + // const matrix: Float32Array = this._$transform._$rawMatrix(); + + // let xScale: number = $Math.sqrt( + // matrix[0] * matrix[0] + // + matrix[1] * matrix[1] + // ); + // if (!$Number.isInteger(xScale)) { + // const value: string = xScale.toString(); + // const index: number = value.indexOf("e"); + // if (index !== -1) { + // xScale = +value.slice(0, index); + // } + // xScale = +xScale.toFixed(4); + // } + + // return 0 > matrix[0] ? xScale * -1 : xScale; + // } + // set scaleX (scale_x: number) + // { + // scale_x = $clamp(+scale_x, + // $SHORT_INT_MIN, $SHORT_INT_MAX + // ); + + // if (!$Number.isInteger(scale_x)) { + // const value: string = scale_x.toString(); + // const index: number = value.indexOf("e"); + // if (index !== -1) { + // scale_x = +value.slice(0, index); + // } + // scale_x = +scale_x.toFixed(4); + // } + + // if (this._$scaleX === scale_x) { + // return ; + // } + + // const transform: Transform = this._$transform; + + // const hasMatrix: boolean = transform._$matrix !== null; + + // const matrix: Matrix = hasMatrix + // ? transform._$matrix as NonNullable + // : transform.matrix; + + // if (matrix.b === 0 || $isNaN(matrix.b)) { + + // matrix.a = scale_x; + + // } else { + + // let radianX = $Math.atan2(matrix.b, matrix.a); + // if (radianX === -$Math.PI) { + // radianX = 0; + // } + + // matrix.b = scale_x * $Math.sin(radianX); + // matrix.a = scale_x * $Math.cos(radianX); + + // } + + // if (hasMatrix) { + // this._$doChanged(); + // $doUpdated(); + // } else { + // transform.matrix = matrix; + // $poolMatrix(matrix); + // } + + // this._$scaleX = scale_x; + // } + + // /** + // * @description 基準点から適用されるオブジェクトの垂直スケール(パーセンテージ)を示します。 + // * IIndicates the vertical scale (percentage) + // * of an object as applied from the registration point. + // * + // * @member {number} + // * @public + // */ + // get scaleY (): number + // { + // if (this._$scaleY !== null) { + // return this._$scaleY; + // } + + // const matrix: Float32Array = this._$transform._$rawMatrix(); + + // let yScale: number = $Math.sqrt( + // matrix[2] * matrix[2] + // + matrix[3] * matrix[3] + // ); + + // if (!$Number.isInteger(yScale)) { + // const value: string = yScale.toString(); + // const index: number = value.indexOf("e"); + // if (index !== -1) { + // yScale = +value.slice(0, index); + // } + // yScale = +yScale.toFixed(4); + // } + + // return 0 > matrix[3] ? yScale * -1 : yScale; + // } + // set scaleY (scale_y: number) + // { + // scale_y = $clamp(+scale_y, + // $SHORT_INT_MIN, $SHORT_INT_MAX + // ); + + // if (!$Number.isInteger(scale_y)) { + // const value: string = scale_y.toString(); + // const index: number = value.indexOf("e"); + // if (index !== -1) { + // scale_y = +value.slice(0, index); + // } + // scale_y = +scale_y.toFixed(4); + // } + + // if (this._$scaleY === scale_y) { + // return ; + // } + + // const transform: Transform = this._$transform; + + // const hasMatrix: boolean = transform._$matrix !== null; + + // const matrix: Matrix = hasMatrix + // ? transform._$matrix as NonNullable + // : transform.matrix; + + // if (matrix.c === 0 || $isNaN(matrix.c)) { + + // matrix.d = scale_y; + + // } else { + + // let radianY = $Math.atan2(-matrix.c, matrix.d); + // if (radianY === -$Math.PI) { + // radianY = 0; + // } + // matrix.c = -scale_y * $Math.sin(radianY); + // matrix.d = scale_y * $Math.cos(radianY); + + // } + + // if (hasMatrix) { + // this._$doChanged(); + // $doUpdated(); + // } else { + // transform.matrix = matrix; + // $poolMatrix(matrix); + // } + + // this._$scaleY = scale_y; + // } + + // /** + // * @description 表示オブジェクトのステージです。 + // * The Stage of the display object. + // * + // * @member {Stage} + // * @readonly + // * @public + // */ + // get stage (): Stage | null + // { + // if (this._$stage) { + // return this._$stage; + // } + + // // find parent + // const parent: ParentImpl | null = this._$parent; + // if (parent) { + // return parent._$stage; + // } + + // return null; + // } + + // /** + // * @description 表示オブジェクトのマトリックス、カラー変換、 + // * ピクセル境界に関係するプロパティを持つオブジェクトです。 + // * An object with properties pertaining + // * to a display object's matrix, color transform, and pixel bounds. + // * + // * @member {Transform} + // * @public + // */ + // get transform (): Transform + // { + // return this._$transform; + // } + // set transform (transform: Transform) + // { + // this._$transform = transform; + // } + + // /** + // * @description 表示オブジェクトが可視かどうかを示します。 + // * Whether or not the display object is visible. + // * + // * @member {boolean} + // * @public + // */ + // get visible (): boolean + // { + // return this._$visible; + // } + // set visible (visible: boolean) + // { + // if (this._$visible !== visible) { + // this._$visible = !!visible; + // this._$doChanged(); + // $doUpdated(); + // } + // } + + // /** + // * @description 表示オブジェクトの幅を示します(ピクセル単位)。 + // * Indicates the width of the display object, in pixels. + // * + // * @member {number} + // * @public + // */ + // get width (): number + // { + // const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" + // ? this._$getBounds() as BoundsImpl + // : $getBoundsObject(); + + // const bounds: BoundsImpl = $boundsMatrix( + // baseBounds, + // this._$transform._$rawMatrix() + // ); + + // $poolBoundsObject(baseBounds); + + // const width: number = $Math.abs(bounds.xMax - bounds.xMin); + // $poolBoundsObject(bounds); + + // switch (true) { + + // case width === 0: + // case width === $Infinity: + // case width === 0 - $Infinity: + // return 0; + + // default: + // return +width.toFixed(2); + + // } + // } + // set width (width: number) + // { + // width = +width; + // if (!$isNaN(width) && width > -1) { + + // const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" + // ? this._$getBounds() as BoundsImpl + // : $getBoundsObject(); + + // const rotation: number = this.rotation; + // const bounds = rotation + // ? $boundsMatrix(baseBounds, this._$transform._$rawMatrix()) + // : baseBounds; + + // if (rotation) { + // $poolBoundsObject(baseBounds); + // } + + // const exWidth = $Math.abs(bounds.xMax - bounds.xMin); + // $poolBoundsObject(bounds); + + // switch (true) { + + // case exWidth === 0: + // case exWidth === $Infinity: + // case exWidth === -$Infinity: + // this.scaleX = 0; + // break; + + // default: + // this.scaleX = width / exWidth; + // break; + + // } + // } + // } + + // /** + // * @description 親 DisplayObjectContainer のローカル座標を基準にした + // * DisplayObject インスタンスの x 座標を示します。 + // * Indicates the x coordinate + // * of the DisplayObject instance relative to the local coordinates + // * of the parent DisplayObjectContainer. + // * + // * @member {number} + // * @public + // */ + // get x (): number + // { + // return this._$transform._$rawMatrix()[4]; + // } + // set x (x: number) + // { + // const transform: Transform = this._$transform; + + // if (!transform._$matrix) { + // const matrix: Matrix = transform.matrix; + // matrix.tx = x; + // transform.matrix = matrix; + // $poolMatrix(matrix); + // } else { + // transform._$matrix.tx = x; + // this._$doChanged(); + // $doUpdated(); + // } + // } + + // /** + // * @description 親 DisplayObjectContainer のローカル座標を基準にした + // * DisplayObject インスタンスの y 座標を示します。 + // * Indicates the y coordinate + // * of the DisplayObject instance relative to the local coordinates + // * of the parent DisplayObjectContainer. + // * + // * @member {number} + // * @public + // */ + // get y (): number + // { + // return this._$transform._$rawMatrix()[5]; + // } + // set y (y: number) + // { + // const transform: Transform = this._$transform; + + // if (!transform._$matrix) { + // const matrix = transform.matrix; + // matrix.ty = y; + + // transform.matrix = matrix; + // $poolMatrix(matrix); + // } else { + // transform._$matrix.ty = y; + // this._$doChanged(); + // $doUpdated(); + // } + // } + + // /** + // * @description targetCoordinateSpace オブジェクトの座標系を基準にして、 + // * 表示オブジェクトの領域を定義する矩形を返します。 + // * Returns a rectangle that defines the area + // * of the display object relative to the coordinate system + // * of the targetCoordinateSpace object. + // * + // * @param {DisplayObject} [target=null] + // * @return {Rectangle} + // */ + // getBounds (target: DisplayObjectImpl | null = null): Rectangle + // { + // const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" + // ? this._$getBounds() as BoundsImpl + // : $getBoundsObject(); + + // const matrix: Matrix = this._$transform.concatenatedMatrix; + + // // to global + // const bounds: BoundsImpl = $boundsMatrix(baseBounds, matrix._$matrix); + + // // pool + // $poolMatrix(matrix); + // $poolBoundsObject(baseBounds); + + // // create bounds object + // const targetBaseBounds: BoundsImpl = $getBoundsObject( + // bounds.xMin, + // bounds.xMax, + // bounds.yMin, + // bounds.yMax + // ); + + // // pool + // $poolBoundsObject(bounds); + + // if (!target) { + // target = this; + // } + + // const targetMatrix: Matrix = target._$transform.concatenatedMatrix; + // targetMatrix.invert(); + + // const resultBounds: BoundsImpl = $boundsMatrix( + // targetBaseBounds, targetMatrix._$matrix + // ); + // $poolBoundsObject(targetBaseBounds); + // $poolMatrix(targetMatrix); + + // const xMin: number = resultBounds.xMin; + // const yMin: number = resultBounds.yMin; + // const xMax: number = resultBounds.xMax; + // const yMax: number = resultBounds.yMax; + + // // pool + // $poolBoundsObject(resultBounds); + + // return new Rectangle( + // xMin, yMin, + // $Math.abs(xMax - xMin), + // $Math.abs(yMax - yMin) + // ); + // } + + // /** + // * @description point オブジェクトをステージ(グローバル)座標から + // * 表示オブジェクトの(ローカル)座標に変換します。 + // * Converts the point object from the Stage (global) coordinates + // * to the display object's (local) coordinates. + // * + // * @param {Point} point + // * @return {Point} + // * @public + // */ + // globalToLocal (point: Point): Point + // { + // const matrix: Matrix = this._$transform.concatenatedMatrix; + // matrix.invert(); + + // const newPoint: Point = new Point( + // point.x * matrix.a + point.y * matrix.c + matrix.tx, + // point.x * matrix.b + point.y * matrix.d + matrix.ty + // ); + + // $poolMatrix(matrix); + + // return newPoint; + // } + + // /** + // * @description 表示オブジェクトの境界ボックスを評価して、 + // * obj 表示オブジェクトの境界ボックスと重複または交差するかどうかを調べます。 + // * Evaluates the bounding box of the display object to see + // * if it overlaps or intersects with the bounding box of the obj display object. + // * + // * @param {DisplayObject} object + // * @returns {boolean} + // * @public + // */ + // hitTestObject (object: DisplayObjectImpl): boolean + // { + // const baseBounds1: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" + // ? this._$getBounds() as BoundsImpl + // : $getBoundsObject(); + + // const matrix1: Matrix = this._$transform.concatenatedMatrix; + // const bounds1: BoundsImpl = $boundsMatrix(baseBounds1, matrix1._$matrix); + + // // pool + // $poolMatrix(matrix1); + // $poolBoundsObject(baseBounds1); + + // const baseBounds2: BoundsImpl = object._$getBounds(null); + // const matrix2: Matrix = object._$transform.concatenatedMatrix; + // const bounds2: BoundsImpl = $boundsMatrix(baseBounds2, matrix2._$matrix); + + // // pool + // $poolMatrix(matrix2); + // $poolBoundsObject(baseBounds2); + + // // calc + // const sx: number = $Math.max(bounds1.xMin, bounds2.xMin); + // const sy: number = $Math.max(bounds1.yMin, bounds2.yMin); + // const ex: number = $Math.min(bounds1.xMax, bounds2.xMax); + // const ey: number = $Math.min(bounds1.yMax, bounds2.yMax); + + // // pool + // $poolBoundsObject(bounds1); + // $poolBoundsObject(bounds2); + + // return ex - sx >= 0 && ey - sy >= 0; + // } + + // /** + // * @description 表示オブジェクトを評価して、x および y パラメーターで指定された + // * ポイントと重複または交差するかどうかを調べます。 + // * Evaluates the display object to see if it overlaps + // * or intersects with the point specified by the x and y parameters. + // * + // * @param {number} x + // * @param {number} y + // * @param {boolean} [shape_flag=false] + // * @returns {boolean} + // * @public + // */ + // hitTestPoint ( + // x: number, y: number, + // shape_flag: boolean = false + // ): boolean { + + // if (shape_flag) { + + // let matrix: Float32Array = $MATRIX_ARRAY_IDENTITY; + + // let parent: ParentImpl | null = this._$parent; + // while (parent) { + + // matrix = $multiplicationMatrix( + // parent._$transform._$rawMatrix(), + // matrix + // ); + + // parent = parent._$parent; + // } + + // $hitContext.setTransform(1, 0, 0, 1, 0, 0); + // $hitContext.beginPath(); + + // let result: boolean = false; + // if ("_$hit" in this && typeof this._$hit === "function") { + // result = this._$hit($hitContext, matrix, { "x": x, "y": y }, true); + // } + + // if (matrix !== $MATRIX_ARRAY_IDENTITY) { + // $poolFloat32Array6(matrix); + // } + + // return result; + // } + + // const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" + // ? this._$getBounds() as BoundsImpl + // : $getBoundsObject(); + + // const bounds: BoundsImpl = $boundsMatrix(baseBounds, this._$transform._$rawMatrix()); + // $poolBoundsObject(baseBounds); + + // const rectangle: Rectangle = new Rectangle( + // bounds.xMin, bounds.yMin, + // bounds.xMax - bounds.xMin, + // bounds.yMax - bounds.yMin + // ); + + // // pool + // $poolBoundsObject(bounds); + + // const point: Point = this._$parent + // ? this._$parent.globalToLocal(new Point(x, y)) + // : new Point(x, y); + + // return rectangle.containsPoint(point); + // } + + // /** + // * @description point オブジェクトを表示オブジェクトの(ローカル)座標から + // * ステージ(グローバル)座標に変換します。 + // * Converts the point object from the display object's (local) coordinates + // * to the Stage (global) coordinates. + // * + // * + // * @param {Point} point + // * @returns {Point} + // * @public + // */ + // localToGlobal (point: Point): Point + // { + // const matrix: Matrix = this + // ._$transform + // .concatenatedMatrix; + + // const newPoint: Point = new Point( + // point.x * matrix.a + point.y * matrix.c + matrix.tx, + // point.x * matrix.b + point.y * matrix.d + matrix.ty + // ); + + // $poolMatrix(matrix); + + // return newPoint; + // } + + // /** + // * @description クラスのローカル変数空間から値を取得 + // * Get a value from the local variable space of the class + // * + // * @param {*} key + // * @return {*} + // * @method + // * @public + // */ + // getLocalVariable (key: any): any + // { + // if (!this._$variables) { + // return null; + // } + + // if (this._$variables.has(key)) { + // return this._$variables.get(key); + // } + // } + + // /** + // * @description クラスのローカル変数空間へ値を保存 + // * Store values in the local variable space of the class + // * + // * @param {*} key + // * @param {*} value + // * @return {void} + // * @method + // * @public + // */ + // setLocalVariable (key: any, value: any): void + // { + // if (!this._$variables) { + // this._$variables = $getMap(); + // } + // this._$variables.set(key, value); + // } + + // /** + // * @description クラスのローカル変数空間に値があるかどうかを判断します。 + // * Determines if there is a value in the local variable space of the class. + // * + // * @param {*} key + // * @return {boolean} + // * @method + // * @public + // */ + // hasLocalVariable (key: any): boolean + // { + // return this._$variables + // ? this._$variables.has(key) + // : false; + // } + + // /** + // * @description クラスのローカル変数空間の値を削除 + // * Remove values from the local variable space of a class + // * + // * @param {*} key + // * @return {void} + // * @method + // * @public + // */ + // deleteLocalVariable (key: any): void + // { + // if (this._$variables && this._$variables.has(key)) { + // this._$variables.delete(key); + // if (!this._$variables.size) { + // $poolMap(this._$variables); + // this._$variables = null; + // } + // } + // } + + // /** + // * @description グローバル変数空間から値を取得 + // * Get a value from the global variable space + // * + // * @param {*} key + // * @return {*} + // * @method + // * @public + // */ + // getGlobalVariable (key: any): any + // { + // if ($variables.has(key)) { + // return $variables.get(key); + // } + // return null; + // } + + // /** + // * @description グローバル変数空間へ値を保存 + // * Save values to global variable space + // * + // * @param {*} key + // * @param {*} value + // * @return {void} + // * @method + // * @public + // */ + // setGlobalVariable (key: any, value: any): void + // { + // $variables.set(key, value); + // } + + // /** + // * @description グローバル変数空間に値があるかどうかを判断します。 + // * Determines if there is a value in the global variable space. + // * + // * @param {*} key + // * @return {boolean} + // * @method + // * @public + // */ + // hasGlobalVariable (key: any): boolean + // { + // return $variables.has(key); + // } + + // /** + // * @description グローバル変数空間の値を削除 + // * Remove values from global variable space. + // * + // * @param {*} key + // * @return {void} + // * @method + // * @public + // */ + // deleteGlobalVariable (key: any): void + // { + // if ($variables.has(key)) { + // $variables.delete(key); + // } + // } + + // /** + // * @description グローバル変数空間に値を全てクリアします。 + // * Clear all values in the global variable space. + // * + // * @return {void} + // * @method + // * @public + // */ + // clearGlobalVariable (): void + // { + // return $variables.clear(); + // } + + // /** + // * @return {object} + // * @method + // * @private + // */ + // _$getPlaceObject (): PlaceObjectImpl | null + // { + // if (!this._$placeObject) { + + // const placeId = this._$placeId; + // if (placeId === -1) { + // return null; + // } + + // const parent: ParentImpl | null = this._$parent; + // if (!parent || !parent._$placeObjects) { + // return null; + // } + + // const placeMap: Array> | null = parent._$placeMap; + // if (!placeMap || !placeMap.length) { + // return null; + // } + + // const frame: number = "currentFrame" in parent ? parent.currentFrame : 1; + // const places: number[] | void = placeMap[frame]; + // if (!places) { + // return null; + // } + + // const currentPlaceId: number = places[placeId] | 0; + // const placeObject: PlaceObjectImpl | void = parent._$placeObjects[currentPlaceId]; + // if (!placeObject) { + // return null; + // } + + // this._$changePlace = currentPlaceId !== this._$currentPlaceId; + // this._$currentPlaceId = currentPlaceId; + // this._$placeObject = placeObject; + + // return placeObject; + // } + + // return this._$placeObject; + // } + + // /** + // * @param {object} tag + // * @param {DisplayObjectContainer} parent + // * @return {object} + // * @method + // * @private + // */ + // _$baseBuild ( + // tag: DictionaryTagImpl, + // parent: ParentImpl + // ): T { + + // const loaderInfo: LoaderInfo | null = parent._$loaderInfo; + // if (!loaderInfo || !loaderInfo._$data) { + // throw new Error("the loaderInfo or data is nul."); + // } + + // // setup + // this._$parent = parent; + // this._$root = parent._$root; + // this._$stage = parent._$stage; + // this._$loaderInfo = loaderInfo; + + // // bind tag data + // this._$characterId = tag.characterId | 0; + // this._$clipDepth = tag.clipDepth | 0; + // this._$startFrame = tag.startFrame | 0; + // this._$endFrame = tag.endFrame | 0; + // this._$name = tag.name || ""; + + // return loaderInfo._$data.characters[tag.characterId]; + // } + + // /** + // * @return {boolean} + // * @method + // * @private + // */ + // _$isUpdated (): boolean + // { + // return this._$updated; + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$updateState (): void + // { + // this._$isNext = true; + + // const parent: ParentImpl | null = this._$parent; + // if (parent) { + // parent._$updateState(); + // } + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$doChanged (): void + // { + // this._$posted = false; + // this._$isNext = true; + // this._$updated = true; + + // const parent: ParentImpl | null = this._$parent; + // if (parent) { + // if (!parent._$updated) { + // parent._$doChanged(); + // } + // } + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @param {array} filters + // * @param {number} width + // * @param {number} height + // * @param {WebGLTexture} [target_texture = null] + // * @return {object} + // * @method + // * @private + // */ + // _$drawFilter ( + // context: CanvasToWebGLContext, + // matrix: Float32Array, + // filters: FilterArrayImpl, + // width: number, + // height: number, + // target_texture: WebGLTexture | null = null + // ): CachePositionImpl { + + // const cacheKeys: any[] = $getArray(this._$instanceId, "f"); + // let position: CachePositionImpl | void = $cacheStore.get(cacheKeys); + + // const updated: boolean = this._$isFilterUpdated(matrix, filters, true); + + // if (position && !updated) { + // context.cachePosition = position; + // return position; + // } + + // // cache clear + // if (position) { + // $cacheStore.set(cacheKeys, null); + // } + + // const manager: FrameBufferManager = context.frameBuffer; + // const targetTexture: WebGLTexture = target_texture + // ? target_texture + // : context.getTextureFromRect( + // context.cachePosition as NonNullable + // ); + + // const texture: WebGLTexture = this._$applyFilter( + // context, filters, targetTexture, + // matrix, width, height + // ); + // manager.textureManager.release(targetTexture); + + // const bounds: BoundsImpl = this._$getLayerBounds(matrix); + // position = manager.createCachePosition( + // $Math.ceil($Math.abs(bounds.xMax - bounds.xMin)), + // $Math.ceil($Math.abs(bounds.yMax - bounds.yMin)) + // ); + // $poolBoundsObject(bounds); + + // position.filterState = true; + // position.matrix = `${matrix[0]}_${matrix[1]}_${matrix[2]}_${matrix[3]}_0_0`; + // position.offsetX = texture.offsetX; + // position.offsetY = texture.offsetY; + + // // 関数先でtextureがreleaseされる + // context.drawTextureFromRect(texture, position); + + // $cacheStore.set(cacheKeys, position); + // $poolArray(cacheKeys); + + // return position; + // } + + // /** + // * @param {Float32Array} multi_matrix + // * @returns {object} + // * @private + // */ + // _$getLayerBounds (multi_matrix: Float32Array): BoundsImpl + // { + // const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" + // ? this._$getBounds() as BoundsImpl + // : $getBoundsObject(); + + // const bounds: BoundsImpl = $boundsMatrix(baseBounds, multi_matrix); + // $poolBoundsObject(baseBounds); + + // const filters: FilterArrayImpl = this._$filters || this.filters; + // if (!filters.length) { + // return bounds; + // } + + // let filterBounds: BoundsImpl = $getBoundsObject( + // 0, + // $Math.abs(bounds.xMax - bounds.xMin), + // 0, + // $Math.abs(bounds.yMax - bounds.yMin) + // ); + // $poolBoundsObject(bounds); + + // let xScale: number = +$Math.sqrt( + // multi_matrix[0] * multi_matrix[0] + // + multi_matrix[1] * multi_matrix[1] + // ); + // let yScale: number = +$Math.sqrt( + // multi_matrix[2] * multi_matrix[2] + // + multi_matrix[3] * multi_matrix[3] + // ); + + // xScale /= $devicePixelRatio; + // yScale /= $devicePixelRatio; + + // xScale *= 2; + // yScale *= 2; + + // for (let idx: number = 0; idx < filters.length; ++idx) { + // filterBounds = filters[idx] + // ._$generateFilterRect(filterBounds, xScale, yScale); + // } + + // return filterBounds; + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$executeAddedEvent (): void + // { + // if (!this._$parent) { + // return ; + // } + + // // add event + // if (!this._$added) { + + // // added event + // if (this.willTrigger(Next2DEvent.ADDED)) { + // this.dispatchEvent(new Next2DEvent(Next2DEvent.ADDED, true)); + // } + + // // update + // this._$added = true; + // } + + // if (!this._$addedStage && this._$stage !== null) { + + // if (this.willTrigger(Next2DEvent.ADDED_TO_STAGE)) { + // this.dispatchEvent(new Next2DEvent(Next2DEvent.ADDED_TO_STAGE)); + // } + + // // update + // this._$addedStage = true; + // } + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$prepareActions (): void + // { + // this._$nextFrame(); + // } + + // /** + // * @return {boolean} + // * @method + // * @private + // */ + // _$nextFrame (): boolean + // { + // // added event + // this._$executeAddedEvent(); + + // this._$isNext = false; + + // if (!this._$posted && $rendererWorker) { + // // @ts-ignore + // this._$postProperty(); + // } + + // return false; + // } + + // /** + // * @param {array} [filters=null] + // * @return {boolean} + // * @private + // */ + // _$canApply (filters: FilterArrayImpl | null = null): boolean + // { + // if (filters) { + // for (let idx: number = 0; idx < filters.length; ++idx) { + // if (filters[idx]._$canApply()) { + // return true; + // } + // } + // } + // return false; + // } + + // /** + // * @param {Float32Array} matrix + // * @param {array} [filters=null] + // * @param {boolean} [can_apply=false] + // * @param {number} [position_x=0] + // * @param {number} [position_y=0] + // * @return {boolean} + // * @private + // */ + // _$isFilterUpdated ( + // matrix: Float32Array, + // filters: FilterArrayImpl | null = null, + // can_apply: boolean = false + // ): boolean { + + // // cache flag + // if (this._$isUpdated()) { + // return true; + // } + + // // check filter data + // if (can_apply && filters) { + + // for (let idx: number = 0; idx < filters.length; ++idx) { + + // if (!filters[idx]._$isUpdated()) { + // continue; + // } + + // return true; + // } + + // } + + // // check status + // const cache: CachePositionImpl = $cacheStore.get([this._$instanceId, "f"]); + // if (!cache) { + // return true; + // } + + // if (cache.filterState !== can_apply) { + // return true; + // } + + // if (cache.matrix !== `${matrix[0]}_${matrix[1]}_${matrix[2]}_${matrix[3]}`) { + // return true; + // } + + // return false; + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {array} filters + // * @param {WebGLTexture} target_texture + // * @param {Float32Array} matrix + // * @param {number} width + // * @param {number} height + // * @return {WebGLTexture} + // * @private + // */ + // _$applyFilter ( + // context: CanvasToWebGLContext, + // filters: FilterArrayImpl, + // target_texture: WebGLTexture, + // matrix: Float32Array, + // width: number, + // height: number + // ): WebGLTexture { + + // const xScale: number = +$Math.sqrt( + // matrix[0] * matrix[0] + // + matrix[1] * matrix[1] + // ); + // const yScale: number = +$Math.sqrt( + // matrix[2] * matrix[2] + // + matrix[3] * matrix[3] + // ); + + // const radianX: number = $Math.atan2(matrix[1], matrix[0]); + // const radianY: number = $Math.atan2(-matrix[2], matrix[3]); + + // const parentMatrix: Float32Array = $getFloat32Array6( + // $Math.cos(radianX), $Math.sin(radianX), + // -$Math.sin(radianY), $Math.cos(radianY), + // width / 2, height / 2 + // ); + + // const baseMatrix: Float32Array = $getFloat32Array6( + // 1, 0, 0, 1, + // -target_texture.width / 2, + // -target_texture.height / 2 + // ); + + // const multiMatrix: Float32Array = $multiplicationMatrix( + // parentMatrix, baseMatrix + // ); + // $poolFloat32Array6(parentMatrix); + // $poolFloat32Array6(baseMatrix); + + // const manager: FrameBufferManager = context.frameBuffer; + // const currentAttachment: AttachmentImpl | null = manager.currentAttachment; + + // const attachment: AttachmentImpl = manager + // .createCacheAttachment(width, height); + // context._$bind(attachment); + + // context.reset(); + // context.setTransform( + // multiMatrix[0], multiMatrix[1], + // multiMatrix[2], multiMatrix[3], + // multiMatrix[4], multiMatrix[5] + // ); + // $poolFloat32Array6(multiMatrix); + + // context.drawImage(target_texture, + // 0, 0, target_texture.width, target_texture.height + // ); + + // // init + // context._$offsetX = 0; + // context._$offsetY = 0; + + // const filterMatrix: Float32Array = $getFloat32Array6( + // xScale, 0, 0, yScale, 0, 0 + // ); + + // let texture: WebGLTexture | null = null; + // for (let idx: number = 0; idx < filters.length; ++idx) { + // texture = filters[idx]._$applyFilter(context, filterMatrix); + // } + + // $poolFloat32Array6(filterMatrix); + + // if (!texture) { + // return target_texture; + // } + + // const offsetX: number = context._$offsetX; + // const offsetY: number = context._$offsetY; + + // // reset + // context._$offsetX = 0; + // context._$offsetY = 0; + + // // set offset + // texture.offsetX = offsetX; + // texture.offsetY = offsetY; + + // context._$bind(currentAttachment); + // manager.releaseAttachment(attachment, false); + + // return texture; + // } + + // /** + // * @param {Float32Array} matrix + // * @return {boolean} + // * @method + // * @private + // */ + // _$shouldClip (matrix: Float32Array): boolean + // { + // const bounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" + // ? this._$getBounds(matrix) as BoundsImpl + // : $getBoundsObject(); + + // const width = $Math.abs(bounds.xMax - bounds.xMin); + // const height = $Math.abs(bounds.yMax - bounds.yMin); + // $poolBoundsObject(bounds); + + // // size 0 + // return !(!width || !height); + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @return {boolean} + // * @method + // * @private + // */ + // _$startClip ( + // context: CanvasToWebGLContext, + // matrix: Float32Array + // ): boolean { + + // context.drawInstacedArray(); + + // // マスクの描画反映を限定 + // const bounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" + // ? this._$getBounds(matrix) as BoundsImpl + // : $getBoundsObject(); + + // const result = context._$startClip(bounds); + // $poolBoundsObject(bounds); + + // if (!result) { + // return false; + // } + + // // start clip + // context._$enterClip(); + + // // mask start + // context._$beginClipDef(); + + // let containerClip = false; + // if ("_$children" in this) { + // containerClip = true; + // context._$updateContainerClipFlag(true); + // } + + // // @ts-ignore + // this._$clip(context, matrix); + // this._$updated = false; + + // // container clip + // if (containerClip) { + + // // update flag + // context._$updateContainerClipFlag(false); + + // // execute clip + // context._$drawContainerClip(); + // } + + // // mask end + // context._$endClipDef(); + + // return true; + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$removeWorkerInstance (): void + // { + // if ($rendererWorker) { + // $rendererWorker.postMessage({ + // "command": "remove", + // "instanceId": this._$instanceId + // }); + // } + // } + + // /** + // * @param {Float32Array} buffer + // * @param {number} [index = 0] + // * @return {void} + // * @method + // * @private + // */ + // _$registerProperty (buffer: Float32Array, index: number = 0): void + // { + // // visible + // buffer[index++] = +this._$visible; + + // // depth + // buffer[index++] = this._$placeId; + + // // clip depth + // buffer[index++] = this._$clipDepth; + + // // isMask + // buffer[index++] = +this._$isMask; + + // const mask: DisplayObjectImpl | null = this._$mask; + // buffer[index++] = +(mask !== null); + // if (mask) { + + // // mask id + // buffer[index++] = mask._$instanceId; + + // let maskMatrix: Float32Array = $MATRIX_ARRAY_IDENTITY; + // let parent: ParentImpl | null = mask._$parent; + // while (parent) { + + // maskMatrix = $multiplicationMatrix( + // parent._$transform._$rawMatrix(), + // maskMatrix + // ); + + // parent = parent._$parent; + // } + + // // mask matrix + // buffer[index++] = maskMatrix[0]; + // buffer[index++] = maskMatrix[1]; + // buffer[index++] = maskMatrix[2]; + // buffer[index++] = maskMatrix[3]; + // buffer[index++] = maskMatrix[4]; + // buffer[index++] = maskMatrix[5]; + // } else { + // index += 7; + // } + + // if (this._$visible) { + // const transform: Transform = this._$transform; + + // // matrix + // const matrix: Float32Array = transform._$rawMatrix(); + // buffer[index++] = matrix[0]; + // buffer[index++] = matrix[1]; + // buffer[index++] = matrix[2]; + // buffer[index++] = matrix[3]; + // buffer[index++] = matrix[4]; + // buffer[index++] = matrix[5]; + + // // colorTransform + // const colorTransform = transform._$rawColorTransform(); + // buffer[index++] = colorTransform[0]; + // buffer[index++] = colorTransform[1]; + // buffer[index++] = colorTransform[2]; + // buffer[index++] = colorTransform[3]; + // buffer[index++] = colorTransform[4]; + // buffer[index++] = colorTransform[5]; + // buffer[index++] = colorTransform[6]; + // buffer[index++] = colorTransform[7]; + + // } else { + // index += 6; // matrix + // index += 8; // colorTransform + // } + + // // blend mode + // const blendMode: BlendModeImpl = this._$blendMode || this.blendMode; + // buffer[index++] = $blendToNumber(blendMode); + + // // scale9Grid + // const scale9Grid: Rectangle | null = this._$scale9Grid; + // buffer[index++] = +(scale9Grid !== null); + + // if (scale9Grid) { + // buffer[index++] = scale9Grid.x; + // buffer[index++] = scale9Grid.y; + // buffer[index++] = scale9Grid.width; + // buffer[index++] = scale9Grid.height; + // } else { + // index += 4; + // } + + // // filter + // } + + // /** + // * @return {object} + // * @method + // * @private + // */ + // _$createMessage (): PropertyMessageMapImpl + // { + // const message: PropertyMessageImpl = { + // "command": "setProperty", + // "buffer": new Float32Array(), + // "instanceId": this._$instanceId, + // "parentId": this._$parent ? this._$parent._$instanceId : -1, + // "visible": this._$visible + // }; + + // if (this._$placeId > -1) { + // message.depth = this._$placeId; + // } + + // if (this._$clipDepth) { + // message.clipDepth = this._$clipDepth; + // } + + // if (this._$isMask) { + // message.isMask = this._$isMask; + // } + + // const mask: DisplayObjectImpl | null = this._$mask; + // if (mask) { + // message.maskId = mask._$instanceId; + + // let maskMatrix: Float32Array = $MATRIX_ARRAY_IDENTITY; + // let parent: ParentImpl | null = mask._$parent; + // while (parent) { + + // maskMatrix = $multiplicationMatrix( + // parent._$transform._$rawMatrix(), + // maskMatrix + // ); + + // parent = parent._$parent; + // } + + // message.maskMatrix = maskMatrix; + // } + + // if (this._$visible) { + + // const transform: Transform = this._$transform; + + // const matrix: Float32Array = transform._$rawMatrix(); + // if (matrix[0] !== 1) { + // message.a = matrix[0]; + // } + + // if (matrix[1] !== 0) { + // message.b = matrix[1]; + // } + + // if (matrix[2] !== 0) { + // message.c = matrix[2]; + // } + + // if (matrix[3] !== 1) { + // message.d = matrix[3]; + // } + + // if (matrix[4] !== 0) { + // message.tx = matrix[4]; + // } + + // if (matrix[5] !== 0) { + // message.ty = matrix[5]; + // } + + // const colorTransform = transform._$rawColorTransform(); + // if (colorTransform[0] !== 1) { + // message.f0 = colorTransform[0]; + // } + + // if (colorTransform[1] !== 1) { + // message.f1 = colorTransform[1]; + // } + + // if (colorTransform[2] !== 1) { + // message.f2 = colorTransform[2]; + // } + + // if (colorTransform[3] !== 1) { + // message.f3 = colorTransform[3]; + // } + + // if (colorTransform[4] !== 0) { + // message.f4 = colorTransform[4]; + // } + + // if (colorTransform[5] !== 0) { + // message.f5 = colorTransform[5]; + // } + + // if (colorTransform[6] !== 0) { + // message.f6 = colorTransform[6]; + // } + + // if (colorTransform[7] !== 0) { + // message.f7 = colorTransform[7]; + // } + + // const filters: FilterArrayImpl | null = this._$filters || this.filters; + // if (filters && filters.length) { + // const parameters: any[] = $getArray(); + // for (let idx: number = 0; idx < filters.length; ++idx) { + // parameters.push(filters[idx]._$toArray()); + // } - matrix.d = scale_y; + // message.filters = parameters; + // } + + // const blendMode: BlendModeImpl = this._$blendMode || this.blendMode; + // if (blendMode !== "normal") { + // message.blendMode = blendMode; + // } - } else { - - let radianY = $Math.atan2(-matrix.c, matrix.d); - if (radianY === -$Math.PI) { - radianY = 0; - } - matrix.c = -scale_y * $Math.sin(radianY); - matrix.d = scale_y * $Math.cos(radianY); - - } + // const scale9Grid: Rectangle | null = this._$scale9Grid; + // if (scale9Grid && this._$isUpdated()) { + + // const baseMatrix: Matrix = this + // ._$parent + // ._$transform + // .concatenatedMatrix; - if (hasMatrix) { - this._$doChanged(); - $doUpdated(); - } else { - transform.matrix = matrix; - $poolMatrix(matrix); - } + // message.matrixBase = baseMatrix._$matrix.slice(); + // $poolMatrix(baseMatrix); + + // message.grid = { + // "x": scale9Grid.x, + // "y": scale9Grid.y, + // "w": scale9Grid.width, + // "h": scale9Grid.height + // }; + // } + // } - this._$scaleY = scale_y; - } - - /** - * @description 表示オブジェクトのステージです。 - * The Stage of the display object. - * - * @member {Stage} - * @readonly - * @public - */ - get stage (): Stage | null - { - if (this._$stage) { - return this._$stage; - } - - // find parent - const parent: ParentImpl | null = this._$parent; - if (parent) { - return parent._$stage; - } - - return null; - } - - /** - * @description 表示オブジェクトのマトリックス、カラー変換、 - * ピクセル境界に関係するプロパティを持つオブジェクトです。 - * An object with properties pertaining - * to a display object's matrix, color transform, and pixel bounds. - * - * @member {Transform} - * @public - */ - get transform (): Transform - { - return this._$transform; - } - set transform (transform: Transform) - { - this._$transform = transform; - } - - /** - * @description 表示オブジェクトが可視かどうかを示します。 - * Whether or not the display object is visible. - * - * @member {boolean} - * @public - */ - get visible (): boolean - { - return this._$visible; - } - set visible (visible: boolean) - { - if (this._$visible !== visible) { - this._$visible = !!visible; - this._$doChanged(); - $doUpdated(); - } - } - - /** - * @description 表示オブジェクトの幅を示します(ピクセル単位)。 - * Indicates the width of the display object, in pixels. - * - * @member {number} - * @public - */ - get width (): number - { - const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" - ? this._$getBounds() as BoundsImpl - : $getBoundsObject(); - - const bounds: BoundsImpl = $boundsMatrix( - baseBounds, - this._$transform._$rawMatrix() - ); - - $poolBoundsObject(baseBounds); - - const width: number = $Math.abs(bounds.xMax - bounds.xMin); - $poolBoundsObject(bounds); - - switch (true) { - - case width === 0: - case width === $Infinity: - case width === 0 - $Infinity: - return 0; - - default: - return +width.toFixed(2); - - } - } - set width (width: number) - { - width = +width; - if (!$isNaN(width) && width > -1) { - - const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" - ? this._$getBounds() as BoundsImpl - : $getBoundsObject(); - - const rotation: number = this.rotation; - const bounds = rotation - ? $boundsMatrix(baseBounds, this._$transform._$rawMatrix()) - : baseBounds; - - if (rotation) { - $poolBoundsObject(baseBounds); - } - - const exWidth = $Math.abs(bounds.xMax - bounds.xMin); - $poolBoundsObject(bounds); - - switch (true) { - - case exWidth === 0: - case exWidth === $Infinity: - case exWidth === -$Infinity: - this.scaleX = 0; - break; - - default: - this.scaleX = width / exWidth; - break; - - } - } - } - - /** - * @description 親 DisplayObjectContainer のローカル座標を基準にした - * DisplayObject インスタンスの x 座標を示します。 - * Indicates the x coordinate - * of the DisplayObject instance relative to the local coordinates - * of the parent DisplayObjectContainer. - * - * @member {number} - * @public - */ - get x (): number - { - return this._$transform._$rawMatrix()[4]; - } - set x (x: number) - { - const transform: Transform = this._$transform; - - if (!transform._$matrix) { - const matrix: Matrix = transform.matrix; - matrix.tx = x; - transform.matrix = matrix; - $poolMatrix(matrix); - } else { - transform._$matrix.tx = x; - this._$doChanged(); - $doUpdated(); - } - } - - /** - * @description 親 DisplayObjectContainer のローカル座標を基準にした - * DisplayObject インスタンスの y 座標を示します。 - * Indicates the y coordinate - * of the DisplayObject instance relative to the local coordinates - * of the parent DisplayObjectContainer. - * - * @member {number} - * @public - */ - get y (): number - { - return this._$transform._$rawMatrix()[5]; - } - set y (y: number) - { - const transform: Transform = this._$transform; - - if (!transform._$matrix) { - const matrix = transform.matrix; - matrix.ty = y; - - transform.matrix = matrix; - $poolMatrix(matrix); - } else { - transform._$matrix.ty = y; - this._$doChanged(); - $doUpdated(); - } - } - - /** - * @description targetCoordinateSpace オブジェクトの座標系を基準にして、 - * 表示オブジェクトの領域を定義する矩形を返します。 - * Returns a rectangle that defines the area - * of the display object relative to the coordinate system - * of the targetCoordinateSpace object. - * - * @param {DisplayObject} [target=null] - * @return {Rectangle} - */ - getBounds (target: DisplayObjectImpl | null = null): Rectangle - { - const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" - ? this._$getBounds() as BoundsImpl - : $getBoundsObject(); - - const matrix: Matrix = this._$transform.concatenatedMatrix; - - // to global - const bounds: BoundsImpl = $boundsMatrix(baseBounds, matrix._$matrix); - - // pool - $poolMatrix(matrix); - $poolBoundsObject(baseBounds); - - // create bounds object - const targetBaseBounds: BoundsImpl = $getBoundsObject( - bounds.xMin, - bounds.xMax, - bounds.yMin, - bounds.yMax - ); - - // pool - $poolBoundsObject(bounds); - - if (!target) { - target = this; - } - - const targetMatrix: Matrix = target._$transform.concatenatedMatrix; - targetMatrix.invert(); - - const resultBounds: BoundsImpl = $boundsMatrix( - targetBaseBounds, targetMatrix._$matrix - ); - $poolBoundsObject(targetBaseBounds); - $poolMatrix(targetMatrix); - - const xMin: number = resultBounds.xMin; - const yMin: number = resultBounds.yMin; - const xMax: number = resultBounds.xMax; - const yMax: number = resultBounds.yMax; - - // pool - $poolBoundsObject(resultBounds); - - return new Rectangle( - xMin, yMin, - $Math.abs(xMax - xMin), - $Math.abs(yMax - yMin) - ); - } - - /** - * @description point オブジェクトをステージ(グローバル)座標から - * 表示オブジェクトの(ローカル)座標に変換します。 - * Converts the point object from the Stage (global) coordinates - * to the display object's (local) coordinates. - * - * @param {Point} point - * @return {Point} - * @public - */ - globalToLocal (point: Point): Point - { - const matrix: Matrix = this._$transform.concatenatedMatrix; - matrix.invert(); - - const newPoint: Point = new Point( - point.x * matrix.a + point.y * matrix.c + matrix.tx, - point.x * matrix.b + point.y * matrix.d + matrix.ty - ); - - $poolMatrix(matrix); - - return newPoint; - } - - /** - * @description 表示オブジェクトの境界ボックスを評価して、 - * obj 表示オブジェクトの境界ボックスと重複または交差するかどうかを調べます。 - * Evaluates the bounding box of the display object to see - * if it overlaps or intersects with the bounding box of the obj display object. - * - * @param {DisplayObject} object - * @returns {boolean} - * @public - */ - hitTestObject (object: DisplayObjectImpl): boolean - { - const baseBounds1: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" - ? this._$getBounds() as BoundsImpl - : $getBoundsObject(); - - const matrix1: Matrix = this._$transform.concatenatedMatrix; - const bounds1: BoundsImpl = $boundsMatrix(baseBounds1, matrix1._$matrix); - - // pool - $poolMatrix(matrix1); - $poolBoundsObject(baseBounds1); - - const baseBounds2: BoundsImpl = object._$getBounds(null); - const matrix2: Matrix = object._$transform.concatenatedMatrix; - const bounds2: BoundsImpl = $boundsMatrix(baseBounds2, matrix2._$matrix); - - // pool - $poolMatrix(matrix2); - $poolBoundsObject(baseBounds2); - - // calc - const sx: number = $Math.max(bounds1.xMin, bounds2.xMin); - const sy: number = $Math.max(bounds1.yMin, bounds2.yMin); - const ex: number = $Math.min(bounds1.xMax, bounds2.xMax); - const ey: number = $Math.min(bounds1.yMax, bounds2.yMax); - - // pool - $poolBoundsObject(bounds1); - $poolBoundsObject(bounds2); - - return ex - sx >= 0 && ey - sy >= 0; - } - - /** - * @description 表示オブジェクトを評価して、x および y パラメーターで指定された - * ポイントと重複または交差するかどうかを調べます。 - * Evaluates the display object to see if it overlaps - * or intersects with the point specified by the x and y parameters. - * - * @param {number} x - * @param {number} y - * @param {boolean} [shape_flag=false] - * @returns {boolean} - * @public - */ - hitTestPoint ( - x: number, y: number, - shape_flag: boolean = false - ): boolean { - - if (shape_flag) { - - let matrix: Float32Array = $MATRIX_ARRAY_IDENTITY; - - let parent: ParentImpl | null = this._$parent; - while (parent) { - - matrix = $multiplicationMatrix( - parent._$transform._$rawMatrix(), - matrix - ); - - parent = parent._$parent; - } - - $hitContext.setTransform(1, 0, 0, 1, 0, 0); - $hitContext.beginPath(); - - let result: boolean = false; - if ("_$hit" in this && typeof this._$hit === "function") { - result = this._$hit($hitContext, matrix, { "x": x, "y": y }, true); - } - - if (matrix !== $MATRIX_ARRAY_IDENTITY) { - $poolFloat32Array6(matrix); - } - - return result; - } - - const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" - ? this._$getBounds() as BoundsImpl - : $getBoundsObject(); - - const bounds: BoundsImpl = $boundsMatrix(baseBounds, this._$transform._$rawMatrix()); - $poolBoundsObject(baseBounds); - - const rectangle: Rectangle = new Rectangle( - bounds.xMin, bounds.yMin, - bounds.xMax - bounds.xMin, - bounds.yMax - bounds.yMin - ); - - // pool - $poolBoundsObject(bounds); - - const point: Point = this._$parent - ? this._$parent.globalToLocal(new Point(x, y)) - : new Point(x, y); - - return rectangle.containsPoint(point); - } - - /** - * @description point オブジェクトを表示オブジェクトの(ローカル)座標から - * ステージ(グローバル)座標に変換します。 - * Converts the point object from the display object's (local) coordinates - * to the Stage (global) coordinates. - * - * - * @param {Point} point - * @returns {Point} - * @public - */ - localToGlobal (point: Point): Point - { - const matrix: Matrix = this - ._$transform - .concatenatedMatrix; - - const newPoint: Point = new Point( - point.x * matrix.a + point.y * matrix.c + matrix.tx, - point.x * matrix.b + point.y * matrix.d + matrix.ty - ); - - $poolMatrix(matrix); - - return newPoint; - } - - /** - * @description クラスのローカル変数空間から値を取得 - * Get a value from the local variable space of the class - * - * @param {*} key - * @return {*} - * @method - * @public - */ - getLocalVariable (key: any): any - { - if (!this._$variables) { - return null; - } - - if (this._$variables.has(key)) { - return this._$variables.get(key); - } - } - - /** - * @description クラスのローカル変数空間へ値を保存 - * Store values in the local variable space of the class - * - * @param {*} key - * @param {*} value - * @return {void} - * @method - * @public - */ - setLocalVariable (key: any, value: any): void - { - if (!this._$variables) { - this._$variables = $getMap(); - } - this._$variables.set(key, value); - } - - /** - * @description クラスのローカル変数空間に値があるかどうかを判断します。 - * Determines if there is a value in the local variable space of the class. - * - * @param {*} key - * @return {boolean} - * @method - * @public - */ - hasLocalVariable (key: any): boolean - { - return this._$variables - ? this._$variables.has(key) - : false; - } - - /** - * @description クラスのローカル変数空間の値を削除 - * Remove values from the local variable space of a class - * - * @param {*} key - * @return {void} - * @method - * @public - */ - deleteLocalVariable (key: any): void - { - if (this._$variables && this._$variables.has(key)) { - this._$variables.delete(key); - if (!this._$variables.size) { - $poolMap(this._$variables); - this._$variables = null; - } - } - } - - /** - * @description グローバル変数空間から値を取得 - * Get a value from the global variable space - * - * @param {*} key - * @return {*} - * @method - * @public - */ - getGlobalVariable (key: any): any - { - if ($variables.has(key)) { - return $variables.get(key); - } - return null; - } - - /** - * @description グローバル変数空間へ値を保存 - * Save values to global variable space - * - * @param {*} key - * @param {*} value - * @return {void} - * @method - * @public - */ - setGlobalVariable (key: any, value: any): void - { - $variables.set(key, value); - } - - /** - * @description グローバル変数空間に値があるかどうかを判断します。 - * Determines if there is a value in the global variable space. - * - * @param {*} key - * @return {boolean} - * @method - * @public - */ - hasGlobalVariable (key: any): boolean - { - return $variables.has(key); - } - - /** - * @description グローバル変数空間の値を削除 - * Remove values from global variable space. - * - * @param {*} key - * @return {void} - * @method - * @public - */ - deleteGlobalVariable (key: any): void - { - if ($variables.has(key)) { - $variables.delete(key); - } - } - - /** - * @description グローバル変数空間に値を全てクリアします。 - * Clear all values in the global variable space. - * - * @return {void} - * @method - * @public - */ - clearGlobalVariable (): void - { - return $variables.clear(); - } - - /** - * @return {object} - * @method - * @private - */ - _$getPlaceObject (): PlaceObjectImpl | null - { - if (!this._$placeObject) { - - const placeId = this._$placeId; - if (placeId === -1) { - return null; - } - - const parent: ParentImpl | null = this._$parent; - if (!parent || !parent._$placeObjects) { - return null; - } - - const placeMap: Array> | null = parent._$placeMap; - if (!placeMap || !placeMap.length) { - return null; - } - - const frame: number = "currentFrame" in parent ? parent.currentFrame : 1; - const places: number[] | void = placeMap[frame]; - if (!places) { - return null; - } - - const currentPlaceId: number = places[placeId] | 0; - const placeObject: PlaceObjectImpl | void = parent._$placeObjects[currentPlaceId]; - if (!placeObject) { - return null; - } - - this._$changePlace = currentPlaceId !== this._$currentPlaceId; - this._$currentPlaceId = currentPlaceId; - this._$placeObject = placeObject; - - return placeObject; - } - - return this._$placeObject; - } - - /** - * @param {object} tag - * @param {DisplayObjectContainer} parent - * @return {object} - * @method - * @private - */ - _$baseBuild ( - tag: DictionaryTagImpl, - parent: ParentImpl - ): T { - - const loaderInfo: LoaderInfo | null = parent._$loaderInfo; - if (!loaderInfo || !loaderInfo._$data) { - throw new Error("the loaderInfo or data is nul."); - } - - // setup - this._$parent = parent; - this._$root = parent._$root; - this._$stage = parent._$stage; - this._$loaderInfo = loaderInfo; - - // bind tag data - this._$characterId = tag.characterId | 0; - this._$clipDepth = tag.clipDepth | 0; - this._$startFrame = tag.startFrame | 0; - this._$endFrame = tag.endFrame | 0; - this._$name = tag.name || ""; - - return loaderInfo._$data.characters[tag.characterId]; - } - - /** - * @return {boolean} - * @method - * @private - */ - _$isUpdated (): boolean - { - return this._$updated; - } - - /** - * @return {void} - * @method - * @private - */ - _$updateState (): void - { - this._$isNext = true; - - const parent: ParentImpl | null = this._$parent; - if (parent) { - parent._$updateState(); - } - } - - /** - * @return {void} - * @method - * @private - */ - _$doChanged (): void - { - this._$posted = false; - this._$isNext = true; - this._$updated = true; - - const parent: ParentImpl | null = this._$parent; - if (parent) { - if (!parent._$updated) { - parent._$doChanged(); - } - } - } - - /** - * @param {CanvasToWebGLContext} context - * @param {Float32Array} matrix - * @param {array} filters - * @param {number} width - * @param {number} height - * @param {WebGLTexture} [target_texture = null] - * @return {object} - * @method - * @private - */ - _$drawFilter ( - context: CanvasToWebGLContext, - matrix: Float32Array, - filters: FilterArrayImpl, - width: number, - height: number, - target_texture: WebGLTexture | null = null - ): CachePositionImpl { - - const cacheKeys: any[] = $getArray(this._$instanceId, "f"); - let position: CachePositionImpl | void = $cacheStore.get(cacheKeys); - - const updated: boolean = this._$isFilterUpdated(matrix, filters, true); - - if (position && !updated) { - context.cachePosition = position; - return position; - } - - // cache clear - if (position) { - $cacheStore.set(cacheKeys, null); - } - - const manager: FrameBufferManager = context.frameBuffer; - const targetTexture: WebGLTexture = target_texture - ? target_texture - : context.getTextureFromRect( - context.cachePosition as NonNullable - ); - - const texture: WebGLTexture = this._$applyFilter( - context, filters, targetTexture, - matrix, width, height - ); - manager.textureManager.release(targetTexture); - - const bounds: BoundsImpl = this._$getLayerBounds(matrix); - position = manager.createCachePosition( - $Math.ceil($Math.abs(bounds.xMax - bounds.xMin)), - $Math.ceil($Math.abs(bounds.yMax - bounds.yMin)) - ); - $poolBoundsObject(bounds); - - position.filterState = true; - position.matrix = `${matrix[0]}_${matrix[1]}_${matrix[2]}_${matrix[3]}_0_0`; - position.offsetX = texture.offsetX; - position.offsetY = texture.offsetY; - - // 関数先でtextureがreleaseされる - context.drawTextureFromRect(texture, position); - - $cacheStore.set(cacheKeys, position); - $poolArray(cacheKeys); - - return position; - } - - /** - * @param {Float32Array} multi_matrix - * @returns {object} - * @private - */ - _$getLayerBounds (multi_matrix: Float32Array): BoundsImpl - { - const baseBounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" - ? this._$getBounds() as BoundsImpl - : $getBoundsObject(); - - const bounds: BoundsImpl = $boundsMatrix(baseBounds, multi_matrix); - $poolBoundsObject(baseBounds); - - const filters: FilterArrayImpl = this._$filters || this.filters; - if (!filters.length) { - return bounds; - } - - let filterBounds: BoundsImpl = $getBoundsObject( - 0, - $Math.abs(bounds.xMax - bounds.xMin), - 0, - $Math.abs(bounds.yMax - bounds.yMin) - ); - $poolBoundsObject(bounds); - - let xScale: number = +$Math.sqrt( - multi_matrix[0] * multi_matrix[0] - + multi_matrix[1] * multi_matrix[1] - ); - let yScale: number = +$Math.sqrt( - multi_matrix[2] * multi_matrix[2] - + multi_matrix[3] * multi_matrix[3] - ); - - xScale /= $devicePixelRatio; - yScale /= $devicePixelRatio; - - xScale *= 2; - yScale *= 2; - - for (let idx: number = 0; idx < filters.length; ++idx) { - filterBounds = filters[idx] - ._$generateFilterRect(filterBounds, xScale, yScale); - } - - return filterBounds; - } - - /** - * @return {void} - * @method - * @private - */ - _$executeAddedEvent (): void - { - if (!this._$parent) { - return ; - } - - // add event - if (!this._$added) { - - // added event - if (this.willTrigger(Next2DEvent.ADDED)) { - this.dispatchEvent(new Next2DEvent(Next2DEvent.ADDED, true)); - } - - // update - this._$added = true; - } - - if (!this._$addedStage && this._$stage !== null) { - - if (this.willTrigger(Next2DEvent.ADDED_TO_STAGE)) { - this.dispatchEvent(new Next2DEvent(Next2DEvent.ADDED_TO_STAGE)); - } - - // update - this._$addedStage = true; - } - } - - /** - * @return {void} - * @method - * @private - */ - _$prepareActions (): void - { - this._$nextFrame(); - } - - /** - * @return {boolean} - * @method - * @private - */ - _$nextFrame (): boolean - { - // added event - this._$executeAddedEvent(); - - this._$isNext = false; - - if (!this._$posted && $rendererWorker) { - // @ts-ignore - this._$postProperty(); - } - - return false; - } - - /** - * @param {array} [filters=null] - * @return {boolean} - * @private - */ - _$canApply (filters: FilterArrayImpl | null = null): boolean - { - if (filters) { - for (let idx: number = 0; idx < filters.length; ++idx) { - if (filters[idx]._$canApply()) { - return true; - } - } - } - return false; - } - - /** - * @param {Float32Array} matrix - * @param {array} [filters=null] - * @param {boolean} [can_apply=false] - * @param {number} [position_x=0] - * @param {number} [position_y=0] - * @return {boolean} - * @private - */ - _$isFilterUpdated ( - matrix: Float32Array, - filters: FilterArrayImpl | null = null, - can_apply: boolean = false - ): boolean { - - // cache flag - if (this._$isUpdated()) { - return true; - } - - // check filter data - if (can_apply && filters) { - - for (let idx: number = 0; idx < filters.length; ++idx) { - - if (!filters[idx]._$isUpdated()) { - continue; - } - - return true; - } - - } - - // check status - const cache: CachePositionImpl = $cacheStore.get([this._$instanceId, "f"]); - if (!cache) { - return true; - } - - if (cache.filterState !== can_apply) { - return true; - } - - if (cache.matrix !== `${matrix[0]}_${matrix[1]}_${matrix[2]}_${matrix[3]}`) { - return true; - } - - return false; - } - - /** - * @param {CanvasToWebGLContext} context - * @param {array} filters - * @param {WebGLTexture} target_texture - * @param {Float32Array} matrix - * @param {number} width - * @param {number} height - * @return {WebGLTexture} - * @private - */ - _$applyFilter ( - context: CanvasToWebGLContext, - filters: FilterArrayImpl, - target_texture: WebGLTexture, - matrix: Float32Array, - width: number, - height: number - ): WebGLTexture { - - const xScale: number = +$Math.sqrt( - matrix[0] * matrix[0] - + matrix[1] * matrix[1] - ); - const yScale: number = +$Math.sqrt( - matrix[2] * matrix[2] - + matrix[3] * matrix[3] - ); - - const radianX: number = $Math.atan2(matrix[1], matrix[0]); - const radianY: number = $Math.atan2(-matrix[2], matrix[3]); - - const parentMatrix: Float32Array = $getFloat32Array6( - $Math.cos(radianX), $Math.sin(radianX), - -$Math.sin(radianY), $Math.cos(radianY), - width / 2, height / 2 - ); - - const baseMatrix: Float32Array = $getFloat32Array6( - 1, 0, 0, 1, - -target_texture.width / 2, - -target_texture.height / 2 - ); - - const multiMatrix: Float32Array = $multiplicationMatrix( - parentMatrix, baseMatrix - ); - $poolFloat32Array6(parentMatrix); - $poolFloat32Array6(baseMatrix); - - const manager: FrameBufferManager = context.frameBuffer; - const currentAttachment: AttachmentImpl | null = manager.currentAttachment; - - const attachment: AttachmentImpl = manager - .createCacheAttachment(width, height); - context._$bind(attachment); - - context.reset(); - context.setTransform( - multiMatrix[0], multiMatrix[1], - multiMatrix[2], multiMatrix[3], - multiMatrix[4], multiMatrix[5] - ); - $poolFloat32Array6(multiMatrix); - - context.drawImage(target_texture, - 0, 0, target_texture.width, target_texture.height - ); - - // init - context._$offsetX = 0; - context._$offsetY = 0; - - const filterMatrix: Float32Array = $getFloat32Array6( - xScale, 0, 0, yScale, 0, 0 - ); - - let texture: WebGLTexture | null = null; - for (let idx: number = 0; idx < filters.length; ++idx) { - texture = filters[idx]._$applyFilter(context, filterMatrix); - } - - $poolFloat32Array6(filterMatrix); - - if (!texture) { - return target_texture; - } - - const offsetX: number = context._$offsetX; - const offsetY: number = context._$offsetY; - - // reset - context._$offsetX = 0; - context._$offsetY = 0; - - // set offset - texture.offsetX = offsetX; - texture.offsetY = offsetY; - - context._$bind(currentAttachment); - manager.releaseAttachment(attachment, false); - - return texture; - } - - /** - * @param {Float32Array} matrix - * @return {boolean} - * @method - * @private - */ - _$shouldClip (matrix: Float32Array): boolean - { - const bounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" - ? this._$getBounds(matrix) as BoundsImpl - : $getBoundsObject(); - - const width = $Math.abs(bounds.xMax - bounds.xMin); - const height = $Math.abs(bounds.yMax - bounds.yMin); - $poolBoundsObject(bounds); - - // size 0 - return !(!width || !height); - } - - /** - * @param {CanvasToWebGLContext} context - * @param {Float32Array} matrix - * @return {boolean} - * @method - * @private - */ - _$startClip ( - context: CanvasToWebGLContext, - matrix: Float32Array - ): boolean { - - context.drawInstacedArray(); - - // マスクの描画反映を限定 - const bounds: BoundsImpl = "_$getBounds" in this && typeof this._$getBounds === "function" - ? this._$getBounds(matrix) as BoundsImpl - : $getBoundsObject(); - - const result = context._$startClip(bounds); - $poolBoundsObject(bounds); - - if (!result) { - return false; - } - - // start clip - context._$enterClip(); - - // mask start - context._$beginClipDef(); - - let containerClip = false; - if ("_$children" in this) { - containerClip = true; - context._$updateContainerClipFlag(true); - } - - // @ts-ignore - this._$clip(context, matrix); - this._$updated = false; - - // container clip - if (containerClip) { - - // update flag - context._$updateContainerClipFlag(false); - - // execute clip - context._$drawContainerClip(); - } - - // mask end - context._$endClipDef(); - - return true; - } - - /** - * @return {void} - * @method - * @private - */ - _$removeWorkerInstance (): void - { - if ($rendererWorker) { - $rendererWorker.postMessage({ - "command": "remove", - "instanceId": this._$instanceId - }); - } - } - - /** - * @param {Float32Array} buffer - * @param {number} [index = 0] - * @return {void} - * @method - * @private - */ - _$registerProperty (buffer: Float32Array, index: number = 0): void - { - // visible - buffer[index++] = +this._$visible; - - // depth - buffer[index++] = this._$placeId; - - // clip depth - buffer[index++] = this._$clipDepth; - - // isMask - buffer[index++] = +this._$isMask; - - const mask: DisplayObjectImpl | null = this._$mask; - buffer[index++] = +(mask !== null); - if (mask) { - - // mask id - buffer[index++] = mask._$instanceId; - - let maskMatrix: Float32Array = $MATRIX_ARRAY_IDENTITY; - let parent: ParentImpl | null = mask._$parent; - while (parent) { - - maskMatrix = $multiplicationMatrix( - parent._$transform._$rawMatrix(), - maskMatrix - ); - - parent = parent._$parent; - } - - // mask matrix - buffer[index++] = maskMatrix[0]; - buffer[index++] = maskMatrix[1]; - buffer[index++] = maskMatrix[2]; - buffer[index++] = maskMatrix[3]; - buffer[index++] = maskMatrix[4]; - buffer[index++] = maskMatrix[5]; - } else { - index += 7; - } - - if (this._$visible) { - const transform: Transform = this._$transform; - - // matrix - const matrix: Float32Array = transform._$rawMatrix(); - buffer[index++] = matrix[0]; - buffer[index++] = matrix[1]; - buffer[index++] = matrix[2]; - buffer[index++] = matrix[3]; - buffer[index++] = matrix[4]; - buffer[index++] = matrix[5]; - - // colorTransform - const colorTransform = transform._$rawColorTransform(); - buffer[index++] = colorTransform[0]; - buffer[index++] = colorTransform[1]; - buffer[index++] = colorTransform[2]; - buffer[index++] = colorTransform[3]; - buffer[index++] = colorTransform[4]; - buffer[index++] = colorTransform[5]; - buffer[index++] = colorTransform[6]; - buffer[index++] = colorTransform[7]; - - } else { - index += 6; // matrix - index += 8; // colorTransform - } - - // blend mode - const blendMode: BlendModeImpl = this._$blendMode || this.blendMode; - buffer[index++] = $blendToNumber(blendMode); - - // scale9Grid - const scale9Grid: Rectangle | null = this._$scale9Grid; - buffer[index++] = +(scale9Grid !== null); - - if (scale9Grid) { - buffer[index++] = scale9Grid.x; - buffer[index++] = scale9Grid.y; - buffer[index++] = scale9Grid.width; - buffer[index++] = scale9Grid.height; - } else { - index += 4; - } - - // filter - } - - /** - * @return {object} - * @method - * @private - */ - _$createMessage (): PropertyMessageMapImpl - { - const message: PropertyMessageImpl = { - "command": "setProperty", - "buffer": new Float32Array(), - "instanceId": this._$instanceId, - "parentId": this._$parent ? this._$parent._$instanceId : -1, - "visible": this._$visible - }; - - if (this._$placeId > -1) { - message.depth = this._$placeId; - } - - if (this._$clipDepth) { - message.clipDepth = this._$clipDepth; - } - - if (this._$isMask) { - message.isMask = this._$isMask; - } - - const mask: DisplayObjectImpl | null = this._$mask; - if (mask) { - message.maskId = mask._$instanceId; - - let maskMatrix: Float32Array = $MATRIX_ARRAY_IDENTITY; - let parent: ParentImpl | null = mask._$parent; - while (parent) { - - maskMatrix = $multiplicationMatrix( - parent._$transform._$rawMatrix(), - maskMatrix - ); - - parent = parent._$parent; - } - - message.maskMatrix = maskMatrix; - } - - if (this._$visible) { - - const transform: Transform = this._$transform; - - const matrix: Float32Array = transform._$rawMatrix(); - if (matrix[0] !== 1) { - message.a = matrix[0]; - } - - if (matrix[1] !== 0) { - message.b = matrix[1]; - } - - if (matrix[2] !== 0) { - message.c = matrix[2]; - } - - if (matrix[3] !== 1) { - message.d = matrix[3]; - } - - if (matrix[4] !== 0) { - message.tx = matrix[4]; - } - - if (matrix[5] !== 0) { - message.ty = matrix[5]; - } - - const colorTransform = transform._$rawColorTransform(); - if (colorTransform[0] !== 1) { - message.f0 = colorTransform[0]; - } - - if (colorTransform[1] !== 1) { - message.f1 = colorTransform[1]; - } - - if (colorTransform[2] !== 1) { - message.f2 = colorTransform[2]; - } - - if (colorTransform[3] !== 1) { - message.f3 = colorTransform[3]; - } - - if (colorTransform[4] !== 0) { - message.f4 = colorTransform[4]; - } - - if (colorTransform[5] !== 0) { - message.f5 = colorTransform[5]; - } - - if (colorTransform[6] !== 0) { - message.f6 = colorTransform[6]; - } - - if (colorTransform[7] !== 0) { - message.f7 = colorTransform[7]; - } - - const filters: FilterArrayImpl | null = this._$filters || this.filters; - if (filters && filters.length) { - const parameters: any[] = $getArray(); - for (let idx: number = 0; idx < filters.length; ++idx) { - parameters.push(filters[idx]._$toArray()); - } - - message.filters = parameters; - } - - const blendMode: BlendModeImpl = this._$blendMode || this.blendMode; - if (blendMode !== "normal") { - message.blendMode = blendMode; - } - - const scale9Grid: Rectangle | null = this._$scale9Grid; - if (scale9Grid && this._$isUpdated()) { - - const baseMatrix: Matrix = this - ._$parent - ._$transform - .concatenatedMatrix; - - message.matrixBase = baseMatrix._$matrix.slice(); - $poolMatrix(baseMatrix); - - message.grid = { - "x": scale9Grid.x, - "y": scale9Grid.y, - "w": scale9Grid.width, - "h": scale9Grid.height - }; - } - } - - return message; - } + // return message; + // } } diff --git a/packages/display/src/DisplayObject/DisplayObjectGetPlaceObjectService.ts b/packages/display/src/DisplayObject/DisplayObjectGetPlaceObjectService.ts new file mode 100644 index 00000000..e4c1b5de --- /dev/null +++ b/packages/display/src/DisplayObject/DisplayObjectGetPlaceObjectService.ts @@ -0,0 +1,53 @@ +import type { DisplayObjectImpl } from "../interface/DisplayObjectImpl"; +import type { PlaceObjectImpl } from "../interface/PlaceObjectImpl"; +import type { ParentImpl } from "../interface/ParentImpl"; + +/** + * @description DisplayObjectのPlaceObjectを返却、存在しない場合はnullを返却 + * Return the PlaceObject of the DisplayObject, or return null if it does not exist. + * + * @param {DisplayObject} display_object + * @return {object} + * @method + * @protected + */ +export const execute = (display_object: DisplayObjectImpl): PlaceObjectImpl | null => +{ + // キャッシュされたPlaceObjectがあれば返却 + const placeObject: PlaceObjectImpl | null = display_object._$placeObject; + if (placeObject) { + return placeObject; + } + + const placeId = display_object._$placeId; + if (placeId === -1) { + return null; + } + + const parent: ParentImpl | null = display_object.parent; + if (!parent || !parent._$placeObjects) { + return null; + } + + const placeMap: Array> | null = parent._$placeMap; + if (!placeMap || !placeMap.length) { + return null; + } + + const frame: number = "currentFrame" in parent ? parent.currentFrame : 1; + const places: number[] | void = placeMap[frame]; + if (!places) { + return null; + } + + const targetPlaceId: number = places[placeId] | 0; + const targetPlaceObject: PlaceObjectImpl | void = parent._$placeObjects[targetPlaceId]; + if (!targetPlaceObject) { + return null; + } + + // キャッシュ + display_object._$placeObject = targetPlaceObject; + + return null; +}; \ No newline at end of file diff --git a/packages/display/src/DisplayObject/DisplayObjectGetRawMatrixService.ts b/packages/display/src/DisplayObject/DisplayObjectGetRawMatrixService.ts new file mode 100644 index 00000000..9cb3d3e2 --- /dev/null +++ b/packages/display/src/DisplayObject/DisplayObjectGetRawMatrixService.ts @@ -0,0 +1,47 @@ +import type { Matrix } from "@next2d/geom"; +import type { PlaceObjectImpl } from "../interface/PlaceObjectImpl"; +import type { DisplayObjectImpl } from "../interface/DisplayObjectImpl"; +import { execute as displayObjectGetPlaceObjectService } from "./DisplayObjectGetPlaceObjectService"; +import { $getFloat32Array6 } from "../DisplayObjectUtil"; + +/** + * @type {Float32Array} + * @const + */ +const $MATRIX_ARRAY_IDENTITY: Float32Array = new Float32Array([1, 0, 0, 1, 0, 0]); + +/** + * @description DisplayObjectの内部Float32Arrayデータを返却、存在しない場合は固定のFloat32Arrayデータを返却 + * Return the internal Float32Array data of the DisplayObject, + * or return a fixed Float32Array data if it does not exist. + * + * @param {DisplayObject} display_object + * @param {Matrix | null} [matrix=null] + * @return {Float32Array} + * @method + * @protected + */ +export const execute = ( + display_object: DisplayObjectImpl, + matrix: Matrix | null = null +): Float32Array => { + + if (matrix) { + return matrix.rawData; + } + + const placeObject: PlaceObjectImpl | null = displayObjectGetPlaceObjectService(display_object); + if (!placeObject || !placeObject.matrix) { + return $MATRIX_ARRAY_IDENTITY; + } + + if (!placeObject.typedMatrix) { + const matrix: number[] = placeObject.matrix; + placeObject.typedMatrix = $getFloat32Array6( + matrix[0], matrix[1], matrix[2], + matrix[3], matrix[4], matrix[5] + ); + } + + return placeObject.typedMatrix; +}; \ No newline at end of file diff --git a/packages/display/src/DisplayObjectContainer.ts b/packages/display/src/DisplayObjectContainer.ts index 92a2d815..1af55957 100644 --- a/packages/display/src/DisplayObjectContainer.ts +++ b/packages/display/src/DisplayObjectContainer.ts @@ -1,78 +1,31 @@ import { InteractiveObject } from "./InteractiveObject"; -import { Event as Next2DEvent } from "@next2d/events"; -import type { LoaderInfo } from "./LoaderInfo"; -import type { Player } from "@next2d/core"; -import type { Sound } from "@next2d/media"; -import type { Transform } from "@next2d/geom"; -import type { - DictionaryTagImpl, - PlaceObjectImpl, - DisplayObjectImpl, - BoundsImpl, - FilterArrayImpl, - LoopConfigImpl, - ParentImpl, - PreObjectImpl, - AttachmentImpl, - BlendModeImpl, - PlayerHitObjectImpl, - PropertyMessageMapImpl, - PropertyContainerMessageImpl, - Character -} from "@next2d/interface"; -import type { - CanvasToWebGLContext, - FrameBufferManager -} from "@next2d/webgl"; +// import { Event as Next2DEvent } from "@next2d/events"; +// import type { LoaderInfo } from "./LoaderInfo"; +// import type { Sound } from "@next2d/media"; +// import type { Transform } from "@next2d/geom"; +import type { PlaceObjectImpl } from "./interface/PlaceObjectImpl"; +import type { DisplayObjectImpl } from "./interface/DisplayObjectImpl"; +import type { DictionaryTagImpl } from "./interface/DictionaryTagImpl"; +// import type { +// CanvasToWebGLContext, +// FrameBufferManager +// } from "@next2d/webgl"; import { - $createInstance, - $currentPlayer, - $getRenderBufferArray, - $getRenderMessageObject, - $hitContext, - $isTouch, - $MATRIX_HIT_ARRAY_IDENTITY, - $poolRenderMessageObject, - $rendererWorker -} from "@next2d/util"; -import { - $cacheStore, - $doUpdated, - $boundsMatrix, - $clamp, - $getArray, - $getBoundsObject, - $getFloat32Array6, - $getFloat32Array8, - $getMap, - $getPreObject, - $Math, - $COLOR_ARRAY_IDENTITY, - $MATRIX_ARRAY_IDENTITY, - $multiplicationColor, - $multiplicationMatrix, - $Number, - $poolArray, - $poolBoundsObject, - $poolFloat32Array6, - $poolFloat32Array8, - $poolMap, - $poolPreObject, - $devicePixelRatio -} from "@next2d/share"; + $getArray +} from "./DisplayObjectUtil"; /** - * DisplayObjectContainer クラスは、表示リストで表示オブジェクトコンテナとして機能するすべてのオブジェクトの基本クラスです。 - * このクラス自体は、画面上でのコンテンツの描画のための API を含みません。 - * そのため、DisplayObject クラスのカスタムサブクラスを作成する場合は、 - * Sprite、または MovieClip など、画面上にコンテンツを描画する API を持つサブクラスの 1 つを拡張する必要があります。 + * @description DisplayObjectContainer クラスは、表示リストで表示オブジェクトコンテナとして機能するすべてのオブジェクトの基本クラスです。 + * このクラス自体は、画面上でのコンテンツの描画のための API を含みません。 + * そのため、DisplayObject クラスのカスタムサブクラスを作成する場合は、 + * Sprite、または MovieClip など、画面上にコンテンツを描画する API を持つサブクラスの 1 つを拡張する必要があります。 * - * The DisplayObjectContainer class is the base class for all objects that can serve - * as display object containers on the display list. - * This class itself does not contain any API for drawing content on the screen. - * Therefore, if you want to create a custom subclass of the DisplayObject class, - * you need to extend one of its subclasses that has an API for drawing content on the screen, - * such as Sprite or MovieClip. + * The DisplayObjectContainer class is the base class for all objects that can serve + * as display object containers on the display list. + * This class itself does not contain any API for drawing content on the screen. + * Therefore, if you want to create a custom subclass of the DisplayObject class, + * you need to extend one of its subclasses that has an API for drawing content on the screen, + * such as Sprite or MovieClip. * * @class * @memberOf next2d.display @@ -157,7 +110,7 @@ export class DisplayObjectContainer extends InteractiveObject * @type {Map} * @private */ - this._$names = $getMap(); + this._$names = new Map(); return new Proxy(this, { "get": (object: this, name: string): any => @@ -187,2088 +140,1984 @@ export class DisplayObjectContainer extends InteractiveObject this._$mouseChildren = !!mouse_children; } - /** - * @description このオブジェクトの子の数を返します。 - * Returns the number of children of this object. - * - * @member {number} - * @readonly - * @public - */ - get numChildren (): number - { - return this._$needsChildren - ? this._$getChildren().length - : this._$children.length; - } - - /** - * @description この DisplayObjectContainer インスタンスに子 DisplayObject インスタンスを追加します。 - * Adds a child DisplayObject instance to this DisplayObjectContainer instance. - * - * @param {DisplayObject} child - * @return {DisplayObject} - * @method - * @public - */ - addChild (child: DisplayObjectImpl): DisplayObjectImpl - { - if (child._$parent) { - child._$parent._$remove(child, - !(child._$parent._$instanceId === this._$instanceId) - ); - } - - this._$getChildren().push(child); - - if (child._$name) { - this._$names.set(child._$name, child); - } - - return this._$addChild(child); - } - - /** - * @description この DisplayObjectContainer インスタンスに子 DisplayObject インスタンスを追加します。 - * Adds a child DisplayObject instance to this DisplayObjectContainer instance. - * - * @param {DisplayObject} child - * @param {number} index - * @return {DisplayObject} - * @method - * @public - */ - addChildAt ( - child: DisplayObjectImpl, - index: number - ): DisplayObjectImpl { - - if (child._$parent) { - child._$parent._$remove(child, - !(child._$parent._$instanceId === this._$instanceId) - ); - } - - const children: DisplayObjectImpl[] = this._$getChildren(); - const length: number = children.length; - if (0 > index || index > length) { - throw new RangeError(`RangeError: addChildAt: index error: ${index}`); - } - - if (length && length > index) { - - children.splice(index, 0, child); - - for (let idx: number = 0; idx < index; ++idx) { - const instance: DisplayObjectImpl = children[idx]; - if (instance._$name) { - this._$names.set(instance._$name, instance); - } - } - - } else { - - children.push(child); - if (child._$name) { - this._$names.set(child._$name, child); - } - - } - - return this._$addChild(child); - } - - /** - * @description 指定された表示オブジェクトが、DisplayObjectContainer インスタンスの子であるか - * インスタンス自体であるかを指定します。 - * Determines whether the specified display object is a child - * of the DisplayObjectContainer instance or the instance itself. - * - * @param {DisplayObject} child - * @return {boolean} - * @method - * @public - */ - contains (child: DisplayObjectImpl): boolean - { - if (this._$instanceId === child._$instanceId) { - return true; - } - - const children: DisplayObjectImpl[] = this._$getChildren(); - for (let idx: number = 0; idx < children.length; ++idx) { - - const instance: DisplayObjectImpl = children[idx]; - - if (instance._$instanceId === child._$instanceId) { - return true; - } - - if (instance instanceof DisplayObjectContainer) { - - if (instance.contains(child)) { - return true; - } - - } - - } - - return false; - } - - /** - * @description 指定のインデックス位置にある子表示オブジェクトインスタンスを返します。 - * Returns the child display object instance that exists at the specified index. - * - * @param {number} index - * @return {DisplayObject} - * @method - * @public - */ - getChildAt (index: number): DisplayObjectImpl - { - const children: DisplayObjectImpl[] = this._$getChildren(); - - if (0 > index || index > children.length) { - throw new RangeError(`RangeError: getChildAt: index error: ${index}`); - } - - return index in children ? children[index] : null; - } - - /** - * @description 指定された名前に一致する子表示オブジェクトを返します。 - * Returns the child display object that exists with the specified name. - * - * @param {string} name - * @return {{DisplayObject}|null} - * @method - * @public - */ - getChildByName (name: string): DisplayObjectImpl | null - { - if (!name) { - return null; - } - - // fixed logic - const children: DisplayObjectImpl[] = this._$getChildren(); - for (let idx: number = 0; idx < children.length; ++idx) { - - const child: DisplayObjectImpl = children[idx]; - if (child.name !== name) { - continue; - } - - return child; - } - - return null; - } - - /** - * @description 子 DisplayObject インスタンスのインデックス位置を返します。 - * Returns the index position of a child DisplayObject instance. - * - * @param {DisplayObject} child - * @return {number} - * @method - * @public - */ - getChildIndex (child: DisplayObjectImpl): number - { - if (child._$parent !== this) { - throw new Error("ArgumentError: getChildIndex: not child"); - } - - const index: number = this._$getChildren().indexOf(child); - if (index === -1) { - throw new Error("ArgumentError: getChildIndex: not found."); - } - - return index; - } - - /** - * @description DisplayObjectContainer インスタンスの子リストから指定の - * child DisplayObject インスタンスを削除します。 - * Removes the specified child DisplayObject instance from the - * child list of the DisplayObjectContainer instance. - * - * @param {DisplayObject} child - * @return {DisplayObject} - * @method - * @public - */ - removeChild (child: DisplayObjectImpl): DisplayObjectImpl - { - if (child._$parent !== this) { - throw new Error("ArgumentError: removeChild: not child"); - } - return this._$remove(child); - } - - /** - * @description DisplayObjectContainer の子リストの指定された index 位置から子 DisplayObject を削除します。 - * Removes a child DisplayObject from the specified index position - * in the child list of the DisplayObjectContainer. - * - * @param {number} index - * @return {DisplayObject} - * @method - * @public - */ - removeChildAt (index: number): DisplayObjectImpl - { - return this._$remove(this.getChildAt(index)); - } - - /** - * @description DisplayObjectContainer インスタンスの子リストから - * すべての child DisplayObject インスタンスを削除します。 - * Removes all child DisplayObject instances from - * the child list of the DisplayObjectContainer instance. - * - * @param {number} [begin_index=0] - * @param {number} [end_index=0x7fffffff] - * @return {void} - * @method - * @public - */ - removeChildren ( - begin_index: number = 0, - end_index: number = 0x7fffffff - ): void { - - const children: DisplayObjectImpl[] = this._$getChildren(); - if (!children.length) { - return ; - } - - begin_index = $clamp(begin_index, 0, 0x7ffffffe, 0) - 1; - end_index = $clamp(end_index, 1, 0x7ffffff, 0x7ffffff); - - for (let idx: number = $Math.min(end_index, children.length - 1); idx > begin_index; --idx) { - this._$remove(children[idx]); - } - } - - /** - * @description 表示オブジェクトコンテナの既存の子の位置を変更します。 - * Changes the position of an existing child in the display object container. - * - * @param {DisplayObject} child - * @param {number} index - * @return {void} - * @method - * @public - */ - setChildIndex ( - child: DisplayObjectImpl, - index: number - ): void { - - const currentIndex: number = this.getChildIndex(child); - if (currentIndex === index) { - return ; - } - - const children: DisplayObjectImpl[] = this._$getChildren(); - children.splice(currentIndex, 1); - children.splice(index, 0, child); - - if ($rendererWorker) { - this._$postChildrenIds(); - } - - this._$doChanged(); - } - - /** - * @description 指定された 2 つの子オブジェクトの z 順序(重ね順)を入れ替えます。 - * Swaps the z-order (front-to-back order) of the two specified child objects. - * - * @param {DisplayObject} child1 - * @param {DisplayObject} child2 - * @return {void} - * @method - * @public - */ - swapChildren ( - child1: DisplayObjectImpl, - child2: DisplayObjectImpl - ): void { - - const children: DisplayObjectImpl[] = this._$getChildren(); - const index1: number = this.getChildIndex(child1); - const index2: number = this.getChildIndex(child2); - - children[index1] = child2; - children[index2] = child1; - - if ($rendererWorker) { - this._$postChildrenIds(); - } - - this._$doChanged(); - } - - /** - * @description 子リスト内の指定されたインデックス位置に該当する 2 つの子オブジェクトの z 順序(重ね順)を入れ替えます。 - * Swaps the z-order (front-to-back order) of the child objects at - * the two specified index positions in the child list. - * - * @param {number} index1 - * @param {number} index2 - * @return {void} - * @method - * @public - */ - swapChildrenAt (index1: number, index2: number): void - { - this.swapChildren( - this.getChildAt(index1), - this.getChildAt(index2) - ); - } - - /** - * @param {array} [matrix=null] - * @return {object} - * @private - */ - _$getBounds (matrix: Float32Array | null = null): BoundsImpl - { - let multiMatrix: Float32Array = $MATRIX_ARRAY_IDENTITY; - if (matrix) { - - multiMatrix = matrix; - - const rawMatrix: Float32Array = this._$transform._$rawMatrix(); - if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 - || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 - || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 - ) { - multiMatrix = $multiplicationMatrix(matrix, rawMatrix); - } - } - - const children: DisplayObjectImpl[] = this._$needsChildren - ? this._$getChildren() - : this._$children; - - // size zero - if (!children.length) { - - const bounds: BoundsImpl = $getBoundsObject( - multiMatrix[4], -multiMatrix[4], - multiMatrix[5], -multiMatrix[5] - ); - - if (matrix && multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - - return bounds; - } - - // data init - const no = $Number.MAX_VALUE; - let xMin = no; - let xMax = -no; - let yMin = no; - let yMax = -no; - for (let idx: number = 0; idx < children.length; ++idx) { - - const bounds: BoundsImpl = children[idx]._$getBounds(multiMatrix); - - xMin = $Math.min(xMin, bounds.xMin); - xMax = $Math.max(xMax, bounds.xMax); - yMin = $Math.min(yMin, bounds.yMin); - yMax = $Math.max(yMax, bounds.yMax); - - $poolBoundsObject(bounds); - - } - - if (matrix && multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - - // end - return $getBoundsObject(xMin, xMax, yMin, yMax); - } - - /** - * @param {Float32Array} multi_matrix - * @return {object} - * @private - */ - _$getLayerBounds (multi_matrix: Float32Array): BoundsImpl - { - - const children: DisplayObjectImpl[] = this._$needsChildren - ? this._$getChildren() - : this._$children; - - // size zero - if (!children.length) { - return $getBoundsObject(0, 0, 0, 0); - } - - // data init - const no: number = $Number.MAX_VALUE; - let xMin: number = no; - let xMax: number = -no; - let yMin: number = no; - let yMax: number = -no; - for (let idx: number = 0; idx < children.length; ++idx) { - - const instance = children[idx]; - - let multiMatrix = multi_matrix; - const rawMatrix: Float32Array = instance._$transform._$rawMatrix(); - if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 - || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 - || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 - ) { - multiMatrix = $multiplicationMatrix(multi_matrix, rawMatrix); - } - - const bounds: BoundsImpl = instance._$getLayerBounds(multiMatrix); - - xMin = $Math.min(xMin, bounds.xMin); - xMax = $Math.max(xMax, bounds.xMax); - yMin = $Math.min(yMin, bounds.yMin); - yMax = $Math.max(yMax, bounds.yMax); - - $poolBoundsObject(bounds); - - if (multiMatrix !== multi_matrix) { - $poolFloat32Array6(multiMatrix); - } - } - - const filters: FilterArrayImpl = this._$filters || this.filters; - if (!filters.length) { - return $getBoundsObject(xMin, xMax, yMin, yMax); - } - - let filterBounds: BoundsImpl = $getBoundsObject( - 0, xMax - xMin, - 0, yMax - yMin - ); - - let xScale: number = +$Math.sqrt( - multi_matrix[0] * multi_matrix[0] - + multi_matrix[1] * multi_matrix[1] - ); - let yScale: number = +$Math.sqrt( - multi_matrix[2] * multi_matrix[2] - + multi_matrix[3] * multi_matrix[3] - ); - - xScale /= $devicePixelRatio; - yScale /= $devicePixelRatio; - - xScale *= 2; - yScale *= 2; - - for (let idx: number = 0; idx < filters.length; ++idx) { - filterBounds = filters[idx] - ._$generateFilterRect(filterBounds, xScale, yScale); - } - - xMax += filterBounds.xMax - (xMax - xMin); - yMax += filterBounds.yMax - (yMax - yMin); - xMin += filterBounds.xMin; - yMin += filterBounds.yMin; - - $poolBoundsObject(filterBounds); - - return $getBoundsObject(xMin, xMax, yMin, yMax); - } - - /** - * @return {array} - * @private - */ - _$getChildren (): DisplayObjectImpl[] - { - if (this._$needsChildren) { - - // set flag - this._$needsChildren = false; - - const currentChildren: DisplayObjectImpl[] = this._$children; - if (!this._$controller) { - return currentChildren; - } - - const frame: number = "_$currentFrame" in this ? this._$currentFrame as number : 1; - const controller: number[] = this._$controller[frame]; - - // first build - if (!currentChildren.length) { - - if (controller) { - - for (let idx: number = 0; idx < controller.length; ++idx) { - - const dictionaryId = controller[idx]; - if (typeof dictionaryId !== "number") { - continue; - } - - const instance: DisplayObjectImpl = this._$createInstance(dictionaryId); - instance._$placeId = idx; - - const loopConfig: LoopConfigImpl | null = instance.loopConfig; - if (loopConfig) { - instance._$currentFrame = instance - ._$getLoopFrame(loopConfig); - } - - currentChildren.push(instance); - if (instance._$name) { - this._$names.set(instance._$name, instance); - } - } - } - - return currentChildren; - } - - const useWorker: boolean = !!$rendererWorker && !!this._$stage; - - const skipIds: Map = $getMap(); - const poolInstances: Map> = $getMap(); - - let depth: number = 0; - const children: DisplayObjectImpl[] = $getArray(); - for (let idx: number = 0; idx < currentChildren.length; ++idx) { - - const instance: DisplayObjectImpl = currentChildren[idx]; - - const parent: ParentImpl = instance._$parent; - if (!parent || parent._$instanceId !== this._$instanceId) { - continue; - } - - const instanceId: number = instance._$instanceId; - const startFrame: number = instance._$startFrame; - const endFrame: number = instance._$endFrame; - if (startFrame === 1 && endFrame === 0 - || startFrame <= frame && endFrame > frame - ) { - - // reset - instance._$isNext = true; - instance._$placeObject = null; - instance._$filters = null; - instance._$blendMode = null; - - if (instance._$id === -1) { - - children.push(instance); - if (instance._$name) { - this._$names.set(instance._$name, instance); - } - - continue; - } - - const id: number = controller[depth]; - if (instance._$id === id) { - - instance._$placeId = depth; - children.push(instance); - - if (instance._$name) { - this._$names.set(instance._$name, instance); - } - - if (poolInstances.has(id)) { - poolInstances.delete(id); - } - - skipIds.set(id, true); - depth++; + // /** + // * @description このオブジェクトの子の数を返します。 + // * Returns the number of children of this object. + // * + // * @member {number} + // * @readonly + // * @public + // */ + // get numChildren (): number + // { + // return this._$needsChildren + // ? this._$getChildren().length + // : this._$children.length; + // } + + // /** + // * @description この DisplayObjectContainer インスタンスに子 DisplayObject インスタンスを追加します。 + // * Adds a child DisplayObject instance to this DisplayObjectContainer instance. + // * + // * @param {DisplayObject} child + // * @return {DisplayObject} + // * @method + // * @public + // */ + // addChild (child: DisplayObjectImpl): DisplayObjectImpl + // { + // if (child._$parent) { + // child._$parent._$remove(child, + // !(child._$parent._$instanceId === this._$instanceId) + // ); + // } + + // this._$getChildren().push(child); + + // if (child._$name) { + // this._$names.set(child._$name, child); + // } + + // return this._$addChild(child); + // } + + // /** + // * @description この DisplayObjectContainer インスタンスに子 DisplayObject インスタンスを追加します。 + // * Adds a child DisplayObject instance to this DisplayObjectContainer instance. + // * + // * @param {DisplayObject} child + // * @param {number} index + // * @return {DisplayObject} + // * @method + // * @public + // */ + // addChildAt ( + // child: DisplayObjectImpl, + // index: number + // ): DisplayObjectImpl { + + // if (child._$parent) { + // child._$parent._$remove(child, + // !(child._$parent._$instanceId === this._$instanceId) + // ); + // } + + // const children: DisplayObjectImpl[] = this._$getChildren(); + // const length: number = children.length; + // if (0 > index || index > length) { + // throw new RangeError(`RangeError: addChildAt: index error: ${index}`); + // } + + // if (length && length > index) { + + // children.splice(index, 0, child); + + // for (let idx: number = 0; idx < index; ++idx) { + // const instance: DisplayObjectImpl = children[idx]; + // if (instance._$name) { + // this._$names.set(instance._$name, instance); + // } + // } + + // } else { + + // children.push(child); + // if (child._$name) { + // this._$names.set(child._$name, child); + // } + + // } + + // return this._$addChild(child); + // } + + // /** + // * @description 指定された表示オブジェクトが、DisplayObjectContainer インスタンスの子であるか + // * インスタンス自体であるかを指定します。 + // * Determines whether the specified display object is a child + // * of the DisplayObjectContainer instance or the instance itself. + // * + // * @param {DisplayObject} child + // * @return {boolean} + // * @method + // * @public + // */ + // contains (child: DisplayObjectImpl): boolean + // { + // if (this._$instanceId === child._$instanceId) { + // return true; + // } + + // const children: DisplayObjectImpl[] = this._$getChildren(); + // for (let idx: number = 0; idx < children.length; ++idx) { + + // const instance: DisplayObjectImpl = children[idx]; + + // if (instance._$instanceId === child._$instanceId) { + // return true; + // } + + // if (instance instanceof DisplayObjectContainer) { + + // if (instance.contains(child)) { + // return true; + // } + + // } + + // } + + // return false; + // } + + // /** + // * @description 指定のインデックス位置にある子表示オブジェクトインスタンスを返します。 + // * Returns the child display object instance that exists at the specified index. + // * + // * @param {number} index + // * @return {DisplayObject} + // * @method + // * @public + // */ + // getChildAt (index: number): DisplayObjectImpl + // { + // const children: DisplayObjectImpl[] = this._$getChildren(); + + // if (0 > index || index > children.length) { + // throw new RangeError(`RangeError: getChildAt: index error: ${index}`); + // } + + // return index in children ? children[index] : null; + // } + + // /** + // * @description 指定された名前に一致する子表示オブジェクトを返します。 + // * Returns the child display object that exists with the specified name. + // * + // * @param {string} name + // * @return {{DisplayObject}|null} + // * @method + // * @public + // */ + // getChildByName (name: string): DisplayObjectImpl | null + // { + // if (!name) { + // return null; + // } + + // // fixed logic + // const children: DisplayObjectImpl[] = this._$getChildren(); + // for (let idx: number = 0; idx < children.length; ++idx) { + + // const child: DisplayObjectImpl = children[idx]; + // if (child.name !== name) { + // continue; + // } + + // return child; + // } + + // return null; + // } + + // /** + // * @description 子 DisplayObject インスタンスのインデックス位置を返します。 + // * Returns the index position of a child DisplayObject instance. + // * + // * @param {DisplayObject} child + // * @return {number} + // * @method + // * @public + // */ + // getChildIndex (child: DisplayObjectImpl): number + // { + // if (child._$parent !== this) { + // throw new Error("ArgumentError: getChildIndex: not child"); + // } + + // const index: number = this._$getChildren().indexOf(child); + // if (index === -1) { + // throw new Error("ArgumentError: getChildIndex: not found."); + // } + + // return index; + // } + + // /** + // * @description DisplayObjectContainer インスタンスの子リストから指定の + // * child DisplayObject インスタンスを削除します。 + // * Removes the specified child DisplayObject instance from the + // * child list of the DisplayObjectContainer instance. + // * + // * @param {DisplayObject} child + // * @return {DisplayObject} + // * @method + // * @public + // */ + // removeChild (child: DisplayObjectImpl): DisplayObjectImpl + // { + // if (child._$parent !== this) { + // throw new Error("ArgumentError: removeChild: not child"); + // } + // return this._$remove(child); + // } + + // /** + // * @description DisplayObjectContainer の子リストの指定された index 位置から子 DisplayObject を削除します。 + // * Removes a child DisplayObject from the specified index position + // * in the child list of the DisplayObjectContainer. + // * + // * @param {number} index + // * @return {DisplayObject} + // * @method + // * @public + // */ + // removeChildAt (index: number): DisplayObjectImpl + // { + // return this._$remove(this.getChildAt(index)); + // } + + // /** + // * @description DisplayObjectContainer インスタンスの子リストから + // * すべての child DisplayObject インスタンスを削除します。 + // * Removes all child DisplayObject instances from + // * the child list of the DisplayObjectContainer instance. + // * + // * @param {number} [begin_index=0] + // * @param {number} [end_index=0x7fffffff] + // * @return {void} + // * @method + // * @public + // */ + // removeChildren ( + // begin_index: number = 0, + // end_index: number = 0x7fffffff + // ): void { + + // const children: DisplayObjectImpl[] = this._$getChildren(); + // if (!children.length) { + // return ; + // } + + // begin_index = $clamp(begin_index, 0, 0x7ffffffe, 0) - 1; + // end_index = $clamp(end_index, 1, 0x7ffffff, 0x7ffffff); + + // for (let idx: number = $Math.min(end_index, children.length - 1); idx > begin_index; --idx) { + // this._$remove(children[idx]); + // } + // } + + // /** + // * @description 表示オブジェクトコンテナの既存の子の位置を変更します。 + // * Changes the position of an existing child in the display object container. + // * + // * @param {DisplayObject} child + // * @param {number} index + // * @return {void} + // * @method + // * @public + // */ + // setChildIndex ( + // child: DisplayObjectImpl, + // index: number + // ): void { + + // const currentIndex: number = this.getChildIndex(child); + // if (currentIndex === index) { + // return ; + // } + + // const children: DisplayObjectImpl[] = this._$getChildren(); + // children.splice(currentIndex, 1); + // children.splice(index, 0, child); + + // if ($rendererWorker) { + // this._$postChildrenIds(); + // } + + // this._$doChanged(); + // } + + // /** + // * @description 指定された 2 つの子オブジェクトの z 順序(重ね順)を入れ替えます。 + // * Swaps the z-order (front-to-back order) of the two specified child objects. + // * + // * @param {DisplayObject} child1 + // * @param {DisplayObject} child2 + // * @return {void} + // * @method + // * @public + // */ + // swapChildren ( + // child1: DisplayObjectImpl, + // child2: DisplayObjectImpl + // ): void { + + // const children: DisplayObjectImpl[] = this._$getChildren(); + // const index1: number = this.getChildIndex(child1); + // const index2: number = this.getChildIndex(child2); + + // children[index1] = child2; + // children[index2] = child1; + + // if ($rendererWorker) { + // this._$postChildrenIds(); + // } + + // this._$doChanged(); + // } + + // /** + // * @description 子リスト内の指定されたインデックス位置に該当する 2 つの子オブジェクトの z 順序(重ね順)を入れ替えます。 + // * Swaps the z-order (front-to-back order) of the child objects at + // * the two specified index positions in the child list. + // * + // * @param {number} index1 + // * @param {number} index2 + // * @return {void} + // * @method + // * @public + // */ + // swapChildrenAt (index1: number, index2: number): void + // { + // this.swapChildren( + // this.getChildAt(index1), + // this.getChildAt(index2) + // ); + // } + + // /** + // * @param {array} [matrix=null] + // * @return {object} + // * @private + // */ + // _$getBounds (matrix: Float32Array | null = null): BoundsImpl + // { + // let multiMatrix: Float32Array = $MATRIX_ARRAY_IDENTITY; + // if (matrix) { + + // multiMatrix = matrix; + + // const rawMatrix: Float32Array = this._$transform._$rawMatrix(); + // if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + // || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + // || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + // ) { + // multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + // } + // } + + // const children: DisplayObjectImpl[] = this._$needsChildren + // ? this._$getChildren() + // : this._$children; + + // // size zero + // if (!children.length) { + + // const bounds: BoundsImpl = $getBoundsObject( + // multiMatrix[4], -multiMatrix[4], + // multiMatrix[5], -multiMatrix[5] + // ); + + // if (matrix && multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + + // return bounds; + // } + + // // data init + // const no = $Number.MAX_VALUE; + // let xMin = no; + // let xMax = -no; + // let yMin = no; + // let yMax = -no; + // for (let idx: number = 0; idx < children.length; ++idx) { + + // const bounds: BoundsImpl = children[idx]._$getBounds(multiMatrix); + + // xMin = $Math.min(xMin, bounds.xMin); + // xMax = $Math.max(xMax, bounds.xMax); + // yMin = $Math.min(yMin, bounds.yMin); + // yMax = $Math.max(yMax, bounds.yMax); + + // $poolBoundsObject(bounds); + + // } + + // if (matrix && multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + + // // end + // return $getBoundsObject(xMin, xMax, yMin, yMax); + // } + + // /** + // * @param {Float32Array} multi_matrix + // * @return {object} + // * @private + // */ + // _$getLayerBounds (multi_matrix: Float32Array): BoundsImpl + // { + + // const children: DisplayObjectImpl[] = this._$needsChildren + // ? this._$getChildren() + // : this._$children; + + // // size zero + // if (!children.length) { + // return $getBoundsObject(0, 0, 0, 0); + // } + + // // data init + // const no: number = $Number.MAX_VALUE; + // let xMin: number = no; + // let xMax: number = -no; + // let yMin: number = no; + // let yMax: number = -no; + // for (let idx: number = 0; idx < children.length; ++idx) { + + // const instance = children[idx]; + + // let multiMatrix = multi_matrix; + // const rawMatrix: Float32Array = instance._$transform._$rawMatrix(); + // if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + // || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + // || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + // ) { + // multiMatrix = $multiplicationMatrix(multi_matrix, rawMatrix); + // } + + // const bounds: BoundsImpl = instance._$getLayerBounds(multiMatrix); + + // xMin = $Math.min(xMin, bounds.xMin); + // xMax = $Math.max(xMax, bounds.xMax); + // yMin = $Math.min(yMin, bounds.yMin); + // yMax = $Math.max(yMax, bounds.yMax); + + // $poolBoundsObject(bounds); + + // if (multiMatrix !== multi_matrix) { + // $poolFloat32Array6(multiMatrix); + // } + // } + + // const filters: FilterArrayImpl = this._$filters || this.filters; + // if (!filters.length) { + // return $getBoundsObject(xMin, xMax, yMin, yMax); + // } + + // let filterBounds: BoundsImpl = $getBoundsObject( + // 0, xMax - xMin, + // 0, yMax - yMin + // ); + + // let xScale: number = +$Math.sqrt( + // multi_matrix[0] * multi_matrix[0] + // + multi_matrix[1] * multi_matrix[1] + // ); + // let yScale: number = +$Math.sqrt( + // multi_matrix[2] * multi_matrix[2] + // + multi_matrix[3] * multi_matrix[3] + // ); + + // xScale /= $devicePixelRatio; + // yScale /= $devicePixelRatio; + + // xScale *= 2; + // yScale *= 2; + + // for (let idx: number = 0; idx < filters.length; ++idx) { + // filterBounds = filters[idx] + // ._$generateFilterRect(filterBounds, xScale, yScale); + // } + + // xMax += filterBounds.xMax - (xMax - xMin); + // yMax += filterBounds.yMax - (yMax - yMin); + // xMin += filterBounds.xMin; + // yMin += filterBounds.yMin; + + // $poolBoundsObject(filterBounds); + + // return $getBoundsObject(xMin, xMax, yMin, yMax); + // } + + // /** + // * @return {array} + // * @private + // */ + // _$getChildren (): DisplayObjectImpl[] + // { + // if (this._$needsChildren) { + + // // set flag + // this._$needsChildren = false; + + // const currentChildren: DisplayObjectImpl[] = this._$children; + // if (!this._$controller) { + // return currentChildren; + // } + + // const frame: number = "_$currentFrame" in this ? this._$currentFrame as number : 1; + // const controller: number[] = this._$controller[frame]; + + // // first build + // if (!currentChildren.length) { - if (useWorker) { - instance._$postProperty(); - } + // if (controller) { + + // for (let idx: number = 0; idx < controller.length; ++idx) { + + // const dictionaryId = controller[idx]; + // if (typeof dictionaryId !== "number") { + // continue; + // } + + // const instance: DisplayObjectImpl = this._$createInstance(dictionaryId); + // instance._$placeId = idx; + + // const loopConfig: LoopConfigImpl | null = instance.loopConfig; + // if (loopConfig) { + // instance._$currentFrame = instance + // ._$getLoopFrame(loopConfig); + // } + + // currentChildren.push(instance); + // if (instance._$name) { + // this._$names.set(instance._$name, instance); + // } + // } + // } + + // return currentChildren; + // } + + // const useWorker: boolean = !!$rendererWorker && !!this._$stage; + + // const skipIds: Map = $getMap(); + // const poolInstances: Map> = $getMap(); + + // let depth: number = 0; + // const children: DisplayObjectImpl[] = $getArray(); + // for (let idx: number = 0; idx < currentChildren.length; ++idx) { + + // const instance: DisplayObjectImpl = currentChildren[idx]; + + // const parent: ParentImpl = instance._$parent; + // if (!parent || parent._$instanceId !== this._$instanceId) { + // continue; + // } + + // const instanceId: number = instance._$instanceId; + // const startFrame: number = instance._$startFrame; + // const endFrame: number = instance._$endFrame; + // if (startFrame === 1 && endFrame === 0 + // || startFrame <= frame && endFrame > frame + // ) { + + // // reset + // instance._$isNext = true; + // instance._$placeObject = null; + // instance._$filters = null; + // instance._$blendMode = null; + + // if (instance._$id === -1) { + + // children.push(instance); + // if (instance._$name) { + // this._$names.set(instance._$name, instance); + // } + + // continue; + // } + + // const id: number = controller[depth]; + // if (instance._$id === id) { + + // instance._$placeId = depth; + // children.push(instance); + + // if (instance._$name) { + // this._$names.set(instance._$name, instance); + // } + + // if (poolInstances.has(id)) { + // poolInstances.delete(id); + // } + + // skipIds.set(id, true); + // depth++; + + // if (useWorker) { + // instance._$postProperty(); + // } + + // continue; + // } + + // poolInstances.set(instance._$id, instance); + + // continue; + // } + + // if (useWorker) { + // instance._$removeWorkerInstance(); + // } + + // $cacheStore.setRemoveTimer(instanceId); + // if (instance._$loaderInfo && instance._$characterId) { + // $cacheStore.setRemoveTimer( + // `${instance._$loaderInfo._$id}@${instance._$characterId}` + // ); + // } + // if (instance._$graphics) { + // $cacheStore.setRemoveTimer(instance._$graphics._$uniqueKey); + // } + + // // remove event + // if (instance.willTrigger(Next2DEvent.REMOVED)) { + // instance.dispatchEvent( + // new Next2DEvent(Next2DEvent.REMOVED, true) + // ); + // } + // if (instance.willTrigger(Next2DEvent.REMOVED_FROM_STAGE)) { + // instance.dispatchEvent( + // new Next2DEvent(Next2DEvent.REMOVED_FROM_STAGE, true) + // ); + // } + + // // reset + // instance._$added = false; + // instance._$addedStage = false; + // instance._$active = false; + // instance._$updated = true; + // instance._$filters = null; + // instance._$blendMode = null; + // instance._$isNext = true; + // instance._$placeObject = null; + // instance._$created = false; + // instance._$posted = false; + + // if (instance instanceof DisplayObjectContainer) { + // instance._$executeRemovedFromStage(); + // instance._$removeParentAndStage(); + // } + + // } + + // if (controller) { + + // for (let idx: number = 0; idx < controller.length; ++idx) { + + // const dictionaryId: number = controller[idx]; + // if (typeof dictionaryId !== "number" || skipIds.has(dictionaryId)) { + // continue; + // } + + // const instance: DisplayObjectImpl = poolInstances.has(dictionaryId) + // ? poolInstances.get(dictionaryId) + // : this._$createInstance(dictionaryId); + + // instance._$placeId = idx; + + // const loopConfig: LoopConfigImpl | null = instance.loopConfig; + // if (loopConfig) { + // instance._$currentFrame = instance + // ._$getLoopFrame(loopConfig); + // } + + // children.push(instance); + // if (instance._$name) { + // this._$names.set(instance._$name, instance); + // } + + // } + // } + + // // object pool + // $poolMap(skipIds); + // $poolMap(poolInstances); + + // // update + // currentChildren.length = 0; + // currentChildren.push(...children); + // $poolArray(children); + // } + + // return this._$children; + // } + + // /** + // * @return void + // * @private + // */ + // _$clearChildren (): void + // { + // this._$doChanged(); + // $doUpdated(); + + // // reset + // this._$names.clear(); + + // // clear + // this._$needsChildren = true; + // } + + // /** + // * @param {DisplayObject} child + // * @returns {DisplayObject} + // * @private + // */ + // _$addChild (child: DisplayObjectImpl): DisplayObjectImpl + // { + // // init + // child._$parent = this; + // if (!child._$stage || !child._$root) { + // child._$stage = this._$stage; + // child._$root = this._$root; + // } + + // // setup + // if (child instanceof DisplayObjectContainer) { + // child._$setParentAndStage(); + // child._$wait = true; + // } + + // // added event + // if (!child._$added) { + // if (child.willTrigger(Next2DEvent.ADDED)) { + // child.dispatchEvent( + // new Next2DEvent(Next2DEvent.ADDED, true) + // ); + // } + // child._$added = true; + // } + + // if (this._$stage !== null && !child._$addedStage) { + + // if (child.willTrigger(Next2DEvent.ADDED_TO_STAGE)) { + // child.dispatchEvent( + // new Next2DEvent(Next2DEvent.ADDED_TO_STAGE) + // ); + // } + + // child._$addedStage = true; + + // // set params + // if (child instanceof DisplayObjectContainer) { + // child._$executeAddedToStage(); + // } + + // if ($rendererWorker) { + // child._$createWorkerInstance(); + // this._$postChildrenIds(); + // } + // } + + // this._$doChanged(); + // child._$active = true; + // child._$updated = true; + // child._$isNext = true; + + // return child; + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$setParentAndStage (): void + // { + // const children: DisplayObjectImpl[] = this._$needsChildren + // ? this._$getChildren() + // : this._$children; + + // for (let idx: number = 0; idx < children.length; ++idx) { + + // const instance: DisplayObjectImpl = children[idx]; + + // instance._$root = this._$root; + // instance._$stage = this._$stage; + + // if (instance instanceof DisplayObjectContainer) { + // instance._$setParentAndStage(); + // instance._$wait = true; + // } + + // } + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$executeAddedToStage (): void + // { + // const children: DisplayObjectImpl[] = this._$needsChildren + // ? this._$getChildren() + // : this._$children; + + // const childrenIds: number[] = $getArray(); + + // for (let idx: number = 0; idx < children.length; ++idx) { + + // const instance: DisplayObjectImpl = children[idx]; + // if (!instance) { + // continue; + // } + + // childrenIds.push(instance._$instanceId); + // if (!instance._$addedStage) { + + // if ($rendererWorker) { + // instance._$createWorkerInstance(); + // } + + // if (instance.willTrigger(Next2DEvent.ADDED_TO_STAGE)) { + // instance.dispatchEvent( + // new Next2DEvent(Next2DEvent.ADDED_TO_STAGE) + // ); + // } + + // instance._$addedStage = true; + // } + + // if (instance instanceof DisplayObjectContainer) { + // instance._$executeAddedToStage(); + // } + + // } + + // if ($rendererWorker) { + // this._$postChildrenIds(childrenIds); + // } + + // $poolArray(childrenIds); + // } + + // /** + // * @param {DisplayObject} child + // * @param {boolean} do_event + // * @return {DisplayObject} + // * @private + // */ + // _$remove ( + // child: DisplayObjectImpl, + // do_event: boolean = true + // ): DisplayObjectImpl { + + // child._$transform._$transform(); + + // // remove all broadcast events + // if (child.hasEventListener(Next2DEvent.ENTER_FRAME)) { + // child.removeAllEventListener(Next2DEvent.ENTER_FRAME); + // } + + // if (child.hasEventListener(Next2DEvent.EXIT_FRAME)) { + // child.removeAllEventListener(Next2DEvent.EXIT_FRAME); + // } + + // if (child.hasEventListener(Next2DEvent.FRAME_CONSTRUCTED)) { + // child.removeAllEventListener(Next2DEvent.FRAME_CONSTRUCTED); + // } + + // if (child.hasEventListener(Next2DEvent.RENDER)) { + // child.removeAllEventListener(Next2DEvent.RENDER); + // } + + // if (child.hasEventListener(Next2DEvent.ACTIVATE)) { + // child.removeAllEventListener(Next2DEvent.ACTIVATE); + // } + + // if (child.hasEventListener(Next2DEvent.DEACTIVATE)) { + // child.removeAllEventListener(Next2DEvent.DEACTIVATE); + // } + + // if (child.hasEventListener("keyDown")) { + // child.removeAllEventListener("keyDown"); + // } + + // if (child.hasEventListener("keyUp")) { + // child.removeAllEventListener("keyUp"); + // } + + // // remove + // const children: DisplayObjectImpl[] = this._$needsChildren + // ? this._$getChildren() + // : this._$children; + + // const depth: number = this.getChildIndex(child); + // children.splice(depth, 1); + + // this._$names.delete(child.name); + // if (do_event) { + + // // event + // if (child.willTrigger(Next2DEvent.REMOVED)) { + // child.dispatchEvent( + // new Next2DEvent(Next2DEvent.REMOVED, true) + // ); + // } + + // // remove stage event + // if (this._$stage !== null) { + + // // worker側のDisplayObjectも削除 + // if ($rendererWorker) { + // child._$removeWorkerInstance(); + // this._$postChildrenIds(); + // } + + // if (child.willTrigger(Next2DEvent.REMOVED_FROM_STAGE)) { + // child.dispatchEvent( + // new Next2DEvent(Next2DEvent.REMOVED_FROM_STAGE) + // ); + // } + + // if (child instanceof DisplayObjectContainer) { + // child._$executeRemovedFromStage(); + // } + // } + + // $cacheStore.setRemoveTimer(child._$instanceId); + // if (child._$loaderInfo && child._$characterId) { + // $cacheStore.setRemoveTimer( + // `${child._$loaderInfo._$id}@${child._$characterId}` + // ); + // } + // if (child._$graphics) { + // $cacheStore.setRemoveTimer(child._$graphics._$uniqueKey); + // } + + // // reset params + // if (child instanceof DisplayObjectContainer) { + // child._$removeParentAndStage(); + // } + + // // reset + // child._$stage = null; + // child._$parent = null; + // child._$root = null; + // child._$active = false; + // child._$wait = true; + // child._$updated = true; + // child._$added = false; + // child._$addedStage = false; + // child._$created = false; + // child._$posted = false; + // this._$doChanged(); + + // } + + // return child; + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$executeRemovedFromStage (): void + // { + // const children: DisplayObjectImpl[] = this._$getChildren().slice(0); + // for (let idx: number = 0; idx < children.length; ++idx) { + + // const instance: DisplayObjectImpl = children[idx]; + // if (!instance) { + // continue; + // } + + // if (instance._$addedStage) { + + // // workerのDisplayObjectを削除 + // if ($rendererWorker) { + // instance._$removeWorkerInstance(); + // } + + // if (instance.willTrigger(Next2DEvent.REMOVED_FROM_STAGE)) { + // instance.dispatchEvent( + // new Next2DEvent(Next2DEvent.REMOVED_FROM_STAGE) + // ); + // } + + // instance._$created = false; + // instance._$posted = false; + // instance._$addedStage = false; + // } + + // if (instance instanceof DisplayObjectContainer) { + // instance._$executeRemovedFromStage(); + // } + + // } + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$removeParentAndStage (): void + // { + // const children: DisplayObjectImpl[] = this._$needsChildren + // ? this._$getChildren() + // : this._$children; + + // for (let idx: number = 0; idx < children.length; ++idx) { + + // const instance: DisplayObjectImpl = children[idx]; + + // $cacheStore.setRemoveTimer(instance._$instanceId); + // if (instance._$loaderInfo && instance._$characterId) { + // $cacheStore.setRemoveTimer( + // `${instance._$loaderInfo._$id}@${instance._$characterId}` + // ); + // } + // if (instance._$graphics) { + // $cacheStore.setRemoveTimer(instance._$graphics._$uniqueKey); + // } + + // if (instance instanceof DisplayObjectContainer) { + // instance._$removeParentAndStage(); + // } + + // instance._$stage = null; + // instance._$root = null; + // instance._$addedStage = false; + // } + + // if ("_$sounds" in this) { + // const soundsMap: Map = this._$sounds as Map; + // if (soundsMap.size) { + // for (const sounds of soundsMap.values()) { + // for (let idx: number = 0; idx < sounds.length; ++idx) { + // const sound: Sound = sounds[idx]; + // sound.stop(); + // } + // } + // } + // } + + // this._$needsChildren = true; + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$prepareActions (): void + // { + // const children: DisplayObjectImpl[] = this._$needsChildren + // ? this._$getChildren() + // : this._$children; + + // for (let idx: number = children.length - 1; idx > -1; --idx) { + // children[idx]._$prepareActions(); + // } + + // // added event + // this._$executeAddedEvent(); + // } + + // /** + // * @return {boolean} + // * @method + // * @private + // */ + // _$nextFrame (): boolean + // { + // let isNext: boolean = false; + + // const children: DisplayObjectImpl[] = this._$getChildren(); + // for (let idx: number = children.length - 1; idx > -1; --idx) { + + // const child: DisplayObjectImpl = children[idx]; + // if (!child._$isNext) { + // continue; + // } + + // if (isNext) { + + // child._$nextFrame(); + + // } else { + + // isNext = child._$nextFrame(); + + // } + // } + + // // added event + // this._$executeAddedEvent(); + + // this._$isNext = isNext; + + // if (!this._$posted && $rendererWorker) { + // this._$postProperty(); + // } + + // return this._$isNext; + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @return {void} + // * @method + // * @private + // */ + // _$clip ( + // context: CanvasToWebGLContext, + // matrix: Float32Array + // ): void { + + // let multiMatrix: Float32Array = matrix; + + // const rawMatrix: Float32Array = this._$transform._$rawMatrix(); + // if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + // || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + // || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + // ) { + // multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + // } + + // const children: DisplayObjectImpl[] = this._$getChildren(); + // for (let idx: number = 0; idx < children.length; ++idx) { + + // const instance: DisplayObjectImpl = children[idx]; + + // // mask instance + // if (instance._$isMask) { + // continue; + // } + + // instance._$clip(context, multiMatrix); + // instance._$updated = false; + + // } + + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @return {object} + // * @private + // */ + // _$preDraw ( + // context: CanvasToWebGLContext, + // matrix: Float32Array + // ): PreObjectImpl | null { + + // let multiMatrix: Float32Array = matrix; + // const rawMatrix: Float32Array = this._$transform._$rawMatrix(); + // if (rawMatrix !== $MATRIX_HIT_ARRAY_IDENTITY + // && rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + // || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + // || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + // ) { + // multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + // } + + // // size zero + // if (!multiMatrix[0] && !multiMatrix[1] + // || !multiMatrix[2] && !multiMatrix[3] + // ) { + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + // return null; + // } + + // // return object + // const object: PreObjectImpl = $getPreObject(); + + // // setup + // object.matrix = multiMatrix; + + // // check + // const filters: FilterArrayImpl = this._$filters || this.filters; + // const blendMode: BlendModeImpl = this._$blendMode || this.blendMode; + // if (filters.length > 0 || blendMode !== "normal") { + + // // check size + // const baseBounds: BoundsImpl = this._$getBounds(null); + // const bounds: BoundsImpl = $boundsMatrix(baseBounds, multiMatrix); + // $poolBoundsObject(baseBounds); + + // const xMax: number = +bounds.xMax; + // const xMin: number = +bounds.xMin; + // const yMax: number = +bounds.yMax; + // const yMin: number = +bounds.yMin; + // $poolBoundsObject(bounds); + + // const width: number = $Math.ceil($Math.abs(xMax - xMin)); + // const height: number = $Math.ceil($Math.abs(yMax - yMin)); + // if (0 >= width || 0 >= height) { + // $poolPreObject(object); + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + // return null; + // } + + // let xScale: number = +$Math.sqrt( + // multiMatrix[0] * multiMatrix[0] + // + multiMatrix[1] * multiMatrix[1] + // ); + // if (!$Number.isInteger(xScale)) { + // const value: string = xScale.toString(); + // const index: number = value.indexOf("e"); + // if (index !== -1) { + // xScale = +value.slice(0, index); + // } + // xScale = +xScale.toFixed(4); + // } + + // let yScale: number = +$Math.sqrt( + // multiMatrix[2] * multiMatrix[2] + // + multiMatrix[3] * multiMatrix[3] + // ); + // if (!$Number.isInteger(yScale)) { + // const value: string = yScale.toString(); + // const index: number = value.indexOf("e"); + // if (index !== -1) { + // yScale = +value.slice(0, index); + // } + // yScale = +yScale.toFixed(4); + // } + + // object.canApply = this._$canApply(filters); + // let filterBounds: BoundsImpl = $getBoundsObject(0, width, 0, height); + // if (object.canApply && filters) { + // for (let idx: number = 0; idx < filters.length ; ++idx) { + // filterBounds = filters[idx] + // ._$generateFilterRect(filterBounds, xScale, yScale); + // } + // } + + // const currentAttachment: AttachmentImpl | null = context + // .frameBuffer + // .currentAttachment; + + // if (!currentAttachment + // || !currentAttachment.texture + // || xMin - filterBounds.xMin > currentAttachment.width + // || yMin - filterBounds.yMin > currentAttachment.height + // ) { + // $poolBoundsObject(filterBounds); + // $poolPreObject(object); + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + // return null; + // } + + // if (0 > xMin + filterBounds.xMax || 0 > yMin + filterBounds.yMax) { + // $poolBoundsObject(filterBounds); + // $poolPreObject(object); + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + // return null; + // } + + // // move size + // let tx: number = multiMatrix[4] - xMin; + // let ty: number = multiMatrix[5] - yMin; + + // // start layer + // context._$startLayer( + // $getBoundsObject(xMin, xMax, yMin, yMax) + // ); + + // // check cache + // const updated: boolean = this._$isFilterUpdated( + // multiMatrix, filters, object.canApply + // ); + + // const layerBounds: BoundsImpl = this._$getLayerBounds(multiMatrix); + + // const layerWidth: number = $Math.ceil($Math.abs(layerBounds.xMax - layerBounds.xMin)); + // const layerHeight: number = $Math.ceil($Math.abs(layerBounds.yMax - layerBounds.yMin)); + // $poolBoundsObject(layerBounds); + + // const sw = layerWidth - filterBounds.xMax + filterBounds.xMin; + // const sh = layerHeight - filterBounds.yMax + filterBounds.yMin; + + // tx += sw; + // ty += sh; + + // object.sw = sw; + // object.sh = sh; + // if (updated) { + // context._$saveAttachment( + // $Math.ceil(width + sw), + // $Math.ceil(height + sh), + // true + // ); + // } + + // // setup + // object.isLayer = true; + // object.isUpdated = updated; + // object.filters = filters; + // object.blendMode = blendMode; + // object.color = $getFloat32Array8(); + // object.matrix = $getFloat32Array6( + // multiMatrix[0], multiMatrix[1], + // multiMatrix[2], multiMatrix[3], + // tx, ty + // ); + + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + + // $poolBoundsObject(filterBounds); + // } + + // return object; + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @param {Float32Array} color_transform + // * @param {object} object + // * @return {void} + // * @method + // * @private + // */ + // _$postDraw ( + // context: CanvasToWebGLContext, + // matrix: Float32Array, + // color_transform: Float32Array, + // object: PreObjectImpl + // ): void { + + // context.drawInstacedArray(); + + // // cache + // const cacheKeys: any[] = $getArray(this._$instanceId, "f"); + + // const manager: FrameBufferManager = context.frameBuffer; + // const multiMatrix: Float32Array = object.matrix as NonNullable; + + // let offsetX: number = 0; + // let offsetY: number = 0; + // let texture: WebGLTexture | null = $cacheStore.get(cacheKeys); + + // if (!texture || object.isUpdated) { + + // // remove + // if (texture) { + // $cacheStore.set(cacheKeys, null); + // } + + // texture = manager + // .getTextureFromCurrentAttachment(); + + // const filters: FilterArrayImpl | null = object.filters; + // let filterState = false; + // if (filters && filters.length) { + + // for (let idx: number = 0; idx < filters.length; ++idx) { + // texture = filters[idx] + // ._$applyFilter(context, matrix); + // } + + // // update + // filterState = true; + // offsetX = context._$offsetX; + // offsetY = context._$offsetY; + + // // reset + // context._$offsetX = 0; + // context._$offsetY = 0; + // } + + // texture.filterState = filterState; + // texture.matrix = `${multiMatrix[0]}_` + // + `${multiMatrix[1]}_` + // + `${multiMatrix[2]}_` + // + `${multiMatrix[3]}`; + + // texture.offsetX = offsetX; + // texture.offsetY = offsetY; + + // $cacheStore.set(cacheKeys, texture); + + // context._$restoreAttachment(); + // } + + // if (texture.offsetX) { + // offsetX = texture.offsetX; + // } + + // if (texture.offsetY) { + // offsetY = texture.offsetY; + // } + + // // set + // context.reset(); + // context.globalAlpha = $clamp( + // color_transform[3] + color_transform[7] / 255, 0, 1 + // ); + // context.globalCompositeOperation = object.blendMode; + + // const bounds: BoundsImpl = context.getCurrentPosition(); + + // context.setTransform( + // 1, 0, 0, 1, + // bounds.xMin - offsetX - object.sw, + // bounds.yMin - offsetY - object.sh + // ); + + // context.drawImage(texture, + // 0, 0, texture.width, texture.height, + // color_transform + // ); + + // // end blend + // context._$endLayer(); + + // // object pool + // $poolFloat32Array6(object.matrix as NonNullable); + // $poolPreObject(object); + + // // reset + // context.cachePosition = null; + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @param {Float32Array} color_transform + // * @return {void} + // * @method + // * @private + // */ + // _$draw ( + // context: CanvasToWebGLContext, + // matrix: Float32Array, + // color_transform: Float32Array + // ): void { + + // // not draw + // if (!this._$visible) { + // return ; + // } + + // const transform: Transform = this._$transform; + + // let multiColor: Float32Array = color_transform; + // const rawColor: Float32Array = transform._$rawColorTransform(); + // if (rawColor !== $COLOR_ARRAY_IDENTITY + // && rawColor[0] !== 1 || rawColor[1] !== 1 + // || rawColor[2] !== 1 || rawColor[3] !== 1 + // || rawColor[4] !== 0 || rawColor[5] !== 0 + // || rawColor[6] !== 0 || rawColor[7] !== 0 + // ) { + // multiColor = $multiplicationColor(color_transform, rawColor); + // } + + // // not draw + // const alpha: number = $clamp(multiColor[3] + multiColor[7] / 255, 0, 1, 0); + // if (!alpha) { + // return ; + // } + + // // not draw + // const children: DisplayObjectImpl[] = this._$getChildren(); + // const length: number = children.length; + // if (!length) { + // return ; + // } + + // // pre data + // const preObject: PreObjectImpl | null = this._$preDraw(context, matrix); + // if (!preObject) { + // return ; + // } + + // // use cache + // if (preObject.isLayer && !preObject.isUpdated) { + // this._$postDraw(context, matrix, multiColor, preObject); + // return ; + // } + + // const preMatrix: Float32Array = preObject.matrix as NonNullable; + + // const preColorTransform: Float32Array = preObject.isLayer && preObject.color + // ? preObject.color + // : multiColor; + + // // init clip params + // let shouldClip: boolean = true; + // let clipDepth: number = 0; + + // const player: Player = $currentPlayer(); + + // // draw children + // const isLayer: boolean = context.isLayer; + // const isUpdate: boolean = this._$isUpdated(); + // for (let idx: number = 0; idx < length; ++idx) { + + // const instance = children[idx]; + + // if (isUpdate) { + // instance._$placeObject = null; + // } + + // // mask instance + // if (instance._$isMask) { + // continue; + // } + + // // not layer mode + // const blendMode: BlendModeImpl = instance._$blendMode || instance.blendMode; + // if ((blendMode === "alpha" || blendMode === "erase") + // && !isLayer + // ) { + // continue; + // } + + // // mask end + // if (clipDepth + // && (instance._$placeId > clipDepth || instance._$clipDepth > 0) + // ) { + + // context.restore(); + + // if (shouldClip) { + // context._$leaveClip(); + // } + + // // clear + // clipDepth = 0; + // shouldClip = true; + // } + + // // mask size 0 + // if (!shouldClip) { + // continue; + // } - continue; - } + // // mask start + // if (instance._$clipDepth > 0) { - poolInstances.set(instance._$id, instance); + // clipDepth = instance._$clipDepth; + // shouldClip = instance._$shouldClip(preMatrix); - continue; - } - - if (useWorker) { - instance._$removeWorkerInstance(); - } - - $cacheStore.setRemoveTimer(instanceId); - if (instance._$loaderInfo && instance._$characterId) { - $cacheStore.setRemoveTimer( - `${instance._$loaderInfo._$id}@${instance._$characterId}` - ); - } - if (instance._$graphics) { - $cacheStore.setRemoveTimer(instance._$graphics._$uniqueKey); - } - - // remove event - if (instance.willTrigger(Next2DEvent.REMOVED)) { - instance.dispatchEvent( - new Next2DEvent(Next2DEvent.REMOVED, true) - ); - } - if (instance.willTrigger(Next2DEvent.REMOVED_FROM_STAGE)) { - instance.dispatchEvent( - new Next2DEvent(Next2DEvent.REMOVED_FROM_STAGE, true) - ); - } - - // reset - instance._$added = false; - instance._$addedStage = false; - instance._$active = false; - instance._$updated = true; - instance._$filters = null; - instance._$blendMode = null; - instance._$isNext = true; - instance._$placeObject = null; - instance._$created = false; - instance._$posted = false; - - if (instance instanceof DisplayObjectContainer) { - instance._$executeRemovedFromStage(); - instance._$removeParentAndStage(); - } - - } - - if (controller) { - - for (let idx: number = 0; idx < controller.length; ++idx) { - - const dictionaryId: number = controller[idx]; - if (typeof dictionaryId !== "number" || skipIds.has(dictionaryId)) { - continue; - } + // if (shouldClip) { + // context.save(); + // shouldClip = instance._$startClip(context, preMatrix); + // } - const instance: DisplayObjectImpl = poolInstances.has(dictionaryId) - ? poolInstances.get(dictionaryId) - : this._$createInstance(dictionaryId); + // continue; + // } - instance._$placeId = idx; + // // mask start + // const maskInstance: DisplayObjectImpl | null = instance._$mask; + // if (maskInstance) { - const loopConfig: LoopConfigImpl | null = instance.loopConfig; - if (loopConfig) { - instance._$currentFrame = instance - ._$getLoopFrame(loopConfig); - } + // maskInstance._$updated = false; + + // let maskMatrix: Float32Array; + + // if (this === maskInstance._$parent) { + + // maskMatrix = preMatrix; + + // } else { + + // maskMatrix = $MATRIX_ARRAY_IDENTITY; + + // let parent: ParentImpl | null = maskInstance._$parent; + // while (parent) { - children.push(instance); - if (instance._$name) { - this._$names.set(instance._$name, instance); - } + // maskMatrix = $multiplicationMatrix( + // parent._$transform._$rawMatrix(), + // maskMatrix + // ); - } - } + // parent = parent._$parent; + // } - // object pool - $poolMap(skipIds); - $poolMap(poolInstances); + // const mScale: number = player.scaleX; + // const playerMatrix: Float32Array = $getFloat32Array6( + // mScale, 0, 0, mScale, 0, 0 + // ); - // update - currentChildren.length = 0; - currentChildren.push(...children); - $poolArray(children); - } + // maskMatrix = $multiplicationMatrix( + // playerMatrix, maskMatrix + // ); + // $poolFloat32Array6(playerMatrix); - return this._$children; - } + // if (context.isLayer) { + // const currentPosition: BoundsImpl = context.getCurrentPosition(); + // maskMatrix[4] -= currentPosition.xMin; + // maskMatrix[5] -= currentPosition.yMin; + // } + + // } + + // if (!maskInstance._$shouldClip(maskMatrix)) { + // continue; + // } + + // const result: boolean = maskInstance._$startClip(context, maskMatrix); + + // context.save(); + + // if (!result) { // fixed + // context.restore(); + // continue; + // } + + // } - /** - * @return void - * @private - */ - _$clearChildren (): void - { - this._$doChanged(); - $doUpdated(); + // instance._$draw(context, preMatrix, preColorTransform); + // instance._$updated = false; - // reset - this._$names.clear(); + // // mask end + // if (maskInstance) { + // context.restore(); + // context._$leaveClip(); + // } + // } - // clear - this._$needsChildren = true; - } + // // end mask + // if (clipDepth) { + // context.restore(); - /** - * @param {DisplayObject} child - * @returns {DisplayObject} - * @private - */ - _$addChild (child: DisplayObjectImpl): DisplayObjectImpl - { - // init - child._$parent = this; - if (!child._$stage || !child._$root) { - child._$stage = this._$stage; - child._$root = this._$root; - } - - // setup - if (child instanceof DisplayObjectContainer) { - child._$setParentAndStage(); - child._$wait = true; - } - - // added event - if (!child._$added) { - if (child.willTrigger(Next2DEvent.ADDED)) { - child.dispatchEvent( - new Next2DEvent(Next2DEvent.ADDED, true) - ); - } - child._$added = true; - } + // if (shouldClip) { + // context._$leaveClip(); + // } + // } - if (this._$stage !== null && !child._$addedStage) { + // // filter and blend + // if (preObject.isLayer) { + // return this._$postDraw(context, matrix, multiColor, preObject); + // } - if (child.willTrigger(Next2DEvent.ADDED_TO_STAGE)) { - child.dispatchEvent( - new Next2DEvent(Next2DEvent.ADDED_TO_STAGE) - ); - } + // if (preObject.matrix !== matrix) { + // $poolFloat32Array6(preObject.matrix as NonNullable); + // } - child._$addedStage = true; + // if (multiColor !== color_transform) { + // $poolFloat32Array8(multiColor); + // } - // set params - if (child instanceof DisplayObjectContainer) { - child._$executeAddedToStage(); - } + // $poolPreObject(preObject); + // } - if ($rendererWorker) { - child._$createWorkerInstance(); - this._$postChildrenIds(); - } - } + // /** + // * @param {CanvasRenderingContext2D} context + // * @param {Float32Array} matrix + // * @param {object} options + // * @param {boolean} [mouse_children=true] + // * @return {boolean} + // * @method + // * @private + // */ + // _$mouseHit ( + // context: CanvasRenderingContext2D, + // matrix: Float32Array, + // options: PlayerHitObjectImpl, + // mouse_children: boolean = true + // ): boolean { - this._$doChanged(); - child._$active = true; - child._$updated = true; - child._$isNext = true; + // let multiMatrix: Float32Array = matrix; + // const rawMatrix: Float32Array = this._$transform._$rawMatrix(); + // if (rawMatrix !== $MATRIX_ARRAY_IDENTITY) { + // multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + // } - return child; - } + // const children: DisplayObjectImpl[] = this._$getChildren(); - /** - * @return {void} - * @method - * @private - */ - _$setParentAndStage (): void - { - const children: DisplayObjectImpl[] = this._$needsChildren - ? this._$getChildren() - : this._$children; + // // mask set + // const clips: DisplayObjectImpl[] = $getArray(); + // const targets: DisplayObjectImpl[] = $getArray(); + // const clipIndexes: Map = $getMap(); - for (let idx: number = 0; idx < children.length; ++idx) { + // let clipDepth: number = 0; + // let clipIdx: number = 0; + // for (let idx: number = 0; idx < children.length; ++idx) { - const instance: DisplayObjectImpl = children[idx]; + // const instance: DisplayObjectImpl = children[idx]; - instance._$root = this._$root; - instance._$stage = this._$stage; + // if (!instance._$visible && !instance._$hitObject) { + // continue; + // } - if (instance instanceof DisplayObjectContainer) { - instance._$setParentAndStage(); - instance._$wait = true; - } + // if (instance._$clipDepth) { + // clipIdx = clips.length; + // clipDepth = instance._$clipDepth; + // clips.push(instance); + // continue; + // } - } - } + // // clip end + // if (clipDepth && instance._$placeId > clipDepth) { + // clipIdx = 0; + // clipDepth = 0; + // } - /** - * @return {void} - * @method - * @private - */ - _$executeAddedToStage (): void - { - const children: DisplayObjectImpl[] = this._$needsChildren - ? this._$getChildren() - : this._$children; + // // clip check on + // if (clipIdx) { + // clipIndexes.set(instance._$instanceId, clipIdx); + // } - const childrenIds: number[] = $getArray(); + // targets.push(instance); + + // } + + // // setup + // const mouseChildren: boolean = this._$mouseChildren && mouse_children; + + // let hit: boolean = false; + // const isRoot = this._$root === this; + + // while (targets.length) { + + // const instance: DisplayObjectImpl = targets.pop(); + // if (instance._$isMask) { + // continue; + // } - for (let idx: number = 0; idx < children.length; ++idx) { + // if (isRoot && !(instance instanceof InteractiveObject)) { + // continue; + // } - const instance: DisplayObjectImpl = children[idx]; - if (!instance) { - continue; - } + // // mask target + // if (clipIndexes.has(instance._$instanceId)) { - childrenIds.push(instance._$instanceId); - if (!instance._$addedStage) { + // const index: number | void = clipIndexes.get(instance._$instanceId); + // if (!index) { + // continue; + // } - if ($rendererWorker) { - instance._$createWorkerInstance(); - } + // const clip: DisplayObjectImpl = clips[index]; + // if (!clip._$hit(context, multiMatrix, options, true)) { + // continue; + // } - if (instance.willTrigger(Next2DEvent.ADDED_TO_STAGE)) { - instance.dispatchEvent( - new Next2DEvent(Next2DEvent.ADDED_TO_STAGE) - ); - } + // } - instance._$addedStage = true; - } + // // mask hit test + // const maskInstance: DisplayObjectImpl | null = instance._$mask; + // if (maskInstance) { - if (instance instanceof DisplayObjectContainer) { - instance._$executeAddedToStage(); - } + // if (this === maskInstance._$parent) { - } + // if (!maskInstance._$hit(context, multiMatrix, options, true)) { + // continue; + // } - if ($rendererWorker) { - this._$postChildrenIds(childrenIds); - } + // } else { - $poolArray(childrenIds); - } + // let maskMatrix: Float32Array = $MATRIX_ARRAY_IDENTITY; - /** - * @param {DisplayObject} child - * @param {boolean} do_event - * @return {DisplayObject} - * @private - */ - _$remove ( - child: DisplayObjectImpl, - do_event: boolean = true - ): DisplayObjectImpl { - - child._$transform._$transform(); - - // remove all broadcast events - if (child.hasEventListener(Next2DEvent.ENTER_FRAME)) { - child.removeAllEventListener(Next2DEvent.ENTER_FRAME); - } - - if (child.hasEventListener(Next2DEvent.EXIT_FRAME)) { - child.removeAllEventListener(Next2DEvent.EXIT_FRAME); - } - - if (child.hasEventListener(Next2DEvent.FRAME_CONSTRUCTED)) { - child.removeAllEventListener(Next2DEvent.FRAME_CONSTRUCTED); - } - - if (child.hasEventListener(Next2DEvent.RENDER)) { - child.removeAllEventListener(Next2DEvent.RENDER); - } - - if (child.hasEventListener(Next2DEvent.ACTIVATE)) { - child.removeAllEventListener(Next2DEvent.ACTIVATE); - } - - if (child.hasEventListener(Next2DEvent.DEACTIVATE)) { - child.removeAllEventListener(Next2DEvent.DEACTIVATE); - } - - if (child.hasEventListener("keyDown")) { - child.removeAllEventListener("keyDown"); - } - - if (child.hasEventListener("keyUp")) { - child.removeAllEventListener("keyUp"); - } - - // remove - const children: DisplayObjectImpl[] = this._$needsChildren - ? this._$getChildren() - : this._$children; - - const depth: number = this.getChildIndex(child); - children.splice(depth, 1); - - this._$names.delete(child.name); - if (do_event) { - - // event - if (child.willTrigger(Next2DEvent.REMOVED)) { - child.dispatchEvent( - new Next2DEvent(Next2DEvent.REMOVED, true) - ); - } + // let parent: ParentImpl | null = maskInstance._$parent; + // while (parent) { - // remove stage event - if (this._$stage !== null) { + // maskMatrix = $multiplicationMatrix( + // parent._$transform._$rawMatrix(), + // maskMatrix + // ); - // worker側のDisplayObjectも削除 - if ($rendererWorker) { - child._$removeWorkerInstance(); - this._$postChildrenIds(); - } + // parent = parent._$parent; + // } - if (child.willTrigger(Next2DEvent.REMOVED_FROM_STAGE)) { - child.dispatchEvent( - new Next2DEvent(Next2DEvent.REMOVED_FROM_STAGE) - ); - } + // if (!maskInstance._$hit(context, maskMatrix, options, true)) { + // continue; + // } - if (child instanceof DisplayObjectContainer) { - child._$executeRemovedFromStage(); - } - } + // } - $cacheStore.setRemoveTimer(child._$instanceId); - if (child._$loaderInfo && child._$characterId) { - $cacheStore.setRemoveTimer( - `${child._$loaderInfo._$id}@${child._$characterId}` - ); - } - if (child._$graphics) { - $cacheStore.setRemoveTimer(child._$graphics._$uniqueKey); - } + // } - // reset params - if (child instanceof DisplayObjectContainer) { - child._$removeParentAndStage(); - } + // if (instance._$mouseHit(context, multiMatrix, options, mouseChildren) + // || instance._$hitArea + // && instance + // ._$hitArea + // ._$mouseHit(context, multiMatrix, options, mouseChildren) + // ) { - // reset - child._$stage = null; - child._$parent = null; - child._$root = null; - child._$active = false; - child._$wait = true; - child._$updated = true; - child._$added = false; - child._$addedStage = false; - child._$created = false; - child._$posted = false; - this._$doChanged(); - - } - - return child; - } + // if (instance._$root === instance) { + // return true; + // } - /** - * @return {void} - * @method - * @private - */ - _$executeRemovedFromStage (): void - { - const children: DisplayObjectImpl[] = this._$getChildren().slice(0); - for (let idx: number = 0; idx < children.length; ++idx) { + // if (!mouseChildren) { + // return true; + // } - const instance: DisplayObjectImpl = children[idx]; - if (!instance) { - continue; - } + // hit = true; + // if (instance instanceof InteractiveObject) { - if (instance._$addedStage) { + // if (!instance.mouseEnabled && !instance._$hitObject) { + // continue; + // } - // workerのDisplayObjectを削除 - if ($rendererWorker) { - instance._$removeWorkerInstance(); - } + // if (!$isTouch && !options.pointer) { - if (instance.willTrigger(Next2DEvent.REMOVED_FROM_STAGE)) { - instance.dispatchEvent( - new Next2DEvent(Next2DEvent.REMOVED_FROM_STAGE) - ); - } + // if ("_$text" in instance + // && "type" in instance + // && instance.type === "input" + // ) { + // options.pointer = "text"; + // } - instance._$created = false; - instance._$posted = false; - instance._$addedStage = false; - } + // if ("buttonMode" in instance + // && "useHandCursor" in instance + // && instance.buttonMode + // && instance.useHandCursor + // ) { + // options.pointer = "pointer"; + // } + + // } - if (instance instanceof DisplayObjectContainer) { - instance._$executeRemovedFromStage(); - } - - } - } - - /** - * @return {void} - * @method - * @private - */ - _$removeParentAndStage (): void - { - const children: DisplayObjectImpl[] = this._$needsChildren - ? this._$getChildren() - : this._$children; - - for (let idx: number = 0; idx < children.length; ++idx) { - - const instance: DisplayObjectImpl = children[idx]; - - $cacheStore.setRemoveTimer(instance._$instanceId); - if (instance._$loaderInfo && instance._$characterId) { - $cacheStore.setRemoveTimer( - `${instance._$loaderInfo._$id}@${instance._$characterId}` - ); - } - if (instance._$graphics) { - $cacheStore.setRemoveTimer(instance._$graphics._$uniqueKey); - } - - if (instance instanceof DisplayObjectContainer) { - instance._$removeParentAndStage(); - } - - instance._$stage = null; - instance._$root = null; - instance._$addedStage = false; - } - - if ("_$sounds" in this) { - const soundsMap: Map = this._$sounds as Map; - if (soundsMap.size) { - for (const sounds of soundsMap.values()) { - for (let idx: number = 0; idx < sounds.length; ++idx) { - const sound: Sound = sounds[idx]; - sound.stop(); - } - } - } - } - - this._$needsChildren = true; - } - - /** - * @return {void} - * @method - * @private - */ - _$prepareActions (): void - { - const children: DisplayObjectImpl[] = this._$needsChildren - ? this._$getChildren() - : this._$children; - - for (let idx: number = children.length - 1; idx > -1; --idx) { - children[idx]._$prepareActions(); - } - - // added event - this._$executeAddedEvent(); - } - - /** - * @return {boolean} - * @method - * @private - */ - _$nextFrame (): boolean - { - let isNext: boolean = false; - - const children: DisplayObjectImpl[] = this._$getChildren(); - for (let idx: number = children.length - 1; idx > -1; --idx) { - - const child: DisplayObjectImpl = children[idx]; - if (!child._$isNext) { - continue; - } - - if (isNext) { - - child._$nextFrame(); - - } else { - - isNext = child._$nextFrame(); - - } - } - - // added event - this._$executeAddedEvent(); - - this._$isNext = isNext; - - if (!this._$posted && $rendererWorker) { - this._$postProperty(); - } - - return this._$isNext; - } - - /** - * @param {CanvasToWebGLContext} context - * @param {Float32Array} matrix - * @return {void} - * @method - * @private - */ - _$clip ( - context: CanvasToWebGLContext, - matrix: Float32Array - ): void { - - let multiMatrix: Float32Array = matrix; - - const rawMatrix: Float32Array = this._$transform._$rawMatrix(); - if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 - || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 - || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 - ) { - multiMatrix = $multiplicationMatrix(matrix, rawMatrix); - } - - const children: DisplayObjectImpl[] = this._$getChildren(); - for (let idx: number = 0; idx < children.length; ++idx) { - - const instance: DisplayObjectImpl = children[idx]; - - // mask instance - if (instance._$isMask) { - continue; - } - - instance._$clip(context, multiMatrix); - instance._$updated = false; - - } - - if (multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - } - - /** - * @param {CanvasToWebGLContext} context - * @param {Float32Array} matrix - * @return {object} - * @private - */ - _$preDraw ( - context: CanvasToWebGLContext, - matrix: Float32Array - ): PreObjectImpl | null { - - let multiMatrix: Float32Array = matrix; - const rawMatrix: Float32Array = this._$transform._$rawMatrix(); - if (rawMatrix !== $MATRIX_HIT_ARRAY_IDENTITY - && rawMatrix[0] !== 1 || rawMatrix[1] !== 0 - || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 - || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 - ) { - multiMatrix = $multiplicationMatrix(matrix, rawMatrix); - } - - // size zero - if (!multiMatrix[0] && !multiMatrix[1] - || !multiMatrix[2] && !multiMatrix[3] - ) { - if (multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - return null; - } - - // return object - const object: PreObjectImpl = $getPreObject(); - - // setup - object.matrix = multiMatrix; - - // check - const filters: FilterArrayImpl = this._$filters || this.filters; - const blendMode: BlendModeImpl = this._$blendMode || this.blendMode; - if (filters.length > 0 || blendMode !== "normal") { - - // check size - const baseBounds: BoundsImpl = this._$getBounds(null); - const bounds: BoundsImpl = $boundsMatrix(baseBounds, multiMatrix); - $poolBoundsObject(baseBounds); - - const xMax: number = +bounds.xMax; - const xMin: number = +bounds.xMin; - const yMax: number = +bounds.yMax; - const yMin: number = +bounds.yMin; - $poolBoundsObject(bounds); - - const width: number = $Math.ceil($Math.abs(xMax - xMin)); - const height: number = $Math.ceil($Math.abs(yMax - yMin)); - if (0 >= width || 0 >= height) { - $poolPreObject(object); - if (multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - return null; - } - - let xScale: number = +$Math.sqrt( - multiMatrix[0] * multiMatrix[0] - + multiMatrix[1] * multiMatrix[1] - ); - if (!$Number.isInteger(xScale)) { - const value: string = xScale.toString(); - const index: number = value.indexOf("e"); - if (index !== -1) { - xScale = +value.slice(0, index); - } - xScale = +xScale.toFixed(4); - } - - let yScale: number = +$Math.sqrt( - multiMatrix[2] * multiMatrix[2] - + multiMatrix[3] * multiMatrix[3] - ); - if (!$Number.isInteger(yScale)) { - const value: string = yScale.toString(); - const index: number = value.indexOf("e"); - if (index !== -1) { - yScale = +value.slice(0, index); - } - yScale = +yScale.toFixed(4); - } - - object.canApply = this._$canApply(filters); - let filterBounds: BoundsImpl = $getBoundsObject(0, width, 0, height); - if (object.canApply && filters) { - for (let idx: number = 0; idx < filters.length ; ++idx) { - filterBounds = filters[idx] - ._$generateFilterRect(filterBounds, xScale, yScale); - } - } - - const currentAttachment: AttachmentImpl | null = context - .frameBuffer - .currentAttachment; - - if (!currentAttachment - || !currentAttachment.texture - || xMin - filterBounds.xMin > currentAttachment.width - || yMin - filterBounds.yMin > currentAttachment.height - ) { - $poolBoundsObject(filterBounds); - $poolPreObject(object); - if (multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - return null; - } - - if (0 > xMin + filterBounds.xMax || 0 > yMin + filterBounds.yMax) { - $poolBoundsObject(filterBounds); - $poolPreObject(object); - if (multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - return null; - } - - // move size - let tx: number = multiMatrix[4] - xMin; - let ty: number = multiMatrix[5] - yMin; - - // start layer - context._$startLayer( - $getBoundsObject(xMin, xMax, yMin, yMax) - ); - - // check cache - const updated: boolean = this._$isFilterUpdated( - multiMatrix, filters, object.canApply - ); - - const layerBounds: BoundsImpl = this._$getLayerBounds(multiMatrix); - - const layerWidth: number = $Math.ceil($Math.abs(layerBounds.xMax - layerBounds.xMin)); - const layerHeight: number = $Math.ceil($Math.abs(layerBounds.yMax - layerBounds.yMin)); - $poolBoundsObject(layerBounds); - - const sw = layerWidth - filterBounds.xMax + filterBounds.xMin; - const sh = layerHeight - filterBounds.yMax + filterBounds.yMin; - - tx += sw; - ty += sh; - - object.sw = sw; - object.sh = sh; - if (updated) { - context._$saveAttachment( - $Math.ceil(width + sw), - $Math.ceil(height + sh), - true - ); - } - - // setup - object.isLayer = true; - object.isUpdated = updated; - object.filters = filters; - object.blendMode = blendMode; - object.color = $getFloat32Array8(); - object.matrix = $getFloat32Array6( - multiMatrix[0], multiMatrix[1], - multiMatrix[2], multiMatrix[3], - tx, ty - ); - - if (multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - - $poolBoundsObject(filterBounds); - } - - return object; - } - - /** - * @param {CanvasToWebGLContext} context - * @param {Float32Array} matrix - * @param {Float32Array} color_transform - * @param {object} object - * @return {void} - * @method - * @private - */ - _$postDraw ( - context: CanvasToWebGLContext, - matrix: Float32Array, - color_transform: Float32Array, - object: PreObjectImpl - ): void { - - context.drawInstacedArray(); - - // cache - const cacheKeys: any[] = $getArray(this._$instanceId, "f"); - - const manager: FrameBufferManager = context.frameBuffer; - const multiMatrix: Float32Array = object.matrix as NonNullable; - - let offsetX: number = 0; - let offsetY: number = 0; - let texture: WebGLTexture | null = $cacheStore.get(cacheKeys); - - if (!texture || object.isUpdated) { - - // remove - if (texture) { - $cacheStore.set(cacheKeys, null); - } - - texture = manager - .getTextureFromCurrentAttachment(); - - const filters: FilterArrayImpl | null = object.filters; - let filterState = false; - if (filters && filters.length) { - - for (let idx: number = 0; idx < filters.length; ++idx) { - texture = filters[idx] - ._$applyFilter(context, matrix); - } - - // update - filterState = true; - offsetX = context._$offsetX; - offsetY = context._$offsetY; - - // reset - context._$offsetX = 0; - context._$offsetY = 0; - } - - texture.filterState = filterState; - texture.matrix = `${multiMatrix[0]}_` - + `${multiMatrix[1]}_` - + `${multiMatrix[2]}_` - + `${multiMatrix[3]}`; - - texture.offsetX = offsetX; - texture.offsetY = offsetY; - - $cacheStore.set(cacheKeys, texture); - - context._$restoreAttachment(); - } - - if (texture.offsetX) { - offsetX = texture.offsetX; - } - - if (texture.offsetY) { - offsetY = texture.offsetY; - } - - // set - context.reset(); - context.globalAlpha = $clamp( - color_transform[3] + color_transform[7] / 255, 0, 1 - ); - context.globalCompositeOperation = object.blendMode; - - const bounds: BoundsImpl = context.getCurrentPosition(); - - context.setTransform( - 1, 0, 0, 1, - bounds.xMin - offsetX - object.sw, - bounds.yMin - offsetY - object.sh - ); - - context.drawImage(texture, - 0, 0, texture.width, texture.height, - color_transform - ); - - // end blend - context._$endLayer(); - - // object pool - $poolFloat32Array6(object.matrix as NonNullable); - $poolPreObject(object); - - // reset - context.cachePosition = null; - } - - /** - * @param {CanvasToWebGLContext} context - * @param {Float32Array} matrix - * @param {Float32Array} color_transform - * @return {void} - * @method - * @private - */ - _$draw ( - context: CanvasToWebGLContext, - matrix: Float32Array, - color_transform: Float32Array - ): void { - - // not draw - if (!this._$visible) { - return ; - } - - const transform: Transform = this._$transform; - - let multiColor: Float32Array = color_transform; - const rawColor: Float32Array = transform._$rawColorTransform(); - if (rawColor !== $COLOR_ARRAY_IDENTITY - && rawColor[0] !== 1 || rawColor[1] !== 1 - || rawColor[2] !== 1 || rawColor[3] !== 1 - || rawColor[4] !== 0 || rawColor[5] !== 0 - || rawColor[6] !== 0 || rawColor[7] !== 0 - ) { - multiColor = $multiplicationColor(color_transform, rawColor); - } - - // not draw - const alpha: number = $clamp(multiColor[3] + multiColor[7] / 255, 0, 1, 0); - if (!alpha) { - return ; - } - - // not draw - const children: DisplayObjectImpl[] = this._$getChildren(); - const length: number = children.length; - if (!length) { - return ; - } - - // pre data - const preObject: PreObjectImpl | null = this._$preDraw(context, matrix); - if (!preObject) { - return ; - } - - // use cache - if (preObject.isLayer && !preObject.isUpdated) { - this._$postDraw(context, matrix, multiColor, preObject); - return ; - } - - const preMatrix: Float32Array = preObject.matrix as NonNullable; - - const preColorTransform: Float32Array = preObject.isLayer && preObject.color - ? preObject.color - : multiColor; - - // init clip params - let shouldClip: boolean = true; - let clipDepth: number = 0; - - const player: Player = $currentPlayer(); - - // draw children - const isLayer: boolean = context.isLayer; - const isUpdate: boolean = this._$isUpdated(); - for (let idx: number = 0; idx < length; ++idx) { - - const instance = children[idx]; - - if (isUpdate) { - instance._$placeObject = null; - } - - // mask instance - if (instance._$isMask) { - continue; - } - - // not layer mode - const blendMode: BlendModeImpl = instance._$blendMode || instance.blendMode; - if ((blendMode === "alpha" || blendMode === "erase") - && !isLayer - ) { - continue; - } - - // mask end - if (clipDepth - && (instance._$placeId > clipDepth || instance._$clipDepth > 0) - ) { - - context.restore(); - - if (shouldClip) { - context._$leaveClip(); - } - - // clear - clipDepth = 0; - shouldClip = true; - } - - // mask size 0 - if (!shouldClip) { - continue; - } - - // mask start - if (instance._$clipDepth > 0) { - - clipDepth = instance._$clipDepth; - shouldClip = instance._$shouldClip(preMatrix); - - if (shouldClip) { - context.save(); - shouldClip = instance._$startClip(context, preMatrix); - } - - continue; - } - - // mask start - const maskInstance: DisplayObjectImpl | null = instance._$mask; - if (maskInstance) { - - maskInstance._$updated = false; - - let maskMatrix: Float32Array; - - if (this === maskInstance._$parent) { - - maskMatrix = preMatrix; - - } else { - - maskMatrix = $MATRIX_ARRAY_IDENTITY; - - let parent: ParentImpl | null = maskInstance._$parent; - while (parent) { - - maskMatrix = $multiplicationMatrix( - parent._$transform._$rawMatrix(), - maskMatrix - ); - - parent = parent._$parent; - } - - const mScale: number = player.scaleX; - const playerMatrix: Float32Array = $getFloat32Array6( - mScale, 0, 0, mScale, 0, 0 - ); - - maskMatrix = $multiplicationMatrix( - playerMatrix, maskMatrix - ); - $poolFloat32Array6(playerMatrix); - - if (context.isLayer) { - const currentPosition: BoundsImpl = context.getCurrentPosition(); - maskMatrix[4] -= currentPosition.xMin; - maskMatrix[5] -= currentPosition.yMin; - } - - } - - if (!maskInstance._$shouldClip(maskMatrix)) { - continue; - } - - const result: boolean = maskInstance._$startClip(context, maskMatrix); - - context.save(); - - if (!result) { // fixed - context.restore(); - continue; - } - - } - - instance._$draw(context, preMatrix, preColorTransform); - instance._$updated = false; - - // mask end - if (maskInstance) { - context.restore(); - context._$leaveClip(); - } - } - - // end mask - if (clipDepth) { - context.restore(); - - if (shouldClip) { - context._$leaveClip(); - } - } - - // filter and blend - if (preObject.isLayer) { - return this._$postDraw(context, matrix, multiColor, preObject); - } - - if (preObject.matrix !== matrix) { - $poolFloat32Array6(preObject.matrix as NonNullable); - } - - if (multiColor !== color_transform) { - $poolFloat32Array8(multiColor); - } - - $poolPreObject(preObject); - } - - /** - * @param {CanvasRenderingContext2D} context - * @param {Float32Array} matrix - * @param {object} options - * @param {boolean} [mouse_children=true] - * @return {boolean} - * @method - * @private - */ - _$mouseHit ( - context: CanvasRenderingContext2D, - matrix: Float32Array, - options: PlayerHitObjectImpl, - mouse_children: boolean = true - ): boolean { - - let multiMatrix: Float32Array = matrix; - const rawMatrix: Float32Array = this._$transform._$rawMatrix(); - if (rawMatrix !== $MATRIX_ARRAY_IDENTITY) { - multiMatrix = $multiplicationMatrix(matrix, rawMatrix); - } - - const children: DisplayObjectImpl[] = this._$getChildren(); - - // mask set - const clips: DisplayObjectImpl[] = $getArray(); - const targets: DisplayObjectImpl[] = $getArray(); - const clipIndexes: Map = $getMap(); - - let clipDepth: number = 0; - let clipIdx: number = 0; - for (let idx: number = 0; idx < children.length; ++idx) { - - const instance: DisplayObjectImpl = children[idx]; - - if (!instance._$visible && !instance._$hitObject) { - continue; - } - - if (instance._$clipDepth) { - clipIdx = clips.length; - clipDepth = instance._$clipDepth; - clips.push(instance); - continue; - } - - // clip end - if (clipDepth && instance._$placeId > clipDepth) { - clipIdx = 0; - clipDepth = 0; - } - - // clip check on - if (clipIdx) { - clipIndexes.set(instance._$instanceId, clipIdx); - } - - targets.push(instance); - - } - - // setup - const mouseChildren: boolean = this._$mouseChildren && mouse_children; - - let hit: boolean = false; - const isRoot = this._$root === this; - - while (targets.length) { - - const instance: DisplayObjectImpl = targets.pop(); - if (instance._$isMask) { - continue; - } - - if (isRoot && !(instance instanceof InteractiveObject)) { - continue; - } - - // mask target - if (clipIndexes.has(instance._$instanceId)) { - - const index: number | void = clipIndexes.get(instance._$instanceId); - if (!index) { - continue; - } - - const clip: DisplayObjectImpl = clips[index]; - if (!clip._$hit(context, multiMatrix, options, true)) { - continue; - } - - } - - // mask hit test - const maskInstance: DisplayObjectImpl | null = instance._$mask; - if (maskInstance) { - - if (this === maskInstance._$parent) { - - if (!maskInstance._$hit(context, multiMatrix, options, true)) { - continue; - } - - } else { - - let maskMatrix: Float32Array = $MATRIX_ARRAY_IDENTITY; - - let parent: ParentImpl | null = maskInstance._$parent; - while (parent) { - - maskMatrix = $multiplicationMatrix( - parent._$transform._$rawMatrix(), - maskMatrix - ); - - parent = parent._$parent; - } - - if (!maskInstance._$hit(context, maskMatrix, options, true)) { - continue; - } - - } - - } - - if (instance._$mouseHit(context, multiMatrix, options, mouseChildren) - || instance._$hitArea - && instance - ._$hitArea - ._$mouseHit(context, multiMatrix, options, mouseChildren) - ) { - - if (instance._$root === instance) { - return true; - } - - if (!mouseChildren) { - return true; - } - - hit = true; - if (instance instanceof InteractiveObject) { - - if (!instance.mouseEnabled && !instance._$hitObject) { - continue; - } - - if (!$isTouch && !options.pointer) { - - if ("_$text" in instance - && "type" in instance - && instance.type === "input" - ) { - options.pointer = "text"; - } - - if ("buttonMode" in instance - && "useHandCursor" in instance - && instance.buttonMode - && instance.useHandCursor - ) { - options.pointer = "pointer"; - } - - } - - if (!options.hit) { - - options.hit = !instance.mouseEnabled && instance._$hitObject - ? instance._$hitObject - : instance; - - } - - return true; - } - - } - - } - - // pool - $poolArray(clips); - $poolArray(targets); - $poolMap(clipIndexes); - - if (multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - - // not found - return hit; - } - - /** - * @param {CanvasRenderingContext2D} context - * @param {Float32Array} matrix - * @param {object} options - * @param {boolean} [is_clip=false] - * @return {boolean} - * @method - * @private - */ - _$hit ( - context: CanvasRenderingContext2D, - matrix: Float32Array, - options: PlayerHitObjectImpl, - is_clip: boolean = false - ): boolean { - - let multiMatrix: Float32Array = matrix; - const rawMatrix: Float32Array = this._$transform._$rawMatrix(); - if (rawMatrix !== $MATRIX_ARRAY_IDENTITY) { - multiMatrix = $multiplicationMatrix(matrix, rawMatrix); - } - - const children: DisplayObjectImpl[] = this._$getChildren(); - for (let idx: number = children.length; idx > -1; --idx) { - - const instance: DisplayObjectImpl = children[idx]; - if (instance._$isMask) { - continue; - } - - if (instance._$hit(context, multiMatrix, options, is_clip)) { - return true; - } - - } - - if (multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - - return false; - } - - /** - * @param {number} index - * @return {DisplayObject} - * @method - * @private - */ - _$createInstance (index: number): DisplayObjectImpl - { - if (!this._$dictionary) { - throw new Error("the dictionary is null."); - } - - // build - const tag: DictionaryTagImpl = this._$dictionary[index]; - const loaderInfo: LoaderInfo | null = this._$loaderInfo; - if (!loaderInfo || !loaderInfo._$data) { - throw new Error("the loaderInfo or data is null."); - } - - const character: Character = loaderInfo._$data.characters[tag.characterId]; - - // symbol class - const instance: DisplayObjectImpl = $createInstance(character.extends); - instance._$build(tag, this); - instance._$id = index; - - return instance; - } - - /** - * @param {number} x - * @param {number} y - * @return {boolean} - * @method - * @private - */ - _$outCheck (x: number, y: number): boolean - { - let matrix: Float32Array = $MATRIX_ARRAY_IDENTITY; - let parent: ParentImpl | null = this._$parent; - while (parent) { - - matrix = $multiplicationMatrix( - parent._$transform._$rawMatrix(), - matrix - ); - - parent = parent._$parent; - } - - $hitContext.setTransform(1, 0, 0, 1, 0, 0); - $hitContext.beginPath(); - - const options: PlayerHitObjectImpl = { - "x": x, - "y": y, - "pointer": "", - "hit": null - }; - - return this._$mouseHit($hitContext, matrix, options); - } - - /** - * @return {void} - * @method - * @private - */ - _$createWorkerInstance (): void - { - if (this._$created || !$rendererWorker) { - return ; - } - - this._$created = true; - this._$posted = true; - this._$updated = false; - - let index: number = 0; - const buffer: Float32Array = $getRenderBufferArray(); - buffer[index++] = this._$instanceId; - buffer[index++] = this._$parent ? this._$parent._$instanceId : -1; - - this._$registerProperty(buffer, index); - - const message: PropertyMessageMapImpl = $getRenderMessageObject(); - message.command = "createDisplayObjectContainer"; - message.buffer = buffer; - - const options: ArrayBuffer[] = $getArray(buffer.buffer); - $rendererWorker.postMessage(message, options); - - $poolRenderMessageObject(message); - $poolArray(options); - - this._$postChildrenIds(); - } - - /** - * @return {void} - * @method - * @private - */ - _$postProperty (): void - { - if (!$rendererWorker) { - return ; - } - - this._$postChildrenIds(); - - const options: ArrayBuffer[] = $getArray(); - const message: PropertyMessageMapImpl = this._$createMessage(); - - $rendererWorker - .postMessage(message, options); - - $poolArray(options); - - this._$posted = true; - this._$updated = false; - } - - /** - * @param {array} [childrenIds=null] - * @return {void} - * @method - * @private - */ - _$postChildrenIds (childrenIds: number[] | null = null): void - { - if (!$rendererWorker || !this._$created) { - return ; - } - - let poolIds = false; - if (!childrenIds) { - - const children: DisplayObjectImpl[] = this._$getChildren(); - - childrenIds = $getArray(); - for (let idx: number = 0; idx < children.length; ++idx) { - childrenIds.push(children[idx]._$instanceId); - } - - poolIds = true; - } - - const buffer: Int32Array = new Int32Array(childrenIds.length + 1); - buffer[0] = this._$instanceId; - buffer.set(childrenIds, 1); - - const message: PropertyMessageMapImpl = $getRenderMessageObject(); - message.command = "setChildren"; - message.buffer = buffer; - - const options: ArrayBuffer[] = $getArray(buffer.buffer); - $rendererWorker.postMessage(message, options); - - $poolRenderMessageObject(message); - $poolArray(options); - - if (poolIds) { - $poolArray(childrenIds); - } - } + // if (!options.hit) { + + // options.hit = !instance.mouseEnabled && instance._$hitObject + // ? instance._$hitObject + // : instance; + + // } + + // return true; + // } + + // } + + // } + + // // pool + // $poolArray(clips); + // $poolArray(targets); + // $poolMap(clipIndexes); + + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + + // // not found + // return hit; + // } + + // /** + // * @param {CanvasRenderingContext2D} context + // * @param {Float32Array} matrix + // * @param {object} options + // * @param {boolean} [is_clip=false] + // * @return {boolean} + // * @method + // * @private + // */ + // _$hit ( + // context: CanvasRenderingContext2D, + // matrix: Float32Array, + // options: PlayerHitObjectImpl, + // is_clip: boolean = false + // ): boolean { + + // let multiMatrix: Float32Array = matrix; + // const rawMatrix: Float32Array = this._$transform._$rawMatrix(); + // if (rawMatrix !== $MATRIX_ARRAY_IDENTITY) { + // multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + // } + + // const children: DisplayObjectImpl[] = this._$getChildren(); + // for (let idx: number = children.length; idx > -1; --idx) { + + // const instance: DisplayObjectImpl = children[idx]; + // if (instance._$isMask) { + // continue; + // } + + // if (instance._$hit(context, multiMatrix, options, is_clip)) { + // return true; + // } + + // } + + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + + // return false; + // } + + // /** + // * @param {number} index + // * @return {DisplayObject} + // * @method + // * @private + // */ + // _$createInstance (index: number): DisplayObjectImpl + // { + // if (!this._$dictionary) { + // throw new Error("the dictionary is null."); + // } + + // // build + // const tag: DictionaryTagImpl = this._$dictionary[index]; + // const loaderInfo: LoaderInfo | null = this._$loaderInfo; + // if (!loaderInfo || !loaderInfo._$data) { + // throw new Error("the loaderInfo or data is null."); + // } + + // const character: Character = loaderInfo._$data.characters[tag.characterId]; + + // // symbol class + // const instance: DisplayObjectImpl = $createInstance(character.extends); + // instance._$build(tag, this); + // instance._$id = index; + + // return instance; + // } + + // /** + // * @param {number} x + // * @param {number} y + // * @return {boolean} + // * @method + // * @private + // */ + // _$outCheck (x: number, y: number): boolean + // { + // let matrix: Float32Array = $MATRIX_ARRAY_IDENTITY; + // let parent: ParentImpl | null = this._$parent; + // while (parent) { + + // matrix = $multiplicationMatrix( + // parent._$transform._$rawMatrix(), + // matrix + // ); + + // parent = parent._$parent; + // } + + // $hitContext.setTransform(1, 0, 0, 1, 0, 0); + // $hitContext.beginPath(); + + // const options: PlayerHitObjectImpl = { + // "x": x, + // "y": y, + // "pointer": "", + // "hit": null + // }; + + // return this._$mouseHit($hitContext, matrix, options); + // } } diff --git a/packages/display/src/DisplayObjectUtil.ts b/packages/display/src/DisplayObjectUtil.ts new file mode 100644 index 00000000..4f3a2e74 --- /dev/null +++ b/packages/display/src/DisplayObjectUtil.ts @@ -0,0 +1,289 @@ +import type { AjaxOptionImpl } from "./interface/AjaxOptionImpl"; +import type { URLRequestHeaderImpl } from "./interface/URLRequestHeaderImpl"; + +/** + * @type {number} + */ +let instanceId: number = 0; + +/** + * @description インスタンスユニークIDを返却 + * Returns the instance unique ID + * + * @return {number} + * @method + * @public + */ +export const $getInstanceId = (): number => +{ + return instanceId++; +}; + +/** + * @description 使用済みになったArrayのプール配列 + * Pool array of used Array. + * + * @type {array[]} + * @const + * @static + */ +export const $arrays: any[] = []; + +/** + * @description 使用済みになったFloat32Arrayをプール、サイズは6固定 + * Pool used Float32Array, size fixed at 6. + * + * @type {Float32Array[]} + * @const + * @static + */ +export const $float32Array6: Float32Array[] = []; + +/** + * @description 使用済みになったFloat32Arrayをプール、サイズは8固定 + * Pool used Float32Array, size fixed at 8. + * + * @type {Float32Array[]} + * @const + * @static + */ +export const $float32Array8: Float32Array[] = []; + +/** + * @description プールされたFloat32Arrayがあればプールから。なければ新規作成して返却、サイズは6固定 + * If there is a pooled Float32Array, it is taken from the pool. + * If not, create a new one and return it. Size is fixed at 6. + * + * @param {number} [f0=0] + * @param {number} [f0=0] + * @param {number} [f1=0] + * @param {number} [f2=0] + * @param {number} [f3=0] + * @param {number} [f4=0] + * @param {number} [f5=0] + * @return {Float32Array} + * @method + * @static + */ +export const $getFloat32Array6 = ( + f0: number = 0, f1: number = 0, + f2: number = 0, f3: number = 0, + f4: number = 0, f5: number = 0 +): Float32Array => { + + const array: Float32Array = $float32Array6.pop() || new Float32Array(6); + + array[0] = f0; + array[1] = f1; + array[2] = f2; + array[3] = f3; + array[4] = f4; + array[5] = f5; + + return array; +}; + +/** + * @description 使用済みになったFloat32Arrayをプール + * Pool used Float32Array. + * + * @param {Float32Array} array + * @return {void} + * @method + * @static + */ +export const $poolFloat32Array6 = (array: Float32Array): void => +{ + $float32Array6.push(array); +}; + +/** + * @description プールされたFloat32Arrayがあればプールから。なければ新規作成して返却、サイズは8固定 + * If there is a pooled Float32Array, it is taken from the pool. + * If not, create a new one and return it. Size is fixed at 8. + * + * @param {number} [f0=0] + * @param {number} [f1=0] + * @param {number} [f2=0] + * @param {number} [f3=0] + * @param {number} [f4=0] + * @param {number} [f5=0] + * @param {number} [f6=0] + * @param {number} [f7=0] + * @return {Float32Array} + * @method + * @static + */ +export const $getFloat32Array8 = ( + f0: number = 1, f1: number = 1, + f2: number = 1, f3: number = 1, + f4: number = 0, f5: number = 0, + f6: number = 0, f7: number = 0 +): Float32Array => { + + const array: Float32Array = $float32Array8.pop() || new Float32Array(8); + + array[0] = f0; + array[1] = f1; + array[2] = f2; + array[3] = f3; + array[4] = f4; + array[5] = f5; + array[6] = f6; + array[7] = f7; + + return array; +}; + +/** + * @description 使用済みになったFloat32Arrayをプール + * Pool used Float32Array. + * + * @param {Float32Array} array + * @return {void} + * @method + * @static + */ +export const $poolFloat32Array8 = (array: Float32Array): void => +{ + $float32Array8.push(array); +}; + +/** + * @description プールされたArrayがあればプールから、なければ新規作成して返却 + * If there is a pooled Array, return it from the pool, + * otherwise create a new one and return it. + * + * @param {array} args + * @return {array} + * @method + * @static + */ +export const $getArray = (...args: any[]): any[] => +{ + const array: any[] = $arrays.pop() || []; + if (args.length) { + array.push(...args); + } + return array; +}; + +/** + * @description 使用済みになったArrayをプール + * Pool used Array. + * + * @param {array} array + * @return {void} + * @method + * @static + */ +export const $poolArray = (array: any[]): void => +{ + if (array.length) { + array.length = 0; + } + + $arrays.push(array); +}; + +/** + * @param {object} option + * @return {void} + * @method + * @public + */ +export const $ajax = (option: AjaxOptionImpl): void => +{ + // get or post + let postData: string | null = null; + switch (option.method.toUpperCase()) { + + case "GET": + if (option.data) { + const urls = option.url.split("?"); + + urls[1] = urls.length === 1 + ? option.data.toString() + : `${urls[1]}&${option.data.toString()}`; + + option.url = urls.join("?"); + } + break; + + case "PUT": + case "POST": + if (option.data) { + postData = option.data.toString(); + } + break; + + default: + break; + + } + + // start + const xmlHttpRequest = new XMLHttpRequest(); + + // init + xmlHttpRequest.open(option.method, option.url, true); + + // set mimeType + xmlHttpRequest.responseType = option.format; + + // use cookie + xmlHttpRequest.withCredentials = option.withCredentials; + + // add event + if (option.event) { + const keys: string[] = Object.keys(option.event); + for (let idx = 0; idx < keys.length; ++idx) { + + const name: string = keys[idx]; + + // @ts-ignore + xmlHttpRequest.addEventListener(name, option.event[name]); + } + } + + // set request header + for (let idx: number = 0; idx < option.headers.length; ++idx) { + const header = option.headers[idx]; + if (!header) { + continue; + } + xmlHttpRequest.setRequestHeader(header.name, header.value); + } + + xmlHttpRequest.send(postData); +}; + +/** + * @description ヘッダー文字列を配列に変換 + * Convert header string to array + * + * @param {string} header + * @return {array} + * @method + * @public + */ +export const $headerStringToArray = (header: string): URLRequestHeaderImpl[] => +{ + const results = $getArray(); + if (header) { + + const headers = header.trim().split("\n"); + for (let idx = 0; idx < headers.length; ++idx) { + + const values = headers[idx].split(":"); + + results.push({ + "name": values[0].trim(), + "value": values[1].trim() + }); + + } + + } + return results; +}; \ No newline at end of file diff --git a/packages/display/src/FrameLabel.ts b/packages/display/src/FrameLabel.ts index 4400db43..e5b8f558 100644 --- a/packages/display/src/FrameLabel.ts +++ b/packages/display/src/FrameLabel.ts @@ -1,25 +1,16 @@ import { EventDispatcher } from "@next2d/events"; /** - * FrameLabel オブジェクトには、フレーム番号および対応するラベル名を指定するプロパティがあります。 - * MovieClip クラスには、currentLabels プロパティがあります。 - * これは、現在のシーンの FrameLabel オブジェクトの配列です。 - * MovieClip インスタンスがシーンを使用していない場合、配列には MovieClip インスタンス全体のすべてのフレームラベルが含まれます。 + * @description FrameLabel オブジェクトには、フレーム番号および対応するラベル名を指定するプロパティがあります。 + * MovieClip クラスには、currentLabels プロパティがあります。 + * これは、現在のシーンの FrameLabel オブジェクトの配列です。 + * MovieClip インスタンスがシーンを使用していない場合、配列には MovieClip インスタンス全体のすべてのフレームラベルが含まれます。 * - * The FrameLabel object contains properties that specify a frame number and the corresponding label name. - * The MovieClip class includes a currentLabels property, - * which is an Array of FrameLabel objects for the current scene. - * If the MovieClip instance does not use scenes, - * the Array includes all frame labels from the entire MovieClip instance. - * - * @example Example usage of FrameLabel. - * // static BlendMode - * const {FrameLabel} = next2d.display; - * const frameLabel = new FrameLabel(); - * frameLabel.addEventListener(Event.FRAME_LABEL, (event) => - * { - * // more... - * } + * The FrameLabel object contains properties that specify a frame number and the corresponding label name. + * The MovieClip class includes a currentLabels property, + * which is an Array of FrameLabel objects for the current scene. + * If the MovieClip instance does not use scenes, + * the Array includes all frame labels from the entire MovieClip instance. * * @class * @memberOf next2d.display @@ -59,7 +50,7 @@ export class FrameLabel extends EventDispatcher * Returns the string representation of the specified class. * * @return {string} - * @default [class FrameLabel] + * @default "[class FrameLabel]" * @method * @static */ @@ -73,7 +64,7 @@ export class FrameLabel extends EventDispatcher * Returns the space name of the specified class. * * @return {string} - * @default next2d.display.FrameLabel + * @default "next2d.display.FrameLabel" * @const * @static */ @@ -87,7 +78,7 @@ export class FrameLabel extends EventDispatcher * Returns the string representation of the specified object. * * @return {string} - * @default [object FrameLabel] + * @default "[object FrameLabel]" * @method * @public */ @@ -101,7 +92,7 @@ export class FrameLabel extends EventDispatcher * Returns the space name of the specified object. * * @return {string} - * @default next2d.display.FrameLabel + * @default "next2d.display.FrameLabel" * @const * @public */ diff --git a/packages/display/src/InteractiveObject.ts b/packages/display/src/InteractiveObject.ts index 4fe499e9..8ab73b21 100644 --- a/packages/display/src/InteractiveObject.ts +++ b/packages/display/src/InteractiveObject.ts @@ -1,11 +1,11 @@ import { DisplayObject } from "./DisplayObject"; /** - * InteractiveObject クラスは、マウス、キーボードまたは他のユーザー入力デバイスを使用して - * ユーザーが操作できるすべての表示オブジェクトの抽象基本クラスです。 + * @description InteractiveObject クラスは、マウス、キーボードまたは他のユーザー入力デバイスを使用して + * ユーザーが操作できるすべての表示オブジェクトの抽象基本クラスです。 * - * The InteractiveObject class is the abstract base class for all display objects - * with which the user can interact, using the mouse, keyboard, or other user input device. + * The InteractiveObject class is the abstract base class for all display objects + * with which the user can interact, using the mouse, keyboard, or other user input device. * * @class * @memberOf next2d.display @@ -32,10 +32,8 @@ export class InteractiveObject extends DisplayObject } /** - * @description このオブジェクトでマウスまたはその他のユーザー入力メッセージを - * 受け取るかどうかを指定します。 - * Specifies whether this object receives mouse, - * or other user input, messages. + * @description このオブジェクトでマウスまたはその他のユーザー入力メッセージを受け取るかどうかを指定します。 + * Specifies whether this object receives mouse, or other user input, messages. * * @member {boolean} * @default true diff --git a/packages/display/src/Loader.ts b/packages/display/src/Loader.ts index 4e32d8f9..c62d49cf 100644 --- a/packages/display/src/Loader.ts +++ b/packages/display/src/Loader.ts @@ -1,39 +1,21 @@ +import type { ParentImpl } from "./interface/ParentImpl"; +import type { Sprite } from "./Sprite"; import { DisplayObjectContainer } from "./DisplayObjectContainer"; import { LoaderInfo } from "./LoaderInfo"; import { MovieClip } from "./MovieClip"; import { URLRequest } from "@next2d/net"; -import { $getMap } from "@next2d/share"; -import { - IOErrorEvent, - Event, - ProgressEvent as Next2DProgressEvent, - HTTPStatusEvent -} from "@next2d/events"; -import type { Player } from "@next2d/core"; -import type { - NoCodeDataZlibImpl, - NoCodeDataImpl, - ParentImpl, - MovieClipCharacterImpl -} from "@next2d/interface"; -import { - $ajax, - $headerToArray, - $unzipQueues, - $updateUnzipWorkerStatus, - $getUnzipWorker, - $currentPlayer, - $useUnzipWorker -} from "@next2d/util"; +import { $ajax } from "./DisplayObjectUtil"; +import { execute as loaderLoadstartEventService } from "./Loader/LoaderLoadStartEventService"; +import { execute as loaderProgressEventService } from "./Loader/LoaderProgressEventService"; +import { execute as loaderLoadEndEventService } from "./Loader/LoaderLoadEndEventService"; +import { execute as loaderLoadJsonService } from "./Loader/LoaderLoadJsonService"; /** - * Loader クラスは、JSON ファイルまたはイメージ(JPEG、PNG、または GIF)ファイルを読み込むために使用します。 - * 読み込みを開始するには load() メソッドを使用します。 - * 読み込まれた表示オブジェクトは Loader オブジェクトの子として追加されます。 + * @description Loader クラスは、JSON ファイルを読み込むために使用します。 + * 外部からの読み込みを開始するには load() メソッドを使用し、ローカルのJSONを読み込むには loadJSON() メソッドを使用します。 * - * The Loader class is used to load JSON files or image (JPEG, PNG, or GIF) files. - * Use the load() method to initiate loading. - * The loaded display object is added as a child of the Loader object. + * The Loader class is used to load JSON files. + * To start loading from an external source, use the load() method, and to load local JSON, use the loadJSON() method. * * @class * @memberOf next2d.display @@ -61,7 +43,7 @@ export class Loader extends DisplayObjectContainer * Returns the string representation of the specified class. * * @return {string} - * @default [class Loader] + * @default "[class Loader]" * @method * @static */ @@ -75,7 +57,7 @@ export class Loader extends DisplayObjectContainer * Returns the space name of the specified class. * * @return {string} - * @default next2d.display.Loader + * @default "next2d.display.Loader" * @const * @static */ @@ -89,7 +71,7 @@ export class Loader extends DisplayObjectContainer * Returns the string representation of the specified object. * * @return {string} - * @default [object Loader] + * @default "[object Loader]" * @method * @public */ @@ -103,7 +85,7 @@ export class Loader extends DisplayObjectContainer * Returns the space name of the specified object. * * @return {string} - * @default next2d.display.Loader + * @default "next2d.display.Loader" * @const * @public */ @@ -120,9 +102,9 @@ export class Loader extends DisplayObjectContainer * @readonly * @public */ - get content (): ParentImpl | null + get content (): ParentImpl | null { - return this._$loaderInfo ? this._$loaderInfo.content : null; + return (this._$loaderInfo as NonNullable).content; } /** @@ -146,41 +128,45 @@ export class Loader extends DisplayObjectContainer * are loaded into the content property in the same way with loadImage. * * @param {URLRequest} request - * @returns {void} + * @returns {Promise} * @method * @public */ - load (request: URLRequest): void + async load (request: URLRequest): Promise { - const loaderInfo: LoaderInfo | null = this._$loaderInfo; - if (!loaderInfo) { - return ; - } - + const loaderInfo = this._$loaderInfo as NonNullable; loaderInfo.url = request.url; loaderInfo.format = request.responseDataFormat; - $ajax({ - "format": request.responseDataFormat, - "url": request.url, - "method": request.method, - "data": request.data, - "headers": request.headers, - "withCredentials": request.withCredentials, - "event": { - "loadstart": (event: ProgressEvent) => - { - this._$loadstart(event); - }, - "progress": (event: ProgressEvent) => - { - this._$progress(event); - }, - "loadend": (event: ProgressEvent) => - { - this._$loadend(event); + if (loaderInfo.format !== "json") { + throw new Error("The only format that can be loaded by this function is `json` format."); + } + + await new Promise((resolve): void => + { + $ajax({ + "format": request.responseDataFormat, + "url": request.url, + "method": request.method, + "data": request.data, + "headers": request.headers, + "withCredentials": request.withCredentials, + "event": { + "loadstart": (event: ProgressEvent): void => + { + loaderLoadstartEventService(loaderInfo, event); + }, + "progress": (event: ProgressEvent): void => + { + loaderProgressEventService(loaderInfo, event); + }, + "loadend": async (event: ProgressEvent): Promise => + { + await loaderLoadEndEventService(loaderInfo, event); + resolve(); + } } - } + }); }); } @@ -188,197 +174,15 @@ export class Loader extends DisplayObjectContainer * @description NoCodeToolのJSONを直接読み込む * Read JSON directly from NoCodeTool * - * @param {object} json + * @param {string} json * @return {void} * @method * @public */ - loadJSON (json: any): void + async loadJSON (json: string): Promise { - if (json.type === "zlib") { - - if ($useUnzipWorker()) { - - $unzipQueues.push(json); - - return ; - } - - $updateUnzipWorkerStatus(true); - - const unzipWorker: Worker = $getUnzipWorker(); - - const buffer: Uint8Array = new Uint8Array(json.buffer); - unzipWorker.onmessage = (event: MessageEvent) => - { - this._$unzipHandler(event); - }; - unzipWorker.postMessage(buffer, [buffer.buffer]); - - } else { - - this._$build(json); - - } - } - - /** - * @param {ProgressEvent} event - * @return {void} - * @method - * @private - */ - _$loadend (event: ProgressEvent): void - { - const loaderInfo: LoaderInfo | null = this._$loaderInfo; - if (!loaderInfo) { - return ; - } - - // set - loaderInfo.bytesLoaded = event.loaded; - loaderInfo.bytesTotal = event.total; - - // progress event - if (loaderInfo.willTrigger(Next2DProgressEvent.PROGRESS)) { - loaderInfo.dispatchEvent(new Next2DProgressEvent( - Next2DProgressEvent.PROGRESS, - false, false, event.loaded, event.total - )); - } - - const target: any = event.target; - - // http status event - if (loaderInfo.willTrigger(HTTPStatusEvent.HTTP_STATUS)) { - - const responseHeaders = $headerToArray( - target.getAllResponseHeaders() - ); - - loaderInfo.dispatchEvent(new HTTPStatusEvent( - HTTPStatusEvent.HTTP_STATUS, false, false, - target.status, target.responseURL, - responseHeaders - )); - } - - if (199 < target.status && 400 > target.status) { - - if (loaderInfo.format === "json") { - - this.loadJSON(target.response); - - } else { - - if (loaderInfo.willTrigger(IOErrorEvent.IO_ERROR)) { - loaderInfo.dispatchEvent(new IOErrorEvent( - IOErrorEvent.IO_ERROR, false, false, - "LoaderInfo format is `json`" - )); - } - - } - - } else { - - if (loaderInfo.willTrigger(IOErrorEvent.IO_ERROR)) { - loaderInfo.dispatchEvent(new IOErrorEvent( - IOErrorEvent.IO_ERROR, false, false, - target.statusText - )); - } - - } - - } - - /** - * @param {MessageEvent} event - * @return {void} - * @method - * @private - */ - _$unzipHandler (event: MessageEvent): void - { - this._$build(event.data); - - if ($unzipQueues.length) { - - const object: NoCodeDataZlibImpl | void = $unzipQueues.pop(); - if (!object) { - return ; - } - - const buffer: Uint8Array = new Uint8Array(object.buffer); - - const unzipWorker = $getUnzipWorker(); - - unzipWorker.onmessage = (event: MessageEvent) => - { - this._$unzipHandler(event); - }; - unzipWorker.postMessage(buffer, [buffer.buffer]); - - } else { - - $updateUnzipWorkerStatus(false); - - } - } - - /** - * @param {ProgressEvent} event - * @return {void} - * @method - * @private - */ - _$loadstart (event: ProgressEvent): void - { - const loaderInfo: LoaderInfo | null = this._$loaderInfo; - if (!loaderInfo) { - return ; - } - - loaderInfo.bytesLoaded = event.loaded; - loaderInfo.bytesTotal = event.total; - - if (loaderInfo.willTrigger(Event.OPEN)) { - loaderInfo.dispatchEvent(new Event(Event.OPEN)); - } - - if (loaderInfo.willTrigger(Next2DProgressEvent.PROGRESS)) { - loaderInfo.dispatchEvent(new Next2DProgressEvent( - Next2DProgressEvent.PROGRESS, - false, false, event.loaded, event.total - )); - } - } - - /** - * @param {ProgressEvent} event - * @return {void} - * @method - * @private - */ - _$progress (event: ProgressEvent): void - { - const loaderInfo: LoaderInfo | null = this._$loaderInfo; - if (!loaderInfo) { - return ; - } - - // set - loaderInfo.bytesLoaded = event.loaded; - loaderInfo.bytesTotal = event.total; - - // progress event - if (loaderInfo.willTrigger(Next2DProgressEvent.PROGRESS)) { - loaderInfo.dispatchEvent(new Next2DProgressEvent( - Next2DProgressEvent.PROGRESS, - false, false, event.loaded, event.total - )); - } + const loaderInfo = this._$loaderInfo as NonNullable; + await loaderLoadJsonService(loaderInfo, json); } /** @@ -387,56 +191,56 @@ export class Loader extends DisplayObjectContainer * @method * @private */ - _$build (object: NoCodeDataImpl): void - { - const loaderInfo: LoaderInfo | null = this._$loaderInfo; - if (!loaderInfo) { - return ; - } - - const symbols: Map = $getMap(); - if (object.symbols.length) { - for (let idx: number = 0; idx < object.symbols.length; ++idx) { - - const values: any[] = object.symbols[idx]; - - symbols.set(values[0], values[1]); - } - } - - loaderInfo._$data = { - "stage": object.stage, - "characters": object.characters, - "symbols": symbols - }; - - // setup - loaderInfo._$content = new MovieClip(); - - // build root - const root: MovieClipCharacterImpl = object.characters[0]; - loaderInfo._$content._$build({ - "characterId": 0, - "clipDepth": 0, - "depth": 0, - "endFrame": root.controller.length, - "startFrame": 1 - }, this); - - // fixed logic - loaderInfo._$content._$parent = null; - this.addChild(loaderInfo._$content); - - // fixed logic - loaderInfo._$content._$added = false; - loaderInfo._$content._$addedStage = false; - - // to event - const player: Player = $currentPlayer(); - player._$loaders.push(loaderInfo); - - if (player._$loadStatus === 1) { // LOAD_START - player._$loadStatus = 2; // LOAD_END - } - } + // _$build (object: NoCodeDataImpl): void + // { + // const loaderInfo: LoaderInfo | null = this._$loaderInfo; + // if (!loaderInfo) { + // return ; + // } + + // const symbols: Map = $getMap(); + // if (object.symbols.length) { + // for (let idx: number = 0; idx < object.symbols.length; ++idx) { + + // const values: any[] = object.symbols[idx]; + + // symbols.set(values[0], values[1]); + // } + // } + + // loaderInfo._$data = { + // "stage": object.stage, + // "characters": object.characters, + // "symbols": symbols + // }; + + // // setup + // loaderInfo._$content = new MovieClip(); + + // // build root + // const root: MovieClipCharacterImpl = object.characters[0]; + // loaderInfo._$content._$build({ + // "characterId": 0, + // "clipDepth": 0, + // "depth": 0, + // "endFrame": root.controller.length, + // "startFrame": 1 + // }, this); + + // // fixed logic + // loaderInfo._$content._$parent = null; + // this.addChild(loaderInfo._$content); + + // // fixed logic + // loaderInfo._$content._$added = false; + // loaderInfo._$content._$addedStage = false; + + // // to event + // const player: Player = $currentPlayer(); + // player._$loaders.push(loaderInfo); + + // if (player._$loadStatus === 1) { // LOAD_START + // player._$loadStatus = 2; // LOAD_END + // } + // } } diff --git a/packages/display/src/Loader/LoaderBuildService.ts b/packages/display/src/Loader/LoaderBuildService.ts new file mode 100644 index 00000000..c2a84337 --- /dev/null +++ b/packages/display/src/Loader/LoaderBuildService.ts @@ -0,0 +1,35 @@ +import type { NoCodeDataImpl } from "../interface/NoCodeDataImpl"; +import type { LoaderInfo } from "../LoaderInfo"; + +export const execute = async (loader_info: LoaderInfo, object: NoCodeDataImpl): Promise => +{ + const symbols: Map = new Map(); + if (object.symbols.length) { + for (let idx: number = 0; idx < object.symbols.length; ++idx) { + + const values: any[] = object.symbols[idx]; + + symbols.set(values[0], values[1]); + } + } + + loader_info.data = { + "stage": object.stage, + "characters": object.characters, + "symbols": symbols + }; + + // setup + // loader_info.content = new MovieClip(); + console.log(object); + + // build root + // const root: MovieClipCharacterImpl = object.characters[0]; + // loaderInfo._$content._$build({ + // "characterId": 0, + // "clipDepth": 0, + // "depth": 0, + // "endFrame": root.controller.length, + // "startFrame": 1 + // }, this); +}; \ No newline at end of file diff --git a/packages/display/src/Loader/LoaderLoadEndEventService.test.ts b/packages/display/src/Loader/LoaderLoadEndEventService.test.ts new file mode 100644 index 00000000..666d3007 --- /dev/null +++ b/packages/display/src/Loader/LoaderLoadEndEventService.test.ts @@ -0,0 +1,93 @@ +import { Loader } from "../Loader"; +import { execute } from "./LoaderLoadEndEventService"; +import { + IOErrorEvent, + ProgressEvent as Next2DProgressEvent +} from "@next2d/events"; +import { describe, expect, it, vi } from "vitest"; + +describe("LoaderLoadEndEventService.js test", () => +{ + it("execute test case1", () => + { + const loader = new Loader(); + + let openState = ""; + let loaded = 0; + let total = 0; + loader + .contentLoaderInfo + .addEventListener(Next2DProgressEvent.PROGRESS, (event: Next2DProgressEvent): void => + { + openState = event.type; + loaded = event.bytesLoaded; + total = event.bytesTotal; + }); + + expect(openState).toBe(""); + expect(loaded).toBe(0); + expect(total).toBe(0); + + const json = { + "type": "json", + "stage": { + "width": 240, + "height": 240, + "fps": 60, + "bgColor": "#ffffff" + }, + "characters": [], + "symbols": [] + }; + + // mock event + const MockEvent = vi.fn().mockImplementation(() => + { + return { + "target": { + "status": 200, + "statusText": "OK", + "response": JSON.stringify(json) + }, + "loaded": 1, + "total": 10 + } as unknown as ProgressEvent; + }); + + execute(loader.contentLoaderInfo, new MockEvent()); + + expect(openState).toBe(Next2DProgressEvent.PROGRESS); + }); + + it("execute test case2", () => + { + const loader = new Loader(); + + let openState = ""; + loader + .contentLoaderInfo + .addEventListener(IOErrorEvent.IO_ERROR, (event: IOErrorEvent): void => + { + openState = event.type; + }); + + expect(openState).toBe(""); + + // mock event + const MockEvent = vi.fn().mockImplementation(() => + { + return { + "target": { + "status": 404, + "statusText": "Not Found" + }, + "loaded": 1, + "total": 10 + } as unknown as ProgressEvent; + }); + + execute(loader.contentLoaderInfo, new MockEvent()); + + expect(openState).toBe(IOErrorEvent.IO_ERROR); + }); +}); \ No newline at end of file diff --git a/packages/display/src/Loader/LoaderLoadEndEventService.ts b/packages/display/src/Loader/LoaderLoadEndEventService.ts new file mode 100644 index 00000000..73f6ac72 --- /dev/null +++ b/packages/display/src/Loader/LoaderLoadEndEventService.ts @@ -0,0 +1,57 @@ +import type { LoaderInfo } from "../LoaderInfo"; +import { $headerStringToArray } from "../DisplayObjectUtil"; +import { execute as loaderLoadJsonService } from "./LoaderLoadJsonService"; +import { + ProgressEvent as Next2DProgressEvent, + IOErrorEvent, + HTTPStatusEvent +} from "@next2d/events"; + +/** + * @description 外部JSONのローディング完了イベントの実行関数 + * Execution function for external JSON loading completion event + * + * @param {LoaderInfo} loader_info + * @param {ProgressEvent} event + * @return {Promise} + * @method + * @public + */ +export const execute = async (loader_info: LoaderInfo, event: ProgressEvent): Promise => +{ + const target = event.target as XMLHttpRequest; + if (!target) { + return ; + } + + if (loader_info.willTrigger(Next2DProgressEvent.PROGRESS)) { + loader_info.dispatchEvent(new Next2DProgressEvent( + Next2DProgressEvent.PROGRESS, false, false, + event.loaded, event.total + )); + } + + // http status event + if (loader_info.willTrigger(HTTPStatusEvent.HTTP_STATUS)) { + + const responseHeaders = $headerStringToArray( + target.getAllResponseHeaders() + ); + + loader_info.dispatchEvent(new HTTPStatusEvent( + HTTPStatusEvent.HTTP_STATUS, false, false, + target.status, target.responseURL, + responseHeaders + )); + } + + if (199 < target.status && 400 > target.status) { + await loaderLoadJsonService(loader_info, target.response); + } else { + if (loader_info.willTrigger(IOErrorEvent.IO_ERROR)) { + loader_info.dispatchEvent(new IOErrorEvent( + IOErrorEvent.IO_ERROR, false, false, target.statusText + )); + } + } +}; \ No newline at end of file diff --git a/packages/display/src/Loader/LoaderLoadJsonService.ts b/packages/display/src/Loader/LoaderLoadJsonService.ts new file mode 100644 index 00000000..45043ede --- /dev/null +++ b/packages/display/src/Loader/LoaderLoadJsonService.ts @@ -0,0 +1,41 @@ +import type { NoCodeDataImpl } from "../interface/NoCodeDataImpl"; +import type { LoaderInfo } from "../LoaderInfo"; +import { execute as loaderBuildService } from "./LoaderBuildService"; + +// @ts-ignore +import ZlibInflateWorker from "./ZlibInflateWorker?worker&inline"; + +/** + * @type {Worker} + * @private + */ +const worker: Worker = new ZlibInflateWorker(); + +/** + * @description JSONオブジェクトがzlib圧縮されている場合はworkerで解凍、無圧縮ならビルド処理を実行 + * If the JSON object is zlib compressed, decompress it with a worker, otherwise execute the build process + * + * @param {LoaderInfo} loader_info + * @param {object} json + * @return {Promise} + * @method + * @public + */ +export const execute = async (loader_info: LoaderInfo, json: any): Promise => +{ + if (json.type === "zlib") { + await new Promise((resolve): void => + { + worker.onmessage = async (event: MessageEvent): Promise => + { + await loaderBuildService(loader_info, event.data as NoCodeDataImpl); + resolve(); + }; + + const buffer: Uint8Array = new Uint8Array(json.buffer); + worker.postMessage(buffer, [buffer.buffer]); + }); + } else { + await loaderBuildService(loader_info, json as NoCodeDataImpl); + } +}; \ No newline at end of file diff --git a/packages/display/src/Loader/LoaderLoadStartEventService.test.ts b/packages/display/src/Loader/LoaderLoadStartEventService.test.ts new file mode 100644 index 00000000..d959d97e --- /dev/null +++ b/packages/display/src/Loader/LoaderLoadStartEventService.test.ts @@ -0,0 +1,74 @@ +import { Loader } from "../Loader"; +import { execute } from "./LoaderLoadStartEventService"; +import { + Event, + ProgressEvent as Next2DProgressEvent +} from "@next2d/events"; +import { describe, expect, it, vi } from "vitest"; + +describe("SoundLoadStartEventService.js test", () => +{ + it("execute test case1", () => + { + const loader = new Loader(); + + let openState = ""; + loader + .contentLoaderInfo + .addEventListener(Event.OPEN, (event: Event): void => + { + openState = event.type; + }); + + expect(openState).toBe(""); + + // mock event + const MockEvent = vi.fn().mockImplementation(() => + { + return { + "loaded": 1, + "total": 10 + } as unknown as ProgressEvent; + }); + + execute(loader.contentLoaderInfo, new MockEvent()); + + expect(openState).toBe(Event.OPEN); + }); + + it("execute test case2", () => + { + const loader = new Loader(); + + let openState = ""; + let loaded = 0; + let total = 0; + loader + .contentLoaderInfo + .addEventListener(Next2DProgressEvent.PROGRESS, (event: Next2DProgressEvent): void => + { + openState = event.type; + loaded = event.bytesLoaded; + total = event.bytesTotal; + }); + + expect(openState).toBe(""); + expect(loaded).toBe(0); + expect(total).toBe(0); + + // mock event + const MockEvent = vi.fn().mockImplementation(() => + { + return { + "loaded": 1, + "total": 10 + } as unknown as ProgressEvent; + }); + + execute(loader.contentLoaderInfo, new MockEvent()); + + expect(openState).toBe(Next2DProgressEvent.PROGRESS); + expect(loaded).toBe(1); + expect(total).toBe(10); + }); +}); \ No newline at end of file diff --git a/packages/display/src/Loader/LoaderLoadStartEventService.ts b/packages/display/src/Loader/LoaderLoadStartEventService.ts new file mode 100644 index 00000000..1c1e52cd --- /dev/null +++ b/packages/display/src/Loader/LoaderLoadStartEventService.ts @@ -0,0 +1,29 @@ +import type { LoaderInfo } from "../LoaderInfo"; +import { + Event, + ProgressEvent as Next2DProgressEvent +} from "@next2d/events"; + +/** + * @description 外部JSONの読み込みが開始イベントの実行関数 + * Execution function of the external JSON loading start event + * + * @param {LoaderInfo} loader_info + * @param {ProgressEvent} event + * @return {void} + * @method + * @public + */ +export const execute = (loader_info: LoaderInfo, event: ProgressEvent): void => +{ + if (loader_info.willTrigger(Event.OPEN)) { + loader_info.dispatchEvent(new Event(Event.OPEN)); + } + + if (loader_info.willTrigger(Next2DProgressEvent.PROGRESS)) { + loader_info.dispatchEvent(new Next2DProgressEvent( + Next2DProgressEvent.PROGRESS, false, false, + event.loaded, event.total + )); + } +}; \ No newline at end of file diff --git a/packages/display/src/Loader/LoaderProgressEventService.test.ts b/packages/display/src/Loader/LoaderProgressEventService.test.ts new file mode 100644 index 00000000..8d8f9dd5 --- /dev/null +++ b/packages/display/src/Loader/LoaderProgressEventService.test.ts @@ -0,0 +1,44 @@ +import { Loader } from "../Loader"; +import { execute } from "./LoaderProgressEventService"; +import { ProgressEvent as Next2DProgressEvent } from "@next2d/events"; +import { describe, expect, it, vi } from "vitest"; + +describe("LoaderProgressEventService.js test", () => +{ + it("execute test case1", () => + { + const loader = new Loader(); + + let openState = ""; + let loaded = 0; + let total = 0; + loader + .contentLoaderInfo + .addEventListener(Next2DProgressEvent.PROGRESS, (event: Next2DProgressEvent): void => + { + openState = event.type; + loaded = event.bytesLoaded; + total = event.bytesTotal; + }); + + expect(openState).toBe(""); + expect(loaded).toBe(0); + expect(total).toBe(0); + + // mock event + const MockEvent = vi.fn().mockImplementation(() => + { + return { + "loaded": 1, + "total": 10 + } as unknown as ProgressEvent; + }); + + execute(loader.contentLoaderInfo, new MockEvent()); + + expect(openState).toBe(Next2DProgressEvent.PROGRESS); + expect(loaded).toBe(1); + expect(total).toBe(10); + + }); +}); \ No newline at end of file diff --git a/packages/display/src/Loader/LoaderProgressEventService.ts b/packages/display/src/Loader/LoaderProgressEventService.ts new file mode 100644 index 00000000..874eb3b8 --- /dev/null +++ b/packages/display/src/Loader/LoaderProgressEventService.ts @@ -0,0 +1,22 @@ +import type { LoaderInfo } from "../LoaderInfo"; +import { ProgressEvent as Next2DProgressEvent } from "@next2d/events"; + +/** + * @description 外部JSONのローディング中のイベント実行関数 + * Execution function of the external JSON loading event + * + * @param {Sound} loader_info + * @param {ProgressEvent} event + * @return {void} + * @method + * @public + */ +export const execute = (loader_info: LoaderInfo, event: ProgressEvent): void => +{ + if (loader_info.willTrigger(Next2DProgressEvent.PROGRESS)) { + loader_info.dispatchEvent(new Next2DProgressEvent( + Next2DProgressEvent.PROGRESS, false, false, + event.loaded, event.total + )); + } +}; \ No newline at end of file diff --git a/packages/display/src/Loader/ZlibInflateWorker.ts b/packages/display/src/Loader/ZlibInflateWorker.ts new file mode 100644 index 00000000..1a995ea6 --- /dev/null +++ b/packages/display/src/Loader/ZlibInflateWorker.ts @@ -0,0 +1,24 @@ +"use strict"; + +import { decompressSync } from "fflate"; + +/** + * @description zilbの圧縮されたデータを解凍します。 + * Unzips zlib-compressed data. + * + * @param {MessageEvent} event + * @return {void} + * @method + * @public + */ +self.addEventListener("message", (event: MessageEvent): void => +{ + const buffer = decompressSync(event.data); + + let json = ""; + for (let idx: number = 0; idx < buffer.length; idx += 4096) { + json += String.fromCharCode(...buffer.slice(idx, idx + 4096)); + } + + self.postMessage(JSON.parse(decodeURIComponent(json))); +}); \ No newline at end of file diff --git a/packages/display/src/LoaderInfo.test.ts b/packages/display/src/LoaderInfo.test.ts new file mode 100644 index 00000000..293321e5 --- /dev/null +++ b/packages/display/src/LoaderInfo.test.ts @@ -0,0 +1,31 @@ +import { LoaderInfo } from "./LoaderInfo"; +import { describe, expect, it } from "vitest"; + +describe("LoaderInfo.js namespace test", () => +{ + it("namespace test public", () => + { + expect(new LoaderInfo().namespace).toBe("next2d.display.LoaderInfo"); + }); + + it("namespace test static", () => + { + expect(LoaderInfo.namespace).toBe("next2d.display.LoaderInfo"); + }); +}); + +describe("LoaderInfo.js toString test", () => +{ + it("toString test success", () => + { + expect(new LoaderInfo().toString()).toBe("[object LoaderInfo]"); + }); +}); + +describe("LoaderInfo.js static toString test", () => +{ + it("static toString test", () => + { + expect(LoaderInfo.toString()).toBe("[class LoaderInfo]"); + }); +}); \ No newline at end of file diff --git a/packages/display/src/LoaderInfo.ts b/packages/display/src/LoaderInfo.ts index c7d39bb9..375b090d 100644 --- a/packages/display/src/LoaderInfo.ts +++ b/packages/display/src/LoaderInfo.ts @@ -1,20 +1,17 @@ +import type { MovieClip } from "./MovieClip"; +import type { Sprite } from "./Sprite"; +import type { ParentImpl } from "./interface/ParentImpl"; +import type { URLLoaderDataFormatImpl } from "./interface/URLLoaderDataFormatImpl"; +import type { LoaderInfoDataImpl } from "./interface/LoaderInfoDataImpl"; import { EventDispatcher } from "@next2d/events"; -import { $getLoaderInfoId } from "@next2d/util"; -import type { - URLLoaderDataFormatImpl, - ParentImpl, - LoaderInfoDataImpl -} from "@next2d/interface"; +import { $getInstanceId } from "./DisplayObjectUtil"; /** - * LoaderInfo クラスは、読み込まれる JSON ファイルやイメージファイル(JPEG、GIF、PNG ファイルなど)に関する情報を提供します。 - * LoaderInfo オブジェクトは、すべての表示オブジェクトで使用できます。 - * 提供される情報には、読み込みの進行状況、読み込む側と読み込まれたコンテンツの URL、メディアの総バイト数、メディアの規格高さと幅などが含まれます。 + * @description LoaderInfo クラスは、読み込まれる JSON ファイルに関する情報を提供します。 + * LoaderInfo オブジェクトは、すべての表示オブジェクトで使用できます。 * - * The LoaderInfo class provides information about a loaded JSON file or a loaded image file (JPEG, GIF, or PNG). - * LoaderInfo objects are available for any display object. - * The information provided includes load progress, the URLs of the loader and loaded content, - * the number of bytes total for the media, and the nominal height and width of the media. + * The LoaderInfo class provides information about the JSON file to be loaded. + * The LoaderInfo object can be used with all display objects. * * @class * @memberOf next2d.display @@ -22,11 +19,9 @@ import type { */ export class LoaderInfo extends EventDispatcher { - public readonly _$id: number; - public _$content: ParentImpl | null; - public _$data: LoaderInfoDataImpl | null; - private _$bytesLoaded: number; - private _$bytesTotal: number; + private readonly _$id: number; + private _$content: ParentImpl | null; + private _$data: LoaderInfoDataImpl | null; private _$url: string; private _$format: URLLoaderDataFormatImpl; @@ -42,21 +37,7 @@ export class LoaderInfo extends EventDispatcher * @type {number} * @private */ - this._$id = $getLoaderInfoId(); - - /** - * @type {number} - * @default 0 - * @private - */ - this._$bytesLoaded = 0; - - /** - * @type {number} - * @default 0 - * @private - */ - this._$bytesTotal = 0; + this._$id = $getInstanceId(); /** * @type {string} @@ -66,7 +47,7 @@ export class LoaderInfo extends EventDispatcher this._$url = ""; /** - * @type {DisplayObject} + * @type {Sprite} * @default null * @private */ @@ -92,7 +73,7 @@ export class LoaderInfo extends EventDispatcher * Returns the string representation of the specified class. * * @return {string} - * @default [class LoaderInfo] + * @default "[class LoaderInfo]" * @method * @static */ @@ -106,7 +87,7 @@ export class LoaderInfo extends EventDispatcher * Returns the space name of the specified class. * * @return {string} - * @default next2d.display.LoaderInfo + * @default "next2d.display.LoaderInfo" * @const * @static */ @@ -120,7 +101,7 @@ export class LoaderInfo extends EventDispatcher * Returns the string representation of the specified object. * * @return {string} - * @default [object LoaderInfo] + * @default "[object LoaderInfo]" * @method * @public */ @@ -134,7 +115,7 @@ export class LoaderInfo extends EventDispatcher * Returns the space name of the specified object. * * @return {string} - * @default next2d.display.LoaderInfo + * @default "next2d.display.LoaderInfo" * @const * @public */ @@ -144,51 +125,46 @@ export class LoaderInfo extends EventDispatcher } /** - * @description そのメディアのロード済みのバイト数です。 - * The uint of bytes that are loaded for the media. + * @description LoaderInfoのユニークIDを返却 + * Returns the unique ID of LoaderInfo * * @member {number} - * @default 0 + * @readonly * @public */ - get bytesLoaded (): number + get id (): number { - return this._$bytesLoaded; - } - set bytesLoaded (bytes_loaded: number) - { - this._$bytesLoaded = bytes_loaded | 0; + return this._$id; } /** - * @description メディアファイル全体のバイト数です。 - * The number of bytes in the entire media file. + * @description Loaderで読み込まれたデータオブジェクトを返却 + * Returns the data object loaded by the Loader * - * @member {number} - * @default 0 + * @member {object} * @public */ - get bytesTotal (): number + get data (): LoaderInfoDataImpl | null { - return this._$bytesTotal; + return this._$data; } - set bytesTotal (bytes_total: number) + set data (data: LoaderInfoDataImpl | null) { - this._$bytesTotal = bytes_total | 0; + this._$data = data; } /** * @description LoaderInfo オブジェクトに関係したロードされたオブジェクトです。 * The loaded object associated with this LoaderInfo object. * - * @member {DisplayObject} + * @member {MovieClip | Sprite | null} * @public */ - get content (): ParentImpl + get content (): ParentImpl | null { return this._$content; } - set content (content: ParentImpl) + set content (content: ParentImpl) { this._$content = content; } diff --git a/packages/display/src/index.ts b/packages/display/src/index.ts index dd7e3996..1810b63a 100644 --- a/packages/display/src/index.ts +++ b/packages/display/src/index.ts @@ -1,18 +1,14 @@ export * from "./BitmapData"; export * from "./BlendMode"; export * from "./DisplayObject"; -export * from "./DisplayObjectContainer"; export * from "./FrameLabel"; export * from "./Graphics"; -export * from "./GraphicsBitmapFill"; -export * from "./GraphicsGradientFill"; export * from "./InteractiveObject"; export * from "./Loader"; -export * from "./LoaderInfo"; export * from "./LoopConfig"; export * from "./LoopType"; export * from "./MovieClip"; export * from "./Shape"; export * from "./Sprite"; export * from "./Stage"; -export * from "./TextField"; \ No newline at end of file +export * from "../../text/src/TextField"; \ No newline at end of file diff --git a/packages/display/src/interface/AjaxEventImpl.ts b/packages/display/src/interface/AjaxEventImpl.ts new file mode 100644 index 00000000..6cd6ce28 --- /dev/null +++ b/packages/display/src/interface/AjaxEventImpl.ts @@ -0,0 +1,5 @@ +export interface AjaxEventImpl { + loadstart?: Function; + progress?: Function; + loadend?: Function; +} \ No newline at end of file diff --git a/packages/display/src/interface/AjaxOptionImpl.ts b/packages/display/src/interface/AjaxOptionImpl.ts new file mode 100644 index 00000000..e431eb1f --- /dev/null +++ b/packages/display/src/interface/AjaxOptionImpl.ts @@ -0,0 +1,14 @@ +import type { URLRequestMethodImpl } from "./URLRequestMethodImpl"; +import type { URLLoaderDataFormatImpl } from "./URLLoaderDataFormatImpl"; +import type { AjaxEventImpl } from "./AjaxEventImpl"; +import type { URLRequestHeaderImpl } from "./URLRequestHeaderImpl"; + +export interface AjaxOptionImpl { + url: string; + format: URLLoaderDataFormatImpl; + method: URLRequestMethodImpl; + withCredentials: boolean; + headers: URLRequestHeaderImpl[]; + data?: any; + event?: AjaxEventImpl; +} \ No newline at end of file diff --git a/packages/display/src/interface/BlendModeImpl.ts b/packages/display/src/interface/BlendModeImpl.ts new file mode 100644 index 00000000..6ed290eb --- /dev/null +++ b/packages/display/src/interface/BlendModeImpl.ts @@ -0,0 +1,15 @@ +export type BlendModeImpl = "copy" + | "add" + | "alpha" + | "darken" + | "difference" + | "erase" + | "hardlight" + | "invert" + | "layer" + | "lighten" + | "multiply" + | "normal" + | "overlay" + | "screen" + | "subtract"; \ No newline at end of file diff --git a/packages/display/src/interface/Character.ts b/packages/display/src/interface/Character.ts new file mode 100644 index 00000000..7b37721a --- /dev/null +++ b/packages/display/src/interface/Character.ts @@ -0,0 +1,3 @@ +import { CharacterImpl } from "./CharacterImpl"; + +export type Character = T; \ No newline at end of file diff --git a/packages/display/src/interface/CharacterImpl.ts b/packages/display/src/interface/CharacterImpl.ts new file mode 100644 index 00000000..a4a2ac84 --- /dev/null +++ b/packages/display/src/interface/CharacterImpl.ts @@ -0,0 +1 @@ +export interface CharacterImpl {} \ No newline at end of file diff --git a/packages/display/src/interface/DictionaryTagImpl.ts b/packages/display/src/interface/DictionaryTagImpl.ts new file mode 100644 index 00000000..a441e1e6 --- /dev/null +++ b/packages/display/src/interface/DictionaryTagImpl.ts @@ -0,0 +1,7 @@ +export interface DictionaryTagImpl { + characterId: number; + name: string; + startFrame: number; + endFrame: number; + clipDepth: number; +} \ No newline at end of file diff --git a/packages/display/src/interface/DisplayObjectImpl.ts b/packages/display/src/interface/DisplayObjectImpl.ts new file mode 100644 index 00000000..23c464fe --- /dev/null +++ b/packages/display/src/interface/DisplayObjectImpl.ts @@ -0,0 +1,3 @@ +import type { DisplayObject } from "@next2d/display"; + +export type DisplayObjectImpl = T; \ No newline at end of file diff --git a/packages/display/src/interface/FilterArrayImpl.ts b/packages/display/src/interface/FilterArrayImpl.ts new file mode 100644 index 00000000..0ce7f18f --- /dev/null +++ b/packages/display/src/interface/FilterArrayImpl.ts @@ -0,0 +1,23 @@ +import type { + BlurFilter, + BevelFilter, + ColorMatrixFilter, + ConvolutionFilter, + DisplacementMapFilter, + DropShadowFilter, + GlowFilter, + GradientBevelFilter, + GradientGlowFilter +} from "@next2d/filters"; + +export type FilterArrayImpl = Array< + BlurFilter + | BevelFilter + | ColorMatrixFilter + | ConvolutionFilter + | DisplacementMapFilter + | DropShadowFilter + | GlowFilter + | GradientBevelFilter + | GradientGlowFilter +>; \ No newline at end of file diff --git a/packages/display/src/interface/LoaderInfoDataImpl.ts b/packages/display/src/interface/LoaderInfoDataImpl.ts new file mode 100644 index 00000000..92a8e337 --- /dev/null +++ b/packages/display/src/interface/LoaderInfoDataImpl.ts @@ -0,0 +1,8 @@ +import type { StageDataImpl } from "./StageDataImpl"; +import type { Character } from "./Character"; + +export interface LoaderInfoDataImpl { + stage: StageDataImpl; + characters: Character[]; + symbols: Map; +} \ No newline at end of file diff --git a/packages/display/src/interface/LoopConfigImpl.ts b/packages/display/src/interface/LoopConfigImpl.ts new file mode 100644 index 00000000..22b8a727 --- /dev/null +++ b/packages/display/src/interface/LoopConfigImpl.ts @@ -0,0 +1,9 @@ +import type { LoopTypeImpl } from "./LoopTypeImpl"; + +export interface LoopConfigImpl { + type: LoopTypeImpl; + frame: number; + start: number; + end: number; + tweenFrame?: number; +} \ No newline at end of file diff --git a/packages/display/src/interface/LoopTypeImpl.ts b/packages/display/src/interface/LoopTypeImpl.ts new file mode 100644 index 00000000..75998297 --- /dev/null +++ b/packages/display/src/interface/LoopTypeImpl.ts @@ -0,0 +1,5 @@ +export type LoopTypeImpl = 0 // REPEAT + | 1 // NO_REPEAT + | 2 // FIXED + | 3 // NO_REPEAT_REVERSAL + | 4 ;// REPEAT_REVERSAL \ No newline at end of file diff --git a/packages/display/src/interface/NoCodeDataImpl.ts b/packages/display/src/interface/NoCodeDataImpl.ts new file mode 100644 index 00000000..2cf30a8b --- /dev/null +++ b/packages/display/src/interface/NoCodeDataImpl.ts @@ -0,0 +1,8 @@ +import { StageDataImpl } from "./StageDataImpl"; + +export interface NoCodeDataImpl { + type: "json"; + stage: StageDataImpl; + characters: any[]; + symbols: any[]; +} \ No newline at end of file diff --git a/packages/display/src/interface/ParentImpl.ts b/packages/display/src/interface/ParentImpl.ts new file mode 100644 index 00000000..1bea3398 --- /dev/null +++ b/packages/display/src/interface/ParentImpl.ts @@ -0,0 +1,3 @@ +import type { DisplayObjectContainer } from "@next2d/display"; + +export type ParentImpl = T; \ No newline at end of file diff --git a/packages/display/src/interface/PlaceObjectImpl.ts b/packages/display/src/interface/PlaceObjectImpl.ts new file mode 100644 index 00000000..139f5ecf --- /dev/null +++ b/packages/display/src/interface/PlaceObjectImpl.ts @@ -0,0 +1,15 @@ +import type { LoopConfigImpl } from "./LoopConfigImpl"; +import type { SurfaceFilterImpl } from "./SurfaceFilterImpl"; +import type { FilterArrayImpl } from "./FilterArrayImpl"; +import type { BlendModeImpl } from "./BlendModeImpl"; + +export interface PlaceObjectImpl { + matrix?: number[]; + colorTransform?: number[]; + typedMatrix?: Float32Array; + typedColorTransform?: Float32Array; + blendMode?: BlendModeImpl; + surfaceFilterList?: SurfaceFilterImpl[]; + filters?: FilterArrayImpl; + loop?: LoopConfigImpl; +} \ No newline at end of file diff --git a/packages/display/src/interface/StageDataImpl.ts b/packages/display/src/interface/StageDataImpl.ts new file mode 100644 index 00000000..1eab12a2 --- /dev/null +++ b/packages/display/src/interface/StageDataImpl.ts @@ -0,0 +1,6 @@ +export interface StageDataImpl { + width: number; + height: number; + fps: number + bgColor: string; +} \ No newline at end of file diff --git a/packages/display/src/interface/SurfaceFilterImpl.ts b/packages/display/src/interface/SurfaceFilterImpl.ts new file mode 100644 index 00000000..3bddb677 --- /dev/null +++ b/packages/display/src/interface/SurfaceFilterImpl.ts @@ -0,0 +1,14 @@ +type ClassName = "BevelFilter" + | "BlurFilter" + | "ColorMatrixFilter" + | "ConvolutionFilter" + | "DisplacementMapFilter" + | "DropShadowFilter" + | "GlowFilter" + | "GradientBevelFilter" + | "GradientGlowFilter"; + +export interface SurfaceFilterImpl { + class: ClassName; + params: any[]; +} \ No newline at end of file diff --git a/packages/display/src/interface/URLLoaderDataFormatImpl.ts b/packages/display/src/interface/URLLoaderDataFormatImpl.ts new file mode 100644 index 00000000..af72978d --- /dev/null +++ b/packages/display/src/interface/URLLoaderDataFormatImpl.ts @@ -0,0 +1 @@ +export type URLLoaderDataFormatImpl = "json" | "arraybuffer" | "text"; \ No newline at end of file diff --git a/packages/display/src/interface/URLRequestHeaderImpl.ts b/packages/display/src/interface/URLRequestHeaderImpl.ts new file mode 100644 index 00000000..efbdd5c9 --- /dev/null +++ b/packages/display/src/interface/URLRequestHeaderImpl.ts @@ -0,0 +1,5 @@ +export interface URLRequestHeaderImpl +{ + name: string; + value: string; +} \ No newline at end of file diff --git a/packages/display/src/interface/URLRequestMethodImpl.ts b/packages/display/src/interface/URLRequestMethodImpl.ts new file mode 100644 index 00000000..866e2360 --- /dev/null +++ b/packages/display/src/interface/URLRequestMethodImpl.ts @@ -0,0 +1 @@ +export type URLRequestMethodImpl = "DELETE" | "GET" | "HEAD" | "OPTIONS" | "POST" | "PUT"; \ No newline at end of file diff --git a/packages/geom/src/Matrix.ts b/packages/geom/src/Matrix.ts index 6a5b8ef6..abae4dcc 100644 --- a/packages/geom/src/Matrix.ts +++ b/packages/geom/src/Matrix.ts @@ -220,6 +220,19 @@ export class Matrix this._$matrix[5] = ty; } + /** + * @description Matrixの内部Float32Arrayデータを返却 + * Returns the internal Float32Array data of Matrix + * + * @member {Float32Array} + * @readonly + * @public + */ + get rawData (): Float32Array + { + return this._$matrix; + } + /** * @return {Matrix} * @method diff --git a/packages/interface/src/Character.ts b/packages/interface/src/Character.ts index 7b37721a..8df0291f 100644 --- a/packages/interface/src/Character.ts +++ b/packages/interface/src/Character.ts @@ -1,3 +1,3 @@ -import { CharacterImpl } from "./CharacterImpl"; +import type { CharacterImpl } from "./CharacterImpl"; export type Character = T; \ No newline at end of file diff --git a/packages/media/src/Sound.ts b/packages/media/src/Sound.ts index 30011da1..1403466d 100644 --- a/packages/media/src/Sound.ts +++ b/packages/media/src/Sound.ts @@ -3,7 +3,7 @@ import { URLRequest } from "@next2d/net"; import { SoundMixer } from "./SoundMixer"; import { execute as soundLoadStartEventService } from "./Sound/SoundLoadStartEventService"; import { execute as soundProgressEventService } from "./Sound/SoundProgressEventService"; -import { execute as soundLoadendEventService } from "./Sound/SoundLoadendEventService"; +import { execute as soundLoadEndEventService } from "./Sound/SoundLoadEndEventService"; import { execute as soundEndedEventService } from "./Sound/SoundEndedEventService"; import { execute as soundDecodeService } from "./Sound/SoundDecodeService"; import { @@ -16,6 +16,7 @@ import { $audioContext, $getSounds } from "./MediaUtil"; +import { LoaderInfo } from "packages/display/src/LoaderInfo"; /** * @description Sound クラスを使用すると、アプリケーション内のサウンドを処理することができます。 @@ -297,7 +298,7 @@ export class Sound extends EventDispatcher }, "loadend": async (event: ProgressEvent): Promise => { - await soundLoadendEventService(this, event); + await soundLoadEndEventService(this, event); resolve(); } } @@ -388,13 +389,13 @@ export class Sound extends EventDispatcher parent: any ): Promise { - const loaderInfo: any = parent.loaderInfo; - if (!loaderInfo || !loaderInfo._$data) { + const loaderInfo: LoaderInfo | null = parent.loaderInfo; + if (!loaderInfo || !loaderInfo.data) { throw new Error("the loaderInfo or data is null."); } const character = loaderInfo - ._$data + .data .characters[tag.characterId]; if (!character) { diff --git a/packages/media/src/Sound/SoundLoadendEventService.test.ts b/packages/media/src/Sound/SoundLoadendEventService.test.ts index 1f841162..9e8074df 100644 --- a/packages/media/src/Sound/SoundLoadendEventService.test.ts +++ b/packages/media/src/Sound/SoundLoadendEventService.test.ts @@ -1,5 +1,5 @@ import { Sound } from "../Sound"; -import { execute } from "./SoundLoadendEventService"; +import { execute } from "./SoundLoadEndEventService"; import { IOErrorEvent, ProgressEvent as Next2DProgressEvent diff --git a/packages/media/src/Sound/SoundLoadendEventService.ts b/packages/media/src/Sound/SoundLoadendEventService.ts index 314741bd..16dbbf20 100644 --- a/packages/media/src/Sound/SoundLoadendEventService.ts +++ b/packages/media/src/Sound/SoundLoadendEventService.ts @@ -7,8 +7,8 @@ import { } from "@next2d/events"; /** - * @description サウンドデータのローディング中のイベント実行関数 - * Event execution function during sound data loading + * @description サウンドデータのローディング完了イベントの実行関数 + * Execution function for sound data loading completion event * * @param {Sound} sound * @param {ProgressEvent} event diff --git a/packages/renderer/package.json b/packages/renderer/package.json index 3bdedc08..b79e49ba 100644 --- a/packages/renderer/package.json +++ b/packages/renderer/package.json @@ -26,6 +26,8 @@ "url": "git+https://github.com/Next2D/Player.git" }, "peerDependencies": { - "@next2d/webgl": "file:../webgl" + "@next2d/webgl": "file:../webgl", + "@next2d/filters": "file:../filters", + "@next2d/cache": "file:../cache" } } diff --git a/packages/renderer/src/Command/CommandInitializeContextService.test.ts b/packages/renderer/src/Command/CommandInitializeContextService.test.ts new file mode 100644 index 00000000..8c5f5c1e --- /dev/null +++ b/packages/renderer/src/Command/CommandInitializeContextService.test.ts @@ -0,0 +1,67 @@ +import { execute } from "./CommandInitializeContextService"; +import { $devicePixelRatio } from "../RendererUtil"; +import { describe, expect, it, vi } from "vitest"; + +describe("CommandInitializeContextService.js test", () => +{ + it("execute test case1", () => + { + const MockCanvas = vi.fn().mockImplementation(() => + { + return { + "getContext": vi.fn((contextId: string, options: any) => + { + expect(contextId).toBe("webgl2"); + expect(options.stencil).toBe(true); + expect(options.premultipliedAlpha).toBe(true); + expect(options.antialias).toBe(false); + expect(options.depth).toBe(false); + expect(options.preserveDrawingBuffer).toBe(true); + + return { + "getParameter": vi.fn(), + "createFramebuffer": vi.fn(), + "bindFramebuffer": vi.fn(), + "pixelStorei": vi.fn(), + "createRenderbuffer": vi.fn(), + "bindRenderbuffer": vi.fn(), + "renderbufferStorageMultisample": vi.fn(), + "createTexture": vi.fn(() => + { + return {}; + }), + "activeTexture": vi.fn(), + "bindTexture": vi.fn(), + "texParameteri": vi.fn(), + "texStorage2D": vi.fn(), + "createBuffer": vi.fn(), + "createVertexArray": vi.fn(), + "bindBuffer": vi.fn(), + "bufferData": vi.fn(), + "enableVertexAttribArray": vi.fn(), + "vertexAttribPointer": vi.fn(), + "vertexAttribDivisor": vi.fn(), + "createProgram": vi.fn(() => + { + return {}; + }), + "createShader": vi.fn(), + "shaderSource": vi.fn(), + "compileShader": vi.fn(), + "attachShader": vi.fn(), + "linkProgram": vi.fn(), + "detachShader": vi.fn(), + "deleteShader": vi.fn(), + "getProgramParameter": vi.fn(), + "enable": vi.fn(), + "blendFunc": vi.fn(), + }; + }) + } as unknown as HTMLCanvasElement; + }); + + expect($devicePixelRatio).toBe(1); + execute(new MockCanvas(), 2); + expect($devicePixelRatio).toBe(2); + }); +}); \ No newline at end of file diff --git a/packages/renderer/src/Command/CommandInitializeContextService.ts b/packages/renderer/src/Command/CommandInitializeContextService.ts new file mode 100644 index 00000000..fbf74f0e --- /dev/null +++ b/packages/renderer/src/Command/CommandInitializeContextService.ts @@ -0,0 +1,48 @@ +import { CanvasToWebGLContext } from "@next2d/webgl"; +import { + $setCanvas, + $setContext, + $setDevicePixelRatio, + $setWebGL2RenderingContext, + $samples +} from "../RendererUtil"; + +/** + * @description OffscreenCanvasからWebGL2のコンテキストを取得 + * Get WebGL2 context from OffscreenCanvas + * + * @param {OffscreenCanvas} canvas + * @param {number} ratio + * @return {void} + * @method + * @public + */ +export const execute = ( + canvas: OffscreenCanvas, + ratio: number +): void => { + + // Set OffscreenCanvas + $setCanvas(canvas); + + // // Set Device Pixel Ratio + $setDevicePixelRatio(ratio); + + const gl: WebGL2RenderingContext | null = canvas.getContext("webgl2", { + "stencil": true, + "premultipliedAlpha": true, + "antialias": false, + "depth": false, + "preserveDrawingBuffer": true + }); + + if (!gl) { + throw new Error("webgl2 is not supported."); + } + + // Set WebGL2 context + $setWebGL2RenderingContext(gl); + + // Set CanvasToWebGLContext + $setContext(new CanvasToWebGLContext(gl, $samples)); +}; \ No newline at end of file diff --git a/packages/renderer/src/Command/CommandResizeService.ts b/packages/renderer/src/Command/CommandResizeService.ts new file mode 100644 index 00000000..7166d9aa --- /dev/null +++ b/packages/renderer/src/Command/CommandResizeService.ts @@ -0,0 +1,77 @@ +import { + $canvas, + $setRendererHeight, + $setRendererWidth, + $rendererMatrix, + $devicePixelRatio, + $gl, + $context, + $rendererStage +} from "../RendererUtil"; +import { $cacheStore } from "@next2d/cache"; + +/** + * @description 画面リサイズ時にcanvasのリサイズ、内部情報の更新を行う + * Resize the canvas when resizing the screen and update internal information + * + * @param {number} scale + * @param {number} renderer_width + * @param {number} renderer_height + * @param {number} stage_width + * @param {number} stage_height + * @param {boolean} full_screen + * @return {void} + * @method + * @public + */ +export const execute = ( + scale: number, + renderer_width: number, + renderer_height: number, + stage_width: number, + stage_height: number, + full_screen: boolean +): void => { + + if ($canvas.width === renderer_width + && $canvas.height === renderer_height + ) { + return ; + } + + // resize + $setRendererWidth(renderer_width); + $setRendererHeight(renderer_height); + + // update canvas size + $canvas.width = renderer_width; + $canvas.height = renderer_height; + $gl.viewport(0, 0, renderer_width, renderer_height); + + // update matrix scale + $rendererMatrix[0] = scale; + $rendererMatrix[3] = scale; + + // reset + $rendererMatrix[4] = 0; + $rendererMatrix[5] = 0; + + if (full_screen) { + $rendererMatrix[4] = (renderer_width + - stage_width + * scale * $devicePixelRatio) / 2; + + $rendererMatrix[5] = (stage_height + - stage_height + * scale * $devicePixelRatio) / 2; + } + + // cache clear + $cacheStore.reset(); + + // context reset and update + $context.resize(renderer_width, renderer_height); + + // stage update + $rendererStage.doChanged(); +}; \ No newline at end of file diff --git a/packages/renderer/src/CommandController.ts b/packages/renderer/src/CommandController.ts index d51982e5..28173498 100644 --- a/packages/renderer/src/CommandController.ts +++ b/packages/renderer/src/CommandController.ts @@ -6,7 +6,8 @@ // $cacheStore // } from "@next2d/share"; import type { PropertyMessageMapImpl } from "./interface/PropertyMessageMapImpl"; -import type { RenderDisplayObjectImpl } from "./interface/RenderDisplayObjectImpl"; +import { execute as commandInitializeContextService } from "./Command/CommandInitializeContextService"; +import { execute as commandResizeService } from "./Command/CommandResizeService"; /** * @class @@ -55,7 +56,7 @@ export class CommandController { this.state = "active"; - let returnBuffer = true; + // let returnBuffer = true; while (this.queue.length) { const object: PropertyMessageMapImpl | void = this.queue.shift(); @@ -63,7 +64,7 @@ export class CommandController continue; } - returnBuffer = true; + // returnBuffer = true; switch (object.command) { // case "draw": @@ -131,18 +132,25 @@ export class CommandController // break; case "resize": - $renderPlayer._$resize(object.buffer); + commandResizeService( + object.buffer[0] as number, + object.buffer[1] as number, + object.buffer[2] as number, + object.buffer[3] as number, + object.buffer[4] as number, + !!object.buffer[5] + ); break; case "initialize": - $renderPlayer._$initialize( - object.buffer, object.canvas + commandInitializeContextService( + object.canvas, object.buffer[0] as number ); break; - case "setBackgroundColor": - $renderPlayer._$setBackgroundColor(object.buffer); - break; + // case "setBackgroundColor": + // $renderPlayer._$setBackgroundColor(object.buffer); + // break; // case "stop": // $renderPlayer.stop(); @@ -194,18 +202,18 @@ export class CommandController } - if (object.buffer && returnBuffer) { - // this._$options.push(object.buffer.buffer); + // if (object.buffer && returnBuffer) { + // // this._$options.push(object.buffer.buffer); - // globalThis.postMessage({ - // "command": "renderBuffer", - // "buffer": object.buffer - // // @ts-ignore - // }, this._$options); + // // globalThis.postMessage({ + // // "command": "renderBuffer", + // // "buffer": object.buffer + // // // @ts-ignore + // // }, this._$options); - // reset - this._$options.length = 0; - } + // // reset + // this._$options.length = 0; + // } } this.state = "deactivate"; diff --git a/packages/renderer/src/RendererDisplayObject.ts b/packages/renderer/src/RendererDisplayObject.ts new file mode 100644 index 00000000..56ebdbeb --- /dev/null +++ b/packages/renderer/src/RendererDisplayObject.ts @@ -0,0 +1,819 @@ +// import type { RenderPlayer } from "../RenderPlayer"; +// import type { RenderDisplayObjectImpl } from "../interface/RenderDisplayObjectImpl"; +// import type { BlendModeImpl } from "../interface/BlendModeImpl"; +// import type { FilterArrayImpl } from "../interface/FilterArrayImpl"; +// import type { BoundsImpl } from "../interface/BoundsImpl"; +// import type { PropertyMessageMapImpl } from "../interface/PropertyMessageMapImpl"; +// import type { AttachmentImpl } from "../interface/AttachmentImpl"; +// import type { GridImpl } from "../interface/GridImpl"; +// import type { CachePositionImpl } from "../interface/CachePositionImpl"; +// import { $renderPlayer } from "../RenderGlobal"; +// import type { +// CanvasToWebGLContext, +// FrameBufferManager +// } from "@next2d/webgl"; +// import { +// BevelFilter, +// BlurFilter, +// ColorMatrixFilter, +// ConvolutionFilter, +// DisplacementMapFilter, +// DropShadowFilter, +// GlowFilter, +// GradientBevelFilter, +// GradientGlowFilter +// } from "@next2d/filters"; + +/** + * @class + */ +export class RendererDisplayObject +{ + protected _$instanceId: number; + protected _$parentId: number; + protected _$loaderInfoId: number; + protected _$characterId: number; + protected _$clipDepth: number; + protected _$depth: number; + protected _$isMask: boolean; + protected _$updated: boolean; + protected readonly _$matrix: Float32Array; + protected _$blendMode: BlendModeImpl; + protected readonly _$colorTransform: Float32Array; + protected _$filters: FilterArrayImpl | null; + protected _$visible: boolean; + protected _$maskId: number; + protected _$maskMatrix: Float32Array | null; + protected _$xMin: number; + protected _$yMin: number; + protected _$xMax: number; + protected _$yMax: number; + protected _$scale9Grid: GridImpl | null; + protected _$matrixBase: Float32Array | null; + + /** + * @constructor + * @public + */ + constructor () + { + /** + * @type {number} + * @default -1 + * @private + */ + this._$instanceId = -1; + + /** + * @type {number} + * @default -1 + * @private + */ + this._$parentId = -1; + + /** + * @type {number} + * @default -1 + * @private + */ + this._$loaderInfoId = -1; + + /** + * @type {number} + * @default -1 + * @private + */ + this._$characterId = -1; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$clipDepth = 0; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$depth = 0; + + /** + * @type {boolean} + * @default false + * @private + */ + this._$isMask = false; + + /** + * @type {boolean} + * @default true + * @private + */ + this._$updated = true; + + // /** + // * @type {Float32Array} + // * @private + // */ + // this._$matrix = $getFloat32Array6(1, 0, 0, 1, 0, 0); + + // /** + // * @type {Float32Array} + // * @private + // */ + // this._$colorTransform = $getFloat32Array8(1, 1, 1, 1, 0, 0, 0, 0); + + /** + * @type {string} + * @default BlendMode.NORMAL + * @private + */ + this._$blendMode = "normal"; + + /** + * @type {array} + * @default null + * @private + */ + this._$filters = null; + + /** + * @type {boolean} + * @default true + * @private + */ + this._$visible = true; + + /** + * @type {number} + * @default -1 + * @private + */ + this._$maskId = -1; + + /** + * @type {Float32Array} + * @default null + * @private + */ + this._$maskMatrix = null; + + /** + * @type {boolean} + * @default false + * @private + */ + this._$isMask = false; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$xMin = 0; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$yMin = 0; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$xMax = 0; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$yMax = 0; + + /** + * @type {object|null} + * @default null + * @private + */ + this._$scale9Grid = null; + + /** + * @type {Float32Array} + * @default null + * @private + */ + this._$matrixBase = null; + } + + // /** + // * @param {Float32Array} matrix + // * @return {boolean} + // * @method + // * @private + // */ + // _$shouldClip (matrix: Float32Array): boolean + // { + // const bounds: BoundsImpl = this._$getBounds(matrix); + // const width: number = $Math.abs(bounds.xMax - bounds.xMin); + // const height: number = $Math.abs(bounds.yMax - bounds.yMin); + // $poolBoundsObject(bounds); + + // return !(!width || !height); + // } + + // /** + // * @param {Float32Array} multi_matrix + // * @returns {object} + // * @private + // */ + // _$getLayerBounds (multi_matrix: Float32Array): BoundsImpl + // { + // const baseBounds: BoundsImpl = this._$getBounds(); + + // const bounds: BoundsImpl = $boundsMatrix(baseBounds, multi_matrix); + // $poolBoundsObject(baseBounds); + + // const filters: FilterArrayImpl | null = this._$filters; + // if (!filters || !filters.length) { + // return bounds; + // } + + // let filterBounds: BoundsImpl = $getBoundsObject( + // 0, + // $Math.abs(bounds.xMax - bounds.xMin), + // 0, + // $Math.abs(bounds.yMax - bounds.yMin) + // ); + // $poolBoundsObject(bounds); + + // let xScale: number = +$Math.sqrt( + // multi_matrix[0] * multi_matrix[0] + // + multi_matrix[1] * multi_matrix[1] + // ); + // let yScale: number = +$Math.sqrt( + // multi_matrix[2] * multi_matrix[2] + // + multi_matrix[3] * multi_matrix[3] + // ); + + // xScale /= $devicePixelRatio; + // yScale /= $devicePixelRatio; + + // xScale *= 2; + // yScale *= 2; + + // for (let idx: number = 0; idx < filters.length; ++idx) { + // filterBounds = filters[idx] + // ._$generateFilterRect(filterBounds, xScale, yScale); + // } + + // return filterBounds; + // } + + // /** + // * @param {Float32Array} [matrix=null] + // * @returns {object} + // * @method + // * @private + // */ + // _$getBounds (matrix: Float32Array | null = null): BoundsImpl + // { + // const baseBounds: BoundsImpl = $getBoundsObject( + // this._$xMin, this._$xMax, + // this._$yMin, this._$yMax + // ); + + // if (!matrix) { + // return baseBounds; + // } + + // let multiMatrix: Float32Array = matrix; + // const rawMatrix: Float32Array = this._$matrix; + // if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + // || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + // || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + // ) { + // multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + // } + + // const bounds: BoundsImpl = $boundsMatrix(baseBounds, multiMatrix); + // $poolBoundsObject(baseBounds); + + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + + // return bounds; + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @return {boolean} + // * @method + // * @private + // */ + // _$startClip ( + // context: CanvasToWebGLContext, + // matrix: Float32Array + // ): boolean { + + // context.drawInstacedArray(); + + // const bounds: BoundsImpl = this._$getBounds(matrix); + // const result = context._$startClip(bounds); + // $poolBoundsObject(bounds); + + // if (!result) { + // return false; + // } + + // // start clip + // context._$enterClip(); + + // // mask start + // context._$beginClipDef(); + + // let containerClip = false; + // if ("_$children" in this) { + // containerClip = true; + // context._$updateContainerClipFlag(true); + // } + + // // @ts-ignore + // this._$clip(context, matrix); + // this._$updated = false; + + // // container clip + // if (containerClip) { + + // // update flag + // context._$updateContainerClipFlag(false); + + // // execute clip + // context._$drawContainerClip(); + // } + + // // mask end + // context._$endClipDef(); + + // return true; + // } + + /** + * @description 自身と親の状態をアクティブにする + * + * @return {void} + * @method + * @protected + */ + doChanged (): void + { + this._$updated = true; + + // if (this._$parentId > -1) { + + // const instances: Map> = $renderPlayer.instances; + // if (!instances.has(this._$parentId)) { + // return ; + // } + + // const instance = instances.get(this._$parentId); + // if (!instance._$updated) { + // instance._$doChanged(); + // } + // } + } + + // /** + // * @description 描画情報を更新 + // * + // * @param {object} object + // * @return {void} + // * @method + // * @private + // */ + // _$update (object: PropertyMessageMapImpl): void + // { + // this._$doChanged(); + + // this._$visible = object.visible; + + // if ("depth" in object) { + // this._$depth = object.depth; + // } + + // if ("isMask" in object) { + // this._$isMask = object.isMask; + // } + + // if ("clipDepth" in object) { + // this._$clipDepth = object.clipDepth; + // } + + // if ("maskId" in object) { + // this._$maskId = object.maskId; + // if (this._$maskId > -1 && object.maskMatrix) { + // this._$maskMatrix = object.maskMatrix; + // } + // } + + // this._$matrix[0] = "a" in object ? object.a : 1; + // this._$matrix[1] = "b" in object ? object.b : 0; + // this._$matrix[2] = "c" in object ? object.c : 0; + // this._$matrix[3] = "d" in object ? object.d : 1; + // this._$matrix[4] = "tx" in object ? object.tx : 0; + // this._$matrix[5] = "ty" in object ? object.ty : 0; + + // this._$colorTransform[0] = "f0" in object ? object.f0 : 1; + // this._$colorTransform[1] = "f1" in object ? object.f1 : 1; + // this._$colorTransform[2] = "f2" in object ? object.f2 : 1; + // this._$colorTransform[3] = "f3" in object ? object.f3 : 1; + // this._$colorTransform[4] = "f4" in object ? object.f4 : 0; + // this._$colorTransform[5] = "f5" in object ? object.f5 : 0; + // this._$colorTransform[6] = "f6" in object ? object.f6 : 0; + // this._$colorTransform[7] = "f7" in object ? object.f7 : 0; + + // this._$blendMode = object.blendMode || "normal"; + + // this._$filters = null; + // if (object.filters && object.filters.length) { + // this._$filters = $getArray(); + // for (let idx: number = 0; idx < object.filters.length; ++idx) { + + // const parameters = object.filters[idx]; + // const type: number = parameters.shift(); + + // switch (type) { + + // case 0: + // this._$filters.push( + // new BevelFilter(...parameters) + // ); + // break; + + // case 1: + // this._$filters.push( + // new BlurFilter(...parameters) + // ); + // break; + + // case 2: + // this._$filters.push( + // new ColorMatrixFilter(...parameters) + // ); + // break; + + // case 3: + // this._$filters.push( + // new ConvolutionFilter(...parameters) + // ); + // break; + + // case 4: + // this._$filters.push( + // new DisplacementMapFilter(...parameters) + // ); + // break; + + // case 5: + // this._$filters.push( + // new DropShadowFilter(...parameters) + // ); + // break; + + // case 6: + // this._$filters.push( + // new GlowFilter(...parameters) + // ); + // break; + + // case 7: + // this._$filters.push( + // new GradientBevelFilter(...parameters) + // ); + // break; + + // case 8: + // this._$filters.push( + // new GradientGlowFilter(...parameters) + // ); + // break; + + // } + // } + // } + + // if (object.grid) { + // this._$scale9Grid = object.grid; + + // if (object.matrixBase) { + // this._$matrixBase = object.matrixBase; + // } + // } + // } + + // /** + // * @param {array} [filters] + // * @return {boolean} + // * @private + // */ + // _$canApply (filters: FilterArrayImpl | null = null): boolean + // { + // if (filters) { + // for (let idx: number = 0; idx < filters.length; ++idx) { + // if (filters[idx]._$canApply()) { + // return true; + // } + // } + // } + // return false; + // } + + // /** + // * @description Playerから登録を削除 + // * + // * @return {void} + // * @method + // * @private + // */ + // _$remove (): void + // { + // this._$doChanged(); + + // const player: RenderPlayer = $renderPlayer; + + // // キャッシュ削除のタイマーをセット + // $cacheStore.setRemoveTimer(this._$instanceId); + + // if (this._$loaderInfoId > -1 && this._$characterId) { + // $cacheStore.setRemoveTimer( + // `${this._$loaderInfoId}@${this._$characterId}` + // ); + // } + + // player.instances.delete(this._$instanceId); + + // // reset + // this._$instanceId = -1; + // this._$parentId = -1; + // this._$loaderInfoId = -1; + // this._$characterId = -1; + // this._$blendMode = "normal"; + // this._$filters = null; + // this._$visible = true; + // this._$maskId = -1; + // this._$isMask = false; + // this._$depth = 0; + // this._$clipDepth = 0; + // this._$scale9Grid = null; + // } + + // /** + // * @return {boolean} + // * @method + // * @private + // */ + // _$isUpdated (): boolean + // { + // return this._$updated; + // } + + // /** + // * @param {number} width + // * @param {number} height + // * @param {Float32Array} matrix + // * @param {array} [filters=null] + // * @param {boolean} [can_apply=false] + // * @param {number} [position_x=0] + // * @param {number} [position_y=0] + // * @return {boolean} + // * @private + // */ + // _$isFilterUpdated ( + // matrix: Float32Array, + // filters: FilterArrayImpl | null = null, + // can_apply: boolean = false + // ): boolean { + + // // cache flag + // if (this._$isUpdated()) { + // return true; + // } + + // // check filter data + // if (can_apply && filters) { + + // for (let idx: number = 0; idx < filters.length; ++idx) { + + // if (!filters[idx]._$isUpdated()) { + // continue; + // } + + // return true; + // } + + // } + + // // check status + // const cache: CachePositionImpl = $cacheStore.get([this._$instanceId, "f"]); + + // if (!cache) { + // return true; + // } + + // if (cache.filterState !== can_apply) { + // return true; + // } + + // if (cache.matrix !== `${matrix[0]}_${matrix[1]}_${matrix[2]}_${matrix[3]}`) { + // return true; + // } + + // return false; + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {array} filters + // * @param {WebGLTexture} target_texture + // * @param {Float32Array} matrix + // * @param {number} width + // * @param {number} height + // * @return {WebGLTexture} + // * @private + // */ + // _$applyFilter ( + // context: CanvasToWebGLContext, + // filters: FilterArrayImpl, + // target_texture: WebGLTexture, + // matrix: Float32Array, + // width: number, height: number + // ): WebGLTexture { + + // const xScale: number = +$Math.sqrt( + // matrix[0] * matrix[0] + // + matrix[1] * matrix[1] + // ); + // const yScale: number = +$Math.sqrt( + // matrix[2] * matrix[2] + // + matrix[3] * matrix[3] + // ); + + // const radianX: number = $Math.atan2(matrix[1], matrix[0]); + // const radianY: number = $Math.atan2(0 - matrix[2], matrix[3]); + + // const parentMatrix: Float32Array = $getFloat32Array6( + // $Math.cos(radianX), $Math.sin(radianX), + // 0 - $Math.sin(radianY), $Math.cos(radianY), + // width / 2, height / 2 + // ); + + // const baseMatrix: Float32Array = $getFloat32Array6( + // 1, 0, 0, 1, + // 0 - target_texture.width / 2, + // 0 - target_texture.height / 2 + // ); + + // const multiMatrix: Float32Array = $multiplicationMatrix( + // parentMatrix, baseMatrix + // ); + // $poolFloat32Array6(parentMatrix); + // $poolFloat32Array6(baseMatrix); + + // const manager: FrameBufferManager = context.frameBuffer; + // const currentAttachment: AttachmentImpl | null = manager.currentAttachment; + + // const attachment: AttachmentImpl = manager + // .createCacheAttachment(width, height); + + // context._$bind(attachment); + + // context.reset(); + // context.setTransform( + // multiMatrix[0], multiMatrix[1], + // multiMatrix[2], multiMatrix[3], + // multiMatrix[4], multiMatrix[5] + // ); + // $poolFloat32Array6(multiMatrix); + + // context.drawImage(target_texture, + // 0, 0, target_texture.width, target_texture.height + // ); + + // // init + // context._$offsetX = 0; + // context._$offsetY = 0; + + // const filterMatrix: Float32Array = $getFloat32Array6( + // xScale, 0, 0, yScale, 0, 0 + // ); + + // let texture: WebGLTexture | null = null; + // for (let idx: number = 0; idx < filters.length; ++idx) { + // texture = filters[idx]._$applyFilter(context, filterMatrix); + // } + + // $poolFloat32Array6(filterMatrix); + + // if (!texture) { + // return target_texture; + // } + + // const offsetX: number = context._$offsetX; + // const offsetY: number = context._$offsetY; + + // // reset + // context._$offsetX = 0; + // context._$offsetY = 0; + + // // set offset + // texture.offsetX = offsetX; + // texture.offsetY = offsetY; + + // // cache texture + // texture.matrix = + // matrix[0] + "_" + matrix[1] + "_" + // + matrix[2] + "_" + matrix[3]; + + // texture.filterState = true; + + // context._$bind(currentAttachment); + // manager.releaseAttachment(attachment, false); + + // return texture; + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @param {array} filters + // * @param {number} width + // * @param {number} height + // * @param {WebGLTexture} [target_texture = null] + // * @return {object} + // * @method + // * @private + // */ + // _$drawFilter ( + // context: CanvasToWebGLContext, + // matrix: Float32Array, + // filters: FilterArrayImpl, + // width: number, + // height: number, + // target_texture: WebGLTexture | null = null + // ): CachePositionImpl { + + // const cacheKeys: any[] = $getArray(this._$instanceId, "f"); + // let position: CachePositionImpl | void = $cacheStore.get(cacheKeys); + + // const updated: boolean = this._$isFilterUpdated(matrix, filters, true); + + // if (position && !updated) { + // context.cachePosition = position; + // return position; + // } + + // // cache clear + // if (position) { + // $cacheStore.set(cacheKeys, null); + // } + + // const manager: FrameBufferManager = context.frameBuffer; + // const targetTexture: WebGLTexture = target_texture + // ? target_texture + // : context.getTextureFromRect( + // context.cachePosition as NonNullable + // ); + + // const texture: WebGLTexture = this._$applyFilter( + // context, filters, targetTexture, + // matrix, width, height + // ); + // manager.textureManager.release(targetTexture); + + // const bounds: BoundsImpl = this._$getLayerBounds(matrix); + // position = manager.createCachePosition( + // $Math.ceil($Math.abs(bounds.xMax - bounds.xMin)), + // $Math.ceil($Math.abs(bounds.yMax - bounds.yMin)) + // ); + + // $poolBoundsObject(bounds); + // position.filterState = true; + // position.matrix = `${matrix[0]}_${matrix[1]}_${matrix[2]}_${matrix[3]}_0_0`; + // position.offsetX = texture.offsetX; + // position.offsetY = texture.offsetY; + + // // 関数先でtextureがreleaseされる + // context.drawTextureFromRect(texture, position); + + // $cacheStore.set(cacheKeys, position); + // $poolArray(cacheKeys); + + // return position; + // } +} \ No newline at end of file diff --git a/packages/renderer/src/RendererDisplayObjectContainer.ts b/packages/renderer/src/RendererDisplayObjectContainer.ts new file mode 100644 index 00000000..84f9cbec --- /dev/null +++ b/packages/renderer/src/RendererDisplayObjectContainer.ts @@ -0,0 +1,783 @@ +import { RendererDisplayObject } from "./RendererDisplayObject"; +// import type { RenderDisplayObjectImpl } from "../interface/RenderDisplayObjectImpl"; +// import type { FilterArrayImpl } from "../interface/FilterArrayImpl"; +// import type { BlendModeImpl } from "../interface/BlendModeImpl"; +// import type { BoundsImpl } from "../interface/BoundsImpl"; +// import type { AttachmentImpl } from "../interface/AttachmentImpl"; +// import type { ParentImpl } from "../interface/ParentImpl"; +// import type { PreObjectImpl } from "../interface/PreObjectImpl"; +// import type { +// CanvasToWebGLContext, +// FrameBufferManager +// } from "@next2d/webgl"; +// import { +// $containers, +// $renderPlayer +// } from "../RenderGlobal"; + +/** + * @class + */ +export class RendererDisplayObjectContainer extends RendererDisplayObject +{ + private _$children: Int32Array; + + /** + * @constructor + * @public + */ + constructor () + { + super(); + + /** + * @type {Int32Array} + * @private + */ + this._$children = new Int32Array(); + } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @return {void} + // * @method + // * @private + // */ + // _$clip ( + // context: CanvasToWebGLContext, + // matrix: Float32Array + // ): void { + + // let multiMatrix: Float32Array = matrix; + // const rawMatrix: Float32Array = this._$matrix; + // if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + // || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + // || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + // ) { + // multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + // } + + // const instances: Map> = $renderPlayer.instances; + // const children: Int32Array = this._$children; + // for (let idx: number = 0; idx < this._$children.length; ++idx) { + + // const id: number = children[idx]; + // if (!instances.has(id)) { + // continue; + // } + + // const instance: RenderDisplayObjectImpl | void = instances.get(id); + + // // mask instance + // if (!instance || instance._$isMask) { + // continue; + // } + + // instance._$clip(context, multiMatrix); + // instance._$updated = false; + + // } + + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @param {Float32Array} color_transform + // * @return {void} + // * @method + // * @private + // */ + // _$draw ( + // context: CanvasToWebGLContext, + // matrix: Float32Array, + // color_transform: Float32Array + // ): void { + + // // not draw + // if (!this._$visible) { + // return ; + // } + + // let multiColor: Float32Array = color_transform; + // const rawColor: Float32Array = this._$colorTransform; + // if (rawColor[0] !== 1 || rawColor[1] !== 1 + // || rawColor[2] !== 1 || rawColor[3] !== 1 + // || rawColor[4] !== 0 || rawColor[5] !== 0 + // || rawColor[6] !== 0 || rawColor[7] !== 0 + // ) { + // multiColor = $multiplicationColor(color_transform, rawColor); + // } + + // // not draw + // const alpha: number = $clamp(multiColor[3] + multiColor[7] / 255, 0, 1, 0); + // if (!alpha) { + // return ; + // } + + // // not draw + // const children: Int32Array = this._$children; + // const length: number = children.length; + // if (!length) { + // return ; + // } + + // // pre data + // const preObject: PreObjectImpl | null = this._$preDraw(context, matrix); + // if (!preObject) { + // return ; + // } + + // // use cache + // if (preObject.isLayer && !preObject.isUpdated) { + // this._$postDraw(context, matrix, multiColor, preObject); + // return ; + // } + + // const preMatrix: Float32Array = preObject.matrix as NonNullable; + // const preColorTransform: Float32Array = preObject.isLayer && preObject.color + // ? preObject.color + // : multiColor; + + // // init clip params + // let shouldClip: boolean = true; + // let clipDepth: number = 0; + + // // draw children + // const instances: Map> = $renderPlayer.instances; + // const isLayer: boolean = context.isLayer; + // for (let idx: number = 0; idx < length; ++idx) { + + // const id: number = children[idx]; + // if (!instances.has(id)) { + // continue; + // } + + // const instance: RenderDisplayObjectImpl = instances.get(id); + + // // mask instance + // if (instance._$isMask) { + // continue; + // } + + // // not layer mode + // const blendMode: BlendModeImpl = instance._$blendMode; + // if ((blendMode === "alpha" || blendMode === "erase") + // && !isLayer + // ) { + // continue; + // } + + // // mask end + // if (clipDepth + // && (instance._$depth > clipDepth || instance._$clipDepth > 0) + // ) { + + // context.restore(); + + // if (shouldClip) { + // context._$leaveClip(); + // } + + // // clear + // clipDepth = 0; + // shouldClip = true; + // } + + // // mask size 0 + // if (!shouldClip) { + // continue; + // } + + // // mask start + // if (instance._$clipDepth > 0) { + + // clipDepth = instance._$clipDepth; + // shouldClip = instance._$shouldClip(preMatrix); + + // if (shouldClip) { + // context.save(); + // shouldClip = instance._$startClip(context, preMatrix); + // } + + // continue; + // } + + // // mask start + // const maskInstance: RenderDisplayObjectImpl | null = instance._$maskId > -1 && instances.has(instance._$maskId) + // ? instances.get(instance._$maskId) + // : null; + + // if (maskInstance) { + + // maskInstance._$updated = false; + + // let maskMatrix: Float32Array; + + // if (this._$instanceId === maskInstance._$parentId) { + + // maskMatrix = preMatrix; + + // } else { + + // maskMatrix = $MATRIX_ARRAY_IDENTITY; + + // let parent: ParentImpl | void = instances.get(maskInstance._$parentId); + // while (parent || parent._$instanceId !== parent._$parentId) { + + // maskMatrix = $multiplicationMatrix( + // parent._$matrix, + // maskMatrix + // ); + + // parent = instances.get(parent._$parentId); + // } + + // const mScale: number = $renderPlayer.scaleX; + // const playerMatrix: Float32Array = $getFloat32Array6( + // mScale, 0, 0, mScale, 0, 0 + // ); + + // maskMatrix = $multiplicationMatrix( + // playerMatrix, maskMatrix + // ); + // $poolFloat32Array6(playerMatrix); + + // if (context.isLayer) { + // const currentPosition: BoundsImpl = context.getCurrentPosition(); + // maskMatrix[4] -= currentPosition.xMin; + // maskMatrix[5] -= currentPosition.yMin; + // } + // } + + // if (!maskInstance._$shouldClip(maskMatrix)) { + // continue; + // } + + // const result: boolean = maskInstance._$startClip(context, maskMatrix); + + // context.save(); + + // if (!result) { // fixed + // context.restore(); + // continue; + // } + // } + + // instance._$draw(context, preMatrix, preColorTransform); + // instance._$updated = false; + + // // mask end + // if (maskInstance) { + // context.restore(); + // context._$leaveClip(); + // } + // } + + // // end mask + // if (clipDepth) { + // context.restore(); + + // if (shouldClip) { + // context._$leaveClip(); + // } + // } + + // // filter and blend + // if (preObject.isLayer) { + // return this._$postDraw(context, matrix, multiColor, preObject); + // } + + // if (preObject.matrix !== matrix) { + // $poolFloat32Array6(preObject.matrix as NonNullable); + // } + + // if (multiColor !== color_transform) { + // $poolFloat32Array8(multiColor); + // } + + // $poolPreObject(preObject); + // } + + // /** + // * @param {Float32Array} multi_matrix + // * @return {object} + // * @private + // */ + // _$getLayerBounds (multi_matrix: Float32Array): BoundsImpl + // { + // const children: Int32Array = this._$children; + // const length: number = children.length; + + // // size zero + // if (!length) { + // return $getBoundsObject(0, 0, 0, 0); + // } + + // // data init + // const no: number = $Number.MAX_VALUE; + // let xMin: number = no; + // let xMax: number = -no; + // let yMin: number = no; + // let yMax: number = -no; + + // const instances: Map> = $renderPlayer.instances; + // for (let idx: number = 0; idx < children.length; ++idx) { + + // const id: number = children[idx]; + // if (!instances.has(id)) { + // continue; + // } + + // const instance = instances.get(id); + + // let multiMatrix = multi_matrix; + // const rawMatrix: Float32Array = instance._$matrix; + // if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + // || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + // || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + // ) { + // multiMatrix = $multiplicationMatrix(multi_matrix, rawMatrix); + // } + + // const bounds: BoundsImpl = instance._$getLayerBounds(multiMatrix); + + // xMin = $Math.min(xMin, bounds.xMin); + // xMax = $Math.max(xMax, bounds.xMax); + // yMin = $Math.min(yMin, bounds.yMin); + // yMax = $Math.max(yMax, bounds.yMax); + + // $poolBoundsObject(bounds); + + // if (multiMatrix !== multi_matrix) { + // $poolFloat32Array6(multiMatrix); + // } + // } + + // if (!this._$filters || !this._$filters.length) { + // return $getBoundsObject(xMin, xMax, yMin, yMax); + // } + + // let filterBounds: BoundsImpl = $getBoundsObject( + // 0, xMax - xMin, + // 0, yMax - yMin + // ); + + // let xScale: number = +$Math.sqrt( + // multi_matrix[0] * multi_matrix[0] + // + multi_matrix[1] * multi_matrix[1] + // ); + // let yScale: number = +$Math.sqrt( + // multi_matrix[2] * multi_matrix[2] + // + multi_matrix[3] * multi_matrix[3] + // ); + + // xScale /= $devicePixelRatio; + // yScale /= $devicePixelRatio; + + // xScale *= 2; + // yScale *= 2; + // for (let idx: number = 0; idx < this._$filters.length; ++idx) { + // filterBounds = this._$filters[idx] + // ._$generateFilterRect(filterBounds, xScale, yScale); + // } + + // xMax += filterBounds.xMax - (xMax - xMin); + // yMax += filterBounds.yMax - (yMax - yMin); + // xMin += filterBounds.xMin; + // yMin += filterBounds.yMin; + + // $poolBoundsObject(filterBounds); + + // return $getBoundsObject(xMin, xMax, yMin, yMax); + // } + + // /** + // * @param {Float32Array} [matrix=null] + // * @returns {object} + // * @method + // * @private + // */ + // _$getBounds (matrix: Float32Array | null = null): BoundsImpl + // { + // let multiMatrix: Float32Array = $MATRIX_ARRAY_IDENTITY; + // if (matrix) { + + // multiMatrix = matrix; + + // const rawMatrix: Float32Array = this._$matrix; + // if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + // || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + // || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + // ) { + // multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + // } + // } + + // const children: Int32Array = this._$children; + // const length: number = children.length; + + // // size zero + // if (!length) { + + // const bounds: BoundsImpl = $getBoundsObject( + // multiMatrix[4], -multiMatrix[4], + // multiMatrix[5], -multiMatrix[5] + // ); + + // if (matrix && multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + + // return bounds; + // } + + // // data init + // const no = $Number.MAX_VALUE; + // let xMin = no; + // let xMax = -no; + // let yMin = no; + // let yMax = -no; + + // const instances: Map> = $renderPlayer.instances; + // for (let idx: number = 0; idx < children.length; ++idx) { + + // const id: number = children[idx]; + // if (!instances.has(id)) { + // continue; + // } + + // const bounds: BoundsImpl = instances + // .get(id) + // ._$getBounds(multiMatrix); + + // xMin = $Math.min(xMin, bounds.xMin); + // xMax = $Math.max(xMax, bounds.xMax); + // yMin = $Math.min(yMin, bounds.yMin); + // yMax = $Math.max(yMax, bounds.yMax); + + // $poolBoundsObject(bounds); + + // } + + // if (matrix && multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + + // // end + // return $getBoundsObject(xMin, xMax, yMin, yMax); + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @return {object} + // * @private + // */ + // _$preDraw ( + // context: CanvasToWebGLContext, + // matrix: Float32Array + // ): PreObjectImpl | null { + + // let multiMatrix: Float32Array = matrix; + // const rawMatrix: Float32Array = this._$matrix; + // if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + // || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + // || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + // ) { + // multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + // } + + // // size zero + // if (!multiMatrix[0] && !multiMatrix[1] + // || !multiMatrix[2] && !multiMatrix[3] + // ) { + // return null; + // } + + // // return object + // const object: PreObjectImpl = $getPreObject(); + + // // setup + // object.matrix = multiMatrix; + + // // check + // const blendMode: BlendModeImpl = this._$blendMode; + // if (blendMode !== "normal" + // || this._$filters && this._$filters.length > 0 + // ) { + + // // check size + // const baseBounds: BoundsImpl = this._$getBounds(null); + // const bounds: BoundsImpl = $boundsMatrix(baseBounds, multiMatrix); + // $poolBoundsObject(baseBounds); + + // const xMax: number = +bounds.xMax; + // const xMin: number = +bounds.xMin; + // const yMax: number = +bounds.yMax; + // const yMin: number = +bounds.yMin; + // $poolBoundsObject(bounds); + + // const width: number = $Math.ceil($Math.abs(xMax - xMin)); + // const height: number = $Math.ceil($Math.abs(yMax - yMin)); + // if (0 >= width || 0 >= height) { + // $poolPreObject(object); + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + // return null; + // } + + // let xScale: number = +$Math.sqrt( + // multiMatrix[0] * multiMatrix[0] + // + multiMatrix[1] * multiMatrix[1] + // ); + // if (!$Number.isInteger(xScale)) { + // const value: string = xScale.toString(); + // const index: number = value.indexOf("e"); + // if (index !== -1) { + // xScale = +value.slice(0, index); + // } + // xScale = +xScale.toFixed(4); + // } + + // let yScale: number = +$Math.sqrt( + // multiMatrix[2] * multiMatrix[2] + // + multiMatrix[3] * multiMatrix[3] + // ); + // if (!$Number.isInteger(yScale)) { + // const value: string = yScale.toString(); + // const index: number = value.indexOf("e"); + // if (index !== -1) { + // yScale = +value.slice(0, index); + // } + // yScale = +yScale.toFixed(4); + // } + + // object.canApply = this._$canApply(this._$filters); + // let filterBounds: BoundsImpl = $getBoundsObject(0, width, 0, height); + // if (object.canApply && this._$filters) { + // for (let idx: number = 0; idx < this._$filters.length ; ++idx) { + // filterBounds = this._$filters[idx] + // ._$generateFilterRect(filterBounds, xScale, yScale); + // } + // } + + // const currentAttachment: AttachmentImpl | null = context + // .frameBuffer + // .currentAttachment; + + // if (!currentAttachment + // || !currentAttachment.texture + // || xMin - filterBounds.xMin > currentAttachment.width + // || yMin - filterBounds.yMin > currentAttachment.height + // ) { + // $poolBoundsObject(filterBounds); + // $poolPreObject(object); + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + // return null; + // } + + // if (0 > xMin + filterBounds.xMax || 0 > yMin + filterBounds.yMax) { + // $poolBoundsObject(filterBounds); + // $poolPreObject(object); + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + // return null; + // } + + // // move size + // let tx: number = multiMatrix[4] - xMin; + // let ty: number = multiMatrix[5] - yMin; + + // // start layer + // context._$startLayer( + // $getBoundsObject(xMin, xMax, yMin, yMax) + // ); + + // // check cache + // const updated: boolean = this._$isFilterUpdated( + // multiMatrix, this._$filters, object.canApply + // ); + + // const layerBounds: BoundsImpl = this._$getLayerBounds(multiMatrix); + + // const layerWidth: number = $Math.ceil($Math.abs(layerBounds.xMax - layerBounds.xMin)); + // const layerHeight: number = $Math.ceil($Math.abs(layerBounds.yMax - layerBounds.yMin)); + // $poolBoundsObject(layerBounds); + + // const sw = layerWidth - filterBounds.xMax + filterBounds.xMin; + // const sh = layerHeight - filterBounds.yMax + filterBounds.yMin; + + // tx += sw; + // ty += sh; + + // object.sw = sw; + // object.sh = sh; + // if (updated) { + // context._$saveAttachment( + // $Math.ceil(width + sw), + // $Math.ceil(height + sh), + // true + // ); + // } + + // // setup + // object.isLayer = true; + // object.isUpdated = updated; + // object.filters = this._$filters; + // object.blendMode = blendMode; + // object.color = $getFloat32Array8(); + // object.matrix = $getFloat32Array6( + // multiMatrix[0], multiMatrix[1], + // multiMatrix[2], multiMatrix[3], + // tx, ty + // ); + + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + + // $poolBoundsObject(filterBounds); + // } + + // return object; + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @param {Float32Array} color_transform + // * @param {object} object + // * @return {void} + // * @method + // * @private + // */ + // _$postDraw ( + // context: CanvasToWebGLContext, + // matrix: Float32Array, + // color_transform: Float32Array, + // object: PreObjectImpl + // ): void { + + // context.drawInstacedArray(); + + // // cache + // const cacheKeys: any[] = $getArray(this._$instanceId, "f"); + + // const manager: FrameBufferManager = context.frameBuffer; + // const multiMatrix: Float32Array = object.matrix as NonNullable; + + // let offsetX: number = 0; + // let offsetY: number = 0; + // let texture: WebGLTexture | null = $cacheStore.get(cacheKeys); + + // if (!texture || object.isUpdated) { + + // // remove + // if (texture) { + // $cacheStore.set(cacheKeys, null); + // } + + // texture = manager + // .getTextureFromCurrentAttachment(); + + // const filters: FilterArrayImpl | null = object.filters; + // let filterState = false; + // if (filters && filters.length) { + + // for (let idx: number = 0; idx < filters.length; ++idx) { + // texture = filters[idx] + // ._$applyFilter(context, matrix); + // } + + // // update + // filterState = true; + // offsetX = context._$offsetX; + // offsetY = context._$offsetY; + + // // reset + // context._$offsetX = 0; + // context._$offsetY = 0; + // } + + // texture.filterState = filterState; + // texture.matrix = `${multiMatrix[0]}_` + // + `${multiMatrix[1]}_` + // + `${multiMatrix[2]}_` + // + `${multiMatrix[3]}`; + + // texture.offsetX = offsetX; + // texture.offsetY = offsetY; + + // $cacheStore.set(cacheKeys, texture); + + // context._$restoreAttachment(); + // } + + // if (texture.offsetX) { + // offsetX = texture.offsetX; + // } + + // if (texture.offsetY) { + // offsetY = texture.offsetY; + // } + + // // set + // context.reset(); + // context.globalAlpha = $clamp( + // color_transform[3] + color_transform[7] / 255, 0, 1 + // ); + // context.globalCompositeOperation = object.blendMode; + + // const bounds: BoundsImpl = context.getCurrentPosition(); + + // context.setTransform( + // 1, 0, 0, 1, + // bounds.xMin - offsetX - object.sw, + // bounds.yMin - offsetY - object.sh + // ); + + // context.drawImage(texture, + // 0, 0, texture.width, texture.height, + // color_transform + // ); + + // // end blend + // context._$endLayer(); + + // // end blend + // context._$endLayer(); + + // // object pool + // $poolFloat32Array6(object.matrix as NonNullable); + // $poolPreObject(object); + + // // reset + // context.cachePosition = null; + // } + + // /** + // * @description Playerから登録を削除 + // * + // * @return {void} + // * @method + // * @private + // */ + // _$remove (): void + // { + // // reset + // this._$children = new Int32Array(); + + // super._$remove(); + + // $containers.push(this); + // } +} \ No newline at end of file diff --git a/packages/renderer/src/RendererGraphics.ts b/packages/renderer/src/RendererGraphics.ts new file mode 100644 index 00000000..f27ebad6 --- /dev/null +++ b/packages/renderer/src/RendererGraphics.ts @@ -0,0 +1,1176 @@ +import { RenderDisplayObject } from "./RenderDisplayObject"; +import type { GridImpl } from "../interface/GridImpl"; +import type { BlendModeImpl } from "../interface/BlendModeImpl"; +import type { FilterArrayImpl } from "../interface/FilterArrayImpl"; +import type { BoundsImpl } from "../interface/BoundsImpl"; +import type { AttachmentImpl } from "../interface/AttachmentImpl"; +import type { SpreadMethodImpl } from "../interface/SpreadMethodImpl"; +import type { PropertyMessageMapImpl } from "../interface/PropertyMessageMapImpl"; +import type { ColorStopImpl } from "../interface/ColorStopImpl"; +import type { CachePositionImpl } from "../interface/CachePositionImpl"; +import type { ShapeModeImpl } from "../interface/ShapeModeImpl"; +import type { + CanvasToWebGLContext, + CanvasGradientToWebGL, + FrameBufferManager +} from "@next2d/webgl"; +import { $renderPlayer } from "../RenderGlobal"; +import { + $cacheStore, + $clamp, + $getBoundsObject, + $boundsMatrix, + $Math, + $poolBoundsObject, + $Infinity, + $Number, + $getArray, + $poolArray, + $getFloat32Array6, + $getFloat32Array4, + $multiplicationMatrix, + $poolFloat32Array6, + $getInt32Array4, + $linearGradientXY, + $getFloat32Array8 +} from "@next2d/share"; + +/** + * @class + */ +export class RenderGraphics extends RenderDisplayObject +{ + public _$recodes: Float32Array | null; + public _$maxAlpha: number; + public _$canDraw: boolean; + private _$uniqueKey: string; + private _$cacheKeys: string[]; + private _$cacheParams: number[]; + public _$bitmapId: number; + public _$mode: ShapeModeImpl; + + /** + * @constructor + * @public + */ + constructor () + { + super(); + + /** + * @type {Float32Array} + * @default null + * @private + */ + this._$recodes = null; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$maxAlpha = 0; + + /** + * @type {boolean} + * @default false + * @private + */ + this._$canDraw = false; + + /** + * @type {string} + * @default "" + * @private + */ + this._$uniqueKey = ""; + + /** + * @type {array} + * @private + */ + this._$cacheKeys = $getArray(); + + /** + * @type {array} + * @private + */ + this._$cacheParams = $getArray(0, 0, 0); + + /** + * @type {number} + * @default 0 + * @private + */ + this._$bitmapId = 0; + + /** + * @type {string} + * @default "shape" + * @private + */ + this._$mode = "shape"; + } + + /** + * @param {CanvasToWebGLContext} context + * @param {Float32Array} matrix + * @return {void} + * @method + * @private + */ + _$clip ( + context: CanvasToWebGLContext, + matrix: Float32Array + ): void { + + if (!this._$recodes) { + return ; + } + + // size + const baseBounds: BoundsImpl = this._$getBounds(); + + const bounds: BoundsImpl = $boundsMatrix(baseBounds, matrix); + $poolBoundsObject(baseBounds); + + const width: number = $Math.ceil($Math.abs(bounds.xMax - bounds.xMin)); + const height: number = $Math.ceil($Math.abs(bounds.yMax - bounds.yMin)); + $poolBoundsObject(bounds); + + switch (true) { + + case width === 0: + case height === 0: + case width === -$Infinity: + case height === -$Infinity: + case width === $Infinity: + case height === $Infinity: + return; + + default: + break; + + } + + context.reset(); + context.setTransform( + matrix[0], matrix[1], matrix[2], + matrix[3], matrix[4], matrix[5] + ); + + this._$runCommand(context, this._$recodes, null, true); + + context.clip(); + } + + /** + * @return {string} + * @method + * @private + */ + _$createCacheKey (): string + { + if (!this._$recodes) { + return ""; + } + + let hash = 0; + for (let idx: number = 0; idx < this._$recodes.length; idx++) { + + const chr: number = this._$recodes[idx]; + + hash = (hash << 5) - hash + chr; + hash |= 0; + } + + return `${hash}`; + } + + /** + * @return {WebGLTexture | null} + * @method + * @private + */ + _$createBitmapTexture ( + context: CanvasToWebGLContext, + position: CachePositionImpl, + x_scale: number, + y_scale: number, + width: number, + height: number + ): WebGLTexture | null { + + if (this._$mode !== "bitmap") { + return null; + } + + context.drawInstacedArray(); + + const manager: FrameBufferManager = context.frameBuffer; + const currentAttachment: AttachmentImpl | null = manager.currentAttachment; + + const attachment: AttachmentImpl = manager + .createCacheAttachment(width, height); + + context._$bind(attachment); + + context.reset(); + + const parentMatrix: Float32Array = $getFloat32Array6( + x_scale, 0, 0, y_scale, + width / 2, height / 2 + ); + + const texture: WebGLTexture = context.getTextureFromRect(position); + + const baseMatrix: Float32Array = $getFloat32Array6( + 1, 0, 0, 1, + -texture.width / 2, + -texture.height / 2 + ); + + const scaleMatrix = $multiplicationMatrix( + parentMatrix, baseMatrix + ); + $poolFloat32Array6(parentMatrix); + $poolFloat32Array6(baseMatrix); + + context.setTransform( + scaleMatrix[0], scaleMatrix[1], + scaleMatrix[2], scaleMatrix[3], + scaleMatrix[4], scaleMatrix[5] + ); + + context.drawImage(texture, 0, 0, texture.width, texture.height); + + const bitmapTexture: WebGLTexture = manager.getTextureFromCurrentAttachment(); + context._$bind(currentAttachment); + + manager.releaseAttachment(attachment); + manager.textureManager.release(texture); + + return bitmapTexture; + } + + /** + * @param {CanvasToWebGLContext} context + * @param {Float32Array} matrix + * @param {Float32Array} color_transform + * @param {string} [blend_mode=BlendMode.NORMAL] + * @param {array} [filters=null] + * @return {void} + * @method + * @private + */ + _$draw ( + context: CanvasToWebGLContext, + matrix: Float32Array, + color_transform: Float32Array, + blend_mode: BlendModeImpl = "normal", + filters: FilterArrayImpl | null = null + ): void { + + if (!this._$visible + || !this._$recodes + || !this._$maxAlpha + || !this._$canDraw + ) { + return ; + } + + const alpha: number = $clamp(color_transform[3] + color_transform[7] / 255, 0, 1, 0); + if (!alpha) { + return ; + } + + const rawMatrix: Float32Array = this._$matrix; + + // set grid data + let hasGrid: boolean = this._$scale9Grid !== null; + + // 9スライスを有効にしたオブジェクトが回転・傾斜成分を含む場合は + // 9スライスは無効になる + if (hasGrid) { + hasGrid = hasGrid + && $Math.abs(rawMatrix[1]) < 0.001 + && $Math.abs(rawMatrix[2]) < 0.0001; + } + + // size + const baseBounds: BoundsImpl = $getBoundsObject( + this._$xMin, this._$xMax, + this._$yMin, this._$yMax + ); + + const bounds: BoundsImpl = $boundsMatrix(baseBounds, matrix); + const xMax: number = bounds.xMax; + const xMin: number = bounds.xMin; + const yMax: number = bounds.yMax; + const yMin: number = bounds.yMin; + $poolBoundsObject(bounds); + + const width: number = $Math.ceil($Math.abs(xMax - xMin)); + const height: number = $Math.ceil($Math.abs(yMax - yMin)); + switch (true) { + + case width === 0: + case height === 0: + case width === 0 - $Infinity: + case height === 0 - $Infinity: + case width === $Infinity: + case height === $Infinity: + return; + + default: + break; + + } + + let xScale: number = +$Math.sqrt( + matrix[0] * matrix[0] + + matrix[1] * matrix[1] + ); + if (!$Number.isInteger(xScale)) { + const value: string = xScale.toString(); + const index: number = value.indexOf("e"); + if (index !== -1) { + xScale = +value.slice(0, index); + } + xScale = +xScale.toFixed(4); + } + + let yScale: number = +$Math.sqrt( + matrix[2] * matrix[2] + + matrix[3] * matrix[3] + ); + if (!$Number.isInteger(yScale)) { + const value: string = yScale.toString(); + const index: number = value.indexOf("e"); + if (index !== -1) { + yScale = +value.slice(0, index); + } + yScale = +yScale.toFixed(4); + } + + const canApply: boolean = filters !== null + && filters.length > 0 + && this._$canApply(filters); + + let filterBounds: BoundsImpl = $getBoundsObject(0, width, 0, height); + if (canApply && filters) { + for (let idx: number = 0; idx < filters.length ; ++idx) { + filterBounds = filters[idx] + ._$generateFilterRect(filterBounds, xScale, yScale); + } + } + + // cache current buffer + const manager: FrameBufferManager = context.frameBuffer; + const currentAttachment: AttachmentImpl | null = manager.currentAttachment; + if (!currentAttachment + || xMin - filterBounds.xMin > currentAttachment.width + || yMin - filterBounds.yMin > currentAttachment.height + ) { + $poolBoundsObject(filterBounds); + return; + } + + if (0 > xMin + filterBounds.xMax || 0 > yMin + filterBounds.yMax) { + $poolBoundsObject(filterBounds); + return; + } + + $poolBoundsObject(filterBounds); + + // get cache + if (this._$uniqueKey === "") { + if (!hasGrid + && this._$loaderInfoId > -1 + && this._$characterId > -1 + ) { + this._$uniqueKey = `${this._$loaderInfoId}@${this._$characterId}`; + } else { + this._$uniqueKey = this._$createCacheKey(); + } + } + + if (this._$mode === "bitmap") { + + if (!this._$cacheKeys.length) { + this._$cacheKeys = $cacheStore.generateKeys(this._$uniqueKey); + } + + } else { + + if (!this._$cacheKeys.length + || this._$cacheParams[0] !== xScale + || this._$cacheParams[1] !== yScale + || this._$cacheParams[2] !== color_transform[7] + ) { + + const keys: number[] = $getArray(); + keys[0] = xScale; + keys[1] = yScale; + + this._$cacheKeys = $cacheStore.generateKeys( + this._$uniqueKey, keys, color_transform + ); + + $poolArray(keys); + + this._$cacheParams[0] = xScale; + this._$cacheParams[1] = yScale; + this._$cacheParams[2] = color_transform[7]; + } + } + + context.cachePosition = $cacheStore.get(this._$cacheKeys); + if (!context.cachePosition) { + + const currentAttachment: AttachmentImpl | null = manager.currentAttachment; + + if (currentAttachment && currentAttachment.mask) { + context.stopStencil(); + } + + let width: number = 0; + let height: number = 0; + if (this._$mode === "shape") { + + width = $Math.ceil($Math.abs(baseBounds.xMax - baseBounds.xMin) * xScale); + height = $Math.ceil($Math.abs(baseBounds.yMax - baseBounds.yMin) * yScale); + + // resize + const textureScale: number = context._$getTextureScale(width, height); + if (textureScale < 1) { + width *= textureScale; + height *= textureScale; + } + + } else { + width = $Math.ceil($Math.abs(baseBounds.xMax - baseBounds.xMin)); + height = $Math.ceil($Math.abs(baseBounds.yMax - baseBounds.yMin)); + } + + // create cache position + context.cachePosition = manager.createCachePosition(width, height); + context.bindRenderBuffer(context.cachePosition); + + // reset + context.reset(); + + if (this._$mode === "shape") { + context.setTransform( + xScale, 0, 0, yScale, + -baseBounds.xMin * xScale, + -baseBounds.yMin * yScale + ); + } else { + context.setTransform( + 1, 0, 0, 1, + -baseBounds.xMin, + -baseBounds.yMin + ); + } + + if (hasGrid) { + + const mScale: number = $renderPlayer.scaleX; + + const baseMatrix: Float32Array = $getFloat32Array6( + mScale, 0, 0, mScale, 0, 0 + ); + + const pMatrix: Float32Array = $multiplicationMatrix( + baseMatrix, rawMatrix + ); + + $poolFloat32Array6(baseMatrix); + + const aMatrixBase: Float32Array = this._$matrixBase as NonNullable; + const aMatrix = $getFloat32Array6( + aMatrixBase[0], aMatrixBase[1], + aMatrixBase[2], aMatrixBase[3], + aMatrixBase[4] * mScale - xMin, + aMatrixBase[5] * mScale - yMin + ); + + const apMatrix: Float32Array = $multiplicationMatrix( + aMatrix, pMatrix + ); + + const aOffsetX: number = apMatrix[4] - (matrix[4] - xMin); + const aOffsetY: number = apMatrix[5] - (matrix[5] - yMin); + $poolFloat32Array6(apMatrix); + + const parentBounds: BoundsImpl = $boundsMatrix(baseBounds, pMatrix); + const parentXMax: number = +parentBounds.xMax; + const parentXMin: number = +parentBounds.xMin; + const parentYMax: number = +parentBounds.yMax; + const parentYMin: number = +parentBounds.yMin; + const parentWidth: number = $Math.ceil($Math.abs(parentXMax - parentXMin)); + const parentHeight: number = $Math.ceil($Math.abs(parentYMax - parentYMin)); + + $poolBoundsObject(parentBounds); + + context.grid.enable( + parentXMin, parentYMin, parentWidth, parentHeight, + baseBounds, this._$scale9Grid as NonNullable, mScale, + pMatrix[0], pMatrix[1], pMatrix[2], pMatrix[3], pMatrix[4], pMatrix[5], + aMatrix[0], aMatrix[1], aMatrix[2], aMatrix[3], aMatrix[4] - aOffsetX, aMatrix[5] - aOffsetY + ); + + $poolFloat32Array6(pMatrix); + $poolFloat32Array6(aMatrix); + } + + this._$runCommand(context, this._$recodes, color_transform, false); + + if (hasGrid) { + context.grid.disable(); + } + + manager.transferTexture(context.cachePosition); + + // set cache + $cacheStore.set(this._$cacheKeys, context.cachePosition); + + // end draw and reset current buffer + context._$bind(currentAttachment); + } + + let offsetX: number = 0; + let offsetY: number = 0; + if (canApply && filters) { + + const bitmapTexture: WebGLTexture | null = this._$createBitmapTexture( + context, context.cachePosition, + xScale, yScale, width, height + ); + + const position: CachePositionImpl = this._$drawFilter( + context, matrix, filters, + width, height, bitmapTexture + ); + + if (position.offsetX) { + offsetX = position.offsetX; + } + + if (position.offsetY) { + offsetY = position.offsetY; + } + + // update + context.cachePosition = position; + } + + if (!canApply && this._$mode === "bitmap") { + + context.setTransform( + matrix[0], matrix[1], + matrix[2], matrix[3], + baseBounds.xMin * matrix[0] + baseBounds.yMin * matrix[2] + matrix[4], + baseBounds.xMin * matrix[1] + baseBounds.yMin * matrix[3] + matrix[5] + ); + + } else { + + const radianX: number = $Math.atan2(matrix[1], matrix[0]); + const radianY: number = $Math.atan2(-matrix[2], matrix[3]); + if (!canApply && (radianX || radianY)) { + + const tx: number = baseBounds.xMin * xScale; + const ty: number = baseBounds.yMin * yScale; + + const cosX: number = $Math.cos(radianX); + const sinX: number = $Math.sin(radianX); + const cosY: number = $Math.cos(radianY); + const sinY: number = $Math.sin(radianY); + + context.setTransform( + cosX, sinX, -sinY, cosY, + tx * cosX - ty * sinY + matrix[4], + tx * sinX + ty * cosY + matrix[5] + ); + + } else { + + context.setTransform(1, 0, 0, 1, + xMin - offsetX, yMin - offsetY + ); + + } + } + + // draw + if (context.cachePosition) { + + context.globalAlpha = alpha; + context.imageSmoothingEnabled = this._$mode === "shape"; + context.globalCompositeOperation = blend_mode; + + context.drawInstance( + xMin - offsetX, yMin - offsetY, xMax, yMax, + color_transform + ); + + // cache position clear + context.cachePosition = null; + } + + // pool + $poolBoundsObject(baseBounds); + } + + /** + * @description strokeのセットアップ + * + * @param {CanvasToWebGLContext} context + * @param {number} line_width + * @param {number} line_cap + * @param {number} line_join + * @param {number} miter_limit + * @return {void} + * @method + * @public + */ + setupStroke ( + context: CanvasToWebGLContext, + line_width: number, line_cap: number, + line_join: number, miter_limit: number + ): void { + + context.lineWidth = line_width; + + switch (line_cap) { + + case 0: + context.lineCap = "none"; + break; + + case 1: + context.lineCap = "round"; + break; + + case 2: + context.lineCap = "square"; + break; + + } + + switch (line_join) { + + case 0: + context.lineJoin = "bevel"; + break; + + case 1: + context.lineJoin = "miter"; + break; + + case 2: + context.lineJoin = "round"; + break; + + } + + context.miterLimit = miter_limit; + } + + /** + * @description CanvasGradientToWebGLオブジェクトを生成 + * + * @param {CanvasToWebGLContext} context + * @param {number} type + * @param {array} stops + * @param {Float32Array} matrix + * @param {number} spread + * @param {number} interpolation + * @param {number} focal + * @param {Float32Array} [color_transform=null] + * @return {CanvasGradientToWebGL} + * @method + * @public + */ + createGradientStyle ( + context: CanvasToWebGLContext, + type: number, stops: ColorStopImpl[], + matrix: Float32Array, + spread: number, interpolation: number, focal: number, + color_transform: Float32Array | null = null + ): CanvasGradientToWebGL { + + let spreadMethod: SpreadMethodImpl = "pad"; + switch (spread) { + + case 0:// REFLECT + spreadMethod = "reflect"; + break; + + case 1: // REPEAT + spreadMethod = "repeat"; + break; + + } + + let css: CanvasGradientToWebGL; + if (type === 0) { + + // LINEAR + const xy: Float32Array = $linearGradientXY(matrix); + css = context.createLinearGradient( + xy[0], xy[1], xy[2], xy[3], + interpolation ? "rgb" : "linearRGB", + spreadMethod + ); + + } else { + + // RADIAL + context.save(); + context.transform( + matrix[0], matrix[1], matrix[2], + matrix[3], matrix[4], matrix[5] + ); + + css = context.createRadialGradient( + 0, 0, 0, 0, 0, 819.2, + interpolation ? "rgb" : "linearRGB", + spreadMethod, focal + ); + + } + + for (let idx: number = 0; idx < stops.length; ++idx) { + + const color: ColorStopImpl = stops[idx]; + + let alpha: number = color.A; + if (color_transform) { + if (color_transform[3] !== 1 || color_transform[7] !== 0) { + alpha = $Math.max(0, $Math.min(color.A * color_transform[3] + color_transform[7], 255)) | 0; + } + } + + css.addColorStop(color.ratio, $getInt32Array4( + color.R, color.G, color.B, alpha + )); + } + + return css; + } + + /** + * @description Graphicsクラスの描画を実行 + * Execute drawing in the Graphics class + * + * @param {CanvasToWebGLContext} context + * @param {Float32Array} recodes + * @param {Float32Array} [color_transform=null] + * @param {boolean} [is_clip=false] + * @return {void} + * @method + * @public + */ + _$runCommand ( + context: CanvasToWebGLContext, + recodes: Float32Array, + color_transform: Float32Array | null = null, + is_clip: boolean = false + ): void { + + // reset + context.reset(); + context.beginPath(); + + const length: number = recodes.length; + for (let idx: number = 0; idx < length; ) { + + switch (recodes[idx++]) { + + case 9: // BEGIN_PATH + context.beginPath(); + break; + + case 0: // MOVE_TO + context.moveTo(recodes[idx++], recodes[idx++]); + break; + + case 2: // LINE_TO + context.lineTo(recodes[idx++], recodes[idx++]); + break; + + case 1: // CURVE_TO + context.quadraticCurveTo( + recodes[idx++], recodes[idx++], + recodes[idx++], recodes[idx++] + ); + break; + + case 5: // FILL_STYLE + { + if (is_clip) { + idx += 4; + continue; + } + + const color: Float32Array = $getFloat32Array4(); + color[0] = recodes[idx++] / 255; + color[1] = recodes[idx++] / 255; + color[2] = recodes[idx++] / 255; + color[3] = recodes[idx++] / 255; + + if (color_transform !== null) { + if (color_transform[3] !== 1 || color_transform[7] !== 0) { + color[3] = $Math.max(0, $Math.min( + color[3] * color_transform[3] + color_transform[7], 255) + ) / 255; + } + } + + context.fillStyle = color; + } + break; + + case 7: // END_FILL + + if (!is_clip) { + context.fill(); + } + + break; + + case 6: // STROKE_STYLE + { + if (is_clip) { + idx += 8; + continue; + } + + this.setupStroke( + context, + recodes[idx++], recodes[idx++], + recodes[idx++], recodes[idx++] + ); + + const color = $getFloat32Array4(); + + color[0] = recodes[idx++] / 255; + color[1] = recodes[idx++] / 255; + color[2] = recodes[idx++] / 255; + color[3] = recodes[idx++] / 255; + + if (color_transform !== null) { + if (color_transform[3] !== 1 || color_transform[7] !== 0) { + color[3] = $Math.max(0, $Math.min( + color[3] * color_transform[3] + color_transform[7], 255) + ) / 255; + } + } + + context.strokeStyle = color; + } + break; + + case 8: // END_STROKE + if (!is_clip) { + context.stroke(); + } + break; + + case 12: // CLOSE_PATH + context.closePath(); + break; + + case 3: // CUBIC + context.bezierCurveTo( + recodes[idx++], recodes[idx++], + recodes[idx++], recodes[idx++], + recodes[idx++], recodes[idx++] + ); + break; + + case 4: // ARC + context.arc(recodes[idx++], recodes[idx++], recodes[idx++]); + break; + + case 10: // GRADIENT_FILL + { + if (is_clip) { + idx += 1; + const length = recodes[idx++]; + idx += length * 5; + idx += 9; + continue; + } + + const type: number = recodes[idx++]; + + let stopLength: number = recodes[idx++]; + const stops: ColorStopImpl[] = $getArray(); + while (stopLength) { + stops.push({ + "ratio": recodes[idx++], + "R": recodes[idx++], + "G": recodes[idx++], + "B": recodes[idx++], + "A": recodes[idx++] + }); + stopLength--; + } + + const matrix: Float32Array = $getFloat32Array6( + recodes[idx++], recodes[idx++], recodes[idx++], + recodes[idx++], recodes[idx++], recodes[idx++] + ); + + context.fillStyle = this.createGradientStyle( + context, type, stops, matrix, + recodes[idx++], recodes[idx++], recodes[idx++], + color_transform + ); + + context.fill(); + + // if RADIAL + if (type === 1) { + context.restore(); + } + + $poolFloat32Array6(matrix); + $poolArray(stops); + } + break; + + case 11: // GRADIENT_STROKE + { + if (is_clip) { + idx += 5; + const length = recodes[idx++]; + idx += length * 5; + idx += 9; + continue; + } + + this.setupStroke( + context, + recodes[idx++], recodes[idx++], + recodes[idx++], recodes[idx++] + ); + + const type: number = recodes[idx++]; + + let stopLength: number = recodes[idx++]; + + const stops: ColorStopImpl[] = $getArray(); + while (stopLength) { + stops.push({ + "ratio": recodes[idx++], + "R": recodes[idx++], + "G": recodes[idx++], + "B": recodes[idx++], + "A": recodes[idx++] + }); + stopLength--; + } + + const matrix: Float32Array = $getFloat32Array6( + recodes[idx++], recodes[idx++], recodes[idx++], + recodes[idx++], recodes[idx++], recodes[idx++] + ); + + context.strokeStyle = this.createGradientStyle( + context, type, stops, matrix, + recodes[idx++], recodes[idx++], recodes[idx++], + color_transform + ); + + context.stroke(); + + // if RADIAL + if (type === 1) { + context.restore(); + } + + $poolFloat32Array6(matrix); + $poolArray(stops); + } + break; + + case 13: // BITMAP_FILL + { + const width: number = recodes[idx++]; + const height: number = recodes[idx++]; + const graphicsWidth: number = recodes[idx++]; + const graphicsHeight: number = recodes[idx++]; + const bitmapLength: number = recodes[idx++]; + if (is_clip) { + idx += bitmapLength; + idx += 8; + continue; + } + + const buffer: Uint8Array = new Uint8Array( + recodes.subarray(idx, bitmapLength + idx) + ); + + idx += bitmapLength; + const matrix: Float32Array = $getFloat32Array6( + recodes[idx++], recodes[idx++], recodes[idx++], + recodes[idx++], recodes[idx++], recodes[idx++] + ); + + const repeat: boolean = !!recodes[idx++]; + const smooth: boolean = !!recodes[idx++]; + + context.save(); + + if (matrix[0] !== 1 || matrix[1] !== 0 + || matrix[2] !== 0 || matrix[3] !== 1 + || matrix[4] !== 0 || matrix[5] !== 0 + ) { + context.transform( + matrix[0], matrix[1], matrix[2], + matrix[3], matrix[4], matrix[5] + ); + } + $poolFloat32Array6(matrix); + + const manager: FrameBufferManager = context.frameBuffer; + const texture: WebGLTexture = manager.createTextureFromPixels( + width, height, buffer, true + ); + + if (!repeat + && width === graphicsWidth + && height === graphicsHeight + ) { + + context.drawImage(texture, 0, 0, width, height); + manager.releaseTexture(texture); + + } else { + + context.fillStyle = context.createPattern( + texture, repeat, color_transform || $getFloat32Array8() + ); + + context.imageSmoothingEnabled = smooth; + context.fill(); + + } + + // restore + context.restore(); + context.imageSmoothingEnabled = false; + + } + break; + + case 14: // BITMAP_STROKE + { + if (is_clip) { + idx += 4; + const bitmapLength = recodes[idx++]; + idx += bitmapLength; + idx += 8; + continue; + } + + context.save(); + + this.setupStroke( + context, + recodes[idx++], recodes[idx++], + recodes[idx++], recodes[idx++] + ); + + const width: number = recodes[idx++]; + const height: number = recodes[idx++]; + const bitmapLength: number = recodes[idx++]; + + const buffer: Uint8Array = new Uint8Array( + recodes.subarray(idx, bitmapLength + idx) + ); + + idx += bitmapLength; + const matrix: Float32Array = $getFloat32Array6( + recodes[idx++], recodes[idx++], recodes[idx++], + recodes[idx++], recodes[idx++], recodes[idx++] + ); + + if (matrix[0] !== 1 || matrix[1] !== 0 + || matrix[2] !== 0 || matrix[3] !== 1 + || matrix[4] !== 0 || matrix[5] !== 0 + ) { + context.transform( + matrix[0], matrix[1], matrix[2], + matrix[3], matrix[4], matrix[5] + ); + } + $poolFloat32Array6(matrix); + + const repeat: boolean = !!recodes[idx++]; + const smooth: boolean = !!recodes[idx++]; + + const manager: FrameBufferManager = context.frameBuffer; + const texture: WebGLTexture = manager.createTextureFromPixels( + width, height, buffer, true + ); + + context.strokeStyle = context.createPattern( + texture, repeat, color_transform || $getFloat32Array8() + ); + + context.imageSmoothingEnabled = smooth; + context.stroke(); + + // restore + context.restore(); + context.imageSmoothingEnabled = false; + } + break; + + default: + break; + + } + } + } + + /** + * @description 描画情報を更新 + * + * @param {object} object + * @return {void} + * @method + * @private + */ + _$update (object: PropertyMessageMapImpl): void + { + super._$update(object); + + if (object.recodes) { + + this._$recodes = object.recodes; + this._$xMin = object.xMin; + this._$yMin = object.yMin; + this._$xMax = object.xMax; + this._$yMax = object.yMax; + this._$maxAlpha = object.maxAlpha; + this._$canDraw = object.canDraw; + + $cacheStore.removeCache(this._$instanceId); + + if (this._$loaderInfoId > -1 + && this._$characterId > -1 + ) { + $cacheStore.removeCache( + `${this._$loaderInfoId}@${this._$characterId}` + ); + } + } + } +} \ No newline at end of file diff --git a/packages/renderer/src/RendererShape.ts b/packages/renderer/src/RendererShape.ts new file mode 100644 index 00000000..2c826a9f --- /dev/null +++ b/packages/renderer/src/RendererShape.ts @@ -0,0 +1,152 @@ +import { RenderGraphics } from "./RenderGraphics"; +import { $shapes } from "../RenderGlobal"; +import type { BoundsImpl } from "../interface/BoundsImpl"; +import type { CanvasToWebGLContext } from "@next2d/webgl"; +import { + $boundsMatrix, + $clamp, + $Infinity, + $Math, + $multiplicationColor, + $multiplicationMatrix, + $poolBoundsObject, + $poolFloat32Array6, + $poolFloat32Array8 +} from "@next2d/share"; + +/** + * @class + */ +export class RenderShape extends RenderGraphics +{ + /** + * @param {CanvasToWebGLContext} context + * @param {Float32Array} matrix + * @return {void} + * @method + * @private + */ + _$clip ( + context: CanvasToWebGLContext, + matrix: Float32Array + ): void { + + let multiMatrix: Float32Array = matrix; + const rawMatrix: Float32Array = this._$matrix; + if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + ) { + multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + } + + // size + const baseBounds: BoundsImpl = this._$getBounds(); + const bounds: BoundsImpl = $boundsMatrix(baseBounds, multiMatrix); + $poolBoundsObject(baseBounds); + + const width: number = $Math.ceil($Math.abs(bounds.xMax - bounds.xMin)); + const height: number = $Math.ceil($Math.abs(bounds.yMax - bounds.yMin)); + $poolBoundsObject(bounds); + + switch (true) { + + case width === 0: + case height === 0: + case width === 0 - $Infinity: + case height === 0 - $Infinity: + case width === $Infinity: + case height === $Infinity: + return; + + default: + break; + + } + + super._$clip(context, multiMatrix); + + if (multiMatrix !== matrix) { + $poolFloat32Array6(multiMatrix); + } + } + + /** + * @param {CanvasToWebGLContext} context + * @param {Float32Array} matrix + * @param {Float32Array} color_transform + * @return {void} + * @method + * @private + */ + _$draw ( + context: CanvasToWebGLContext, + matrix: Float32Array, + color_transform: Float32Array + ): void { + + if (!this._$visible || !this._$maxAlpha || !this._$canDraw) { + return ; + } + + let multiColor: Float32Array = color_transform; + const rawColor: Float32Array = this._$colorTransform; + if (rawColor[0] !== 1 || rawColor[1] !== 1 + || rawColor[2] !== 1 || rawColor[3] !== 1 + || rawColor[4] !== 0 || rawColor[5] !== 0 + || rawColor[6] !== 0 || rawColor[7] !== 0 + ) { + multiColor = $multiplicationColor(color_transform, rawColor); + } + + const alpha: number = $clamp(multiColor[3] + multiColor[7] / 255, 0, 1, 0); + if (!alpha) { + if (multiColor !== color_transform) { + $poolFloat32Array8(multiColor); + } + return ; + } + + let multiMatrix: Float32Array = matrix; + const rawMatrix: Float32Array = this._$matrix; + if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + ) { + multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + } + + super._$draw( + context, multiMatrix, multiColor, + this._$blendMode, this._$filters + ); + + if (multiMatrix !== matrix) { + $poolFloat32Array6(multiMatrix); + } + + if (multiColor !== color_transform) { + $poolFloat32Array8(multiColor); + } + } + + /** + * @description Playerから登録を削除 + * + * @return {void} + * @method + * @private + */ + _$remove (): void + { + this._$xMin = 0; + this._$yMin = 0; + this._$xMax = 0; + this._$yMax = 0; + this._$recodes = null; + + super._$remove(); + + $shapes.push(this); + } +} \ No newline at end of file diff --git a/packages/renderer/src/RendererTextField.ts b/packages/renderer/src/RendererTextField.ts new file mode 100644 index 00000000..1a16d4cc --- /dev/null +++ b/packages/renderer/src/RendererTextField.ts @@ -0,0 +1,1031 @@ +import { RenderDisplayObject } from "./RenderDisplayObject"; +import type{ TextDataImpl } from "../interface/TextDataImpl"; +import type{ PropertyTextMessageImpl } from "../interface/PropertyTextMessageImpl"; +import type{ TextFieldAutoSizeImpl } from "../interface/TextFieldAutoSizeImpl"; +import type{ TextFormatVerticalAlignImpl } from "../interface/TextFormatVerticalAlignImpl"; +import type{ BoundsImpl } from "../interface/BoundsImpl"; +import type{ AttachmentImpl } from "../interface/AttachmentImpl"; +import type{ RGBAImpl } from "../interface/RGBAImpl"; +import type{ TextFormatImpl } from "../interface/TextFormatImpl"; +import type { FilterArrayImpl } from "../interface/FilterArrayImpl"; +import type { CachePositionImpl } from "../interface/CachePositionImpl"; +import type { + CanvasToWebGLContext, + FrameBufferManager +} from "@next2d/webgl"; +import { + $isSafari, + $textFields +} from "../RenderGlobal"; +import { + $cacheStore, + $boundsMatrix, + $clamp, + $generateFontStyle, + $getArray, + $Infinity, + $intToRGBA, + $Math, + $multiplicationColor, + $multiplicationMatrix, + $Number, + $poolArray, + $poolBoundsObject, + $poolFloat32Array6, + $poolFloat32Array8, + $getBoundsObject +} from "@next2d/share"; + +/** + * @class + */ +export class RenderTextField extends RenderDisplayObject +{ + private _$background: boolean; + private _$backgroundColor: number; + private _$border: boolean; + private _$borderColor: number; + private readonly _$textData: TextDataImpl[]; + private _$textAreaActive: boolean; + private _$thickness: number; + private _$thicknessColor: number; + private _$limitWidth: number; + private _$limitHeight: number; + private _$autoSize: TextFieldAutoSizeImpl; + private readonly _$widthTable: number[]; + private readonly _$heightTable: number[]; + private readonly _$objectTable: TextDataImpl[]; + private readonly _$textHeightTable: number[]; + private _$scrollV: number; + private _$maxScrollV: number | null; + private _$textHeight: number; + private _$verticalAlign: TextFormatVerticalAlignImpl; + private _$wordWrap: boolean; + private _$cacheKeys: string[]; + private _$cacheParams: number[]; + + /** + * @constructor + * @public + */ + constructor () + { + super(); + + /** + * @type {boolean} + * @default false + * @private + */ + this._$background = false; + + /** + * @type {number} + * @default 0xffffff + * @private + */ + this._$backgroundColor = 0xffffff; + + /** + * @type {boolean} + * @default false + * @private + */ + this._$border = false; + + /** + * @type {number} + * @default 0x000000 + * @private + */ + this._$borderColor = 0x000000; + + /** + * @type {boolean} + * @default false + * @private + */ + this._$wordWrap = false; + + /** + * @type {array} + * @private + */ + this._$textData = $getArray(); + + /** + * @type {boolean} + * @default false + * @private + */ + this._$textAreaActive = false; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$thickness = 0; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$thicknessColor = 0; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$limitWidth = 0; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$limitHeight = 0; + + /** + * @type {string} + * @default TextFieldAutoSize.NONE + * @private + */ + this._$autoSize = "none"; + + /** + * @type {array} + * @default null + * @private + */ + this._$widthTable = $getArray(); + + /** + * @type {array} + * @default null + * @private + */ + this._$heightTable = $getArray(); + + /** + * @type {array} + * @default null + * @private + */ + this._$objectTable = $getArray(); + + /** + * @type {array} + * @default null + * @private + */ + this._$textHeightTable = $getArray(); + + /** + * @type {number} + * @default 0 + * @private + */ + this._$xMin = 0; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$yMin = 0; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$xMax = 0; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$yMax = 0; + + /** + * @type {number} + * @default null + * @private + */ + this._$maxScrollV = null; + + /** + * @type {number} + * @default 1 + * @private + */ + this._$scrollV = 1; + + /** + * @type {number} + * @default 0 + * @private + */ + this._$textHeight = 0; + + /** + * @type {string} + * @default TextFormatVerticalAlign.TOP + * @private + */ + this._$verticalAlign = "top"; + + /** + * @type {array} + * @private + */ + this._$cacheKeys = $getArray(); + + /** + * @type {array} + * @private + */ + this._$cacheParams = $getArray(0, 0, 0); + } + + /** + * @description 表示オブジェクトの幅を示します(ピクセル単位)。 + * Indicates the width of the display object, in pixels. + * + * @member {number} + * @public + */ + get width (): number + { + const bounds: BoundsImpl = $boundsMatrix( + this._$getBounds(null), + this._$matrix + ); + + const width: number = $Math.abs(bounds.xMax - bounds.xMin); + $poolBoundsObject(bounds); + + switch (true) { + + case width === 0: + case width === $Infinity: + case width === 0 - $Infinity: + return 0; + + default: + return width; + + } + } + + /** + * @description 表示オブジェクトの高さを示します(ピクセル単位)。 + * Indicates the height of the display object, in pixels. + * + * @member {number} + * @public + */ + get height (): number + { + const bounds: BoundsImpl = $boundsMatrix( + this._$getBounds(null), + this._$matrix + ); + + const height: number = $Math.abs(bounds.yMax - bounds.yMin); + + // object pool + $poolBoundsObject(bounds); + + switch (height) { + + case 0: + case $Infinity: + case 0 - $Infinity: + return 0; + + default: + return height; + + } + } + + /** + * @description scrollV の最大値です。 + * The maximum value of scrollV. + * + * @member {number} + * @readonly + * @public + */ + get maxScrollV (): number + { + if (this._$maxScrollV === null) { + + this._$maxScrollV = 1; + + const length: number = this._$textHeightTable.length; + const maxHeight: number = this.height; + + if (maxHeight > this._$textHeight) { + return this._$maxScrollV; + } + + let textHeight: number = 0; + + let idx: number = 0; + while (length > idx) { + + textHeight += this._$textHeightTable[idx++]; + if (textHeight > maxHeight) { + break; + } + + this._$maxScrollV++; + } + } + return this._$maxScrollV; + } + + /** + * @param {CanvasToWebGLContext} context + * @param {Float32Array} matrix + * @return {void} + * @method + * @private + */ + _$clip ( + context: CanvasToWebGLContext, + matrix: Float32Array + ): void { + + // size + const bounds: BoundsImpl = this._$getBounds(); + const xMax: number = bounds.xMax; + const xMin: number = bounds.xMin; + const yMax: number = bounds.yMax; + const yMin: number = bounds.yMin; + $poolBoundsObject(bounds); + + const width: number = $Math.ceil($Math.abs(xMax - xMin)); + const height: number = $Math.ceil($Math.abs(yMax - yMin)); + if (!width || !height) { + return; + } + + let multiMatrix: Float32Array = matrix; + const rawMatrix: Float32Array = this._$matrix; + if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + ) { + multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + } + + context.reset(); + context.setTransform( + matrix[0], matrix[1], matrix[2], + matrix[3], matrix[4], matrix[5] + ); + context.beginPath(); + context.moveTo(0, 0); + context.lineTo(width, 0); + context.lineTo(width, height); + context.lineTo(0, height); + context.lineTo(0, 0); + context.clip(); + + if (multiMatrix !== matrix) { + $poolFloat32Array6(multiMatrix); + } + } + + /** + * @param {CanvasToWebGLContext} context + * @param {Float32Array} matrix + * @param {Float32Array} color_transform + * @return {void} + * @method + * @private + */ + _$draw ( + context: CanvasToWebGLContext, + matrix: Float32Array, + color_transform: Float32Array + ): void { + + if (!this._$visible || this._$textAreaActive) { + return ; + } + + if (!this._$background && !this._$border + && 2 > this._$textData.length + ) { + return; + } + + let multiColor: Float32Array = color_transform; + const rawColor: Float32Array = this._$colorTransform; + if (rawColor[0] !== 1 || rawColor[1] !== 1 + || rawColor[2] !== 1 || rawColor[3] !== 1 + || rawColor[4] !== 0 || rawColor[5] !== 0 + || rawColor[6] !== 0 || rawColor[7] !== 0 + ) { + multiColor = $multiplicationColor(color_transform, rawColor); + } + + const alpha: number = $clamp(multiColor[3] + multiColor[7] / 255, 0 ,1); + if (!alpha) { + return ; + } + + let multiMatrix: Float32Array = matrix; + const rawMatrix: Float32Array = this._$matrix; + if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + ) { + multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + } + + const baseBounds: BoundsImpl = this._$getBounds(null); + baseBounds.xMin -= this._$thickness; + baseBounds.xMax += this._$thickness; + baseBounds.yMin -= this._$thickness; + baseBounds.yMax += this._$thickness; + + const bounds: BoundsImpl = $boundsMatrix(baseBounds, multiMatrix); + const xMax = +bounds.xMax; + const xMin = +bounds.xMin; + const yMax = +bounds.yMax; + const yMin = +bounds.yMin; + $poolBoundsObject(bounds); + + const width: number = $Math.ceil($Math.abs(xMax - xMin)); + const height: number = $Math.ceil($Math.abs(yMax - yMin)); + switch (true) { + + case width === 0: + case height === 0: + case width === -$Infinity: + case height === -$Infinity: + case width === $Infinity: + case height === $Infinity: + return; + + default: + break; + + } + + let xScale: number = +$Math.sqrt( + multiMatrix[0] * multiMatrix[0] + + multiMatrix[1] * multiMatrix[1] + ); + if (!$Number.isInteger(xScale)) { + const value: string = xScale.toString(); + const index: number = value.indexOf("e"); + if (index !== -1) { + xScale = +value.slice(0, index); + } + xScale = +xScale.toFixed(4); + } + + let yScale: number = +$Math.sqrt( + multiMatrix[2] * multiMatrix[2] + + multiMatrix[3] * multiMatrix[3] + ); + if (!$Number.isInteger(yScale)) { + const value: string = yScale.toString(); + const index: number = value.indexOf("e"); + if (index !== -1) { + yScale = +value.slice(0, index); + } + yScale = +yScale.toFixed(4); + } + + const filters: FilterArrayImpl | null = this._$filters; + const canApply: boolean = filters !== null + && filters.length > 0 + && this._$canApply(filters); + + let filterBounds: BoundsImpl = $getBoundsObject(0, width, 0, height); + if (canApply && filters) { + for (let idx: number = 0; idx < filters.length ; ++idx) { + filterBounds = filters[idx] + ._$generateFilterRect(filterBounds, xScale, yScale); + } + } + + // cache current buffer + const manager: FrameBufferManager = context.frameBuffer; + const currentAttachment: AttachmentImpl | null = manager.currentAttachment; + if (!currentAttachment + || xMin - filterBounds.xMin > currentAttachment.width + || yMin - filterBounds.yMin > currentAttachment.height + ) { + $poolBoundsObject(filterBounds); + return; + } + + if (0 > xMin + filterBounds.xMax || 0 > yMin + filterBounds.yMax) { + $poolBoundsObject(filterBounds); + return; + } + + $poolBoundsObject(filterBounds); + + // texture is small or renew + if (this._$isUpdated()) { + $cacheStore.removeCache(this._$instanceId); + context.cachePosition = null; + this._$cacheKeys.length = 0; + } + + if (!this._$cacheKeys.length + || this._$cacheParams[0] !== xScale + || this._$cacheParams[1] !== yScale + || this._$cacheParams[2] !== color_transform[7] + ) { + const keys: number[] = $getArray(xScale, yScale); + this._$cacheKeys = $cacheStore.generateKeys( + this._$instanceId, keys + ); + $poolArray(keys); + + this._$cacheParams[0] = xScale; + this._$cacheParams[1] = yScale; + this._$cacheParams[2] = color_transform[7]; + } + + context.cachePosition = $cacheStore.get(this._$cacheKeys); + if (!context.cachePosition) { + + // resize + const lineWidth: number = $Math.min(1, $Math.max(xScale, yScale)); + const baseWidth: number = $Math.ceil($Math.abs(baseBounds.xMax - baseBounds.xMin) * xScale); + const baseHeight: number = $Math.ceil($Math.abs(baseBounds.yMax - baseBounds.yMin) * yScale); + + // alpha reset + multiColor[3] = 1; + + // new canvas + const canvas: OffscreenCanvas = new OffscreenCanvas( + baseWidth + lineWidth * 2, + baseHeight + lineWidth * 2 + ); + const ctx: OffscreenCanvasRenderingContext2D | null = canvas.getContext("2d"); + if (!ctx) { + return ; + } + + // border and background + if (this._$background || this._$border) { + + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(baseWidth, 0); + ctx.lineTo(baseWidth, baseHeight); + ctx.lineTo(0, baseHeight); + ctx.lineTo(0, 0); + + if (this._$background) { + + const color: RGBAImpl = $intToRGBA(this._$backgroundColor); + const alpha: number = $Math.max(0, $Math.min( + color.A * 255 * color_transform[3] + color_transform[7], 255) + ) / 255; + + ctx.fillStyle = `rgba(${color.R},${color.G},${color.B},${alpha})`; + ctx.fill(); + } + + if (this._$border) { + + const color: RGBAImpl = $intToRGBA(this._$borderColor); + const alpha: number = $Math.max(0, $Math.min( + color.A * 255 * color_transform[3] + color_transform[7], 255) + ) / 255; + + ctx.lineWidth = lineWidth; + ctx.strokeStyle = `rgba(${color.R},${color.G},${color.B},${alpha})`; + ctx.stroke(); + } + + } + + // mask start + ctx.save(); + ctx.beginPath(); + ctx.moveTo(2, 2); + ctx.lineTo(baseWidth - 2, 2); + ctx.lineTo(baseWidth - 2, baseHeight - 2); + ctx.lineTo(2, baseHeight - 2); + ctx.lineTo(2, 2); + ctx.clip(); + + ctx.beginPath(); + ctx.setTransform(xScale, 0, 0, yScale, 0, 0); + this._$doDraw(ctx, matrix, color_transform, baseWidth / xScale); + ctx.restore(); + + const position: CachePositionImpl = manager + .createCachePosition(width, height); + + const texture: WebGLTexture = manager + .createTextureFromCanvas(ctx.canvas); + + context.drawTextureFromRect(texture, position); + + // set cache + context.cachePosition = position; + $cacheStore.set(this._$cacheKeys, position); + } + + let drawFilter: boolean = false; + let offsetX: number = 0; + let offsetY: number = 0; + if (filters && filters.length + && this._$canApply(filters) + ) { + + drawFilter = true; + + const position: CachePositionImpl = this._$drawFilter( + context, multiMatrix, filters, + width, height + ); + + if (position.offsetX) { + offsetX = position.offsetX; + } + + if (position.offsetY) { + offsetY = position.offsetY; + } + + // update + context.cachePosition = position; + } + + const radianX: number = $Math.atan2(multiMatrix[1], multiMatrix[0]); + const radianY: number = $Math.atan2(-multiMatrix[2], multiMatrix[3]); + if (!drawFilter && (radianX || radianY)) { + + const tx: number = baseBounds.xMin * xScale; + const ty: number = baseBounds.yMin * yScale; + + const cosX: number = $Math.cos(radianX); + const sinX: number = $Math.sin(radianX); + const cosY: number = $Math.cos(radianY); + const sinY: number = $Math.sin(radianY); + + context.setTransform( + cosX, sinX, -sinY, cosY, + tx * cosX - ty * sinY + multiMatrix[4], + tx * sinX + ty * cosY + multiMatrix[5] + ); + + } else { + + context.setTransform(1, 0, 0, 1, + xMin - offsetX, yMin - offsetY + ); + + } + + // draw + if (context.cachePosition) { + + context.globalAlpha = alpha; + context.imageSmoothingEnabled = true; + context.globalCompositeOperation = this._$blendMode; + + context.drawInstance( + xMin - offsetX, yMin - offsetY, xMax, yMax, + color_transform + ); + + // cache position clear + context.cachePosition = null; + } + + // get cache + $poolBoundsObject(baseBounds); + + // pool + if (multiMatrix !== matrix) { + $poolFloat32Array6(multiMatrix); + } + + if (multiColor !== color_transform) { + $poolFloat32Array8(multiColor); + } + } + + /** + * @param {CanvasRenderingContext2D} context + * @param {Float32Array} matrix + * @param {Float32Array} color_transform + * @param {number} width + * @return {void} + * @method + * @private + */ + _$doDraw ( + context: OffscreenCanvasRenderingContext2D, + matrix: Float32Array, + color_transform: Float32Array, + width: number + ): void { + + const limitWidth: number = this.width; + const limitHeight: number = this.height; + + // setup + let xOffset: number = 0; + let offsetHeight: number = 0; + let currentV: number = 0; + + let yOffset: number = 0; + if (this._$verticalAlign !== "top" + && this.height > this._$textHeight + ) { + + switch (this._$verticalAlign) { + + case "middle": + yOffset = (this.height - this._$textHeight + 2) / 2; + break; + + case "bottom": + yOffset = this.height - this._$textHeight + 2; + break; + + } + + } + + const length: number = this._$textData.length; + for (let idx: number = 0; idx < length; ++idx) { + + const obj: TextDataImpl = this._$textData[idx]; + if (obj.width === 0) { + continue; + } + + // check + const offsetWidth: number = xOffset + obj.x; + if (this._$autoSize === "none" + && (offsetHeight > limitHeight || offsetWidth > limitWidth) + ) { + continue; + } + + const tf: TextFormatImpl = obj.textFormat; + + // color + const color: RGBAImpl = $intToRGBA(obj.textFormat._$color); + const alpha: number = $Math.max(0, $Math.min( + color.A * 255 * color_transform[3] + color_transform[7], 255) + ) / 255; + + context.fillStyle = `rgba(${color.R},${color.G},${color.B},${alpha})`; + + if (this._$thickness) { + const color: RGBAImpl = $intToRGBA(this._$thicknessColor); + const alpha: number = $Math.max(0, $Math.min( + color.A * 255 * color_transform[3] + color_transform[7], 255) + ) / 255; + context.lineWidth = this._$thickness; + context.strokeStyle = `rgba(${color.R},${color.G},${color.B},${alpha})`; + } + + const yIndex: number = obj.yIndex; + switch (obj.mode) { + + case "break": + case "wrap": + + currentV++; + + if (this._$scrollV > currentV) { + continue; + } + + offsetHeight += this._$textHeightTable[yIndex]; + + xOffset = this._$getAlignOffset(this._$objectTable[yIndex], width); + if (tf._$underline) { + + const offset: number = obj.textFormat._$size / 12; + + const color: RGBAImpl = $intToRGBA(tf._$color); + const alpha: number = $Math.max(0, $Math.min( + color.A * 255 * color_transform[3] + color_transform[7], 255) + ) / 255; + + context.lineWidth = $Math.max(1, 1 / $Math.min(matrix[0], matrix[3])); + context.strokeStyle = `rgba(${color.R},${color.G},${color.B},${alpha})`; + + context.beginPath(); + context.moveTo(xOffset, yOffset + offsetHeight - offset); + context.lineTo(xOffset + this._$widthTable[yIndex], yOffset + offsetHeight - offset); + context.stroke(); + + } + + break; + + case "text": + { + if (this._$scrollV > currentV) { + continue; + } + + let offsetY = offsetHeight - this._$heightTable[0]; + if (!$isSafari) { + offsetY += 2 * (obj.textFormat._$size / 12); + } + + context.beginPath(); + context.textBaseline = "top"; + context.font = $generateFontStyle( + tf._$font, tf._$size, tf._$italic, tf._$bold + ); + + if (this._$thickness) { + context.strokeText(obj.text, offsetWidth, yOffset + offsetY); + } + + context.fillText(obj.text, offsetWidth, yOffset + offsetY); + + } + break; + + case "image": + + if (!obj.loaded) { + continue; + } + + context.beginPath(); + context.drawImage(obj.image, + obj.hspace, yOffset + obj.y, + obj.width, obj.height + ); + + break; + + } + } + } + + /** + * @param {object} obj + * @param {number} width + * @return {number} + * @private + */ + _$getAlignOffset ( + obj: TextDataImpl, + width: number + ): number { + + // default + const totalWidth: number = this._$widthTable[obj.yIndex]; + const textFormat: TextFormatImpl = obj.textFormat; + const indent: number = textFormat._$blockIndent + textFormat._$leftMargin > 0 + ? textFormat._$blockIndent + textFormat._$leftMargin + : 0; + + switch (true) { + + // wordWrap case + case !this._$wordWrap && totalWidth > width: + return $Math.max(0, indent); + + case textFormat._$align === "center": // format CENTER + case this._$autoSize === "center": // autoSize CENTER + return $Math.max(0, width / 2 - indent - textFormat._$rightMargin - totalWidth / 2); + + case textFormat._$align === "right": // format RIGHT + case this._$autoSize === "right": // autoSize RIGHT + return $Math.max(0, width - indent - totalWidth - textFormat._$rightMargin - 2); + + // autoSize LEFT + // format LEFT + default: + return $Math.max(0, indent + 2); + + } + } + + /** + * @description Playerから登録を削除 + * + * @return {void} + * @method + * @private + */ + _$remove (): void + { + this._$xMin = 0; + this._$yMin = 0; + this._$xMax = 0; + this._$yMax = 0; + + // array reset + this._$textData.length = 0; + this._$widthTable.length = 0; + this._$heightTable.length = 0; + this._$objectTable.length = 0; + this._$textHeightTable.length = 0; + + this._$textAreaActive = false; + + super._$remove(); + + $textFields.push(this); + } + + /** + * @description 情報を更新 + * + * @param {object} object + * @return {void} + * @method + * @private + */ + _$updateProperty (object: PropertyTextMessageImpl): void + { + // update property + this._$textAreaActive = !!object.textAreaActive; + + // set array + this._$textData.length = 0; + this._$widthTable.length = 0; + this._$heightTable.length = 0; + this._$objectTable.length = 0; + this._$textHeightTable.length = 0; + + this._$textData.push(...object.textData); + this._$widthTable.push(...object.widthTable); + this._$heightTable.push(...object.heightTable); + this._$objectTable.push(...object.objectTable); + this._$textHeightTable.push(...object.textHeightTable); + + // format + this._$wordWrap = object.wordWrap; + this._$limitWidth = object.limitWidth; + this._$limitHeight = object.limitHeight; + this._$autoSize = object.autoSize; + this._$scrollV = object.scrollV; + this._$textHeight = object.textHeight; + this._$verticalAlign = object.verticalAlign; + + // color + this._$border = object.border; + if (this._$border) { + this._$borderColor = object.borderColor as NonNullable; + } + + this._$background = object.background; + if (this._$background) { + this._$backgroundColor = object.backgroundColor as NonNullable; + } + + if ("thickness" in object) { + this._$thickness = object.thickness; + this._$thicknessColor = object.thicknessColor as NonNullable; + } + } + + /** + * @description 描画情報を更新 + * + * @param {object} object + * @return {void} + * @method + * @private + */ + _$update (object: PropertyTextMessageImpl): void + { + super._$update(object); + + this._$textAreaActive = !!object.textAreaActive; + + this._$xMin = object.xMin as NonNullable; + this._$yMin = object.yMin as NonNullable; + this._$xMax = object.xMax as NonNullable; + this._$yMax = object.yMax as NonNullable; + + if (object.textData) { + this._$updateProperty(object); + } + } +} \ No newline at end of file diff --git a/packages/renderer/src/RendererUtil.ts b/packages/renderer/src/RendererUtil.ts new file mode 100644 index 00000000..d6151aba --- /dev/null +++ b/packages/renderer/src/RendererUtil.ts @@ -0,0 +1,140 @@ +import type { CanvasToWebGLContext } from "@next2d/webgl"; +import { RendererDisplayObjectContainer } from "./RendererDisplayObjectContainer"; + +/** + * @type {RendererDisplayObjectContainer} + * @public + */ +export const $rendererStage: RendererDisplayObjectContainer = new RendererDisplayObjectContainer(); + +/** + * @type {number} + * @public + */ +export const $samples: number = 4; + +/** + * @type {number} + * @public + */ +export let $devicePixelRatio: number = 1; + +/** + * @description 画面の解像度を設定 + * Set screen resolution + * + * @param {number} ratio + * @return {void} + * @method + * @public + */ +export const $setDevicePixelRatio = (ratio: number): void => +{ + $devicePixelRatio = ratio; +}; + +/** + * @type {CanvasToWebGLContext} + * @public + */ +export let $context: CanvasToWebGLContext; + +/** + * @description Next2DのWebGLの描画コンテキストを設定 + * Set the drawing context of Next2D's WebGL + * + * @param {number} context + * @return {void} + * @method + * @public + */ +export const $setContext = (context: CanvasToWebGLContext): void => +{ + $context = context; +}; + +/** + * @type {CanvasToWebGLContext} + * @public + */ +export let $canvas: OffscreenCanvas; + +/** + * @description OffscreenCanvasをutilの変数のセット + * Set OffscreenCanvas to util variable + * + * @param {OffscreenCanvas} canvas + * @return {void} + * @method + * @public + */ +export const $setCanvas = (canvas: OffscreenCanvas): void => +{ + $canvas = canvas; +}; + +/** + * @type {WebGL2RenderingContext} + * @public + */ +export let $gl: WebGL2RenderingContext; + +/** + * @description WebGL2のコンテキストをセット + * Set WebGL2 context + * + * @param {WebGL2RenderingContext} gl + * @return {void} + * @method + * @public + */ +export const $setWebGL2RenderingContext = (gl: WebGL2RenderingContext): void => +{ + $gl = gl; +}; + +/** + * @type {number} + * @public + */ +export let $rendererWidth: number = 0; + +/** + * @description 描画エリアの幅を設定 + * Set the width of the drawing area + * + * @param {number} width + * @return {void} + * @method + * @public + */ +export const $setRendererWidth = (width: number): void => +{ + $rendererWidth = width; +}; + +/** + * @type {number} + * @public + */ +export let $rendererHeight: number = 0; + +/** + * @description 描画エリアの高さを設定 + * Set the height of the drawing area + * + * @param {number} height + * @return {void} + * @method + * @public + */ +export const $setRendererHeight = (height: number): void => +{ + $rendererHeight = height; +}; + +/** + * @type {Float32Array} + * @public + */ +export const $rendererMatrix: Float32Array = new Float32Array([1, 0, 0, 1, 0, 0]); \ No newline at end of file diff --git a/packages/renderer/src/RendererVideo.ts b/packages/renderer/src/RendererVideo.ts new file mode 100644 index 00000000..0a0c50fc --- /dev/null +++ b/packages/renderer/src/RendererVideo.ts @@ -0,0 +1,452 @@ +import { RenderDisplayObject } from "../display/RenderDisplayObject"; +import { $videos } from "../RenderGlobal"; +import type { BoundsImpl } from "../interface/BoundsImpl"; +import type { AttachmentImpl } from "../interface/AttachmentImpl"; +import type { PropertyVideoMessageImpl } from "../interface/PropertyVideoMessageImpl"; +import type { FilterArrayImpl } from "../interface/FilterArrayImpl"; +import type { CachePositionImpl } from "../interface/CachePositionImpl"; +import type { + CanvasToWebGLContext, + FrameBufferManager +} from "@next2d/webgl"; + +/** + * @class + */ +export class RenderVideo extends RenderDisplayObject +{ + private _$imageBitmap: ImageBitmap | null; + private _$context: OffscreenCanvasRenderingContext2D | null; + private _$smoothing: boolean; + private _$cacheKeys: string[]; + private _$cacheParams: number[]; + + /** + * @constructor + * @public + */ + constructor () + { + super(); + + /** + * @type {ImageBitmap} + * @default null + * @private + */ + this._$imageBitmap = null; + + /** + * @type {OffscreenCanvasRenderingContext2D} + * @default null + * @private + */ + this._$context = null; + + /** + * @type {boolean} + * @default true + * @private + */ + this._$smoothing = true; + + /** + * @type {array} + * @private + */ + this._$cacheKeys = $getArray(); + + /** + * @type {array} + * @private + */ + this._$cacheParams = $getArray(0, 0, 0); + } + + /** + * @param {CanvasToWebGLContext} context + * @param {Float32Array} matrix + * @return {void} + * @method + * @private + */ + _$clip ( + context: CanvasToWebGLContext, + matrix: Float32Array + ): void { + + const width: number = this._$xMax; + const height: number = this._$yMax; + if (!width || !height) { + return; + } + + let multiMatrix: Float32Array = matrix; + const rawMatrix: Float32Array = this._$matrix; + if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + ) { + multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + } + + context.reset(); + context.setTransform( + multiMatrix[0], multiMatrix[1], multiMatrix[2], + multiMatrix[3], multiMatrix[4], multiMatrix[5] + ); + + context.beginPath(); + context.moveTo(0, 0); + context.lineTo(width, 0); + context.lineTo(width, height); + context.lineTo(0, height); + context.lineTo(0, 0); + context.clip(); + + if (multiMatrix !== matrix) { + $poolFloat32Array6(multiMatrix); + } + } + + /** + * @param {CanvasToWebGLContext} context + * @param {Float32Array} matrix + * @param {Float32Array} color_transform + * @return {void} + * @method + * @private + */ + _$draw ( + context: CanvasToWebGLContext, + matrix: Float32Array, + color_transform: Float32Array + ): void { + + if (!this._$visible + || !this._$imageBitmap + || !this._$context + ) { + return ; + } + + let multiColor: Float32Array = color_transform; + const rawColor: Float32Array = this._$colorTransform; + if (rawColor[0] !== 1 || rawColor[1] !== 1 + || rawColor[2] !== 1 || rawColor[3] !== 1 + || rawColor[4] !== 0 || rawColor[5] !== 0 + || rawColor[6] !== 0 || rawColor[7] !== 0 + ) { + multiColor = $multiplicationColor(color_transform, rawColor); + } + + const alpha: number = $clamp(multiColor[3] + multiColor[7] / 255, 0, 1, 0); + if (!alpha) { + if (multiColor !== color_transform) { + $poolFloat32Array8(multiColor); + } + return ; + } + + let multiMatrix: Float32Array = matrix; + const rawMatrix: Float32Array = this._$matrix; + if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + ) { + multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + } + + // default bounds + const baseBounds: BoundsImpl = this._$getBounds(); + $poolBoundsObject(baseBounds); + + const bounds: BoundsImpl = $boundsMatrix(baseBounds, multiMatrix); + const xMax: number = +bounds.xMax; + const xMin: number = +bounds.xMin; + const yMax: number = +bounds.yMax; + const yMin: number = +bounds.yMin; + $poolBoundsObject(bounds); + + const width: number = $Math.ceil($Math.abs(xMax - xMin)); + const height: number = $Math.ceil($Math.abs(yMax - yMin)); + switch (true) { + + case width === 0: + case height === 0: + case width === 0 - $Infinity: + case height === 0 - $Infinity: + case width === $Infinity: + case height === $Infinity: + return; + + default: + break; + + } + + let xScale: number = +$Math.sqrt( + multiMatrix[0] * multiMatrix[0] + + multiMatrix[1] * multiMatrix[1] + ); + if (!$Number.isInteger(xScale)) { + const value: string = xScale.toString(); + const index: number = value.indexOf("e"); + if (index !== -1) { + xScale = +value.slice(0, index); + } + xScale = +xScale.toFixed(4); + } + + let yScale: number = +$Math.sqrt( + multiMatrix[2] * multiMatrix[2] + + multiMatrix[3] * multiMatrix[3] + ); + if (!$Number.isInteger(yScale)) { + const value: string = yScale.toString(); + const index: number = value.indexOf("e"); + if (index !== -1) { + yScale = +value.slice(0, index); + } + yScale = +yScale.toFixed(4); + } + + const filters: FilterArrayImpl | null = this._$filters; + const canApply: boolean = filters !== null + && filters.length > 0 + && this._$canApply(filters); + + let filterBounds: BoundsImpl = $getBoundsObject(0, width, 0, height); + if (canApply && filters) { + for (let idx: number = 0; idx < filters.length ; ++idx) { + filterBounds = filters[idx] + ._$generateFilterRect(filterBounds, xScale, yScale); + } + } + + // cache current buffer + const manager: FrameBufferManager = context.frameBuffer; + const currentAttachment: AttachmentImpl | null = manager.currentAttachment; + if (!currentAttachment + || xMin - filterBounds.xMin > currentAttachment.width + || yMin - filterBounds.yMin > currentAttachment.height + ) { + $poolBoundsObject(filterBounds); + return; + } + + if (0 > xMin + filterBounds.xMax || 0 > yMin + filterBounds.yMax) { + $poolBoundsObject(filterBounds); + return; + } + $poolBoundsObject(filterBounds); + + if (!this._$cacheKeys.length + || this._$cacheParams[0] !== xScale + || this._$cacheParams[1] !== yScale + || this._$cacheParams[2] !== color_transform[7] + ) { + const keys: number[] = $getArray(); + keys[0] = xScale; + keys[1] = yScale; + + this._$cacheKeys = $cacheStore.generateKeys( + this._$instanceId, keys, color_transform + ); + + $poolArray(keys); + + this._$cacheParams[0] = xScale; + this._$cacheParams[1] = yScale; + this._$cacheParams[2] = color_transform[7]; + } + + context.cachePosition = $cacheStore.get(this._$cacheKeys); + if (!context.cachePosition) { + + const width: number = $Math.ceil($Math.abs(this._$xMax - this._$xMin)); + const height: number = $Math.ceil($Math.abs(this._$yMax - this._$yMin)); + + const position: CachePositionImpl = manager + .createCachePosition(width, height); + + context.cachePosition = position; + $cacheStore.set(this._$cacheKeys, position); + } + + this._$context.drawImage(this._$imageBitmap, 0, 0); + + const texture: WebGLTexture = manager + .textureManager + ._$createFromElement( + this._$imageBitmap.width, + this._$imageBitmap.height, + this._$context.canvas, + this._$smoothing + ); + + let offsetX: number = 0; + let offsetY: number = 0; + if (canApply && filters) { + + const currentAttachment: AttachmentImpl | null = manager.currentAttachment; + + const attachment: AttachmentImpl = manager + .createCacheAttachment(width, height); + + context._$bind(attachment); + + context.reset(); + + const parentMatrix: Float32Array = $getFloat32Array6( + xScale, 0, 0, yScale, + width / 2, height / 2 + ); + + const baseMatrix: Float32Array = $getFloat32Array6( + 1, 0, 0, 1, + -texture.width / 2, + -texture.height / 2 + ); + + const scaleMatrix = $multiplicationMatrix( + parentMatrix, baseMatrix + ); + $poolFloat32Array6(parentMatrix); + $poolFloat32Array6(baseMatrix); + + context.setTransform( + scaleMatrix[0], scaleMatrix[1], + scaleMatrix[2], scaleMatrix[3], + scaleMatrix[4], scaleMatrix[5] + ); + + context.drawImage(texture, 0, 0, texture.width, texture.height); + + const videoTexture: WebGLTexture = manager.getTextureFromCurrentAttachment(); + context._$bind(currentAttachment); + + manager.releaseAttachment(attachment); + + // release + context.drawTextureFromRect(texture, context.cachePosition); + + const position: CachePositionImpl = this._$drawFilter( + context, multiMatrix, filters, + width, height, videoTexture + ); + + if (position.offsetX) { + offsetX = position.offsetX; + } + + if (position.offsetY) { + offsetY = position.offsetY; + } + + // update + context.cachePosition = position; + + context.setTransform(1, 0, 0, 1, + xMin - offsetX, yMin - offsetY + ); + + } else { + + context.drawTextureFromRect(texture, context.cachePosition); + + context.setTransform( + multiMatrix[0], multiMatrix[1], multiMatrix[2], + multiMatrix[3], multiMatrix[4], multiMatrix[5] + ); + + } + + // draw + if (context.cachePosition) { + + context.globalAlpha = alpha; + context.imageSmoothingEnabled = true; + context.globalCompositeOperation = this._$blendMode; + + context.drawInstance( + xMin - offsetX, yMin - offsetY, xMax, yMax, + color_transform + ); + + // cache position clear + context.cachePosition = null; + } + + // pool + if (multiMatrix !== matrix) { + $poolFloat32Array6(multiMatrix); + } + + if (multiColor !== color_transform) { + $poolFloat32Array8(multiColor); + } + } + + /** + * @description Playerから登録を削除 + * + * @return {void} + * @method + * @private + */ + _$remove () + { + this._$xMin = 0; + this._$yMin = 0; + this._$xMax = 0; + this._$yMax = 0; + this._$context = null; + this._$imageBitmap = null; + this._$smoothing = true; + + super._$remove(); + + $videos.push(this); + } + + /** + * @description 情報を更新 + * + * @param {object} object + * @return {void} + * @method + * @private + */ + _$updateProperty (object: PropertyVideoMessageImpl) + { + this._$xMin = object.xMin as NonNullable; + this._$yMin = object.yMin as NonNullable; + this._$xMax = object.xMax as NonNullable; + this._$yMax = object.yMax as NonNullable; + this._$imageBitmap = object.imageBitmap as NonNullable; + this._$smoothing = object.smoothing as NonNullable; + + if (!this._$context && this._$imageBitmap) { + const canvas: OffscreenCanvas = new $OffscreenCanvas( + this._$imageBitmap.width, + this._$imageBitmap.height + ); + this._$context = canvas.getContext("2d"); + } + } + + /** + * @description 描画情報を更新 + * + * @param {object} object + * @return {void} + * @method + * @private + */ + _$update (object: PropertyVideoMessageImpl): void + { + super._$update(object); + this._$updateProperty(object); + } +} \ No newline at end of file diff --git a/packages/renderer/src/index.ts b/packages/renderer/src/index.ts index 98826cab..cb5a2a0e 100644 --- a/packages/renderer/src/index.ts +++ b/packages/renderer/src/index.ts @@ -1,8 +1,8 @@ "use strict"; -// import { CommandController } from "./CommandController"; +import { CommandController } from "./CommandController"; -// const command: CommandController = new CommandController(); +const command: CommandController = new CommandController(); /** * @description OffscreenCanvasのメッセージイベント @@ -16,10 +16,10 @@ self.addEventListener("message", async (event: MessageEvent): Promise => { console.log(event.data); - // command.queue.push(event.data); - // if (command.state === "deactivate") { - // await command.execute(); - // } + command.queue.push(event.data); + if (command.state === "deactivate") { + await command.execute(); + } }); export default {}; \ No newline at end of file diff --git a/packages/renderer/src/interface/BlendModeImpl.ts b/packages/renderer/src/interface/BlendModeImpl.ts new file mode 100644 index 00000000..6ed290eb --- /dev/null +++ b/packages/renderer/src/interface/BlendModeImpl.ts @@ -0,0 +1,15 @@ +export type BlendModeImpl = "copy" + | "add" + | "alpha" + | "darken" + | "difference" + | "erase" + | "hardlight" + | "invert" + | "layer" + | "lighten" + | "multiply" + | "normal" + | "overlay" + | "screen" + | "subtract"; \ No newline at end of file diff --git a/packages/renderer/src/interface/GridImpl.ts b/packages/renderer/src/interface/GridImpl.ts new file mode 100644 index 00000000..eecb9aba --- /dev/null +++ b/packages/renderer/src/interface/GridImpl.ts @@ -0,0 +1,6 @@ +export interface GridImpl { + x: number; + y: number; + w: number; + h: number; +} \ No newline at end of file diff --git a/packages/renderer/src/interface/PropertyMessageImpl.ts b/packages/renderer/src/interface/PropertyMessageImpl.ts new file mode 100644 index 00000000..4e9896bb --- /dev/null +++ b/packages/renderer/src/interface/PropertyMessageImpl.ts @@ -0,0 +1,39 @@ +import type { BlendModeImpl } from "./BlendModeImpl"; +import type { GridImpl } from "./GridImpl"; + +export interface PropertyMessageImpl { + command: string; + buffer: Float32Array; + instanceId?: number; + parentId?: number; + visible?: boolean; + isMask?: boolean; + clipDepth?: number; + depth?: number; + maskId?: number; + loaderInfoId?: number; + characterId?: number; + maskMatrix?: Float32Array; + xMin?: number; + yMin?: number; + xMax?: number; + yMax?: number; + a?: number; + b?: number; + c?: number; + d?: number; + tx?: number; + ty?: number; + f0?: number; + f1?: number; + f2?: number; + f3?: number; + f4?: number; + f5?: number; + f6?: number; + f7?: number; + filters?: any[]; + blendMode?: BlendModeImpl; + matrixBase?: Float32Array; + grid?: GridImpl; +} \ No newline at end of file diff --git a/packages/renderer/src/interface/PropertyMessageMapImpl.ts b/packages/renderer/src/interface/PropertyMessageMapImpl.ts new file mode 100644 index 00000000..b286a99d --- /dev/null +++ b/packages/renderer/src/interface/PropertyMessageMapImpl.ts @@ -0,0 +1,3 @@ +import type { PropertyMessageImpl } from "./PropertyMessageImpl"; + +export type PropertyMessageMapImpl = T; \ No newline at end of file diff --git a/packages/display/src/TextField.ts b/packages/text/src/TextField.ts similarity index 100% rename from packages/display/src/TextField.ts rename to packages/text/src/TextField.ts diff --git a/packages/webgl/src/CanvasToWebGLContext.ts b/packages/webgl/src/CanvasToWebGLContext.ts index 8c69b8c9..bcd1d083 100644 --- a/packages/webgl/src/CanvasToWebGLContext.ts +++ b/packages/webgl/src/CanvasToWebGLContext.ts @@ -29,12 +29,14 @@ import type { JointStyleImpl } from "./interface/JointStyleImpl"; import type { CachePositionImpl } from "./interface/CachePositionImpl"; import { $setRenderSize, + $setWebGL2RenderingContext, $getFloat32Array9, $getArray, $clamp, $poolArray, $inverseMatrix, - $poolFloat32Array9 + $poolFloat32Array9, + $gl } from "./WebGLUtil"; /** @@ -44,7 +46,6 @@ export class CanvasToWebGLContext { public _$offsetX: number; public _$offsetY: number; - public readonly _$gl: WebGL2RenderingContext; private _$cacheBounds: BoundsImpl; private _$matrix: Float32Array; private _$cacheAttachment: AttachmentImpl|null; @@ -74,6 +75,7 @@ export class CanvasToWebGLContext private readonly _$blend: CanvasToWebGLContextBlend; private readonly _$maskBounds: BoundsImpl; private readonly _$attachmentArray: Array; + private _$mainAttachment: AttachmentImpl | null; /** * @param {WebGL2RenderingContext} gl @@ -83,14 +85,9 @@ export class CanvasToWebGLContext */ constructor (gl: WebGL2RenderingContext, sample: number) { + $setWebGL2RenderingContext(gl); $setRenderSize(gl.getParameter(gl.MAX_TEXTURE_SIZE)); - /** - * @type {WebGL2RenderingContext} - * @private - */ - this._$gl = gl; - /** * @type {number} * @private @@ -311,6 +308,58 @@ export class CanvasToWebGLContext * @private */ this._$cachePosition = null; + + /** + * @type {object} + * @default null + * @private + */ + this._$mainAttachment = null; + } + + /** + * @description 描画のメインとなるAttachmentを設定 + * Set the main Attachment for drawing + * + * @member {AttachmentImpl | null} + * @public + */ + get mainAttachment (): AttachmentImpl | null + { + return this._$mainAttachment; + } + set mainAttachment (attachment: AttachmentImpl | null) + { + this._$mainAttachment = attachment; + } + + /** + * @description 描画サイズのリサイズ処理 + * Resize processing of drawing size + * + * @param {number} width + * @param {number} height + * @return {void} + * @method + * @public + */ + resize (width: number, height: number): void + { + this.clearInstacedArray(); + + const manager: FrameBufferManager = this.frameBuffer; + if (this._$mainAttachment) { + manager.unbind(); + manager.releaseAttachment(this._$mainAttachment, true); + } + + this._$mainAttachment = manager + .createCacheAttachment(width, height, true); + + this.bind(this._$mainAttachment); + + // update cache max size + this.setMaxSize(width, height); } /** @@ -358,7 +407,7 @@ export class CanvasToWebGLContext */ get canvas (): HTMLCanvasElement | OffscreenCanvas { - return this._$gl.canvas; + return $gl.canvas; } /** @@ -626,16 +675,16 @@ export class CanvasToWebGLContext .bindRenderBuffer(); // 初期化 - this._$gl.clearColor(0, 0, 0, 0); - this._$gl.clear(this._$gl.COLOR_BUFFER_BIT | this._$gl.STENCIL_BUFFER_BIT); + $gl.clearColor(0, 0, 0, 0); + $gl.clear($gl.COLOR_BUFFER_BIT | $gl.STENCIL_BUFFER_BIT); // 描画領域をあらためて設定 this._$viewportWidth = position.w; this._$viewportHeight = position.h; - this._$gl.viewport(position.x, position.y, position.w, position.h); + $gl.viewport(position.x, position.y, position.w, position.h); - this._$gl.enable(this._$gl.SCISSOR_TEST); - this._$gl.scissor( + $gl.enable($gl.SCISSOR_TEST); + $gl.scissor( position.x, position.y, position.w, position.h ); @@ -662,7 +711,7 @@ export class CanvasToWebGLContext position.w, position.h ); - this._$bind(attachment); + this.bind(attachment); this.save(); this.setTransform(1, 0, 0, 1, 0, 0); @@ -680,7 +729,7 @@ export class CanvasToWebGLContext manager.releaseAttachment(attachment); // reset - this._$bind(currentAttachment); + this.bind(currentAttachment); return texture; } @@ -736,15 +785,15 @@ export class CanvasToWebGLContext const attachment: AttachmentImpl = manager .createTextureAttachmentFrom(atlasTexture); - this._$bind(attachment); + this.bind(attachment); - this._$gl.enable(this._$gl.SCISSOR_TEST); - this._$gl.scissor( + $gl.enable($gl.SCISSOR_TEST); + $gl.scissor( position.x, position.y, position.w, position.h ); - this._$gl.clearColor(0, 0, 0, 0); - this._$gl.disable(this._$gl.SCISSOR_TEST); + $gl.clearColor(0, 0, 0, 0); + $gl.disable($gl.SCISSOR_TEST); this.save(); this.setTransform(1, 0, 0, 1, 0, 0); @@ -760,7 +809,7 @@ export class CanvasToWebGLContext manager.releaseAttachment(attachment); // reset - this._$bind(currentAttachment); + this.bind(currentAttachment); manager.textureManager.release(texture); } @@ -781,7 +830,7 @@ export class CanvasToWebGLContext * @method * @public */ - _$bind (attachment: AttachmentImpl | null = null): void + bind (attachment: AttachmentImpl | null = null): void { if (!attachment) { return; @@ -798,7 +847,7 @@ export class CanvasToWebGLContext if (this._$viewportWidth !== width || this._$viewportHeight !== height) { this._$viewportWidth = width; this._$viewportHeight = height; - this._$gl.viewport(0, 0, width, height); + $gl.viewport(0, 0, width, height); } // カラーバッファorステンシルバッファが、未初期化の場合はクリアする @@ -814,9 +863,9 @@ export class CanvasToWebGLContext stencilBuffer.dirty = false; } - this._$gl.clearColor(0, 0, 0, 0); + $gl.clearColor(0, 0, 0, 0); this.clearRect(0, 0, this._$viewportWidth, this._$viewportHeight); - this._$gl.clearColor(this._$clearColorR, this._$clearColorG, this._$clearColorB, this._$clearColorA); + $gl.clearColor(this._$clearColorR, this._$clearColorG, this._$clearColorB, this._$clearColorA); this._$mask._$onClear(attachment.mask); } @@ -900,12 +949,12 @@ export class CanvasToWebGLContext const currentAttachment = manager.currentAttachment; const attachment: AttachmentImpl = manager.createTextureAttachmentFrom(atlasTexture); - this._$bind(attachment); + this.bind(attachment); const pixels = new Uint8Array(atlasTexture.width * atlasTexture.height * 4); - this._$gl.readPixels( + $gl.readPixels( 0, 0, atlasTexture.width, atlasTexture.height, - this._$gl.RGBA, this._$gl.UNSIGNED_BYTE, pixels + $gl.RGBA, $gl.UNSIGNED_BYTE, pixels ); const canvas = document.createElement("canvas"); @@ -921,7 +970,7 @@ export class CanvasToWebGLContext ctx?.putImageData(imageData, 0, 0); console.log(canvas.toDataURL()); - this._$bind(currentAttachment); + this.bind(currentAttachment); manager.releaseAttachment(attachment); } @@ -1067,10 +1116,13 @@ export class CanvasToWebGLContext this._$clearColorG = g; this._$clearColorB = b; this._$clearColorA = a; - this._$gl.clearColor(r, g, b, a); + $gl.clearColor(r, g, b, a); } /** + * @description 指定範囲の描画をクリア + * Clear the drawing in the specified range + * * @param {number} x * @param {number} y * @param {number} w @@ -1084,10 +1136,10 @@ export class CanvasToWebGLContext w: number, h: number ): void { this._$mask._$onClearRect(); - this._$gl.enable(this._$gl.SCISSOR_TEST); - this._$gl.scissor(x, y, w, h); - this._$gl.clear(this._$gl.COLOR_BUFFER_BIT | this._$gl.STENCIL_BUFFER_BIT); - this._$gl.disable(this._$gl.SCISSOR_TEST); + $gl.enable($gl.SCISSOR_TEST); + $gl.scissor(x, y, w, h); + $gl.clear($gl.COLOR_BUFFER_BIT | $gl.STENCIL_BUFFER_BIT); + $gl.disable($gl.SCISSOR_TEST); } /** @@ -1101,15 +1153,15 @@ export class CanvasToWebGLContext this._$mask._$onClearRect(); // マスクの描画領域に限定してstencil情報をクリア - this._$gl.enable(this._$gl.SCISSOR_TEST); - this._$gl.scissor( + $gl.enable($gl.SCISSOR_TEST); + $gl.scissor( this._$maskBounds.xMin, this._$maskBounds.yMin, this._$maskBounds.xMax, this._$maskBounds.yMax ); - this._$gl.clear(this._$gl.STENCIL_BUFFER_BIT); - this._$gl.disable(this._$gl.SCISSOR_TEST); + $gl.clear($gl.STENCIL_BUFFER_BIT); + $gl.disable($gl.SCISSOR_TEST); } /** @@ -1356,25 +1408,25 @@ export class CanvasToWebGLContext ); // mask on - this._$gl.enable(this._$gl.STENCIL_TEST); - this._$gl.stencilMask(0xff); + $gl.enable($gl.STENCIL_TEST); + $gl.stencilMask(0xff); // draw shape - this._$gl.enable(this._$gl.SAMPLE_ALPHA_TO_COVERAGE); - this._$gl.stencilFunc(this._$gl.ALWAYS, 0, 0xff); - this._$gl.stencilOp(this._$gl.KEEP, this._$gl.INVERT, this._$gl.INVERT); - this._$gl.colorMask(false, false, false, false); + $gl.enable($gl.SAMPLE_ALPHA_TO_COVERAGE); + $gl.stencilFunc($gl.ALWAYS, 0, 0xff); + $gl.stencilOp($gl.KEEP, $gl.INVERT, $gl.INVERT); + $gl.colorMask(false, false, false, false); coverageShader._$fill(fillVertexArrayObject); - this._$gl.disable(this._$gl.SAMPLE_ALPHA_TO_COVERAGE); + $gl.disable($gl.SAMPLE_ALPHA_TO_COVERAGE); // draw shape range - this._$gl.stencilFunc(this._$gl.NOTEQUAL, 0, 0xff); - this._$gl.stencilOp(this._$gl.KEEP, this._$gl.ZERO, this._$gl.ZERO); - this._$gl.colorMask(true, true, true, true); + $gl.stencilFunc($gl.NOTEQUAL, 0, 0xff); + $gl.stencilOp($gl.KEEP, $gl.ZERO, $gl.ZERO); + $gl.colorMask(true, true, true, true); shader._$fill(fillVertexArrayObject); // mask off - this._$gl.disable(this._$gl.STENCIL_TEST); + $gl.disable($gl.STENCIL_TEST); // release vertex array this.releaseFillVertexArray(fillVertexArrayObject); @@ -2019,7 +2071,7 @@ export class CanvasToWebGLContext ._$frameBufferManager .createTextureAttachment(width, height); - this._$bind(targetTextureAttachment); + this.bind(targetTextureAttachment); if (isGradient && lut) { @@ -2150,7 +2202,7 @@ export class CanvasToWebGLContext ._$frameBufferManager .createTextureAttachment(width, height); - this._$bind(targetTextureAttachment); + this.bind(targetTextureAttachment); this ._$frameBufferManager @@ -2215,7 +2267,7 @@ export class CanvasToWebGLContext ._$frameBufferManager .createTextureAttachment(width, height); - this._$bind(targetTextureAttachment); + this.bind(targetTextureAttachment); if (!point) { point = { "x": 0, "y": 0 }; @@ -2299,7 +2351,7 @@ export class CanvasToWebGLContext ._$attachmentArray .push(manager.currentAttachment); - this._$bind( + this.bind( manager.createCacheAttachment(width, height, multisample) ); } @@ -2318,7 +2370,7 @@ export class CanvasToWebGLContext manager.currentAttachment, release_texture ); - this._$bind( + this.bind( this._$attachmentArray.pop() ); } diff --git a/packages/webgl/src/WebGLUtil.ts b/packages/webgl/src/WebGLUtil.ts index fb9c8031..59975d08 100644 --- a/packages/webgl/src/WebGLUtil.ts +++ b/packages/webgl/src/WebGLUtil.ts @@ -15,6 +15,26 @@ export const $setRenderSize = (size: number): void => $RENDER_SIZE = Math.min(4096, size / 2); }; +/** + * @type {WebGL2RenderingContext} + * @public + */ +export let $gl: WebGL2RenderingContext; + +/** + * @description WebGL2のコンテキストをセット + * Set WebGL2 context + * + * @param {WebGL2RenderingContext} gl + * @return {void} + * @method + * @public + */ +export const $setWebGL2RenderingContext = (gl: WebGL2RenderingContext): void => +{ + $gl = gl; +}; + /** * @type {number} */ diff --git a/packages/webgl/src/index.ts b/packages/webgl/src/index.ts index ee7e3c28..f79807ad 100644 --- a/packages/webgl/src/index.ts +++ b/packages/webgl/src/index.ts @@ -1,5 +1,6 @@ export * from "./CanvasGradientToWebGL"; export * from "./CanvasPatternToWebGL"; +export * from "./CanvasToWebGLContext"; export * from "./CanvasToWebGLContextPath"; export * from "./CanvasToWebGLContextStyle"; export * from "./FrameBufferManager"; \ No newline at end of file diff --git a/worker/unzip/UnzipWorker.min.js b/worker/unzip/UnzipWorker.min.js deleted file mode 100644 index c10543fd..00000000 --- a/worker/unzip/UnzipWorker.min.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{"use strict";var r=Uint8Array,n=Uint16Array,e=Int32Array,a=new r([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),t=new r([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),i=new r([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),o=function(r,a){for(var t=new n(31),i=0;i<31;++i)t[i]=a+=1<>1|(21845&s)<<1;w=(61680&(w=(52428&w)>>2|(13107&w)<<2))>>4|(3855&w)<<4,d[s]=((65280&w)>>8|(255&w)<<8)>>1}var h=function(r,e,a){for(var t=r.length,i=0,o=new n(e);i>v]=c}else for(f=new n(t),i=0;i>15-r[i]);return f},y=new r(288);for(s=0;s<144;++s)y[s]=8;for(s=144;s<256;++s)y[s]=9;for(s=256;s<280;++s)y[s]=7;for(s=280;s<288;++s)y[s]=8;var b=new r(32);for(s=0;s<32;++s)b[s]=5;var g=h(y,9,1),p=h(b,5,1),m=function(r){for(var n=r[0],e=1;en&&(n=r[e]);return n},k=function(r,n,e){var a=n/8|0;return(r[a]|r[a+1]<<8)>>(7&n)&e},x=function(r,n){var e=n/8|0;return(r[e]|r[e+1]<<8|r[e+2]<<16)>>(7&n)},T=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],z=function(r,n,e){var a=new Error(n||T[r]);if(a.code=r,Error.captureStackTrace&&Error.captureStackTrace(a,z),!e)throw a;return a},E=function(n,e,o,f){var v=n.length,c=f?f.length:0;if(!v||e.f&&!e.l)return o||new r(0);var d=!o,s=d||2!=e.i,w=e.i;d&&(o=new r(3*v));var y,b=function(n){var e=o.length;if(n>e){var a=new r(Math.max(2*e,n));a.set(o),o=a}},T=e.f||0,E=e.p||0,M=e.b||0,S=e.l,U=e.d,A=e.m,C=e.n,q=8*v;do{if(!S){T=k(n,E,1);var D=k(n,E+1,3);if(E+=3,!D){var F=n[(y=E,(H=4+((y+7)/8|0))-4)]|n[H-3]<<8,I=H+F;if(I>v){w&&z(0);break}s&&b(M+F),o.set(n.subarray(H,I),M),e.b=M+=F,e.p=E=8*I,e.f=T;continue}if(1==D)S=g,U=p,A=9,C=5;else if(2==D){var O=k(n,E,31)+257,J=k(n,E+10,15)+4,L=O+k(n,E+5,31)+1;E+=14;for(var N=new r(L),P=new r(19),R=0;R>4)<16)N[R++]=H;else{var Q=0,V=0;for(16==H?(V=3+k(n,E,3),E+=2,Q=N[R-1]):17==H?(V=3+k(n,E,7),E+=3):18==H&&(V=11+k(n,E,127),E+=7);V--;)N[R++]=Q}}var W=N.subarray(0,O),X=N.subarray(O);A=m(W),C=m(X),S=h(W,A,1),U=h(X,C,1)}else z(1);if(E>q){w&&z(0);break}}s&&b(M+131072);for(var Y=(1<>4;if((E+=15&Q)>q){w&&z(0);break}if(Q||z(2),_<256)o[M++]=_;else{if(256==_){$=E,S=null;break}var rr=_-254;if(_>264){var nr=a[R=_-257];rr=k(n,E,(1<>4;if(er||z(3),E+=15&er,X=l[ar],ar>3&&(nr=t[ar],X+=x(n,E)&(1<q){w&&z(0);break}s&&b(M+131072);var tr=M+rr;if(Mn.length)&&(a=n.length),new r(n.subarray(e,a))}(o,0,M):o.subarray(0,M)},M=new r(0);function S(n,e){var a,t,i=function(r){31==r[0]&&139==r[1]&&8==r[2]||z(6,"invalid gzip data");var n=r[3],e=10;4&n&&(e+=2+(r[10]|r[11]<<8));for(var a=(n>>3&1)+(n>>4&1);a>0;a-=!r[e++]);return e+(2&n)}(n);return i+8>n.length&&z(6,"invalid gzip data"),E(n.subarray(i,-8),{i:2},e&&e.out||new r((t=(a=n).length,(a[t-4]|a[t-3]<<8|a[t-2]<<16|a[t-1]<<24)>>>0)),e&&e.dictionary)}function U(r,n){return E(r.subarray((e=r,a=n&&n.dictionary,(8!=(15&e[0])||e[0]>>4>7||(e[0]<<8|e[1])%31)&&z(6,"invalid zlib data"),(e[1]>>5&1)==+!a&&z(6,"invalid zlib data: "+(32&e[1]?"need":"unexpected")+" dictionary"),2+(e[1]>>3&4)),-4),{i:2},n&&n.out,n&&n.dictionary);var e,a}var A="undefined"!=typeof TextDecoder&&new TextDecoder;try{A.decode(M,{stream:!0})}catch(r){}"function"==typeof queueMicrotask?queueMicrotask:"function"==typeof setTimeout&&setTimeout;self.addEventListener("message",(r=>{return n=void 0,e=void 0,t=function*(){const n=31==(e=r.data)[0]&&139==e[1]&&8==e[2]?S(e,a):8!=(15&e[0])||e[0]>>4>7||(e[0]<<8|e[1])%31?function(r,n){return E(r,{i:2},n&&n.out,n&&n.dictionary)}(e,a):U(e,a);var e,a;let t="";for(let r=0;r +self.addEventListener("message", (event: MessageEvent): void => { - const buffer: Uint8Array = decompressSync(event.data); + const buffer = decompressSync(event.data); - let json: string = ""; + let json = ""; for (let idx: number = 0; idx < buffer.length; idx += 4096) { json += String.fromCharCode(...buffer.slice(idx, idx + 4096)); } From f610ea75de54dd8f2315ffc85e375c1d84db7781 Mon Sep 17 00:00:00 2001 From: ienaga Date: Fri, 2 Aug 2024 18:48:28 +0900 Subject: [PATCH 031/343] =?UTF-8?q?#154=20display=E3=83=91=E3=83=83?= =?UTF-8?q?=E3=82=B1=E3=83=BC=E3=82=B8=E3=82=92=E7=A7=BB=E8=A1=8C(WIP)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 744 ++++++++---------- package.json | 14 +- packages/core/src/CoreUtil.ts | 28 +- .../core/src/Next2D/CreateRootMovieClip.ts | 15 +- packages/core/src/Next2D/LoadService.ts | 63 +- packages/core/src/Player.ts | 81 +- .../PlayerAppendCanvasElementService.ts | 19 + .../PlayerRemoveLoadingElementService.test.ts | 23 + .../PlayerRemoveLoadingElementService.ts | 21 + .../src/Player/PlayerResizeEventService.ts | 32 +- .../Player/PlayerResizePostMessageService.ts | 10 +- .../src/Player/PlayerResizeRegisterService.ts | 15 +- ...UpdateBackgroundColorPostMessageService.ts | 51 ++ .../core/src/interface/ResizeMessageImpl.ts | 2 +- .../UpdateBackgroundColorMessageImpl.ts | 4 + .../display/src/Loader/LoaderBuildService.ts | 2 +- .../Loader/LoaderLoadEndEventService.test.ts | 4 +- .../src/Loader/LoaderLoadJsonService.ts | 11 +- .../src/interface/NoCodeDataZlibImpl.ts | 4 + .../Command/CommandBackgroundColorService.ts | 28 + .../src/Command/CommandResizeService.ts | 6 +- packages/renderer/src/CommandController.ts | 147 +--- packages/renderer/src/RendererUtil.ts | 22 +- packages/webgl/src/CanvasToWebGLContext.ts | 2 +- 24 files changed, 604 insertions(+), 744 deletions(-) create mode 100644 packages/core/src/Player/PlayerAppendCanvasElementService.ts create mode 100644 packages/core/src/Player/PlayerRemoveLoadingElementService.test.ts create mode 100644 packages/core/src/Player/PlayerRemoveLoadingElementService.ts create mode 100644 packages/core/src/Player/PlayerUpdateBackgroundColorPostMessageService.ts create mode 100644 packages/core/src/interface/UpdateBackgroundColorMessageImpl.ts create mode 100644 packages/display/src/interface/NoCodeDataZlibImpl.ts create mode 100644 packages/renderer/src/Command/CommandBackgroundColorService.ts diff --git a/package-lock.json b/package-lock.json index 216cae80..f6834006 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,17 +15,17 @@ "htmlparser2": "^9.1.0" }, "devDependencies": { - "@types/node": "^22.0.0", - "@typescript-eslint/eslint-plugin": "^7.17.0", - "@typescript-eslint/parser": "^7.17.0", - "@vitest/web-worker": "^2.0.4", - "eslint": "^8.57.0", - "eslint-plugin-unused-imports": "^3.2.0", + "@types/node": "^22.0.3", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", + "@vitest/web-worker": "^2.0.5", + "eslint": "^9.8.0", + "eslint-plugin-unused-imports": "^4.0.1", "fflate": "^0.8.2", "jsdom": "^24.1.1", "typescript": "^5.5.4", "vite": "^5.3.5", - "vitest": "^2.0.4" + "vitest": "^2.0.5" }, "funding": { "type": "github", @@ -477,31 +477,22 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "node_modules/@eslint/config-array": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", + "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "node_modules/@eslint/config-array/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", @@ -512,7 +503,7 @@ "concat-map": "0.0.1" } }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "node_modules/@eslint/config-array/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", @@ -525,33 +516,31 @@ "node": "*" } }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dev": true, "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=10.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", @@ -562,7 +551,7 @@ "concat-map": "0.0.1" } }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", @@ -575,6 +564,26 @@ "node": "*" } }, + "node_modules/@eslint/js": { + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz", + "integrity": "sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -589,13 +598,19 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", "dev": true, - "license": "BSD-3-Clause" + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", @@ -749,9 +764,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.1.tgz", - "integrity": "sha512-XzqSg714++M+FXhHfXpS1tDnNZNpgxxuGZWlRG/jSj+VEPmZ0yg6jV4E0AL3uyBKxO8mO3xtOsP5mQ+XLfrlww==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.2.tgz", + "integrity": "sha512-OHflWINKtoCFSpm/WmuQaWW4jeX+3Qt3XQDepkkiFTsoxFc5BpF3Z5aDxFZgBqRjO6ATP5+b1iilp4kGIZVWlA==", "cpu": [ "arm" ], @@ -763,9 +778,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.1.tgz", - "integrity": "sha512-thFUbkHteM20BGShD6P08aungq4irbIZKUNbG70LN8RkO7YztcGPiKTTGZS7Kw+x5h8hOXs0i4OaHwFxlpQN6A==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.2.tgz", + "integrity": "sha512-k0OC/b14rNzMLDOE6QMBCjDRm3fQOHAL8Ldc9bxEWvMo4Ty9RY6rWmGetNTWhPo+/+FNd1lsQYRd0/1OSix36A==", "cpu": [ "arm64" ], @@ -777,9 +792,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.1.tgz", - "integrity": "sha512-8o6eqeFZzVLia2hKPUZk4jdE3zW7LCcZr+MD18tXkgBBid3lssGVAYuox8x6YHoEPDdDa9ixTaStcmx88lio5Q==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.2.tgz", + "integrity": "sha512-IIARRgWCNWMTeQH+kr/gFTHJccKzwEaI0YSvtqkEBPj7AshElFq89TyreKNFAGh5frLfDCbodnq+Ye3dqGKPBw==", "cpu": [ "arm64" ], @@ -791,9 +806,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.1.tgz", - "integrity": "sha512-4T42heKsnbjkn7ovYiAdDVRRWZLU9Kmhdt6HafZxFcUdpjlBlxj4wDrt1yFWLk7G4+E+8p2C9tcmSu0KA6auGA==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.2.tgz", + "integrity": "sha512-52udDMFDv54BTAdnw+KXNF45QCvcJOcYGl3vQkp4vARyrcdI/cXH8VXTEv/8QWfd6Fru8QQuw1b2uNersXOL0g==", "cpu": [ "x64" ], @@ -805,9 +820,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.1.tgz", - "integrity": "sha512-MXg1xp+e5GhZ3Vit1gGEyoC+dyQUBy2JgVQ+3hUrD9wZMkUw/ywgkpK7oZgnB6kPpGrxJ41clkPPnsknuD6M2Q==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.2.tgz", + "integrity": "sha512-r+SI2t8srMPYZeoa1w0o/AfoVt9akI1ihgazGYPQGRilVAkuzMGiTtexNZkrPkQsyFrvqq/ni8f3zOnHw4hUbA==", "cpu": [ "arm" ], @@ -819,9 +834,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.1.tgz", - "integrity": "sha512-DZNLwIY4ftPSRVkJEaxYkq7u2zel7aah57HESuNkUnz+3bZHxwkCUkrfS2IWC1sxK6F2QNIR0Qr/YXw7nkF3Pw==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.2.tgz", + "integrity": "sha512-+tYiL4QVjtI3KliKBGtUU7yhw0GMcJJuB9mLTCEauHEsqfk49gtUBXGtGP3h1LW8MbaTY6rSFIQV1XOBps1gBA==", "cpu": [ "arm" ], @@ -833,9 +848,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.1.tgz", - "integrity": "sha512-C7evongnjyxdngSDRRSQv5GvyfISizgtk9RM+z2biV5kY6S/NF/wta7K+DanmktC5DkuaJQgoKGf7KUDmA7RUw==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.2.tgz", + "integrity": "sha512-OR5DcvZiYN75mXDNQQxlQPTv4D+uNCUsmSCSY2FolLf9W5I4DSoJyg7z9Ea3TjKfhPSGgMJiey1aWvlWuBzMtg==", "cpu": [ "arm64" ], @@ -847,9 +862,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.1.tgz", - "integrity": "sha512-89tFWqxfxLLHkAthAcrTs9etAoBFRduNfWdl2xUs/yLV+7XDrJ5yuXMHptNqf1Zw0UCA3cAutkAiAokYCkaPtw==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.2.tgz", + "integrity": "sha512-Hw3jSfWdUSauEYFBSFIte6I8m6jOj+3vifLg8EU3lreWulAUpch4JBjDMtlKosrBzkr0kwKgL9iCfjA8L3geoA==", "cpu": [ "arm64" ], @@ -861,9 +876,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.1.tgz", - "integrity": "sha512-PromGeV50sq+YfaisG8W3fd+Cl6mnOOiNv2qKKqKCpiiEke2KiKVyDqG/Mb9GWKbYMHj5a01fq/qlUR28PFhCQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.2.tgz", + "integrity": "sha512-rhjvoPBhBwVnJRq/+hi2Q3EMiVF538/o9dBuj9TVLclo9DuONqt5xfWSaE6MYiFKpo/lFPJ/iSI72rYWw5Hc7w==", "cpu": [ "ppc64" ], @@ -875,9 +890,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.1.tgz", - "integrity": "sha512-/1BmHYh+iz0cNCP0oHCuF8CSiNj0JOGf0jRlSo3L/FAyZyG2rGBuKpkZVH9YF+x58r1jgWxvm1aRg3DHrLDt6A==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.2.tgz", + "integrity": "sha512-EAz6vjPwHHs2qOCnpQkw4xs14XJq84I81sDRGPEjKPFVPBw7fwvtwhVjcZR6SLydCv8zNK8YGFblKWd/vRmP8g==", "cpu": [ "riscv64" ], @@ -889,9 +904,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.1.tgz", - "integrity": "sha512-0cYP5rGkQWRZKy9/HtsWVStLXzCF3cCBTRI+qRL8Z+wkYlqN7zrSYm6FuY5Kd5ysS5aH0q5lVgb/WbG4jqXN1Q==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.2.tgz", + "integrity": "sha512-IJSUX1xb8k/zN9j2I7B5Re6B0NNJDJ1+soezjNojhT8DEVeDNptq2jgycCOpRhyGj0+xBn7Cq+PK7Q+nd2hxLA==", "cpu": [ "s390x" ], @@ -903,9 +918,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.1.tgz", - "integrity": "sha512-XUXeI9eM8rMP8aGvii/aOOiMvTs7xlCosq9xCjcqI9+5hBxtjDpD+7Abm1ZhVIFE1J2h2VIg0t2DX/gjespC2Q==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.2.tgz", + "integrity": "sha512-OgaToJ8jSxTpgGkZSkwKE+JQGihdcaqnyHEFOSAU45utQ+yLruE1dkonB2SDI8t375wOKgNn8pQvaWY9kPzxDQ==", "cpu": [ "x64" ], @@ -917,9 +932,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.1.tgz", - "integrity": "sha512-V7cBw/cKXMfEVhpSvVZhC+iGifD6U1zJ4tbibjjN+Xi3blSXaj/rJynAkCFFQfoG6VZrAiP7uGVzL440Q6Me2Q==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.2.tgz", + "integrity": "sha512-5V3mPpWkB066XZZBgSd1lwozBk7tmOkKtquyCJ6T4LN3mzKENXyBwWNQn8d0Ci81hvlBw5RoFgleVpL6aScLYg==", "cpu": [ "x64" ], @@ -931,9 +946,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.1.tgz", - "integrity": "sha512-88brja2vldW/76jWATlBqHEoGjJLRnP0WOEKAUbMcXaAZnemNhlAHSyj4jIwMoP2T750LE9lblvD4e2jXleZsA==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.2.tgz", + "integrity": "sha512-ayVstadfLeeXI9zUPiKRVT8qF55hm7hKa+0N1V6Vj+OTNFfKSoUxyZvzVvgtBxqSb5URQ8sK6fhwxr9/MLmxdA==", "cpu": [ "arm64" ], @@ -945,9 +960,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.1.tgz", - "integrity": "sha512-LdxxcqRVSXi6k6JUrTah1rHuaupoeuiv38du8Mt4r4IPer3kwlTo+RuvfE8KzZ/tL6BhaPlzJ3835i6CxrFIRQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.2.tgz", + "integrity": "sha512-Mda7iG4fOLHNsPqjWSjANvNZYoW034yxgrndof0DwCy0D3FvTjeNo+HGE6oGWgvcLZNLlcp0hLEFcRs+UGsMLg==", "cpu": [ "ia32" ], @@ -959,9 +974,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.1.tgz", - "integrity": "sha512-2bIrL28PcK3YCqD9anGxDxamxdiJAxA+l7fWIwM5o8UqNy1t3d1NdAweO2XhA0KTDJ5aH1FsuiT5+7VhtHliXg==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.2.tgz", + "integrity": "sha512-DPi0ubYhSow/00YqmG1jWm3qt1F8aXziHc/UNy8bo9cpCacqhuWu+iSq/fp2SyEQK7iYTZ60fBU9cat3MXTjIQ==", "cpu": [ "x64" ], @@ -980,9 +995,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.0.tgz", - "integrity": "sha512-VT7KSYudcPOzP5Q0wfbowyNLaVR8QWUdw+088uFWwfvpY6uCWaXpqV6ieLAu9WBcnTa7H4Z5RLK8I5t2FuOcqw==", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.3.tgz", + "integrity": "sha512-/e0NZtK2gs6Vk2DoyrXSZZ4AlamqTkx0CcKx1Aq8/P4ITlRgU9OtVf5fl+LXkWWJce1M89pkSlH6lJJEnK7bQA==", "dev": true, "license": "MIT", "dependencies": { @@ -990,32 +1005,32 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz", - "integrity": "sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.0.tgz", + "integrity": "sha512-STIZdwEQRXAHvNUS6ILDf5z3u95Gc8jzywunxSNqX00OooIemaaNIA0vEgynJlycL5AjabYLLrIyHd4iazyvtg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/type-utils": "7.17.0", - "@typescript-eslint/utils": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/scope-manager": "8.0.0", + "@typescript-eslint/type-utils": "8.0.0", + "@typescript-eslint/utils": "8.0.0", + "@typescript-eslint/visitor-keys": "8.0.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1024,27 +1039,27 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.17.0.tgz", - "integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.0.tgz", + "integrity": "sha512-pS1hdZ+vnrpDIxuFXYQpLTILglTjSYJ9MbetZctrUawogUsPdz31DIIRZ9+rab0LhYNTsk88w4fIzVheiTbWOQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/scope-manager": "8.0.0", + "@typescript-eslint/types": "8.0.0", + "@typescript-eslint/typescript-estree": "8.0.0", + "@typescript-eslint/visitor-keys": "8.0.0", "debug": "^4.3.4" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1053,17 +1068,17 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz", - "integrity": "sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.0.tgz", + "integrity": "sha512-V0aa9Csx/ZWWv2IPgTfY7T4agYwJyILESu/PVqFtTFz9RIS823mAze+NbnBI8xiwdX3iqeQbcTYlvB04G9wyQw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0" + "@typescript-eslint/types": "8.0.0", + "@typescript-eslint/visitor-keys": "8.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1071,27 +1086,24 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz", - "integrity": "sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.0.tgz", + "integrity": "sha512-mJAFP2mZLTBwAn5WI4PMakpywfWFH5nQZezUQdSKV23Pqo6o9iShQg1hP2+0hJJXP2LnZkWPphdIq4juYYwCeg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/utils": "7.17.0", + "@typescript-eslint/typescript-estree": "8.0.0", + "@typescript-eslint/utils": "8.0.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.56.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -1099,13 +1111,13 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.17.0.tgz", - "integrity": "sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.0.tgz", + "integrity": "sha512-wgdSGs9BTMWQ7ooeHtu5quddKKs5Z5dS+fHLbrQI+ID0XWJLODGMHRfhwImiHoeO2S5Wir2yXuadJN6/l4JRxw==", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1113,14 +1125,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz", - "integrity": "sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.0.tgz", + "integrity": "sha512-5b97WpKMX+Y43YKi4zVcCVLtK5F98dFls3Oxui8LbnmRsseKenbbDinmvxrWegKDMmlkIq/XHuyy0UGLtpCDKg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/types": "8.0.0", + "@typescript-eslint/visitor-keys": "8.0.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1129,7 +1141,7 @@ "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1142,62 +1154,55 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.17.0.tgz", - "integrity": "sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.0.tgz", + "integrity": "sha512-k/oS/A/3QeGLRvOWCg6/9rATJL5rec7/5s1YmdS0ZU6LHveJyGFwBvLhSRBv6i9xaj7etmosp+l+ViN1I9Aj/Q==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0" + "@typescript-eslint/scope-manager": "8.0.0", + "@typescript-eslint/types": "8.0.0", + "@typescript-eslint/typescript-estree": "8.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz", - "integrity": "sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.0.tgz", + "integrity": "sha512-oN0K4nkHuOyF3PVMyETbpP5zp6wfyOvm7tWhTMfoqxSSsPmJIh6JNASuZDlODE8eE+0EB9uar+6+vxr9DBTYOA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/types": "8.0.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true, - "license": "ISC" - }, "node_modules/@vitest/expect": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.4.tgz", - "integrity": "sha512-39jr5EguIoanChvBqe34I8m1hJFI4+jxvdOpD7gslZrVQBKhh8H9eD7J/LJX4zakrw23W+dITQTDqdt43xVcJw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", + "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "2.0.4", - "@vitest/utils": "2.0.4", + "@vitest/spy": "2.0.5", + "@vitest/utils": "2.0.5", "chai": "^5.1.1", "tinyrainbow": "^1.2.0" }, @@ -1206,9 +1211,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.4.tgz", - "integrity": "sha512-RYZl31STbNGqf4l2eQM1nvKPXE0NhC6Eq0suTTePc4mtMQ1Fn8qZmjV4emZdEdG2NOWGKSCrHZjmTqDCDoeFBw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz", + "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1219,13 +1224,13 @@ } }, "node_modules/@vitest/runner": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.4.tgz", - "integrity": "sha512-Gk+9Su/2H2zNfNdeJR124gZckd5st4YoSuhF1Rebi37qTXKnqYyFCd9KP4vl2cQHbtuVKjfEKrNJxHHCW8thbQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.5.tgz", + "integrity": "sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "2.0.4", + "@vitest/utils": "2.0.5", "pathe": "^1.1.2" }, "funding": { @@ -1233,13 +1238,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.4.tgz", - "integrity": "sha512-or6Mzoz/pD7xTvuJMFYEtso1vJo1S5u6zBTinfl+7smGUhqybn6VjzCDMhmTyVOFWwkCMuNjmNNxnyXPgKDoPw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.5.tgz", + "integrity": "sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.0.4", + "@vitest/pretty-format": "2.0.5", "magic-string": "^0.30.10", "pathe": "^1.1.2" }, @@ -1248,9 +1253,9 @@ } }, "node_modules/@vitest/spy": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.4.tgz", - "integrity": "sha512-uTXU56TNoYrTohb+6CseP8IqNwlNdtPwEO0AWl+5j7NelS6x0xZZtP0bDWaLvOfUbaYwhhWp1guzXUxkC7mW7Q==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", + "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==", "dev": true, "license": "MIT", "dependencies": { @@ -1261,13 +1266,13 @@ } }, "node_modules/@vitest/utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.4.tgz", - "integrity": "sha512-Zc75QuuoJhOBnlo99ZVUkJIuq4Oj0zAkrQ2VzCqNCx6wAwViHEh5Fnp4fiJTE9rA+sAoXRf00Z9xGgfEzV6fzQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz", + "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.0.4", + "@vitest/pretty-format": "2.0.5", "estree-walker": "^3.0.3", "loupe": "^3.1.1", "tinyrainbow": "^1.2.0" @@ -1277,9 +1282,9 @@ } }, "node_modules/@vitest/web-worker": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/web-worker/-/web-worker-2.0.4.tgz", - "integrity": "sha512-szSNjgmymobgimyIWNDymEwHSRM4MczyhtP+yrKR61vXTqvKWEiu5jiHBnjqMdHLeN3McHOdO5wHK7rLKPYDAg==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/web-worker/-/web-worker-2.0.5.tgz", + "integrity": "sha512-V569KT8CAeh/Cj8JE1oG8FZ7ajmcqSZQ5bhCMwYsYxeceDcV9iDDkRgQFWOJX7yOI95ldiUOaQdFpLrc2eBREA==", "dev": true, "license": "MIT", "dependencies": { @@ -1289,7 +1294,7 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": "2.0.4" + "vitest": "2.0.5" } }, "node_modules/acorn": { @@ -1653,19 +1658,6 @@ "node": ">=8" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -1786,42 +1778,38 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.8.0.tgz", + "integrity": "sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.17.1", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.8.0", "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", @@ -1835,27 +1823,27 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" } }, "node_modules/eslint-plugin-unused-imports": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.2.0.tgz", - "integrity": "sha512-6uXyn6xdINEpxE1MtDjxQsyXB37lfyO2yKGVVgtD7WEWQGORSOZjgrD6hBhvGv4/SO+TOlS+UnC6JppRqbuwGQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.0.1.tgz", + "integrity": "sha512-rax76s05z64uQgG9YXsWFmXrgjkaK79AvfeAWiSxhPP6RVGxeRaj4+2u+wxxu/mDy2pmJoOy1QTOEALMia2xGQ==", "dev": true, "license": "MIT", "dependencies": { "eslint-rule-composer": "^0.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "6 - 7", - "eslint": "8" + "@typescript-eslint/eslint-plugin": "^8.0.0-0", + "eslint": "^9.0.0" }, "peerDependenciesMeta": { "@typescript-eslint/eslint-plugin": { @@ -1874,9 +1862,9 @@ } }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -1884,7 +1872,7 @@ "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -1914,6 +1902,19 @@ "concat-map": "0.0.1" } }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1928,18 +1929,31 @@ } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2094,16 +2108,16 @@ "license": "MIT" }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/fill-range": { @@ -2137,18 +2151,17 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { @@ -2173,13 +2186,6 @@ "node": ">= 6" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2218,28 +2224,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -2253,41 +2237,14 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2451,25 +2408,6 @@ "node": ">=0.8.19" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2673,13 +2611,13 @@ } }, "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/merge-stream": { @@ -2834,16 +2772,6 @@ "dev": true, "license": "MIT" }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/onetime": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", @@ -2946,16 +2874,6 @@ "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -3125,27 +3043,10 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/rollup": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.1.tgz", - "integrity": "sha512-K5vziVlg7hTpYfFBI+91zHBEMo6jafYXpkMlqZjg7/zhIG9iHqazBf4xz9AVdjS9BruRn280ROqLI7G3OFRIlw==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.2.tgz", + "integrity": "sha512-6/jgnN1svF9PjNYJ4ya3l+cqutg49vOZ4rVgsDKxdl+5gpGPnByFXWGyfH9YGx9i3nfBwSu1Iyu6vGwFFA0BdQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3159,22 +3060,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.19.1", - "@rollup/rollup-android-arm64": "4.19.1", - "@rollup/rollup-darwin-arm64": "4.19.1", - "@rollup/rollup-darwin-x64": "4.19.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.19.1", - "@rollup/rollup-linux-arm-musleabihf": "4.19.1", - "@rollup/rollup-linux-arm64-gnu": "4.19.1", - "@rollup/rollup-linux-arm64-musl": "4.19.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.19.1", - "@rollup/rollup-linux-riscv64-gnu": "4.19.1", - "@rollup/rollup-linux-s390x-gnu": "4.19.1", - "@rollup/rollup-linux-x64-gnu": "4.19.1", - "@rollup/rollup-linux-x64-musl": "4.19.1", - "@rollup/rollup-win32-arm64-msvc": "4.19.1", - "@rollup/rollup-win32-ia32-msvc": "4.19.1", - "@rollup/rollup-win32-x64-msvc": "4.19.1", + "@rollup/rollup-android-arm-eabi": "4.19.2", + "@rollup/rollup-android-arm64": "4.19.2", + "@rollup/rollup-darwin-arm64": "4.19.2", + "@rollup/rollup-darwin-x64": "4.19.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.19.2", + "@rollup/rollup-linux-arm-musleabihf": "4.19.2", + "@rollup/rollup-linux-arm64-gnu": "4.19.2", + "@rollup/rollup-linux-arm64-musl": "4.19.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.19.2", + "@rollup/rollup-linux-riscv64-gnu": "4.19.2", + "@rollup/rollup-linux-s390x-gnu": "4.19.2", + "@rollup/rollup-linux-x64-gnu": "4.19.2", + "@rollup/rollup-linux-x64-musl": "4.19.2", + "@rollup/rollup-win32-arm64-msvc": "4.19.2", + "@rollup/rollup-win32-ia32-msvc": "4.19.2", + "@rollup/rollup-win32-x64-msvc": "4.19.2", "fsevents": "~2.3.2" } }, @@ -3490,19 +3391,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typescript": { "version": "5.5.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", @@ -3612,9 +3500,9 @@ } }, "node_modules/vite-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.4.tgz", - "integrity": "sha512-ZpJVkxcakYtig5iakNeL7N3trufe3M6vGuzYAr4GsbCTwobDeyPJpE4cjDhhPluv8OvQCFzu2LWp6GkoKRITXA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.5.tgz", + "integrity": "sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==", "dev": true, "license": "MIT", "dependencies": { @@ -3635,19 +3523,19 @@ } }, "node_modules/vitest": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.4.tgz", - "integrity": "sha512-luNLDpfsnxw5QSW4bISPe6tkxVvv5wn2BBs/PuDRkhXZ319doZyLOBr1sjfB5yCEpTiU7xCAdViM8TNVGPwoog==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.5.tgz", + "integrity": "sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.3.0", - "@vitest/expect": "2.0.4", - "@vitest/pretty-format": "^2.0.4", - "@vitest/runner": "2.0.4", - "@vitest/snapshot": "2.0.4", - "@vitest/spy": "2.0.4", - "@vitest/utils": "2.0.4", + "@vitest/expect": "2.0.5", + "@vitest/pretty-format": "^2.0.5", + "@vitest/runner": "2.0.5", + "@vitest/snapshot": "2.0.5", + "@vitest/spy": "2.0.5", + "@vitest/utils": "2.0.5", "chai": "^5.1.1", "debug": "^4.3.5", "execa": "^8.0.1", @@ -3658,7 +3546,7 @@ "tinypool": "^1.0.0", "tinyrainbow": "^1.2.0", "vite": "^5.0.0", - "vite-node": "2.0.4", + "vite-node": "2.0.5", "why-is-node-running": "^2.3.0" }, "bin": { @@ -3673,8 +3561,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.0.4", - "@vitest/ui": "2.0.4", + "@vitest/browser": "2.0.5", + "@vitest/ui": "2.0.5", "happy-dom": "*", "jsdom": "*" }, @@ -3802,13 +3690,6 @@ "node": ">=0.10.0" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, "node_modules/ws": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", @@ -3874,10 +3755,13 @@ "@next2d/core": "file:../core", "@next2d/display": "file:../display", "@next2d/events": "file:../events", + "@next2d/filters": "file:../filters", "@next2d/geom": "file:../geom", "@next2d/media": "file:../media", "@next2d/net": "file:../net", + "@next2d/renderer": "file:../renderer", "@next2d/text": "file:../text", + "@next2d/ui": "file:../ui", "@next2d/webgl": "file:../webgl" } }, @@ -3950,6 +3834,8 @@ "version": "*", "license": "MIT", "peerDependencies": { + "@next2d/cache": "file:../cache", + "@next2d/filters": "file:../filters", "@next2d/webgl": "file:../webgl" } }, diff --git a/package.json b/package.json index 22472f95..5eca89ed 100644 --- a/package.json +++ b/package.json @@ -45,17 +45,17 @@ "htmlparser2": "^9.1.0" }, "devDependencies": { - "@types/node": "^22.0.0", - "@typescript-eslint/eslint-plugin": "^7.17.0", - "@typescript-eslint/parser": "^7.17.0", - "@vitest/web-worker": "^2.0.4", - "eslint": "^8.57.0", - "eslint-plugin-unused-imports": "^3.2.0", + "@types/node": "^22.0.3", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", + "@vitest/web-worker": "^2.0.5", + "eslint": "^9.8.0", + "eslint-plugin-unused-imports": "^4.0.1", "fflate": "^0.8.2", "jsdom": "^24.1.1", "typescript": "^5.5.4", "vite": "^5.3.5", - "vitest": "^2.0.4" + "vitest": "^2.0.5" }, "peerDependencies": { "@next2d/cache": "file:packages/cache", diff --git a/packages/core/src/CoreUtil.ts b/packages/core/src/CoreUtil.ts index 4e656c59..525b57f2 100644 --- a/packages/core/src/CoreUtil.ts +++ b/packages/core/src/CoreUtil.ts @@ -54,29 +54,11 @@ export const $clamp = ( : Math.min(Math.max(min, isNaN(number) ? 0 : number), max); }; -/** - * @type {number} - * @public - */ -export let $stageWidth: number = 0; - -/** - * @type {number} - * @public - */ -export let $stageHeight: number = 0; +const canvas = document.createElement("canvas"); +canvas.width = canvas.height = 1; /** - * @description ステージサイズを設定 - * Set stage size - * - * @param {number} width - * @return {void} - * @method - * @public + * @type {CanvasRenderingContext2D} + * @const */ -export const $setStageSize = (width: number, height: number): void => -{ - $stageWidth = width; - $stageHeight = height; -}; \ No newline at end of file +export const $hitContext: CanvasRenderingContext2D = canvas.getContext("2d") as NonNullable; \ No newline at end of file diff --git a/packages/core/src/Next2D/CreateRootMovieClip.ts b/packages/core/src/Next2D/CreateRootMovieClip.ts index ea237fc1..62b7366a 100644 --- a/packages/core/src/Next2D/CreateRootMovieClip.ts +++ b/packages/core/src/Next2D/CreateRootMovieClip.ts @@ -1,7 +1,7 @@ import type { PlayerOptionsImpl } from "../interface/PlayerOptionsImpl"; import { Sprite, $stage } from "@next2d/display"; import { $player } from "../Player"; -import { $LOAD_END } from "../CoreUtil"; +import { $LOAD_END, $clamp } from "../CoreUtil"; /** * @description RootのMovieClipを作成します。 @@ -23,16 +23,15 @@ export const execute = async ( ): Promise => { // setup - $player.mode = "create"; - $player.width = width | 0; - $player.height = height | 0; - $player.frameRate = fps | 0; + $player.mode = "create"; + $player.stageWidth = width | 0; + $player.stageHeight = height | 0; + $player.frameRate = $clamp(fps, 1, 60, 60); $player.boot(options); - const root: Sprite = $stage.addChild(new Sprite()); - - $player._$loadStatus = $LOAD_END; + // const root: Sprite = $stage.addChild(new Sprite()); + // $player._$loadStatus = $LOAD_END; $player.play(); return root; diff --git a/packages/core/src/Next2D/LoadService.ts b/packages/core/src/Next2D/LoadService.ts index d027824e..3b8a39e0 100644 --- a/packages/core/src/Next2D/LoadService.ts +++ b/packages/core/src/Next2D/LoadService.ts @@ -1,13 +1,14 @@ import type { PlayerOptionsImpl } from "../interface/PlayerOptionsImpl"; import type { StageDataImpl } from "../interface/StageDataImpl"; import { $player } from "../Player"; +import { $stage } from "../Stage"; import { $clamp } from "../CoreUtil"; import { URLRequest } from "@next2d/net"; import { IOErrorEvent } from "@next2d/events"; -import { - Loader, - $stage -} from "@next2d/display"; +import { Loader } from "@next2d/display"; +import { execute as playerResizeEventService } from "../Player/PlayerResizeEventService"; +import { execute as playerRemoveLoadingElementService } from "../Player/PlayerRemoveLoadingElementService"; +import { execute as playerAppendCanvasElementService } from "../Player/PlayerAppendCanvasElementService"; /** * @description 指定のURLからJSONファイルを読み込みます。 @@ -41,6 +42,7 @@ export const execute = async (url: string, options: PlayerOptionsImpl): Promise< url = url.slice(1); } + // player $player.boot(options); const loader: Loader = new Loader(); @@ -51,54 +53,25 @@ export const execute = async (url: string, options: PlayerOptionsImpl): Promise< alert("Error: " + event.text); }); - // loader - // .contentLoaderInfo - // .addEventListener(Event.COMPLETE, (event: Event): void => - // { - // const loaderInfo: LoaderInfo = event.target as NonNullable; - - // if (event.listener) { - // loaderInfo - // .removeEventListener(Event.COMPLETE, event.listener); - // } - - // if (loaderInfo._$data) { - - // const stage: StageDataImpl = loaderInfo._$data.stage; - - // $player.bgColor = stage.bgColor; - // // $player._$setBackgroundColor(stage.bgColor); - - // $stage.addChild(loaderInfo.content); - - // $player.width = stage.width; - // $player.height = stage.height; - - // // set fps fixed logic - // $player.frameRate = $clamp(+stage.fps, 1, 60, 60); - // } - - // // $player._$resize(); - - // resolve(); - // }); - await loader.load(new URLRequest(url)); if (!loaderInfo.data) { return ; } - const stage: StageDataImpl = loaderInfo.data.stage; - - $player.bgColor = stage.bgColor; - // $player._$setBackgroundColor(stage.bgColor); + // update properties + const stageData: StageDataImpl = loaderInfo.data.stage; + $player.stageWidth = stageData.width; + $player.stageHeight = stageData.height; + $player.frameRate = $clamp(stageData.fps, 1, 60, 60); + $player.bgColor = stageData.bgColor; - $stage.addChild(loaderInfo.content); + // $stage.addChild(loaderInfo.content); - $player.rendererWidth = stage.width; - $player.rendererHeight = stage.height; + // resize + playerResizeEventService($player); - // set fps fixed logic - $player.frameRate = $clamp(stage.fps, 1, 60, 60); + // load complete + playerRemoveLoadingElementService(); + playerAppendCanvasElementService(); }; \ No newline at end of file diff --git a/packages/core/src/Player.ts b/packages/core/src/Player.ts index 7e3a4ddc..65d80315 100644 --- a/packages/core/src/Player.ts +++ b/packages/core/src/Player.ts @@ -20,6 +20,7 @@ import { execute as playerApplyContainerElementStyleService } from "./Player/Pla import { execute as playerLoadingAnimationService } from "./Player/PlayerLoadingAnimationService"; import { execute as playerResizeEventService } from "./Player/PlayerResizeEventService"; import { execute as playerResizeRegisterService } from "./Player/PlayerResizeRegisterService"; +import { execute as playerUpdateBackgroundColorPostMessageService } from "./Player/PlayerUpdateBackgroundColorPostMessageService"; /** * @description Next2Dの描画、イベント、設定、コントロールの管理クラスです。 @@ -38,8 +39,8 @@ export class Player private _$rendererWidth: number; private _$rendererHeight: number; private _$rendererScale: number; - private _$initialWidth: number; - private _$initialHeight: number; + private _$stageWidth: number; + private _$stageHeight: number; private _$fixedWidth: number; private _$fixedHeight: number; private _$frameRate: number; @@ -175,14 +176,14 @@ export class Player * @default 0 * @private */ - this._$initialWidth = 0; + this._$stageWidth = 0; /** * @type {number} * @default 0 * @private */ - this._$initialHeight = 0; + this._$stageHeight = 0; /** * @type {number} @@ -500,12 +501,7 @@ export class Player this._$fullScreen = full_screen; // display resize - playerResizeEventService( - this, - this._$initialWidth, - this._$initialHeight, - this._$fullScreen - ); + playerResizeEventService(this); } /** @@ -518,7 +514,12 @@ export class Player } set bgColor (bg_color: string) { + if (this._$bgColor === bg_color) { + return ; + } + this._$bgColor = `${bg_color}`; + playerUpdateBackgroundColorPostMessageService(this._$bgColor); } /** @@ -534,6 +535,40 @@ export class Player this._$frameRate = frame_rate; } + /** + * @description ステージの幅 + * Stage width + * + * @member {number} + * @default 0 + * @public + */ + get stageWidth (): number + { + return this._$stageWidth; + } + set stageWidth (stage_width: number) + { + this._$stageWidth = stage_width; + } + + /** + * @description ステージの高さ + * Stage height + * + * @member {number} + * @default 0 + * @public + */ + get stageHeight (): number + { + return this._$stageHeight; + } + set stageHeight (stage_height: number) + { + this._$stageHeight = stage_height; + } + /** * @return {void} * @method @@ -575,13 +610,6 @@ export class Player this._$timerId = -1; SoundMixer.stopAll(); - $cacheStore.reset(); - - // if ($rendererWorker) { - // $rendererWorker.postMessage({ - // "command": "stop" - // }); - // } } // /** @@ -639,29 +667,16 @@ export class Player element, this._$fixedWidth, this._$fixedHeight ); - this._$initialWidth = element.clientWidth; - this._$initialHeight = element.clientHeight; - // start loading playerLoadingAnimationService(element); + // register resize event if (!this._$fixedWidth && !this._$fixedHeight) { - // register resize event - playerResizeRegisterService( - this, - this._$initialWidth, - this._$initialHeight, - this._$fullScreen - ); + playerResizeRegisterService(this); } // initialize resize - playerResizeEventService( - this, - this._$initialWidth, - this._$initialHeight, - this._$fullScreen - ); + playerResizeEventService(this); } // /** diff --git a/packages/core/src/Player/PlayerAppendCanvasElementService.ts b/packages/core/src/Player/PlayerAppendCanvasElementService.ts new file mode 100644 index 00000000..eb0aeff2 --- /dev/null +++ b/packages/core/src/Player/PlayerAppendCanvasElementService.ts @@ -0,0 +1,19 @@ +import { $PREFIX } from "../CoreUtil"; +import { $canvas } from "../Canvas"; + +/** + * @description canvas elementをメインのdivに追加 + * Add canvas element to main div + * + * @return {void} + * @method + * @public + */ +export const execute = (): void => +{ + const element: HTMLElement | null = document.getElementById($PREFIX); + if (!element) { + return ; + } + element.appendChild($canvas); +}; \ No newline at end of file diff --git a/packages/core/src/Player/PlayerRemoveLoadingElementService.test.ts b/packages/core/src/Player/PlayerRemoveLoadingElementService.test.ts new file mode 100644 index 00000000..2bbdafc5 --- /dev/null +++ b/packages/core/src/Player/PlayerRemoveLoadingElementService.test.ts @@ -0,0 +1,23 @@ +import { execute } from "./PlayerRemoveLoadingElementService"; +import { execute as playerLoadingAnimationService } from "./PlayerLoadingAnimationService"; +import { $PREFIX } from "../CoreUtil"; +import { describe, expect, it } from "vitest"; + +describe("PlayerRemoveLoadingElementService.js test", () => +{ + it("execute test case1", () => + { + const parent = document.createElement("div"); + parent.id = $PREFIX; + document.body.appendChild(parent); + expect(parent.children.length).toBe(0); + + playerLoadingAnimationService(parent); + expect(parent.children.length).toBe(2); + + execute(); + expect(parent.children.length).toBe(0); + + parent.remove(); + }); +}); \ No newline at end of file diff --git a/packages/core/src/Player/PlayerRemoveLoadingElementService.ts b/packages/core/src/Player/PlayerRemoveLoadingElementService.ts new file mode 100644 index 00000000..cf61d6b0 --- /dev/null +++ b/packages/core/src/Player/PlayerRemoveLoadingElementService.ts @@ -0,0 +1,21 @@ +import { $PREFIX } from "../CoreUtil"; + +/** + * @description ローディングのelementを削除 + * Remove the loading element + * + * @return {void} + * @method + * @public + */ +export const execute = (): void => +{ + const element: HTMLElement | null = document.getElementById($PREFIX); + if (!element) { + return ; + } + + while (element.firstChild) { + element.removeChild(element.firstChild); + } +}; \ No newline at end of file diff --git a/packages/core/src/Player/PlayerResizeEventService.ts b/packages/core/src/Player/PlayerResizeEventService.ts index 117d4931..0e6bf4db 100644 --- a/packages/core/src/Player/PlayerResizeEventService.ts +++ b/packages/core/src/Player/PlayerResizeEventService.ts @@ -4,25 +4,19 @@ import { $PREFIX, $devicePixelRatio } from "../CoreUtil"; +import { $canvas } from "../Canvas"; /** * @description 画面リサイズ時にcanvasのリサイズを行う * Resize the canvas when resizing the screen * * @param {Player} player - * @param {number} initial_width - * @param {number} initial_height - * @param {boolean} full_screen * @return {void} * @method * @protected */ -export const execute = ( - player: Player, - initial_width: number, - initial_height: number, - full_screen: boolean -): void => { +export const execute = (player: Player): void => +{ const element: HTMLElement | null = document .getElementById($PREFIX); @@ -36,11 +30,11 @@ export const execute = ( return ; } - const screenWidth: number = full_screen || parent.tagName === "BODY" + const screenWidth: number = player.fullScreen || parent.tagName === "BODY" ? window.innerWidth : parent.clientWidth; - const screenHeight: number = full_screen || parent.tagName === "BODY" + const screenHeight: number = player.fullScreen || parent.tagName === "BODY" ? window.innerHeight : parent.clientHeight; @@ -48,18 +42,22 @@ export const execute = ( style.width = `${screenWidth}px`; style.height = `${screenHeight}px`; + if (!player.stageWidth || !player.stageHeight) { + return ; + } + const scale: number = Math.min( - screenWidth / initial_width, - screenHeight / initial_height + screenWidth / player.stageWidth, + screenHeight / player.stageHeight ); - const width: number = full_screen + const width: number = player.fullScreen ? window.innerWidth * $devicePixelRatio - : initial_width * scale * $devicePixelRatio | 0; + : player.stageWidth * scale * $devicePixelRatio | 0; - const height: number = full_screen + const height: number = player.fullScreen ? window.innerHeight * $devicePixelRatio - : initial_height * scale * $devicePixelRatio | 0; + : player.stageHeight * scale * $devicePixelRatio | 0; // 同じサイズの場合は、ここれで終了 if (width === player.rendererWidth diff --git a/packages/core/src/Player/PlayerResizePostMessageService.ts b/packages/core/src/Player/PlayerResizePostMessageService.ts index eaad7ce4..ef37ae27 100644 --- a/packages/core/src/Player/PlayerResizePostMessageService.ts +++ b/packages/core/src/Player/PlayerResizePostMessageService.ts @@ -1,10 +1,6 @@ import type { Player } from "../Player"; import type { ResizeMessageImpl } from "../interface/ResizeMessageImpl"; -import { - $rendererWorker, - $stageWidth, - $stageHeight -} from "../CoreUtil"; +import { $rendererWorker } from "../CoreUtil"; /** * @description リサイズメッセージ @@ -43,8 +39,8 @@ export const execute = (player: Player): void => player.rendererScale, player.rendererWidth, player.rendererHeight, - $stageWidth, - $stageHeight, + player.stageWidth, + player.stageHeight, player.fullScreen ? 1 : 0 ]); diff --git a/packages/core/src/Player/PlayerResizeRegisterService.ts b/packages/core/src/Player/PlayerResizeRegisterService.ts index 06f9bd7f..b51a3edb 100644 --- a/packages/core/src/Player/PlayerResizeRegisterService.ts +++ b/packages/core/src/Player/PlayerResizeRegisterService.ts @@ -15,23 +15,14 @@ let timerId: number = -1; * @method * @protected */ -export const execute = ( - player: Player, - initial_width: number, - initial_height: number, - full_screen: boolean -): void => { +export const execute = (player: Player): void => +{ window.addEventListener("resize", (): void => { cancelAnimationFrame(timerId); timerId = requestAnimationFrame((): void => { - playerResizeEventService( - player, - initial_width, - initial_height, - full_screen - ); + playerResizeEventService(player); }); }); }; \ No newline at end of file diff --git a/packages/core/src/Player/PlayerUpdateBackgroundColorPostMessageService.ts b/packages/core/src/Player/PlayerUpdateBackgroundColorPostMessageService.ts new file mode 100644 index 00000000..33363f8f --- /dev/null +++ b/packages/core/src/Player/PlayerUpdateBackgroundColorPostMessageService.ts @@ -0,0 +1,51 @@ +import type { UpdateBackgroundColorMessageImpl } from "../interface/UpdateBackgroundColorMessageImpl"; +import { + $rendererWorker, + $hitContext +} from "../CoreUtil"; + +/** + * @description リサイズメッセージ + * Resize message + * + * @type {UpdateBackgroundColorMessageImpl} + * @private + */ +const message: UpdateBackgroundColorMessageImpl = { + "command": "setBackgroundColor", + "buffer": null +}; + +/** + * @description Transferableオブジェクト + * Transferable object + * + * @type {Transferable[]} + * @private + */ +const options: Transferable[] = []; + +/** + * @description 背景色を変更をworkerに通知 + * Notify the worker of the background color change + * + * @param {string} background_color + * @return {void} + * @method + * @protected + */ +export const execute = (background_color: string): void => +{ + let color = -1; + if (background_color === "transparent") { + $hitContext.fillStyle = background_color; + color = +`0x${$hitContext.fillStyle.slice(1)}`; + } + + // postMessage + message.buffer = new Float32Array([color]); + + options[0] = message.buffer.buffer; + + $rendererWorker.postMessage(message, options); +}; \ No newline at end of file diff --git a/packages/core/src/interface/ResizeMessageImpl.ts b/packages/core/src/interface/ResizeMessageImpl.ts index 0c3985f2..a1e95f30 100644 --- a/packages/core/src/interface/ResizeMessageImpl.ts +++ b/packages/core/src/interface/ResizeMessageImpl.ts @@ -1,4 +1,4 @@ export interface ResizeMessageImpl { - command: string; + command: "resize"; buffer: Float32Array | null; } \ No newline at end of file diff --git a/packages/core/src/interface/UpdateBackgroundColorMessageImpl.ts b/packages/core/src/interface/UpdateBackgroundColorMessageImpl.ts new file mode 100644 index 00000000..da0631b1 --- /dev/null +++ b/packages/core/src/interface/UpdateBackgroundColorMessageImpl.ts @@ -0,0 +1,4 @@ +export interface UpdateBackgroundColorMessageImpl { + command: "setBackgroundColor"; + buffer: Float32Array | null; +} \ No newline at end of file diff --git a/packages/display/src/Loader/LoaderBuildService.ts b/packages/display/src/Loader/LoaderBuildService.ts index c2a84337..d10bb0bd 100644 --- a/packages/display/src/Loader/LoaderBuildService.ts +++ b/packages/display/src/Loader/LoaderBuildService.ts @@ -21,7 +21,7 @@ export const execute = async (loader_info: LoaderInfo, object: NoCodeDataImpl): // setup // loader_info.content = new MovieClip(); - console.log(object); + // console.log(object); // build root // const root: MovieClipCharacterImpl = object.characters[0]; diff --git a/packages/display/src/Loader/LoaderLoadEndEventService.test.ts b/packages/display/src/Loader/LoaderLoadEndEventService.test.ts index 666d3007..df6b859e 100644 --- a/packages/display/src/Loader/LoaderLoadEndEventService.test.ts +++ b/packages/display/src/Loader/LoaderLoadEndEventService.test.ts @@ -28,7 +28,7 @@ describe("LoaderLoadEndEventService.js test", () => expect(loaded).toBe(0); expect(total).toBe(0); - const json = { + const object = { "type": "json", "stage": { "width": 240, @@ -47,7 +47,7 @@ describe("LoaderLoadEndEventService.js test", () => "target": { "status": 200, "statusText": "OK", - "response": JSON.stringify(json) + "response": object }, "loaded": 1, "total": 10 diff --git a/packages/display/src/Loader/LoaderLoadJsonService.ts b/packages/display/src/Loader/LoaderLoadJsonService.ts index 45043ede..9f7f6709 100644 --- a/packages/display/src/Loader/LoaderLoadJsonService.ts +++ b/packages/display/src/Loader/LoaderLoadJsonService.ts @@ -1,4 +1,5 @@ import type { NoCodeDataImpl } from "../interface/NoCodeDataImpl"; +import type { NoCodeDataZlibImpl } from "../interface/NoCodeDataZlibImpl"; import type { LoaderInfo } from "../LoaderInfo"; import { execute as loaderBuildService } from "./LoaderBuildService"; @@ -16,14 +17,14 @@ const worker: Worker = new ZlibInflateWorker(); * If the JSON object is zlib compressed, decompress it with a worker, otherwise execute the build process * * @param {LoaderInfo} loader_info - * @param {object} json + * @param {object} object * @return {Promise} * @method * @public */ -export const execute = async (loader_info: LoaderInfo, json: any): Promise => +export const execute = async (loader_info: LoaderInfo, object: NoCodeDataImpl | NoCodeDataZlibImpl): Promise => { - if (json.type === "zlib") { + if (object.type === "zlib") { await new Promise((resolve): void => { worker.onmessage = async (event: MessageEvent): Promise => @@ -32,10 +33,10 @@ export const execute = async (loader_info: LoaderInfo, json: any): Promise resolve(); }; - const buffer: Uint8Array = new Uint8Array(json.buffer); + const buffer: Uint8Array = new Uint8Array(object.buffer); worker.postMessage(buffer, [buffer.buffer]); }); } else { - await loaderBuildService(loader_info, json as NoCodeDataImpl); + await loaderBuildService(loader_info, object as NoCodeDataImpl); } }; \ No newline at end of file diff --git a/packages/display/src/interface/NoCodeDataZlibImpl.ts b/packages/display/src/interface/NoCodeDataZlibImpl.ts new file mode 100644 index 00000000..d7b36d56 --- /dev/null +++ b/packages/display/src/interface/NoCodeDataZlibImpl.ts @@ -0,0 +1,4 @@ +export interface NoCodeDataZlibImpl { + type: "zlib"; + buffer: number[]; +} \ No newline at end of file diff --git a/packages/renderer/src/Command/CommandBackgroundColorService.ts b/packages/renderer/src/Command/CommandBackgroundColorService.ts new file mode 100644 index 00000000..e4d2978a --- /dev/null +++ b/packages/renderer/src/Command/CommandBackgroundColorService.ts @@ -0,0 +1,28 @@ +import { $context } from "../RendererUtil"; + +/** + * @description 背景色を更新 + * Update background color + * + * @param {number} color + * @return {void} + * @method + * @protected + */ +export const execute = (color: number): void => +{ + if (color === -1) { + + $context.updateBackgroundColor(1,1,1,1); + + } else { + + $context.updateBackgroundColor( + (color & 0x00ff0000) >> 16 / 255, + (color & 0x0000ff00) >> 8 / 255, + color & 0x000000ff / 255, + 1 + ); + + } +}; \ No newline at end of file diff --git a/packages/renderer/src/Command/CommandResizeService.ts b/packages/renderer/src/Command/CommandResizeService.ts index 7166d9aa..1a21c06c 100644 --- a/packages/renderer/src/Command/CommandResizeService.ts +++ b/packages/renderer/src/Command/CommandResizeService.ts @@ -1,7 +1,6 @@ import { $canvas, - $setRendererHeight, - $setRendererWidth, + $setRendererSize, $rendererMatrix, $devicePixelRatio, $gl, @@ -40,8 +39,7 @@ export const execute = ( } // resize - $setRendererWidth(renderer_width); - $setRendererHeight(renderer_height); + $setRendererSize(renderer_width, renderer_height); // update canvas size $canvas.width = renderer_width; diff --git a/packages/renderer/src/CommandController.ts b/packages/renderer/src/CommandController.ts index 28173498..04bfff4b 100644 --- a/packages/renderer/src/CommandController.ts +++ b/packages/renderer/src/CommandController.ts @@ -1,13 +1,7 @@ -// import { $renderPlayer } from "./RenderGlobal"; -// import { -// $MATRIX_ARRAY_IDENTITY, -// $COLOR_ARRAY_IDENTITY, -// $OffscreenCanvas, -// $cacheStore -// } from "@next2d/share"; import type { PropertyMessageMapImpl } from "./interface/PropertyMessageMapImpl"; import { execute as commandInitializeContextService } from "./Command/CommandInitializeContextService"; import { execute as commandResizeService } from "./Command/CommandResizeService"; +import { execute as commandBackgroundColorService } from "./Command/CommandBackgroundColorService"; /** * @class @@ -67,69 +61,8 @@ export class CommandController // returnBuffer = true; switch (object.command) { - // case "draw": - // $renderPlayer._$draw(); - // break; - - // case "setProperty": - // { - // const instances: Map> = $renderPlayer.instances; - // if (!instances.has(object.instanceId)) { - // continue; - // } - - // // instances.get(object.instanceId)._$update(object); - // } - // break; - - // case "setChildren": - // { - // returnBuffer = false; - - // const buffer: Float32Array = object.buffer; - - // const instances: Map> = $renderPlayer.instances; - // if (!instances.has(buffer[0])) { - // continue; - // } - - // const instance: RenderDisplayObjectImpl = instances.get(buffer[0]); - // instance._$doChanged(); - - // instance._$children = buffer.subarray(1); - // } - // break; - - // case "remove": - // { - // const instances: Map> = $renderPlayer.instances; - // if (!instances.has(object.instanceId)) { - // continue; - // } - - // instances.get(object.instanceId)._$remove(); - // instances.delete(object.instanceId); - // } - // break; - - // case "createShape": - // $renderPlayer._$createShape(object.buffer); - // break; - - // case "createDisplayObjectContainer": - - // $renderPlayer - // ._$createDisplayObjectContainer(object.buffer); - - // break; - - // case "createTextField": - // $renderPlayer._$createTextField(object); - // break; - - // case "createVideo": - // $renderPlayer._$createVideo(object); - // break; + case "draw": + break; case "resize": commandResizeService( @@ -148,72 +81,22 @@ export class CommandController ); break; - // case "setBackgroundColor": - // $renderPlayer._$setBackgroundColor(object.buffer); - // break; - - // case "stop": - // $renderPlayer.stop(); - // break; - - // case "removeCache": - // $cacheStore.removeCache(object.id); - // break; - - // case "bitmapDraw": - // { - // const instances: Map> = $renderPlayer.instances; - // if (!instances.has(object.sourceId)) { - // continue; - // } - - // const instance: RenderDisplayObjectImpl = instances.get(object.sourceId); - - // const canvas: OffscreenCanvas = new $OffscreenCanvas( - // object.width, - // object.height - // ); - - // $renderPlayer._$bitmapDraw( - // instance, - // object.matrix || $MATRIX_ARRAY_IDENTITY, - // object.colorTransform || $COLOR_ARRAY_IDENTITY, - // canvas - // ); - - // const imageBitmap: ImageBitmap = canvas.transferToImageBitmap(); - // globalThis.postMessage({ - // "command": "bitmapDraw", - // "sourceId": object.sourceId, - // "imageBitmap": imageBitmap - // // @ts-ignore - // }, [imageBitmap]); - - // } - // break; - - // default: - // if (object.command.indexOf("shapeRecodes") > -1) { - // returnBuffer = false; - // const instanceId: number = +object.command.split("@")[1]; - // $renderPlayer._$registerShapeRecodes(instanceId, object.buffer); - // } - // break; + case "setBackgroundColor": + commandBackgroundColorService(object.buffer[0] as number); + break; - } + case "removeCache": + // todo + break; - // if (object.buffer && returnBuffer) { - // // this._$options.push(object.buffer.buffer); + case "bitmapDraw": + // todo + break; - // // globalThis.postMessage({ - // // "command": "renderBuffer", - // // "buffer": object.buffer - // // // @ts-ignore - // // }, this._$options); + default: + break; - // // reset - // this._$options.length = 0; - // } + } } this.state = "deactivate"; diff --git a/packages/renderer/src/RendererUtil.ts b/packages/renderer/src/RendererUtil.ts index d6151aba..d41e0ef7 100644 --- a/packages/renderer/src/RendererUtil.ts +++ b/packages/renderer/src/RendererUtil.ts @@ -99,20 +99,6 @@ export const $setWebGL2RenderingContext = (gl: WebGL2RenderingContext): void => */ export let $rendererWidth: number = 0; -/** - * @description 描画エリアの幅を設定 - * Set the width of the drawing area - * - * @param {number} width - * @return {void} - * @method - * @public - */ -export const $setRendererWidth = (width: number): void => -{ - $rendererWidth = width; -}; - /** * @type {number} * @public @@ -120,16 +106,18 @@ export const $setRendererWidth = (width: number): void => export let $rendererHeight: number = 0; /** - * @description 描画エリアの高さを設定 - * Set the height of the drawing area + * @description 描画エリアの幅を設定 + * Set the width of the drawing area * + * @param {number} width * @param {number} height * @return {void} * @method * @public */ -export const $setRendererHeight = (height: number): void => +export const $setRendererSize = (width: number, height: number): void => { + $rendererWidth = width; $rendererHeight = height; }; diff --git a/packages/webgl/src/CanvasToWebGLContext.ts b/packages/webgl/src/CanvasToWebGLContext.ts index bcd1d083..4846cd80 100644 --- a/packages/webgl/src/CanvasToWebGLContext.ts +++ b/packages/webgl/src/CanvasToWebGLContext.ts @@ -1108,7 +1108,7 @@ export class CanvasToWebGLContext * @method * @public */ - _$setColor ( + updateBackgroundColor ( r: number = 0, g: number = 0, b: number = 0, a: number = 0 ): void { From ebf87697708c21b4509ac2d3a4ac3bdd552a336c Mon Sep 17 00:00:00 2001 From: ienaga Date: Fri, 2 Aug 2024 22:16:01 +0900 Subject: [PATCH 032/343] =?UTF-8?q?#154=20display=E3=83=91=E3=83=83?= =?UTF-8?q?=E3=82=B1=E3=83=BC=E3=82=B8=E3=82=92=E7=A7=BB=E6=A4=8D(WIP)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/Canvas.ts | 22 + .../src/Canvas/CanvasRegisterEventService.ts | 63 + packages/core/src/Display.ts | 8 +- packages/core/src/Next2D/LoadService.ts | 4 +- packages/core/src/Player.ts | 299 +-- .../src/Player/PlayerReadyCompleteService.ts | 7 + .../src/Player/PlayerResizeEventService.ts | 37 +- .../Player/PlayerResizePostMessageService.ts | 17 +- packages/core/src/Text.ts | 5 +- packages/core/src/interface/DisplayImpl.ts | 6 +- packages/core/src/interface/TextImpl.ts | 2 + packages/display/src/BitmapData.ts | 21 - packages/display/src/DisplayObject.ts | 28 +- .../DisplayObjectBaseBuildService.ts | 43 + packages/display/src/Graphics.ts | 41 - packages/display/src/GraphicsBitmapFill.ts | 1 - packages/display/src/GraphicsGradientFill.ts | 13 - packages/display/src/Loader.ts | 11 +- .../display/src/Loader/LoaderBuildService.ts | 42 +- .../Loader/LoaderLoadEndEventService.test.ts | 23 +- .../src/Loader/LoaderLoadEndEventService.ts | 26 +- .../src/Loader/LoaderLoadJsonService.ts | 10 +- packages/display/src/LoopConfig.ts | 2 +- packages/display/src/MovieClip.ts | 1672 ++++++++--------- .../src/MovieClip/MovieClipBuildService.ts | 88 + packages/display/src/Shape.ts | 1029 +++++----- packages/display/src/Sprite.ts | 322 ++-- packages/display/src/index.ts | 4 +- .../src/interface/DictionaryTagImpl.ts | 1 + .../interface/MovieClipActionObjectImpl.ts | 5 + .../src/interface/MovieClipCharacterImpl.ts | 19 + .../src/interface/MovieClipLabelObjectImpl.ts | 4 + .../src/interface/MovieClipSoundObjectImpl.ts | 6 + .../display/src/interface/NoCodeDataImpl.ts | 4 +- packages/display/src/interface/ParentImpl.ts | 2 +- .../display/src/interface/SoundTagImpl.ts | 6 + packages/media/src/Sound.ts | 52 +- packages/media/src/interface/Character.ts | 3 + packages/media/src/interface/CharacterImpl.ts | 1 + packages/text/src/index.ts | 1 + packages/util/src/Util.ts | 2 +- 41 files changed, 1838 insertions(+), 2114 deletions(-) create mode 100644 packages/core/src/Canvas/CanvasRegisterEventService.ts create mode 100644 packages/core/src/Player/PlayerReadyCompleteService.ts create mode 100644 packages/display/src/DisplayObject/DisplayObjectBaseBuildService.ts create mode 100644 packages/display/src/MovieClip/MovieClipBuildService.ts create mode 100644 packages/display/src/interface/MovieClipActionObjectImpl.ts create mode 100644 packages/display/src/interface/MovieClipCharacterImpl.ts create mode 100644 packages/display/src/interface/MovieClipLabelObjectImpl.ts create mode 100644 packages/display/src/interface/MovieClipSoundObjectImpl.ts create mode 100644 packages/display/src/interface/SoundTagImpl.ts create mode 100644 packages/media/src/interface/Character.ts create mode 100644 packages/media/src/interface/CharacterImpl.ts diff --git a/packages/core/src/Canvas.ts b/packages/core/src/Canvas.ts index 4029a022..3ee42bb1 100644 --- a/packages/core/src/Canvas.ts +++ b/packages/core/src/Canvas.ts @@ -1,6 +1,25 @@ import { $devicePixelRatio } from "./CoreUtil"; import { execute as canvasInitializeService } from "./Canvas/CanvasInitializeService"; import { execute as canvasBootOffscreenCanvasService } from "./Canvas/CanvasBootOffscreenCanvasService"; +import { execute as canvasRegisterEventService } from "./Canvas/CanvasRegisterEventService"; + +/** + * @type {string} + * @public + */ +export const $POINTER_DOWN: string = "pointerdown"; + +/** + * @type {string} + * @public + */ +export const $POINTER_UP: string = "pointerup"; + +/** + * @type {string} + * @public + */ +export const $POINTER_MOVE: string = "pointermove"; /** * @type {HTMLCanvasElement} @@ -11,5 +30,8 @@ export const $canvas: HTMLCanvasElement = document.createElement("canvas"); // initial invoking function canvasInitializeService($canvas, $devicePixelRatio); +// Register an event +canvasRegisterEventService($canvas); + // Boot offscreen canvas canvasBootOffscreenCanvasService($canvas, $devicePixelRatio); \ No newline at end of file diff --git a/packages/core/src/Canvas/CanvasRegisterEventService.ts b/packages/core/src/Canvas/CanvasRegisterEventService.ts new file mode 100644 index 00000000..1b8e2a7d --- /dev/null +++ b/packages/core/src/Canvas/CanvasRegisterEventService.ts @@ -0,0 +1,63 @@ +import { + $POINTER_DOWN, + $POINTER_UP, + $POINTER_MOVE +} from "../Canvas"; + +/** + * + * @param {HTMLCanvasElement} canvas + * @return {void} + * @method + * @public + */ +export const execute = (canvas: HTMLCanvasElement): void => +{ + canvas.addEventListener($POINTER_DOWN, (event: PointerEvent): void => + { + // イベントの伝播を止める + event.preventDefault(); + event.stopPropagation(); + + // $setEvent(event); + // $setEventType($POINTER_DOWN); + + // // start position + // this._$hitTest(); + }); + + canvas.addEventListener($POINTER_UP, (event: PointerEvent): void => + { + // イベントの伝播を止める + event.preventDefault(); + event.stopPropagation(); + + const element: HTMLElement = event.target as HTMLElement; + if (!element) { + return ; + } + + element.releasePointerCapture(event.pointerId); + // $setEvent(event); + // $setEventType($POINTER_UP); + // this._$hitTest(); + }); + + canvas.addEventListener($POINTER_MOVE, (event: PointerEvent) => + { + // イベントの伝播を止める + event.preventDefault(); + event.stopPropagation(); + + const element: HTMLElement = event.target as HTMLElement; + if (!element) { + return ; + } + + element.setPointerCapture(event.pointerId); + // $setEvent(event); + // $setEventType($POINTER_MOVE); + + // this._$hitTest(); + }, { "passive": false }); +}; \ No newline at end of file diff --git a/packages/core/src/Display.ts b/packages/core/src/Display.ts index 98d10c0d..e61dd86d 100644 --- a/packages/core/src/Display.ts +++ b/packages/core/src/Display.ts @@ -5,13 +5,13 @@ import { BitmapData, BlendMode, DisplayObject, + DisplayObjectContainer, FrameLabel, Graphics, InteractiveObject, Loader, Shape, - Stage, - TextField + Stage } from "@next2d/display"; const display: DisplayImpl = { @@ -20,13 +20,13 @@ const display: DisplayImpl = { BitmapData, BlendMode, DisplayObject, + DisplayObjectContainer, FrameLabel, Graphics, InteractiveObject, Loader, Shape, - Stage, - TextField + Stage }; Object.entries(display).forEach(([key, DisplayClass]) => diff --git a/packages/core/src/Next2D/LoadService.ts b/packages/core/src/Next2D/LoadService.ts index 3b8a39e0..f148180c 100644 --- a/packages/core/src/Next2D/LoadService.ts +++ b/packages/core/src/Next2D/LoadService.ts @@ -9,6 +9,7 @@ import { Loader } from "@next2d/display"; import { execute as playerResizeEventService } from "../Player/PlayerResizeEventService"; import { execute as playerRemoveLoadingElementService } from "../Player/PlayerRemoveLoadingElementService"; import { execute as playerAppendCanvasElementService } from "../Player/PlayerAppendCanvasElementService"; +import { execute as playerReadyCompleteService } from "../Player/PlayerReadyCompleteService"; /** * @description 指定のURLからJSONファイルを読み込みます。 @@ -69,9 +70,10 @@ export const execute = async (url: string, options: PlayerOptionsImpl): Promise< // $stage.addChild(loaderInfo.content); // resize - playerResizeEventService($player); + playerResizeEventService(); // load complete playerRemoveLoadingElementService(); playerAppendCanvasElementService(); + playerReadyCompleteService(); }; \ No newline at end of file diff --git a/packages/core/src/Player.ts b/packages/core/src/Player.ts index 65d80315..e8750a48 100644 --- a/packages/core/src/Player.ts +++ b/packages/core/src/Player.ts @@ -582,17 +582,18 @@ export class Player this._$stopFlag = false; - // if (this._$timerId > -1) { - // cancelAnimationFrame(this._$timerId); - // } + if (this._$timerId > -1) { + cancelAnimationFrame(this._$timerId); + } - // this._$fps = 1000 / this._$frameRate | 0; + this._$fps = 1000 / this._$frameRate | 0; - // this._$startTime = performance.now(); - // this._$timerId = requestAnimationFrame(async (timestamp: number): Promise => - // { - // await this._$run(timestamp); - // }); + this._$startTime = performance.now(); + this._$timerId = requestAnimationFrame(async (timestamp: number): Promise => + { + // todo + // await this._$run(timestamp); + }); } /** @@ -679,29 +680,6 @@ export class Player playerResizeEventService(this); } - // /** - // * @return {void} - // * @method - // * @private - // */ - // _$updateLoadStatus (): void - // { - // if (this._$loadStatus === $LOAD_END) { - // if (this._$loadId > -1) { - // $cancelAnimationFrame(this._$loadId); - // } - - // this._$loadId = -1; - // this._$loaded(); - // return ; - // } - - // this._$loadId = $requestAnimationFrame(() => - // { - // this._$updateLoadStatus(); - // }); - // } - // /** // * @return {void} // * @method @@ -774,100 +752,6 @@ export class Player // } - // /** - // * @return {void} - // * @method - // * @private - // */ - // _$initialize (): void - // { - // if (!this._$tagId) { - - // $document - // .body - // .insertAdjacentHTML( - // "beforeend", `
` - // ); - - // } else { - - // const container: HTMLElement | null = $document.getElementById(this._$tagId); - // if (!container) { - // alert("Not Found Tag ID:" + this._$tagId); - // return ; - // } - - // const div: HTMLElement | null = $document.getElementById($PREFIX); - // if (!div) { - - // const element: HTMLDivElement = $document.createElement("div"); - // element.id = $PREFIX; - // element.tabIndex = -1; - // container.appendChild(element); - - // } else { - - // this._$deleteNode(); - - // } - - // } - - // const element: HTMLElement | null = $document.getElementById($PREFIX); - // if (!element) { - // throw new Error("the content element is null."); - // } - - // const parent: HTMLElement | null = element.parentElement; - // if (parent) { - - // this._$initStyle(element); - // this._$buildWait(); - - // const width: number = this._$fixedWidth - // ? this._$fixedWidth - // : parent.tagName === "BODY" - // ? window.innerWidth - // : parent.clientWidth; - - // const height: number = this._$fixedHeight - // ? this._$fixedHeight - // : parent.tagName === "BODY" - // ? window.innerHeight - // : parent.clientHeight; - - // // set center - // if (this._$mode === "loader" && width && height) { - // this._$baseWidth = width; - // this._$baseHeight = height; - // this._$resize(); - // } - // } - - // if (this._$mode === "loader") { - // this._$loadStatus = $LOAD_START; - // this._$updateLoadStatus(); - // } else { - // this._$resize(); - // this._$loaded(); - // } - // } - - // /** - // * @returns {void} - // * @method - // * @private - // */ - // _$deleteNode (): void - // { - // const element: HTMLElement | null = $document.getElementById($PREFIX); - // if (element) { - // while (element.childNodes.length) { - // element.removeChild(element.childNodes[0]); - // } - // } - // } - // // @ts-ignore // this._$canvas.addEventListener($TOUCH_START, (event: TouchEvent) => // { @@ -971,169 +855,6 @@ export class Player // }, { "passive": false }); // } - // /** - // * @return {void} - // * @method - // * @private - // */ - // _$resize (): void - // { - // const div: HTMLElement | null = $document - // .getElementById($PREFIX); - - // if (div) { - - // const parent: HTMLElement | null = div.parentElement; - // if (!parent) { - // throw new Error("the parentElement is null."); - // } - - // const innerWidth: number = this._$fixedWidth - // ? this._$fixedWidth - // : parent.tagName === "BODY" - // ? window.innerWidth - // : parent.clientWidth; - - // const innerHeight: number = this._$fixedHeight - // ? this._$fixedHeight - // : parent.tagName === "BODY" - // ? window.innerHeight - // : parent.clientHeight; - - // const screenWidth: number = parent.tagName === "BODY" - // ? $window.innerWidth - // : parent.offsetWidth; - - // const scale: number = $Math.min( - // innerWidth / this._$baseWidth, - // innerHeight / this._$baseHeight - // );z - - // let width: number = this._$fullScreen - // ? innerWidth - // : this._$baseWidth * scale | 0; - - // let height: number = this._$fullScreen - // ? innerHeight - // : this._$baseHeight * scale | 0; - - // // div - // const style: CSSStyleDeclaration = div.style; - // style.width = `${width}px`; - // style.height = `${height}px`; - // style.top = "0"; - // style.left = this._$fullScreen - // ? "0" - // : `${screenWidth / 2 - width / 2}px`; - - // width *= $devicePixelRatio; - // height *= $devicePixelRatio; - - // // no resize - // if (this._$width === width && this._$height === height) { - // return ; - // } - - // // cache reset - // this._$stage._$doChanged(); - // $cacheStore.reset(); - - // // params - // this._$scale = scale; - // this._$width = width; - // this._$height = height; - - // const mScale: number = this._$scale * $devicePixelRatio; - // this._$matrix[0] = mScale; - // this._$matrix[3] = mScale; - - // if (this._$fullScreen) { - - // const tx = (width - - // this._$baseWidth - // * scale - // * $devicePixelRatio) / 2; - - // const ty = (height - - // this._$baseHeight - // * scale - // * $devicePixelRatio) / 2; - - // this._$matrix[4] = tx; - // this._$matrix[5] = ty; - - // } - - // // main canvas resize - // this._$resizeCanvas(width, height, mScale, this._$matrix[4], this._$matrix[5]); - - // if (div.children.length > 1) { - // div.children[1].dispatchEvent( - // new Event(`${$PREFIX}_blur`) - // ); - // } - // } - // } - - // /** - // * @description 表示用のcanvasを更新 - // * Update canvas for display - // * - // * @param {string} [background_color=transparent] - // * @return {void} - // * @method - // * @public - // */ - // _$setBackgroundColor (background_color: string = "transparent"): void - // { - // if ($rendererWorker) { - - // const buffer: Float32Array = $getRenderBufferArray(); - - // buffer[0] = background_color === "transparent" - // ? -1 - // : $toColorInt(background_color); - - // const message: PropertyMessageMapImpl = $getRenderMessageObject(); - // message.command = "setBackgroundColor"; - // message.buffer = buffer; - - // const options: ArrayBuffer[] = $getArray(buffer.buffer); - - // $rendererWorker.postMessage(message, options); - - // $poolRenderMessageObject(message); - // $poolArray(options); - - // } else { - - // const context: CanvasToWebGLContext | null = this._$context; - // if (!context) { - // return ; - // } - - // if (background_color === "transparent") { - - // context._$setColor(0, 0, 0, 0); - - // } else { - - // const color: RGBAImpl = $uintToRGBA( - // $toColorInt(background_color) - // ); - - // context._$setColor( - // color.R / 255, - // color.G / 255, - // color.B / 255, - // 1 - // ); - - // } - - // } - // } - // /** // * @param {Event} event // * @return {boolean} diff --git a/packages/core/src/Player/PlayerReadyCompleteService.ts b/packages/core/src/Player/PlayerReadyCompleteService.ts new file mode 100644 index 00000000..6d06bfce --- /dev/null +++ b/packages/core/src/Player/PlayerReadyCompleteService.ts @@ -0,0 +1,7 @@ +// import { $player } from "../Player"; + +export const execute = (): void => +{ + // + // $player.play(); +}; \ No newline at end of file diff --git a/packages/core/src/Player/PlayerResizeEventService.ts b/packages/core/src/Player/PlayerResizeEventService.ts index 0e6bf4db..f4843d29 100644 --- a/packages/core/src/Player/PlayerResizeEventService.ts +++ b/packages/core/src/Player/PlayerResizeEventService.ts @@ -1,23 +1,20 @@ -import type { Player } from "../Player"; +import { $player } from "../Player"; import { execute as playerResizePostMessageService } from "./PlayerResizePostMessageService"; import { $PREFIX, $devicePixelRatio } from "../CoreUtil"; -import { $canvas } from "../Canvas"; /** * @description 画面リサイズ時にcanvasのリサイズを行う * Resize the canvas when resizing the screen * - * @param {Player} player * @return {void} * @method * @protected */ -export const execute = (player: Player): void => +export const execute = (): void => { - const element: HTMLElement | null = document .getElementById($PREFIX); @@ -30,11 +27,11 @@ export const execute = (player: Player): void => return ; } - const screenWidth: number = player.fullScreen || parent.tagName === "BODY" + const screenWidth: number = $player.fullScreen || parent.tagName === "BODY" ? window.innerWidth : parent.clientWidth; - const screenHeight: number = player.fullScreen || parent.tagName === "BODY" + const screenHeight: number = $player.fullScreen || parent.tagName === "BODY" ? window.innerHeight : parent.clientHeight; @@ -42,37 +39,37 @@ export const execute = (player: Player): void => style.width = `${screenWidth}px`; style.height = `${screenHeight}px`; - if (!player.stageWidth || !player.stageHeight) { + if (!$player.stageWidth || !$player.stageHeight) { return ; } const scale: number = Math.min( - screenWidth / player.stageWidth, - screenHeight / player.stageHeight + screenWidth / $player.stageWidth, + screenHeight / $player.stageHeight ); - const width: number = player.fullScreen + const width: number = $player.fullScreen ? window.innerWidth * $devicePixelRatio - : player.stageWidth * scale * $devicePixelRatio | 0; + : $player.stageWidth * scale * $devicePixelRatio | 0; - const height: number = player.fullScreen + const height: number = $player.fullScreen ? window.innerHeight * $devicePixelRatio - : player.stageHeight * scale * $devicePixelRatio | 0; + : $player.stageHeight * scale * $devicePixelRatio | 0; // 同じサイズの場合は、ここれで終了 - if (width === player.rendererWidth - && height === player.rendererHeight + if (width === $player.rendererWidth + && height === $player.rendererHeight ) { return ; } // update - player.rendererScale = scale; - player.rendererWidth = width; - player.rendererHeight = height; + $player.rendererScale = scale; + $player.rendererWidth = width; + $player.rendererHeight = height; // worker postMessage - playerResizePostMessageService(player); + playerResizePostMessageService(); if (element.children.length > 1) { element.children[1].dispatchEvent( diff --git a/packages/core/src/Player/PlayerResizePostMessageService.ts b/packages/core/src/Player/PlayerResizePostMessageService.ts index ef37ae27..9b38ee75 100644 --- a/packages/core/src/Player/PlayerResizePostMessageService.ts +++ b/packages/core/src/Player/PlayerResizePostMessageService.ts @@ -1,5 +1,5 @@ -import type { Player } from "../Player"; import type { ResizeMessageImpl } from "../interface/ResizeMessageImpl"; +import { $player } from "../Player"; import { $rendererWorker } from "../CoreUtil"; /** @@ -27,21 +27,20 @@ const options: Transferable[] = []; * @description 画面リサイズ情報をworkerに送る * Send screen resize information to worker * - * @param {Player} player * @return {void} * @method * @protected */ -export const execute = (player: Player): void => +export const execute = (): void => { // postMessage message.buffer = new Float32Array([ - player.rendererScale, - player.rendererWidth, - player.rendererHeight, - player.stageWidth, - player.stageHeight, - player.fullScreen ? 1 : 0 + $player.rendererScale, + $player.rendererWidth, + $player.rendererHeight, + $player.stageWidth, + $player.stageHeight, + $player.fullScreen ? 1 : 0 ]); options[0] = message.buffer.buffer; diff --git a/packages/core/src/Text.ts b/packages/core/src/Text.ts index 2d27bd7c..1e513e6f 100644 --- a/packages/core/src/Text.ts +++ b/packages/core/src/Text.ts @@ -1,8 +1,9 @@ import type { TextImpl } from "./interface/TextImpl"; -import { TextFormat } from "@next2d/text"; +import { TextFormat, TextField } from "@next2d/text"; const text: TextImpl = { - TextFormat + TextFormat, + TextField }; Object.entries(text).forEach(([key, TextClass]) => diff --git a/packages/core/src/interface/DisplayImpl.ts b/packages/core/src/interface/DisplayImpl.ts index 099ea16e..61548b5e 100644 --- a/packages/core/src/interface/DisplayImpl.ts +++ b/packages/core/src/interface/DisplayImpl.ts @@ -2,6 +2,7 @@ import type { BitmapData, BlendMode, DisplayObject, + DisplayObjectContainer, FrameLabel, Graphics, InteractiveObject, @@ -9,13 +10,13 @@ import type { MovieClip, Shape, Sprite, - Stage, - TextField + Stage } from "@next2d/display"; export interface DisplayImpl { BitmapData: typeof BitmapData; BlendMode: typeof BlendMode; DisplayObject: typeof DisplayObject; + DisplayObjectContainer: typeof DisplayObjectContainer; FrameLabel: typeof FrameLabel; Graphics: typeof Graphics; InteractiveObject: typeof InteractiveObject; @@ -24,5 +25,4 @@ export interface DisplayImpl { Shape: typeof Shape; Sprite: typeof Sprite; Stage: typeof Stage; - TextField: typeof TextField; } diff --git a/packages/core/src/interface/TextImpl.ts b/packages/core/src/interface/TextImpl.ts index f299d84d..585f0205 100644 --- a/packages/core/src/interface/TextImpl.ts +++ b/packages/core/src/interface/TextImpl.ts @@ -1,5 +1,7 @@ import type { TextFormat } from "@next2d/text"; +import type { TextField } from "@next2d/text"; export interface TextImpl { TextFormat: typeof TextFormat; + TextField: typeof TextField; } \ No newline at end of file diff --git a/packages/display/src/BitmapData.ts b/packages/display/src/BitmapData.ts index 59f81355..998606d1 100644 --- a/packages/display/src/BitmapData.ts +++ b/packages/display/src/BitmapData.ts @@ -1,31 +1,10 @@ import { DisplayObjectContainer } from "./DisplayObjectContainer"; import type { Player } from "@next2d/core"; import type { CanvasToWebGLContext } from "@next2d/webgl"; -import type { - DisplayObjectImpl, - PropertyBitmapDataMessageImpl -} from "@next2d/interface"; import type { Matrix, ColorTransform } from "@next2d/geom"; -import { - $COLOR_ARRAY_IDENTITY, - $getArray, - $MATRIX_ARRAY_IDENTITY, - $multiplicationMatrix, - $poolArray, - $cacheStore -} from "@next2d/share"; -import { - $getInstanceId, - $bitmapDrawMap, - $currentPlayer, - $poolColorTransform, - $poolMatrix, - $postContainerWorker, - $rendererWorker -} from "@next2d/util"; /** * BitmapData クラスを使用すると、Bitmap オブジェクトのデータ (ピクセル) を処理できます。 diff --git a/packages/display/src/DisplayObject.ts b/packages/display/src/DisplayObject.ts index f888c913..e8798a6d 100644 --- a/packages/display/src/DisplayObject.ts +++ b/packages/display/src/DisplayObject.ts @@ -576,20 +576,20 @@ export class DisplayObject extends EventDispatcher // } // } - // /** - // * @description この表示オブジェクトが属するファイルの読み込み情報を含む LoaderInfo オブジェクトを返します。 - // * Returns a LoaderInfo object containing information - // * about loading the file to which this display object belongs. - // * - // * @member {LoaderInfo} - // * @default null - // * @readonly - // * @public - // */ - // get loaderInfo (): LoaderInfo | null - // { - // return this._$loaderInfo; - // } + /** + * @description この表示オブジェクトが属するファイルの読み込み情報を含む LoaderInfo オブジェクトを返します。 + * Returns a LoaderInfo object containing information + * about loading the file to which this display object belongs. + * + * @member {LoaderInfo} + * @default null + * @readonly + * @public + */ + get loaderInfo (): LoaderInfo | null + { + return this._$loaderInfo; + } // /** // * @description 呼び出し元の表示オブジェクトは、指定された mask オブジェクトによってマスクされます。 diff --git a/packages/display/src/DisplayObject/DisplayObjectBaseBuildService.ts b/packages/display/src/DisplayObject/DisplayObjectBaseBuildService.ts new file mode 100644 index 00000000..51162b76 --- /dev/null +++ b/packages/display/src/DisplayObject/DisplayObjectBaseBuildService.ts @@ -0,0 +1,43 @@ +import type { DisplayObjectImpl } from "../interface/DisplayObjectImpl"; +import type { DictionaryTagImpl } from "../interface/DictionaryTagImpl"; +import type { ParentImpl } from "../interface/ParentImpl"; +import type { Character } from "../interface/Character"; +import type { LoaderInfo } from "../LoaderInfo"; + +/** + * @description DisplayObjectの基礎となる情報を設定、個別のCharacterを返却 + * Sets the underlying information for DisplayObject and returns individual Character + * + * @param {DisplayObject} display_object + * @param {object} tag + * @param {DisplayObjectContainer} parent + * @return {void} + * @method + * @public + */ +export const execute = ( + display_object: DisplayObjectImpl, + tag: DictionaryTagImpl, + parent: ParentImpl +): Character => { + + const loaderInfo = parent._$loaderInfo as LoaderInfo; + if (!loaderInfo || !loaderInfo.data) { + throw new Error("the loaderInfo or data is nul."); + } + + // setup + display_object._$parent = parent; + display_object._$root = parent._$root; + display_object._$stage = parent._$stage; + display_object._$loaderInfo = loaderInfo; + + // bind tag data + display_object._$characterId = tag.characterId | 0; + display_object._$clipDepth = tag.clipDepth | 0; + display_object._$startFrame = tag.startFrame | 0; + display_object._$endFrame = tag.endFrame | 0; + display_object._$name = tag.name || ""; + + return loaderInfo.data.characters[tag.characterId]; +}; \ No newline at end of file diff --git a/packages/display/src/Graphics.ts b/packages/display/src/Graphics.ts index 58e69c3d..55c61999 100644 --- a/packages/display/src/Graphics.ts +++ b/packages/display/src/Graphics.ts @@ -3,52 +3,11 @@ import { GraphicsGradientFill } from "./GraphicsGradientFill"; import type { BitmapData } from "./BitmapData"; import type { Player } from "@next2d/core"; import type { Matrix, Rectangle } from "@next2d/geom"; -import type { - GraphicsParentImpl, - CapsStyleImpl, - JointStyleImpl, - FilterArrayImpl, - BlendModeImpl, - BoundsImpl, - DisplayObjectImpl, - AttachmentImpl, - PlayerHitObjectImpl, - ColorStopImpl, - SpreadMethodImpl, - GradientTypeImpl, - InterpolationMethodImpl, - CachePositionImpl, - ShapeModeImpl, - GridImpl -} from "@next2d/interface"; import type { CanvasToWebGLContext, FrameBufferManager, CanvasGradientToWebGL } from "@next2d/webgl"; -import { $currentPlayer } from "@next2d/util"; -import { - $cacheStore, - $doUpdated, - $Math, - $Number, - $getArray, - $poolArray, - $toColorInt, - $intToRGBA, - $clamp, - $boundsMatrix, - $poolBoundsObject, - $Infinity, - $getFloat32Array6, - $multiplicationMatrix, - $poolFloat32Array6, - $getBoundsObject, - $Float32Array, - $getFloat32Array4, - $getInt32Array4, - $linearGradientXY -} from "@next2d/share"; /** * Graphics クラスには、ベクターシェイプの作成に使用できる一連のメソッドがあります。 diff --git a/packages/display/src/GraphicsBitmapFill.ts b/packages/display/src/GraphicsBitmapFill.ts index b0969972..f36766b9 100644 --- a/packages/display/src/GraphicsBitmapFill.ts +++ b/packages/display/src/GraphicsBitmapFill.ts @@ -1,6 +1,5 @@ import type { BitmapData } from "./BitmapData"; import type { Matrix } from "@next2d/geom"; -import { $getArray } from "@next2d/share"; /** * ビットマップ塗りを定義します。ビットマップは、スムージング、繰り返し、 diff --git a/packages/display/src/GraphicsGradientFill.ts b/packages/display/src/GraphicsGradientFill.ts index 38243361..f4dd6b49 100644 --- a/packages/display/src/GraphicsGradientFill.ts +++ b/packages/display/src/GraphicsGradientFill.ts @@ -1,17 +1,4 @@ import type { Matrix } from "@next2d/geom"; -import type { - ColorStopImpl, - GradientTypeImpl, - SpreadMethodImpl, - InterpolationMethodImpl -} from "@next2d/interface"; -import { - $colorStringToInt, - $getArray, - $intToRGBA, - $Math, - $MATRIX_ARRAY_IDENTITY -} from "@next2d/share"; /** * グラデーション塗りを定義します。 diff --git a/packages/display/src/Loader.ts b/packages/display/src/Loader.ts index c62d49cf..71f4f67f 100644 --- a/packages/display/src/Loader.ts +++ b/packages/display/src/Loader.ts @@ -1,5 +1,7 @@ import type { ParentImpl } from "./interface/ParentImpl"; import type { Sprite } from "./Sprite"; +import type { NoCodeDataImpl } from "./interface/NoCodeDataImpl"; +import type { NoCodeDataZlibImpl } from "./interface/NoCodeDataZlibImpl"; import { DisplayObjectContainer } from "./DisplayObjectContainer"; import { LoaderInfo } from "./LoaderInfo"; import { MovieClip } from "./MovieClip"; @@ -162,7 +164,7 @@ export class Loader extends DisplayObjectContainer }, "loadend": async (event: ProgressEvent): Promise => { - await loaderLoadEndEventService(loaderInfo, event); + await loaderLoadEndEventService(this, event); resolve(); } } @@ -174,15 +176,14 @@ export class Loader extends DisplayObjectContainer * @description NoCodeToolのJSONを直接読み込む * Read JSON directly from NoCodeTool * - * @param {string} json + * @param {object} json * @return {void} * @method * @public */ - async loadJSON (json: string): Promise + async loadJSON (json: NoCodeDataImpl | NoCodeDataZlibImpl): Promise { - const loaderInfo = this._$loaderInfo as NonNullable; - await loaderLoadJsonService(loaderInfo, json); + await loaderLoadJsonService(this, json); } /** diff --git a/packages/display/src/Loader/LoaderBuildService.ts b/packages/display/src/Loader/LoaderBuildService.ts index d10bb0bd..cdcb87bd 100644 --- a/packages/display/src/Loader/LoaderBuildService.ts +++ b/packages/display/src/Loader/LoaderBuildService.ts @@ -1,7 +1,19 @@ +import { DictionaryTagImpl } from "../interface/DictionaryTagImpl"; import type { NoCodeDataImpl } from "../interface/NoCodeDataImpl"; -import type { LoaderInfo } from "../LoaderInfo"; +import type { Loader } from "../Loader"; +import { execute as movieClipBuildService } from "../MovieClip/MovieClipBuildService"; -export const execute = async (loader_info: LoaderInfo, object: NoCodeDataImpl): Promise => +/** + * @description 読み込んだJSONオブジェクトからMovieClipを作成 + * Create a MovieClip from a loaded JSON object + * + * @param {Loader} loader + * @param {object} object + * @return {Promise} + * @method + * @protected + */ +export const execute = async (loader: Loader, object: NoCodeDataImpl): Promise => { const symbols: Map = new Map(); if (object.symbols.length) { @@ -13,23 +25,21 @@ export const execute = async (loader_info: LoaderInfo, object: NoCodeDataImpl): } } - loader_info.data = { + const loaderInfo = loader.contentLoaderInfo; + loaderInfo.data = { "stage": object.stage, "characters": object.characters, "symbols": symbols }; - // setup - // loader_info.content = new MovieClip(); - // console.log(object); - - // build root - // const root: MovieClipCharacterImpl = object.characters[0]; - // loaderInfo._$content._$build({ - // "characterId": 0, - // "clipDepth": 0, - // "depth": 0, - // "endFrame": root.controller.length, - // "startFrame": 1 - // }, this); + // build root content + loaderInfo.content = await movieClipBuildService({ + "characterId": 0, + "name": "main", + "clipDepth": 0, + "depth": 0, + "endFrame": object.characters[0].controller.length, + "startFrame": 1 + }, loader); + console.log(loaderInfo); }; \ No newline at end of file diff --git a/packages/display/src/Loader/LoaderLoadEndEventService.test.ts b/packages/display/src/Loader/LoaderLoadEndEventService.test.ts index df6b859e..6eae62c9 100644 --- a/packages/display/src/Loader/LoaderLoadEndEventService.test.ts +++ b/packages/display/src/Loader/LoaderLoadEndEventService.test.ts @@ -1,6 +1,7 @@ import { Loader } from "../Loader"; import { execute } from "./LoaderLoadEndEventService"; import { + Event, IOErrorEvent, ProgressEvent as Next2DProgressEvent } from "@next2d/events"; @@ -8,7 +9,7 @@ import { describe, expect, it, vi } from "vitest"; describe("LoaderLoadEndEventService.js test", () => { - it("execute test case1", () => + it("execute test case1", async () => { const loader = new Loader(); @@ -24,6 +25,15 @@ describe("LoaderLoadEndEventService.js test", () => total = event.bytesTotal; }); + let completeState = ""; + loader + .contentLoaderInfo + .addEventListener(Event.COMPLETE, (event: Event): void => + { + completeState = event.type; + }); + + expect(completeState).toBe(""); expect(openState).toBe(""); expect(loaded).toBe(0); expect(total).toBe(0); @@ -36,7 +46,11 @@ describe("LoaderLoadEndEventService.js test", () => "fps": 60, "bgColor": "#ffffff" }, - "characters": [], + "characters": [ + { + "controller": [1,2,3] + } + ], "symbols": [] }; @@ -54,8 +68,9 @@ describe("LoaderLoadEndEventService.js test", () => } as unknown as ProgressEvent; }); - execute(loader.contentLoaderInfo, new MockEvent()); + await execute(loader, new MockEvent()); + expect(completeState).toBe(Event.COMPLETE); expect(openState).toBe(Next2DProgressEvent.PROGRESS); }); @@ -86,7 +101,7 @@ describe("LoaderLoadEndEventService.js test", () => } as unknown as ProgressEvent; }); - execute(loader.contentLoaderInfo, new MockEvent()); + execute(loader, new MockEvent()); expect(openState).toBe(IOErrorEvent.IO_ERROR); }); diff --git a/packages/display/src/Loader/LoaderLoadEndEventService.ts b/packages/display/src/Loader/LoaderLoadEndEventService.ts index 73f6ac72..00ae9999 100644 --- a/packages/display/src/Loader/LoaderLoadEndEventService.ts +++ b/packages/display/src/Loader/LoaderLoadEndEventService.ts @@ -1,7 +1,8 @@ -import type { LoaderInfo } from "../LoaderInfo"; +import { Loader } from "../Loader"; import { $headerStringToArray } from "../DisplayObjectUtil"; import { execute as loaderLoadJsonService } from "./LoaderLoadJsonService"; import { + Event, ProgressEvent as Next2DProgressEvent, IOErrorEvent, HTTPStatusEvent @@ -11,34 +12,35 @@ import { * @description 外部JSONのローディング完了イベントの実行関数 * Execution function for external JSON loading completion event * - * @param {LoaderInfo} loader_info + * @param {Loader} loader * @param {ProgressEvent} event * @return {Promise} * @method * @public */ -export const execute = async (loader_info: LoaderInfo, event: ProgressEvent): Promise => +export const execute = async (loader: Loader, event: ProgressEvent): Promise => { const target = event.target as XMLHttpRequest; if (!target) { return ; } - if (loader_info.willTrigger(Next2DProgressEvent.PROGRESS)) { - loader_info.dispatchEvent(new Next2DProgressEvent( + const loaderInfo = loader.contentLoaderInfo; + if (loaderInfo.willTrigger(Next2DProgressEvent.PROGRESS)) { + loaderInfo.dispatchEvent(new Next2DProgressEvent( Next2DProgressEvent.PROGRESS, false, false, event.loaded, event.total )); } // http status event - if (loader_info.willTrigger(HTTPStatusEvent.HTTP_STATUS)) { + if (loaderInfo.willTrigger(HTTPStatusEvent.HTTP_STATUS)) { const responseHeaders = $headerStringToArray( target.getAllResponseHeaders() ); - loader_info.dispatchEvent(new HTTPStatusEvent( + loaderInfo.dispatchEvent(new HTTPStatusEvent( HTTPStatusEvent.HTTP_STATUS, false, false, target.status, target.responseURL, responseHeaders @@ -46,10 +48,14 @@ export const execute = async (loader_info: LoaderInfo, event: ProgressEvent): Pr } if (199 < target.status && 400 > target.status) { - await loaderLoadJsonService(loader_info, target.response); + await loaderLoadJsonService(loader, target.response); + + if (loaderInfo.willTrigger(Event.COMPLETE)) { + loaderInfo.dispatchEvent(new Event(Event.COMPLETE)); + } } else { - if (loader_info.willTrigger(IOErrorEvent.IO_ERROR)) { - loader_info.dispatchEvent(new IOErrorEvent( + if (loaderInfo.willTrigger(IOErrorEvent.IO_ERROR)) { + loaderInfo.dispatchEvent(new IOErrorEvent( IOErrorEvent.IO_ERROR, false, false, target.statusText )); } diff --git a/packages/display/src/Loader/LoaderLoadJsonService.ts b/packages/display/src/Loader/LoaderLoadJsonService.ts index 9f7f6709..f42c445e 100644 --- a/packages/display/src/Loader/LoaderLoadJsonService.ts +++ b/packages/display/src/Loader/LoaderLoadJsonService.ts @@ -1,6 +1,6 @@ import type { NoCodeDataImpl } from "../interface/NoCodeDataImpl"; import type { NoCodeDataZlibImpl } from "../interface/NoCodeDataZlibImpl"; -import type { LoaderInfo } from "../LoaderInfo"; +import type { Loader } from "../Loader"; import { execute as loaderBuildService } from "./LoaderBuildService"; // @ts-ignore @@ -16,20 +16,20 @@ const worker: Worker = new ZlibInflateWorker(); * @description JSONオブジェクトがzlib圧縮されている場合はworkerで解凍、無圧縮ならビルド処理を実行 * If the JSON object is zlib compressed, decompress it with a worker, otherwise execute the build process * - * @param {LoaderInfo} loader_info + * @param {Loader} loader * @param {object} object * @return {Promise} * @method * @public */ -export const execute = async (loader_info: LoaderInfo, object: NoCodeDataImpl | NoCodeDataZlibImpl): Promise => +export const execute = async (loader: Loader, object: NoCodeDataImpl | NoCodeDataZlibImpl): Promise => { if (object.type === "zlib") { await new Promise((resolve): void => { worker.onmessage = async (event: MessageEvent): Promise => { - await loaderBuildService(loader_info, event.data as NoCodeDataImpl); + await loaderBuildService(loader, event.data as NoCodeDataImpl); resolve(); }; @@ -37,6 +37,6 @@ export const execute = async (loader_info: LoaderInfo, object: NoCodeDataImpl | worker.postMessage(buffer, [buffer.buffer]); }); } else { - await loaderBuildService(loader_info, object as NoCodeDataImpl); + await loaderBuildService(loader, object as NoCodeDataImpl); } }; \ No newline at end of file diff --git a/packages/display/src/LoopConfig.ts b/packages/display/src/LoopConfig.ts index 2bbd56e4..163c4e84 100644 --- a/packages/display/src/LoopConfig.ts +++ b/packages/display/src/LoopConfig.ts @@ -1,4 +1,4 @@ -import { $clamp } from "@next2d/share"; +// import { $clamp } from "./DisplayObjectUtil"; /** * LoopConfig クラスで、MovieClipのフレームヘッダーの移動方法を指定できます。 diff --git a/packages/display/src/MovieClip.ts b/packages/display/src/MovieClip.ts index 7d24b4c3..ff027bcd 100644 --- a/packages/display/src/MovieClip.ts +++ b/packages/display/src/MovieClip.ts @@ -1,45 +1,19 @@ import { Sprite } from "./Sprite"; import { FrameLabel } from "./FrameLabel"; -import { Event } from "@next2d/events"; import { Sound } from "@next2d/media"; import type { SoundTransform } from "@next2d/media"; -import type { Player } from "@next2d/core"; -import type { - PlaceObjectImpl, - LoopConfigImpl, - DisplayObjectImpl, - ParentImpl, - MovieClipCharacterImpl, - MovieClipSoundObjectImpl, - MovieClipActionObjectImpl, - MovieClipLabelObjectImpl, - DictionaryTagImpl, - Character -} from "@next2d/interface"; -import { - $setCurrentLoaderInfo, - $currentPlayer, - $rendererWorker -} from "@next2d/util"; -import { - $Array, - $getArray, - $getMap, - $isNaN, - $Math -} from "@next2d/share"; /** - * MovieClip クラスは、Sprite、DisplayObjectContainer、InteractiveObject、DisplayObject - * および EventDispatcher クラスを継承します。 - * MovieClip オブジェクトには、Sprite オブジェクトとは違ってタイムラインがあります。 - * タイムラインの再生ヘッドが停止されても、その MovieClip オブジェクトの子 MovieClip オブジェクトの再生ヘッドは停止しません。 + * @description MovieClip クラスは、Sprite、DisplayObjectContainer、InteractiveObject、DisplayObject + * および EventDispatcher クラスを継承します。 + * MovieClip オブジェクトには、Sprite オブジェクトとは違ってタイムラインがあります。 + * タイムラインの再生ヘッドが停止されても、その MovieClip オブジェクトの子 MovieClip オブジェクトの再生ヘッドは停止しません。 * - * The MovieClip class inherits from the following classes: Sprite, DisplayObjectContainer, - * InteractiveObject, DisplayObject, and EventDispatcher. - * Unlike the Sprite object, a MovieClip object has a timeline. - * When the playback head of the timeline is stopped, - * the playback head of the child MovieClip object of that MovieClip object will not be stopped. + * The MovieClip class inherits from the following classes: Sprite, DisplayObjectContainer, + * InteractiveObject, DisplayObject, and EventDispatcher. + * Unlike the Sprite object, a MovieClip object has a timeline. + * When the playback head of the timeline is stopped, + * the playback head of the child MovieClip object of that MovieClip object will not be stopped. * * @class * @memberOf next2d.display @@ -60,8 +34,8 @@ export class MovieClip extends Sprite public _$actionLimit: number; public _$totalFrames: number; public _$isPlaying: boolean; - public _$loopConfig: LoopConfigImpl | null; - private _$tweenFrame: number; + // public _$loopConfig: LoopConfigImpl | null; + // private _$tweenFrame: number; /** * @constructor @@ -103,13 +77,13 @@ export class MovieClip extends Sprite * @type {Map} * @private */ - this._$actions = $getMap(); + this._$actions = new Map(); /** * @type {Map} * @private */ - this._$frameCache = $getMap(); + this._$frameCache = new Map(); /** * @type {Map} @@ -122,7 +96,7 @@ export class MovieClip extends Sprite * @type {Map} * @private */ - this._$sounds = $getMap(); + this._$sounds = new Map(); /** * @type {number} @@ -159,19 +133,19 @@ export class MovieClip extends Sprite */ this._$isPlaying = false; - /** - * @type {LoopConfig} - * @default null - * @private - */ - this._$loopConfig = null; - - /** - * @type {number} - * @default 0 - * @private - */ - this._$tweenFrame = 0; + // /** + // * @type {LoopConfig} + // * @default null + // * @private + // */ + // this._$loopConfig = null; + + // /** + // * @type {number} + // * @default 0 + // * @private + // */ + // this._$tweenFrame = 0; } /** @@ -179,7 +153,7 @@ export class MovieClip extends Sprite * Returns the string representation of the specified class. * * @return {string} - * @default [class MovieClip] + * @default "[class MovieClip]" * @method * @static */ @@ -193,7 +167,7 @@ export class MovieClip extends Sprite * Returns the space name of the specified class. * * @return {string} - * @default next2d.display.MovieClip + * @default "next2d.display.MovieClip" * @const * @static */ @@ -207,7 +181,7 @@ export class MovieClip extends Sprite * Returns the string representation of the specified object. * * @return {string} - * @default [object MovieClip] + * @default "[object MovieClip]" * @method * @public */ @@ -221,7 +195,7 @@ export class MovieClip extends Sprite * Returns the space name of the specified object. * * @return {string} - * @default next2d.display.MovieClip + * @default "next2d.display.MovieClip" * @const * @public */ @@ -279,7 +253,7 @@ export class MovieClip extends Sprite { return !this._$labels || !this._$labels.size ? null - : $Array.from(this._$labels.values()); + : Array.from(this._$labels.values()); } /** @@ -310,124 +284,124 @@ export class MovieClip extends Sprite return this._$totalFrames; } - /** - * @description MovieClipのフレームヘッダーの移動方法の設定オブジェクトを返します。 - * Returns a configuration object for how MovieClip's frame headers are moved. - * - * @member {object} - * @default null - * @public - */ - get loopConfig (): LoopConfigImpl | null - { - if (this._$loopConfig) { - return this._$loopConfig; - } - - const place: PlaceObjectImpl | null = this._$placeObject || this._$getPlaceObject(); - if (!place || !place.loop) { - return null; - } - - if (this._$tweenFrame) { - this._$changePlace = this._$tweenFrame !== this._$parent._$currentFrame; - this._$tweenFrame = 0; - } - - if (place.loop.tweenFrame) { - this._$tweenFrame = place.loop.tweenFrame; - } - - return place.loop; - } - set loopConfig (loop_config: LoopConfigImpl | null) - { - this._$loopConfig = loop_config; - if (loop_config) { - loop_config.frame = this._$startFrame; - this._$loopConfig = loop_config; - this._$currentFrame = this._$getLoopFrame(loop_config); - } - } - - /** - * @description 指定されたフレームで SWF ファイルの再生を開始します。 - * Starts playing the SWF file at the specified frame. - * - * @param {number|string} frame - * @return {void} - * @method - * @public - */ - gotoAndPlay (frame: string | number): void - { - this.play(); - this._$goToFrame(frame); - } - - /** - * @description このムービークリップの指定されたフレームに再生ヘッドを送り、そこで停止させます。 - * Brings the playhead to the specified frame - * of the movie clip and stops it there. - * - * @param {number|string} frame - * @return {void} - * @method - * @public - */ - gotoAndStop (frame: string | number): void - { - this.stop(); - this._$goToFrame(frame); - } - - /** - * @description 次のフレームに再生ヘッドを送り、停止します。 - * Sends the playhead to the next frame and stops it. - * - * @return {void} - * @method - * @public - */ - nextFrame (): void - { - this.stop(); - if (this._$totalFrames > this._$currentFrame) { - this._$goToFrame(this._$currentFrame + 1); - } - } - - /** - * @description ムービークリップのタイムライン内で再生ヘッドを移動します。 - * Moves the playhead in the timeline of the movie clip. - * - * @return {void} - * @method - * @public - */ - play (): void - { - this._$stopFlag = false; - this._$isPlaying = true; - this._$updateState(); - } - - /** - * @description 直前のフレームに再生ヘッドを戻し、停止します。 - * Sends the playhead to the previous frame and stops it. - * - * @return {void} - * @method - * @public - */ - prevFrame (): void - { - const frame: number = this._$currentFrame - 1; - if (frame) { - this.stop(); - this._$goToFrame(frame); - } - } + // /** + // * @description MovieClipのフレームヘッダーの移動方法の設定オブジェクトを返します。 + // * Returns a configuration object for how MovieClip's frame headers are moved. + // * + // * @member {object} + // * @default null + // * @public + // */ + // get loopConfig (): LoopConfigImpl | null + // { + // if (this._$loopConfig) { + // return this._$loopConfig; + // } + + // const place: PlaceObjectImpl | null = this._$placeObject || this._$getPlaceObject(); + // if (!place || !place.loop) { + // return null; + // } + + // if (this._$tweenFrame) { + // this._$changePlace = this._$tweenFrame !== this._$parent._$currentFrame; + // this._$tweenFrame = 0; + // } + + // if (place.loop.tweenFrame) { + // this._$tweenFrame = place.loop.tweenFrame; + // } + + // return place.loop; + // } + // set loopConfig (loop_config: LoopConfigImpl | null) + // { + // this._$loopConfig = loop_config; + // if (loop_config) { + // loop_config.frame = this._$startFrame; + // this._$loopConfig = loop_config; + // this._$currentFrame = this._$getLoopFrame(loop_config); + // } + // } + + // /** + // * @description 指定されたフレームで SWF ファイルの再生を開始します。 + // * Starts playing the SWF file at the specified frame. + // * + // * @param {number|string} frame + // * @return {void} + // * @method + // * @public + // */ + // gotoAndPlay (frame: string | number): void + // { + // this.play(); + // this._$goToFrame(frame); + // } + + // /** + // * @description このムービークリップの指定されたフレームに再生ヘッドを送り、そこで停止させます。 + // * Brings the playhead to the specified frame + // * of the movie clip and stops it there. + // * + // * @param {number|string} frame + // * @return {void} + // * @method + // * @public + // */ + // gotoAndStop (frame: string | number): void + // { + // this.stop(); + // this._$goToFrame(frame); + // } + + // /** + // * @description 次のフレームに再生ヘッドを送り、停止します。 + // * Sends the playhead to the next frame and stops it. + // * + // * @return {void} + // * @method + // * @public + // */ + // nextFrame (): void + // { + // this.stop(); + // if (this._$totalFrames > this._$currentFrame) { + // this._$goToFrame(this._$currentFrame + 1); + // } + // } + + // /** + // * @description ムービークリップのタイムライン内で再生ヘッドを移動します。 + // * Moves the playhead in the timeline of the movie clip. + // * + // * @return {void} + // * @method + // * @public + // */ + // play (): void + // { + // this._$stopFlag = false; + // this._$isPlaying = true; + // this._$updateState(); + // } + + // /** + // * @description 直前のフレームに再生ヘッドを戻し、停止します。 + // * Sends the playhead to the previous frame and stops it. + // * + // * @return {void} + // * @method + // * @public + // */ + // prevFrame (): void + // { + // const frame: number = this._$currentFrame - 1; + // if (frame) { + // this.stop(); + // this._$goToFrame(frame); + // } + // } /** * @description ムービークリップ内の再生ヘッドを停止します。 @@ -443,802 +417,802 @@ export class MovieClip extends Sprite this._$isPlaying = false; } - /** - * @description タイムラインに対して動的にLabelを追加できます。 - * Labels can be added dynamically to the timeline. - * - * @example Example1 usage of addFrameLabel. - * // case 1 - * const {MovieClip, FrameLabel} = next2d.display; - * const movieClip = new MovieClip(); - * movieClip.addFrameLabel(new FrameLabel(1, "start")); - * - * @param {FrameLabel} frame_label - * @return {void} - * @public - */ - addFrameLabel (frame_label: FrameLabel): void - { - if (!this._$labels) { - this._$labels = $getMap(); - } + // /** + // * @description タイムラインに対して動的にLabelを追加できます。 + // * Labels can be added dynamically to the timeline. + // * + // * @example Example1 usage of addFrameLabel. + // * // case 1 + // * const {MovieClip, FrameLabel} = next2d.display; + // * const movieClip = new MovieClip(); + // * movieClip.addFrameLabel(new FrameLabel(1, "start")); + // * + // * @param {FrameLabel} frame_label + // * @return {void} + // * @public + // */ + // addFrameLabel (frame_label: FrameLabel): void + // { + // if (!this._$labels) { + // this._$labels = $getMap(); + // } + + // this._$labels.set(frame_label.frame, frame_label); + // } + + // /** + // * @description 指定のフレームのアクションを追加できます + // * You can add an action for a given frame. + // * + // * @example Example1 usage of addFrameScript. + // * // case 1 + // * const {MovieClip} = next2d.display; + // * const movieClip = new MovieClip(); + // * movieClip.addFrameScript(1 , function () + // * { + // * this.stop(); + // * }); + // * + // * @example Example3 usage of addFrameScript. + // * // case 2 + // * const {MovieClip} = next2d.display; + // * const movieClip = new MovieClip(); + // * movieClip.addFrameScript(1, method_1, 2, method_2, 10, method_10); + // * + // * @return {void} + // * @method + // * @public + // */ + // addFrameScript (...args: any[]): void + // { + // for (let idx = 0; idx < args.length; idx += 2) { + + // const value: string | number = args[idx]; + + // let frame: number = +value; + // if ($isNaN(frame)) { + // frame = this._$getFrameForLabel(`${value}`); + // } + + // const script: Function = args[idx + 1]; + // if (script && frame && this._$totalFrames >= frame) { + // this._$addAction(frame, script); + // } + + // // end action add + // if (frame === this._$currentFrame) { + + // // set action position + // const player: Player = $currentPlayer(); + // player._$actionOffset = player._$actions.length; + + // // execute action stack + // this._$canAction = true; + // this._$setAction(); + + // // adjustment + // if (player._$actionOffset !== player._$actions.length) { + + // // marge + // const actions: MovieClip[] = player._$actions.splice(0, player._$actionOffset); + // player._$actions.push( + // ...player._$actions, + // ...actions + // ); + + // // reset + // player._$actionOffset = 0; + // } + + // } + // } + // } + + // /** + // * @param {string} name + // * @return {number} + // * @private + // */ + // _$getFrameForLabel (name: string): number + // { + // if (!this._$labels) { + // return 0; + // } + + // for (const [frame, frameLabel] of this._$labels) { + // if (frameLabel.name === name) { + // return frame; + // } + // } + + // return 0; + // } + + // /** + // * @param {number} frame + // * @param {function} script + // * @return {void} + // * @method + // * @private + // */ + // _$addAction (frame: number, script: Function): void + // { + // if (frame) { + // if (!this._$actions.has(frame)) { + // this._$actions.set(frame, $getArray()); + // } + + // const actions: Function[] | void = this._$actions.get(frame); + // if (actions) { + // actions.push(script); + // } + + // } + // } + + // /** + // * @return {void} + // * @private + // */ + // _$setAction (): void + // { + // // added event + // this._$executeAddedEvent(); + + // if (this._$canAction) { + + // const frame: number = this._$currentFrame; + + // // frame label event + // if (this._$labels && this._$labels.has(frame)) { + + // const frameLabel: FrameLabel | void = this._$labels.get(frame); + + // if (frameLabel && frameLabel.willTrigger(Event.FRAME_LABEL)) { + // frameLabel.dispatchEvent(new Event(Event.FRAME_LABEL)); + // } + // } + + // // add action queue + // if (this._$actions.size && this._$actions.has(frame)) { + + // const player: Player = $currentPlayer(); + // const index = player._$actions.indexOf(this); + // if (index === -1) { + // player._$actions.push(this); + // } + + // } + // } + // } + + // /** + // * @param {number|string} value + // * @return {void} + // * @private + // */ + // _$goToFrame (value: string | number): void + // { + // let frame: number = +value; + // if ($isNaN(frame)) { + // frame = this._$getFrameForLabel(`${value}`); + // } + + // if (frame < 1) { + // frame = 1; + // } + + // // over + // if (frame > this._$totalFrames) { + // this._$currentFrame = this._$totalFrames; + // this._$clearChildren(); + + // // flag off + // this._$canAction = false; + // this._$wait = false; + + // return ; + // } + + // const player: Player = $currentPlayer(); + // switch (true) { + + // case frame !== this._$currentFrame: + // { + // // flag off + // this._$wait = false; + + // const currentFrame: number = this._$currentFrame; + + // if (this._$actionProcess) { + // this._$frameCache.set("nextFrame", frame); + // this._$frameCache.set("stopFlag", this._$stopFlag); + // this._$frameCache.set("isPlaying", this._$isPlaying); + // } + + // // setup + // this._$currentFrame = frame; + // this._$clearChildren(); + + // // set action position + // player._$actionOffset = player._$actions.length; + // const position: number = player._$actionOffset + // ? player._$actions.indexOf(this) + // : -1; + + // this._$canAction = true; + // this._$prepareActions(); + + // // adjustment + // if (player._$actionOffset + // && player._$actionOffset !== player._$actions.length + // ) { + + // // marge + // const actions: MovieClip[] = player._$actions.splice(0, player._$actionOffset); + // player._$actions.push( + // ...player._$actions, + // ...actions + // ); + + // // reset + // player._$actionOffset = 0; + // } - this._$labels.set(frame_label.frame, frame_label); - } + // if (!this._$actionProcess && (position > -1 || !player._$actionOffset)) { - /** - * @description 指定のフレームのアクションを追加できます - * You can add an action for a given frame. - * - * @example Example1 usage of addFrameScript. - * // case 1 - * const {MovieClip} = next2d.display; - * const movieClip = new MovieClip(); - * movieClip.addFrameScript(1 , function () - * { - * this.stop(); - * }); - * - * @example Example3 usage of addFrameScript. - * // case 2 - * const {MovieClip} = next2d.display; - * const movieClip = new MovieClip(); - * movieClip.addFrameScript(1, method_1, 2, method_2, 10, method_10); - * - * @return {void} - * @method - * @public - */ - addFrameScript (...args: any[]): void - { - for (let idx = 0; idx < args.length; idx += 2) { + // while (player._$actions.length) { - const value: string | number = args[idx]; + // if (player._$actions.length === position) { + // break; + // } - let frame: number = +value; - if ($isNaN(frame)) { - frame = this._$getFrameForLabel(`${value}`); - } + // // target object + // const mc: MovieClip | void = player._$actions.pop(); + // if (!mc) { + // continue; + // } - const script: Function = args[idx + 1]; - if (script && frame && this._$totalFrames >= frame) { - this._$addAction(frame, script); - } + // mc._$canAction = false; + // mc._$actionOffset = 0; + // mc._$actionLimit = 0; - // end action add - if (frame === this._$currentFrame) { + // if (mc._$actionProcess && mc._$frameCache.size) { - // set action position - const player: Player = $currentPlayer(); - player._$actionOffset = player._$actions.length; + // mc._$currentFrame = mc._$frameCache.get("nextFrame"); + // mc._$clearChildren(); - // execute action stack - this._$canAction = true; - this._$setAction(); + // mc._$stopFlag = mc._$frameCache.get("stopFlag"); + // mc._$isPlaying = mc._$frameCache.get("isPlaying"); + // mc._$frameCache.clear(); + // } - // adjustment - if (player._$actionOffset !== player._$actions.length) { + // const frame: number = mc._$currentFrame; + // if (!mc._$actions.has(frame)) { + // continue; + // } - // marge - const actions: MovieClip[] = player._$actions.splice(0, player._$actionOffset); - player._$actions.push( - ...player._$actions, - ...actions - ); + // const actions: Function[] | void = mc._$actions.get(frame); + // if (!actions) { + // continue; + // } - // reset - player._$actionOffset = 0; - } + // for (let idx: number = 0; idx < actions.length; ++idx) { - } - } - } + // try { - /** - * @param {string} name - * @return {number} - * @private - */ - _$getFrameForLabel (name: string): number - { - if (!this._$labels) { - return 0; - } + // $setCurrentLoaderInfo(mc._$loaderInfo); + // actions[idx].apply(mc); - for (const [frame, frameLabel] of this._$labels) { - if (frameLabel.name === name) { - return frame; - } - } + // } catch (e) { - return 0; - } + // mc.stop(); - /** - * @param {number} frame - * @param {function} script - * @return {void} - * @method - * @private - */ - _$addAction (frame: number, script: Function): void - { - if (frame) { - if (!this._$actions.has(frame)) { - this._$actions.set(frame, $getArray()); - } + // } + // } + // } + // } - const actions: Function[] | void = this._$actions.get(frame); - if (actions) { - actions.push(script); - } + // if (this._$actionProcess) { + // this._$currentFrame = currentFrame; + // this._$clearChildren(); + // } + // } + // break; - } - } + // case !this._$actionProcess && player._$actions.indexOf(this) > -1: + // { + // if (!this._$actionLimit) { + // break; + // } + + // // flag off + // this._$wait = false; - /** - * @return {void} - * @private - */ - _$setAction (): void - { - // added event - this._$executeAddedEvent(); + // const myActions: MovieClip[] = player._$actions.splice( + // this._$actionOffset, this._$actionLimit + // ); - if (this._$canAction) { + // while (myActions.length) { - const frame: number = this._$currentFrame; + // const mc: MovieClip | void = myActions.pop(); + // if (!mc) { + // continue; + // } - // frame label event - if (this._$labels && this._$labels.has(frame)) { + // // target reset + // mc._$canAction = false; + // mc._$actionOffset = 0; + // mc._$actionLimit = 0; - const frameLabel: FrameLabel | void = this._$labels.get(frame); + // const frame = mc._$currentFrame; + // if (!mc._$actions.has(frame)) { + // continue; + // } - if (frameLabel && frameLabel.willTrigger(Event.FRAME_LABEL)) { - frameLabel.dispatchEvent(new Event(Event.FRAME_LABEL)); - } - } + // const actions: Function[] | void = mc._$actions.get(frame); + // if (!actions) { + // continue; + // } - // add action queue - if (this._$actions.size && this._$actions.has(frame)) { + // for (let idx: number = 0; idx < actions.length; ++idx) { - const player: Player = $currentPlayer(); - const index = player._$actions.indexOf(this); - if (index === -1) { - player._$actions.push(this); - } + // try { - } - } - } + // $setCurrentLoaderInfo(mc._$loaderInfo); + // // @ts-ignore + // actions[idx].apply(mc); - /** - * @param {number|string} value - * @return {void} - * @private - */ - _$goToFrame (value: string | number): void - { - let frame: number = +value; - if ($isNaN(frame)) { - frame = this._$getFrameForLabel(`${value}`); - } + // } catch (e) { - if (frame < 1) { - frame = 1; - } + // mc.stop(); - // over - if (frame > this._$totalFrames) { - this._$currentFrame = this._$totalFrames; - this._$clearChildren(); + // } - // flag off - this._$canAction = false; - this._$wait = false; + // } - return ; - } - - const player: Player = $currentPlayer(); - switch (true) { - - case frame !== this._$currentFrame: - { - // flag off - this._$wait = false; - - const currentFrame: number = this._$currentFrame; - - if (this._$actionProcess) { - this._$frameCache.set("nextFrame", frame); - this._$frameCache.set("stopFlag", this._$stopFlag); - this._$frameCache.set("isPlaying", this._$isPlaying); - } - - // setup - this._$currentFrame = frame; - this._$clearChildren(); - - // set action position - player._$actionOffset = player._$actions.length; - const position: number = player._$actionOffset - ? player._$actions.indexOf(this) - : -1; - - this._$canAction = true; - this._$prepareActions(); + // } + // } + // break; - // adjustment - if (player._$actionOffset - && player._$actionOffset !== player._$actions.length - ) { + // default: + // break; - // marge - const actions: MovieClip[] = player._$actions.splice(0, player._$actionOffset); - player._$actions.push( - ...player._$actions, - ...actions - ); + // } - // reset - player._$actionOffset = 0; - } + // $setCurrentLoaderInfo(null); - if (!this._$actionProcess && (position > -1 || !player._$actionOffset)) { + // // set sound + // if (this._$canSound && this._$sounds.size + // && this._$sounds.has(this._$currentFrame) + // && !player._$sounds.has(this._$instanceId) + // ) { + // player._$sounds.set(this._$instanceId, this); + // } + // } - while (player._$actions.length) { + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$prepareActions (): void + // { + // // draw flag + // this._$wait = false; - if (player._$actions.length === position) { - break; - } + // const children: DisplayObjectImpl[] = this._$needsChildren + // ? this._$getChildren() + // : this._$children; - // target object - const mc: MovieClip | void = player._$actions.pop(); - if (!mc) { - continue; - } + // for (let idx: number = children.length - 1; idx > -1; --idx) { + // children[idx]._$prepareActions(); + // } - mc._$canAction = false; - mc._$actionOffset = 0; - mc._$actionLimit = 0; + // this._$setAction(); + // } - if (mc._$actionProcess && mc._$frameCache.size) { + // /** + // * @return {boolean} + // * @method + // * @private + // */ + // _$nextFrame (): boolean + // { + // let isNext: boolean = this._$needsChildren; + // switch (true) { - mc._$currentFrame = mc._$frameCache.get("nextFrame"); - mc._$clearChildren(); + // case this._$wait: + // isNext = true; + // this._$wait = false; + // break; - mc._$stopFlag = mc._$frameCache.get("stopFlag"); - mc._$isPlaying = mc._$frameCache.get("isPlaying"); - mc._$frameCache.clear(); - } + // case this._$stopFlag: + // case this._$totalFrames === 1: + // break; - const frame: number = mc._$currentFrame; - if (!mc._$actions.has(frame)) { - continue; - } + // default: + // { + // isNext = true; - const actions: Function[] | void = mc._$actions.get(frame); - if (!actions) { - continue; - } + // // action on + // this._$canAction = true; - for (let idx: number = 0; idx < actions.length; ++idx) { + // // sound on + // this._$canSound = true; - try { + // const loopConfig: LoopConfigImpl | null = this.loopConfig; + // if (!loopConfig) { - $setCurrentLoaderInfo(mc._$loaderInfo); - actions[idx].apply(mc); + // // next frame point + // ++this._$currentFrame; + // if (this._$currentFrame > this._$totalFrames) { + // this._$currentFrame = 1; + // } - } catch (e) { + // } else { - mc.stop(); + // const totalFrames: number = loopConfig.end + // ? loopConfig.end + // : this._$totalFrames; - } - } - } - } + // switch (loopConfig.type) { - if (this._$actionProcess) { - this._$currentFrame = currentFrame; - this._$clearChildren(); - } - } - break; + // case 0: // REPEAT + // if (this._$changePlace) { - case !this._$actionProcess && player._$actions.indexOf(this) > -1: - { - if (!this._$actionLimit) { - break; - } + // this._$currentFrame = loopConfig.start; - // flag off - this._$wait = false; + // } else { - const myActions: MovieClip[] = player._$actions.splice( - this._$actionOffset, this._$actionLimit - ); + // ++this._$currentFrame; + // if (this._$currentFrame > totalFrames) { + // this._$currentFrame = loopConfig.start; + // } - while (myActions.length) { + // } + // break; - const mc: MovieClip | void = myActions.pop(); - if (!mc) { - continue; - } + // case 1: // NO_REPEAT + // if (this._$changePlace) { - // target reset - mc._$canAction = false; - mc._$actionOffset = 0; - mc._$actionLimit = 0; + // this._$currentFrame = loopConfig.start; - const frame = mc._$currentFrame; - if (!mc._$actions.has(frame)) { - continue; - } + // } else { - const actions: Function[] | void = mc._$actions.get(frame); - if (!actions) { - continue; - } + // ++this._$currentFrame; + // if (this._$currentFrame > totalFrames) { - for (let idx: number = 0; idx < actions.length; ++idx) { + // this._$currentFrame = totalFrames; + // isNext = false; - try { + // // action on + // this._$canAction = false; - $setCurrentLoaderInfo(mc._$loaderInfo); - // @ts-ignore - actions[idx].apply(mc); + // // sound on + // this._$canSound = false; + // } - } catch (e) { + // } + // break; - mc.stop(); + // case 2: // FIXED + // if (this._$changePlace) { - } + // this._$currentFrame = loopConfig.start; - } - - } - } - break; - - default: - break; - - } - - $setCurrentLoaderInfo(null); - - // set sound - if (this._$canSound && this._$sounds.size - && this._$sounds.has(this._$currentFrame) - && !player._$sounds.has(this._$instanceId) - ) { - player._$sounds.set(this._$instanceId, this); - } - } + // } else { - /** - * @return {void} - * @method - * @private - */ - _$prepareActions (): void - { - // draw flag - this._$wait = false; - - const children: DisplayObjectImpl[] = this._$needsChildren - ? this._$getChildren() - : this._$children; - - for (let idx: number = children.length - 1; idx > -1; --idx) { - children[idx]._$prepareActions(); - } - - this._$setAction(); - } - - /** - * @return {boolean} - * @method - * @private - */ - _$nextFrame (): boolean - { - let isNext: boolean = this._$needsChildren; - switch (true) { + // isNext = false; - case this._$wait: - isNext = true; - this._$wait = false; - break; + // // action on + // this._$canAction = false; - case this._$stopFlag: - case this._$totalFrames === 1: - break; + // // sound on + // this._$canSound = false; - default: - { - isNext = true; + // } + // break; - // action on - this._$canAction = true; + // case 3: // NO_REPEAT_REVERSAL + // if (this._$changePlace) { - // sound on - this._$canSound = true; + // this._$currentFrame = totalFrames; - const loopConfig: LoopConfigImpl | null = this.loopConfig; - if (!loopConfig) { + // } else { - // next frame point - ++this._$currentFrame; - if (this._$currentFrame > this._$totalFrames) { - this._$currentFrame = 1; - } + // --this._$currentFrame; + // if (loopConfig.start > this._$currentFrame) { + // this._$currentFrame = loopConfig.start; - } else { + // isNext = false; - const totalFrames: number = loopConfig.end - ? loopConfig.end - : this._$totalFrames; + // // action on + // this._$canAction = false; - switch (loopConfig.type) { + // // sound on + // this._$canSound = false; + // } - case 0: // REPEAT - if (this._$changePlace) { + // } + // break; - this._$currentFrame = loopConfig.start; + // case 4: // REPEAT_REVERSAL + // if (this._$changePlace) { - } else { + // this._$currentFrame = totalFrames; - ++this._$currentFrame; - if (this._$currentFrame > totalFrames) { - this._$currentFrame = loopConfig.start; - } + // } else { - } - break; + // --this._$currentFrame; + // if (loopConfig.start > this._$currentFrame) { + // this._$currentFrame = totalFrames; + // } - case 1: // NO_REPEAT - if (this._$changePlace) { + // } + // break; - this._$currentFrame = loopConfig.start; + // } + // } - } else { + // // clear + // if (isNext) { + // this._$clearChildren(); + // } - ++this._$currentFrame; - if (this._$currentFrame > totalFrames) { + // // set sound + // if (this._$canSound && this._$sounds.size + // && this._$sounds.has(this._$currentFrame) + // ) { + // const player: Player = $currentPlayer(); + // if (!player._$sounds.has(this._$instanceId)) { + // player._$sounds.set(this._$instanceId, this); + // } + // } - this._$currentFrame = totalFrames; - isNext = false; + // } + // break; - // action on - this._$canAction = false; + // } - // sound on - this._$canSound = false; - } + // const children: DisplayObjectImpl[] = this._$needsChildren + // ? this._$getChildren() + // : this._$children; - } - break; + // for (let idx: number = children.length - 1; idx > -1; --idx) { - case 2: // FIXED - if (this._$changePlace) { + // const child: DisplayObjectImpl = children[idx]; - this._$currentFrame = loopConfig.start; + // if (!child._$isNext) { + // continue; + // } - } else { + // if (isNext) { - isNext = false; + // child._$nextFrame(); - // action on - this._$canAction = false; + // } else { - // sound on - this._$canSound = false; + // isNext = child._$nextFrame(); - } - break; + // } - case 3: // NO_REPEAT_REVERSAL - if (this._$changePlace) { + // } - this._$currentFrame = totalFrames; + // // frame action + // this._$setAction(); - } else { + // this._$isNext = isNext; - --this._$currentFrame; - if (loopConfig.start > this._$currentFrame) { - this._$currentFrame = loopConfig.start; + // if (!this._$posted && $rendererWorker) { + // this._$postProperty(); + // } - isNext = false; + // return this._$isNext; + // } - // action on - this._$canAction = false; + // /** + // * @param {LoopConfig} loop_config + // * @return {number} + // * @method + // * @private + // */ + // _$getLoopFrame (loop_config: LoopConfigImpl): number + // { + // const parent: ParentImpl = this._$parent; + // const length: number = parent._$currentFrame - loop_config.frame; - // sound on - this._$canSound = false; - } + // let frame: number = 1; + // switch (loop_config.type) { - } - break; + // case 0: // REPEAT + // { + // const totalFrame = loop_config.end + // ? loop_config.end + // : this._$totalFrames; - case 4: // REPEAT_REVERSAL - if (this._$changePlace) { + // frame = loop_config.start; + // for (let idx = 0; idx < length; ++idx) { - this._$currentFrame = totalFrames; + // ++frame; - } else { - - --this._$currentFrame; - if (loopConfig.start > this._$currentFrame) { - this._$currentFrame = totalFrames; - } - - } - break; - - } - } - - // clear - if (isNext) { - this._$clearChildren(); - } - - // set sound - if (this._$canSound && this._$sounds.size - && this._$sounds.has(this._$currentFrame) - ) { - const player: Player = $currentPlayer(); - if (!player._$sounds.has(this._$instanceId)) { - player._$sounds.set(this._$instanceId, this); - } - } - - } - break; - - } - - const children: DisplayObjectImpl[] = this._$needsChildren - ? this._$getChildren() - : this._$children; - - for (let idx: number = children.length - 1; idx > -1; --idx) { - - const child: DisplayObjectImpl = children[idx]; - - if (!child._$isNext) { - continue; - } - - if (isNext) { - - child._$nextFrame(); - - } else { - - isNext = child._$nextFrame(); - - } - - } - - // frame action - this._$setAction(); - - this._$isNext = isNext; - - if (!this._$posted && $rendererWorker) { - this._$postProperty(); - } - - return this._$isNext; - } - - /** - * @param {LoopConfig} loop_config - * @return {number} - * @method - * @private - */ - _$getLoopFrame (loop_config: LoopConfigImpl): number - { - const parent: ParentImpl = this._$parent; - const length: number = parent._$currentFrame - loop_config.frame; + // if (frame > totalFrame) { + // frame = loop_config.start; + // } - let frame: number = 1; - switch (loop_config.type) { + // } + // } + // break; - case 0: // REPEAT - { - const totalFrame = loop_config.end - ? loop_config.end - : this._$totalFrames; + // case 1: // NO_REPEAT + // { + // const totalFrame = loop_config.end + // ? loop_config.end + // : this._$totalFrames; - frame = loop_config.start; - for (let idx = 0; idx < length; ++idx) { + // frame = $Math.min(totalFrame, loop_config.start + length); + // } + // break; - ++frame; + // case 2: // FIXED + // frame = loop_config.start; + // break; - if (frame > totalFrame) { - frame = loop_config.start; - } + // case 3: // NO_REPEAT_REVERSAL - } - } - break; + // frame = loop_config.end + // ? loop_config.end + // : this._$totalFrames; - case 1: // NO_REPEAT - { - const totalFrame = loop_config.end - ? loop_config.end - : this._$totalFrames; + // frame = $Math.max(loop_config.start, frame - length); + // break; - frame = $Math.min(totalFrame, loop_config.start + length); - } - break; + // case 4: // REPEAT_REVERSAL + // { + // const totalFrame: number = loop_config.end + // ? loop_config.end + // : this._$totalFrames; - case 2: // FIXED - frame = loop_config.start; - break; + // frame = totalFrame; + // for (let idx: number = 0; idx < length; ++idx) { - case 3: // NO_REPEAT_REVERSAL + // --frame; - frame = loop_config.end - ? loop_config.end - : this._$totalFrames; + // if (loop_config.start > frame) { + // frame = totalFrame; + // } - frame = $Math.max(loop_config.start, frame - length); - break; + // } + // } + // break; - case 4: // REPEAT_REVERSAL - { - const totalFrame: number = loop_config.end - ? loop_config.end - : this._$totalFrames; + // } - frame = totalFrame; - for (let idx: number = 0; idx < length; ++idx) { + // return frame; + // } - --frame; + // /** + // * @param {object} character + // * @return {void} + // * @method + // * @private + // */ + // _$buildCharacter (character: MovieClipCharacterImpl): void + // { + // if (character.sounds) { + // for (let idx: number = 0; idx < character.sounds.length; ++idx) { + + // const object: MovieClipSoundObjectImpl = character.sounds[idx]; + + // const sounds: Sound[] = $getArray(); + // for (let idx: number = 0; idx < object.sound.length; ++idx) { + + // const sound: Sound = new Sound(); + // sound._$build(object.sound[idx], this); + + // sounds.push(sound); + // } + + // this._$sounds.set(object.frame, sounds); + // } + // } + + // if (character.actions) { + // for (let idx: number = 0; idx < character.actions.length; ++idx) { + + // const object: MovieClipActionObjectImpl = character.actions[idx]; + // if (!object.script) { + // object.script = Function(object.action); + // } + + // this._$addAction(object.frame, object.script); + // } + // } + + // if (character.labels) { + // for (let idx: number = 0; idx < character.labels.length; ++idx) { + + // const label: MovieClipLabelObjectImpl = character.labels[idx]; - if (loop_config.start > frame) { - frame = totalFrame; - } + // this.addFrameLabel(new FrameLabel(label.name, label.frame)); + + // } + // } + + // this._$totalFrames = character.totalFrame || 1; + // } + + // /** + // * @param {object} character + // * @return {void} + // * @method + // * @private + // */ + // _$sync (character: Character): void + // { + // super._$sync(character); + // this._$buildCharacter(character); + // } - } - } - break; - - } - - return frame; - } - - /** - * @param {object} character - * @return {void} - * @method - * @private - */ - _$buildCharacter (character: MovieClipCharacterImpl): void - { - if (character.sounds) { - for (let idx: number = 0; idx < character.sounds.length; ++idx) { - - const object: MovieClipSoundObjectImpl = character.sounds[idx]; - - const sounds: Sound[] = $getArray(); - for (let idx: number = 0; idx < object.sound.length; ++idx) { - - const sound: Sound = new Sound(); - sound._$build(object.sound[idx], this); - - sounds.push(sound); - } - - this._$sounds.set(object.frame, sounds); - } - } - - if (character.actions) { - for (let idx: number = 0; idx < character.actions.length; ++idx) { - - const object: MovieClipActionObjectImpl = character.actions[idx]; - if (!object.script) { - object.script = Function(object.action); - } - - this._$addAction(object.frame, object.script); - } - } - - if (character.labels) { - for (let idx: number = 0; idx < character.labels.length; ++idx) { - - const label: MovieClipLabelObjectImpl = character.labels[idx]; - - this.addFrameLabel(new FrameLabel(label.name, label.frame)); - - } - } - - this._$totalFrames = character.totalFrame || 1; - } - - /** - * @param {object} character - * @return {void} - * @method - * @private - */ - _$sync (character: Character): void - { - super._$sync(character); - this._$buildCharacter(character); - } - - /** - * @param {object} tag - * @param {DisplayObjectContainer} parent - * @return {object} - * @method - * @private - */ - _$build ( - tag: DictionaryTagImpl, - parent: ParentImpl - ): MovieClipCharacterImpl { - - const character: MovieClipCharacterImpl = super._$build(tag, parent); - - this._$buildCharacter(character); - - return character; - } - - /** - * @return {void} - * @method - * @private - */ - _$soundPlay (): void - { - if (!this._$sounds.has(this._$currentFrame)) { - return ; - } - - const sounds: Sound[] = this._$sounds.get(this._$currentFrame) as NonNullable; - if (sounds.length) { - - // set SoundTransform - let soundTransform: SoundTransform | null = this._$soundTransform; - - let parent = this._$parent; - while (parent) { - - if (parent._$soundTransform) { - soundTransform = parent._$soundTransform; - } - - parent = parent._$parent; - } - - // play sound - for (let idx: number = 0; idx < sounds.length; ++idx) { - - const sound = sounds[idx]; - - if (soundTransform) { - sound.loopCount = soundTransform.loop ? 0xffffff : 0; - sound.volume = soundTransform.volume; - } - sound.play(); - } - } - - this._$canSound = false; - } -} + // /** + // * @param {object} tag + // * @param {DisplayObjectContainer} parent + // * @return {object} + // * @method + // * @private + // */ + // _$build ( + // tag: DictionaryTagImpl, + // parent: ParentImpl + // ): MovieClipCharacterImpl { + + // const character: MovieClipCharacterImpl = super._$build(tag, parent); + + // this._$buildCharacter(character); + + // return character; + // } + + // /** + // * @return {void} + // * @method + // * @private + // */ + // _$soundPlay (): void + // { + // if (!this._$sounds.has(this._$currentFrame)) { + // return ; + // } + + // const sounds: Sound[] = this._$sounds.get(this._$currentFrame) as NonNullable; + // if (sounds.length) { + + // // set SoundTransform + // let soundTransform: SoundTransform | null = this._$soundTransform; + + // let parent = this._$parent; + // while (parent) { + + // if (parent._$soundTransform) { + // soundTransform = parent._$soundTransform; + // } + + // parent = parent._$parent; + // } + + // // play sound + // for (let idx: number = 0; idx < sounds.length; ++idx) { + + // const sound = sounds[idx]; + + // if (soundTransform) { + // sound.loopCount = soundTransform.loop ? 0xffffff : 0; + // sound.volume = soundTransform.volume; + // } + // sound.play(); + // } + // } + + // this._$canSound = false; + // } +} \ No newline at end of file diff --git a/packages/display/src/MovieClip/MovieClipBuildService.ts b/packages/display/src/MovieClip/MovieClipBuildService.ts new file mode 100644 index 00000000..c07a6c43 --- /dev/null +++ b/packages/display/src/MovieClip/MovieClipBuildService.ts @@ -0,0 +1,88 @@ +import type { DictionaryTagImpl } from "../interface/DictionaryTagImpl"; +import type { ParentImpl } from "../interface/ParentImpl"; +import type { MovieClipSoundObjectImpl } from "../interface/MovieClipSoundObjectImpl"; +import type { MovieClipActionObjectImpl } from "../interface/MovieClipActionObjectImpl"; +import type { MovieClipLabelObjectImpl } from "../interface/MovieClipLabelObjectImpl"; +import type { LoaderInfoDataImpl } from "../interface/LoaderInfoDataImpl"; +import { execute as displayObjectBaseBuildService } from "../DisplayObject/DisplayObjectBaseBuildService"; +import { LoaderInfo } from "../LoaderInfo"; +import { FrameLabel } from "../FrameLabel"; +import { MovieClip } from "../MovieClip"; +import { $getArray } from "../DisplayObjectUtil"; +import { Sound, SoundMixer } from "@next2d/media"; + +/** + * @description 指定tagの情報を元に、MovieClipを作成 + * Create a MovieClip based on the specified tag information + * + * @param {object} tag + * @param {DisplayObjectContainer} parent + * @return {Promise} + * @method + * @public + */ +export const execute = async ( + tag: DictionaryTagImpl, + parent: ParentImpl +): Promise => { + + const movieClip = new MovieClip(); + const character = displayObjectBaseBuildService( + movieClip, tag, parent + ); + + if (character.sounds) { + + const loaderInfo = movieClip.loaderInfo as NonNullable; + const data = loaderInfo.data as NonNullable; + + for (let idx: number = 0; idx < character.sounds.length; ++idx) { + + const object: MovieClipSoundObjectImpl = character.sounds[idx]; + + const sounds: Sound[] = $getArray(); + for (let idx: number = 0; idx < object.sound.length; ++idx) { + + const sound: Sound = new Sound(); + + const tag = object.sound[idx]; + + sound.loopCount = tag.loopCount | 0; + sound.volume = Math.min(SoundMixer.volume, tag.volume); + + const character = data.characters[tag.characterId]; + await sound.build(character); + + sounds.push(sound); + } + + movieClip._$sounds.set(object.frame, sounds); + } + } + + if (character.actions) { + for (let idx: number = 0; idx < character.actions.length; ++idx) { + + const object: MovieClipActionObjectImpl = character.actions[idx]; + if (!object.script) { + object.script = Function(object.action); + } + + movieClip._$addAction(object.frame, object.script); + } + } + + if (character.labels) { + for (let idx: number = 0; idx < character.labels.length; ++idx) { + + const label: MovieClipLabelObjectImpl = character.labels[idx]; + + movieClip.addFrameLabel(new FrameLabel(label.name, label.frame)); + + } + } + + movieClip._$totalFrames = character.totalFrame || 1; + + return movieClip; +}; \ No newline at end of file diff --git a/packages/display/src/Shape.ts b/packages/display/src/Shape.ts index 4cea3ec1..d8370699 100644 --- a/packages/display/src/Shape.ts +++ b/packages/display/src/Shape.ts @@ -1,47 +1,7 @@ import { DisplayObject } from "./DisplayObject"; import { Graphics } from "./Graphics"; import { BitmapData } from "./BitmapData"; -import { Rectangle } from "@next2d/geom"; import { Event } from "@next2d/events"; -import type { LoaderInfo } from "./LoaderInfo"; -import type { CanvasToWebGLContext } from "@next2d/webgl"; -import type { - BoundsImpl, - ShapeCharacterImpl, - CapsStyleImpl, - JointStyleImpl, - ParentImpl, - DictionaryTagImpl, - FilterArrayImpl, - BlendModeImpl, - PlayerHitObjectImpl, - PropertyMessageMapImpl, - PropertyShapeMessageImpl, - Character, - PropertyMessageImpl -} from "@next2d/interface"; -import { - $MATRIX_HIT_ARRAY_IDENTITY, - $getRenderBufferArray, - $getRenderMessageObject, - $poolRenderMessageObject, - $rendererWorker -} from "@next2d/util"; -import { - $getArray, - $poolArray, - $getFloat32Array6, - $getBoundsObject, - $poolBoundsObject, - $multiplicationMatrix, - $boundsMatrix, - $poolFloat32Array6, - $multiplicationColor, - $clamp, - $poolFloat32Array8, - $Math, - $COLOR_ARRAY_IDENTITY -} from "@next2d/share"; /** * Shape クラスには、Graphics クラスからメソッドにアクセスできる graphics プロパティがあります。 @@ -195,560 +155,437 @@ export class Shape extends DisplayObject this.graphics._$mode = "bitmap"; } - /** - * @param {object} character - * @param {LoaderInfo} loaderInfo - * @return {void} - * @method - * @private - */ - _$buildCharacter ( - character: Character, - loaderInfo: LoaderInfo - ): void { - - const graphics: Graphics = this.graphics; - - if (!loaderInfo._$data) { - throw new Error("the loaderInfo data is null."); - } - - if (character.recodes) { - - switch (true) { - - case character.bitmapId > 0: - { - const bitmap: Character = loaderInfo - ._$data - .characters[character.bitmapId]; - - if (!bitmap.buffer) { - throw new Error("the bitmap buffer is null."); - } - - const width: number = $Math.abs(bitmap.bounds.xMax - bitmap.bounds.xMin); - const height: number = $Math.abs(bitmap.bounds.yMax - bitmap.bounds.yMin); - - const bitmapData: BitmapData = new BitmapData(width, height); - if (!bitmap._$buffer) { - bitmap._$buffer = new Uint8Array(bitmap.buffer); - $poolArray(bitmap.buffer); - bitmap.buffer = null; - } - bitmapData.buffer = bitmap._$buffer.slice(); - - // setup - graphics._$recode = $getArray(); - - if (width === character.bounds.xMax - character.bounds.xMin - && height === character.bounds.yMax - character.bounds.yMin - ) { - graphics._$bitmapId = character.bitmapId; - graphics._$mode = "bitmap"; - } - - // clone - const recodes: any[] = character.recodes; - if (recodes[recodes.length - 1] === Graphics.END_FILL) { - - const length: number = recodes.length - 6; - for (let idx: number = 0; idx < length; ++idx) { - graphics._$recode.push(recodes[idx]); - } - - // add Bitmap Fill - graphics._$recode.push( - Graphics.BITMAP_FILL, - bitmapData, - null, - "repeat", - false - ); - - } else { - - const width: number = recodes[recodes.length - 9]; - const caps: CapsStyleImpl = recodes[recodes.length - 8]; - const joints: JointStyleImpl = recodes[recodes.length - 7]; - const miterLimit: number = recodes[recodes.length - 6]; - - const length: number = recodes.length - 10; - for (let idx: number = 0; idx < length; ++idx) { - graphics._$recode.push(recodes[idx]); - } - - graphics._$recode.push( - Graphics.BITMAP_STROKE, - width, - caps, - joints, - miterLimit, - bitmapData, - $getFloat32Array6( - 1, 0, 0, 1, character.bounds.xMin, character.bounds.yMin - ), - "repeat", - false - ); - } - } - break; - - case character.inBitmap: - { - // setup - graphics._$recode = $getArray(); - - const recodes: any[] = character.recodes; - for (let idx: number = 0; idx < recodes.length; ++idx) { - - const value: BitmapData = recodes[idx]; - graphics._$recode[idx] = value; - - if (typeof value !== "object") { - continue; - } - - if (!value.buffer) { - continue; - } - - const bitmapData: BitmapData = new BitmapData( - value.width, value.height - ); - bitmapData.buffer = new Uint8Array(value.buffer); - graphics._$recode[idx++] = bitmapData; - - const matrix: number[] = recodes[idx]; - graphics._$recode[idx] = $getFloat32Array6( - matrix[0], matrix[1], matrix[2], - matrix[3], matrix[4], matrix[5] - ); - - if (value.width === character.bounds.xMax - character.bounds.xMin - && value.height === character.bounds.yMax - character.bounds.yMin - ) { - graphics._$bitmapId = character.bitmapId; - graphics._$mode = "bitmap"; - } - } - } - break; - - default: - graphics._$recode = character.recodes.slice(0); - break; - - } - - } else { - - graphics._$mode = "bitmap"; - - const width: number = $Math.abs(character.bounds.xMax - character.bounds.xMin); - const height: number = $Math.abs(character.bounds.yMax - character.bounds.yMin); - - const bitmapData: BitmapData = new BitmapData(width, height); - if (!character._$buffer) { - if (!character.buffer) { - throw new Error("the bitmap buffer is null."); - } - character._$buffer = new Uint8Array(character.buffer); - $poolArray(character.buffer); - character.buffer = null; - } - bitmapData.buffer = character._$buffer.slice(0); - - graphics - .beginBitmapFill(bitmapData, null, false) - .drawRect(0, 0, width, height); - - } - - graphics._$maxAlpha = 1; - graphics._$canDraw = true; - - graphics._$xMin = character.bounds.xMin; - graphics._$xMax = character.bounds.xMax; - graphics._$yMin = character.bounds.yMin; - graphics._$yMax = character.bounds.yMax; - - // 9-scale - if (character.grid) { - this._$scale9Grid = new Rectangle( - character.grid.x, character.grid.y, - character.grid.w, character.grid.h - ); - } - - if ($rendererWorker && this._$stage) { - this._$createWorkerInstance(); - } - } - - /** - * @param {object} character - * @return {void} - * @method - * @protected - */ - _$sync (character: ShapeCharacterImpl): void - { - if (this._$loaderInfo) { - this._$buildCharacter(character, this._$loaderInfo); - } - } - - /** - * @param {object} tag - * @param {DisplayObjectContainer} parent - * @return {object} - * @method - * @private - */ - _$build ( - tag: DictionaryTagImpl, - parent: ParentImpl - ): ShapeCharacterImpl { - - const character: ShapeCharacterImpl = this - ._$baseBuild(tag, parent); - - this._$buildCharacter(character, parent._$loaderInfo); - - return character; - } - - /** - * @param {Float32Array} [matrix=null] - * @returns {object} - * @method - * @private - */ - _$getBounds ( - matrix: Float32Array | null = null - ): BoundsImpl { - - if (!this._$graphics) { - return $getBoundsObject(0, 0, 0, 0); - } - - const baseBounds: BoundsImpl = this._$graphics._$getBounds(); - if (!matrix) { - return baseBounds; - } - - let multiMatrix: Float32Array = matrix; - - const rawMatrix: Float32Array = this._$transform._$rawMatrix(); - if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 - || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 - || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 - ) { - multiMatrix = $multiplicationMatrix(matrix, rawMatrix); - } - - const bounds: BoundsImpl = $boundsMatrix(baseBounds, multiMatrix); - $poolBoundsObject(baseBounds); - - if (multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - - return bounds; - } - - /** - * @param {CanvasToWebGLContext} context - * @param {Float32Array} matrix - * @param {Float32Array} color_transform - * @return {void} - * @method - * @private - */ - _$draw ( - context: CanvasToWebGLContext, - matrix: Float32Array, - color_transform: Float32Array - ): void { - - if (!this._$visible) { - return ; - } - - if (!this._$graphics || !this._$graphics._$canDraw) { - return ; - } - - let multiColor: Float32Array = color_transform; - const rawColor: Float32Array = this._$transform._$rawColorTransform(); - if (rawColor !== $COLOR_ARRAY_IDENTITY - && rawColor[0] !== 1 || rawColor[1] !== 1 - || rawColor[2] !== 1 || rawColor[3] !== 1 - || rawColor[4] !== 0 || rawColor[5] !== 0 - || rawColor[6] !== 0 || rawColor[7] !== 0 - ) { - multiColor = $multiplicationColor(color_transform, rawColor); - } - - const alpha: number = $clamp(multiColor[3] + multiColor[7] / 255, 0, 1, 0); - if (!alpha) { - if (multiColor !== color_transform) { - $poolFloat32Array8(multiColor); - } - return ; - } - - const filters: FilterArrayImpl | null = this._$filters || this.filters; - const blendMode: BlendModeImpl = this._$blendMode || this.blendMode; - - let multiMatrix: Float32Array = matrix; - const rawMatrix: Float32Array = this._$transform._$rawMatrix(); - if (rawMatrix !== $MATRIX_HIT_ARRAY_IDENTITY - && rawMatrix[0] !== 1 || rawMatrix[1] !== 0 - || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 - || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 - ) { - multiMatrix = $multiplicationMatrix(matrix, rawMatrix); - } - - this - ._$graphics - ._$draw(context, multiMatrix, multiColor, blendMode, filters); - - if (multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - - if (multiColor !== color_transform) { - $poolFloat32Array8(multiColor); - } - - } - - /** - * @param {CanvasToWebGLContext} context - * @param {Float32Array} matrix - * @returns {void} - * @method - * @private - */ - _$clip ( - context: CanvasToWebGLContext, - matrix: Float32Array - ): void { - - if (!this._$graphics) { - return ; - } - - let multiMatrix: Float32Array = matrix; - const rawMatrix: Float32Array = this._$transform._$rawMatrix(); - if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 - || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 - || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 - ) { - multiMatrix = $multiplicationMatrix(matrix, rawMatrix); - } - - this._$graphics._$clip(context, multiMatrix); - - if (multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - } - - /** - * @param {CanvasRenderingContext2D} context - * @param {Float32Array} matrix - * @param {object} options - * @return {boolean} - * @method - * @private - */ - _$mouseHit ( - context: CanvasRenderingContext2D, - matrix: Float32Array, - options: PlayerHitObjectImpl - ): boolean { - - if (!this._$visible) { - return false; - } - - return this._$hit(context, matrix, options); - } - - /** - * @param {CanvasRenderingContext2D} context - * @param {Float32Array} matrix - * @param {object} options - * @param {boolean} [is_clip=false] - * @return {boolean} - * @method - * @private - */ - _$hit ( - context: CanvasRenderingContext2D, - matrix: Float32Array, - options: PlayerHitObjectImpl, - is_clip: boolean = false - ): boolean { - - let hit: boolean = false; - - const graphics: Graphics | null = this._$graphics; - if (graphics - && graphics._$canDraw - && graphics._$getBounds() - ) { - - let multiMatrix: Float32Array = matrix; - const rawMatrix: Float32Array = this._$transform._$rawMatrix(); - if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 - || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 - || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 - ) { - multiMatrix = $multiplicationMatrix(matrix, rawMatrix); - } - - hit = graphics._$hit( - context, - multiMatrix, - options, - is_clip - ); - - if (multiMatrix !== matrix) { - $poolFloat32Array6(multiMatrix); - } - - } - - return hit; - } - - /** - * @return {void} - * @method - * @private - */ - _$createWorkerInstance (): void - { - if (this._$created || !$rendererWorker) { - return ; - } - - // update flag - this._$created = true; - this._$posted = true; - this._$updated = false; - - const buffer: Float32Array = $getRenderBufferArray(); - - let index: number = 0; - buffer[index++] = this._$instanceId; - buffer[index++] = this._$parent ? this._$parent._$instanceId : -1; - buffer[index++] = 0; // maxAlpha - buffer[index++] = 0; // canDraw - - // graphics - const graphics: Graphics | null = this._$graphics; - if (graphics - && !graphics._$posted - && graphics._$maxAlpha > 0 - && graphics._$canDraw - ) { - - graphics._$posted = true; - - const message: PropertyMessageImpl = $getRenderMessageObject(); - const recodes: Float32Array = graphics._$getRecodes(); - - message.command = `shapeRecodes@${this._$instanceId}`; - message.buffer = recodes; - - const options: ArrayBuffer[] = $getArray(recodes.buffer); - $rendererWorker.postMessage(message, options); - - $poolRenderMessageObject(message); - $poolArray(options); - - buffer[2] = graphics._$maxAlpha; - buffer[3] = +graphics._$canDraw; - } - - // bounds - const bounds: BoundsImpl = this._$getBounds(); - buffer[index++] = bounds.xMin; - buffer[index++] = bounds.yMin; - buffer[index++] = bounds.xMax; - buffer[index++] = bounds.yMax; - - // characterId - buffer[index++] = this._$characterId > -1 ? this._$characterId : -1; - - // loaderInfoId - buffer[index++] = this._$loaderInfo ? this._$loaderInfo._$id : -1; - - // property - this._$registerProperty(buffer, index); - - const message: PropertyMessageMapImpl = $getRenderMessageObject(); - message.command = "createShape"; - message.buffer = buffer; - - const options: ArrayBuffer[] = $getArray(buffer.buffer); - $rendererWorker.postMessage(message, options); - - $poolRenderMessageObject(message); - $poolArray(options); - } - - /** - * @return {void} - * @method - * @private - */ - _$postProperty (): void - { - if (!this._$created || !$rendererWorker) { - return ; - } - - const message: PropertyMessageMapImpl = this._$createMessage(); - - const graphics: Graphics | null = this._$graphics; - if (graphics && !graphics._$posted) { - - message.maxAlpha = graphics._$maxAlpha; - message.canDraw = graphics._$canDraw; - - const recodes: Float32Array = graphics._$getRecodes(); - message.recodes = recodes; - - const options: ArrayBuffer[] = $getArray(recodes.buffer); - - const bounds: BoundsImpl = this._$getBounds(); - message.xMin = bounds.xMin; - message.yMin = bounds.yMin; - message.xMax = bounds.xMax; - message.yMax = bounds.yMax; - - $rendererWorker - .postMessage(message, options); - - $poolArray(options); - - } else { - - $rendererWorker - .postMessage(message); - - } - - this._$posted = true; - this._$updated = false; - } + // /** + // * @param {object} character + // * @param {LoaderInfo} loaderInfo + // * @return {void} + // * @method + // * @private + // */ + // _$buildCharacter ( + // character: Character, + // loaderInfo: LoaderInfo + // ): void { + + // const graphics: Graphics = this.graphics; + + // if (!loaderInfo._$data) { + // throw new Error("the loaderInfo data is null."); + // } + + // if (character.recodes) { + + // switch (true) { + + // case character.bitmapId > 0: + // { + // const bitmap: Character = loaderInfo + // ._$data + // .characters[character.bitmapId]; + + // if (!bitmap.buffer) { + // throw new Error("the bitmap buffer is null."); + // } + + // const width: number = $Math.abs(bitmap.bounds.xMax - bitmap.bounds.xMin); + // const height: number = $Math.abs(bitmap.bounds.yMax - bitmap.bounds.yMin); + + // const bitmapData: BitmapData = new BitmapData(width, height); + // if (!bitmap._$buffer) { + // bitmap._$buffer = new Uint8Array(bitmap.buffer); + // $poolArray(bitmap.buffer); + // bitmap.buffer = null; + // } + // bitmapData.buffer = bitmap._$buffer.slice(); + + // // setup + // graphics._$recode = $getArray(); + + // if (width === character.bounds.xMax - character.bounds.xMin + // && height === character.bounds.yMax - character.bounds.yMin + // ) { + // graphics._$bitmapId = character.bitmapId; + // graphics._$mode = "bitmap"; + // } + + // // clone + // const recodes: any[] = character.recodes; + // if (recodes[recodes.length - 1] === Graphics.END_FILL) { + + // const length: number = recodes.length - 6; + // for (let idx: number = 0; idx < length; ++idx) { + // graphics._$recode.push(recodes[idx]); + // } + + // // add Bitmap Fill + // graphics._$recode.push( + // Graphics.BITMAP_FILL, + // bitmapData, + // null, + // "repeat", + // false + // ); + + // } else { + + // const width: number = recodes[recodes.length - 9]; + // const caps: CapsStyleImpl = recodes[recodes.length - 8]; + // const joints: JointStyleImpl = recodes[recodes.length - 7]; + // const miterLimit: number = recodes[recodes.length - 6]; + + // const length: number = recodes.length - 10; + // for (let idx: number = 0; idx < length; ++idx) { + // graphics._$recode.push(recodes[idx]); + // } + + // graphics._$recode.push( + // Graphics.BITMAP_STROKE, + // width, + // caps, + // joints, + // miterLimit, + // bitmapData, + // $getFloat32Array6( + // 1, 0, 0, 1, character.bounds.xMin, character.bounds.yMin + // ), + // "repeat", + // false + // ); + // } + // } + // break; + + // case character.inBitmap: + // { + // // setup + // graphics._$recode = $getArray(); + + // const recodes: any[] = character.recodes; + // for (let idx: number = 0; idx < recodes.length; ++idx) { + + // const value: BitmapData = recodes[idx]; + // graphics._$recode[idx] = value; + + // if (typeof value !== "object") { + // continue; + // } + + // if (!value.buffer) { + // continue; + // } + + // const bitmapData: BitmapData = new BitmapData( + // value.width, value.height + // ); + // bitmapData.buffer = new Uint8Array(value.buffer); + // graphics._$recode[idx++] = bitmapData; + + // const matrix: number[] = recodes[idx]; + // graphics._$recode[idx] = $getFloat32Array6( + // matrix[0], matrix[1], matrix[2], + // matrix[3], matrix[4], matrix[5] + // ); + + // if (value.width === character.bounds.xMax - character.bounds.xMin + // && value.height === character.bounds.yMax - character.bounds.yMin + // ) { + // graphics._$bitmapId = character.bitmapId; + // graphics._$mode = "bitmap"; + // } + // } + // } + // break; + + // default: + // graphics._$recode = character.recodes.slice(0); + // break; + + // } + + // } else { + + // graphics._$mode = "bitmap"; + + // const width: number = $Math.abs(character.bounds.xMax - character.bounds.xMin); + // const height: number = $Math.abs(character.bounds.yMax - character.bounds.yMin); + + // const bitmapData: BitmapData = new BitmapData(width, height); + // if (!character._$buffer) { + // if (!character.buffer) { + // throw new Error("the bitmap buffer is null."); + // } + // character._$buffer = new Uint8Array(character.buffer); + // $poolArray(character.buffer); + // character.buffer = null; + // } + // bitmapData.buffer = character._$buffer.slice(0); + + // graphics + // .beginBitmapFill(bitmapData, null, false) + // .drawRect(0, 0, width, height); + + // } + + // graphics._$maxAlpha = 1; + // graphics._$canDraw = true; + + // graphics._$xMin = character.bounds.xMin; + // graphics._$xMax = character.bounds.xMax; + // graphics._$yMin = character.bounds.yMin; + // graphics._$yMax = character.bounds.yMax; + + // // 9-scale + // if (character.grid) { + // this._$scale9Grid = new Rectangle( + // character.grid.x, character.grid.y, + // character.grid.w, character.grid.h + // ); + // } + + // if ($rendererWorker && this._$stage) { + // this._$createWorkerInstance(); + // } + // } + + // /** + // * @param {object} character + // * @return {void} + // * @method + // * @protected + // */ + // _$sync (character: ShapeCharacterImpl): void + // { + // if (this._$loaderInfo) { + // this._$buildCharacter(character, this._$loaderInfo); + // } + // } + + // /** + // * @param {object} tag + // * @param {DisplayObjectContainer} parent + // * @return {object} + // * @method + // * @private + // */ + // _$build ( + // tag: DictionaryTagImpl, + // parent: ParentImpl + // ): ShapeCharacterImpl { + + // const character: ShapeCharacterImpl = this + // ._$baseBuild(tag, parent); + + // this._$buildCharacter(character, parent._$loaderInfo); + + // return character; + // } + + // /** + // * @param {Float32Array} [matrix=null] + // * @returns {object} + // * @method + // * @private + // */ + // _$getBounds ( + // matrix: Float32Array | null = null + // ): BoundsImpl { + + // if (!this._$graphics) { + // return $getBoundsObject(0, 0, 0, 0); + // } + + // const baseBounds: BoundsImpl = this._$graphics._$getBounds(); + // if (!matrix) { + // return baseBounds; + // } + + // let multiMatrix: Float32Array = matrix; + + // const rawMatrix: Float32Array = this._$transform._$rawMatrix(); + // if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + // || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + // || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + // ) { + // multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + // } + + // const bounds: BoundsImpl = $boundsMatrix(baseBounds, multiMatrix); + // $poolBoundsObject(baseBounds); + + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + + // return bounds; + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @param {Float32Array} color_transform + // * @return {void} + // * @method + // * @private + // */ + // _$draw ( + // context: CanvasToWebGLContext, + // matrix: Float32Array, + // color_transform: Float32Array + // ): void { + + // if (!this._$visible) { + // return ; + // } + + // if (!this._$graphics || !this._$graphics._$canDraw) { + // return ; + // } + + // let multiColor: Float32Array = color_transform; + // const rawColor: Float32Array = this._$transform._$rawColorTransform(); + // if (rawColor !== $COLOR_ARRAY_IDENTITY + // && rawColor[0] !== 1 || rawColor[1] !== 1 + // || rawColor[2] !== 1 || rawColor[3] !== 1 + // || rawColor[4] !== 0 || rawColor[5] !== 0 + // || rawColor[6] !== 0 || rawColor[7] !== 0 + // ) { + // multiColor = $multiplicationColor(color_transform, rawColor); + // } + + // const alpha: number = $clamp(multiColor[3] + multiColor[7] / 255, 0, 1, 0); + // if (!alpha) { + // if (multiColor !== color_transform) { + // $poolFloat32Array8(multiColor); + // } + // return ; + // } + + // const filters: FilterArrayImpl | null = this._$filters || this.filters; + // const blendMode: BlendModeImpl = this._$blendMode || this.blendMode; + + // let multiMatrix: Float32Array = matrix; + // const rawMatrix: Float32Array = this._$transform._$rawMatrix(); + // if (rawMatrix !== $MATRIX_HIT_ARRAY_IDENTITY + // && rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + // || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + // || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + // ) { + // multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + // } + + // this + // ._$graphics + // ._$draw(context, multiMatrix, multiColor, blendMode, filters); + + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + + // if (multiColor !== color_transform) { + // $poolFloat32Array8(multiColor); + // } + + // } + + // /** + // * @param {CanvasToWebGLContext} context + // * @param {Float32Array} matrix + // * @returns {void} + // * @method + // * @private + // */ + // _$clip ( + // context: CanvasToWebGLContext, + // matrix: Float32Array + // ): void { + + // if (!this._$graphics) { + // return ; + // } + + // let multiMatrix: Float32Array = matrix; + // const rawMatrix: Float32Array = this._$transform._$rawMatrix(); + // if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + // || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + // || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + // ) { + // multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + // } + + // this._$graphics._$clip(context, multiMatrix); + + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + // } + + // /** + // * @param {CanvasRenderingContext2D} context + // * @param {Float32Array} matrix + // * @param {object} options + // * @return {boolean} + // * @method + // * @private + // */ + // _$mouseHit ( + // context: CanvasRenderingContext2D, + // matrix: Float32Array, + // options: PlayerHitObjectImpl + // ): boolean { + + // if (!this._$visible) { + // return false; + // } + + // return this._$hit(context, matrix, options); + // } + + // /** + // * @param {CanvasRenderingContext2D} context + // * @param {Float32Array} matrix + // * @param {object} options + // * @param {boolean} [is_clip=false] + // * @return {boolean} + // * @method + // * @private + // */ + // _$hit ( + // context: CanvasRenderingContext2D, + // matrix: Float32Array, + // options: PlayerHitObjectImpl, + // is_clip: boolean = false + // ): boolean { + + // let hit: boolean = false; + + // const graphics: Graphics | null = this._$graphics; + // if (graphics + // && graphics._$canDraw + // && graphics._$getBounds() + // ) { + + // let multiMatrix: Float32Array = matrix; + // const rawMatrix: Float32Array = this._$transform._$rawMatrix(); + // if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0 + // || rawMatrix[2] !== 0 || rawMatrix[3] !== 1 + // || rawMatrix[4] !== 0 || rawMatrix[5] !== 0 + // ) { + // multiMatrix = $multiplicationMatrix(matrix, rawMatrix); + // } + + // hit = graphics._$hit( + // context, + // multiMatrix, + // options, + // is_clip + // ); + + // if (multiMatrix !== matrix) { + // $poolFloat32Array6(multiMatrix); + // } + + // } + + // return hit; + // } } diff --git a/packages/display/src/Sprite.ts b/packages/display/src/Sprite.ts index d6675702..e3d97342 100644 --- a/packages/display/src/Sprite.ts +++ b/packages/display/src/Sprite.ts @@ -4,27 +4,13 @@ import type { Rectangle, Point } from "@next2d/geom"; -import type { - SpriteImpl, - DropTargetImpl, - DictionaryTagImpl, - ParentImpl, - MovieClipCharacterImpl -} from "@next2d/interface"; -import { - $currentMousePoint, - $dragRules, - $dropTarget, - $rendererWorker, - $setDropTarget -} from "@next2d/util"; /** - * Sprite クラスは、表示リストの基本的要素です。 - * グラフィックを表示でき、子を持つこともできる表示リストノードです。 + * @description Sprite クラスは、表示リストの基本的要素です。 + * グラフィックを表示でき、子を持つこともできる表示リストノードです。 * - * The Sprite class is a basic display list building block: - * a display list node that can display graphics and can also contain children. + * The Sprite class is a basic display list building block: + * a display list node that can display graphics and can also contain children. * * @class * @memberOf next2d.display @@ -79,7 +65,7 @@ export class Sprite extends DisplayObjectContainer * Returns the string representation of the specified class. * * @return {string} - * @default [class Sprite] + * @default "[class Sprite]" * @method * @static */ @@ -93,7 +79,7 @@ export class Sprite extends DisplayObjectContainer * Returns the space name of the specified class. * * @return {string} - * @default next2d.display.Sprite + * @default "next2d.display.Sprite" * @const * @static */ @@ -107,7 +93,7 @@ export class Sprite extends DisplayObjectContainer * Returns the string representation of the specified object. * * @return {string} - * @default [object Sprite] + * @default "[object Sprite]" * @method * @public */ @@ -121,7 +107,7 @@ export class Sprite extends DisplayObjectContainer * Returns the space name of the specified object. * * @return {string} - * @default next2d.display.Sprite + * @default "next2d.display.Sprite" * @const * @public */ @@ -147,62 +133,62 @@ export class Sprite extends DisplayObjectContainer this._$buttonMode = !!button_mode; } - /** - * @description スプライトのドラッグ先またはスプライトがドロップされた先の表示オブジェクトを指定します。 - * Specifies the display object over which the sprite is being dragged, - * or on which the sprite was dropped. - * - * @member {DisplayObject|null} - * @readonly - * @public - */ - get dropTarget (): DropTargetImpl - { - return $dropTarget; - } + // /** + // * @description スプライトのドラッグ先またはスプライトがドロップされた先の表示オブジェクトを指定します。 + // * Specifies the display object over which the sprite is being dragged, + // * or on which the sprite was dropped. + // * + // * @member {DisplayObject|null} + // * @readonly + // * @public + // */ + // get dropTarget (): DropTargetImpl + // { + // return $dropTarget; + // } - /** - * @description スプライトのヒット領域となる別のスプライトを指定します。 - * Designates another sprite to serve as the hit area for a sprite. - * - * @member {Sprite|null} - * @public - */ - get hitArea (): SpriteImpl | null - { - return this._$hitArea; - } - set hitArea (hit_area: SpriteImpl | null) - { - // reset - if (this._$hitArea) { - this._$hitArea._$hitObject = null; - } + // /** + // * @description スプライトのヒット領域となる別のスプライトを指定します。 + // * Designates another sprite to serve as the hit area for a sprite. + // * + // * @member {Sprite|null} + // * @public + // */ + // get hitArea (): SpriteImpl | null + // { + // return this._$hitArea; + // } + // set hitArea (hit_area: SpriteImpl | null) + // { + // // reset + // if (this._$hitArea) { + // this._$hitArea._$hitObject = null; + // } - this._$hitArea = hit_area; - if (hit_area) { - hit_area._$hitObject = this; - } - } + // this._$hitArea = hit_area; + // if (hit_area) { + // hit_area._$hitObject = this; + // } + // } - /** - * @description このスプライト内のサウンドを制御します。 - * Controls sound within this sprite. - * - * @member {SoundTransform} - * @public - */ - get soundTransform (): SoundTransform - { - if (!this._$soundTransform) { - this._$soundTransform = new SoundTransform(); - } - return this._$soundTransform; - } - set soundTransform (sound_transform: SoundTransform | null) - { - this._$soundTransform = sound_transform; - } + // /** + // * @description このスプライト内のサウンドを制御します。 + // * Controls sound within this sprite. + // * + // * @member {SoundTransform} + // * @public + // */ + // get soundTransform (): SoundTransform + // { + // if (!this._$soundTransform) { + // this._$soundTransform = new SoundTransform(); + // } + // return this._$soundTransform; + // } + // set soundTransform (sound_transform: SoundTransform | null) + // { + // this._$soundTransform = sound_transform; + // } /** * @description buttonMode プロパティが true に設定されたスプライト上にポインターが移動したときに、 @@ -224,109 +210,109 @@ export class Sprite extends DisplayObjectContainer this._$useHandCursor = use_hand_cursor; } - /** - * @description 指定されたスプライトをユーザーがドラッグできるようにします。 - * Lets the user drag the specified sprite. - * - * @param {boolean} [lock_center=false] - * @param {Rectangle} [bounds=null] - * @return {void} - * @method - * @public - */ - startDrag ( - lock_center: boolean = false, - bounds: Rectangle | null = null - ): void { + // /** + // * @description 指定されたスプライトをユーザーがドラッグできるようにします。 + // * Lets the user drag the specified sprite. + // * + // * @param {boolean} [lock_center=false] + // * @param {Rectangle} [bounds=null] + // * @return {void} + // * @method + // * @public + // */ + // startDrag ( + // lock_center: boolean = false, + // bounds: Rectangle | null = null + // ): void { - let x: number = 0; - let y: number = 0; + // let x: number = 0; + // let y: number = 0; - if (!lock_center) { - const point: Point = this._$dragMousePoint(); - x = this.x - point.x; - y = this.y - point.y; - } + // if (!lock_center) { + // const point: Point = this._$dragMousePoint(); + // x = this.x - point.x; + // y = this.y - point.y; + // } - $setDropTarget(this); - $dragRules.lock = lock_center; - $dragRules.position.x = x; - $dragRules.position.y = y; - $dragRules.bounds = bounds; - } + // $setDropTarget(this); + // $dragRules.lock = lock_center; + // $dragRules.position.x = x; + // $dragRules.position.y = y; + // $dragRules.bounds = bounds; + // } - /** - * @description startDrag() メソッドを終了します。 - * Ends the startDrag() method. - * - * @return void - * @method - * @public - */ - stopDrag () - { - // reset - $setDropTarget(null); - $dragRules.lock = false; - $dragRules.position.x = 0; - $dragRules.position.y = 0; - $dragRules.bounds = null; - } + // /** + // * @description startDrag() メソッドを終了します。 + // * Ends the startDrag() method. + // * + // * @return void + // * @method + // * @public + // */ + // stopDrag () + // { + // // reset + // $setDropTarget(null); + // $dragRules.lock = false; + // $dragRules.position.x = 0; + // $dragRules.position.y = 0; + // $dragRules.bounds = null; + // } - /** - * @param {object} character - * @return {void} - * @method - * @private - */ - _$sync (character: MovieClipCharacterImpl): void - { - if ($rendererWorker && this._$stage) { - this._$createWorkerInstance(); - } + // /** + // * @param {object} character + // * @return {void} + // * @method + // * @private + // */ + // _$sync (character: MovieClipCharacterImpl): void + // { + // if ($rendererWorker && this._$stage) { + // this._$createWorkerInstance(); + // } - this._$controller = character.controller; - this._$dictionary = character.dictionary; - this._$placeMap = character.placeMap; - this._$placeObjects = character.placeObjects; - } + // this._$controller = character.controller; + // this._$dictionary = character.dictionary; + // this._$placeMap = character.placeMap; + // this._$placeObjects = character.placeObjects; + // } - /** - * @param {object} tag - * @param {DisplayObjectContainer} parent - * @return {object} - * @method - * @private - */ - _$build ( - tag: DictionaryTagImpl, - parent: ParentImpl - ): MovieClipCharacterImpl { + // /** + // * @param {object} tag + // * @param {DisplayObjectContainer} parent + // * @return {object} + // * @method + // * @private + // */ + // _$build ( + // tag: DictionaryTagImpl, + // parent: ParentImpl + // ): MovieClipCharacterImpl { - const character: MovieClipCharacterImpl = this - ._$baseBuild(tag, parent); + // const character: MovieClipCharacterImpl = this + // ._$baseBuild(tag, parent); - if ($rendererWorker && this._$stage) { - this._$createWorkerInstance(); - } + // if ($rendererWorker && this._$stage) { + // this._$createWorkerInstance(); + // } - this._$controller = character.controller; - this._$dictionary = character.dictionary; - this._$placeMap = character.placeMap; - this._$placeObjects = character.placeObjects; + // this._$controller = character.controller; + // this._$dictionary = character.dictionary; + // this._$placeMap = character.placeMap; + // this._$placeObjects = character.placeObjects; - return character; - } + // return character; + // } - /** - * @return {Point} - * @method - * @private - */ - _$dragMousePoint (): Point - { - return this._$parent - ? this._$parent.globalToLocal($currentMousePoint()) - : this.globalToLocal($currentMousePoint()); - } + // /** + // * @return {Point} + // * @method + // * @private + // */ + // _$dragMousePoint (): Point + // { + // return this._$parent + // ? this._$parent.globalToLocal($currentMousePoint()) + // : this.globalToLocal($currentMousePoint()); + // } } diff --git a/packages/display/src/index.ts b/packages/display/src/index.ts index 1810b63a..75049b53 100644 --- a/packages/display/src/index.ts +++ b/packages/display/src/index.ts @@ -1,6 +1,7 @@ export * from "./BitmapData"; export * from "./BlendMode"; export * from "./DisplayObject"; +export * from "./DisplayObjectContainer"; export * from "./FrameLabel"; export * from "./Graphics"; export * from "./InteractiveObject"; @@ -10,5 +11,4 @@ export * from "./LoopType"; export * from "./MovieClip"; export * from "./Shape"; export * from "./Sprite"; -export * from "./Stage"; -export * from "../../text/src/TextField"; \ No newline at end of file +export * from "./Stage"; \ No newline at end of file diff --git a/packages/display/src/interface/DictionaryTagImpl.ts b/packages/display/src/interface/DictionaryTagImpl.ts index a441e1e6..d1aa1bc6 100644 --- a/packages/display/src/interface/DictionaryTagImpl.ts +++ b/packages/display/src/interface/DictionaryTagImpl.ts @@ -3,5 +3,6 @@ export interface DictionaryTagImpl { name: string; startFrame: number; endFrame: number; + depth: number; clipDepth: number; } \ No newline at end of file diff --git a/packages/display/src/interface/MovieClipActionObjectImpl.ts b/packages/display/src/interface/MovieClipActionObjectImpl.ts new file mode 100644 index 00000000..023a8655 --- /dev/null +++ b/packages/display/src/interface/MovieClipActionObjectImpl.ts @@ -0,0 +1,5 @@ +export interface MovieClipActionObjectImpl { + frame: number; + action: string; + script?: Function; +} \ No newline at end of file diff --git a/packages/display/src/interface/MovieClipCharacterImpl.ts b/packages/display/src/interface/MovieClipCharacterImpl.ts new file mode 100644 index 00000000..431eada1 --- /dev/null +++ b/packages/display/src/interface/MovieClipCharacterImpl.ts @@ -0,0 +1,19 @@ +import { CharacterImpl } from "./CharacterImpl"; +import { MovieClipSoundObjectImpl } from "./MovieClipSoundObjectImpl"; +import { MovieClipActionObjectImpl } from "./MovieClipActionObjectImpl"; +import { MovieClipLabelObjectImpl } from "./MovieClipLabelObjectImpl"; +import { PlaceObjectImpl } from "./PlaceObjectImpl"; +import { DictionaryTagImpl } from "./DictionaryTagImpl"; + +export interface MovieClipCharacterImpl extends CharacterImpl { + extends: string; + totalFrame: number; + controller: Array>; + dictionary: DictionaryTagImpl[]; + placeMap: Array>; + placeObjects: PlaceObjectImpl[]; + labels?: MovieClipLabelObjectImpl[]; + actions?: MovieClipActionObjectImpl[]; + symbol?: string; + sounds?: MovieClipSoundObjectImpl[]; +} \ No newline at end of file diff --git a/packages/display/src/interface/MovieClipLabelObjectImpl.ts b/packages/display/src/interface/MovieClipLabelObjectImpl.ts new file mode 100644 index 00000000..85b40e77 --- /dev/null +++ b/packages/display/src/interface/MovieClipLabelObjectImpl.ts @@ -0,0 +1,4 @@ +export interface MovieClipLabelObjectImpl { + name: string; + frame: number; +} \ No newline at end of file diff --git a/packages/display/src/interface/MovieClipSoundObjectImpl.ts b/packages/display/src/interface/MovieClipSoundObjectImpl.ts new file mode 100644 index 00000000..187d6d7f --- /dev/null +++ b/packages/display/src/interface/MovieClipSoundObjectImpl.ts @@ -0,0 +1,6 @@ +import type { SoundTagImpl } from "./SoundTagImpl"; + +export interface MovieClipSoundObjectImpl { + frame: number; + sound: SoundTagImpl[]; +} \ No newline at end of file diff --git a/packages/display/src/interface/NoCodeDataImpl.ts b/packages/display/src/interface/NoCodeDataImpl.ts index 2cf30a8b..c503651f 100644 --- a/packages/display/src/interface/NoCodeDataImpl.ts +++ b/packages/display/src/interface/NoCodeDataImpl.ts @@ -3,6 +3,6 @@ import { StageDataImpl } from "./StageDataImpl"; export interface NoCodeDataImpl { type: "json"; stage: StageDataImpl; - characters: any[]; - symbols: any[]; + characters: any[]; // todo + symbols: any[]; // todo } \ No newline at end of file diff --git a/packages/display/src/interface/ParentImpl.ts b/packages/display/src/interface/ParentImpl.ts index 1bea3398..a9f21336 100644 --- a/packages/display/src/interface/ParentImpl.ts +++ b/packages/display/src/interface/ParentImpl.ts @@ -1,3 +1,3 @@ -import type { DisplayObjectContainer } from "@next2d/display"; +import type { DisplayObjectContainer } from "@next2d/display"; export type ParentImpl = T; \ No newline at end of file diff --git a/packages/display/src/interface/SoundTagImpl.ts b/packages/display/src/interface/SoundTagImpl.ts new file mode 100644 index 00000000..1f87f809 --- /dev/null +++ b/packages/display/src/interface/SoundTagImpl.ts @@ -0,0 +1,6 @@ +export interface SoundTagImpl { + characterId: number; + volume: number; + autoPlay: boolean; + loopCount: number; +} \ No newline at end of file diff --git a/packages/media/src/Sound.ts b/packages/media/src/Sound.ts index 1403466d..e0474480 100644 --- a/packages/media/src/Sound.ts +++ b/packages/media/src/Sound.ts @@ -1,4 +1,4 @@ -import type { SoundTagImpl } from "./interface/SoundTagImpl"; +import type { Character } from "./interface/Character"; import { URLRequest } from "@next2d/net"; import { SoundMixer } from "./SoundMixer"; import { execute as soundLoadStartEventService } from "./Sound/SoundLoadStartEventService"; @@ -6,17 +6,13 @@ import { execute as soundProgressEventService } from "./Sound/SoundProgressEvent import { execute as soundLoadEndEventService } from "./Sound/SoundLoadEndEventService"; import { execute as soundEndedEventService } from "./Sound/SoundEndedEventService"; import { execute as soundDecodeService } from "./Sound/SoundDecodeService"; -import { - Event, - EventDispatcher -} from "@next2d/events"; +import { EventDispatcher } from "@next2d/events"; import { $clamp, $ajax, $audioContext, $getSounds } from "./MediaUtil"; -import { LoaderInfo } from "packages/display/src/LoaderInfo"; /** * @description Sound クラスを使用すると、アプリケーション内のサウンドを処理することができます。 @@ -274,11 +270,11 @@ export class Sound extends EventDispatcher * @method * @public */ - load (request: URLRequest): Promise + async load (request: URLRequest): Promise { this._$src = request.url; - return new Promise((resolve): void => + await new Promise((resolve): void => { $ajax({ "format": "arraybuffer", @@ -378,42 +374,26 @@ export class Sound extends EventDispatcher } /** - * @param {object} tag - * @param {MovieClip} parent + * @description Character DataからSoundを作成 + * Create Sound from Character Data + * + * @param {Character} character * @return {void} * @method * @private */ - async _$build ( - tag: SoundTagImpl, - parent: any - ): Promise { - - const loaderInfo: LoaderInfo | null = parent.loaderInfo; - if (!loaderInfo || !loaderInfo.data) { - throw new Error("the loaderInfo or data is null."); - } - - const character = loaderInfo - .data - .characters[tag.characterId]; - - if (!character) { - throw new Error("character is null."); - } - - this._$loopCount = tag.loopCount | 0; - this._$volume = Math.min(SoundMixer.volume, tag.volume); - + async build (character: Character): Promise + { // load AudioBuffer if (!character.audioBuffer) { const audioBuffer = await soundDecodeService(character.buffer.buffer); - if (audioBuffer) { - this._$audioBuffer = character.audioBuffer = audioBuffer; - if (this.hasEventListener(Event.COMPLETE)) { - this.dispatchEvent(new Event(Event.COMPLETE)); - } + if (!audioBuffer) { + return ; } + + character.audioBuffer = audioBuffer; } + + this._$audioBuffer = character.audioBuffer; } } \ No newline at end of file diff --git a/packages/media/src/interface/Character.ts b/packages/media/src/interface/Character.ts new file mode 100644 index 00000000..7b37721a --- /dev/null +++ b/packages/media/src/interface/Character.ts @@ -0,0 +1,3 @@ +import { CharacterImpl } from "./CharacterImpl"; + +export type Character = T; \ No newline at end of file diff --git a/packages/media/src/interface/CharacterImpl.ts b/packages/media/src/interface/CharacterImpl.ts new file mode 100644 index 00000000..a4a2ac84 --- /dev/null +++ b/packages/media/src/interface/CharacterImpl.ts @@ -0,0 +1 @@ +export interface CharacterImpl {} \ No newline at end of file diff --git a/packages/text/src/index.ts b/packages/text/src/index.ts index 2b91645e..58385e78 100644 --- a/packages/text/src/index.ts +++ b/packages/text/src/index.ts @@ -1,3 +1,4 @@ +export * from "./TextField"; export * from "./TextFormat"; export * from "./TextParser"; export * from "./TextData"; \ No newline at end of file diff --git a/packages/util/src/Util.ts b/packages/util/src/Util.ts index 674f481b..88eef318 100644 --- a/packages/util/src/Util.ts +++ b/packages/util/src/Util.ts @@ -11,7 +11,7 @@ import { MovieClip, Shape } from "@next2d/display"; -import { TextField } from "@next2d/display"; +import { TextField } from "@next2d/text"; import { Video, Sound From fd2d65236acaa5098bc619fb6cf2ca50493e9420 Mon Sep 17 00:00:00 2001 From: ienaga Date: Sat, 3 Aug 2024 21:00:21 +0900 Subject: [PATCH 033/343] =?UTF-8?q?#154=20=E3=82=A4=E3=83=99=E3=82=93?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=81=AE=E5=9F=BA=E7=9B=A4=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 16 +- package.json | 2 +- packages/core/src/Events.ts | 6 +- packages/core/src/Next2D.ts | 2 +- packages/core/src/Next2D/LoadService.ts | 11 +- packages/core/src/Player.ts | 149 +------ packages/core/src/interface/EventsImpl.ts | 6 +- packages/display/src/DisplayObject.ts | 264 +----------- .../DisplayObjectBaseBuildService.ts | 10 +- .../display/src/DisplayObjectContainer.ts | 53 ++- .../display/src/Loader/LoaderBuildService.ts | 10 +- .../src/Loader/LoaderLoadEndEventService.ts | 6 +- .../src/Loader/LoaderLoadStartEventService.ts | 2 +- .../src/Loader/LoaderProgressEventService.ts | 2 +- packages/display/src/MovieClip.ts | 177 ++------ .../MovieClip/MovieClipAddActionsService.ts | 37 ++ .../MovieClip/MovieClipAddLabelsService.ts | 27 ++ .../src/MovieClip/MovieClipBuildService.ts | 92 ++--- .../MovieClip/MovieClipBuildSoundsService.ts | 55 +++ packages/display/src/Sprite.ts | 71 +--- packages/display/src/Stage.test.ts | 31 ++ packages/display/src/Stage.ts | 32 +- .../interface/MovieClipCharacterImpl copy.ts | 19 + packages/events/src/Event.test.ts | 89 +--- packages/events/src/Event.ts | 380 ++---------------- .../Event/EventFormatToStringService.test.ts | 13 - .../src/Event/EventFormatToStringService.ts | 31 -- packages/events/src/EventDispatcher.test.ts | 21 +- packages/events/src/EventDispatcher.ts | 39 +- ...tDispatcherAddEventListenerService.test.ts | 15 +- .../EventDispatcherAddEventListenerService.ts | 49 +-- ...ventDispatcherDispatchEventService.test.ts | 25 -- .../EventDispatcherDispatchEventService.ts | 46 +-- .../EventDispatcherHasEventListenerService.ts | 16 +- ...DispatcherRemoveAllEventListenerService.ts | 40 +- ...entDispatcherRemoveEventListenerService.ts | 38 +- .../EventDispatcherWillTriggerService.ts | 14 +- packages/events/src/EventPhase.test.ts | 21 +- packages/events/src/EventPhase.ts | 28 -- packages/events/src/EventUtil.ts | 16 +- packages/events/src/FocusEvent.test.ts | 25 +- packages/events/src/FocusEvent.ts | 58 +-- packages/events/src/HTTPStatusEvent.test.ts | 32 +- packages/events/src/HTTPStatusEvent.ts | 39 +- packages/events/src/IOErrorEvent.test.ts | 30 +- packages/events/src/IOErrorEvent.ts | 36 +- packages/events/src/JobEvent.test.ts | 28 ++ packages/events/src/JobEvent.ts | 68 ++++ packages/events/src/KeyboardEvent.test.ts | 28 ++ packages/events/src/KeyboardEvent.ts | 97 +++++ packages/events/src/MouseEvent.test.ts | 76 ---- packages/events/src/MouseEvent.ts | 250 ------------ packages/events/src/PointerEvent.test.ts | 52 +++ packages/events/src/PointerEvent.ts | 170 ++++++++ packages/events/src/ProgressEvent.test.ts | 20 +- packages/events/src/ProgressEvent.ts | 37 +- packages/events/src/VideoEvent.test.ts | 29 +- packages/events/src/VideoEvent.ts | 52 +-- packages/events/src/index.ts | 6 +- .../src/interface/EventDispatcherImpl.ts | 1 + packages/events/src/interface/EventImpl.ts | 1 + .../events/src/interface/EventListenerImpl.ts | 4 +- packages/media/src/Sound.test.ts | 16 - packages/media/src/Sound.ts | 148 +++---- .../src/Sound/SoundEndedEventService.test.ts | 2 +- .../media/src/Sound/SoundEndedEventService.ts | 4 +- .../src/Sound/SoundLoadStartEventService.ts | 2 +- .../src/Sound/SoundLoadendEventService.ts | 4 +- .../src/Sound/SoundProgressEventService.ts | 2 +- packages/media/src/SoundMixer.test.ts | 16 - packages/media/src/SoundMixer.ts | 28 -- packages/media/src/SoundTransform.test.ts | 16 - packages/media/src/SoundTransform.ts | 28 -- packages/media/src/Video.ts | 30 +- .../src/Video/VideoEndedEventService.test.ts | 4 +- .../media/src/Video/VideoEndedEventService.ts | 4 +- .../src/Video/VideoProgressEventService.ts | 4 +- packages/net/src/URLRequest.test.ts | 19 +- packages/net/src/URLRequest.ts | 243 +++-------- packages/ui/src/Easing.test.ts | 22 +- packages/ui/src/Easing.ts | 30 +- packages/ui/src/Job.test.ts | 22 +- packages/ui/src/Job.ts | 292 ++++---------- packages/ui/src/Job/JobUpdateFrameService.ts | 10 +- packages/ui/src/Tween.test.ts | 22 +- packages/ui/src/Tween.ts | 28 -- 86 files changed, 1213 insertions(+), 2883 deletions(-) create mode 100644 packages/display/src/MovieClip/MovieClipAddActionsService.ts create mode 100644 packages/display/src/MovieClip/MovieClipAddLabelsService.ts create mode 100644 packages/display/src/MovieClip/MovieClipBuildSoundsService.ts create mode 100644 packages/display/src/Stage.test.ts create mode 100644 packages/display/src/interface/MovieClipCharacterImpl copy.ts delete mode 100644 packages/events/src/Event/EventFormatToStringService.test.ts delete mode 100644 packages/events/src/Event/EventFormatToStringService.ts create mode 100644 packages/events/src/JobEvent.test.ts create mode 100644 packages/events/src/JobEvent.ts create mode 100644 packages/events/src/KeyboardEvent.test.ts create mode 100644 packages/events/src/KeyboardEvent.ts delete mode 100644 packages/events/src/MouseEvent.test.ts delete mode 100644 packages/events/src/MouseEvent.ts create mode 100644 packages/events/src/PointerEvent.test.ts create mode 100644 packages/events/src/PointerEvent.ts diff --git a/package-lock.json b/package-lock.json index f6834006..263a09f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "htmlparser2": "^9.1.0" }, "devDependencies": { - "@types/node": "^22.0.3", + "@types/node": "^22.1.0", "@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/parser": "^8.0.0", "@vitest/web-worker": "^2.0.5", @@ -995,13 +995,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.3.tgz", - "integrity": "sha512-/e0NZtK2gs6Vk2DoyrXSZZ4AlamqTkx0CcKx1Aq8/P4ITlRgU9OtVf5fl+LXkWWJce1M89pkSlH6lJJEnK7bQA==", + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", + "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.11.1" + "undici-types": "~6.13.0" } }, "node_modules/@typescript-eslint/eslint-plugin": { @@ -3406,9 +3406,9 @@ } }, "node_modules/undici-types": { - "version": "6.11.1", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz", - "integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", "dev": true, "license": "MIT" }, diff --git a/package.json b/package.json index 5eca89ed..b1e6a10d 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "htmlparser2": "^9.1.0" }, "devDependencies": { - "@types/node": "^22.0.3", + "@types/node": "^22.1.0", "@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/parser": "^8.0.0", "@vitest/web-worker": "^2.0.5", diff --git a/packages/core/src/Events.ts b/packages/core/src/Events.ts index 4971f0e9..fe972c99 100644 --- a/packages/core/src/Events.ts +++ b/packages/core/src/Events.ts @@ -6,7 +6,8 @@ import { FocusEvent, HTTPStatusEvent, IOErrorEvent, - MouseEvent, + PointerEvent, + JobEvent, ProgressEvent, VideoEvent } from "@next2d/events"; @@ -18,7 +19,8 @@ const events: EventsImpl = { FocusEvent, HTTPStatusEvent, IOErrorEvent, - MouseEvent, + PointerEvent, + JobEvent, ProgressEvent, VideoEvent }; diff --git a/packages/core/src/Next2D.ts b/packages/core/src/Next2D.ts index 606e944b..1d342f29 100644 --- a/packages/core/src/Next2D.ts +++ b/packages/core/src/Next2D.ts @@ -123,7 +123,7 @@ export class Next2D * @method * @public */ - async load (url: string, options: PlayerOptionsImpl): Promise + async load (url: string, options: PlayerOptionsImpl | null = null): Promise { await Promise.all([this._$promise]); await loadService(url, options); diff --git a/packages/core/src/Next2D/LoadService.ts b/packages/core/src/Next2D/LoadService.ts index f148180c..8aa9e193 100644 --- a/packages/core/src/Next2D/LoadService.ts +++ b/packages/core/src/Next2D/LoadService.ts @@ -1,15 +1,18 @@ import type { PlayerOptionsImpl } from "../interface/PlayerOptionsImpl"; import type { StageDataImpl } from "../interface/StageDataImpl"; +import type { MovieClip } from "@next2d/display"; import { $player } from "../Player"; -import { $stage } from "../Stage"; import { $clamp } from "../CoreUtil"; import { URLRequest } from "@next2d/net"; import { IOErrorEvent } from "@next2d/events"; -import { Loader } from "@next2d/display"; import { execute as playerResizeEventService } from "../Player/PlayerResizeEventService"; import { execute as playerRemoveLoadingElementService } from "../Player/PlayerRemoveLoadingElementService"; import { execute as playerAppendCanvasElementService } from "../Player/PlayerAppendCanvasElementService"; import { execute as playerReadyCompleteService } from "../Player/PlayerReadyCompleteService"; +import { + Loader, + $stage +} from "@next2d/display"; /** * @description 指定のURLからJSONファイルを読み込みます。 @@ -21,7 +24,7 @@ import { execute as playerReadyCompleteService } from "../Player/PlayerReadyComp * @method * @protected */ -export const execute = async (url: string, options: PlayerOptionsImpl): Promise => +export const execute = async (url: string, options: PlayerOptionsImpl | null = null): Promise => { if (url === "develop") { const path: string = location @@ -67,7 +70,7 @@ export const execute = async (url: string, options: PlayerOptionsImpl): Promise< $player.frameRate = $clamp(stageData.fps, 1, 60, 60); $player.bgColor = stageData.bgColor; - // $stage.addChild(loaderInfo.content); + $stage.addChild(loaderInfo.content as MovieClip); // resize playerResizeEventService(); diff --git a/packages/core/src/Player.ts b/packages/core/src/Player.ts index e8750a48..3aa9f519 100644 --- a/packages/core/src/Player.ts +++ b/packages/core/src/Player.ts @@ -1,20 +1,8 @@ import type { PlayerModeImpl } from "./interface/PlayerModeImpl"; -import type { EventDispatcherImpl } from "./interface/EventDispatcherImpl"; -// import type { ParentImpl } from "./interface/ParentImpl"; -// import type { PlayerHitObjectImpl } from "./interface/PlayerHitObjectImpl"; import type { PlayerOptionsImpl } from "./interface/PlayerOptionsImpl"; -// import type { -// MovieClip, -// TextField -// } from "@next2d/display"; +import type { MovieClip } from "@next2d/display"; import { SoundMixer } from "@next2d/media"; -import { $cacheStore } from "@next2d/cache"; -import { - $devicePixelRatio, - $LOAD_START, - $LOAD_END, - $PREFIX -} from "./CoreUtil"; +import { $devicePixelRatio } from "./CoreUtil"; import { execute as playerCreateContainerElementService } from "./Player/PlayerCreateContainerElementService"; import { execute as playerApplyContainerElementStyleService } from "./Player/PlayerApplyContainerElementStyleService"; import { execute as playerLoadingAnimationService } from "./Player/PlayerLoadingAnimationService"; @@ -31,8 +19,7 @@ import { execute as playerUpdateBackgroundColorPostMessageService } from "./Play */ export class Player { - // private readonly _$actions: MovieClip[]; - private readonly _$loaders: EventDispatcherImpl[]; + private readonly _$actions: MovieClip[]; // private readonly _$sounds: Map; // private readonly _$hitObject: PlayerHitObjectImpl; private readonly _$matrix: Float32Array; @@ -45,7 +32,6 @@ export class Player private _$fixedHeight: number; private _$frameRate: number; private _$stopFlag: boolean; - private _$loadStatus: number; private _$scale: number; // private _$state: "up" | "down"; // private _$textField: TextField | null; @@ -53,7 +39,7 @@ export class Player // private _$rollOverObject: EventDispatcherImpl | null; // private _$mouseOverTarget: EventDispatcherImpl | null; // private _$startTime: number; - // private _$fps: number; + private _$fps: number; // private _$hitTestStart: boolean; // private _$stageX: number; // private _$stageY: number; @@ -61,7 +47,6 @@ export class Player private _$bgColor: string; private _$fullScreen: boolean; private _$timerId: number; - private _$loadId: number; // private _$deltaX: number; // private _$deltaY: number; // private _$clickTarget: ParentImpl | null; @@ -79,17 +64,11 @@ export class Player */ this._$mode = "loader"; - // /** - // * @type {array} - // * @private - // */ - // this._$actions = []; - /** * @type {array} - * @public + * @private */ - this._$loaders = []; + this._$actions = []; // /** // * @type {Map} @@ -143,19 +122,12 @@ export class Player // */ // this._$startTime = 0; - // /** - // * @type {number} - // * @default 16 - // * @private - // */ - // this._$fps = 16; - /** * @type {number} - * @default 0 + * @default 16 * @private */ - this._$loadStatus = 0; + this._$fps = 16; // /** // * @type {number} @@ -677,7 +649,7 @@ export class Player } // initialize resize - playerResizeEventService(this); + playerResizeEventService(); } // /** @@ -752,109 +724,6 @@ export class Player // } - // // @ts-ignore - // this._$canvas.addEventListener($TOUCH_START, (event: TouchEvent) => - // { - // $setEvent(event); - // $setEventType($TOUCH_START); - - // // start position - // this._$hitTest(); - // }); - - // // @ts-ignore - // this._$canvas.addEventListener($TOUCH_MOVE, (event: TouchEvent) => - // { - // $setEvent(event); - // $setEventType($TOUCH_MOVE); - // this._$hitTest(); - // }); - - // // @ts-ignore - // this._$canvas.addEventListener($TOUCH_END, (event: TouchEvent) => - // { - // $setEvent(event); - // $setEventType($TOUCH_END); - // this._$hitTest(); - // }); - - // // @ts-ignore - // this._$canvas.addEventListener($TOUCH_MOVE, (event: TouchEvent) => - // { - // $setEvent(event); - // $setEventType($TOUCH_MOVE); - - // this._$hitTest(); - // }, { "passive": false }); - - // // @ts-ignore - // this._$canvas.addEventListener($MOUSE_DOWN, (event: MouseEvent) => - // { - // $setEvent(event); - // $setEventType($MOUSE_DOWN); - - // if (!event.button) { - // this._$hitTest(); - // } - // }); - - // // @ts-ignore - // this._$canvas.addEventListener($DOUBLE_CLICK, (event: MouseEvent) => - // { - // $setEvent(event); - // $setEventType($DOUBLE_CLICK); - - // if (!event.button) { - // this._$hitTest(); - // } - // }); - - // // @ts-ignore - // this._$canvas.addEventListener($MOUSE_LEAVE, (event: MouseEvent) => - // { - // $setEvent(event); - // $setEventType($MOUSE_LEAVE); - - // this._$hitTest(); - - // $setEvent(null); - // this._$stageX = -1; - // this._$stageY = -1; - // }); - - // // @ts-ignore - // this._$canvas.addEventListener($MOUSE_UP, (event: MouseEvent) => - // { - // $setEvent(event); - // $setEventType($MOUSE_UP); - - // if (!event.button) { - // this._$hitTest(); - // } - // }); - - // // @ts-ignore - // this._$canvas.addEventListener($MOUSE_MOVE, (event: MouseEvent) => - // { - // $setEvent(event); - // $setEventType($MOUSE_MOVE); - - // this._$hitTest(); - // }); - - // // @ts-ignore - // this._$canvas.addEventListener($MOUSE_WHEEL, (event: MouseEvent) => - // { - // if (!event.defaultPrevented) { - - // $setEvent(event); - // $setEventType($MOUSE_WHEEL); - - // this._$hitTest(); - // } - // }, { "passive": false }); - // } - // /** // * @param {Event} event // * @return {boolean} diff --git a/packages/core/src/interface/EventsImpl.ts b/packages/core/src/interface/EventsImpl.ts index fd690483..f1577fee 100644 --- a/packages/core/src/interface/EventsImpl.ts +++ b/packages/core/src/interface/EventsImpl.ts @@ -5,7 +5,8 @@ import type { FocusEvent, HTTPStatusEvent, IOErrorEvent, - MouseEvent, + PointerEvent, + JobEvent, ProgressEvent, VideoEvent } from "@next2d/events"; @@ -17,7 +18,8 @@ export interface EventsImpl { FocusEvent: typeof FocusEvent; HTTPStatusEvent: typeof HTTPStatusEvent; IOErrorEvent: typeof IOErrorEvent; - MouseEvent: typeof MouseEvent; + PointerEvent: typeof PointerEvent; + JobEvent: typeof JobEvent; ProgressEvent: typeof ProgressEvent; VideoEvent: typeof VideoEvent; } \ No newline at end of file diff --git a/packages/display/src/DisplayObject.ts b/packages/display/src/DisplayObject.ts index e8798a6d..4b763012 100644 --- a/packages/display/src/DisplayObject.ts +++ b/packages/display/src/DisplayObject.ts @@ -1,6 +1,8 @@ import type { Stage } from "./Stage"; import type { LoaderInfo } from "./LoaderInfo"; import type { Sprite } from "./Sprite"; +import type { ParentImpl } from "./interface/ParentImpl"; + import { Event as Next2DEvent, EventDispatcher @@ -20,6 +22,7 @@ import { $getInstanceId } from "./DisplayObjectUtil"; + /** * @description DisplayObject クラスは、表示リストに含めることのできるすべてのオブジェクトに関する基本クラスです。 * DisplayObject クラス自体は、画面上でのコンテンツの描画のための API を含みません。 @@ -59,7 +62,7 @@ export class DisplayObject extends EventDispatcher protected _$name: string; protected _$mask: DisplayObjectImpl | null; protected _$visible: boolean; - protected _$root: ParentImpl | null; + protected _$root: T | null; protected _$loaderInfo: LoaderInfo | null; protected _$scaleX: number | null; protected _$scaleY: number | null; @@ -2122,263 +2125,4 @@ export class DisplayObject extends EventDispatcher // return true; // } - // /** - // * @return {void} - // * @method - // * @private - // */ - // _$removeWorkerInstance (): void - // { - // if ($rendererWorker) { - // $rendererWorker.postMessage({ - // "command": "remove", - // "instanceId": this._$instanceId - // }); - // } - // } - - // /** - // * @param {Float32Array} buffer - // * @param {number} [index = 0] - // * @return {void} - // * @method - // * @private - // */ - // _$registerProperty (buffer: Float32Array, index: number = 0): void - // { - // // visible - // buffer[index++] = +this._$visible; - - // // depth - // buffer[index++] = this._$placeId; - - // // clip depth - // buffer[index++] = this._$clipDepth; - - // // isMask - // buffer[index++] = +this._$isMask; - - // const mask: DisplayObjectImpl | null = this._$mask; - // buffer[index++] = +(mask !== null); - // if (mask) { - - // // mask id - // buffer[index++] = mask._$instanceId; - - // let maskMatrix: Float32Array = $MATRIX_ARRAY_IDENTITY; - // let parent: ParentImpl | null = mask._$parent; - // while (parent) { - - // maskMatrix = $multiplicationMatrix( - // parent._$transform._$rawMatrix(), - // maskMatrix - // ); - - // parent = parent._$parent; - // } - - // // mask matrix - // buffer[index++] = maskMatrix[0]; - // buffer[index++] = maskMatrix[1]; - // buffer[index++] = maskMatrix[2]; - // buffer[index++] = maskMatrix[3]; - // buffer[index++] = maskMatrix[4]; - // buffer[index++] = maskMatrix[5]; - // } else { - // index += 7; - // } - - // if (this._$visible) { - // const transform: Transform = this._$transform; - - // // matrix - // const matrix: Float32Array = transform._$rawMatrix(); - // buffer[index++] = matrix[0]; - // buffer[index++] = matrix[1]; - // buffer[index++] = matrix[2]; - // buffer[index++] = matrix[3]; - // buffer[index++] = matrix[4]; - // buffer[index++] = matrix[5]; - - // // colorTransform - // const colorTransform = transform._$rawColorTransform(); - // buffer[index++] = colorTransform[0]; - // buffer[index++] = colorTransform[1]; - // buffer[index++] = colorTransform[2]; - // buffer[index++] = colorTransform[3]; - // buffer[index++] = colorTransform[4]; - // buffer[index++] = colorTransform[5]; - // buffer[index++] = colorTransform[6]; - // buffer[index++] = colorTransform[7]; - - // } else { - // index += 6; // matrix - // index += 8; // colorTransform - // } - - // // blend mode - // const blendMode: BlendModeImpl = this._$blendMode || this.blendMode; - // buffer[index++] = $blendToNumber(blendMode); - - // // scale9Grid - // const scale9Grid: Rectangle | null = this._$scale9Grid; - // buffer[index++] = +(scale9Grid !== null); - - // if (scale9Grid) { - // buffer[index++] = scale9Grid.x; - // buffer[index++] = scale9Grid.y; - // buffer[index++] = scale9Grid.width; - // buffer[index++] = scale9Grid.height; - // } else { - // index += 4; - // } - - // // filter - // } - - // /** - // * @return {object} - // * @method - // * @private - // */ - // _$createMessage (): PropertyMessageMapImpl - // { - // const message: PropertyMessageImpl = { - // "command": "setProperty", - // "buffer": new Float32Array(), - // "instanceId": this._$instanceId, - // "parentId": this._$parent ? this._$parent._$instanceId : -1, - // "visible": this._$visible - // }; - - // if (this._$placeId > -1) { - // message.depth = this._$placeId; - // } - - // if (this._$clipDepth) { - // message.clipDepth = this._$clipDepth; - // } - - // if (this._$isMask) { - // message.isMask = this._$isMask; - // } - - // const mask: DisplayObjectImpl | null = this._$mask; - // if (mask) { - // message.maskId = mask._$instanceId; - - // let maskMatrix: Float32Array = $MATRIX_ARRAY_IDENTITY; - // let parent: ParentImpl | null = mask._$parent; - // while (parent) { - - // maskMatrix = $multiplicationMatrix( - // parent._$transform._$rawMatrix(), - // maskMatrix - // ); - - // parent = parent._$parent; - // } - - // message.maskMatrix = maskMatrix; - // } - - // if (this._$visible) { - - // const transform: Transform = this._$transform; - - // const matrix: Float32Array = transform._$rawMatrix(); - // if (matrix[0] !== 1) { - // message.a = matrix[0]; - // } - - // if (matrix[1] !== 0) { - // message.b = matrix[1]; - // } - - // if (matrix[2] !== 0) { - // message.c = matrix[2]; - // } - - // if (matrix[3] !== 1) { - // message.d = matrix[3]; - // } - - // if (matrix[4] !== 0) { - // message.tx = matrix[4]; - // } - - // if (matrix[5] !== 0) { - // message.ty = matrix[5]; - // } - - // const colorTransform = transform._$rawColorTransform(); - // if (colorTransform[0] !== 1) { - // message.f0 = colorTransform[0]; - // } - - // if (colorTransform[1] !== 1) { - // message.f1 = colorTransform[1]; - // } - - // if (colorTransform[2] !== 1) { - // message.f2 = colorTransform[2]; - // } - - // if (colorTransform[3] !== 1) { - // message.f3 = colorTransform[3]; - // } - - // if (colorTransform[4] !== 0) { - // message.f4 = colorTransform[4]; - // } - - // if (colorTransform[5] !== 0) { - // message.f5 = colorTransform[5]; - // } - - // if (colorTransform[6] !== 0) { - // message.f6 = colorTransform[6]; - // } - - // if (colorTransform[7] !== 0) { - // message.f7 = colorTransform[7]; - // } - - // const filters: FilterArrayImpl | null = this._$filters || this.filters; - // if (filters && filters.length) { - // const parameters: any[] = $getArray(); - // for (let idx: number = 0; idx < filters.length; ++idx) { - // parameters.push(filters[idx]._$toArray()); - // } - - // message.filters = parameters; - // } - - // const blendMode: BlendModeImpl = this._$blendMode || this.blendMode; - // if (blendMode !== "normal") { - // message.blendMode = blendMode; - // } - - // const scale9Grid: Rectangle | null = this._$scale9Grid; - // if (scale9Grid && this._$isUpdated()) { - - // const baseMatrix: Matrix = this - // ._$parent - // ._$transform - // .concatenatedMatrix; - - // message.matrixBase = baseMatrix._$matrix.slice(); - // $poolMatrix(baseMatrix); - - // message.grid = { - // "x": scale9Grid.x, - // "y": scale9Grid.y, - // "w": scale9Grid.width, - // "h": scale9Grid.height - // }; - // } - // } - - // return message; - // } } diff --git a/packages/display/src/DisplayObject/DisplayObjectBaseBuildService.ts b/packages/display/src/DisplayObject/DisplayObjectBaseBuildService.ts index 51162b76..e499a26b 100644 --- a/packages/display/src/DisplayObject/DisplayObjectBaseBuildService.ts +++ b/packages/display/src/DisplayObject/DisplayObjectBaseBuildService.ts @@ -1,8 +1,8 @@ -import type { DisplayObjectImpl } from "../interface/DisplayObjectImpl"; import type { DictionaryTagImpl } from "../interface/DictionaryTagImpl"; -import type { ParentImpl } from "../interface/ParentImpl"; import type { Character } from "../interface/Character"; import type { LoaderInfo } from "../LoaderInfo"; +import type { DisplayObject } from "../DisplayObject"; +import type { DisplayObjectContainer } from "../DisplayObjectContainer"; /** * @description DisplayObjectの基礎となる情報を設定、個別のCharacterを返却 @@ -15,10 +15,10 @@ import type { LoaderInfo } from "../LoaderInfo"; * @method * @public */ -export const execute = ( - display_object: DisplayObjectImpl, +export const execute = ( + display_object: D, tag: DictionaryTagImpl, - parent: ParentImpl + parent: P ): Character => { const loaderInfo = parent._$loaderInfo as LoaderInfo; diff --git a/packages/display/src/DisplayObjectContainer.ts b/packages/display/src/DisplayObjectContainer.ts index 1af55957..c9e097ab 100644 --- a/packages/display/src/DisplayObjectContainer.ts +++ b/packages/display/src/DisplayObjectContainer.ts @@ -1,15 +1,8 @@ import { InteractiveObject } from "./InteractiveObject"; -// import { Event as Next2DEvent } from "@next2d/events"; -// import type { LoaderInfo } from "./LoaderInfo"; -// import type { Sound } from "@next2d/media"; -// import type { Transform } from "@next2d/geom"; +import type { DisplayObject } from "./DisplayObject"; import type { PlaceObjectImpl } from "./interface/PlaceObjectImpl"; import type { DisplayObjectImpl } from "./interface/DisplayObjectImpl"; import type { DictionaryTagImpl } from "./interface/DictionaryTagImpl"; -// import type { -// CanvasToWebGLContext, -// FrameBufferManager -// } from "@next2d/webgl"; import { $getArray } from "./DisplayObjectUtil"; @@ -155,31 +148,31 @@ export class DisplayObjectContainer extends InteractiveObject // : this._$children.length; // } - // /** - // * @description この DisplayObjectContainer インスタンスに子 DisplayObject インスタンスを追加します。 - // * Adds a child DisplayObject instance to this DisplayObjectContainer instance. - // * - // * @param {DisplayObject} child - // * @return {DisplayObject} - // * @method - // * @public - // */ - // addChild (child: DisplayObjectImpl): DisplayObjectImpl - // { - // if (child._$parent) { - // child._$parent._$remove(child, - // !(child._$parent._$instanceId === this._$instanceId) - // ); - // } + /** + * @description この DisplayObjectContainer インスタンスに子 DisplayObject インスタンスを追加します。 + * Adds a child DisplayObject instance to this DisplayObjectContainer instance. + * + * @param {DisplayObject} display_object + * @return {DisplayObject} + * @method + * @public + */ + addChild (display_object: T): T + { + // if (child._$parent) { + // child._$parent._$remove(child, + // !(child._$parent._$instanceId === this._$instanceId) + // ); + // } - // this._$getChildren().push(child); + // this._$getChildren().push(child); - // if (child._$name) { - // this._$names.set(child._$name, child); - // } + // if (child._$name) { + // this._$names.set(child._$name, child); + // } - // return this._$addChild(child); - // } + return display_object;//this._$addChild(child); + } // /** // * @description この DisplayObjectContainer インスタンスに子 DisplayObject インスタンスを追加します。 diff --git a/packages/display/src/Loader/LoaderBuildService.ts b/packages/display/src/Loader/LoaderBuildService.ts index cdcb87bd..1ef0bf04 100644 --- a/packages/display/src/Loader/LoaderBuildService.ts +++ b/packages/display/src/Loader/LoaderBuildService.ts @@ -1,6 +1,6 @@ -import { DictionaryTagImpl } from "../interface/DictionaryTagImpl"; import type { NoCodeDataImpl } from "../interface/NoCodeDataImpl"; import type { Loader } from "../Loader"; +import { MovieClip } from "../MovieClip"; import { execute as movieClipBuildService } from "../MovieClip/MovieClipBuildService"; /** @@ -9,7 +9,7 @@ import { execute as movieClipBuildService } from "../MovieClip/MovieClipBuildSer * * @param {Loader} loader * @param {object} object - * @return {Promise} + * @return {Promise} * @method * @protected */ @@ -33,7 +33,8 @@ export const execute = async (loader: Loader, object: NoCodeDataImpl): Promise if (loader_info.willTrigger(Next2DProgressEvent.PROGRESS)) { loader_info.dispatchEvent(new Next2DProgressEvent( - Next2DProgressEvent.PROGRESS, false, false, + Next2DProgressEvent.PROGRESS, false, event.loaded, event.total )); } diff --git a/packages/display/src/Loader/LoaderProgressEventService.ts b/packages/display/src/Loader/LoaderProgressEventService.ts index 874eb3b8..88045cd1 100644 --- a/packages/display/src/Loader/LoaderProgressEventService.ts +++ b/packages/display/src/Loader/LoaderProgressEventService.ts @@ -15,7 +15,7 @@ export const execute = (loader_info: LoaderInfo, event: ProgressEvent): void => { if (loader_info.willTrigger(Next2DProgressEvent.PROGRESS)) { loader_info.dispatchEvent(new Next2DProgressEvent( - Next2DProgressEvent.PROGRESS, false, false, + Next2DProgressEvent.PROGRESS, false, event.loaded, event.total )); } diff --git a/packages/display/src/MovieClip.ts b/packages/display/src/MovieClip.ts index ff027bcd..518f9ba8 100644 --- a/packages/display/src/MovieClip.ts +++ b/packages/display/src/MovieClip.ts @@ -1,7 +1,10 @@ +import type { MovieClipCharacterImpl } from "./interface/MovieClipCharacterImpl"; +import type { DictionaryTagImpl } from "./interface/DictionaryTagImpl"; +import type { ParentImpl } from "./interface/ParentImpl"; import { Sprite } from "./Sprite"; import { FrameLabel } from "./FrameLabel"; import { Sound } from "@next2d/media"; -import type { SoundTransform } from "@next2d/media"; +import { execute as movieClipBuildService } from "./MovieClip/MovieClipBuildService"; /** * @description MovieClip クラスは、Sprite、DisplayObjectContainer、InteractiveObject、DisplayObject @@ -21,19 +24,19 @@ import type { SoundTransform } from "@next2d/media"; */ export class MovieClip extends Sprite { - private _$labels: Map | null; - public _$currentFrame: number; - public _$stopFlag: boolean; - public _$canAction: boolean; - public _$canSound: boolean; - public _$actionProcess: boolean; - public _$actions: Map; - public _$frameCache: Map; - public _$sounds: Map; - public _$actionOffset: number; - public _$actionLimit: number; - public _$totalFrames: number; - public _$isPlaying: boolean; + protected _$labels: Map | null; + protected _$currentFrame: number; + protected _$stopFlag: boolean; + protected _$canAction: boolean; + protected _$canSound: boolean; + protected _$actionProcess: boolean; + protected _$actions: Map | null; + protected _$frameCache: Map | null; + protected _$sounds: Map | null; + protected _$actionOffset: number; + protected _$actionLimit: number; + protected _$totalFrames: number; + protected _$isPlaying: boolean; // public _$loopConfig: LoopConfigImpl | null; // private _$tweenFrame: number; @@ -77,13 +80,13 @@ export class MovieClip extends Sprite * @type {Map} * @private */ - this._$actions = new Map(); + this._$actions = null; /** * @type {Map} * @private */ - this._$frameCache = new Map(); + this._$frameCache = null; /** * @type {Map} @@ -96,7 +99,7 @@ export class MovieClip extends Sprite * @type {Map} * @private */ - this._$sounds = new Map(); + this._$sounds = null; /** * @type {number} @@ -417,28 +420,22 @@ export class MovieClip extends Sprite this._$isPlaying = false; } - // /** - // * @description タイムラインに対して動的にLabelを追加できます。 - // * Labels can be added dynamically to the timeline. - // * - // * @example Example1 usage of addFrameLabel. - // * // case 1 - // * const {MovieClip, FrameLabel} = next2d.display; - // * const movieClip = new MovieClip(); - // * movieClip.addFrameLabel(new FrameLabel(1, "start")); - // * - // * @param {FrameLabel} frame_label - // * @return {void} - // * @public - // */ - // addFrameLabel (frame_label: FrameLabel): void - // { - // if (!this._$labels) { - // this._$labels = $getMap(); - // } + /** + * @description タイムラインに対して動的にLabelを追加できます。 + * Labels can be added dynamically to the timeline. + * + * @param {FrameLabel} frame_label + * @return {void} + * @public + */ + addFrameLabel (frame_label: FrameLabel): void + { + if (!this._$labels) { + this._$labels = new Map(); + } - // this._$labels.set(frame_label.frame, frame_label); - // } + this._$labels.set(frame_label.frame, frame_label); + } // /** // * @description 指定のフレームのアクションを追加できます @@ -528,28 +525,6 @@ export class MovieClip extends Sprite // return 0; // } - // /** - // * @param {number} frame - // * @param {function} script - // * @return {void} - // * @method - // * @private - // */ - // _$addAction (frame: number, script: Function): void - // { - // if (frame) { - // if (!this._$actions.has(frame)) { - // this._$actions.set(frame, $getArray()); - // } - - // const actions: Function[] | void = this._$actions.get(frame); - // if (actions) { - // actions.push(script); - // } - - // } - // } - // /** // * @return {void} // * @private @@ -1091,88 +1066,6 @@ export class MovieClip extends Sprite // return frame; // } - // /** - // * @param {object} character - // * @return {void} - // * @method - // * @private - // */ - // _$buildCharacter (character: MovieClipCharacterImpl): void - // { - // if (character.sounds) { - // for (let idx: number = 0; idx < character.sounds.length; ++idx) { - - // const object: MovieClipSoundObjectImpl = character.sounds[idx]; - - // const sounds: Sound[] = $getArray(); - // for (let idx: number = 0; idx < object.sound.length; ++idx) { - - // const sound: Sound = new Sound(); - // sound._$build(object.sound[idx], this); - - // sounds.push(sound); - // } - - // this._$sounds.set(object.frame, sounds); - // } - // } - - // if (character.actions) { - // for (let idx: number = 0; idx < character.actions.length; ++idx) { - - // const object: MovieClipActionObjectImpl = character.actions[idx]; - // if (!object.script) { - // object.script = Function(object.action); - // } - - // this._$addAction(object.frame, object.script); - // } - // } - - // if (character.labels) { - // for (let idx: number = 0; idx < character.labels.length; ++idx) { - - // const label: MovieClipLabelObjectImpl = character.labels[idx]; - - // this.addFrameLabel(new FrameLabel(label.name, label.frame)); - - // } - // } - - // this._$totalFrames = character.totalFrame || 1; - // } - - // /** - // * @param {object} character - // * @return {void} - // * @method - // * @private - // */ - // _$sync (character: Character): void - // { - // super._$sync(character); - // this._$buildCharacter(character); - // } - - // /** - // * @param {object} tag - // * @param {DisplayObjectContainer} parent - // * @return {object} - // * @method - // * @private - // */ - // _$build ( - // tag: DictionaryTagImpl, - // parent: ParentImpl - // ): MovieClipCharacterImpl { - - // const character: MovieClipCharacterImpl = super._$build(tag, parent); - - // this._$buildCharacter(character); - - // return character; - // } - // /** // * @return {void} // * @method diff --git a/packages/display/src/MovieClip/MovieClipAddActionsService.ts b/packages/display/src/MovieClip/MovieClipAddActionsService.ts new file mode 100644 index 00000000..e8c023a3 --- /dev/null +++ b/packages/display/src/MovieClip/MovieClipAddActionsService.ts @@ -0,0 +1,37 @@ +import type { MovieClipActionObjectImpl } from "../interface/MovieClipActionObjectImpl"; +import { $getArray } from "../DisplayObjectUtil"; + +/** + * @description 指定フレームに関数を追加 + * Add a function to the specified frame + * + * @param {Map} actions + * @param {array} objects + * @return {void} + * @method + * @public + */ +export const execute = ( + actions: Map, + objects: MovieClipActionObjectImpl[] +): void => { + + for (let idx = 0; idx < objects.length; ++idx) { + + const object = objects[idx]; + if (!object) { + continue; + } + + if (!object.script) { + object.script = Function(object.action); + } + + const frame = object.frame; + if (!actions.has(frame)) { + actions.set(frame, $getArray()); + } + + actions.get(frame)?.push(object.script); + } +}; \ No newline at end of file diff --git a/packages/display/src/MovieClip/MovieClipAddLabelsService.ts b/packages/display/src/MovieClip/MovieClipAddLabelsService.ts new file mode 100644 index 00000000..fb661d90 --- /dev/null +++ b/packages/display/src/MovieClip/MovieClipAddLabelsService.ts @@ -0,0 +1,27 @@ +import type { MovieClipLabelObjectImpl } from "../interface/MovieClipLabelObjectImpl"; +import { FrameLabel } from "../FrameLabel"; + +/** + * @description ラベル情報をマップに追加 + * Add label information to map + * + * @param {Map} label_map + * @param {array} labels + * @return {void} + * @method + * @protected + */ +export const execute = ( + label_map: Map, + labels: MovieClipLabelObjectImpl[] +): void => { + + for (let idx: number = 0; idx < labels.length; ++idx) { + const label: MovieClipLabelObjectImpl = labels[idx]; + if (!label) { + continue; + } + + label_map.set(label.frame, new FrameLabel(label.name, label.frame)); + } +}; \ No newline at end of file diff --git a/packages/display/src/MovieClip/MovieClipBuildService.ts b/packages/display/src/MovieClip/MovieClipBuildService.ts index c07a6c43..2fdb6d03 100644 --- a/packages/display/src/MovieClip/MovieClipBuildService.ts +++ b/packages/display/src/MovieClip/MovieClipBuildService.ts @@ -1,88 +1,56 @@ import type { DictionaryTagImpl } from "../interface/DictionaryTagImpl"; import type { ParentImpl } from "../interface/ParentImpl"; -import type { MovieClipSoundObjectImpl } from "../interface/MovieClipSoundObjectImpl"; -import type { MovieClipActionObjectImpl } from "../interface/MovieClipActionObjectImpl"; -import type { MovieClipLabelObjectImpl } from "../interface/MovieClipLabelObjectImpl"; -import type { LoaderInfoDataImpl } from "../interface/LoaderInfoDataImpl"; +import type { MovieClipCharacterImpl } from "../interface/MovieClipCharacterImpl"; +import type { DisplayObjectContainer } from "../DisplayObjectContainer"; import { execute as displayObjectBaseBuildService } from "../DisplayObject/DisplayObjectBaseBuildService"; -import { LoaderInfo } from "../LoaderInfo"; -import { FrameLabel } from "../FrameLabel"; -import { MovieClip } from "../MovieClip"; -import { $getArray } from "../DisplayObjectUtil"; -import { Sound, SoundMixer } from "@next2d/media"; +import { execute as movieClipAddActionsService } from "./MovieClipAddActionsService"; +import { execute as movieClipAddLabelsService } from "./MovieClipAddLabelsService"; +import { execute as movieClipBuildSoundsService } from "./MovieClipBuildSoundsService"; /** - * @description 指定tagの情報を元に、MovieClipを作成 - * Create a MovieClip based on the specified tag information + * @description 指定タグからキャラクターを取得して、MovieClipを構築 + * Get character from specified tag and build MovieClip * + * @param {DisplayObjectContainer} display_object * @param {object} tag * @param {DisplayObjectContainer} parent * @return {Promise} * @method - * @public + * @protected */ -export const execute = async ( +export const execute = async ( + display_object: T, tag: DictionaryTagImpl, - parent: ParentImpl -): Promise => { + parent: T +): Promise => { - const movieClip = new MovieClip(); - const character = displayObjectBaseBuildService( - movieClip, tag, parent - ); + const character = displayObjectBaseBuildService(display_object, tag, parent) as MovieClipCharacterImpl; - if (character.sounds) { - - const loaderInfo = movieClip.loaderInfo as NonNullable; - const data = loaderInfo.data as NonNullable; - - for (let idx: number = 0; idx < character.sounds.length; ++idx) { - - const object: MovieClipSoundObjectImpl = character.sounds[idx]; - - const sounds: Sound[] = $getArray(); - for (let idx: number = 0; idx < object.sound.length; ++idx) { - - const sound: Sound = new Sound(); - - const tag = object.sound[idx]; - - sound.loopCount = tag.loopCount | 0; - sound.volume = Math.min(SoundMixer.volume, tag.volume); - - const character = data.characters[tag.characterId]; - await sound.build(character); - - sounds.push(sound); - } + display_object._$controller = character.controller; + display_object._$dictionary = character.dictionary; + display_object._$placeMap = character.placeMap; + display_object._$placeObjects = character.placeObjects; - movieClip._$sounds.set(object.frame, sounds); + if (character.actions) { + if (!display_object._$actions) { + display_object._$actions = new Map(); } + movieClipAddActionsService(display_object._$actions, character.actions); } - if (character.actions) { - for (let idx: number = 0; idx < character.actions.length; ++idx) { - - const object: MovieClipActionObjectImpl = character.actions[idx]; - if (!object.script) { - object.script = Function(object.action); - } - - movieClip._$addAction(object.frame, object.script); + if (character.sounds) { + if (!display_object._$sounds) { + display_object._$sounds = new Map(); } + movieClipBuildSoundsService(display_object, display_object._$sounds, character.sounds); } if (character.labels) { - for (let idx: number = 0; idx < character.labels.length; ++idx) { - - const label: MovieClipLabelObjectImpl = character.labels[idx]; - - movieClip.addFrameLabel(new FrameLabel(label.name, label.frame)); - + if (!display_object._$labels) { + display_object._$labels = new Map(); } + movieClipAddLabelsService(display_object._$labels, character.labels); } - movieClip._$totalFrames = character.totalFrame || 1; - - return movieClip; + display_object._$totalFrames = character.totalFrame || 1; }; \ No newline at end of file diff --git a/packages/display/src/MovieClip/MovieClipBuildSoundsService.ts b/packages/display/src/MovieClip/MovieClipBuildSoundsService.ts new file mode 100644 index 00000000..91887355 --- /dev/null +++ b/packages/display/src/MovieClip/MovieClipBuildSoundsService.ts @@ -0,0 +1,55 @@ +import type { LoaderInfo } from "../LoaderInfo"; +import type { MovieClip } from "../MovieClip"; +import type { LoaderInfoDataImpl } from "../interface/LoaderInfoDataImpl"; +import type { MovieClipSoundObjectImpl } from "../interface/MovieClipSoundObjectImpl"; +import { $getArray } from "../DisplayObjectUtil"; +import { Sound, SoundMixer } from "@next2d/media"; + +/** + * @description 指定tagの情報を元に、MovieClipにサウンドを追加 + * Add sound to MovieClip based on specified tag information + * + * @param {MovieClip} movieClip + * @param {Map} sound_map + * @param {array} sound_objects + * @return {Promise} + * @method + * @public + */ +export const execute = async ( + movie_clip: MovieClip, + sound_map: Map, + sound_objects: MovieClipSoundObjectImpl[] +): Promise => { + + const loaderInfo = movie_clip.loaderInfo as NonNullable; + const data = loaderInfo.data as NonNullable; + + for (let idx: number = 0; idx < sound_objects.length; ++idx) { + + const object = sound_objects[idx]; + if (!object) { + continue; + } + + const sounds: Sound[] = $getArray(); + for (let idx: number = 0; idx < object.sound.length; ++idx) { + + const tag = object.sound[idx]; + if (!tag) { + continue; + } + + const sound: Sound = new Sound(); + sound.loopCount = tag.loopCount | 0; + sound.volume = Math.min(SoundMixer.volume, tag.volume); + + const character = data.characters[tag.characterId]; + await sound._$build(character); + + sounds.push(sound); + } + + sound_map.set(object.frame, sounds); + } +}; \ No newline at end of file diff --git a/packages/display/src/Sprite.ts b/packages/display/src/Sprite.ts index e3d97342..444626a6 100644 --- a/packages/display/src/Sprite.ts +++ b/packages/display/src/Sprite.ts @@ -1,9 +1,9 @@ +import type { MovieClipCharacterImpl } from "./interface/MovieClipCharacterImpl"; +import type { DictionaryTagImpl } from "./interface/DictionaryTagImpl"; +import type { ParentImpl } from "./interface/ParentImpl"; import { DisplayObjectContainer } from "./DisplayObjectContainer"; import { SoundTransform } from "@next2d/media"; -import type { - Rectangle, - Point -} from "@next2d/geom"; +import { execute as displayObjectBaseBuildService } from "./DisplayObject/DisplayObjectBaseBuildService"; /** * @description Sprite クラスは、表示リストの基本的要素です。 @@ -171,24 +171,24 @@ export class Sprite extends DisplayObjectContainer // } // } - // /** - // * @description このスプライト内のサウンドを制御します。 - // * Controls sound within this sprite. - // * - // * @member {SoundTransform} - // * @public - // */ - // get soundTransform (): SoundTransform - // { - // if (!this._$soundTransform) { - // this._$soundTransform = new SoundTransform(); - // } - // return this._$soundTransform; - // } - // set soundTransform (sound_transform: SoundTransform | null) - // { - // this._$soundTransform = sound_transform; - // } + /** + * @description このスプライト内のサウンドを制御します。 + * Controls sound within this sprite. + * + * @member {SoundTransform} + * @public + */ + get soundTransform (): SoundTransform + { + if (!this._$soundTransform) { + this._$soundTransform = new SoundTransform(); + } + return this._$soundTransform; + } + set soundTransform (sound_transform: SoundTransform | null) + { + this._$soundTransform = sound_transform; + } /** * @description buttonMode プロパティが true に設定されたスプライト上にポインターが移動したときに、 @@ -277,33 +277,6 @@ export class Sprite extends DisplayObjectContainer // this._$placeObjects = character.placeObjects; // } - // /** - // * @param {object} tag - // * @param {DisplayObjectContainer} parent - // * @return {object} - // * @method - // * @private - // */ - // _$build ( - // tag: DictionaryTagImpl, - // parent: ParentImpl - // ): MovieClipCharacterImpl { - - // const character: MovieClipCharacterImpl = this - // ._$baseBuild(tag, parent); - - // if ($rendererWorker && this._$stage) { - // this._$createWorkerInstance(); - // } - - // this._$controller = character.controller; - // this._$dictionary = character.dictionary; - // this._$placeMap = character.placeMap; - // this._$placeObjects = character.placeObjects; - - // return character; - // } - // /** // * @return {Point} // * @method diff --git a/packages/display/src/Stage.test.ts b/packages/display/src/Stage.test.ts new file mode 100644 index 00000000..4feca04b --- /dev/null +++ b/packages/display/src/Stage.test.ts @@ -0,0 +1,31 @@ +import { Stage } from "./Stage"; +import { describe, expect, it } from "vitest"; + +describe("Stage.js namespace test", () => +{ + it("namespace test public", () => + { + expect(new Stage().namespace).toBe("next2d.display.Stage"); + }); + + it("namespace test static", () => + { + expect(Stage.namespace).toBe("next2d.display.Stage"); + }); +}); + +describe("Stage.js toString test", () => +{ + it("toString test success", () => + { + expect(new Stage().toString()).toBe("[object Stage]"); + }); +}); + +describe("Stage.js static toString test", () => +{ + it("static toString test", () => + { + expect(Stage.toString()).toBe("[class Stage]"); + }); +}); \ No newline at end of file diff --git a/packages/display/src/Stage.ts b/packages/display/src/Stage.ts index b9f75a74..ecd08aea 100644 --- a/packages/display/src/Stage.ts +++ b/packages/display/src/Stage.ts @@ -11,8 +11,6 @@ import type { DisplayObjectImpl } from "@next2d/interface"; */ export class Stage extends DisplayObjectContainer { - public _$invalidate: boolean; - /** * @constructor * @public @@ -32,13 +30,6 @@ export class Stage extends DisplayObjectContainer * @private */ this._$stage = this; - - /** - * @type {boolean} - * @default true - * @private - */ - this._$invalidate = true; } /** @@ -97,38 +88,17 @@ export class Stage extends DisplayObjectContainer return "next2d.display.Stage"; } - /** - * @description 表示リストをレンダリングする必要のある次の機会に、 - * 表示オブジェクトに警告するようランタイムに通知します。 - * (例えば、再生ヘッドを新しいフレームに進める場合などです。) - * Calling the invalidate() method signals runtimes - * to alert display objects on the next opportunity - * it has to render the display list. - * (for example, when the playhead advances to a new frame) - * - * @return {void} - * @method - * @public - */ - invalidate (): void - { - this._$invalidate = true; - } - /** * @param {DisplayObject} child * @return {DisplayObject} * @method - * @private + * @protected */ _$addChild (child: DisplayObjectImpl): DisplayObjectImpl { child._$stage = this; child._$root = child; - // worker flag updated - this._$created = true; - return super._$addChild(child); } } diff --git a/packages/display/src/interface/MovieClipCharacterImpl copy.ts b/packages/display/src/interface/MovieClipCharacterImpl copy.ts new file mode 100644 index 00000000..1244023e --- /dev/null +++ b/packages/display/src/interface/MovieClipCharacterImpl copy.ts @@ -0,0 +1,19 @@ +import type { CharacterImpl } from "./CharacterImpl"; +import type { MovieClipSoundObjectImpl } from "./MovieClipSoundObjectImpl"; +import type { MovieClipActionObjectImpl } from "./MovieClipActionObjectImpl"; +import type { MovieClipLabelObjectImpl } from "./MovieClipLabelObjectImpl"; +import type { PlaceObjectImpl } from "./PlaceObjectImpl"; +import type { DictionaryTagImpl } from "./DictionaryTagImpl"; + +export interface MovieClipCharacterImpl extends CharacterImpl { + extends: string; + totalFrame: number; + controller: Array>; + dictionary: DictionaryTagImpl[]; + placeMap: Array>; + placeObjects: PlaceObjectImpl[]; + labels?: MovieClipLabelObjectImpl[]; + actions?: MovieClipActionObjectImpl[]; + symbol?: string; + sounds?: MovieClipSoundObjectImpl[]; +} \ No newline at end of file diff --git a/packages/events/src/Event.test.ts b/packages/events/src/Event.test.ts index af4d38bf..e73551b1 100644 --- a/packages/events/src/Event.test.ts +++ b/packages/events/src/Event.test.ts @@ -1,30 +1,11 @@ import { Event } from "./Event"; import { describe, expect, it } from "vitest"; -describe("Event.js toString test", () => -{ - it("toString test case1", () => - { - const event = new Event("test"); - expect(event.toString()) - .toBe("[Event type=\"test\" bubbles=false cancelable=false eventPhase=2]"); - }); -}); - -describe("Event.js static toString test", () => -{ - it("static toString test", () => - { - expect(Event.toString()).toBe("[class Event]"); - }); -}); - describe("Event.js namespace test", () => { it("namespace test public", () => { - const event = new Event("test"); - expect(event.namespace).toBe("next2d.events.Event"); + expect(new Event("test").namespace).toBe("next2d.events.Event"); }); it("namespace test static", () => @@ -36,11 +17,6 @@ describe("Event.js namespace test", () => describe("Event.js property test", () => { - it("ACTIVATE test", () => - { - expect(Event.ACTIVATE).toBe("activate"); - }); - it("ADDED test", () => { expect(Event.ADDED).toBe("added"); @@ -51,19 +27,14 @@ describe("Event.js property test", () => expect(Event.ADDED_TO_STAGE).toBe("addedToStage"); }); - it("CHANGE test", () => - { - expect(Event.CHANGE).toBe("change"); - }); - it("COMPLETE test", () => { expect(Event.COMPLETE).toBe("complete"); }); - it("DEACTIVATE test", () => + it("ENDED test", () => { - expect(Event.DEACTIVATE).toBe("deactivate"); + expect(Event.ENDED).toBe("ended"); }); it("ENTER_FRAME test", () => @@ -71,34 +42,14 @@ describe("Event.js property test", () => expect(Event.ENTER_FRAME).toBe("enterFrame"); }); - it("EXIT_FRAME test", () => - { - expect(Event.EXIT_FRAME).toBe("exitFrame"); - }); - - it("FRAME_CONSTRUCTED test", () => - { - expect(Event.FRAME_CONSTRUCTED).toBe("frameConstructed"); - }); - it("FRAME_LABEL test", () => { expect(Event.FRAME_LABEL).toBe("frameLabel"); }); - it("INIT test", () => - { - expect(Event.INIT).toBe("init"); - }); - - it("LOAD test", () => - { - expect(Event.LOAD).toBe("load"); - }); - - it("MOUSE_LEAVE test", () => + it("OPEN test", () => { - expect(Event.MOUSE_LEAVE).toBe("mouseLeave"); + expect(Event.OPEN).toBe("open"); }); it("REMOVED test", () => @@ -111,38 +62,8 @@ describe("Event.js property test", () => expect(Event.REMOVED_FROM_STAGE).toBe("removedFromStage"); }); - it("RENDER test", () => - { - expect(Event.RENDER).toBe("render"); - }); - it("RESIZE test", () => { expect(Event.RESIZE).toBe("resize"); }); - - it("SCROLL test", () => - { - expect(Event.SCROLL).toBe("scroll"); - }); - - it("OPEN test", () => - { - expect(Event.OPEN).toBe("open"); - }); - - it("STOP test", () => - { - expect(Event.STOP).toBe("stop"); - }); - - it("SOUND_COMPLETE test", () => - { - expect(Event.SOUND_COMPLETE).toBe("soundComplete"); - }); - - it("UPDATE test", () => - { - expect(Event.UPDATE).toBe("update"); - }); }); \ No newline at end of file diff --git a/packages/events/src/Event.ts b/packages/events/src/Event.ts index 2328aba1..7003e649 100644 --- a/packages/events/src/Event.ts +++ b/packages/events/src/Event.ts @@ -1,6 +1,6 @@ import { EventPhase } from "./EventPhase"; +import type { EventDispatcher } from "./EventDispatcher"; import type { EventDispatcherImpl } from "./interface/EventDispatcherImpl"; -import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; /** * @description Event クラスのメソッドは、イベントリスナー関数で使用してイベントオブジェクトの動作に影響を与えることができます。 @@ -24,26 +24,23 @@ export class Event { private readonly _$type: string; private readonly _$bubbles: boolean; - private readonly _$cancelable: boolean; - private _$target: EventDispatcherImpl | null; - private _$currentTarget: EventDispatcherImpl | null; - private _$listener: Function | null; - private _$eventPhase: number; + public listener: Function | null; + public target: EventDispatcherImpl | null; + public currentTarget: EventDispatcherImpl | null; + public eventPhase: number; public _$stopImmediatePropagation: boolean; public _$stopPropagation: boolean; /** * @param {string} type * @param {boolean} [bubbles=false] - * @param {boolean} [cancelable=false] * * @constructor * @public */ constructor ( type: string, - bubbles: boolean = false, - cancelable: boolean = false + bubbles: boolean = false ) { /** @@ -54,42 +51,38 @@ export class Event /** * @type {boolean} + * @default false * @private */ this._$bubbles = bubbles; /** - * @type {boolean} - * @private - */ - this._$cancelable = cancelable; - - /** - * @type {EventDispatcher} + * @type {EventDispatcher | null} + * @default null * @private */ - this._$target = null; + this.target = null; /** - * @type {EventDispatcher} + * @type {EventDispatcher | null} * @default null * @private */ - this._$currentTarget = null; + this.currentTarget = null; /** * @type {number} * @default EventPhase.AT_TARGET * @private */ - this._$eventPhase = EventPhase.AT_TARGET; + this.eventPhase = EventPhase.AT_TARGET; /** * @type {function} * @default null * @private */ - this._$listener = null; + this.listener = null; /** * @type {boolean} @@ -106,26 +99,11 @@ export class Event this._$stopPropagation = false; } - /** - * 指定されたクラスのストリングを返します。 - * Returns the string representation of the specified class. - * - * @return {string} - * @default "[class Event]" - * @method - * @static - */ - static toString (): string - { - return "[class Event]"; - } - /** * @description 指定されたクラスの空間名を返します。 * Returns the space name of the specified class. * * @member {string} - * @default "next2d.events.Event" * @const * @static */ @@ -134,25 +112,11 @@ export class Event return "next2d.events.Event"; } - /** - * @description 指定されたオブジェクトのストリングを返します。 - * Returns the string representation of the specified object. - * - * @return {string} - * @method - * @public - */ - toString (): string - { - return eventFormatToStringService(this, "Event", "type", "bubbles", "cancelable", "eventPhase"); - } - /** * @description 指定されたオブジェクトの空間名を返します。 * Returns the space name of the specified object. * * @member {string} - * @default "next2d.events.Event" * @const * @public */ @@ -162,23 +126,8 @@ export class Event } /** - * @description ACTIVATE 定数は、type プロパティ(activate イベントオブジェクト)の値を定義します。 - * The ACTIVATE constant defines the value - * of the type property of an activate event object. - * - * @return {string} - * @const - * @static - */ - static get ACTIVATE (): string - { - return "activate"; - } - - /** - * @description Event.ADDED 定数は、added イベントオブジェクトの type プロパティの値を定義します。 - * The Event.ADDED constant defines the value - * of the type property of an added event object. + * @description Sprite または MovieClip を親に持つオブジェクトに追加されたときに発生します。 + * Occurs when the object is added to a parent object. * * @return {string} * @const @@ -190,9 +139,8 @@ export class Event } /** - * @description Event.ADDED_TO_STAGE 定数は、type プロパティ(addedToStage イベントオブジェクト)の値を定義します。 - * The Event.ADDED_TO_STAGE constant defines the value - * of the type property of an addedToStage event object. + * @description Stage に追加されたときに発生します。 + * Occurs when the object is added to the Stage. * * @return {string} * @const @@ -204,23 +152,8 @@ export class Event } /** - * @description Event.CHANGE 定数は、type プロパティ(change イベントオブジェクト)の値を定義します。 - * The Event.CHANGE constant defines the value - * of the type property of a change event object. - * - * @return {string} - * @const - * @static - */ - static get CHANGE (): string - { - return "change"; - } - - /** - * @description Event.COMPLETE 定数は、complete イベントオブジェクトの type プロパティの値を定義します。 - * The Event.COMPLETE constant defines the value - * of the type property of a complete event object. + * @description 読み込みや、処理完了時に発生します。 + * Occurs when loading or processing is complete. * * @return {string} * @const @@ -232,23 +165,21 @@ export class Event } /** - * @description Event.DEACTIVATE 定数は、deactivate イベントオブジェクトの type プロパティの値を定義します。 - * The Event.DEACTIVATE constant defines the value - * of the type property of a deactivate event object. + * @description サウンドやビデオなどの再生処理の終了時に発生します。 + * Occurs when playback of a sound or video ends. * * @return {string} * @const * @static */ - static get DEACTIVATE (): string + static get ENDED (): string { - return "deactivate"; + return "ended"; } /** - * @description Event.ENTER_FRAME 定数は、enterFrame イベントオブジェクトの type プロパティの値を定義します。 - * The Event.ENTER_FRAME constant defines the value - * of the type property of an enterFrame event object. + * @description MovieClip のフレームが変更される度に発生します。 + * Occurs when the frame of a MovieClip changes. * * @return {string} * @const @@ -260,37 +191,8 @@ export class Event } /** - * @description Event.EXIT_FRAME 定数は、exitFrame イベントオブジェクトの type プロパティの値を定義します。 - * The Event.EXIT_FRAME constant defines the value - * of the type property of an exitFrame event object. - * - * @return {string} - * @const - * @static - */ - static get EXIT_FRAME (): string - { - return "exitFrame"; - } - - /** - * @description Event.FRAME_CONSTRUCTED 定数は、frameConstructed イベントオブジェクトの type プロパティの値を定義します。 - * The Event.FRAME_CONSTRUCTED constant defines the value - * of the type property of an frameConstructed event object. - * - * @return {string} - * @const - * @static - */ - static get FRAME_CONSTRUCTED (): string - { - return "frameConstructed"; - } - - /** - * @description Event.FRAME_LABEL 定数は、frameLabel イベントオブジェクトの type プロパティの値を定義します。 - * The Event.FRAME_LABEL constant defines the value - * of the type property of an frameLabel event object. + * @description MovieClip のフレームラベルのキーフレームに到達したときに発生します。 + * Occurs when a MovieClip reaches a keyframe that designates a frame label. * * @return {string} * @const @@ -302,51 +204,22 @@ export class Event } /** - * @description Event.INIT 定数は、init イベントオブジェクトの type プロパティの値を定義します。 - * The Event.INIT constant defines the value - * of the type property of an init event object. - * - * @return {string} - * @const - * @static - */ - static get INIT (): string - { - return "init"; - } - - /** - * @description Event.LOAD 定数は、load イベントオブジェクトの type プロパティの値を定義します。 - * The Event.LOAD constant defines the value - * of the type property of an load event object. - * - * @return {string} - * @const - * @static - */ - static get LOAD (): string - { - return "load"; - } - - /** - * @description Event.MOUSE_LEAVE 定数は、mouseLeave イベントオブジェクトの type プロパティの値を定義します。 - * The Event.MOUSE_LEAVE constant defines the value - * of the type property of a mouseLeave event object. + * @description データの読み込み開始時に発生します。 + * Occurs when sound data loading starts. * * @return {string} + * @default "soundopen" * @const * @static */ - static get MOUSE_LEAVE (): string + static get OPEN (): string { - return "mouseLeave"; + return "open"; } /** - * @description Event.REMOVED 定数は、removed プロパティ(paste イベントオブジェクト)の値を定義します。 - * The Event.REMOVED constant defines the value - * of the type property of a removed event object. + * @description Sprite または MovieClip を親に持つオブジェクトから削除されたときに発生します。 + * Occurs when the object is removed from a parent object. * * @return {string} * @const @@ -358,9 +231,8 @@ export class Event } /** - * @description Event.REMOVED_FROM_STAGE 定数は、removedFromStage イベントオブジェクトの type プロパティの値を定義します。 - * The Event.REMOVED_FROM_STAGE constant defines the value - * of the type property of a removedFromStage event object. + * @description Stage から削除されたときに発生します。 + * Occurs when the object is removed from the Stage. * * @return {string} * @const @@ -372,25 +244,8 @@ export class Event } /** - * @description Event.RENDER 定数は、render イベントオブジェクトの - * type プロパティの値を定義します。 - * The Event.RENDER constant defines the value - * of the type property of a render event object. - * - * @return {string} - * @const - * @static - */ - static get RENDER (): string - { - return "render"; - } - - /** - * @description Event.RESIZE 定数は、resize イベントオブジェクトの - * type プロパティの値を定義します。 - * The Event.RESIZE constant defines the value - * of the type property of a resize event object. + * @description 画面のサイズが変更されたときに発生します。 + * Occurs when the screen size changes. * * @return {string} * @const @@ -401,80 +256,6 @@ export class Event return "resize"; } - /** - * @description Event.SCROLL 定数は、render イベントオブジェクトの - * type プロパティの値を定義します。 - * The Event.SCROLL constant defines the value - * of the type property of a render event object. - * - * @return {string} - * @const - * @static - */ - static get SCROLL (): string - { - return "scroll"; - } - - /** - * @description Event.OPEN 定数は、render イベントオブジェクトの - * type プロパティの値を定義します。 - * The Event.OPEN constant defines the value - * of the type property of a render event object. - * - * @return {string} - * @const - * @static - */ - static get OPEN (): string - { - return "open"; - } - - /** - * @description Event.STOP 定数は、render イベントオブジェクトの - * type プロパティの値を定義します。 - * The Event.STOP constant defines the value - * of the type property of a render event object. - * - * @return {string} - * @const - * @static - */ - static get STOP (): string - { - return "stop"; - } - - /** - * @description Event.SOUND_COMPLETE 定数は、soundComplete イベントオブジェクトの type プロパティの値を定義します。 - * The Event.SOUND_COMPLETE constant defines the value - * of the type property of a soundComplete event object. - * - * @return {string} - * @const - * @static - */ - static get SOUND_COMPLETE (): string - { - return "soundComplete"; - } - - /** - * @description Event.UPDATE 定数は、render イベントオブジェクトの - * type プロパティの値を定義します。 - * The Event.STOP constant defines the value - * of the type property of a render event object. - * - * @return {string} - * @const - * @static - */ - static get UPDATE (): string - { - return "update"; - } - /** * @description イベントがバブリングイベントかどうかを示します。 * Indicates whether an event is a bubbling event. @@ -489,89 +270,6 @@ export class Event return this._$bubbles; } - /** - * @description イベントに関連付けられた動作を回避できるかどうかを示します。 - * Indicates whether the behavior associated - * with the event can be prevented. - * - * @member {boolean} - * @default false - * @readonly - * @public - */ - get cancelable (): boolean - { - return this._$cancelable; - } - - /** - * @description イベントリスナーで Event オブジェクトをアクティブに処理しているオブジェクトです。 - * The object that is actively processing the Event object - * with an event listener. - * - * @member {EventDispatcher|null} - * @default null - * @public - */ - get currentTarget (): EventDispatcherImpl - { - return this._$currentTarget as EventDispatcherImpl; - } - set currentTarget (current_target: EventDispatcherImpl) - { - this._$currentTarget = current_target; - } - - /** - * @description イベントフローの現在の段階です。 - * The current phase in the event flow. - * - * @member {number} - * @default EventPhase.AT_TARGET - * @public - */ - get eventPhase (): number - { - return this._$eventPhase; - } - set eventPhase (event_phase: number) - { - this._$eventPhase = event_phase; - } - - /** - * @description 現在コールされている関数 - * Function currently being called. - * - * @member {function} - * @default null - * @public - */ - get listener (): Function | null - { - return this._$listener; - } - set listener (listener: Function | null) - { - this._$listener = listener; - } - - /** - * @description イベントターゲットです。 - * The event target. - * - * @member {EventDispatcher|null} - * @public - */ - get target (): EventDispatcherImpl - { - return this._$target ? this._$target : this._$currentTarget; - } - set target (target: EventDispatcherImpl) - { - this._$target = target; - } - /** * @description イベントのタイプです。 * The type of event. diff --git a/packages/events/src/Event/EventFormatToStringService.test.ts b/packages/events/src/Event/EventFormatToStringService.test.ts deleted file mode 100644 index 6ef6fb53..00000000 --- a/packages/events/src/Event/EventFormatToStringService.test.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Event } from "../Event"; -import { execute } from "./EventFormatToStringService"; -import { describe, expect, it } from "vitest"; - -describe("EventFormatToStringService.js toString test", () => -{ - it("toString test case", () => - { - const event = new Event("test"); - expect(execute(event, "Event", "type", "bubbles", "cancelable", "eventPhase")) - .toBe("[Event type=\"test\" bubbles=false cancelable=false eventPhase=2]"); - }); -}); diff --git a/packages/events/src/Event/EventFormatToStringService.ts b/packages/events/src/Event/EventFormatToStringService.ts deleted file mode 100644 index fe97624b..00000000 --- a/packages/events/src/Event/EventFormatToStringService.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { EventImpl } from "../interface/EventImpl"; - -/** - * @description toString() メソッドを実装するためのユーティリティ関数 - * Utility functions to implement the toString() method - * - * @param {Event} event - * @param {array} args - * @return {string} - * @method - * @protected - */ -export const execute = (event: EventImpl, ...args: string[]): string => -{ - let str = `[${args[0]}`; - for (let idx = 1; idx < args.length; ++idx) { - - const name = args[idx]; - if (!(name in event)) { - continue; - } - - str += ` ${name}=`; - - const value = event[name]; - str += typeof value === "string" - ? `"${value}"` - : `${value}`; - } - return `${str}]`; -}; \ No newline at end of file diff --git a/packages/events/src/EventDispatcher.test.ts b/packages/events/src/EventDispatcher.test.ts index 96042ffb..ad544747 100644 --- a/packages/events/src/EventDispatcher.test.ts +++ b/packages/events/src/EventDispatcher.test.ts @@ -1,30 +1,11 @@ import { EventDispatcher } from "./EventDispatcher"; import { describe, expect, it } from "vitest"; -describe("EventDispatcher.js toString test", () => -{ - // toString - it("toString test success", () => - { - const eventDispatcher = new EventDispatcher(); - expect(eventDispatcher.toString()).toBe("[object EventDispatcher]"); - }); -}); - -describe("EventDispatcher.js static toString test", () => -{ - it("static toString test", () => - { - expect(EventDispatcher.toString()).toBe("[class EventDispatcher]"); - }); -}); - describe("EventDispatcher.js namespace test", () => { it("namespace test public", () => { - const eventDispatcher = new EventDispatcher(); - expect(eventDispatcher.namespace).toBe("next2d.events.EventDispatcher"); + expect(new EventDispatcher().namespace).toBe("next2d.events.EventDispatcher"); }); it("namespace test static", () => diff --git a/packages/events/src/EventDispatcher.ts b/packages/events/src/EventDispatcher.ts index 67b922ec..2d819073 100644 --- a/packages/events/src/EventDispatcher.ts +++ b/packages/events/src/EventDispatcher.ts @@ -1,5 +1,5 @@ +import type { Event } from "./Event"; import type { EventListenerImpl } from "./interface/EventListenerImpl"; -import type { EventImpl } from "./interface/EventImpl"; import { execute as eventDispatcherAddEventListenerService } from "./EventDispatcher/EventDispatcherAddEventListenerService"; import { execute as eventDispatcherHasEventListenerService } from "./EventDispatcher/EventDispatcherHasEventListenerService"; import { execute as eventDispatcherRemoveEventListenerService } from "./EventDispatcher/EventDispatcherRemoveEventListenerService"; @@ -32,20 +32,6 @@ export class EventDispatcher this._$events = null; } - /** - * 指定されたクラスのストリングを返します。 - * Returns the string representation of the specified class. - * - * @return {string} - * @default "[class EventDispatcher]" - * @method - * @static - */ - static toString (): string - { - return "[class EventDispatcher]"; - } - /** * @description クラスの空間名を返します。 * Returns the space name of the class. @@ -60,20 +46,6 @@ export class EventDispatcher return "next2d.events.EventDispatcher"; } - /** - * @description オブジェクトのストリングを返します。 - * Returns the string representation of the object. - * - * @default "[object EventDispatcher]" - * @return {string} - * @method - * @public - */ - toString (): string - { - return "[object EventDispatcher]"; - } - /** * @description オブジェクトの空間名を返します。 * Returns the space name of the object. @@ -103,10 +75,15 @@ export class EventDispatcher * @public */ addEventListener ( - type: string, listener: Function, + type: string, + listener: Function, use_capture: boolean = false, priority: number = 0 ): void { + if (!this._$events) { + this._$events = new Map(); + } + eventDispatcherAddEventListenerService( this, type, listener, use_capture, priority ); @@ -121,7 +98,7 @@ export class EventDispatcher * @method * @public */ - dispatchEvent (event: EventImpl): boolean + dispatchEvent (event: Event): boolean { return eventDispatcherDispatchEventService(this, event); } diff --git a/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.test.ts b/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.test.ts index 96945adc..24da4f43 100644 --- a/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.test.ts +++ b/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.test.ts @@ -113,26 +113,27 @@ describe("EventDispatcher.js addEventListener test", () => expect(name).toBe("ng"); }); - it("addEventListener test duplicate case4", () => + it("addEventListener test duplicate case3", () => { const eventDispatcher1 = new EventDispatcher(); const eventDispatcher2 = new EventDispatcher(); - let target = null; - const enterFrame = (event: Event) => { target = event.currentTarget }; + let result = ""; $broadcastEvents.clear(); expect($broadcastEvents.size).toBe(0); - eventDispatcher1.addEventListener(Event.ENTER_FRAME, enterFrame); - eventDispatcher2.addEventListener(Event.ENTER_FRAME, enterFrame); + eventDispatcher1.addEventListener(Event.ENTER_FRAME, () => { result += "A" }); + eventDispatcher2.addEventListener(Event.ENTER_FRAME, () => { result += "B" }); expect($broadcastEvents.size).toBe(1); expect($broadcastEvents.get(Event.ENTER_FRAME)?.length).toBe(2); eventDispatcher1.dispatchEvent(new Event(Event.ENTER_FRAME)); - expect(target).toBe(eventDispatcher1); + expect(result).toBe("AB"); + result = ""; + expect(result).toBe(""); eventDispatcher2.dispatchEvent(new Event(Event.ENTER_FRAME)); - expect(target).toBe(eventDispatcher2); + expect(result).toBe("AB"); }); }); \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.ts b/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.ts index d6080eff..3ecc404c 100644 --- a/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.ts +++ b/packages/events/src/EventDispatcher/EventDispatcherAddEventListenerService.ts @@ -1,6 +1,7 @@ import type { EventListenerImpl } from "../interface/EventListenerImpl"; -import type { EventDispatcherImpl } from "../interface/EventDispatcherImpl"; +import type { EventDispatcher } from "../EventDispatcher"; import { Event } from "../Event"; +import { KeyboardEvent } from "../KeyboardEvent"; import { $broadcastEvents, $getArray @@ -18,26 +19,21 @@ import { * @method * @protected */ -export const execute = ( - scope: EventDispatcherImpl, +export const execute = ( + scope: D, type: string, listener: Function, use_capture: boolean = false, priority: number = 0 ): void => { - let events: EventListenerImpl[]; + let listenerObjects: EventListenerImpl[]; switch (type) { // broadcast event case Event.ENTER_FRAME: - case Event.EXIT_FRAME: - case Event.FRAME_CONSTRUCTED: - case Event.RENDER: - case Event.ACTIVATE: - case Event.DEACTIVATE: - case "keyDown": - case "keyUp": + case KeyboardEvent.KEY_DOWN: + case KeyboardEvent.KEY_UP: if (!$broadcastEvents.size || !$broadcastEvents.has(type) @@ -45,14 +41,13 @@ export const execute = ( $broadcastEvents.set(type, $getArray()); } - events = $broadcastEvents.get(type) as NonNullable; + listenerObjects = $broadcastEvents.get(type) as NonNullable; break; // normal event default: - // init if (!scope._$events) { scope._$events = new Map(); } @@ -61,27 +56,27 @@ export const execute = ( scope._$events.set(type, $getArray()); } - events = scope._$events.get(type) as NonNullable; + listenerObjects = scope._$events.get(type) as NonNullable; break; } // duplicate check - const length: number = events.length; + const length = listenerObjects.length; let index = 0; for ( ; index < length; ++index) { - const event: EventListenerImpl = events[index]; - if (use_capture !== event.useCapture) { + const object = listenerObjects[index]; + if (use_capture !== object.useCapture) { continue; } - if (event.target !== scope) { + if (object.target !== scope) { continue; } - if (event.listener !== listener) { + if (object.listener !== listener) { continue; } @@ -91,7 +86,7 @@ export const execute = ( // add or overwrite if (length === index) { // add - events.push({ + listenerObjects.push({ "listener": listener, "priority": priority, "useCapture": use_capture, @@ -99,17 +94,17 @@ export const execute = ( }); } else { // overwrite - const event: EventListenerImpl = events[index]; - event.listener = listener; - event.priority = priority; - event.useCapture = use_capture; - event.target = scope; + const object = listenerObjects[index]; + object.listener = listener; + object.priority = priority; + object.useCapture = use_capture; + object.target = scope; } - if (events.length > 1) { + if (listenerObjects.length > 1) { // sort(DESC) - events.sort((a: EventListenerImpl, b: EventListenerImpl): number => + listenerObjects.sort((a, b): number => { switch (true) { diff --git a/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.test.ts b/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.test.ts index 63da07fc..29574e78 100644 --- a/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.test.ts +++ b/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.test.ts @@ -315,29 +315,4 @@ describe("EventDispatcher.js dispatchEvent test", () => expect(resultCaseB).toBe("stage1ABC"); }); - - it("dispatchEvent test single dispatchEvent", () => - { - const eventDispatcher1 = new EventDispatcher(); - const eventDispatcher2 = new EventDispatcher(); - - $broadcastEvents.clear(); - expect($broadcastEvents.size).toBe(0); - - let result = ""; - eventDispatcher1.addEventListener(Event.ENTER_FRAME, () => - { - result += "eventDispatcher1"; - }); - - eventDispatcher2.addEventListener(Event.ENTER_FRAME, () => - { - result += "eventDispatcher2"; - }); - - expect($broadcastEvents.size).toBe(1); - eventDispatcher1.dispatchEvent(new Event(Event.ENTER_FRAME)); - expect(result).toBe("eventDispatcher1"); - }); - }); \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.ts b/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.ts index 2ba5e333..4b6988f4 100644 --- a/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.ts +++ b/packages/events/src/EventDispatcher/EventDispatcherDispatchEventService.ts @@ -1,7 +1,7 @@ -import type { EventImpl } from "../interface/EventImpl"; -import type { EventDispatcherImpl } from "../interface/EventDispatcherImpl"; import type { EventListenerImpl } from "../interface/EventListenerImpl"; +import type { EventDispatcher } from "../EventDispatcher"; import { Event } from "../Event"; +import { KeyboardEvent } from "../KeyboardEvent"; import { EventPhase } from "../EventPhase"; import { $broadcastEvents, @@ -19,21 +19,16 @@ import { * @method * @protected */ -export const execute = ( - scope: EventDispatcherImpl, - event: EventImpl +export const execute = ( + scope: D, + event: E ): boolean => { switch (event.type) { case Event.ENTER_FRAME: - case Event.EXIT_FRAME: - case Event.FRAME_CONSTRUCTED: - case Event.RENDER: - case Event.ACTIVATE: - case Event.DEACTIVATE: - case "keyDown": - case "keyUp": + case KeyboardEvent.KEY_DOWN: + case KeyboardEvent.KEY_UP: { if (!$broadcastEvents.size || !$broadcastEvents.has(event.type) @@ -41,28 +36,25 @@ export const execute = ( return false; } - const events = $broadcastEvents.get(event.type) as NonNullable; - if (!events.length) { + const listenerObjects = $broadcastEvents.get(event.type) as NonNullable; + if (!listenerObjects.length) { return false; } - for (let idx = 0; idx < events.length; ++idx) { + for (let idx = 0; idx < listenerObjects.length; ++idx) { - const object: EventListenerImpl = events[idx]; - if (object.target !== scope) { - continue; - } + const object = listenerObjects[idx]; // start target event.eventPhase = EventPhase.AT_TARGET; // event execute - event.currentTarget = object.target; + event.target = event.currentTarget = object.target; try { event.listener = object.listener; - object.listener.call(null, event); + object.listener(event); } catch (e) { @@ -77,6 +69,8 @@ export const execute = ( default: { + event.target = scope; + let currentEvents: EventListenerImpl[] | null = null; if (scope._$events && scope._$events.size @@ -92,7 +86,7 @@ export const execute = ( const parentEvents = $getArray(); if ("parent" in scope) { - let parent = scope.parent as EventDispatcherImpl | null; + let parent = scope.parent as D | null; while (parent) { if (parent.hasEventListener(event.type)) { @@ -106,7 +100,11 @@ export const execute = ( } } - parent = parent.parent; + if (!("parent" in parent)) { + break; + } + + parent = parent.parent as D | null; } @@ -120,8 +118,6 @@ export const execute = ( return false; } - event.target = scope; - // stage => child... end if (parentEvents.length) { diff --git a/packages/events/src/EventDispatcher/EventDispatcherHasEventListenerService.ts b/packages/events/src/EventDispatcher/EventDispatcherHasEventListenerService.ts index aa352ed9..4fa0ce93 100644 --- a/packages/events/src/EventDispatcher/EventDispatcherHasEventListenerService.ts +++ b/packages/events/src/EventDispatcher/EventDispatcherHasEventListenerService.ts @@ -1,5 +1,6 @@ import type { EventListenerImpl } from "../interface/EventListenerImpl"; -import type { EventDispatcherImpl } from "../interface/EventDispatcherImpl"; +import type { EventDispatcher } from "../EventDispatcher"; +import { KeyboardEvent } from "../KeyboardEvent"; import { Event } from "../Event"; import { $broadcastEvents } from "../EventUtil"; @@ -13,21 +14,16 @@ import { $broadcastEvents } from "../EventUtil"; * @method * @protected */ -export const execute = ( - scope: EventDispatcherImpl, +export const execute = ( + scope: D, type: string ): boolean => { switch (type) { case Event.ENTER_FRAME: - case Event.EXIT_FRAME: - case Event.FRAME_CONSTRUCTED: - case Event.RENDER: - case Event.ACTIVATE: - case Event.DEACTIVATE: - case "keyDown": - case "keyUp": + case KeyboardEvent.KEY_DOWN: + case KeyboardEvent.KEY_UP: { if ($broadcastEvents.size && $broadcastEvents.has(type) diff --git a/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.ts b/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.ts index 7991376f..6abbcc5f 100644 --- a/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.ts +++ b/packages/events/src/EventDispatcher/EventDispatcherRemoveAllEventListenerService.ts @@ -1,5 +1,6 @@ -import type { EventDispatcherImpl } from "../interface/EventDispatcherImpl"; import type { EventListenerImpl } from "../interface/EventListenerImpl"; +import type { EventDispatcher } from "../EventDispatcher"; +import { KeyboardEvent } from "../KeyboardEvent"; import { Event } from "../Event"; import { $broadcastEvents, @@ -18,29 +19,24 @@ import { * @method * @protected */ -export const execute = ( - scope: EventDispatcherImpl, +export const execute = ( + scope: D, type: string, use_capture: boolean = false ): void => { - let events: EventListenerImpl[]; + let listenerObjects: EventListenerImpl[]; switch (type) { case Event.ENTER_FRAME: - case Event.EXIT_FRAME: - case Event.FRAME_CONSTRUCTED: - case Event.RENDER: - case Event.ACTIVATE: - case Event.DEACTIVATE: - case "keyDown": - case "keyUp": + case KeyboardEvent.KEY_DOWN: + case KeyboardEvent.KEY_UP: if (!$broadcastEvents.size || !$broadcastEvents.has(type) ) { return ; } - events = $broadcastEvents.get(type) as NonNullable; + listenerObjects = $broadcastEvents.get(type) as NonNullable; break; default: @@ -50,26 +46,26 @@ export const execute = ( ) { return ; } - events = scope._$events.get(type) as NonNullable; + listenerObjects = scope._$events.get(type) as NonNullable; break; } - if (!events) { + if (!listenerObjects) { return ; } // remove listener const results: EventListenerImpl[] = $getArray(); - for (let idx = 0; idx < events.length; ++idx) { + for (let idx = 0; idx < listenerObjects.length; ++idx) { // event object - const obj: EventListenerImpl = events[idx]; - if (use_capture === obj.useCapture) { + const object = listenerObjects[idx]; + if (use_capture === object.useCapture) { continue; } - results.push(obj); + results.push(object); } if (!results.length) { @@ -86,7 +82,7 @@ export const execute = ( } $poolArray(results); - $poolArray(events); + $poolArray(listenerObjects); return ; } @@ -94,7 +90,7 @@ export const execute = ( if (results.length > 1) { // event sort (DESC) - results.sort(function (a: EventListenerImpl, b: EventListenerImpl) + results.sort((a, b) => { switch (true) { @@ -115,8 +111,8 @@ export const execute = ( if ($broadcastEvents.has(type)) { $broadcastEvents.set(type, results); } else { - scope._$events.set(type, results); + scope._$events?.set(type, results); } - $poolArray(events); + $poolArray(listenerObjects); }; \ No newline at end of file diff --git a/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.ts b/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.ts index 511168bd..d94e4201 100644 --- a/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.ts +++ b/packages/events/src/EventDispatcher/EventDispatcherRemoveEventListenerService.ts @@ -1,6 +1,7 @@ -import type { EventDispatcherImpl } from "../interface/EventDispatcherImpl"; import type { EventListenerImpl } from "../interface/EventListenerImpl"; +import type { EventDispatcher } from "../EventDispatcher"; import { Event } from "../Event"; +import { KeyboardEvent } from "../KeyboardEvent"; import { $broadcastEvents, $poolArray @@ -18,30 +19,25 @@ import { * @method * @protected */ -export const execute = ( - scope: EventDispatcherImpl, +export const execute = ( + scope: D, type: string, listener: Function, use_capture: boolean = false ): void => { - let events: EventListenerImpl[]; + let listenerObjects: EventListenerImpl[]; switch (type) { case Event.ENTER_FRAME: - case Event.EXIT_FRAME: - case Event.FRAME_CONSTRUCTED: - case Event.RENDER: - case Event.ACTIVATE: - case Event.DEACTIVATE: - case "keyDown": - case "keyUp": + case KeyboardEvent.KEY_DOWN: + case KeyboardEvent.KEY_UP: if (!$broadcastEvents.size || !$broadcastEvents.has(type) ) { return ; } - events = $broadcastEvents.get(type) as NonNullable; + listenerObjects = $broadcastEvents.get(type) as NonNullable; break; default: @@ -51,20 +47,20 @@ export const execute = ( ) { return ; } - events = scope._$events.get(type) as NonNullable; + listenerObjects = scope._$events.get(type) as NonNullable; break; } - if (!events) { + if (!listenerObjects) { return ; } // remove listener - for (let idx = 0; idx < events.length; ++idx) { + for (let idx = 0; idx < listenerObjects.length; ++idx) { // event object - const object: EventListenerImpl = events[idx]; + const object = listenerObjects[idx]; if (use_capture !== object.useCapture) { continue ; } @@ -74,12 +70,12 @@ export const execute = ( } // delete if match - events.splice(idx, 1); + listenerObjects.splice(idx, 1); break; } - if (!events.length) { + if (!listenerObjects.length) { if ($broadcastEvents.has(type)) { $broadcastEvents.delete(type); @@ -92,14 +88,14 @@ export const execute = ( } } - $poolArray(events); + $poolArray(listenerObjects); return ; } - if (events.length > 1) { + if (listenerObjects.length > 1) { // event sort(DESC) - events.sort(function (a: EventListenerImpl, b: EventListenerImpl) + listenerObjects.sort(function (a: EventListenerImpl, b: EventListenerImpl) { switch (true) { diff --git a/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.ts b/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.ts index 26192c84..35e5b4eb 100644 --- a/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.ts +++ b/packages/events/src/EventDispatcher/EventDispatcherWillTriggerService.ts @@ -1,4 +1,4 @@ -import type { EventDispatcherImpl } from "../interface/EventDispatcherImpl"; +import type { EventDispatcher } from "../EventDispatcher"; /** * @description 先祖も含めてイベントリスナーが登録されているかどうかを判定。 @@ -10,8 +10,8 @@ import type { EventDispatcherImpl } from "../interface/EventDispatcherImpl"; * @method * @protected */ -export const execute = ( - scope: EventDispatcherImpl, +export const execute = ( + scope: D, type: string ): boolean => { @@ -21,14 +21,18 @@ export const execute = ( if ("parent" in scope) { - let parent = scope.parent as EventDispatcherImpl | null; + let parent = scope.parent as T | null; while (parent) { if (parent.hasEventListener(type)) { return true; } - parent = parent.parent; + if (!("parent" in parent)) { + break; + } + + parent = parent.parent as T | null; } } diff --git a/packages/events/src/EventPhase.test.ts b/packages/events/src/EventPhase.test.ts index d2845240..80d48668 100644 --- a/packages/events/src/EventPhase.test.ts +++ b/packages/events/src/EventPhase.test.ts @@ -1,30 +1,11 @@ import { EventPhase } from "./EventPhase"; import { describe, expect, it } from "vitest"; -describe("EventPhase.js toString test", () => -{ - it("toString test case1", () => - { - const eventPhase = new EventPhase(); - expect(eventPhase.toString()).toBe("[object EventPhase]"); - }); - -}); - -describe("EventPhase.js static toString test", () => -{ - it("static toString test", () => - { - expect(EventPhase.toString()).toBe("[class EventPhase]"); - }); -}); - describe("EventPhase.js namespace test", () => { it("namespace test public", () => { - const eventPhase = new EventPhase(); - expect(eventPhase.namespace).toBe("next2d.events.EventPhase"); + expect(new EventPhase().namespace).toBe("next2d.events.EventPhase"); }); it("namespace test static", () => diff --git a/packages/events/src/EventPhase.ts b/packages/events/src/EventPhase.ts index 1c03698f..f79b226a 100644 --- a/packages/events/src/EventPhase.ts +++ b/packages/events/src/EventPhase.ts @@ -7,20 +7,6 @@ */ export class EventPhase { - /** - * 指定されたクラスのストリングを返します。 - * Returns the string representation of the specified class. - * - * @return {string} - * @default "[class EventPhase]" - * @method - * @static - */ - static toString (): string - { - return "[class EventPhase]"; - } - /** * @description 指定されたクラスの空間名を返します。 * Returns the space name of the specified class. @@ -35,20 +21,6 @@ export class EventPhase return "next2d.events.EventPhase"; } - /** - * @description 指定されたオブジェクトのストリングを返します。 - * Returns the string representation of the specified object. - * - * @return {string} - * @default "[object EventPhase]" - * @method - * @public - */ - toString (): string - { - return "[object EventPhase]"; - } - /** * @description 指定されたオブジェクトの空間名を返します。 * Returns the space name of the specified object. diff --git a/packages/events/src/EventUtil.ts b/packages/events/src/EventUtil.ts index 4283822a..dd7886a8 100644 --- a/packages/events/src/EventUtil.ts +++ b/packages/events/src/EventUtil.ts @@ -41,21 +41,7 @@ export const $poolArray = (array: any[]): void => * @type {Event} * @private */ -let $activeEvent: PointerEvent | null = null; - -/** - * @description アクティブなイベントオブジェクを返却 - * Returns the active event object - * - * @return {PointerEvent | null} - * @default null - * @method - * @protected - */ -export const $getEvent = (): PointerEvent | null => -{ - return $activeEvent; -}; +export let $activeEvent: PointerEvent | null = null; /** * @description アクティブなイベントオブジェクをセット diff --git a/packages/events/src/FocusEvent.test.ts b/packages/events/src/FocusEvent.test.ts index 7c464780..2e2b3496 100644 --- a/packages/events/src/FocusEvent.test.ts +++ b/packages/events/src/FocusEvent.test.ts @@ -1,30 +1,11 @@ import { FocusEvent } from "./FocusEvent"; import { describe, expect, it } from "vitest"; -describe("FocusEvent.js static toString test", () => -{ - it("static toString test", () => - { - expect(FocusEvent.toString()).toBe("[class FocusEvent]"); - }); -}); - -describe("FocusEvent.js toString test", () => -{ - // toString - it("toString test success", () => - { - const focusEvent = new FocusEvent("focusIn"); - expect(focusEvent.toString()).toBe("[FocusEvent type=\"focusIn\" bubbles=true cancelable=false eventPhase=2]"); - }); -}); - describe("FocusEvent.js namespace test", () => { it("namespace test public", () => { - const object = new FocusEvent("test"); - expect(object.namespace).toBe("next2d.events.FocusEvent"); + expect(new FocusEvent("test").namespace).toBe("next2d.events.FocusEvent"); }); it("namespace test static", () => @@ -37,11 +18,11 @@ describe("FocusEvent.js property test", () => { it("FOCUS_IN test", () => { - expect(FocusEvent.FOCUS_IN).toBe("focusIn"); + expect(FocusEvent.FOCUS_IN).toBe("focusin"); }); it("FOCUS_OUT test", () => { - expect(FocusEvent.FOCUS_OUT).toBe("focusOut"); + expect(FocusEvent.FOCUS_OUT).toBe("focusout"); }); }); \ No newline at end of file diff --git a/packages/events/src/FocusEvent.ts b/packages/events/src/FocusEvent.ts index e2c58a6d..931b30ba 100644 --- a/packages/events/src/FocusEvent.ts +++ b/packages/events/src/FocusEvent.ts @@ -1,5 +1,5 @@ import { Event } from "./Event"; -import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; +import { $activeEvent } from "./EventUtil"; /** * @description FocusEvent オブジェクトは、ユーザーが表示リストの1つのオブジェクトから @@ -19,28 +19,29 @@ export class FocusEvent extends Event /** * @param {string} type * @param {boolean} [bubbles=true] - * @param {boolean} [cancelable=false] * * @constructor * @public */ - constructor (type: string, bubbles: boolean = true, cancelable: boolean = false) + constructor (type: string, bubbles: boolean = true) { - super(type, bubbles, cancelable); - } + super(type, bubbles); - /** - * 指定されたクラスのストリングを返します。 - * Returns the string representation of the specified class. - * - * @return {string} - * @default "[class FocusEvent]" - * @method - * @static - */ - static toString (): string - { - return "[class FocusEvent]"; + return new Proxy(this, { + "get": (object: any, name: string) => + { + if (name in object) { + return object[name]; + } + + if ($activeEvent && name in $activeEvent) { + // @ts-ignore + return $activeEvent[name]; + } + + return undefined; + } + }); } /** @@ -57,21 +58,6 @@ export class FocusEvent extends Event return "next2d.events.FocusEvent"; } - /** - * @description 指定されたオブジェクトのストリングを返します。 - * Returns the string representation of the specified object. - * - * @return {string} - * @method - * @public - */ - toString (): string - { - return eventFormatToStringService(this, - "FocusEvent", "type", "bubbles", "cancelable", "eventPhase" - ); - } - /** * @description 指定されたオブジェクトの空間名を返します。 * Returns the space name of the specified object. @@ -91,13 +77,13 @@ export class FocusEvent extends Event * Defines the value of the type property of a focusIn event object. * * @return {string} - * @default focusIn + * @default "focusin" * @const * @static */ static get FOCUS_IN (): string { - return "focusIn"; + return "focusin"; } /** @@ -105,12 +91,12 @@ export class FocusEvent extends Event * Defines the value of the type property of a focusOut event object. * * @return {string} - * @default focusOut + * @default "focusout" * @const * @static */ static get FOCUS_OUT (): string { - return "focusOut"; + return "focusout"; } } \ No newline at end of file diff --git a/packages/events/src/HTTPStatusEvent.test.ts b/packages/events/src/HTTPStatusEvent.test.ts index 42097944..5bb7654b 100644 --- a/packages/events/src/HTTPStatusEvent.test.ts +++ b/packages/events/src/HTTPStatusEvent.test.ts @@ -1,39 +1,23 @@ import { HTTPStatusEvent } from "./HTTPStatusEvent"; import { describe, expect, it } from "vitest"; -describe("HTTPStatusEvent.js toString test", () => +describe("HTTPStatusEvent.js namespace test", () => { - it("toString test case1", () => - { - const httpStatusEvent = new HTTPStatusEvent(""); - expect(httpStatusEvent.toString()).toBe("[HTTPStatusEvent type=\"\" bubbles=false cancelable=false eventPhase=2 status=0 responseURL=\"\"]"); - }); - - it("toString test case2", () => + it("namespace test public", () => { - const httpStatusEvent = new HTTPStatusEvent("type", true, false, 200, "url"); - expect(httpStatusEvent.toString()).toBe("[HTTPStatusEvent type=\"type\" bubbles=true cancelable=false eventPhase=2 status=200 responseURL=\"url\"]"); + expect(new HTTPStatusEvent("test").namespace).toBe("next2d.events.HTTPStatusEvent"); }); -}); -describe("HTTPStatusEvent.js static toString test", () => -{ - it("static toString test", () => + it("namespace test static", () => { - expect(HTTPStatusEvent.toString()).toBe("[class HTTPStatusEvent]"); + expect(HTTPStatusEvent.namespace).toBe("next2d.events.HTTPStatusEvent"); }); }); -describe("HTTPStatusEvent.js namespace test", () => +describe("HTTPStatusEvent.js property test", () => { - it("namespace test public", () => - { - const object = new HTTPStatusEvent("test"); - expect(object.namespace).toBe("next2d.events.HTTPStatusEvent"); - }); - - it("namespace test static", () => + it("HTTP_STATUS test", () => { - expect(HTTPStatusEvent.namespace).toBe("next2d.events.HTTPStatusEvent"); + expect(HTTPStatusEvent.HTTP_STATUS).toBe("httpStatus"); }); }); \ No newline at end of file diff --git a/packages/events/src/HTTPStatusEvent.ts b/packages/events/src/HTTPStatusEvent.ts index 62a56d74..037abe3b 100644 --- a/packages/events/src/HTTPStatusEvent.ts +++ b/packages/events/src/HTTPStatusEvent.ts @@ -1,6 +1,5 @@ -import { Event } from "./Event"; import type { URLRequestHeaderImpl } from "./interface/URLRequestHeaderImpl"; -import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; +import { Event } from "./Event"; /** * @description ネットワーク要求が HTTP ステータスコードを返すと、アプリケーションによって HTTPStatusEvent オブジェクトが送出されます。 @@ -19,7 +18,6 @@ export class HTTPStatusEvent extends Event /** * @param {string} type * @param {boolean} [bubbles=false] - * @param {boolean} [cancelable=false] * @param {number} [status=0] * @param {string} [response_url=""] * @param {array} [response_headers=[]] @@ -28,12 +26,12 @@ export class HTTPStatusEvent extends Event * @public */ constructor ( - type: string, bubbles: boolean = false, cancelable: boolean = false, + type: string, bubbles: boolean = false, status: number = 0, response_url: string = "", response_headers: URLRequestHeaderImpl[] = [] ) { - super(type, bubbles, cancelable); + super(type, bubbles); /** * @type {number} @@ -57,20 +55,6 @@ export class HTTPStatusEvent extends Event this._$responseURL = response_url; } - /** - * @description 指定されたクラスのストリングを返します。 - * Returns the string representation of the specified class. - * - * @return {string} - * @default "[class HTTPStatusEvent]" - * @method - * @static - */ - static toString (): string - { - return "[class HTTPStatusEvent]"; - } - /** * @description 指定されたクラスの空間名を返します。 * Returns the space name of the specified class. @@ -85,23 +69,6 @@ export class HTTPStatusEvent extends Event return "next2d.events.HTTPStatusEvent"; } - /** - * @description 指定されたオブジェクトのストリングを返します。 - * Returns the string representation of the specified object. - * - * @return {string} - * @method - * @public - */ - toString (): string - { - return eventFormatToStringService(this, - "HTTPStatusEvent", - "type", "bubbles", "cancelable", - "eventPhase", "status", "responseURL" - ); - } - /** * @description 指定されたオブジェクトの空間名を返します。 * Returns the space name of the specified object. diff --git a/packages/events/src/IOErrorEvent.test.ts b/packages/events/src/IOErrorEvent.test.ts index 4dc71219..3f371ec8 100644 --- a/packages/events/src/IOErrorEvent.test.ts +++ b/packages/events/src/IOErrorEvent.test.ts @@ -1,36 +1,11 @@ import { IOErrorEvent } from "./IOErrorEvent"; import { describe, expect, it } from "vitest"; -describe("IOErrorEvent.js toString test", () => -{ - // toString - it("toString test case1", () => - { - const ioErrorEvent = new IOErrorEvent(""); - expect(ioErrorEvent.toString()).toBe("[IOErrorEvent type=\"\" bubbles=false cancelable=false eventPhase=2 text=\"\"]"); - }); - - it("toString test case2", () => - { - const ioErrorEvent = new IOErrorEvent("ioError", false, false, "IOErrorEvent"); - expect(ioErrorEvent.toString()).toBe("[IOErrorEvent type=\"ioError\" bubbles=false cancelable=false eventPhase=2 text=\"IOErrorEvent\"]"); - }); -}); - -describe("IOErrorEvent.js static toString test", () => -{ - it("static toString test", () => - { - expect(IOErrorEvent.toString()).toBe("[class IOErrorEvent]"); - }); -}); - describe("IOErrorEvent.js namespace test", () => { it("namespace test public", () => { - const ioErrorEvent = new IOErrorEvent("test"); - expect(ioErrorEvent.namespace).toBe("next2d.events.IOErrorEvent"); + expect(new IOErrorEvent("test").namespace).toBe("next2d.events.IOErrorEvent"); }); it("namespace test static", () => @@ -41,7 +16,8 @@ describe("IOErrorEvent.js namespace test", () => describe("IOErrorEvent.js property test", () => { - it("IO_ERROR test", function () { + it("IO_ERROR test", () => + { expect(IOErrorEvent.IO_ERROR).toBe("ioError"); }); }); \ No newline at end of file diff --git a/packages/events/src/IOErrorEvent.ts b/packages/events/src/IOErrorEvent.ts index 7867a5bd..9fb13be6 100644 --- a/packages/events/src/IOErrorEvent.ts +++ b/packages/events/src/IOErrorEvent.ts @@ -1,5 +1,4 @@ import { Event } from "./Event"; -import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; /** * @description IOErrorEvent オブジェクトは、エラーが発生して入力操作または出力操作が失敗したときに送出されます。 @@ -16,7 +15,6 @@ export class IOErrorEvent extends Event /** * @param {string} type * @param {boolean} [bubbles=true] - * @param {boolean} [cancelable=false] * @param {string} [text=""] * * @constructor @@ -25,11 +23,10 @@ export class IOErrorEvent extends Event constructor ( type: string, bubbles: boolean = false, - cancelable: boolean = false, text: string = "" ) { - super(type, bubbles, cancelable); + super(type, bubbles); /** * @type {string} @@ -39,20 +36,6 @@ export class IOErrorEvent extends Event this._$text = `${text}`; } - /** - * 指定されたクラスのストリングを返します。 - * Returns the string representation of the specified class. - * - * @return {string} - * @default "[class IOErrorEvent]" - * @method - * @static - */ - static toString (): string - { - return "[class IOErrorEvent]"; - } - /** * @description 指定されたクラスの空間名を返します。 * Returns the space name of the specified class. @@ -67,23 +50,6 @@ export class IOErrorEvent extends Event return "next2d.events.IOErrorEvent"; } - /** - * @description 指定されたオブジェクトのストリングを返します。 - * Returns the string representation of the specified object. - * - * @return {string} - * @method - * @public - */ - toString (): string - { - return eventFormatToStringService(this, - "IOErrorEvent", - "type", "bubbles", "cancelable", - "eventPhase", "text" - ); - } - /** * @description 指定されたオブジェクトの空間名を返します。 * Returns the space name of the specified object. diff --git a/packages/events/src/JobEvent.test.ts b/packages/events/src/JobEvent.test.ts new file mode 100644 index 00000000..bcabf257 --- /dev/null +++ b/packages/events/src/JobEvent.test.ts @@ -0,0 +1,28 @@ +import { JobEvent } from "./JobEvent"; +import { describe, expect, it } from "vitest"; + +describe("JobEvent.js namespace test", () => +{ + it("namespace test public", () => + { + expect(new JobEvent("test").namespace).toBe("next2d.events.JobEvent"); + }); + + it("namespace test static", () => + { + expect(JobEvent.namespace).toBe("next2d.events.JobEvent"); + }); +}); + +describe("JobEvent.js property test", () => +{ + it("UPDATE test", () => + { + expect(JobEvent.UPDATE).toBe("jobupdate"); + }); + + it("STOP test", () => + { + expect(JobEvent.STOP).toBe("jobstop"); + }); +}); \ No newline at end of file diff --git a/packages/events/src/JobEvent.ts b/packages/events/src/JobEvent.ts new file mode 100644 index 00000000..eb0cc496 --- /dev/null +++ b/packages/events/src/JobEvent.ts @@ -0,0 +1,68 @@ +import { Event } from "./Event"; + +/** + * @description Tween処理に関するイベントを示します。 + * Indicates events related to Tween processing. + * + * @class + * @memberOf next2d.events + * @extends Event + */ +export class JobEvent extends Event +{ + /** + * @description 指定されたクラスの空間名を返します。 + * Returns the space name of the specified class. + * + * @member {string} + * @default "next2d.events.JobEvent" + * @const + * @static + */ + static get namespace (): string + { + return "next2d.events.JobEvent"; + } + + /** + * @description 指定されたオブジェクトの空間名を返します。 + * Returns the space name of the specified object. + * + * @member {string} + * @default "next2d.events.JobEvent" + * @const + * @public + */ + get namespace (): string + { + return "next2d.events.JobEvent"; + } + + /** + * @description Jobのプロパティが更新されたときに発生します。 + * Occurs when the Job property is updated. + * + * @return {string} + * @default "jobupdate" + * @const + * @static + */ + static get UPDATE (): string + { + return "jobupdate"; + } + + /** + * @description TweenのJobが停止したときに発生します。 + * Occurs when the Tween Job is stopped. + * + * @return {string} + * @default "jobstop" + * @const + * @static + */ + static get STOP (): string + { + return "jobstop"; + } +} \ No newline at end of file diff --git a/packages/events/src/KeyboardEvent.test.ts b/packages/events/src/KeyboardEvent.test.ts new file mode 100644 index 00000000..f17995d1 --- /dev/null +++ b/packages/events/src/KeyboardEvent.test.ts @@ -0,0 +1,28 @@ +import { KeyboardEvent } from "./KeyboardEvent"; +import { describe, expect, it } from "vitest"; + +describe("KeyboardEvent.js namespace test", () => +{ + it("namespace test public", () => + { + expect(new KeyboardEvent("test").namespace).toBe("next2d.events.KeyboardEvent"); + }); + + it("namespace test static", () => + { + expect(KeyboardEvent.namespace).toBe("next2d.events.KeyboardEvent"); + }); +}); + +describe("KeyboardEvent.js property test", () => +{ + it("KEY_DOWN test", () => + { + expect(KeyboardEvent.KEY_DOWN).toBe("keydown"); + }); + + it("KEY_UP test", () => + { + expect(KeyboardEvent.KEY_UP).toBe("keyup"); + }); +}); \ No newline at end of file diff --git a/packages/events/src/KeyboardEvent.ts b/packages/events/src/KeyboardEvent.ts new file mode 100644 index 00000000..f6210c0e --- /dev/null +++ b/packages/events/src/KeyboardEvent.ts @@ -0,0 +1,97 @@ +import { $activeEvent } from "./EventUtil"; +import { Event } from "./Event"; + +/** + * @description キーボードによるユーザーの操作を示します。 + * Indicates user operation via keyboard. + * + * @class + * @memberOf next2d.events + * @extends Event + */ +export class KeyboardEvent extends Event +{ + /** + * @param {string} type + * @param {boolean} [bubbles=true] + * + * @constructor + * @public + */ + constructor (type: string, bubbles: boolean = true) + { + super(type, bubbles); + + return new Proxy(this, { + "get": (object: any, name: string) => + { + if (name in object) { + return object[name]; + } + + if ($activeEvent && name in $activeEvent) { + // @ts-ignore + return $activeEvent[name]; + } + + return undefined; + } + }); + } + + /** + * @description 指定されたクラスの空間名を返します。 + * Returns the space name of the specified class. + * + * @member {string} + * @default "next2d.events.KeyboardEvent" + * @const + * @static + */ + static get namespace (): string + { + return "next2d.events.KeyboardEvent"; + } + + /** + * @description 指定されたオブジェクトの空間名を返します。 + * Returns the space name of the specified object. + * + * @member {string} + * @default "next2d.events.KeyboardEvent" + * @const + * @public + */ + get namespace (): string + { + return "next2d.events.KeyboardEvent"; + } + + /** + * @description キーボードのキーが押される度に発生します。 + * Occurs each time a key is pressed on the keyboard. + * + * @return {string} + * @default "dblclick" + * @const + * @static + */ + static get KEY_DOWN (): string + { + return "keydown"; + } + + /** + * @description キーボードのキーが離されたときに発生します。 + * Occurs when a key on the keyboard is released. + * + * @return {string} + * @default "dblclick" + * @const + * @static + */ + static get KEY_UP (): string + { + return "keyup"; + } +} \ No newline at end of file diff --git a/packages/events/src/MouseEvent.test.ts b/packages/events/src/MouseEvent.test.ts deleted file mode 100644 index b1c2aaf2..00000000 --- a/packages/events/src/MouseEvent.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { MouseEvent } from "./MouseEvent"; -import { describe, expect, it } from "vitest"; - -describe("MouseEvent.js static toString test", () => -{ - it("static toString test", () => - { - expect(MouseEvent.toString()).toBe("[class MouseEvent]"); - }); -}); - -describe("MouseEvent.js namespace test", () => -{ - it("namespace test public", () => - { - const mouseEvent = new MouseEvent("test"); - expect(mouseEvent.namespace).toBe("next2d.events.MouseEvent"); - }); - - it("namespace test static", () => - { - expect(MouseEvent.namespace).toBe("next2d.events.MouseEvent"); - }); -}); - -describe("MouseEvent.js property test", () => -{ - it("CLICK test", () => - { - expect(MouseEvent.CLICK).toBe("click"); - }); - - it("DOUBLE_CLICK test", () => - { - expect(MouseEvent.DOUBLE_CLICK).toBe("dblclick"); - }); - - it("MOUSE_DOWN test", () => - { - expect(MouseEvent.MOUSE_DOWN).toBe("mouseDown"); - }); - - it("MOUSE_MOVE test", () => - { - expect(MouseEvent.MOUSE_MOVE).toBe("mouseMove"); - }); - - it("MOUSE_OUT test", () => - { - expect(MouseEvent.MOUSE_OUT).toBe("mouseOut"); - }); - - it("MOUSE_OVER test", () => - { - expect(MouseEvent.MOUSE_OVER).toBe("mouseOver"); - }); - - it("MOUSE_UP test", () => - { - expect(MouseEvent.MOUSE_UP).toBe("mouseUp"); - }); - - it("MOUSE_WHEEL test", () => { - expect(MouseEvent.MOUSE_WHEEL).toBe("mouseWheel"); - }); - - it("ROLL_OUT test", () => - { - expect(MouseEvent.ROLL_OUT).toBe("rollOut"); - }); - - it("ROLL_OVER test", () => - { - expect(MouseEvent.ROLL_OVER).toBe("rollOver"); - }); -}); \ No newline at end of file diff --git a/packages/events/src/MouseEvent.ts b/packages/events/src/MouseEvent.ts deleted file mode 100644 index e6fdd6ec..00000000 --- a/packages/events/src/MouseEvent.ts +++ /dev/null @@ -1,250 +0,0 @@ -import { Event } from "./Event"; -import { $getEvent } from "./EventUtil"; -import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; - -/** - * @description MouseEvent オブジェクトは、マウスイベントが発生するたびにイベントフローに送出されます。 - * 通常、マウスイベントは、マウスやトラックボールなど、ポインターを使用したユーザー入力デバイスによって生成されます。 - * A MouseEvent object is dispatched into the event flow whenever mouse events occur. - * A mouse event is usually generated by a user input device, - * such as a mouse or a trackball, that uses a pointer. - * - * @class - * @memberOf next2d.events - * @extends Event - */ -export class MouseEvent extends Event -{ - /** - * @param {string} type - * @param {boolean} [bubbles=true] - * @param {boolean} [cancelable=false] - * - * @constructor - * @public - */ - constructor (type: string, bubbles: boolean = true, cancelable: boolean = false) - { - - super(type, bubbles, cancelable); - - return new Proxy(this, { - "get": (object: any, name: string) => - { - if (name in object) { - return object[name]; - } - - const $event = $getEvent(); - if ($event && name in $event) { - // @ts-ignore - return $event[name]; - } - - return undefined; - } - }); - - } - - /** - * 指定されたクラスのストリングを返します。 - * Returns the string representation of the specified class. - * - * @return {string} - * @default "[class MouseEvent]" - * @method - * @static - */ - static toString (): string - { - return "[class MouseEvent]"; - } - - /** - * @description 指定されたクラスの空間名を返します。 - * Returns the space name of the specified class. - * - * @member {string} - * @default "next2d.events.MouseEvent" - * @const - * @static - */ - static get namespace (): string - { - return "next2d.events.MouseEvent"; - } - - /** - * @description 指定されたオブジェクトのストリングを返します。 - * Returns the string representation of the specified object. - * - * @return {string} - * @method - * @public - */ - toString (): string - { - return eventFormatToStringService(this, - "MouseEvent", - "type", "bubbles", "cancelable", "eventPhase", - "localX", "localY", "stageX", "stageY", - "ctrlKey", "altKey", "shiftKey", "buttonDown", - "delta", "commandKey", "controlKey", "clickCount" - ); - } - - /** - * @description 指定されたオブジェクトの空間名を返します。 - * Returns the space name of the specified object. - * - * @member {string} - * @default "next2d.events.MouseEvent" - * @const - * @public - */ - get namespace (): string - { - return "next2d.events.MouseEvent"; - } - - /** - * @description click イベントオブジェクトの type プロパティ値を定義します。 - * Defines the value of the type property of a click event object. - * - * @return {string} - * @default "click" - * @const - * @static - */ - static get CLICK (): string - { - return "click"; - } - - /** - * @description dblclick イベントオブジェクトの type プロパティ値を定義します。 - * Defines the value of the type property of a dblclick event object. - * - * @return {string} - * @default "dblclick" - * @const - * @static - */ - static get DOUBLE_CLICK (): string - { - return "dblclick"; - } - - /** - * @description mouseDown イベントオブジェクトの type プロパティ値を定義します。 - * Defines the value of the type property of a mouseDown event object. - * - * @return {string} - * @default "mouseDown" - * @const - * @static - */ - static get MOUSE_DOWN (): string - { - return "mouseDown"; - } - - /** - * @description mouseMove イベントオブジェクトの type プロパティ値を定義します。 - * Defines the value of the type property of a mouseMove event object. - * - * @return {string} - * @default "mouseMove" - * @const - * @static - */ - static get MOUSE_MOVE (): string - { - return "mouseMove"; - } - - /** - * @description mouseOut イベントオブジェクトの type プロパティ値を定義します。 - * Defines the value of the type property of a mouseOut event object. - * - * @return {string} - * @default "mouseOut" - * @const - * @static - */ - static get MOUSE_OUT (): string - { - return "mouseOut"; - } - - /** - * @description mouseOver イベントオブジェクトの type プロパティ値を定義します。 - * Defines the value of the type property of a mouseOver event object. - * - * @return {string} - * @default "mouseOver" - * @const - * @static - */ - static get MOUSE_OVER (): string - { - return "mouseOver"; - } - - /** - * @description mouseUp イベントオブジェクトの type プロパティ値を定義します。 - * Defines the value of the type property of a mouseUp event object. - * - * @return {string} - * @default "mouseUp" - * @const - * @static - */ - static get MOUSE_UP (): string - { - return "mouseUp"; - } - - /** - * @description mouseWheel イベントオブジェクトの type プロパティ値を定義します。 - * Defines the value of the type property of a mouseWheel event object. - * - * @return {string} - * @default "mouseWheel" - * @const - * @static - */ - static get MOUSE_WHEEL (): string - { - return "mouseWheel"; - } - - /** - * @description rollOut イベントオブジェクトの type プロパティ値を定義します。 - * Defines the value of the type property of a rollOut event object. - * - * @return {string} - * @default "rollOut" - * @const - * @static - */ - static get ROLL_OUT (): string - { - return "rollOut"; - } - - /** - * @description rollOver イベントオブジェクトの type プロパティ値を定義します。 - * Defines the value of the type property of a rollOver event object. - * - * @return {string} - * @default "rollOver" - * @const - * @static - */ - static get ROLL_OVER (): string - { - return "rollOver"; - } -} \ No newline at end of file diff --git a/packages/events/src/PointerEvent.test.ts b/packages/events/src/PointerEvent.test.ts new file mode 100644 index 00000000..047ecc0b --- /dev/null +++ b/packages/events/src/PointerEvent.test.ts @@ -0,0 +1,52 @@ +import { PointerEvent } from "./PointerEvent"; +import { describe, expect, it } from "vitest"; + +describe("PointerEvent.js namespace test", () => +{ + it("namespace test public", () => + { + expect(new PointerEvent("test").namespace).toBe("next2d.events.PointerEvent"); + }); + + it("namespace test static", () => + { + expect(PointerEvent.namespace).toBe("next2d.events.PointerEvent"); + }); +}); + +describe("PointerEvent.js property test", () => +{ + it("DOUBLE_CLICK test", () => + { + expect(PointerEvent.DOUBLE_CLICK).toBe("dblclick"); + }); + + it("POINTER_DOWN test", () => + { + expect(PointerEvent.POINTER_DOWN).toBe("pointerdown"); + }); + + it("POINTER_MOVE test", () => + { + expect(PointerEvent.POINTER_MOVE).toBe("pointermove"); + }); + + it("POINTER_OUT test", () => + { + expect(PointerEvent.POINTER_OUT).toBe("pointerout"); + }); + + it("POINTER_OVER test", () => + { + expect(PointerEvent.POINTER_OVER).toBe("pointerover"); + }); + + it("POINTER_UP test", () => + { + expect(PointerEvent.POINTER_UP).toBe("pointerup"); + }); + + it("WHEEL test", () => { + expect(PointerEvent.WHEEL).toBe("wheel"); + }); +}); \ No newline at end of file diff --git a/packages/events/src/PointerEvent.ts b/packages/events/src/PointerEvent.ts new file mode 100644 index 00000000..7060848f --- /dev/null +++ b/packages/events/src/PointerEvent.ts @@ -0,0 +1,170 @@ +import { $activeEvent } from "./EventUtil"; +import { Event } from "./Event"; + +/** + * @description ポインターは、入力機器(マウス、ペン、またはタッチ可能な面の上の接触点など)のハードウェアにとらわれない表現です。 + * ポインターは、画面などの接触面上の特定の座標(または座標の集合)をターゲットにすることができます。 + * A pointer is a hardware-agnostic representation of an input device (such as a mouse, pen, or point of contact on a touchable surface). + * A pointer can target a specific coordinate (or set of coordinates) on a screen or other contact surface. + * + * @class + * @memberOf next2d.events + * @extends Event + */ +export class PointerEvent extends Event +{ + /** + * @param {string} type + * @param {boolean} [bubbles=true] + * + * @constructor + * @public + */ + constructor (type: string, bubbles: boolean = true) + { + + super(type, bubbles); + + return new Proxy(this, { + "get": (object: any, name: string) => + { + if (name in object) { + return object[name]; + } + + if ($activeEvent && name in $activeEvent) { + // @ts-ignore + return $activeEvent[name]; + } + + return undefined; + } + }); + } + + /** + * @description 指定されたクラスの空間名を返します。 + * Returns the space name of the specified class. + * + * @member {string} + * @default "next2d.events.PointerEvent" + * @const + * @static + */ + static get namespace (): string + { + return "next2d.events.PointerEvent"; + } + + /** + * @description 指定されたオブジェクトの空間名を返します。 + * Returns the space name of the specified object. + * + * @member {string} + * @default "next2d.events.PointerEvent" + * @const + * @public + */ + get namespace (): string + { + return "next2d.events.PointerEvent"; + } + + /** + * @description ボタンが連続で押された時に発生します。 + * Occurs when a button is pressed continuously. + * + * @return {string} + * @default "dblclick" + * @const + * @static + */ + static get DOUBLE_CLICK (): string + { + return "dblclick"; + } + + /** + * @description ボタンが押されていない状態から 1 つ以上のボタンが押されている状態に遷移したときに発生します + * Occurs when one or more buttons are pressed from the state where no buttons are pressed. + * + * @return {string} + * @default "pointerdown" + * @const + * @static + */ + static get POINTER_DOWN (): string + { + return "pointerdown"; + } + + /** + * @description ポインターの座標が変化し、かつタッチ操作によってポインターがキャンセルされていないときに発生します。 + * Occurs when the pointer coordinates change and the pointer is not canceled by a touch operation. + * + * @return {string} + * @default "pointermove" + * @const + * @static + */ + static get POINTER_MOVE (): string + { + return "pointermove"; + } + + /** + * @description ヒットテスト境界を出たに発生します。ホバーに対応していない端末では発生しません。 + * Occurs when the hit test boundary is exited. Does not occur on devices that do not support hover. + * + * @return {string} + * @default "pointerout" + * @const + * @static + */ + static get POINTER_OUT (): string + { + return "pointerout"; + } + + /** + * @description インティングデバイスが要素のヒットテスト境界内に移動したときに発生します。 + * Occurs when the pointing device moves into the hit test boundary of an element. + * + * @return {string} + * @default "mouseOver" + * @const + * @static + */ + static get POINTER_OVER (): string + { + return "pointerover"; + } + + /** + * @description ポインターがアクティブではなくなったときに発生します。 + * Occurs when the pointer is no longer active. + * + * @return {string} + * @default "pointerup" + * @const + * @static + */ + static get POINTER_UP (): string + { + return "pointerup"; + } + + /** + * @description ポインティングデバイス(通常はマウス)のホイールボタンを回転させたときに発生します。 + * Occurs when the wheel button of a pointing device (usually a mouse) is rotated. + * + * @return {string} + * @default "wheel" + * @const + * @static + */ + static get WHEEL (): string + { + return "wheel"; + } +} \ No newline at end of file diff --git a/packages/events/src/ProgressEvent.test.ts b/packages/events/src/ProgressEvent.test.ts index 02a06c28..8f523f2e 100644 --- a/packages/events/src/ProgressEvent.test.ts +++ b/packages/events/src/ProgressEvent.test.ts @@ -1,29 +1,11 @@ import { ProgressEvent } from "./ProgressEvent"; import { describe, expect, it } from "vitest"; -describe("ProgressEvent.js toString test", () => -{ - it("toString test success", () => - { - const progressEvent = new ProgressEvent(""); - expect(progressEvent.toString()).toBe("[ProgressEvent type=\"\" bubbles=false cancelable=false eventPhase=2 bytesLoaded=0 bytesTotal=0]"); - }); -}); - -describe("ProgressEvent.js static toString test", () => -{ - it("static toString test", () => - { - expect(ProgressEvent.toString()).toBe("[class ProgressEvent]"); - }); -}); - describe("ProgressEvent.js namespace test", () => { it("namespace test public", () => { - const object = new ProgressEvent("test"); - expect(object.namespace).toBe("next2d.events.ProgressEvent"); + expect(new ProgressEvent("test").namespace).toBe("next2d.events.ProgressEvent"); }); it("namespace test static", () => diff --git a/packages/events/src/ProgressEvent.ts b/packages/events/src/ProgressEvent.ts index 443cf066..7566fe92 100644 --- a/packages/events/src/ProgressEvent.ts +++ b/packages/events/src/ProgressEvent.ts @@ -1,5 +1,4 @@ import { Event } from "./Event"; -import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; /** * @description ProgressEvent オブジェクトは、ロード処理が開始されたとき、またはソケットがデータを受信したときに送出されます。 @@ -19,7 +18,6 @@ export class ProgressEvent extends Event /** * @param {string} type * @param {boolean} [bubbles=true] - * @param {boolean} [cancelable=false] * @param {number} [bytes_loaded=0] * @param {number} [bytes_total=0] * @@ -27,11 +25,11 @@ export class ProgressEvent extends Event * @public */ constructor ( - type: string, bubbles: boolean = false, cancelable: boolean = false, + type: string, bubbles: boolean = false, bytes_loaded: number = 0, bytes_total: number = 0 ) { - super(type, bubbles, cancelable); + super(type, bubbles); /** * @type {number} @@ -48,20 +46,6 @@ export class ProgressEvent extends Event this._$bytesTotal = bytes_total | 0; } - /** - * 指定されたクラスのストリングを返します。 - * Returns the string representation of the specified class. - * - * @return {string} - * @default "[class ProgressEvent]" - * @method - * @static - */ - static toString (): string - { - return "[class ProgressEvent]"; - } - /** * @description 指定されたクラスの空間名を返します。 * Returns the space name of the specified class. @@ -76,23 +60,6 @@ export class ProgressEvent extends Event return "next2d.events.ProgressEvent"; } - /** - * @description 指定されたオブジェクトのストリングを返します。 - * Returns the string representation of the specified object. - * - * @return {string} - * @method - * @public - */ - toString (): string - { - return eventFormatToStringService(this, - "ProgressEvent", - "type", "bubbles", "cancelable", - "eventPhase", "bytesLoaded", "bytesTotal" - ); - } - /** * @description 指定されたオブジェクトの空間名を返します。 * Returns the space name of the specified object. diff --git a/packages/events/src/VideoEvent.test.ts b/packages/events/src/VideoEvent.test.ts index 93f3eae1..a4cc31e8 100644 --- a/packages/events/src/VideoEvent.test.ts +++ b/packages/events/src/VideoEvent.test.ts @@ -1,29 +1,11 @@ import { VideoEvent } from "./VideoEvent"; import { describe, expect, it } from "vitest"; -describe("VideoEvent.js toString test", () => -{ - it("toString test success", () => - { - const videoEvent = new VideoEvent(""); - expect(videoEvent.toString()).toBe("[VideoEvent type=\"\" bubbles=false cancelable=false eventPhase=2]"); - }); -}); - -describe("VideoEvent.js static toString test", () => -{ - it("static toString test", () => - { - expect(VideoEvent.toString()).toBe("[class VideoEvent]"); - }); -}); - describe("VideoEvent.js namespace test", () => { it("namespace test public", () => { - const videoEvent = new VideoEvent("test"); - expect(videoEvent.namespace).toBe("next2d.events.VideoEvent"); + expect(new VideoEvent("test").namespace).toBe("next2d.events.VideoEvent"); }); it("namespace test static", () => @@ -34,19 +16,14 @@ describe("VideoEvent.js namespace test", () => describe("VideoEvent.js property test", () => { - it("PLAY_START test", () => - { - expect(VideoEvent.PLAY_START).toBe("playStart"); - }); - it("PLAY test", () => { expect(VideoEvent.PLAY).toBe("play"); }); - it("PLAY_END test", () => + it("PLAYING test", () => { - expect(VideoEvent.PLAY_END).toBe("playEnd"); + expect(VideoEvent.PLAYING).toBe("playing"); }); it("PAUSE test", () => diff --git a/packages/events/src/VideoEvent.ts b/packages/events/src/VideoEvent.ts index 5aac3a55..7d5b3923 100644 --- a/packages/events/src/VideoEvent.ts +++ b/packages/events/src/VideoEvent.ts @@ -1,5 +1,4 @@ import { Event } from "./Event"; -import { execute as eventFormatToStringService } from "./Event/EventFormatToStringService"; /** * @description ビデオを再生または停止すると、VideoEvent オブジェクトを送出します。 @@ -11,19 +10,6 @@ import { execute as eventFormatToStringService } from "./Event/EventFormatToStri */ export class VideoEvent extends Event { - /** - * 指定されたクラスのストリングを返します。 - * Returns the string representation of the specified class. - * - * @return {string} - * @default "[class VideoEvent]" - * @method - * @static - */ - static toString (): string - { - return "[class VideoEvent]"; - } /** * @description 指定されたクラスの空間名を返します。 @@ -39,22 +25,6 @@ export class VideoEvent extends Event return "next2d.events.VideoEvent"; } - /** - * @description 指定されたオブジェクトのストリングを返します。 - * Returns the string representation of the specified object. - * - * @return {string} - * @method - * @public - */ - toString (): string - { - return eventFormatToStringService(this, - "VideoEvent", - "type", "bubbles", "cancelable", "eventPhase" - ); - } - /** * @description 指定されたオブジェクトの空間名を返します。 * Returns the space name of the specified object. @@ -74,7 +44,6 @@ export class VideoEvent extends Event * Defines the value of the type property of a play event object. * * @return {string} - * @default play * @const * @static */ @@ -88,27 +57,12 @@ export class VideoEvent extends Event * Defines the value of the type property of a playStart event object. * * @return {string} - * @default "playStart" - * @const - * @static - */ - static get PLAY_START (): string - { - return "playStart"; - } - - /** - * @description playEnd イベントオブジェクトの type プロパティ値を定義します。 - * Defines the value of the type property of a playEnd event object. - * - * @return {string} - * @default "playEnd" * @const * @static */ - static get PLAY_END (): string + static get PLAYING (): string { - return "playEnd"; + return "playing"; } /** @@ -116,7 +70,6 @@ export class VideoEvent extends Event * Defines the value of the type property of a pause event object. * * @return {string} - * @default "pause" * @const * @static */ @@ -130,7 +83,6 @@ export class VideoEvent extends Event * Defines the value of the type property of a seek event object. * * @return {string} - * @default "seek" * @const * @static */ diff --git a/packages/events/src/index.ts b/packages/events/src/index.ts index e438d7a3..6f18e4da 100644 --- a/packages/events/src/index.ts +++ b/packages/events/src/index.ts @@ -4,6 +4,8 @@ export * from "./EventPhase"; export * from "./FocusEvent"; export * from "./HTTPStatusEvent"; export * from "./IOErrorEvent"; -export * from "./MouseEvent"; +export * from "./PointerEvent"; export * from "./ProgressEvent"; -export * from "./VideoEvent"; \ No newline at end of file +export * from "./VideoEvent"; +export * from "./JobEvent"; +export { $setEvent } from "./EventUtil"; \ No newline at end of file diff --git a/packages/events/src/interface/EventDispatcherImpl.ts b/packages/events/src/interface/EventDispatcherImpl.ts index b93109ee..3964bd3b 100644 --- a/packages/events/src/interface/EventDispatcherImpl.ts +++ b/packages/events/src/interface/EventDispatcherImpl.ts @@ -1,2 +1,3 @@ import type { EventDispatcher } from "../EventDispatcher"; + export type EventDispatcherImpl = T; \ No newline at end of file diff --git a/packages/events/src/interface/EventImpl.ts b/packages/events/src/interface/EventImpl.ts index 4e13165a..73ebf101 100644 --- a/packages/events/src/interface/EventImpl.ts +++ b/packages/events/src/interface/EventImpl.ts @@ -1,2 +1,3 @@ import type { Event } from "../Event"; + export type EventImpl = T; \ No newline at end of file diff --git a/packages/events/src/interface/EventListenerImpl.ts b/packages/events/src/interface/EventListenerImpl.ts index 2e1c9cfe..b33d520c 100644 --- a/packages/events/src/interface/EventListenerImpl.ts +++ b/packages/events/src/interface/EventListenerImpl.ts @@ -1,6 +1,8 @@ +import type { EventDispatcherImpl } from "./EventDispatcherImpl"; + export interface EventListenerImpl { listener: Function; priority: number; useCapture: boolean; - target: any; + target: EventDispatcherImpl; } \ No newline at end of file diff --git a/packages/media/src/Sound.test.ts b/packages/media/src/Sound.test.ts index fd84afb6..ae227d41 100644 --- a/packages/media/src/Sound.test.ts +++ b/packages/media/src/Sound.test.ts @@ -12,20 +12,4 @@ describe("Sound.js namespace test", () => { expect(Sound.namespace).toBe("next2d.media.Sound"); }); -}); - -describe("Sound.js toString test", () => -{ - it("toString test success", () => - { - expect(new Sound().toString()).toBe("[object Sound]"); - }); -}); - -describe("Sound.js static toString test", () => -{ - it("static toString test", () => - { - expect(Sound.toString()).toBe("[class Sound]"); - }); }); \ No newline at end of file diff --git a/packages/media/src/Sound.ts b/packages/media/src/Sound.ts index e0474480..deabcbe6 100644 --- a/packages/media/src/Sound.ts +++ b/packages/media/src/Sound.ts @@ -29,12 +29,30 @@ export class Sound extends EventDispatcher { private _$source: AudioBufferSourceNode | null; private _$gain: GainNode | null; - private _$audioBuffer: AudioBuffer | null; - private _$volume: number; + private _$stopFlag: boolean; private _$currentCount: number; + private _$volume: number; private _$src: string; - private _$loopCount: number; - private _$stopFlag: boolean; + + /** + * @description AudioBuffer + * AudioBuffer + * + * @type {AudioBuffer} + * @default null + * @public + */ + public audioBuffer: AudioBuffer | null; + + /** + * @description ループ回数の設定 + * Loop count setting. + * + * @type {string} + * @default 0 + * @public + */ + public loopCount: number; /** * @constructor @@ -44,6 +62,9 @@ export class Sound extends EventDispatcher { super(); + this.loopCount = 0; + this.audioBuffer = null; + /** * @type {number} * @default 1 @@ -52,18 +73,18 @@ export class Sound extends EventDispatcher this._$volume = 1; /** - * @type {number} - * @default 0 + * @type {string} + * @default "" * @private */ - this._$currentCount = 0; + this._$src = ""; /** * @type {number} * @default 0 * @private */ - this._$loopCount = 0; + this._$currentCount = 0; /** * @type {boolean} @@ -72,13 +93,6 @@ export class Sound extends EventDispatcher */ this._$stopFlag = true; - /** - * @type {string} - * @default "" - * @private - */ - this._$src = ""; - /** * @type {AudioBufferSourceNode} * @default null @@ -92,27 +106,6 @@ export class Sound extends EventDispatcher * @private */ this._$gain = null; - - /** - * @type {AudioBuffer} - * @default null - * @private - */ - this._$audioBuffer = null; - } - - /** - * @description 指定されたクラスのストリングを返します。 - * Returns the string representation of the specified class. - * - * @return {string} - * @default "[class Sound]" - * @method - * @static - */ - static toString (): string - { - return "[class Sound]"; } /** @@ -129,20 +122,6 @@ export class Sound extends EventDispatcher return "next2d.media.Sound"; } - /** - * @description 指定されたオブジェクトのストリングを返します。 - * Returns the string representation of the specified object. - * - * @return {string} - * @default "[object Sound]" - * @method - * @public - */ - toString (): string - { - return "[object Sound]"; - } - /** * @description 指定されたオブジェクトの空間名を返します。 * Returns the space name of the specified object. @@ -157,23 +136,6 @@ export class Sound extends EventDispatcher return "next2d.media.Sound"; } - /** - * @description ループ回数の設定 - * Loop count setting. - * - * @member {number} - * @default 0 - * @public - */ - get loopCount (): number - { - return this._$loopCount; - } - set loopCount (loop_count: number) - { - this._$loopCount = loop_count; - } - /** * @description 外部サウンドのURL * URL for external sound. @@ -224,24 +186,7 @@ export class Sound extends EventDispatcher */ get canLoop (): boolean { - return !this._$stopFlag && this._$loopCount >= this._$currentCount; - } - - /** - * @description AudioBuffer - * AudioBuffer - * - * @member {AudioBuffer} - * @default null - * @public - */ - get audioBuffer (): AudioBuffer | null - { - return this._$audioBuffer; - } - set audioBuffer (audio_buffer: AudioBuffer | null) - { - this._$audioBuffer = audio_buffer; + return !this._$stopFlag && this.loopCount >= this._$currentCount; } /** @@ -256,8 +201,8 @@ export class Sound extends EventDispatcher { const sound = new Sound(); sound.volume = this._$volume; - sound.loopCount = this._$loopCount; - sound.audioBuffer = this._$audioBuffer; + sound.loopCount = this.loopCount; + sound.audioBuffer = this.audioBuffer; return sound; } @@ -313,10 +258,18 @@ export class Sound extends EventDispatcher */ play (start_time: number = 0): void { - if (!this._$audioBuffer || !$audioContext) { + // 再生中なら終了 + if (!this._$stopFlag) { + return ; + } + + if (!this.audioBuffer || !$audioContext) { return ; } + // 初期化 + this.stop(); + this._$gain = $audioContext.createGain(); this._$gain.connect($audioContext.destination); this._$gain.gain.value = Math.min(SoundMixer.volume, this._$volume); @@ -327,19 +280,14 @@ export class Sound extends EventDispatcher soundEndedEventService(this); }); - this._$source.buffer = this._$audioBuffer; + this._$source.buffer = this.audioBuffer; this._$source.connect(this._$gain); this._$source.start(start_time); this._$stopFlag = false; this._$currentCount++; - const sounds = $getSounds(); - const index = sounds.indexOf(this); - if (index > -1) { - sounds.splice(index, 1); - } - sounds.push(this); + $getSounds().push(this); } /** @@ -352,6 +300,10 @@ export class Sound extends EventDispatcher */ stop (): void { + if (this._$stopFlag) { + return ; + } + this._$stopFlag = true; this._$currentCount = 0; @@ -378,11 +330,11 @@ export class Sound extends EventDispatcher * Create Sound from Character Data * * @param {Character} character - * @return {void} + * @return {Promise} * @method * @private */ - async build (character: Character): Promise + async _$build (character: Character): Promise { // load AudioBuffer if (!character.audioBuffer) { @@ -394,6 +346,6 @@ export class Sound extends EventDispatcher character.audioBuffer = audioBuffer; } - this._$audioBuffer = character.audioBuffer; + this.audioBuffer = character.audioBuffer; } } \ No newline at end of file diff --git a/packages/media/src/Sound/SoundEndedEventService.test.ts b/packages/media/src/Sound/SoundEndedEventService.test.ts index c3fec39d..e9927ce0 100644 --- a/packages/media/src/Sound/SoundEndedEventService.test.ts +++ b/packages/media/src/Sound/SoundEndedEventService.test.ts @@ -43,6 +43,6 @@ describe("SoundEndedEventService.js test", () => expect(state).toBe(""); execute(new MockSound()); expect(state).toBe("stop"); - expect(type).toBe(Event.SOUND_COMPLETE); + expect(type).toBe(Event.COMPLETE); }); }); \ No newline at end of file diff --git a/packages/media/src/Sound/SoundEndedEventService.ts b/packages/media/src/Sound/SoundEndedEventService.ts index 7da33026..4fea44e3 100644 --- a/packages/media/src/Sound/SoundEndedEventService.ts +++ b/packages/media/src/Sound/SoundEndedEventService.ts @@ -20,8 +20,8 @@ export const execute = (sound: Sound): void => sound.stop(); - if (sound.willTrigger(Event.SOUND_COMPLETE)) { - sound.dispatchEvent(new Event(Event.SOUND_COMPLETE)); + if (sound.willTrigger(Event.COMPLETE)) { + sound.dispatchEvent(new Event(Event.COMPLETE)); } } }; \ No newline at end of file diff --git a/packages/media/src/Sound/SoundLoadStartEventService.ts b/packages/media/src/Sound/SoundLoadStartEventService.ts index 396e1b94..81411fad 100644 --- a/packages/media/src/Sound/SoundLoadStartEventService.ts +++ b/packages/media/src/Sound/SoundLoadStartEventService.ts @@ -22,7 +22,7 @@ export const execute = (sound: Sound, event: ProgressEvent): void => if (sound.willTrigger(Next2DProgressEvent.PROGRESS)) { sound.dispatchEvent(new Next2DProgressEvent( - Next2DProgressEvent.PROGRESS, false, false, + Next2DProgressEvent.PROGRESS, false, event.loaded, event.total )); } diff --git a/packages/media/src/Sound/SoundLoadendEventService.ts b/packages/media/src/Sound/SoundLoadendEventService.ts index 16dbbf20..cd5c2f33 100644 --- a/packages/media/src/Sound/SoundLoadendEventService.ts +++ b/packages/media/src/Sound/SoundLoadendEventService.ts @@ -25,7 +25,7 @@ export const execute = async (sound: Sound, event: ProgressEvent): Promise