dsh-live2dwaifu 1.0.1 → 1.0.3
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 +17 -2
- package/assets/viewer.js +26 -12
- package/lib/client.js +51 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,7 +35,9 @@ dsh plugin --profile desktop add dsh-live2dwaifu
|
|
|
35
35
|
|
|
36
36
|
### 位置和大小
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
按住**标题栏**能拖到屏幕任何地方。
|
|
39
|
+
**改大小**:卡片左上角那个小斜纹,往左上拖变大、往右下拖变小——卡片本身钉在屏幕右下角,所以动的是它的左上角(宽 200–720,高 220–视口高−80)。
|
|
40
|
+
位置、大小、背景、开合状态都记在本机,下次打开还是这样。
|
|
39
41
|
|
|
40
42
|
拖到一半跑到屏幕外了?关掉重开一次就回到默认位置。
|
|
41
43
|
|
|
@@ -188,6 +190,19 @@ python tools/export-dsh-meme.py
|
|
|
188
190
|
|
|
189
191
|
| 开关 | 位置 | 默认 | 说明 |
|
|
190
192
|
|---|---|---|---|
|
|
193
|
+
| 视线跟随鼠标 | 本机 | 开 | 角色的眼睛和头跟着鼠标动 |
|
|
194
|
+
| 点击角色有反应 | 本机 | 开 | 点她不同部位有不同反应 |
|
|
195
|
+
| 自动播放动作 | 本机 | 开 | 模型带动作文件时,隔一会儿播一个 |
|
|
196
|
+
| 说话带电子音 | 本机 | 开 | 每个字一声短音 |
|
|
197
|
+
| 复述聊天内容 | 本机 | 开 | 聊天窗口出现新回复时,由她念出来 |
|
|
198
|
+
| 闲置时主动说话 | 服务端 | 开 | 一段时间没人说话,她自己开一句 |
|
|
199
|
+
| 回复附带选项按钮 | 服务端 | 开 | 她觉得需要选择时,气泡上方出现可点按钮 |
|
|
200
|
+
| 记住聊过的内容 | 服务端 | 开 | 关掉就不带记忆、不压缩 |
|
|
201
|
+
| 表情包(四档) | 服务端 | 不使用 | 测试功能,见上面那节 |
|
|
202
|
+
|
|
203
|
+
「本机」存 localStorage,只影响这一台浏览器;「服务端」存 `~/.dsh/dsh-live2d/config.json`,换浏览器也一样。
|
|
204
|
+
|
|
205
|
+
---|---|---|---|
|
|
191
206
|
| 眼睛跟着鼠标 | 本机 | 开 | 关掉她就不看鼠标了 |
|
|
192
207
|
| 点她有反应 | 本机 | 开 | 摸头害羞、戳身上瞪你 |
|
|
193
208
|
| 自己播动作 | 本机 | 开 | 有动作文件的模型才会动 |
|
|
@@ -272,7 +287,7 @@ curl -X POST http://127.0.0.1:<端口>/dsh-live2d/api/push \
|
|
|
272
287
|
先重启。还不来,看 profile 的 `package.json`:`dsh.profile.bundles` 和 `dependencies` 里都得有 `dsh-live2dwaifu`。手动拷进 `node_modules` 的不会自动登记。
|
|
273
288
|
|
|
274
289
|
**她只有半张脸 / 位置偏上**
|
|
275
|
-
|
|
290
|
+
模型画布比例跟卡片不一样。卡片是竖的,太宽或太扁的模型会被裁两边。拖左上角那个小斜纹改形状试试。
|
|
276
291
|
|
|
277
292
|
**导入了却不认得**
|
|
278
293
|
`.model3.json` 的层级选错了。选它隔壁那一层。
|
package/assets/viewer.js
CHANGED
|
@@ -44338,30 +44338,43 @@ void main(void)\r
|
|
|
44338
44338
|
}
|
|
44339
44339
|
}
|
|
44340
44340
|
var LOCAL_OPTS = [
|
|
44341
|
-
["gaze", "\
|
|
44342
|
-
["poke", "\u70B9\
|
|
44343
|
-
["motion", "\u81EA\
|
|
44344
|
-
["sound", "\
|
|
44345
|
-
["follow", "\
|
|
44341
|
+
["gaze", "\u89C6\u7EBF\u8DDF\u968F\u9F20\u6807"],
|
|
44342
|
+
["poke", "\u70B9\u51FB\u89D2\u8272\u6709\u53CD\u5E94"],
|
|
44343
|
+
["motion", "\u81EA\u52A8\u64AD\u653E\u52A8\u4F5C"],
|
|
44344
|
+
["sound", "\u8BF4\u8BDD\u5E26\u7535\u5B50\u97F3"],
|
|
44345
|
+
["follow", "\u590D\u8FF0\u804A\u5929\u5185\u5BB9"]
|
|
44346
44346
|
];
|
|
44347
44347
|
var SERVER_OPTS = [
|
|
44348
|
-
["proactive", "\
|
|
44349
|
-
["choices", "\
|
|
44350
|
-
["memory", "\u8BB0\u4F4F\
|
|
44348
|
+
["proactive", "\u95F2\u7F6E\u65F6\u4E3B\u52A8\u8BF4\u8BDD"],
|
|
44349
|
+
["choices", "\u56DE\u590D\u9644\u5E26\u9009\u9879\u6309\u94AE"],
|
|
44350
|
+
["memory", "\u8BB0\u4F4F\u804A\u8FC7\u7684\u5185\u5BB9"]
|
|
44351
44351
|
];
|
|
44352
|
+
var LOCAL_HINT = {
|
|
44353
|
+
gaze: "\u89D2\u8272\u7684\u773C\u775B\u548C\u5934\u4F1A\u8DDF\u7740\u9F20\u6807\u79FB\u52A8",
|
|
44354
|
+
poke: "\u70B9\u89D2\u8272\u7684\u4E0D\u540C\u90E8\u4F4D\u4F1A\u6709\u4E0D\u540C\u53CD\u5E94",
|
|
44355
|
+
motion: "\u6A21\u578B\u5E26\u52A8\u4F5C\u6587\u4EF6\u65F6\uFF0C\u9694\u4E00\u4F1A\u513F\u81EA\u52A8\u64AD\u4E00\u4E2A",
|
|
44356
|
+
sound: "\u8BF4\u8BDD\u65F6\u6BCF\u4E2A\u5B57\u53D1\u4E00\u58F0\u5F88\u77ED\u7684\u7535\u5B50\u97F3",
|
|
44357
|
+
follow: "\u804A\u5929\u7A97\u53E3\u51FA\u73B0\u65B0\u56DE\u590D\u65F6\uFF0C\u7531\u89D2\u8272\u5FF5\u51FA\u6765"
|
|
44358
|
+
};
|
|
44359
|
+
var SERVER_HINT = {
|
|
44360
|
+
proactive: "\u4E00\u6BB5\u65F6\u95F4\u6CA1\u4EBA\u8BF4\u8BDD\uFF0C\u89D2\u8272\u81EA\u5DF1\u5F00\u4E00\u53E5",
|
|
44361
|
+
choices: "\u89D2\u8272\u89C9\u5F97\u9700\u8981\u9009\u62E9\u65F6\uFF0C\u6C14\u6CE1\u4E0A\u65B9\u51FA\u73B0\u53EF\u70B9\u7684\u6309\u94AE",
|
|
44362
|
+
memory: "\u4FDD\u7559\u804A\u8FC7\u7684\u5185\u5BB9\uFF0C\u4E0B\u6B21\u63A5\u7740\u804A\uFF08\u5360\u66F4\u591A\u6A21\u578B\u989D\u5EA6\uFF09"
|
|
44363
|
+
};
|
|
44352
44364
|
var MEME_MODES = ["off", "own", "both", "external"];
|
|
44353
|
-
var MEME_LABELS = ["\u4E0D\u4F7F\u7528", "\
|
|
44365
|
+
var MEME_LABELS = ["\u4E0D\u4F7F\u7528", "\u4EC5\u81EA\u5E26", "\u4E24\u8005\u90FD\u7528", "\u4EC5 dsh-meme"];
|
|
44354
44366
|
var serverSettings = {};
|
|
44355
44367
|
function renderSettings() {
|
|
44356
44368
|
const box = $2("settings");
|
|
44357
44369
|
if (!box) return;
|
|
44358
44370
|
box.innerHTML = "";
|
|
44359
44371
|
const h1 = document.createElement("h3");
|
|
44360
|
-
h1.textContent = "\
|
|
44372
|
+
h1.textContent = "\u663E\u793A\u4E0E\u4EA4\u4E92\uFF08\u5B58\u672C\u673A\uFF09";
|
|
44361
44373
|
box.appendChild(h1);
|
|
44362
44374
|
for (const [k2, label] of LOCAL_OPTS) {
|
|
44363
44375
|
const row = document.createElement("label");
|
|
44364
44376
|
row.className = "opt";
|
|
44377
|
+
row.title = LOCAL_HINT[k2] || "";
|
|
44365
44378
|
const cb = document.createElement("input");
|
|
44366
44379
|
cb.type = "checkbox";
|
|
44367
44380
|
cb.checked = flag(k2);
|
|
@@ -44371,11 +44384,12 @@ void main(void)\r
|
|
|
44371
44384
|
box.appendChild(row);
|
|
44372
44385
|
}
|
|
44373
44386
|
const h2 = document.createElement("h3");
|
|
44374
|
-
h2.textContent = "\
|
|
44387
|
+
h2.textContent = "\u5BF9\u8BDD\u4E0E\u884C\u4E3A\uFF08\u5B58\u670D\u52A1\u7AEF\uFF09";
|
|
44375
44388
|
box.appendChild(h2);
|
|
44376
44389
|
for (const [k2, label] of SERVER_OPTS) {
|
|
44377
44390
|
const row = document.createElement("label");
|
|
44378
44391
|
row.className = "opt";
|
|
44392
|
+
row.title = SERVER_HINT[k2] || "";
|
|
44379
44393
|
const cb = document.createElement("input");
|
|
44380
44394
|
cb.type = "checkbox";
|
|
44381
44395
|
cb.checked = serverSettings[k2] !== false;
|
|
@@ -44422,7 +44436,7 @@ void main(void)\r
|
|
|
44422
44436
|
};
|
|
44423
44437
|
const note = document.createElement("div");
|
|
44424
44438
|
note.className = "opt-note";
|
|
44425
|
-
note.textContent = "\
|
|
44439
|
+
note.textContent = "\u9009\u8BF4\u8BDD\u65F6\u914D\u56FE\u7684\u6765\u6E90\uFF1A\u81EA\u5E26\u662F\u63D2\u4EF6\u5185\u7F6E\u7684\u8D34\u56FE\uFF1Bdsh-meme \u662F\u4F60\u5DF2\u7ECF\u88C5\u597D\u7684\u56FE\u5E93\u3002\u6B64\u529F\u80FD\u4ECD\u5728\u6D4B\u8BD5\uFF0C\u884C\u4E3A\u53EF\u80FD\u8C03\u6574\u3002";
|
|
44426
44440
|
wrap.appendChild(slider);
|
|
44427
44441
|
wrap.appendChild(lab);
|
|
44428
44442
|
wrap.appendChild(note);
|
package/lib/client.js
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
transition:box-shadow .2s ease}
|
|
19
19
|
.dsh-l2d-card:hover{box-shadow:0 22px 58px rgba(0,0,0,.58)}
|
|
20
20
|
.dsh-l2d-card.collapsed{width:150px!important;height:38px!important}
|
|
21
|
-
.dsh-l2d-head{display:flex;align-items:center;gap:7px;padding:9px 11px;color:#a8b1bf;font-size:11px;
|
|
21
|
+
.dsh-l2d-head{display:flex;align-items:center;gap:7px;padding:9px 11px 9px 24px;color:#a8b1bf;font-size:11px;
|
|
22
22
|
letter-spacing:.4px;border-bottom:1px solid rgba(255,255,255,.06);user-select:none;flex:none;cursor:move;
|
|
23
23
|
background:linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,0))}
|
|
24
24
|
.dsh-l2d-dot{width:7px;height:7px;border-radius:50%;background:#6aa9ff;flex:none;
|
|
@@ -43,10 +43,12 @@
|
|
|
43
43
|
transition:filter .15s ease}
|
|
44
44
|
.dsh-l2d-send:hover{filter:brightness(1.14)}
|
|
45
45
|
.dsh-l2d-send:active{filter:brightness(.96)}
|
|
46
|
-
.dsh-l2d-grip{position:absolute;
|
|
47
|
-
transition:opacity .15s ease;
|
|
48
|
-
background:repeating-linear-gradient(135deg,transparent 0 2px,rgba(255,255,255,.
|
|
49
|
-
.dsh-l2d-grip:hover{opacity:1}
|
|
46
|
+
.dsh-l2d-grip{position:absolute;left:0;top:0;width:20px;height:20px;cursor:nwse-resize;opacity:.4;
|
|
47
|
+
transition:opacity .15s ease,background .15s ease;border-radius:16px 0 8px 0;z-index:2;
|
|
48
|
+
background:repeating-linear-gradient(135deg,transparent 0 2px,rgba(255,255,255,.45) 2px 3px) no-repeat left top/10px 10px}
|
|
49
|
+
.dsh-l2d-grip:hover{opacity:1;background-color:rgba(255,255,255,.08)}
|
|
50
|
+
.dsh-l2d-card.resizing{cursor:nwse-resize;box-shadow:0 0 0 1px rgba(106,169,255,.45),0 22px 58px rgba(0,0,0,.6)}
|
|
51
|
+
.dsh-l2d-card.moving{cursor:move;box-shadow:0 0 0 1px rgba(106,169,255,.35),0 22px 58px rgba(0,0,0,.6)}
|
|
50
52
|
`;
|
|
51
53
|
|
|
52
54
|
function ensureCss() {
|
|
@@ -149,42 +151,67 @@
|
|
|
149
151
|
.catch(() => setTitle('Live2D'));
|
|
150
152
|
}, [nonce]);
|
|
151
153
|
|
|
154
|
+
// 拖动时把 iframe 的指针事件关掉,否则光标一进 iframe 父窗口就收不到事件,手感像粘住
|
|
155
|
+
const lockPointer = (on, cls, cardEl) => {
|
|
156
|
+
const f = ref.current;
|
|
157
|
+
if (f) f.style.pointerEvents = on ? 'none' : '';
|
|
158
|
+
if (cardEl && cardEl.classList) {
|
|
159
|
+
cardEl.classList.toggle('resizing', on && cls === 'resizing');
|
|
160
|
+
cardEl.classList.toggle('moving', on && cls === 'moving');
|
|
161
|
+
}
|
|
162
|
+
document.body.style.userSelect = on ? 'none' : '';
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const bindDrag = (move, cls, cardEl) => {
|
|
166
|
+
const up = () => {
|
|
167
|
+
window.removeEventListener('pointermove', move);
|
|
168
|
+
window.removeEventListener('pointerup', up);
|
|
169
|
+
window.removeEventListener('pointercancel', up);
|
|
170
|
+
lockPointer(false, cls, cardEl);
|
|
171
|
+
};
|
|
172
|
+
window.addEventListener('pointermove', move);
|
|
173
|
+
window.addEventListener('pointerup', up);
|
|
174
|
+
window.addEventListener('pointercancel', up);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// 卡片钉在右下角,所以只有左上角会动:往左上拖变大,往右下拖变小
|
|
152
178
|
const startDrag = (e) => {
|
|
153
179
|
e.preventDefault();
|
|
180
|
+
e.stopPropagation();
|
|
181
|
+
const cardEl = e.currentTarget.closest('.dsh-l2d-card');
|
|
154
182
|
const sx = e.clientX;
|
|
155
183
|
const sy = e.clientY;
|
|
156
184
|
const w0 = size.w;
|
|
157
185
|
const h0 = size.h;
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const
|
|
186
|
+
lockPointer(true, 'resizing', cardEl);
|
|
187
|
+
bindDrag((ev) => {
|
|
188
|
+
const maxW = Math.min(720, Math.max(240, window.innerWidth - 60));
|
|
189
|
+
const maxH = Math.max(240, window.innerHeight - 80);
|
|
190
|
+
const w = Math.max(200, Math.min(maxW, w0 + (sx - ev.clientX)));
|
|
191
|
+
const hh = Math.max(220, Math.min(maxH, h0 + (sy - ev.clientY)));
|
|
161
192
|
setSize({ w: Math.round(w), h: Math.round(hh) });
|
|
162
|
-
};
|
|
163
|
-
const up = () => {
|
|
164
|
-
window.removeEventListener('pointermove', move);
|
|
165
|
-
window.removeEventListener('pointerup', up);
|
|
166
|
-
};
|
|
167
|
-
window.addEventListener('pointermove', move);
|
|
168
|
-
window.addEventListener('pointerup', up);
|
|
193
|
+
}, 'resizing', cardEl);
|
|
169
194
|
};
|
|
170
195
|
|
|
171
196
|
const startMove = (e) => {
|
|
172
197
|
if (e.button !== undefined && e.button !== 0) return;
|
|
198
|
+
const cardEl = e.currentTarget.closest('.dsh-l2d-card');
|
|
173
199
|
const sx = e.clientX;
|
|
174
200
|
const sy = e.clientY;
|
|
175
201
|
const x0 = pos.x;
|
|
176
202
|
const y0 = pos.y;
|
|
177
|
-
const
|
|
203
|
+
const w = size.w;
|
|
204
|
+
const hh = open ? size.h : 38;
|
|
205
|
+
lockPointer(true, 'moving', cardEl);
|
|
206
|
+
bindDrag((ev) => {
|
|
178
207
|
const nx = x0 + (ev.clientX - sx);
|
|
179
208
|
const ny = y0 + (ev.clientY - sy);
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
};
|
|
186
|
-
window.addEventListener('pointermove', move);
|
|
187
|
-
window.addEventListener('pointerup', up);
|
|
209
|
+
// 至少留八十像素在视口里,别拖丢
|
|
210
|
+
setPos({
|
|
211
|
+
x: Math.round(Math.min(window.innerWidth - 80, Math.max(-w + 80, nx))),
|
|
212
|
+
y: Math.round(Math.min(window.innerHeight - 44, Math.max(-hh + 44, ny))),
|
|
213
|
+
});
|
|
214
|
+
}, 'moving', cardEl);
|
|
188
215
|
};
|
|
189
216
|
const noDrag = (e) => e.stopPropagation();
|
|
190
217
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-live2dwaifu",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "给 DSH 网页右下角请一个 Live2D 角色:会眨眼、会呼吸、视线跟着鼠标、点她有反应、说话时嘴动、心情变了眉毛跟着动。模型不用内置——谁装谁放自己的文件夹;支持自定义 .exp3.json 表情和 .motion3.json 动作,卡片能拖能缩,背景可换。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|