From fc511dbf299309273de87caef7737ab345adbbfc Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Sat, 21 Dec 2024 23:27:52 +0800 Subject: [PATCH] feat: Text Content --- package.json | 2 +- pnpm-lock.yaml | 685 +++++++++++++------------ src/core/render/components/textbox.tsx | 561 +++++++++++++++----- src/core/render/components/types.ts | 12 + src/core/render/index.tsx | 7 +- src/core/render/pool.ts | 44 ++ src/core/render/renderer/map.ts | 1 + src/core/render/renderer/props.ts | 24 +- src/core/render/sprite.ts | 2 +- src/core/render/utils.ts | 3 +- src/data/logger.json | 2 + 11 files changed, 865 insertions(+), 478 deletions(-) create mode 100644 src/core/render/components/types.ts create mode 100644 src/core/render/pool.ts diff --git a/package.json b/package.json index 87b52da..110e6c4 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "lodash-es": "^4.17.21", "lz-string": "^1.5.0", "mutate-animate": "^1.4.2", - "vue": "^3.4.38" + "vue": "^3.5.13" }, "devDependencies": { "@babel/cli": "^7.24.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5e77a11..524cbac 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,19 +10,19 @@ importers: dependencies: '@ant-design/icons-vue': specifier: ^6.1.0 - version: 6.1.0(vue@3.4.38(typescript@5.5.4)) + version: 6.1.0(vue@3.5.13(typescript@5.5.4)) '@emotion/css': specifier: ^11.13.0 version: 11.13.0 '@vueuse/core': specifier: ^10.11.1 - version: 10.11.1(vue@3.4.38(typescript@5.5.4)) + version: 10.11.1(vue@3.5.13(typescript@5.5.4)) anon-tokyo: specifier: 0.0.0-alpha.0 version: 0.0.0-alpha.0 ant-design-vue: specifier: ^3.2.20 - version: 3.2.20(vue@3.4.38(typescript@5.5.4)) + version: 3.2.20(vue@3.5.13(typescript@5.5.4)) axios: specifier: ^1.7.4 version: 1.7.4 @@ -51,8 +51,8 @@ importers: specifier: ^1.4.2 version: 1.4.2 vue: - specifier: ^3.4.38 - version: 3.4.38(typescript@5.5.4) + specifier: ^3.5.13 + version: 3.5.13(typescript@5.5.4) devDependencies: '@babel/cli': specifier: ^7.24.8 @@ -107,10 +107,10 @@ importers: version: 4.1.1(terser@5.31.6)(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)) '@vitejs/plugin-vue': specifier: ^4.6.2 - version: 4.6.2(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.4.38(typescript@5.5.4)) + version: 4.6.2(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4)) '@vitejs/plugin-vue-jsx': specifier: ^3.1.0 - version: 3.1.0(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.4.38(typescript@5.5.4)) + version: 3.1.0(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4)) chokidar: specifier: ^3.6.0 version: 3.6.0 @@ -131,7 +131,7 @@ importers: version: 4.2.0 postcss-preset-env: specifier: ^9.6.0 - version: 9.6.0(postcss@8.4.47) + version: 9.6.0(postcss@8.4.49) rollup: specifier: ^3.29.4 version: 3.29.4 @@ -146,7 +146,7 @@ importers: version: 5.5.4 unplugin-vue-components: specifier: ^0.22.12 - version: 0.22.12(@babel/parser@7.25.6)(rollup@3.29.4)(vue@3.4.38(typescript@5.5.4)) + version: 0.22.12(@babel/parser@7.26.3)(rollup@3.29.4)(vue@3.5.13(typescript@5.5.4)) vite: specifier: ^4.5.3 version: 4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6) @@ -279,10 +279,18 @@ packages: resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.24.7': resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.24.8': resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} engines: {node: '>=6.9.0'} @@ -309,6 +317,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.26.3': + resolution: {integrity: sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3': resolution: {integrity: sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==} engines: {node: '>=6.9.0'} @@ -787,6 +800,10 @@ packages: resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==} engines: {node: '>=6.9.0'} + '@babel/types@7.26.3': + resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} + engines: {node: '>=6.9.0'} + '@csstools/cascade-layer-name-parser@1.0.13': resolution: {integrity: sha512-MX0yLTwtZzr82sQ0zOjqimpZbzjMaK/h2pmlrLK7DCzlmiZLYFpoO94WmN1akRVo6ll/TdpHb53vihHLUMyvng==} engines: {node: ^14 || ^16 || >=18} @@ -1572,23 +1589,17 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@vue/compiler-core@3.4.38': - resolution: {integrity: sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==} + '@vue/compiler-core@3.5.13': + resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} - '@vue/compiler-core@3.5.10': - resolution: {integrity: sha512-iXWlk+Cg/ag7gLvY0SfVucU8Kh2CjysYZjhhP70w9qI4MvSox4frrP+vDGvtQuzIcgD8+sxM6lZvCtdxGunTAA==} + '@vue/compiler-dom@3.5.13': + resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} - '@vue/compiler-dom@3.4.38': - resolution: {integrity: sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==} + '@vue/compiler-sfc@3.5.13': + resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} - '@vue/compiler-dom@3.5.10': - resolution: {integrity: sha512-DyxHC6qPcktwYGKOIy3XqnHRrrXyWR2u91AjP+nLkADko380srsC2DC3s7Y1Rk6YfOlxOlvEQKa9XXmLI+W4ZA==} - - '@vue/compiler-sfc@3.4.38': - resolution: {integrity: sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==} - - '@vue/compiler-ssr@3.4.38': - resolution: {integrity: sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==} + '@vue/compiler-ssr@3.5.13': + resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} '@vue/compiler-vue2@2.7.16': resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} @@ -1601,25 +1612,22 @@ packages: typescript: optional: true - '@vue/reactivity@3.4.38': - resolution: {integrity: sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==} + '@vue/reactivity@3.5.13': + resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} - '@vue/runtime-core@3.4.38': - resolution: {integrity: sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==} + '@vue/runtime-core@3.5.13': + resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} - '@vue/runtime-dom@3.4.38': - resolution: {integrity: sha512-afZzmUreU7vKwKsV17H1NDThEEmdYI+GCAK/KY1U957Ig2NATPVjCROv61R19fjZNzMmiU03n79OMnXyJVN0UA==} + '@vue/runtime-dom@3.5.13': + resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} - '@vue/server-renderer@3.4.38': - resolution: {integrity: sha512-NggOTr82FbPEkkUvBm4fTGcwUY8UuTsnWC/L2YZBmvaQ4C4Jl/Ao4HHTB+l7WnFCt5M/dN3l0XLuyjzswGYVCA==} + '@vue/server-renderer@3.5.13': + resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} peerDependencies: - vue: 3.4.38 + vue: 3.5.13 - '@vue/shared@3.4.38': - resolution: {integrity: sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==} - - '@vue/shared@3.5.10': - resolution: {integrity: sha512-VkkBhU97Ki+XJ0xvl4C9YJsIZ2uIlQ7HqPpZOS3m9VCvmROPaChZU6DexdMJqvz9tbgG+4EtFVrSuailUq5KGQ==} + '@vue/shared@3.5.13': + resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} '@vueuse/core@10.11.1': resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==} @@ -2539,6 +2547,9 @@ packages: magic-string@0.30.11: resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + make-dir@2.1.0: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} engines: {node: '>=6'} @@ -2964,8 +2975,8 @@ packages: resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} engines: {node: ^10 || ^12 || >=14} - postcss@8.4.47: - resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} engines: {node: ^10 || ^12 || >=14} process-nextick-args@2.0.1: @@ -3183,10 +3194,6 @@ packages: resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} - engines: {node: '>=0.10.0'} - source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -3484,8 +3491,8 @@ packages: peerDependencies: vue: ^3.0.0 - vue@3.4.38: - resolution: {integrity: sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==} + vue@3.5.13: + resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -3563,11 +3570,11 @@ snapshots: '@ant-design/icons-svg@4.4.2': {} - '@ant-design/icons-vue@6.1.0(vue@3.4.38(typescript@5.5.4))': + '@ant-design/icons-vue@6.1.0(vue@3.5.13(typescript@5.5.4))': dependencies: '@ant-design/colors': 6.0.0 '@ant-design/icons-svg': 4.4.2 - vue: 3.4.38(typescript@5.5.4) + vue: 3.5.13(typescript@5.5.4) '@antfu/utils@0.7.10': {} @@ -3737,8 +3744,12 @@ snapshots: '@babel/helper-string-parser@7.24.8': {} + '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-validator-identifier@7.24.7': {} + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-option@7.24.8': {} '@babel/helper-wrap-function@7.25.0': @@ -3769,6 +3780,10 @@ snapshots: dependencies: '@babel/types': 7.25.6 + '@babel/parser@7.26.3': + dependencies: + '@babel/types': 7.26.3 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -4381,6 +4396,11 @@ snapshots: '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 + '@babel/types@7.26.3': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@csstools/cascade-layer-name-parser@1.0.13(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1)': dependencies: '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) @@ -4411,201 +4431,201 @@ snapshots: '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - '@csstools/postcss-cascade-layers@4.0.6(postcss@8.4.47)': + '@csstools/postcss-cascade-layers@4.0.6(postcss@8.4.49)': dependencies: '@csstools/selector-specificity': 3.1.1(postcss-selector-parser@6.1.2) - postcss: 8.4.47 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - '@csstools/postcss-color-function@3.0.19(postcss@8.4.47)': + '@csstools/postcss-color-function@3.0.19(postcss@8.4.49)': dependencies: '@csstools/css-color-parser': 2.0.5(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.47) - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.49) + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 - '@csstools/postcss-color-mix-function@2.0.19(postcss@8.4.47)': + '@csstools/postcss-color-mix-function@2.0.19(postcss@8.4.49)': dependencies: '@csstools/css-color-parser': 2.0.5(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.47) - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.49) + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 - '@csstools/postcss-content-alt-text@1.0.0(postcss@8.4.47)': + '@csstools/postcss-content-alt-text@1.0.0(postcss@8.4.49)': dependencies: '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.47) - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.49) + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 - '@csstools/postcss-exponential-functions@1.0.9(postcss@8.4.47)': + '@csstools/postcss-exponential-functions@1.0.9(postcss@8.4.49)': dependencies: '@csstools/css-calc': 1.2.4(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - postcss: 8.4.47 + postcss: 8.4.49 - '@csstools/postcss-font-format-keywords@3.0.2(postcss@8.4.47)': + '@csstools/postcss-font-format-keywords@3.0.2(postcss@8.4.49)': dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 postcss-value-parser: 4.2.0 - '@csstools/postcss-gamut-mapping@1.0.11(postcss@8.4.47)': + '@csstools/postcss-gamut-mapping@1.0.11(postcss@8.4.49)': dependencies: '@csstools/css-color-parser': 2.0.5(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - postcss: 8.4.47 + postcss: 8.4.49 - '@csstools/postcss-gradients-interpolation-method@4.0.20(postcss@8.4.47)': + '@csstools/postcss-gradients-interpolation-method@4.0.20(postcss@8.4.49)': dependencies: '@csstools/css-color-parser': 2.0.5(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.47) - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.49) + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 - '@csstools/postcss-hwb-function@3.0.18(postcss@8.4.47)': + '@csstools/postcss-hwb-function@3.0.18(postcss@8.4.49)': dependencies: '@csstools/css-color-parser': 2.0.5(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.47) - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.49) + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 - '@csstools/postcss-ic-unit@3.0.7(postcss@8.4.47)': + '@csstools/postcss-ic-unit@3.0.7(postcss@8.4.49)': dependencies: - '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.47) - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.49) + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 postcss-value-parser: 4.2.0 - '@csstools/postcss-initial@1.0.1(postcss@8.4.47)': + '@csstools/postcss-initial@1.0.1(postcss@8.4.49)': dependencies: - postcss: 8.4.47 + postcss: 8.4.49 - '@csstools/postcss-is-pseudo-class@4.0.8(postcss@8.4.47)': + '@csstools/postcss-is-pseudo-class@4.0.8(postcss@8.4.49)': dependencies: '@csstools/selector-specificity': 3.1.1(postcss-selector-parser@6.1.2) - postcss: 8.4.47 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - '@csstools/postcss-light-dark-function@1.0.8(postcss@8.4.47)': + '@csstools/postcss-light-dark-function@1.0.8(postcss@8.4.49)': dependencies: '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.47) - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.49) + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 - '@csstools/postcss-logical-float-and-clear@2.0.1(postcss@8.4.47)': + '@csstools/postcss-logical-float-and-clear@2.0.1(postcss@8.4.49)': dependencies: - postcss: 8.4.47 + postcss: 8.4.49 - '@csstools/postcss-logical-overflow@1.0.1(postcss@8.4.47)': + '@csstools/postcss-logical-overflow@1.0.1(postcss@8.4.49)': dependencies: - postcss: 8.4.47 + postcss: 8.4.49 - '@csstools/postcss-logical-overscroll-behavior@1.0.1(postcss@8.4.47)': + '@csstools/postcss-logical-overscroll-behavior@1.0.1(postcss@8.4.49)': dependencies: - postcss: 8.4.47 + postcss: 8.4.49 - '@csstools/postcss-logical-resize@2.0.1(postcss@8.4.47)': + '@csstools/postcss-logical-resize@2.0.1(postcss@8.4.49)': dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - '@csstools/postcss-logical-viewport-units@2.0.11(postcss@8.4.47)': + '@csstools/postcss-logical-viewport-units@2.0.11(postcss@8.4.49)': dependencies: '@csstools/css-tokenizer': 2.4.1 - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 - '@csstools/postcss-media-minmax@1.1.8(postcss@8.4.47)': + '@csstools/postcss-media-minmax@1.1.8(postcss@8.4.49)': dependencies: '@csstools/css-calc': 1.2.4(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 '@csstools/media-query-list-parser': 2.1.13(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) - postcss: 8.4.47 + postcss: 8.4.49 - '@csstools/postcss-media-queries-aspect-ratio-number-values@2.0.11(postcss@8.4.47)': + '@csstools/postcss-media-queries-aspect-ratio-number-values@2.0.11(postcss@8.4.49)': dependencies: '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 '@csstools/media-query-list-parser': 2.1.13(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) - postcss: 8.4.47 + postcss: 8.4.49 - '@csstools/postcss-nested-calc@3.0.2(postcss@8.4.47)': + '@csstools/postcss-nested-calc@3.0.2(postcss@8.4.49)': dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 postcss-value-parser: 4.2.0 - '@csstools/postcss-normalize-display-values@3.0.2(postcss@8.4.47)': + '@csstools/postcss-normalize-display-values@3.0.2(postcss@8.4.49)': dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - '@csstools/postcss-oklab-function@3.0.19(postcss@8.4.47)': + '@csstools/postcss-oklab-function@3.0.19(postcss@8.4.49)': dependencies: '@csstools/css-color-parser': 2.0.5(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.47) - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.49) + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 - '@csstools/postcss-progressive-custom-properties@3.3.0(postcss@8.4.47)': + '@csstools/postcss-progressive-custom-properties@3.3.0(postcss@8.4.49)': dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - '@csstools/postcss-relative-color-syntax@2.0.19(postcss@8.4.47)': + '@csstools/postcss-relative-color-syntax@2.0.19(postcss@8.4.49)': dependencies: '@csstools/css-color-parser': 2.0.5(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.47) - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.49) + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 - '@csstools/postcss-scope-pseudo-class@3.0.1(postcss@8.4.47)': + '@csstools/postcss-scope-pseudo-class@3.0.1(postcss@8.4.49)': dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - '@csstools/postcss-stepped-value-functions@3.0.10(postcss@8.4.47)': + '@csstools/postcss-stepped-value-functions@3.0.10(postcss@8.4.49)': dependencies: '@csstools/css-calc': 1.2.4(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - postcss: 8.4.47 + postcss: 8.4.49 - '@csstools/postcss-text-decoration-shorthand@3.0.7(postcss@8.4.47)': + '@csstools/postcss-text-decoration-shorthand@3.0.7(postcss@8.4.49)': dependencies: '@csstools/color-helpers': 4.2.1 - postcss: 8.4.47 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - '@csstools/postcss-trigonometric-functions@3.0.10(postcss@8.4.47)': + '@csstools/postcss-trigonometric-functions@3.0.10(postcss@8.4.49)': dependencies: '@csstools/css-calc': 1.2.4(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - postcss: 8.4.47 + postcss: 8.4.49 - '@csstools/postcss-unset-value@3.0.1(postcss@8.4.47)': + '@csstools/postcss-unset-value@3.0.1(postcss@8.4.49)': dependencies: - postcss: 8.4.47 + postcss: 8.4.49 '@csstools/selector-resolve-nested@1.1.0(postcss-selector-parser@6.1.2)': dependencies: @@ -4615,9 +4635,9 @@ snapshots: dependencies: postcss-selector-parser: 6.1.2 - '@csstools/utilities@1.0.0(postcss@8.4.47)': + '@csstools/utilities@1.0.0(postcss@8.4.49)': dependencies: - postcss: 8.4.47 + postcss: 8.4.49 '@ctrl/tinycolor@3.6.1': {} @@ -5016,20 +5036,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue-jsx@3.1.0(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.4.38(typescript@5.5.4))': + '@vitejs/plugin-vue-jsx@3.1.0(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))': dependencies: '@babel/core': 7.25.2 '@babel/plugin-transform-typescript': 7.25.2(@babel/core@7.25.2) '@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.25.2) vite: 4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6) - vue: 3.4.38(typescript@5.5.4) + vue: 3.5.13(typescript@5.5.4) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@4.6.2(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.4.38(typescript@5.5.4))': + '@vitejs/plugin-vue@4.6.2(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))': dependencies: vite: 4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6) - vue: 3.4.38(typescript@5.5.4) + vue: 3.5.13(typescript@5.5.4) '@volar/language-core@2.4.5': dependencies: @@ -5070,50 +5090,37 @@ snapshots: '@babel/helper-module-imports': 7.22.15 '@babel/helper-plugin-utils': 7.24.8 '@babel/parser': 7.25.6 - '@vue/compiler-sfc': 3.4.38 + '@vue/compiler-sfc': 3.5.13 - '@vue/compiler-core@3.4.38': + '@vue/compiler-core@3.5.13': dependencies: - '@babel/parser': 7.25.6 - '@vue/shared': 3.4.38 + '@babel/parser': 7.26.3 + '@vue/shared': 3.5.13 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-core@3.5.10': + '@vue/compiler-dom@3.5.13': dependencies: - '@babel/parser': 7.25.6 - '@vue/shared': 3.5.10 - entities: 4.5.0 + '@vue/compiler-core': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/compiler-sfc@3.5.13': + dependencies: + '@babel/parser': 7.26.3 + '@vue/compiler-core': 3.5.13 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 estree-walker: 2.0.2 + magic-string: 0.30.17 + postcss: 8.4.49 source-map-js: 1.2.1 - '@vue/compiler-dom@3.4.38': + '@vue/compiler-ssr@3.5.13': dependencies: - '@vue/compiler-core': 3.4.38 - '@vue/shared': 3.4.38 - - '@vue/compiler-dom@3.5.10': - dependencies: - '@vue/compiler-core': 3.5.10 - '@vue/shared': 3.5.10 - - '@vue/compiler-sfc@3.4.38': - dependencies: - '@babel/parser': 7.25.3 - '@vue/compiler-core': 3.4.38 - '@vue/compiler-dom': 3.4.38 - '@vue/compiler-ssr': 3.4.38 - '@vue/shared': 3.4.38 - estree-walker: 2.0.2 - magic-string: 0.30.11 - postcss: 8.4.41 - source-map-js: 1.2.0 - - '@vue/compiler-ssr@3.4.38': - dependencies: - '@vue/compiler-dom': 3.4.38 - '@vue/shared': 3.4.38 + '@vue/compiler-dom': 3.5.13 + '@vue/shared': 3.5.13 '@vue/compiler-vue2@2.7.16': dependencies: @@ -5123,9 +5130,9 @@ snapshots: '@vue/language-core@2.1.6(typescript@5.5.4)': dependencies: '@volar/language-core': 2.4.5 - '@vue/compiler-dom': 3.5.10 + '@vue/compiler-dom': 3.5.13 '@vue/compiler-vue2': 2.7.16 - '@vue/shared': 3.5.10 + '@vue/shared': 3.5.13 computeds: 0.0.1 minimatch: 9.0.5 muggle-string: 0.4.1 @@ -5133,47 +5140,45 @@ snapshots: optionalDependencies: typescript: 5.5.4 - '@vue/reactivity@3.4.38': + '@vue/reactivity@3.5.13': dependencies: - '@vue/shared': 3.4.38 + '@vue/shared': 3.5.13 - '@vue/runtime-core@3.4.38': + '@vue/runtime-core@3.5.13': dependencies: - '@vue/reactivity': 3.4.38 - '@vue/shared': 3.4.38 + '@vue/reactivity': 3.5.13 + '@vue/shared': 3.5.13 - '@vue/runtime-dom@3.4.38': + '@vue/runtime-dom@3.5.13': dependencies: - '@vue/reactivity': 3.4.38 - '@vue/runtime-core': 3.4.38 - '@vue/shared': 3.4.38 + '@vue/reactivity': 3.5.13 + '@vue/runtime-core': 3.5.13 + '@vue/shared': 3.5.13 csstype: 3.1.3 - '@vue/server-renderer@3.4.38(vue@3.4.38(typescript@5.5.4))': + '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.5.4))': dependencies: - '@vue/compiler-ssr': 3.4.38 - '@vue/shared': 3.4.38 - vue: 3.4.38(typescript@5.5.4) + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + vue: 3.5.13(typescript@5.5.4) - '@vue/shared@3.4.38': {} + '@vue/shared@3.5.13': {} - '@vue/shared@3.5.10': {} - - '@vueuse/core@10.11.1(vue@3.4.38(typescript@5.5.4))': + '@vueuse/core@10.11.1(vue@3.5.13(typescript@5.5.4))': dependencies: '@types/web-bluetooth': 0.0.20 '@vueuse/metadata': 10.11.1 - '@vueuse/shared': 10.11.1(vue@3.4.38(typescript@5.5.4)) - vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) + '@vueuse/shared': 10.11.1(vue@3.5.13(typescript@5.5.4)) + vue-demi: 0.14.10(vue@3.5.13(typescript@5.5.4)) transitivePeerDependencies: - '@vue/composition-api' - vue '@vueuse/metadata@10.11.1': {} - '@vueuse/shared@10.11.1(vue@3.4.38(typescript@5.5.4))': + '@vueuse/shared@10.11.1(vue@3.5.13(typescript@5.5.4))': dependencies: - vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) + vue-demi: 0.14.10(vue@3.5.13(typescript@5.5.4)) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -5209,10 +5214,10 @@ snapshots: dependencies: color-convert: 1.9.3 - ant-design-vue@3.2.20(vue@3.4.38(typescript@5.5.4)): + ant-design-vue@3.2.20(vue@3.5.13(typescript@5.5.4)): dependencies: '@ant-design/colors': 6.0.0 - '@ant-design/icons-vue': 6.1.0(vue@3.4.38(typescript@5.5.4)) + '@ant-design/icons-vue': 6.1.0(vue@3.5.13(typescript@5.5.4)) '@babel/runtime': 7.25.0 '@ctrl/tinycolor': 3.6.1 '@simonwep/pickr': 1.8.2 @@ -5226,8 +5231,8 @@ snapshots: resize-observer-polyfill: 1.5.1 scroll-into-view-if-needed: 2.2.31 shallow-equal: 1.2.1 - vue: 3.4.38(typescript@5.5.4) - vue-types: 3.0.2(vue@3.4.38(typescript@5.5.4)) + vue: 3.5.13(typescript@5.5.4) + vue-types: 3.0.2(vue@3.5.13(typescript@5.5.4)) warning: 4.0.3 anymatch@3.1.3: @@ -5254,14 +5259,14 @@ snapshots: asynckit@0.4.0: {} - autoprefixer@10.4.20(postcss@8.4.47): + autoprefixer@10.4.20(postcss@8.4.49): dependencies: browserslist: 4.23.3 caniuse-lite: 1.0.30001651 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.1 - postcss: 8.4.47 + postcss: 8.4.49 postcss-value-parser: 4.2.0 axios@1.7.4: @@ -5526,21 +5531,21 @@ snapshots: path-type: 4.0.0 yaml: 1.10.2 - css-blank-pseudo@6.0.2(postcss@8.4.47): + css-blank-pseudo@6.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - css-has-pseudo@6.0.5(postcss@8.4.47): + css-has-pseudo@6.0.5(postcss@8.4.49): dependencies: '@csstools/selector-specificity': 3.1.1(postcss-selector-parser@6.1.2) - postcss: 8.4.47 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 - css-prefers-color-scheme@9.0.1(postcss@8.4.47): + css-prefers-color-scheme@9.0.1(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 cssdb@8.1.0: {} @@ -6143,6 +6148,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + make-dir@2.1.0: dependencies: pify: 4.0.1 @@ -6409,214 +6418,214 @@ snapshots: pify@4.0.1: {} - postcss-attribute-case-insensitive@6.0.3(postcss@8.4.47): + postcss-attribute-case-insensitive@6.0.3(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - postcss-clamp@4.1.0(postcss@8.4.47): + postcss-clamp@4.1.0(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-color-functional-notation@6.0.14(postcss@8.4.47): + postcss-color-functional-notation@6.0.14(postcss@8.4.49): dependencies: '@csstools/css-color-parser': 2.0.5(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.47) - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.49) + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 - postcss-color-hex-alpha@9.0.4(postcss@8.4.47): + postcss-color-hex-alpha@9.0.4(postcss@8.4.49): dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-color-rebeccapurple@9.0.3(postcss@8.4.47): + postcss-color-rebeccapurple@9.0.3(postcss@8.4.49): dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-custom-media@10.0.8(postcss@8.4.47): + postcss-custom-media@10.0.8(postcss@8.4.49): dependencies: '@csstools/cascade-layer-name-parser': 1.0.13(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 '@csstools/media-query-list-parser': 2.1.13(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) - postcss: 8.4.47 + postcss: 8.4.49 - postcss-custom-properties@13.3.12(postcss@8.4.47): + postcss-custom-properties@13.3.12(postcss@8.4.49): dependencies: '@csstools/cascade-layer-name-parser': 1.0.13(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-custom-selectors@7.1.12(postcss@8.4.47): + postcss-custom-selectors@7.1.12(postcss@8.4.49): dependencies: '@csstools/cascade-layer-name-parser': 1.0.13(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - postcss: 8.4.47 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - postcss-dir-pseudo-class@8.0.1(postcss@8.4.47): + postcss-dir-pseudo-class@8.0.1(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - postcss-double-position-gradients@5.0.7(postcss@8.4.47): + postcss-double-position-gradients@5.0.7(postcss@8.4.49): dependencies: - '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.47) - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.49) + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-focus-visible@9.0.1(postcss@8.4.47): + postcss-focus-visible@9.0.1(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - postcss-focus-within@8.0.1(postcss@8.4.47): + postcss-focus-within@8.0.1(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - postcss-font-variant@5.0.0(postcss@8.4.47): + postcss-font-variant@5.0.0(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 - postcss-gap-properties@5.0.1(postcss@8.4.47): + postcss-gap-properties@5.0.1(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 - postcss-image-set-function@6.0.3(postcss@8.4.47): + postcss-image-set-function@6.0.3(postcss@8.4.49): dependencies: - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-lab-function@6.0.19(postcss@8.4.47): + postcss-lab-function@6.0.19(postcss@8.4.49): dependencies: '@csstools/css-color-parser': 2.0.5(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) '@csstools/css-tokenizer': 2.4.1 - '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.47) - '@csstools/utilities': 1.0.0(postcss@8.4.47) - postcss: 8.4.47 + '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.49) + '@csstools/utilities': 1.0.0(postcss@8.4.49) + postcss: 8.4.49 - postcss-logical@7.0.1(postcss@8.4.47): + postcss-logical@7.0.1(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-nesting@12.1.5(postcss@8.4.47): + postcss-nesting@12.1.5(postcss@8.4.49): dependencies: '@csstools/selector-resolve-nested': 1.1.0(postcss-selector-parser@6.1.2) '@csstools/selector-specificity': 3.1.1(postcss-selector-parser@6.1.2) - postcss: 8.4.47 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - postcss-opacity-percentage@2.0.0(postcss@8.4.47): + postcss-opacity-percentage@2.0.0(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 - postcss-overflow-shorthand@5.0.1(postcss@8.4.47): + postcss-overflow-shorthand@5.0.1(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-page-break@3.0.4(postcss@8.4.47): + postcss-page-break@3.0.4(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 - postcss-place@9.0.1(postcss@8.4.47): + postcss-place@9.0.1(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-preset-env@9.6.0(postcss@8.4.47): + postcss-preset-env@9.6.0(postcss@8.4.49): dependencies: - '@csstools/postcss-cascade-layers': 4.0.6(postcss@8.4.47) - '@csstools/postcss-color-function': 3.0.19(postcss@8.4.47) - '@csstools/postcss-color-mix-function': 2.0.19(postcss@8.4.47) - '@csstools/postcss-content-alt-text': 1.0.0(postcss@8.4.47) - '@csstools/postcss-exponential-functions': 1.0.9(postcss@8.4.47) - '@csstools/postcss-font-format-keywords': 3.0.2(postcss@8.4.47) - '@csstools/postcss-gamut-mapping': 1.0.11(postcss@8.4.47) - '@csstools/postcss-gradients-interpolation-method': 4.0.20(postcss@8.4.47) - '@csstools/postcss-hwb-function': 3.0.18(postcss@8.4.47) - '@csstools/postcss-ic-unit': 3.0.7(postcss@8.4.47) - '@csstools/postcss-initial': 1.0.1(postcss@8.4.47) - '@csstools/postcss-is-pseudo-class': 4.0.8(postcss@8.4.47) - '@csstools/postcss-light-dark-function': 1.0.8(postcss@8.4.47) - '@csstools/postcss-logical-float-and-clear': 2.0.1(postcss@8.4.47) - '@csstools/postcss-logical-overflow': 1.0.1(postcss@8.4.47) - '@csstools/postcss-logical-overscroll-behavior': 1.0.1(postcss@8.4.47) - '@csstools/postcss-logical-resize': 2.0.1(postcss@8.4.47) - '@csstools/postcss-logical-viewport-units': 2.0.11(postcss@8.4.47) - '@csstools/postcss-media-minmax': 1.1.8(postcss@8.4.47) - '@csstools/postcss-media-queries-aspect-ratio-number-values': 2.0.11(postcss@8.4.47) - '@csstools/postcss-nested-calc': 3.0.2(postcss@8.4.47) - '@csstools/postcss-normalize-display-values': 3.0.2(postcss@8.4.47) - '@csstools/postcss-oklab-function': 3.0.19(postcss@8.4.47) - '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.47) - '@csstools/postcss-relative-color-syntax': 2.0.19(postcss@8.4.47) - '@csstools/postcss-scope-pseudo-class': 3.0.1(postcss@8.4.47) - '@csstools/postcss-stepped-value-functions': 3.0.10(postcss@8.4.47) - '@csstools/postcss-text-decoration-shorthand': 3.0.7(postcss@8.4.47) - '@csstools/postcss-trigonometric-functions': 3.0.10(postcss@8.4.47) - '@csstools/postcss-unset-value': 3.0.1(postcss@8.4.47) - autoprefixer: 10.4.20(postcss@8.4.47) + '@csstools/postcss-cascade-layers': 4.0.6(postcss@8.4.49) + '@csstools/postcss-color-function': 3.0.19(postcss@8.4.49) + '@csstools/postcss-color-mix-function': 2.0.19(postcss@8.4.49) + '@csstools/postcss-content-alt-text': 1.0.0(postcss@8.4.49) + '@csstools/postcss-exponential-functions': 1.0.9(postcss@8.4.49) + '@csstools/postcss-font-format-keywords': 3.0.2(postcss@8.4.49) + '@csstools/postcss-gamut-mapping': 1.0.11(postcss@8.4.49) + '@csstools/postcss-gradients-interpolation-method': 4.0.20(postcss@8.4.49) + '@csstools/postcss-hwb-function': 3.0.18(postcss@8.4.49) + '@csstools/postcss-ic-unit': 3.0.7(postcss@8.4.49) + '@csstools/postcss-initial': 1.0.1(postcss@8.4.49) + '@csstools/postcss-is-pseudo-class': 4.0.8(postcss@8.4.49) + '@csstools/postcss-light-dark-function': 1.0.8(postcss@8.4.49) + '@csstools/postcss-logical-float-and-clear': 2.0.1(postcss@8.4.49) + '@csstools/postcss-logical-overflow': 1.0.1(postcss@8.4.49) + '@csstools/postcss-logical-overscroll-behavior': 1.0.1(postcss@8.4.49) + '@csstools/postcss-logical-resize': 2.0.1(postcss@8.4.49) + '@csstools/postcss-logical-viewport-units': 2.0.11(postcss@8.4.49) + '@csstools/postcss-media-minmax': 1.1.8(postcss@8.4.49) + '@csstools/postcss-media-queries-aspect-ratio-number-values': 2.0.11(postcss@8.4.49) + '@csstools/postcss-nested-calc': 3.0.2(postcss@8.4.49) + '@csstools/postcss-normalize-display-values': 3.0.2(postcss@8.4.49) + '@csstools/postcss-oklab-function': 3.0.19(postcss@8.4.49) + '@csstools/postcss-progressive-custom-properties': 3.3.0(postcss@8.4.49) + '@csstools/postcss-relative-color-syntax': 2.0.19(postcss@8.4.49) + '@csstools/postcss-scope-pseudo-class': 3.0.1(postcss@8.4.49) + '@csstools/postcss-stepped-value-functions': 3.0.10(postcss@8.4.49) + '@csstools/postcss-text-decoration-shorthand': 3.0.7(postcss@8.4.49) + '@csstools/postcss-trigonometric-functions': 3.0.10(postcss@8.4.49) + '@csstools/postcss-unset-value': 3.0.1(postcss@8.4.49) + autoprefixer: 10.4.20(postcss@8.4.49) browserslist: 4.23.3 - css-blank-pseudo: 6.0.2(postcss@8.4.47) - css-has-pseudo: 6.0.5(postcss@8.4.47) - css-prefers-color-scheme: 9.0.1(postcss@8.4.47) + css-blank-pseudo: 6.0.2(postcss@8.4.49) + css-has-pseudo: 6.0.5(postcss@8.4.49) + css-prefers-color-scheme: 9.0.1(postcss@8.4.49) cssdb: 8.1.0 - postcss: 8.4.47 - postcss-attribute-case-insensitive: 6.0.3(postcss@8.4.47) - postcss-clamp: 4.1.0(postcss@8.4.47) - postcss-color-functional-notation: 6.0.14(postcss@8.4.47) - postcss-color-hex-alpha: 9.0.4(postcss@8.4.47) - postcss-color-rebeccapurple: 9.0.3(postcss@8.4.47) - postcss-custom-media: 10.0.8(postcss@8.4.47) - postcss-custom-properties: 13.3.12(postcss@8.4.47) - postcss-custom-selectors: 7.1.12(postcss@8.4.47) - postcss-dir-pseudo-class: 8.0.1(postcss@8.4.47) - postcss-double-position-gradients: 5.0.7(postcss@8.4.47) - postcss-focus-visible: 9.0.1(postcss@8.4.47) - postcss-focus-within: 8.0.1(postcss@8.4.47) - postcss-font-variant: 5.0.0(postcss@8.4.47) - postcss-gap-properties: 5.0.1(postcss@8.4.47) - postcss-image-set-function: 6.0.3(postcss@8.4.47) - postcss-lab-function: 6.0.19(postcss@8.4.47) - postcss-logical: 7.0.1(postcss@8.4.47) - postcss-nesting: 12.1.5(postcss@8.4.47) - postcss-opacity-percentage: 2.0.0(postcss@8.4.47) - postcss-overflow-shorthand: 5.0.1(postcss@8.4.47) - postcss-page-break: 3.0.4(postcss@8.4.47) - postcss-place: 9.0.1(postcss@8.4.47) - postcss-pseudo-class-any-link: 9.0.2(postcss@8.4.47) - postcss-replace-overflow-wrap: 4.0.0(postcss@8.4.47) - postcss-selector-not: 7.0.2(postcss@8.4.47) + postcss: 8.4.49 + postcss-attribute-case-insensitive: 6.0.3(postcss@8.4.49) + postcss-clamp: 4.1.0(postcss@8.4.49) + postcss-color-functional-notation: 6.0.14(postcss@8.4.49) + postcss-color-hex-alpha: 9.0.4(postcss@8.4.49) + postcss-color-rebeccapurple: 9.0.3(postcss@8.4.49) + postcss-custom-media: 10.0.8(postcss@8.4.49) + postcss-custom-properties: 13.3.12(postcss@8.4.49) + postcss-custom-selectors: 7.1.12(postcss@8.4.49) + postcss-dir-pseudo-class: 8.0.1(postcss@8.4.49) + postcss-double-position-gradients: 5.0.7(postcss@8.4.49) + postcss-focus-visible: 9.0.1(postcss@8.4.49) + postcss-focus-within: 8.0.1(postcss@8.4.49) + postcss-font-variant: 5.0.0(postcss@8.4.49) + postcss-gap-properties: 5.0.1(postcss@8.4.49) + postcss-image-set-function: 6.0.3(postcss@8.4.49) + postcss-lab-function: 6.0.19(postcss@8.4.49) + postcss-logical: 7.0.1(postcss@8.4.49) + postcss-nesting: 12.1.5(postcss@8.4.49) + postcss-opacity-percentage: 2.0.0(postcss@8.4.49) + postcss-overflow-shorthand: 5.0.1(postcss@8.4.49) + postcss-page-break: 3.0.4(postcss@8.4.49) + postcss-place: 9.0.1(postcss@8.4.49) + postcss-pseudo-class-any-link: 9.0.2(postcss@8.4.49) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.4.49) + postcss-selector-not: 7.0.2(postcss@8.4.49) - postcss-pseudo-class-any-link@9.0.2(postcss@8.4.47): + postcss-pseudo-class-any-link@9.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - postcss-replace-overflow-wrap@4.0.0(postcss@8.4.47): + postcss-replace-overflow-wrap@4.0.0(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 - postcss-selector-not@7.0.2(postcss@8.4.47): + postcss-selector-not@7.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.47 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 postcss-selector-parser@6.1.2: @@ -6632,7 +6641,7 @@ snapshots: picocolors: 1.0.1 source-map-js: 1.2.1 - postcss@8.4.47: + postcss@8.4.49: dependencies: nanoid: 3.3.8 picocolors: 1.1.1 @@ -6851,8 +6860,6 @@ snapshots: ip-address: 9.0.5 smart-buffer: 4.2.0 - source-map-js@1.2.0: {} - source-map-js@1.2.1: {} source-map-support@0.5.21: @@ -7045,7 +7052,7 @@ snapshots: universalify@2.0.1: {} - unplugin-vue-components@0.22.12(@babel/parser@7.25.6)(rollup@3.29.4)(vue@3.4.38(typescript@5.5.4)): + unplugin-vue-components@0.22.12(@babel/parser@7.26.3)(rollup@3.29.4)(vue@3.5.13(typescript@5.5.4)): dependencies: '@antfu/utils': 0.7.10 '@rollup/pluginutils': 5.1.0(rollup@3.29.4) @@ -7057,9 +7064,9 @@ snapshots: minimatch: 5.1.6 resolve: 1.22.8 unplugin: 1.12.2 - vue: 3.4.38(typescript@5.5.4) + vue: 3.5.13(typescript@5.5.4) optionalDependencies: - '@babel/parser': 7.25.6 + '@babel/parser': 7.26.3 transitivePeerDependencies: - rollup - supports-color @@ -7146,9 +7153,9 @@ snapshots: vscode-uri@3.0.8: {} - vue-demi@0.14.10(vue@3.4.38(typescript@5.5.4)): + vue-demi@0.14.10(vue@3.5.13(typescript@5.5.4)): dependencies: - vue: 3.4.38(typescript@5.5.4) + vue: 3.5.13(typescript@5.5.4) vue-tsc@2.1.6(typescript@5.5.4): dependencies: @@ -7157,18 +7164,18 @@ snapshots: semver: 7.6.3 typescript: 5.5.4 - vue-types@3.0.2(vue@3.4.38(typescript@5.5.4)): + vue-types@3.0.2(vue@3.5.13(typescript@5.5.4)): dependencies: is-plain-object: 3.0.1 - vue: 3.4.38(typescript@5.5.4) + vue: 3.5.13(typescript@5.5.4) - vue@3.4.38(typescript@5.5.4): + vue@3.5.13(typescript@5.5.4): dependencies: - '@vue/compiler-dom': 3.4.38 - '@vue/compiler-sfc': 3.4.38 - '@vue/runtime-dom': 3.4.38 - '@vue/server-renderer': 3.4.38(vue@3.4.38(typescript@5.5.4)) - '@vue/shared': 3.4.38 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-sfc': 3.5.13 + '@vue/runtime-dom': 3.5.13 + '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.5.4)) + '@vue/shared': 3.5.13 optionalDependencies: typescript: 5.5.4 diff --git a/src/core/render/components/textbox.tsx b/src/core/render/components/textbox.tsx index 9ffdafd..dfc421a 100644 --- a/src/core/render/components/textbox.tsx +++ b/src/core/render/components/textbox.tsx @@ -1,7 +1,21 @@ import { MotaOffscreenCanvas2D } from '@/core/fx/canvas2d'; -import { defineComponent, onUpdated, shallowRef, watch } from 'vue'; +import { + defineComponent, + onMounted, + onUpdated, + ref, + shallowRef, + SlotsType, + VNode, + watch +} from 'vue'; import { Transform } from '../transform'; import { isSetEqual } from '../utils'; +import { logger } from '@/core/common/logger'; +import { Sprite } from '../sprite'; +import { onTick } from '../renderer'; +import { isNil } from 'lodash-es'; +import { SetupComponentOptions } from './types'; export const enum WordBreak { /** 不换行 */ @@ -18,12 +32,22 @@ export const enum TextAlign { End } +let testCanvas: MotaOffscreenCanvas2D; +Mota.require('var', 'loading').once('coreInit', () => { + testCanvas = new MotaOffscreenCanvas2D(false); + testCanvas.withGameScale(false); + testCanvas.setHD(false); + testCanvas.size(32, 32); + testCanvas.freeze(); +}); + export interface TextContentProps { text: string; x?: number; y?: number; width?: number; height?: number; + /** 字体 */ font?: string; /** 是否持续上一次的文本,开启后,如果修改后的文本以修改前的文本为开头,那么会继续播放而不会从头播放 */ keepLast?: boolean; @@ -40,9 +64,24 @@ export interface TextContentProps { /** 行尾忽略字符,即不会出现在行尾的字符 */ ignoreLineEnd?: Iterable; /** 会被分词规则识别的分词字符 */ - breakChars: Iterable; + breakChars?: Iterable; + /** 填充样式 */ + fillStyle?: CanvasStyle; + /** 描边样式 */ + strokeStyle?: CanvasStyle; + /** 线宽 */ + strokeWidth?: number; + /** 是否填充 */ + fill?: boolean; + /** 是否描边 */ + stroke?: boolean; } +export type TextContentEmits = { + typeEnd: () => void; + typeStart: () => void; +}; + interface TextContentData { text: string; width: number; @@ -57,132 +96,395 @@ interface TextContentData { breakChars: Set; } -class TextContentCachePool { - private pool: MotaOffscreenCanvas2D[] = []; - - /** - * 申请画布 - * @param num 要申请多少画布 - */ - requestCanvas(num: number): MotaOffscreenCanvas2D[] { - if (this.pool.length < num) { - const diff = num - this.pool.length; - for (let i = 0; i < diff; i++) { - this.pool.push(new MotaOffscreenCanvas2D(false)); - } - } - return this.pool.splice(0, num); - } - - /** - * 退回画布 - * @param canvas 要退回多少画布 - */ - returnCanvas(canvas: MotaOffscreenCanvas2D[]) { - this.pool.push(...canvas); - } +interface TextContentRenderable { + x: number; + y: number; + /** 行高,为0时表示两行间为默认行距 */ + height: number; + /** 这一行文字的高度,即 measureText 算出的高度 */ + textHeight: number; + /** 这一行的文字 */ + text: string; + /** 当前渲染到了本行的哪个文字 */ + pointer: number; + /** 本行文字在全部文字中的起点 */ + from: number; + /** 本行文字在全部文字中的终点 */ + to: number; } -const pool = new TextContentCachePool(); +const textContentOptions = { + props: [ + 'breakChars', + 'font', + 'height', + 'ignoreLineEnd', + 'ignoreLineStart', + 'interval', + 'keepLast', + 'lineHeight', + 'text', + 'textAlign', + 'width', + 'wordBreak', + 'x', + 'y' + ], + emits: ['typeEnd'] +} satisfies SetupComponentOptions; -export const TextContent = defineComponent((props, ctx) => { - const ensureProps = () => { - props.x ??= 0; - props.y ??= 0; - props.width ??= 200; - props.height ??= 200; - props.font ??= core.status.globalAttribute.font; - props.ignoreLineEnd ??= new Set(); - props.ignoreLineStart ??= new Set(); - props.keepLast ??= false; - props.interval ??= 0; - props.lineHeight ??= 0; - props.wordBreak ??= WordBreak.Space; - props.breakChars ??= new Set(); - }; - - const makeSplitData = (): TextContentData => { - ensureProps(); - return { +export const TextContent = defineComponent( + (props, { emit }) => { + if (props.width && props.width <= 0) { + logger.warn(41, String(props.width)); + } + const renderData: Required = { text: props.text, - width: props.width!, - font: props.font!, - wordBreak: props.wordBreak!, - ignoreLineStart: new Set(props.ignoreLineStart), - ignoreLineEnd: new Set(props.ignoreLineEnd), - breakChars: new Set(props.breakChars) + textAlign: props.textAlign ?? TextAlign.Left, + x: props.x ?? 0, + y: props.y ?? 0, + width: !props.width || props.width <= 0 ? 200 : props.width, + height: props.height ?? 200, + font: + props.font ?? + core.status.globalAttribute?.font ?? + '16px Verdana', + ignoreLineEnd: props.ignoreLineEnd ?? new Set(), + ignoreLineStart: props.ignoreLineStart ?? new Set(), + keepLast: props.keepLast ?? false, + interval: props.interval ?? 0, + lineHeight: props.lineHeight ?? 0, + wordBreak: props.wordBreak ?? WordBreak.Space, + breakChars: props.breakChars ?? new Set(), + fillStyle: props.fillStyle ?? '#fff', + strokeStyle: props.strokeStyle ?? 'transparent', + fill: props.fill ?? true, + stroke: props.stroke ?? false, + strokeWidth: props.strokeWidth ?? 2 }; - }; - /** - * 判断是否需要重新分行 - */ - const needResplit = (value: TextContentData, old: TextContentData) => { - return ( - value.text !== old.text || - value.font !== old.font || - value.width !== old.width || - value.wordBreak !== old.wordBreak || - !isSetEqual(value.breakChars, old.breakChars) || - !isSetEqual(value.ignoreLineEnd, old.ignoreLineEnd) || - !isSetEqual(value.ignoreLineStart, old.ignoreLineStart) - ); - }; - - const render = (canvas: MotaOffscreenCanvas2D, transform: Transform) => {}; - - const data = shallowRef(makeSplitData()); - - onUpdated(() => { - data.value = makeSplitData(); - }); - - let shouldKeep = false; - const lineData = shallowRef([0]); - watch(data, (value, old) => { - if (needResplit(value, old)) { - lineData.value = splitLines(value); - } - - if (props.keepLast && value.text.startsWith(old.text)) { - shouldKeep = true; - } - }); - - watch(lineData, (value, old) => { - if (shouldKeep) { - shouldKeep = false; - const isSub = value.every((v, i) => v === old[i]); - if (isSub) { + const ensureProps = () => { + for (const [key, value] of Object.entries(props)) { + if (key in renderData && !isNil(value)) { + if (key === 'width') { + if (value && value <= 0) { + logger.warn(41); + renderData.width = 200; + } else { + renderData.width = value; + } + } else { + // @ts-ignore + renderData[key] = value; + } + } } - } - }); + }; - return () => { - return ( - - ); - }; -}); + const makeSplitData = (): TextContentData => { + ensureProps(); + return { + text: renderData.text, + width: renderData.width!, + font: renderData.font!, + wordBreak: renderData.wordBreak!, + ignoreLineStart: new Set(renderData.ignoreLineStart), + ignoreLineEnd: new Set(renderData.ignoreLineEnd), + breakChars: new Set(renderData.breakChars) + }; + }; -export const Textbox = defineComponent((props, ctx) => { - return () => {}; -}); + /** + * 判断是否需要重新分行 + */ + const needResplit = (value: TextContentData, old: TextContentData) => { + return ( + value.text !== old.text || + value.font !== old.font || + value.width !== old.width || + value.wordBreak !== old.wordBreak || + !isSetEqual(value.breakChars, old.breakChars) || + !isSetEqual(value.ignoreLineEnd, old.ignoreLineEnd) || + !isSetEqual(value.ignoreLineStart, old.ignoreLineStart) + ); + }; -let testCanvas: MotaOffscreenCanvas2D; -Mota.require('var', 'loading').once('coreInit', () => { - testCanvas = new MotaOffscreenCanvas2D(false); - testCanvas.withGameScale(false); - testCanvas.setHD(false); - testCanvas.size(32, 32); - testCanvas.freeze(); -}); + /** 每行的渲染信息 */ + const renderable: TextContentRenderable[] = []; + /** 需要更新的行数 */ + const dirtyIndex: number[] = []; + const spriteElement = ref(); + + /** dirtyIndex 更新指针 */ + let linePointer = 0; + let startTime = 0; + /** 从哪个字符开始渲染 */ + let fromChar = 0; + /** 是否需要更新渲染 */ + let needUpdate = false; + const tick = () => { + if (!needUpdate) return; + spriteElement.value?.update(); + const time = Date.now(); + const char = + Math.floor((time - startTime) / renderData.interval!) + + fromChar; + if (!isFinite(char)) { + renderable.forEach(v => (v.pointer = v.text.length)); + needUpdate = false; + return; + } + while (linePointer < dirtyIndex.length) { + const line = dirtyIndex[linePointer]; + const data = renderable[line]; + const pointer = char - data.from; + if (pointer >= data.to) { + data.pointer = data.text.length; + linePointer++; + } else { + data.pointer = pointer; + } + } + if (linePointer >= dirtyIndex.length) { + needUpdate = false; + renderable.forEach(v => (v.pointer = v.text.length)); + emit('typeEnd'); + } + }; + + onTick(tick); + onMounted(() => { + data.value = makeSplitData(); + }); + + const renderContent = ( + canvas: MotaOffscreenCanvas2D, + transform: Transform + ) => { + const ctx = canvas.ctx; + ctx.font = renderData.font; + ctx.fillStyle = renderData.fillStyle; + ctx.strokeStyle = renderData.strokeStyle; + ctx.lineWidth = renderData.strokeWidth; + + renderable.forEach(v => { + if (v.pointer === 0) return; + const text = v.text.slice(0, v.pointer); + if (renderData.stroke) ctx.strokeText(text, v.x, v.y); + if (renderData.fill) ctx.fillText(text, v.x, v.y); + }); + }; + + /** + * 生成 renderable 对象 + * @param text 全部文本 + * @param lines 分行信息 + * @param index 从第几行开始生成 + * @param from 从第几个字符开始生成 + */ + const makeRenderable = ( + text: string, + lines: number[], + index: number, + from: number + ) => { + renderable.splice(index); + dirtyIndex.splice(0); + dirtyIndex.push(index); + // 初始化渲染 + linePointer = 0; + startTime = Date.now(); + fromChar = from; + needUpdate = true; + + let startY = renderable.reduce( + (prev, curr) => prev + curr.textHeight + curr.height, + 0 + ); + // 第一个比较特殊,需要特判 + const start = lines[index - 1] ?? 0; + const end = lines[index]; + const startPointer = from > start && from < end ? from - start : 0; + const height = testHeight(text, renderData.font!); + startY += height; + renderable.push({ + text: text.slice(start, end), + x: 0, + y: startY, + height: renderData.lineHeight!, + textHeight: height, + pointer: startPointer, + from: start, + to: end + }); + + for (let i = index + 1; i < lines.length; i++) { + dirtyIndex.push(i); + const start = lines[i - 1] ?? 0; + const end = lines[i]; + const height = testHeight(text, renderData.font!); + startY += height; + + renderable.push({ + text: text.slice(start, end), + x: 0, + y: startY, + height: renderData.lineHeight!, + textHeight: height, + pointer: 0, + from: start, + to: end + }); + } + emit('typeStart'); + }; + + /** + * 从头开始渲染 + */ + const rawRender = (text: string, lines: number[]) => { + makeRenderable(text, lines, 0, 0); + spriteElement.value?.update(); + }; + + /** + * 接续上一个继续渲染 + * @param from 从第几个字符接续渲染 + * @param lines 分行信息 + * @param index 从第几行接续渲染 + */ + const continueRender = ( + text: string, + from: number, + lines: number[], + index: number + ) => { + makeRenderable(text, lines, index, from); + spriteElement.value?.update(); + }; + + const data = shallowRef(makeSplitData()); + + onUpdated(() => { + data.value = makeSplitData(); + }); + + let shouldKeep = false; + const lineData = shallowRef([0]); + watch(data, (value, old) => { + if (needResplit(value, old)) { + lineData.value = splitLines(value); + } + + if (renderData.keepLast && value.text.startsWith(old.text)) { + shouldKeep = true; + } + }); + + // 判断是否需要接续渲染 + watch(lineData, (value, old) => { + if (shouldKeep) { + shouldKeep = false; + const isSub = old.slice(0, -1).every((v, i) => v === value[i]); + + // 有点地狱的条件分歧,大体就是分为两种情况,一种是两个末尾一致,如果一致那直接从下一行接着画就完事了 + // 但是如果不一致,那么从旧的最后一个开始往后画 + if (isSub) { + const last = value[old.length - 1]; + const oldLast = value.at(-1); + if (!last) { + rawRender(data.value.text, value); + return; + } + if (last === oldLast) { + const index = old.length - 1; + continueRender(data.value.text, last, value, index); + } else { + if (!oldLast) { + rawRender(data.value.text, value); + } else { + const index = old.length - 1; + continueRender( + data.value.text, + oldLast, + value, + index + ); + } + } + } else { + rawRender(data.value.text, value); + } + } else { + rawRender(data.value.text, value); + } + }); + lineData.value = splitLines(data.value); + + return () => { + return ( + + ); + }; + }, + textContentOptions +); + +export interface TextboxProps extends TextContentProps { + /** 背景颜色 */ + backColor?: CanvasStyle; + /** 背景 winskin */ + winskin?: string; +} + +interface TextboxSlots extends SlotsType { + default: () => VNode; +} + +const textboxOptions = { + props: (textContentOptions.props as (keyof TextboxProps)[]).concat([ + 'backColor', + 'winskin' + ]) +} satisfies SetupComponentOptions; + +export const Textbox = defineComponent( + (props, { slots }) => { + return () => { + return ( + + {slots.default ? ( + slots.default() + ) : props.winskin ? ( + // todo + + ) : ( + // todo + + )} + + + ); + }; + }, + textboxOptions +); const fontSizeGuessScale = new Map([ ['px', 1], @@ -207,7 +509,8 @@ const fontSizeGuessScale = new Map([ */ function splitLines(data: TextContentData) { const words = breakWords(data); - if (words.length === 1) return [words[0]]; + if (words.length === 0) return []; + else if (words.length === 1) return [words[0]]; // 对文字二分,然后计算长度 const text = data.text; @@ -215,9 +518,9 @@ function splitLines(data: TextContentData) { const fontSize = data.font.match(/\s*[\d\.-]+[a-zA-Z%]*\s*/)?.[0].trim(); const unit = fontSize?.match(/[a-zA-Z%]+/)?.[0]; const guessScale = fontSizeGuessScale.get(unit ?? '') ?? 0.2; - const guessSize = parseInt(fontSize ?? '0') * guessScale; + const guessSize = parseInt(fontSize ?? '1') * guessScale; const averageLength = text.length / words.length; - const guess = data.width / guessSize / averageLength; + const guess = Math.max(data.width / guessSize / averageLength, 1); const ctx = testCanvas.ctx; ctx.font = data.font; @@ -228,7 +531,6 @@ function splitLines(data: TextContentData) { let guessCount = 1; let splitProgress = false; - console.time(); while (1) { if (!splitProgress) { const chars = text.slice(words[start], words[end]); @@ -246,9 +548,10 @@ function splitLines(data: TextContentData) { if (diff === 1) { res.push(words[start]); - if (end === words.length) break; + if (end >= words.length) break; resolved = start; end = Math.ceil(start + guess); + if (end > words.length) end = words.length; guessCount = 1; splitProgress = false; } else { @@ -264,7 +567,6 @@ function splitLines(data: TextContentData) { } } } - console.timeEnd(); return res; } @@ -302,6 +604,7 @@ function isCJK(char: number) { * @returns 一个数字数组,每一项应当在这一项索引之后分词 */ function breakWords(data: TextContentData) { + if (data.text.length <= 1) return [data.text.length]; let allBreak = false; const breakChars = breakSet.union(data.breakChars); switch (data.wordBreak) { @@ -332,7 +635,7 @@ function breakWords(data: TextContentData) { } if (ignoreLineStart.has(char) && !ignoreLineStart.has(next)) { - res.push(pointer); + res.push(pointer + 1); continue; } @@ -342,10 +645,16 @@ function breakWords(data: TextContentData) { char === '\n' || isCJK(char.charCodeAt(0)) ) { - res.push(pointer); + res.push(pointer + 1); continue; } } res.push(text.length); return res; } + +function testHeight(text: string, font: string) { + const ctx = testCanvas.ctx; + ctx.font = font; + return ctx.measureText(text).fontBoundingBoxAscent; +} diff --git a/src/core/render/components/types.ts b/src/core/render/components/types.ts new file mode 100644 index 0000000..ed4a50c --- /dev/null +++ b/src/core/render/components/types.ts @@ -0,0 +1,12 @@ +import { ComponentOptions, EmitsOptions, SlotsType } from 'vue'; + +export type SetupComponentOptions< + Props extends Record, + E extends EmitsOptions = {}, + EE extends string = string, + S extends SlotsType = {} +> = Pick & { + props?: (keyof Props)[]; + emits?: E | EE[]; + slots?: S; +}; diff --git a/src/core/render/index.tsx b/src/core/render/index.tsx index 052a9de..6172a18 100644 --- a/src/core/render/index.tsx +++ b/src/core/render/index.tsx @@ -11,8 +11,8 @@ import { LayerGroupHalo } from '@/plugin/fx/halo'; import { FloorViewport } from './preset/viewport'; import { PopText } from '@/plugin/fx/pop'; import { FloorChange } from '@/plugin/fallback'; -import { render } from './renderer'; -import { defineComponent, ref } from 'vue'; +import { createApp } from './renderer'; +import { defineComponent } from 'vue'; let main: MotaRenderer; @@ -61,7 +61,8 @@ Mota.require('var', 'loading').once('coreInit', () => { }); main.hide(); - render(, main); + createApp(Com).mount(main); + // render(, main); console.log(main); }); diff --git a/src/core/render/pool.ts b/src/core/render/pool.ts new file mode 100644 index 0000000..b4b2f56 --- /dev/null +++ b/src/core/render/pool.ts @@ -0,0 +1,44 @@ +import { logger } from '../common/logger'; +import { MotaOffscreenCanvas2D } from '../fx/canvas2d'; + +export class CanvasPool { + private pool: MotaOffscreenCanvas2D[] = []; + private requested: Set = new Set(); + + /** + * 申请画布 + * @param num 要申请多少画布 + */ + requestCanvas(num: number): MotaOffscreenCanvas2D[] { + if (this.pool.length < num) { + const diff = num - this.pool.length; + for (let i = 0; i < diff; i++) { + this.pool.push(new MotaOffscreenCanvas2D(false)); + } + } + const toProvide = this.pool.splice(0, num); + toProvide.forEach(v => this.requested.add(v)); + return toProvide; + } + + /** + * 退回画布 + * @param canvas 要退回多少画布 + */ + returnCanvas(canvas: MotaOffscreenCanvas2D[]) { + canvas.forEach(v => { + if (!this.requested.has(v)) { + logger.warn(40); + return; + } + this.requested.delete(v); + this.pool.push(v); + v.clear(); + }); + } + + destroy() { + this.pool.forEach(v => v.delete()); + this.requested.forEach(v => v.delete()); + } +} diff --git a/src/core/render/renderer/map.ts b/src/core/render/renderer/map.ts index e6a5446..b3b76b2 100644 --- a/src/core/render/renderer/map.ts +++ b/src/core/render/renderer/map.ts @@ -92,6 +92,7 @@ const standardElementNoCache = ( // Default elements tagMap.register('container', standardElement(Container)); +tagMap.register('template', standardElement(Container)); tagMap.register('mota-renderer', (_0, _1, props) => { return new MotaRenderer(props?.id); }); diff --git a/src/core/render/renderer/props.ts b/src/core/render/renderer/props.ts index 7f0e974..d190a04 100644 --- a/src/core/render/renderer/props.ts +++ b/src/core/render/renderer/props.ts @@ -6,6 +6,7 @@ import { ILayerRenderExtends } from '../preset/layer'; import type { EnemyCollection } from '@/game/enemy/damage'; +import { ILineProperty } from '../preset/graphics'; export interface CustomProps { _item: (props: BaseProps) => RenderItem; @@ -90,19 +91,28 @@ export interface DamageProps extends BaseProps { strokeWidth?: number; } -export interface RectProps extends BaseProps {} +interface GraphicPropsBase extends BaseProps, Partial { + fill?: boolean; + stroke?: boolean; + strokeAndFill?: boolean; + fillRule?: CanvasFillRule; + fillStyle?: CanvasStyle; + strokeStyle?: CanvasStyle; +} -export interface CirclesProps extends BaseProps {} +export interface RectProps extends GraphicPropsBase {} -export interface EllipseProps extends BaseProps {} +export interface CirclesProps extends GraphicPropsBase {} -export interface LineProps extends BaseProps {} +export interface EllipseProps extends GraphicPropsBase {} -export interface BezierProps extends BaseProps {} +export interface LineProps extends GraphicPropsBase {} -export interface QuadraticProps extends BaseProps {} +export interface BezierProps extends GraphicPropsBase {} -export interface PathProps extends BaseProps {} +export interface QuadraticProps extends GraphicPropsBase {} + +export interface PathProps extends GraphicPropsBase {} export interface IconProps extends BaseProps {} diff --git a/src/core/render/sprite.ts b/src/core/render/sprite.ts index 8424eb5..d1f483b 100644 --- a/src/core/render/sprite.ts +++ b/src/core/render/sprite.ts @@ -52,7 +52,7 @@ export class Sprite< ): void { switch (key) { case 'render': - if (this.assertType(nextValue, 'function', key)) return; + if (!this.assertType(nextValue, 'function', key)) return; this.setRenderFn(nextValue); break; } diff --git a/src/core/render/utils.ts b/src/core/render/utils.ts index 58ae347..e41d54b 100644 --- a/src/core/render/utils.ts +++ b/src/core/render/utils.ts @@ -32,5 +32,6 @@ export function multiplyTiming(timing1: TimingFn, timing2: TimingFn): TimingFn { * 判断两个集合是否相等 */ export function isSetEqual(set1: Set, set2: Set) { - return set1.size === set2.size && set1.isSubsetOf(set2); + if (set1 === set2) return true; + else return set1.size === set2.size && set1.isSubsetOf(set2); } diff --git a/src/data/logger.json b/src/data/logger.json index 4348357..dcfaaf6 100644 --- a/src/data/logger.json +++ b/src/data/logger.json @@ -67,6 +67,8 @@ "37": "Cannot execute 'requestSort' on plain render item, please ensure you have overrided 'requestSort' method in your own element.", "38": "Using plain text in jsx is strongly not recommended, since you can hardly modify its attributes. Consider using Text element instead.", "39": "Plain text is not supported outside Text element.", + "40": "Cannot return canvas that is not provided by this pool.", + "41": "Width of text content components must be positive. receive: $1", "1001": "Item-detail extension needs 'floor-binder' and 'floor-damage' extension as dependency.", "1101": "Cannot add new effect to point effect instance, for there's no more reserve space for it. Please increase the max count of the instance." }