Skip to content

Commit aae5527

Browse files
Make the widget draggable
1 parent 4a371bd commit aae5527

File tree

5 files changed

+64
-0
lines changed

5 files changed

+64
-0
lines changed

README.en.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ You can refer to the source code of `dist/autoload.js` to see the available conf
4747
| `apiPath` | `string` | `https://live2d.fghrsh.net/api/` | API path, optional |
4848
| `cdnPath` | `string` | `https://fastly.jsdelivr.net/gh/fghrsh/live2d_api/` | CDN path, optional |
4949
| `tools` | `string[]` | see `autoload.js` | Buttons of the loaded tools, optional |
50+
| `drag` | `boolean` | `false` | Make the widget draggable |
5051
| `logLevel` | `string` | `error` | Log level: `error``info``trace` |
5152

5253
Among them, the parameters `apiPath` and `cdnPath` only need to set one of them. `apiPath` is the URL of the backend API, which can be set up and modified by yourself (there are many things to modify, not discussed here). You can refer to [live2d_api](https://github.com/fghrsh/live2d_api) for more information. On the other hand, `cdnPath` is used to load resources through CDN services like jsDelivr, which provides better stability.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
| `apiPath` | `string` | `https://live2d.fghrsh.net/api/` | API 路径,可选参数 |
4848
| `cdnPath` | `string` | `https://fastly.jsdelivr.net/gh/fghrsh/live2d_api/` | CDN 路径,可选参数 |
4949
| `tools` | `string[]` |`autoload.js` | 加载的小工具按钮,可选参数 |
50+
| `drag` | `boolean` | `false` | 支持拖动看板娘 |
5051
| `logLevel` | `string` | `error` | 日志等级,支持 `error``info``trace` |
5152

5253
其中,`apiPath``cdnPath` 两个参数设置其中一项即可。`apiPath` 是后端 API 的 URL,可以自行搭建,并增加模型(需要修改的内容比较多,此处不再赘述),可以参考 [live2d_api](https://github.com/fghrsh/live2d_api)。而 `cdnPath` 则是通过 jsDelivr 这样的 CDN 服务加载资源,更加稳定。

src/drag.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
function registerDrag() {
2+
const element = document.getElementById('waifu');
3+
const canvas = document.getElementById('live2d');
4+
if (!element || !canvas) return;
5+
let winWidth = window.innerWidth,
6+
winHeight = window.innerHeight;
7+
const imgWidth = element.offsetWidth,
8+
imgHeight = element.offsetHeight;
9+
// 在待拖拽的元素上绑定鼠标按下事件
10+
element.addEventListener('mousedown', event => {
11+
if (event.button === 2) {
12+
// 右键,直接返回,不处理
13+
return;
14+
}
15+
if (event.target !== canvas) return;
16+
event.preventDefault()
17+
// 记录光标在图片按下时的坐标
18+
const _offsetX = event.offsetX,
19+
_offsetY = event.offsetY;
20+
// 绑定鼠标移动事件
21+
document.onmousemove = event => {
22+
// 获取光标在可视窗口中的坐标
23+
const _x = event.clientX,
24+
_y = event.clientY;
25+
// 计算拖动的图片的定位的位置
26+
let _left = _x - _offsetX,
27+
_top = _y - _offsetY;
28+
// 判断是否在窗口范围内
29+
if (_top < 0) { // 上
30+
_top = 0;
31+
} else if (_top >= winHeight - imgHeight) { // 下
32+
_top = winHeight - imgHeight;
33+
}
34+
if (_left < 0) { // 左
35+
_left = 0;
36+
} else if (_left >= winWidth - imgWidth) { // 右
37+
_left = winWidth - imgWidth;
38+
}
39+
// 设置拖动过程中元素的定位
40+
element.style.top = _top + 'px';
41+
element.style.left = _left + 'px';
42+
}
43+
// 绑定鼠标弹起事件
44+
document.onmouseup = () => {
45+
document.onmousemove = null;
46+
}
47+
});
48+
// 当浏览器的窗口大小被改变时重设宽高
49+
window.onresize = () => {
50+
winWidth = window.innerWidth;
51+
winHeight = window.innerHeight;
52+
}
53+
}
54+
55+
export default registerDrag;

src/types/config.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ interface Config {
1818
* @type {string[] | undefined}
1919
*/
2020
tools?: string[];
21+
/**
22+
* 支持拖动看板娘。
23+
* @type {boolean | undefined}
24+
*/
25+
drag?: boolean;
2126
/**
2227
* 日志的等级。
2328
* @type {LogLevel | undefined}

src/widget.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import showMessage from './message.js';
88
import randomSelection from './utils.js';
99
import tools from './tools.js';
1010
import logger from './logger.js';
11+
import registerDrag from './drag.js';
1112

1213
function registerTools(model: ModelManager, config: Config) {
1314
(tools as Tools)['switch-model'].callback = () => model.loadOtherModel();
@@ -185,6 +186,7 @@ async function loadWidget(config: Config) {
185186
</div>`,
186187
);
187188
registerTools(model, config);
189+
if (config.drag) registerDrag();
188190
await initModel(model, config);
189191
document.getElementById('waifu')!.style.bottom = '0';
190192
}

0 commit comments

Comments
 (0)