@seayoo-web/pixi-live2d 0.1.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
## 特性
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
7
|
+
- **零框架依赖**:纯 TypeScript 实现,可用于任何框架(React、Vue、Vanilla JS)。
|
|
8
|
+
- **多实例**:每个 `Live2DViewer` 持有独立的 PIXI 应用与 WebGL context,可在页面多处同时渲染、互不干扰。
|
|
9
|
+
- **响应式缩放**:按 canvas 容器尺寸适配设计稿(默认 1920×1080),并可选监听窗口 resize 自动调整。
|
|
10
|
+
- **交互支持**:内置点击播放动作、指针跟随等交互。
|
|
11
11
|
|
|
12
12
|
## 安装
|
|
13
13
|
|
|
@@ -15,92 +15,106 @@
|
|
|
15
15
|
pnpm add @seayoo-web/pixi-live2d
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
##
|
|
18
|
+
## 使用
|
|
19
19
|
|
|
20
20
|
### 基础用法
|
|
21
21
|
|
|
22
22
|
```typescript
|
|
23
23
|
import { Live2DViewer } from "@seayoo-web/pixi-live2d";
|
|
24
24
|
|
|
25
|
-
// 方式 1
|
|
26
|
-
const
|
|
25
|
+
// 方式 1:传入 canvas 元素的 id
|
|
26
|
+
const viewer = new Live2DViewer("live2d-canvas", {
|
|
27
27
|
modelPath: "https://cdn.example.com/live2d/model.json",
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
// 方式 2
|
|
31
|
-
const
|
|
32
|
-
const viewer2 = new Live2DViewer(
|
|
30
|
+
// 方式 2:传入 HTMLCanvasElement 并配置初始参数
|
|
31
|
+
const canvas = document.getElementById("my-canvas") as HTMLCanvasElement;
|
|
32
|
+
const viewer2 = new Live2DViewer(canvas, {
|
|
33
33
|
modelPath: "https://cdn.example.com/live2d/model.json",
|
|
34
|
-
|
|
35
|
-
// 初始位置和缩放
|
|
36
34
|
x: 0,
|
|
37
35
|
y: 0,
|
|
38
36
|
scale: 0.2, // 模型缩放比例
|
|
39
|
-
|
|
40
|
-
// 设计稿尺寸 (用于自动计算适配比例)
|
|
41
|
-
designWidth: 1920,
|
|
37
|
+
designWidth: 1920, // 设计稿尺寸(用于自动计算适配比例)
|
|
42
38
|
designHeight: 1080,
|
|
43
|
-
|
|
44
39
|
autoResize: true,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
console.log("模型加载成功:", model);
|
|
48
|
-
},
|
|
49
|
-
onModelError: (error) => {
|
|
50
|
-
console.error("模型加载失败:", error);
|
|
51
|
-
},
|
|
40
|
+
onModelLoaded: (model) => console.log("模型加载成功:", model),
|
|
41
|
+
onModelError: (error) => console.error("模型加载失败:", error),
|
|
52
42
|
});
|
|
53
43
|
```
|
|
54
44
|
|
|
55
|
-
###
|
|
45
|
+
### 多实例
|
|
56
46
|
|
|
57
|
-
|
|
47
|
+
每个实例使用各自的 canvas,可同时存在于页面不同位置、互不干扰:
|
|
58
48
|
|
|
59
|
-
|
|
60
|
-
|
|
49
|
+
```typescript
|
|
50
|
+
const left = new Live2DViewer("canvas-left", { modelPath: "/a/model.json", scale: 0.2 });
|
|
51
|
+
const right = new Live2DViewer("canvas-right", { modelPath: "/b/model.json", scale: 0.2 });
|
|
61
52
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
| `scale` | `number` | - | 初始缩放比例 |
|
|
67
|
-
| `x` | `number` | 0 | 初始 X 轴偏移 |
|
|
68
|
-
| `y` | `number` | 0 | 初始 Y 轴偏移 |
|
|
69
|
-
| `designWidth` | `number` | 1920 | 设计稿宽度(用于适配计算) |
|
|
70
|
-
| `designHeight` | `number` | 1080 | 设计稿高度(用于适配计算) |
|
|
71
|
-
| `autoResize` | `boolean` | `true` | 是否监听窗口 resize 事件并自动调整模型大小 |
|
|
72
|
-
| `onModelLoaded` | `(model) => void` | - | 模型加载完成后的回调函数 |
|
|
73
|
-
| `onModelError` | `(error) => void` | - | 模型加载失败的回调函数 |
|
|
74
|
-
|
|
75
|
-
#### 实例方法
|
|
76
|
-
|
|
77
|
-
- **`startMotion(group: string, no: number)`**
|
|
78
|
-
播放指定分组的动作。
|
|
53
|
+
// 卸载时分别销毁,各自释放 WebGL context
|
|
54
|
+
left.destroy();
|
|
55
|
+
right.destroy();
|
|
56
|
+
```
|
|
79
57
|
|
|
80
|
-
|
|
81
|
-
viewer.startMotion("TapBody", 0);
|
|
82
|
-
```
|
|
58
|
+
> 浏览器对同页 WebGL context 数量有上限(通常约 16 个),请按需创建并在不用时调用 `destroy()`。
|
|
83
59
|
|
|
84
|
-
|
|
85
|
-
设置模型的缩放比例(基于自动计算的基础比例)。
|
|
60
|
+
### 自定义 Cubism Core 地址
|
|
86
61
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
62
|
+
库默认从内置 CDN 加载 Live2D Cubism Core。可通过 `cubismCoreUrl` 覆盖,或在创建实例前手动预加载:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
// 预加载(可选),多次调用会自动去重
|
|
66
|
+
await Live2DViewer.loadCubismCore("https://your-cdn.com/live2dcubismcore.js");
|
|
67
|
+
|
|
68
|
+
const viewer = new Live2DViewer("canvas", {
|
|
69
|
+
modelPath: "/model.json",
|
|
70
|
+
cubismCoreUrl: "https://your-cdn.com/live2dcubismcore.js",
|
|
71
|
+
});
|
|
72
|
+
```
|
|
90
73
|
|
|
91
|
-
|
|
92
|
-
手动触发一次重新计算布局(通常在容器大小变化但窗口大小未变时使用)。
|
|
74
|
+
## API
|
|
93
75
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
76
|
+
### `new Live2DViewer(canvas, options)`
|
|
77
|
+
|
|
78
|
+
- `canvas`: `HTMLCanvasElement | string` —— 用于渲染的 canvas 元素或其 id
|
|
79
|
+
- `options`: `Live2DViewerOptions` —— 配置项
|
|
80
|
+
|
|
81
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
82
|
+
| --- | --- | --- | --- |
|
|
83
|
+
| `modelPath` | `string` | (必填) | Live2D 模型配置文件 (.json) 的路径 |
|
|
84
|
+
| `scale` | `number` | `1` | 模型初始缩放比例 |
|
|
85
|
+
| `x` | `number` | `0` | 初始 X 轴偏移 |
|
|
86
|
+
| `y` | `number` | `0` | 初始 Y 轴偏移 |
|
|
87
|
+
| `designWidth` | `number` | `1920` | 设计稿宽度(用于适配计算) |
|
|
88
|
+
| `designHeight` | `number` | `1080` | 设计稿高度(用于适配计算) |
|
|
89
|
+
| `autoResize` | `boolean` | `true` | 是否监听窗口 resize 自动调整模型大小 |
|
|
90
|
+
| `interactive` | `boolean` | `true` | 是否响应指针移动进行跟随;设为 `false` 会同时禁用模型自然晃动 |
|
|
91
|
+
| `enableTapBody` | `boolean` | `true` | 是否在点击时触发 `TapBody` 动作 |
|
|
92
|
+
| `cubismCoreUrl` | `string` | 内置 CDN | Cubism Core 库的加载地址 |
|
|
93
|
+
| `onModelLoaded` | `(model) => void` | - | 模型加载完成后的回调 |
|
|
94
|
+
| `onModelError` | `(error: Error) => void` | - | 模型加载失败的回调 |
|
|
95
|
+
|
|
96
|
+
### 实例方法
|
|
97
|
+
|
|
98
|
+
- **`startMotion(group, no, priority?, startTime?)`** —— 播放指定分组的动作。`priority` 默认 `1`;`startTime`(秒)默认 `0`,大于 0 时从该时间点开始播放。返回 `Promise<boolean>`。
|
|
97
99
|
|
|
98
|
-
- **`destroy()`**
|
|
99
|
-
销毁实例,清理 PIXI 应用及事件监听。
|
|
100
100
|
```typescript
|
|
101
|
-
viewer.
|
|
101
|
+
await viewer.startMotion("TapBody", 0);
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
+
- **`expression(name)`** —— 播放指定表情(名称或索引)。
|
|
105
|
+
- **`waitForMotionFinish()`** —— 返回 `Promise<boolean>`,当前动作播放结束后 resolve;无模型时立即 resolve `false`。
|
|
106
|
+
- **`setScale(scale)`** —— 设置模型缩放比例并刷新布局。
|
|
107
|
+
- **`setXY(x, y)`** —— 设置模型偏移并刷新布局。
|
|
108
|
+
- **`resize()`** —— 手动按当前 canvas 尺寸重新计算布局(容器尺寸变化但窗口未变时使用)。
|
|
109
|
+
- **`lockHeadAngle()`** —— 禁用模型的自然晃动(呼吸、身体/头部摇摆等)。注意:尽管命名含 head,实际会关闭**全部**自然动作。
|
|
110
|
+
- **`destroy()`** —— 销毁实例:移除监听、销毁模型,并释放该实例的 PIXI 应用与 WebGL context(不会移除你传入的 canvas)。销毁后该实例不可复用。
|
|
111
|
+
|
|
112
|
+
### 静态方法
|
|
113
|
+
|
|
114
|
+
- **`Live2DViewer.loadCubismCore(url?)`** —— 预加载 Cubism Core 库,全局按需去重、只真正加载一次;加载失败会抛出明确错误。
|
|
115
|
+
|
|
104
116
|
## 注意事项
|
|
105
117
|
|
|
106
|
-
本库依赖 `pixi.js` v6
|
|
118
|
+
- 本库依赖 `pixi.js` v6(与 `pixi-live2d-display` 兼容),请确保项目中未安装冲突的 PIXI 版本。
|
|
119
|
+
- 模型适配以 **canvas 的显示尺寸** 为基准,请通过 CSS 给 canvas 设定期望的宽高。
|
|
120
|
+
- `interactive: false` 在禁用指针跟随的同时会关闭模型的自然晃动(等同调用 `lockHeadAngle()`)。
|
|
@@ -3211,7 +3211,7 @@ var Y = {
|
|
|
3211
3211
|
}), e.IDENTITY = new e(), e;
|
|
3212
3212
|
}();
|
|
3213
3213
|
//#endregion
|
|
3214
|
-
//#region ../../node_modules/.pnpm/@pixi+display@6.5.2_@pixi+
|
|
3214
|
+
//#region ../../node_modules/.pnpm/@pixi+display@6.5.2_@pixi+m_dbc4d2e5af9caaaf493b57ec65f40b11/node_modules/@pixi/display/dist/esm/display.mjs
|
|
3215
3215
|
B.SORTABLE_CHILDREN = !1;
|
|
3216
3216
|
var Vn = function() {
|
|
3217
3217
|
function e() {
|
|
@@ -3804,7 +3804,7 @@ var gr = function(e) {
|
|
|
3804
3804
|
}), e;
|
|
3805
3805
|
}();
|
|
3806
3806
|
//#endregion
|
|
3807
|
-
//#region ../../node_modules/.pnpm/@pixi+ticker@6.5.2_@pixi+
|
|
3807
|
+
//#region ../../node_modules/.pnpm/@pixi+ticker@6.5.2_@pixi+ex_40a8f4266f4966c790f91b30ddbc0f0c/node_modules/@pixi/ticker/dist/esm/ticker.mjs
|
|
3808
3808
|
Object.defineProperties(X.prototype, {
|
|
3809
3809
|
dispatch: { value: X.prototype.emit },
|
|
3810
3810
|
run: { value: X.prototype.emit }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Bt as e, Kt as t, Lt as n, Rt as r, dn as i, jt as a, nn as o, nt as s } from "./core-
|
|
1
|
+
import { Bt as e, Kt as t, Lt as n, Rt as r, dn as i, jt as a, nn as o, nt as s } from "./core-DBA9LYvt.js";
|
|
2
2
|
//#region ../../node_modules/.pnpm/pixi-live2d-display@0.4.0_d39e0d9e955e28505b3b8642eca0c111/node_modules/pixi-live2d-display/dist/cubism4.es.js
|
|
3
3
|
var c = Math.pow, l = (e, t, n) => new Promise((r, i) => {
|
|
4
4
|
var a = (e) => {
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as e, $t as t, A as n, An as r, At as i, B as a, Bt as o, C as s, Cn as c, Ct as l, D as u, Dn as d, Dt as f, E as p, En as m, Et as h, F as g, Fn as _, Ft as v, G as y, Gt as b, H as x, Ht as S, I as C, In as w, It as T, J as E, Jt as D, K as O, Kt as k, L as A, Ln as j, Lt as M, M as N, Mn as P, Mt as F, N as ee, Nn as te, Nt as ne, O as re, On as ie, Ot as I, P as ae, Pn as oe, Pt as se, Q as L, Qt as R, R as ce, Rn as z, Rt as B, S as V, Sn as le, St as ue, T as de, Tn as fe, Tt as pe, U as me, Ut as H, V as he, Vt as ge, W as _e, Wt as ve, X as ye, Xt as be, Y as xe, Yt as Se, Z as Ce, Zt as we, _ as Te, _n as Ee, _t as De, a as Oe, an as ke, at as Ae, b as je, bn as Me, bt as Ne, c as U, cn as Pe, ct as Fe, d as Ie, dn as Le, dt as Re, en as ze, et as Be, f as Ve, fn as He, ft as Ue, g as We, gn as Ge, gt as Ke, h as qe, hn as Je, ht as Ye, i as Xe, in as Ze, it as Qe, j as $e, jn as W, jt as et, k as tt, kn as nt, kt as rt, l as it, ln as at, lt as ot, m as st, mn as ct, mt as lt, n as ut, nn as dt, nt as G, o as ft, on as pt, ot as mt, p as ht, pn as gt, pt as _t, q as vt, qt as yt, r as bt, rn as xt, rt as St, s as Ct, sn as wt, st as Tt, t as Et, tn as Dt, tt as Ot, u as kt, un as At, ut as jt, v as Mt, vn as Nt, vt as Pt, w as Ft, wn as It, wt as Lt, x as Rt, xn as K, xt as zt, y as Bt, yn as Vt, yt as Ht, z as Ut, zt as Wt } from "./core-
|
|
1
|
+
import { $ as e, $t as t, A as n, An as r, At as i, B as a, Bt as o, C as s, Cn as c, Ct as l, D as u, Dn as d, Dt as f, E as p, En as m, Et as h, F as g, Fn as _, Ft as v, G as y, Gt as b, H as x, Ht as S, I as C, In as w, It as T, J as E, Jt as D, K as O, Kt as k, L as A, Ln as j, Lt as M, M as N, Mn as P, Mt as F, N as ee, Nn as te, Nt as ne, O as re, On as ie, Ot as I, P as ae, Pn as oe, Pt as se, Q as L, Qt as R, R as ce, Rn as z, Rt as B, S as V, Sn as le, St as ue, T as de, Tn as fe, Tt as pe, U as me, Ut as H, V as he, Vt as ge, W as _e, Wt as ve, X as ye, Xt as be, Y as xe, Yt as Se, Z as Ce, Zt as we, _ as Te, _n as Ee, _t as De, a as Oe, an as ke, at as Ae, b as je, bn as Me, bt as Ne, c as U, cn as Pe, ct as Fe, d as Ie, dn as Le, dt as Re, en as ze, et as Be, f as Ve, fn as He, ft as Ue, g as We, gn as Ge, gt as Ke, h as qe, hn as Je, ht as Ye, i as Xe, in as Ze, it as Qe, j as $e, jn as W, jt as et, k as tt, kn as nt, kt as rt, l as it, ln as at, lt as ot, m as st, mn as ct, mt as lt, n as ut, nn as dt, nt as G, o as ft, on as pt, ot as mt, p as ht, pn as gt, pt as _t, q as vt, qt as yt, r as bt, rn as xt, rt as St, s as Ct, sn as wt, st as Tt, t as Et, tn as Dt, tt as Ot, u as kt, un as At, ut as jt, v as Mt, vn as Nt, vt as Pt, w as Ft, wn as It, wt as Lt, x as Rt, xn as K, xt as zt, y as Bt, yn as Vt, yt as Ht, z as Ut, zt as Wt } from "./core-DBA9LYvt.js";
|
|
2
2
|
typeof globalThis < "u" || typeof self < "u" || typeof window < "u" || Function("return this")();
|
|
3
3
|
async function Gt(e) {
|
|
4
4
|
return await new Promise(function(t) {
|
|
@@ -277,7 +277,7 @@ globalThis.requestAnimationFrame || (globalThis.requestAnimationFrame = function
|
|
|
277
277
|
return typeof e == "number" && isFinite(e) && Math.floor(e) === e;
|
|
278
278
|
}), globalThis.ArrayBuffer || (globalThis.ArrayBuffer = Array), globalThis.Float32Array || (globalThis.Float32Array = Array), globalThis.Uint32Array || (globalThis.Uint32Array = Array), globalThis.Uint16Array || (globalThis.Uint16Array = Array), globalThis.Uint8Array || (globalThis.Uint8Array = Array), globalThis.Int32Array || (globalThis.Int32Array = Array);
|
|
279
279
|
//#endregion
|
|
280
|
-
//#region ../../node_modules/.pnpm/@pixi+accessibility@6.5.2_@
|
|
280
|
+
//#region ../../node_modules/.pnpm/@pixi+accessibility@6.5.2_@_6fa672afef0d0e890b1f89be0296d21a/node_modules/@pixi/accessibility/dist/esm/accessibility.mjs
|
|
281
281
|
var mn = {
|
|
282
282
|
accessible: !1,
|
|
283
283
|
accessibleTitle: null,
|
|
@@ -1328,7 +1328,7 @@ var ur = function() {
|
|
|
1328
1328
|
}();
|
|
1329
1329
|
rt.add(or, ur);
|
|
1330
1330
|
//#endregion
|
|
1331
|
-
//#region ../../node_modules/.pnpm/@pixi+compressed-textures@
|
|
1331
|
+
//#region ../../node_modules/.pnpm/@pixi+compressed-textures@6_e163e6679f0f4e58c3f6ee8bbe6275c0/node_modules/@pixi/compressed-textures/dist/esm/compressed-textures.mjs
|
|
1332
1332
|
var Y, X;
|
|
1333
1333
|
(function(e) {
|
|
1334
1334
|
e[e.COMPRESSED_RGB_S3TC_DXT1_EXT = 33776] = "COMPRESSED_RGB_S3TC_DXT1_EXT", e[e.COMPRESSED_RGBA_S3TC_DXT1_EXT = 33777] = "COMPRESSED_RGBA_S3TC_DXT1_EXT", e[e.COMPRESSED_RGBA_S3TC_DXT3_EXT = 33778] = "COMPRESSED_RGBA_S3TC_DXT3_EXT", e[e.COMPRESSED_RGBA_S3TC_DXT5_EXT = 33779] = "COMPRESSED_RGBA_S3TC_DXT5_EXT", e[e.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT = 35917] = "COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT", e[e.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT = 35918] = "COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT", e[e.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT = 35919] = "COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT", e[e.COMPRESSED_SRGB_S3TC_DXT1_EXT = 35916] = "COMPRESSED_SRGB_S3TC_DXT1_EXT", e[e.COMPRESSED_R11_EAC = 37488] = "COMPRESSED_R11_EAC", e[e.COMPRESSED_SIGNED_R11_EAC = 37489] = "COMPRESSED_SIGNED_R11_EAC", e[e.COMPRESSED_RG11_EAC = 37490] = "COMPRESSED_RG11_EAC", e[e.COMPRESSED_SIGNED_RG11_EAC = 37491] = "COMPRESSED_SIGNED_RG11_EAC", e[e.COMPRESSED_RGB8_ETC2 = 37492] = "COMPRESSED_RGB8_ETC2", e[e.COMPRESSED_RGBA8_ETC2_EAC = 37496] = "COMPRESSED_RGBA8_ETC2_EAC", e[e.COMPRESSED_SRGB8_ETC2 = 37493] = "COMPRESSED_SRGB8_ETC2", e[e.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 37497] = "COMPRESSED_SRGB8_ALPHA8_ETC2_EAC", e[e.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 37494] = "COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2", e[e.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 37495] = "COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2", e[e.COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 35840] = "COMPRESSED_RGB_PVRTC_4BPPV1_IMG", e[e.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 35842] = "COMPRESSED_RGBA_PVRTC_4BPPV1_IMG", e[e.COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 35841] = "COMPRESSED_RGB_PVRTC_2BPPV1_IMG", e[e.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 35843] = "COMPRESSED_RGBA_PVRTC_2BPPV1_IMG", e[e.COMPRESSED_RGB_ETC1_WEBGL = 36196] = "COMPRESSED_RGB_ETC1_WEBGL", e[e.COMPRESSED_RGB_ATC_WEBGL = 35986] = "COMPRESSED_RGB_ATC_WEBGL", e[e.COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL = 35986] = "COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL", e[e.COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 34798] = "COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL";
|
|
@@ -5491,7 +5491,7 @@ var $o = "varying vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform floa
|
|
|
5491
5491
|
}(Rt);
|
|
5492
5492
|
es.prototype.grayscale = es.prototype.greyscale;
|
|
5493
5493
|
//#endregion
|
|
5494
|
-
//#region ../../node_modules/.pnpm/@pixi+filter-displacement@
|
|
5494
|
+
//#region ../../node_modules/.pnpm/@pixi+filter-displacement@6_6c8bdb756a202d74aaa77fd3eb3cd558/node_modules/@pixi/filter-displacement/dist/esm/filter-displacement.mjs
|
|
5495
5495
|
var ts = function(e, t) {
|
|
5496
5496
|
return ts = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(e, t) {
|
|
5497
5497
|
e.__proto__ = t;
|
|
@@ -5691,7 +5691,7 @@ var Is = function() {
|
|
|
5691
5691
|
return e;
|
|
5692
5692
|
}();
|
|
5693
5693
|
//#endregion
|
|
5694
|
-
//#region ../../node_modules/.pnpm/@pixi+mixin-get-global-
|
|
5694
|
+
//#region ../../node_modules/.pnpm/@pixi+mixin-get-global-posi_028b3c491a57204327251ef324f60475/node_modules/@pixi/mixin-get-global-position/dist/esm/mixin-get-global-position.mjs
|
|
5695
5695
|
Object.defineProperties(F.prototype, {
|
|
5696
5696
|
cacheAsBitmapResolution: {
|
|
5697
5697
|
get: function() {
|
|
@@ -5795,7 +5795,7 @@ Object.defineProperties(F.prototype, {
|
|
|
5795
5795
|
return e === void 0 && (e = new o()), t === void 0 && (t = !1), this.parent ? this.parent.toGlobal(this.position, e, t) : (e.x = this.position.x, e.y = this.position.y), e;
|
|
5796
5796
|
};
|
|
5797
5797
|
//#endregion
|
|
5798
|
-
//#region ../../node_modules/.pnpm/@pixi+app@6.5.2_@pixi+core@
|
|
5798
|
+
//#region ../../node_modules/.pnpm/@pixi+app@6.5.2_@pixi+core@_d997c290ef5e4553ddd5c6768aff9f1c/node_modules/@pixi/app/dist/esm/app.mjs
|
|
5799
5799
|
var Ls = function() {
|
|
5800
5800
|
function e() {}
|
|
5801
5801
|
return e.init = function(e) {
|
|
@@ -6428,7 +6428,7 @@ var nl = function() {
|
|
|
6428
6428
|
}();
|
|
6429
6429
|
rt.handleByList(I.Application, nl._plugins), rt.add(Ls);
|
|
6430
6430
|
//#endregion
|
|
6431
|
-
//#region ../../node_modules/.pnpm/@pixi+mesh-extras@6.5.2_@
|
|
6431
|
+
//#region ../../node_modules/.pnpm/@pixi+mesh-extras@6.5.2_@pi_2c67296e184f7a20c4c1bea5a2db14c2/node_modules/@pixi/mesh-extras/dist/esm/mesh-extras.mjs
|
|
6432
6432
|
var rl = function(e, t) {
|
|
6433
6433
|
return rl = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(e, t) {
|
|
6434
6434
|
e.__proto__ = t;
|
|
@@ -6958,48 +6958,45 @@ var gl = {
|
|
|
6958
6958
|
DisplacementFilter: as,
|
|
6959
6959
|
FXAAFilter: us,
|
|
6960
6960
|
NoiseFilter: ms
|
|
6961
|
-
}, _l = "https://a0.seayooassets.com/web/libs/live2dcubismcore.js", vl =
|
|
6962
|
-
|
|
6961
|
+
}, _l = "https://a0.seayooassets.com/web/libs/live2dcubismcore.js", vl = null;
|
|
6962
|
+
function yl() {
|
|
6963
|
+
return vl ||= import("./cubism4.es-DbGCrqOi.js"), vl;
|
|
6964
|
+
}
|
|
6965
|
+
var bl = class e {
|
|
6963
6966
|
static coreLoadingPromise = null;
|
|
6964
6967
|
static async loadCubismCore(e = _l) {
|
|
6965
|
-
this.coreLoadingPromise ||= Gt(e), await this.coreLoadingPromise;
|
|
6968
|
+
if (this.coreLoadingPromise ||= Gt(e), !await this.coreLoadingPromise) throw this.coreLoadingPromise = null, Error(`Failed to load Live2D Cubism Core from "${e}"`);
|
|
6966
6969
|
}
|
|
6967
|
-
static loadingToken = 0;
|
|
6968
|
-
static hasWarmedUp = !1;
|
|
6969
6970
|
app;
|
|
6970
6971
|
model = null;
|
|
6971
6972
|
options;
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
|
|
6991
|
-
}
|
|
6992
|
-
let t = r.parentElement, n = e.sharedApp.view;
|
|
6993
|
-
t && (n.className = r.className, n.style.cssText = r.style.cssText, r.id && (n.id = r.id), t.replaceChild(n, r));
|
|
6994
|
-
}
|
|
6995
|
-
this.app = e.sharedApp, this.init(), this.options.autoResize !== !1 && window.addEventListener("resize", this.handleResize);
|
|
6973
|
+
loadingToken = 0;
|
|
6974
|
+
hasWarmedUp = !1;
|
|
6975
|
+
constructor(e, t) {
|
|
6976
|
+
this.options = t, window.PIXI || (window.PIXI = hl);
|
|
6977
|
+
let n;
|
|
6978
|
+
if (typeof e == "string") {
|
|
6979
|
+
let t = document.getElementById(e);
|
|
6980
|
+
if (!t) throw Error(`Canvas element with id "${e}" not found.`);
|
|
6981
|
+
if (!(t instanceof HTMLCanvasElement)) throw Error(`Element with id "${e}" is not a canvas.`);
|
|
6982
|
+
n = t;
|
|
6983
|
+
} else n = e;
|
|
6984
|
+
let r = window.devicePixelRatio || 1, i = n.getBoundingClientRect(), a = Math.max(i.width, 100), o = Math.max(i.height, 100);
|
|
6985
|
+
n.width = a * r, n.height = o * r, this.app = new nl({
|
|
6986
|
+
view: n,
|
|
6987
|
+
resizeTo: n,
|
|
6988
|
+
backgroundAlpha: 0,
|
|
6989
|
+
autoStart: !0,
|
|
6990
|
+
sharedTicker: !0,
|
|
6991
|
+
resolution: r
|
|
6992
|
+
}), this.init(), this.options.autoResize !== !1 && window.addEventListener("resize", this.handleResize);
|
|
6996
6993
|
}
|
|
6997
6994
|
async init() {
|
|
6998
6995
|
try {
|
|
6999
|
-
let t = ++
|
|
6996
|
+
let t = ++this.loadingToken;
|
|
7000
6997
|
await e.loadCubismCore(this.options.cubismCoreUrl);
|
|
7001
|
-
let { Live2DModel: n } = await yl, r = await n.from(this.options.modelPath);
|
|
7002
|
-
if (t !==
|
|
6998
|
+
let { Live2DModel: n } = await yl(), r = await n.from(this.options.modelPath);
|
|
6999
|
+
if (t !== this.loadingToken) {
|
|
7003
7000
|
r.destroy({
|
|
7004
7001
|
children: !0,
|
|
7005
7002
|
texture: !0,
|
|
@@ -7007,8 +7004,8 @@ var gl = {
|
|
|
7007
7004
|
});
|
|
7008
7005
|
return;
|
|
7009
7006
|
}
|
|
7010
|
-
if (!
|
|
7011
|
-
|
|
7007
|
+
if (!this.hasWarmedUp) {
|
|
7008
|
+
this.hasWarmedUp = !0, this.app.stage.addChild(r);
|
|
7012
7009
|
try {
|
|
7013
7010
|
this.app.renderer.render(this.app.stage);
|
|
7014
7011
|
} catch {}
|
|
@@ -7016,8 +7013,8 @@ var gl = {
|
|
|
7016
7013
|
children: !0,
|
|
7017
7014
|
texture: !0,
|
|
7018
7015
|
baseTexture: !0
|
|
7019
|
-
}), await new Promise((e) => requestAnimationFrame(() => e())), t !==
|
|
7020
|
-
if (r = await n.from(this.options.modelPath), t !==
|
|
7016
|
+
}), await new Promise((e) => requestAnimationFrame(() => e())), t !== this.loadingToken) return;
|
|
7017
|
+
if (r = await n.from(this.options.modelPath), t !== this.loadingToken) {
|
|
7021
7018
|
r.destroy({
|
|
7022
7019
|
children: !0,
|
|
7023
7020
|
texture: !0,
|
|
@@ -7054,8 +7051,10 @@ var gl = {
|
|
|
7054
7051
|
};
|
|
7055
7052
|
resize() {
|
|
7056
7053
|
if (!this.model || !this.app) return;
|
|
7057
|
-
let e = window.innerWidth / (this.options.designWidth || 1920),
|
|
7058
|
-
this.app.stage.scale.set(
|
|
7054
|
+
let e = this.app.view.getBoundingClientRect(), t = e.width || window.innerWidth, n = e.height || window.innerHeight, r = t / (this.options.designWidth || 1920), i = n / (this.options.designHeight || 1080), a = Math.min(r, i);
|
|
7055
|
+
this.app.stage.scale.set(a, a);
|
|
7056
|
+
let o = this.options.scale ?? 1;
|
|
7057
|
+
this.model.scale.set(o, o), this.model.x = (this.options.x || 0) * a, this.model.y = (this.options.y || 0) * a;
|
|
7059
7058
|
}
|
|
7060
7059
|
setScale(e) {
|
|
7061
7060
|
this.options.scale = e, this.resize();
|
|
@@ -7083,24 +7082,30 @@ var gl = {
|
|
|
7083
7082
|
}
|
|
7084
7083
|
waitForMotionFinish() {
|
|
7085
7084
|
return new Promise((e) => {
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7085
|
+
if (!this.model) {
|
|
7086
|
+
e(!1);
|
|
7087
|
+
return;
|
|
7088
|
+
}
|
|
7089
|
+
let t = this.model.internalModel.motionManager, n = () => {
|
|
7090
|
+
t.off("motionFinish", n), e(!0);
|
|
7089
7091
|
};
|
|
7090
|
-
|
|
7091
|
-
this.model.internalModel.motionManager.on("motionFinish", t);
|
|
7092
|
+
t.on("motionFinish", n);
|
|
7092
7093
|
});
|
|
7093
7094
|
}
|
|
7094
7095
|
destroy() {
|
|
7095
|
-
this.options.autoResize !== !1 && window.removeEventListener("resize", this.handleResize), this.model &&= (this.app.stage.removeChild(this.model), this.model.destroy({
|
|
7096
|
+
this.options.autoResize !== !1 && window.removeEventListener("resize", this.handleResize), this.loadingToken++, this.model &&= (this.app.stage.removeChild(this.model), this.model.destroy({
|
|
7096
7097
|
children: !0,
|
|
7097
7098
|
texture: !0,
|
|
7098
7099
|
baseTexture: !0
|
|
7099
|
-
}), null)
|
|
7100
|
+
}), null), this.app.destroy(!1, {
|
|
7101
|
+
children: !0,
|
|
7102
|
+
texture: !0,
|
|
7103
|
+
baseTexture: !0
|
|
7104
|
+
});
|
|
7100
7105
|
}
|
|
7101
7106
|
};
|
|
7102
7107
|
function xl(e) {
|
|
7103
7108
|
return e instanceof Error ? e : Error(String(e));
|
|
7104
7109
|
}
|
|
7105
7110
|
//#endregion
|
|
7106
|
-
export { bl as Live2DViewer
|
|
7111
|
+
export { bl as Live2DViewer };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seayoo-web/pixi-live2d",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "pixi-live2d viewer",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pixi-live2d"
|
|
@@ -39,18 +39,20 @@
|
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "^22.13.1",
|
|
42
|
-
"@
|
|
43
|
-
"
|
|
42
|
+
"@vitest/coverage-istanbul": "^4.1.4",
|
|
43
|
+
"happy-dom": "^13.10.1",
|
|
44
|
+
"vitest": "^4.1.4",
|
|
45
|
+
"@seayoo-web/utils": "^4.5.4",
|
|
46
|
+
"@seayoo-web/tsconfig": "^1.0.6"
|
|
44
47
|
},
|
|
45
48
|
"engines": {
|
|
46
49
|
"node": ">=22"
|
|
47
50
|
},
|
|
48
51
|
"scripts": {
|
|
49
|
-
"build": "vite build && tsc --build --
|
|
52
|
+
"build": "vite build && tsc --build --emitDeclarationOnly",
|
|
50
53
|
"type-check": "tsc --noEmit",
|
|
51
54
|
"lint": "oxlint -c ../../oxlint.config.mjs",
|
|
52
55
|
"lint:fix": "oxlint -c ../../oxlint.config.mjs --fix",
|
|
53
|
-
"prepublish": "pnpm lint:fix && pnpm build",
|
|
54
56
|
"test": "vitest --dom",
|
|
55
57
|
"coverage": "vitest run --coverage"
|
|
56
58
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import * as PIXI from "pixi.js";
|
|
2
|
-
declare const coreLoadPromise: Promise<boolean>;
|
|
3
|
-
export { coreLoadPromise };
|
|
4
2
|
import type { InternalModel as InternalModelType, Live2DModel as Live2DModelType } from "pixi-live2d-display/cubism4";
|
|
5
3
|
export type { MotionPriority } from "pixi-live2d-display/cubism4";
|
|
6
4
|
declare global {
|
|
@@ -36,8 +34,6 @@ export interface Live2DViewerOptions {
|
|
|
36
34
|
onModelError?: (error: Error) => void;
|
|
37
35
|
}
|
|
38
36
|
export declare class Live2DViewer {
|
|
39
|
-
/** 单例 PIXI 应用 */
|
|
40
|
-
static sharedApp: PIXI.Application | null;
|
|
41
37
|
/** 引擎加载状态 Promise,用于确保全局只加载一次 Core 库 */
|
|
42
38
|
private static coreLoadingPromise;
|
|
43
39
|
/**
|
|
@@ -45,16 +41,16 @@ export declare class Live2DViewer {
|
|
|
45
41
|
* @param url - Core 库的 URL 地址
|
|
46
42
|
*/
|
|
47
43
|
static loadCubismCore(url?: string): Promise<void>;
|
|
48
|
-
/**
|
|
49
|
-
private static loadingToken;
|
|
50
|
-
/** 整个页面生命周期内 Cubism 渲染管线是否已完成首次预热 */
|
|
51
|
-
private static hasWarmedUp;
|
|
52
|
-
/** PIXI 应用实例 */
|
|
44
|
+
/** PIXI 应用实例(每个 viewer 独立,持有各自的 canvas / stage / WebGL context) */
|
|
53
45
|
app: PIXI.Application;
|
|
54
46
|
/** Live2D 模型实例 */
|
|
55
47
|
model: Live2DModelType<InternalModelType> | null;
|
|
56
|
-
/**
|
|
48
|
+
/** 配置项 */
|
|
57
49
|
private options;
|
|
50
|
+
/** 最新发起的加载任务 token,防同一实例内频繁加载的竞态泄漏 */
|
|
51
|
+
private loadingToken;
|
|
52
|
+
/** 该实例(WebGL context)的渲染管线是否已完成首次预热 */
|
|
53
|
+
private hasWarmedUp;
|
|
58
54
|
/**
|
|
59
55
|
* 创建 Live2D 查看器实例
|
|
60
56
|
* @param canvas - 用于渲染的 Canvas 元素或其 ID
|
|
@@ -66,8 +62,10 @@ export declare class Live2DViewer {
|
|
|
66
62
|
/** 设置点击交互 */
|
|
67
63
|
private setupInteraction;
|
|
68
64
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
65
|
+
* 禁用模型的自然晃动(呼吸、身体/头部摇摆等)。
|
|
66
|
+
*
|
|
67
|
+
* 实现方式是把 internalModel 的 updateNaturalMovements 覆写为空操作。
|
|
68
|
+
* 注意:尽管方法名含 head,实际会关闭**全部**自然动作,而不仅是头部角度。
|
|
71
69
|
*/
|
|
72
70
|
lockHeadAngle(): void;
|
|
73
71
|
/** 窗口大小改变的处理函数 */
|