├── .eslintrc.json
├── .gitignore
├── .vscode
├── extensions.json
├── launch.json
├── settings.json
└── tasks.json
├── .vscodeignore
├── .yarnrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── live2dExtraConfig.json
├── logo.png
├── media
├── main.css
├── main.js
└── vscode.css
├── package.json
├── res
└── live2d
│ ├── assets
│ ├── Ava.png
│ ├── Diana.png
│ ├── Eileen.png
│ ├── au.png
│ ├── beijixing.png
│ ├── border.png
│ ├── chong.jpg
│ ├── jellyfish.png
│ ├── jiaxintang.png
│ ├── naiqilin.png
│ ├── pierce.png
│ ├── pin.png
│ ├── skate.png
│ └── yigehun.png
│ ├── config.json
│ ├── index.html
│ ├── lib
│ ├── background.js
│ ├── live2d_display
│ │ ├── index.min.js
│ │ ├── live2d.min.js
│ │ ├── live2dcubismcore.min.js
│ │ └── pixi.min.js
│ ├── load.js
│ └── pio
│ │ ├── avatar.png
│ │ ├── pio.css
│ │ ├── pio.js
│ │ └── pio_sdk4.js
│ └── models
│ ├── Ava
│ ├── Ava.4096
│ │ └── texture_00.png
│ ├── Ava.moc3
│ ├── Ava.model3.json
│ ├── Ava.physics3.json
│ ├── motions
│ │ ├── Ava_idle.motion3.json
│ │ ├── Ava_shake01.motion3.json
│ │ ├── Ava_shake02.motion3.json
│ │ ├── Ava_tap01.motion3.json
│ │ ├── Ava_tap02.motion3.json
│ │ ├── Ava_tap03.motion3.json
│ │ ├── Ava_tap04.motion3.json
│ │ ├── Ava_tap05.motion3.json
│ │ ├── Ava_tap06.motion3.json
│ │ ├── Ava_tap07.motion3.json
│ │ ├── Ava_tap08.motion3.json
│ │ ├── Ava_tap09.motion3.json
│ │ ├── Ava_tap10.motion3.json
│ │ └── Ava_tap11.motion3.json
│ ├── raw.ex.json
│ ├── raw.model3.json
│ └── raw.preview.png
│ └── Diana
│ ├── Diana.4096
│ └── texture_00.png
│ ├── Diana.moc3
│ ├── Diana.model3.json
│ ├── Diana.physics3.json
│ ├── audio
│ └── jiaxintang-nouse.aac
│ ├── motions
│ ├── Diana_idle.motion3.json
│ ├── Diana_tap01.motion3.json
│ ├── Diana_tap02.motion3.json
│ ├── Diana_tap03.motion3.json
│ ├── Diana_tap04.motion3.json
│ ├── Diana_tap05.motion3.json
│ ├── Diana_tap06.motion3.json
│ ├── Diana_tap07.motion3.json
│ ├── Diana_tap08.motion3.json
│ ├── Diana_tap09.motion3.json
│ ├── Diana_tap10.motion3.json
│ └── Diana_tap11.motion3.json
│ ├── raw.ex.json
│ ├── raw.model3.json
│ └── raw.preview.png
├── src
├── extension.ts
├── live2dModify
│ ├── Dom.ts
│ ├── FileType.ts
│ ├── Main.ts
│ ├── getJs.ts
│ ├── index.ts
│ ├── uninstall.ts
│ ├── version.ts
│ └── vsHelp.ts
├── live2dView
│ └── index.ts
└── test
│ ├── runTest.ts
│ └── suite
│ ├── extension.test.ts
│ └── index.ts
├── tsconfig.json
├── vsc-extension-quickstart.md
└── yarn.lock
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "parser": "@typescript-eslint/parser",
4 | "parserOptions": {
5 | "ecmaVersion": 6,
6 | "sourceType": "module"
7 | },
8 | "plugins": [
9 | "@typescript-eslint"
10 | ],
11 | "rules": {
12 | "@typescript-eslint/naming-convention": "warn",
13 | "@typescript-eslint/semi": "warn",
14 | "curly": "warn",
15 | "eqeqeq": "warn",
16 | "no-throw-literal": "warn",
17 | "semi": "off",
18 | "@typescript-eslint/no-unused-vars": 0,
19 | "@typescript-eslint/no-explicit-any": 0,
20 | "@typescript-eslint/explicit-module-boundary-types": 0,
21 | "@typescript-eslint/no-non-null-assertion": 0,
22 | },
23 | "ignorePatterns": [
24 | "out",
25 | "dist",
26 | "**/*.d.ts"
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 | dist
3 | node_modules
4 | .vscode-test/
5 | *.vsix
6 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // See http://go.microsoft.com/fwlink/?LinkId=827846
3 | // for the documentation about the extensions.json format
4 | "recommendations": [
5 | "dbaeumer.vscode-eslint"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | // A launch configuration that compiles the extension and then opens it inside a new window
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | {
6 | "version": "0.2.0",
7 | "configurations": [
8 | {
9 | "name": "Run Extension",
10 | "type": "extensionHost",
11 | "request": "launch",
12 | "args": [
13 | "--extensionDevelopmentPath=${workspaceFolder}"
14 | ],
15 | "outFiles": [
16 | "${workspaceFolder}/out/**/*.js"
17 | ],
18 | "preLaunchTask": "${defaultBuildTask}"
19 | },
20 | {
21 | "name": "Extension Tests",
22 | "type": "extensionHost",
23 | "request": "launch",
24 | "args": [
25 | "--extensionDevelopmentPath=${workspaceFolder}",
26 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
27 | ],
28 | "outFiles": [
29 | "${workspaceFolder}/out/test/**/*.js"
30 | ],
31 | "preLaunchTask": "${defaultBuildTask}"
32 | }
33 | ]
34 | }
35 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | // Place your settings in this file to overwrite default and user settings.
2 | {
3 | "files.exclude": {
4 | "out": false // set this to true to hide the "out" folder with the compiled JS files
5 | },
6 | "search.exclude": {
7 | "out": true // set this to false to include "out" folder in search results
8 | },
9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts
10 | "typescript.tsc.autoDetect": "off"
11 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | // See https://go.microsoft.com/fwlink/?LinkId=733558
2 | // for the documentation about the tasks.json format
3 | {
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "type": "npm",
8 | "script": "watch",
9 | "problemMatcher": "$tsc-watch",
10 | "isBackground": true,
11 | "presentation": {
12 | "reveal": "never"
13 | },
14 | "group": {
15 | "kind": "build",
16 | "isDefault": true
17 | }
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/.vscodeignore:
--------------------------------------------------------------------------------
1 | .vscode/**
2 | .vscode-test/**
3 | src/**
4 | .gitignore
5 | .yarnrc
6 | vsc-extension-quickstart.md
7 | **/tsconfig.json
8 | **/.eslintrc.json
9 | **/*.map
10 | **/*.ts
11 |
--------------------------------------------------------------------------------
/.yarnrc:
--------------------------------------------------------------------------------
1 | --ignore-engines true
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## ver1.1.1
2 | fix: 随vscode更新版本调整,修复无法运行问题
3 | 保留了上次的更新内容和版本
4 |
5 | ## ver1.0.1
6 | fix: 更新部分失效网站信息
7 |
8 | ## ver1.0.0
9 | fix: 随vscode更新版本调整,修复无法运行问题
10 |
11 | ## ver0.1.12
12 | fix: 图标改成本地文件
13 |
14 | ## ver0.1.11
15 | fix: 修改背景图样式时,当前背景图丢失问题
16 |
17 | ## ver0.1.10
18 | feat: 背景图操作添加下载功能 + fix 因为cdn资源可能导致模型加载过慢bug
19 |
20 | ## ver0.1.8
21 | feat: 背景图操作添加配置属性:不透明度和背景图大小
22 |
23 | ## ver0.1.7
24 | fix: 优化点击穿透的处理,处于穿透状态是,右上角的操作栏不会隐藏
25 |
26 | ## ver0.1.6
27 | fix: 修复vscode 1.63.0版本 控制面板失效问题 + 随机背景图范围扩大
28 |
29 | ## ver0.1.5
30 | fix: 溜冰场内容不生效bug修复
31 |
32 | ## ver0.1.4
33 | fix: 溜冰场内容补充
34 |
35 | ## ver0.1.3
36 | fix: 嘉然语音测试添加默认动作
37 |
38 | ## ver0.1.2
39 | fix: 语音测试文件中文更名为英文,中文识别有bug
40 |
41 | ## ver0.1.1
42 | 补充readme介绍,修复 mac系统 容易拖拽失效bug
43 |
44 | ## ver0.1.0
45 | asoul-live2d 可初步使用 (如果有更多的意见或建议,欢迎提供。我会尽量完善)
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # A-SOUL-live2d 使用简介
2 | 嘉晚饭是真的! 赢!
3 | # 简单预览:
4 | 
5 |
6 | # 视频演示
7 |
8 | [插件介绍视频](https://www.bilibili.com/video/BV1mR4y1J7XL) 可以的话请给我点一下赞,能转发分享评论就最好了
9 | [我的b站账号](https://space.bilibili.com/5637882) 关注吗?也不是不行,(*^_^*)
10 |
11 | # 功能概况:
12 |
13 | 使用 iframe 嵌入页面中,实现效果。
14 |
15 | - 启动 live2d 看板娘视图(使用sdk: [pixi-live2d-display](https://github.com/guansss/pixi-live2d-display) [pio](https://paugram.com/))
16 | - 模型:嘉然、向晚(来源 b 站 up:[木果阿木果](https://space.bilibili.com/886695))
17 | - 整体操作
18 | - 拖拽位置
19 | - 缩放大小
20 | - 点击穿透
21 | - 随机切换背景图
22 | - 该功能可与 A-SOUl-background插件功能配合使用,本插件的背景图优先级会更高
23 | - 点击切换随机背景图 [图来源](https://asoul.cloud/pic)
24 | - 保存背景图
25 | - 加载保存背景图
26 | - 定时切换背景图
27 | - 背景图样式配置
28 | - 下载背景图
29 | - 随机溜冰场: 部分常见溜冰场,可能会有部分滞后
30 | - [asoul 导航](https://asoulworld.com/)入口
31 | - [一个魂二创](https://asoul.cloud/)入口
32 |
33 | # 使用介绍:
34 | ## TIPS: 当人物无法正常启动时,可尝试点击配置文件生成按钮。(vscode版本更新后也需要手动点一下生成按钮)
35 |
36 |
37 |
38 |
39 | 若依赖文件生成失败:
40 | - windows可尝试使用以管理者身份运行vscode,再点击生成按钮
41 | - mac 请留意是否将vscode从【下载】移动到【应用程序】里
42 | - mac 可通过【检查vscode是否可以更新】来判断软件是否处于可写的硬盘中
43 |
44 | ## Warns 警告:
45 |
46 | > **本插件是通过修改 vscode 的 js 文件的方式运行**
47 | > 所以会在初次安装,或者 vscode 升级的时候,出现以下提示,请选择 【不再提示】:
48 | >
49 | > **This extension works by editting the vscode's css file.**
50 | > So, a warning appears while the first time to install or vscode update. U can click the [never show again] to avoid it.
51 |
52 |
53 |
54 | This is the reason:
55 |
56 |
57 |
58 |
59 | ## 使用流程
60 |
61 |
62 |
63 |
64 |
65 | 本插件下载后,可以在侧边栏 “资源管理区” (第一个图标),的最下面看到新的抽屉层【LIVE2D-A-SOUL】。
66 | 初次打开该抽屉,会进行资源的配置,右下角提示需要重新启动vscode
67 |
68 |
69 |
70 |
71 |
72 |
73 | 再次打开该抽屉可以看到很多对应的功能按钮
74 | - 基本操作
75 | - 启动、关闭live2d: 字面意思,会启动看板人物,初始默认位置右下角
76 | - 保存当前配置: 在调整live2d大小缩放和拖拽位置后,可保存信息,下次启动时自动携带
77 | - 重置默认位置: 当前位置异常,无法拖拽移动时可重置使用【缩放大小也会重置】
78 | - 背景图
79 | - 点击切换: 点击按钮为人物右侧图标第二个
80 | - 保存背景图: 需要当前背景图存在才会生效。只能保存一份,再次点击会覆盖旧的
81 | - 加载背景图: 加载保存的背景图
82 | - 定时切换: 字面意思,可查看 切换按钮 是否旋转判断是否开启定时功能
83 | - 背景图样式配置
84 | - 下载背景图
85 | - 配置信息
86 | - 自启动: 字面意思,开启后。vscode启动,live2d自动启动
87 | - 定位依赖: 人物定位的依赖角
88 | - 补充配置
89 | - 插件依赖文件:
90 | - 插件依赖文件会在初次安装插件并启动时自动生成
91 | - 生成: live2d无法正常启动时,可尝试点击该按钮,强制重新生成覆盖配置信息
92 | - 移除: 卸载该插件前,请尽可能先执行该操作。 可移除插件对vscode文件的所有修改
93 |
94 | - 人物功能
95 | - 目光跟随鼠标 【缺点,暂时无法实现整个页面的跟随】
96 | - 点击互动
97 | - asoul粉丝导航网站入口
98 | - 切换背景图
99 | - 切换模型
100 | - 溜冰场
101 | - 音频测试
102 | - 一个魂二创网站入口
103 | - 模型来源
104 |
105 | ## 卸载流程
106 |
107 |
108 |
109 |
110 | 卸载该插件前,请尽可能先执行该操作。可移除插件对vscode文件的所有修改,恢复正常。
111 | 然后在插件列表卸载该插件
112 |
113 | # 额外要求 【如果想开启音频支持】
114 |
115 | 当前插件仅一个简单的语音测试,暂且可以不用考虑该功能
116 |
117 | [VS Code 使用的 Electron 版本不包含 ffmpeg](https://stackoverflow.com/a/51735036),需替换自带的 ffmpeg 动态链接库才能正常播放 (每次更新 VS Code 都需重新替换)
118 |
119 | _VS Code for Windows 1.31.0 - 1.35.1 不需替换,1.36.0 后无此待遇_
120 |
121 | _VS Code for macOS 1.43+ 替换后闪退[解决方案](https://github.com/nondanee/vsc-netease-music/issues/86#issuecomment-786546931)_
122 |
123 |
124 |
125 | 手动替换操作
126 |
127 |
128 | 首先需要查看 vscode 版本对应的electron版本, 然后下载对应系统的electron版本的压缩包,将里面的特定文件ffmpeg 解压到vscode的安装目录下,替换原vscode的ffmpeg文件
129 |
130 | [electron下载](https://npm.taobao.org/mirrors/electron/)
131 |
132 | #### Windows
133 | 界面左上角 点击 help(帮助) => about(关于),弹窗可查看electron版本
134 | 下载 **electron-%version%-win32-x64.zip**
135 | 替换 `./ffmpeg.dll` 文件
136 | #### macOS
137 | 界面左上角 点击 code => about,弹窗可查看electron版本
138 | 下载 **electron-%version%-darwin-x64.zip**
139 | 替换 `./Electron.app/Contents/Frameworks/Electron\ Framework.framework/Libraries/libffmpeg.dylib`
140 | #### Linux
141 | 界面左上角 Help(帮助) → \rightarrow →About(关于)
142 | 下载 **electron-%version%-linux-x64.zip**
143 | 替换 `./libffmpeg.so`
144 |
145 |
146 |
147 |
148 | # 鸣谢
149 | [live2d-widget](https://github.com/stevenjoezhang/live2d-widget)
150 | [vscode-background](https://github.com/shalldie/vscode-background)
151 | [CharlesZ.vscode-live2d](https://marketplace.visualstudio.com/items?itemName=CharlesZ.vscode-live2d)
152 | [pixi-live2d-display](https://github.com/guansss/pixi-live2d-display)
153 | [pio](https://paugram.com/)
154 | [journey-ad](https://github.com/journey-ad)
155 |
156 | 还有乐于分享的一个魂们
157 | [asoul 导航](https://asoulworld.com/)
158 | [一个魂二创](https://asoul.cloud/)
159 | 部分小图标也来源b站一个魂们的分享
160 | 嘉然 向晚 模型:[木果阿木果](https://space.bilibili.com/886695)
161 |
162 | 请勿使用该项目涉及的资源进行商业盈利
163 |
--------------------------------------------------------------------------------
/live2dExtraConfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "溜冰场": [
3 | "https://space.bilibili.com/672328094",
4 | "https://space.bilibili.com/672346917",
5 | "https://space.bilibili.com/672353429",
6 | "https://space.bilibili.com/672342685",
7 | "https://space.bilibili.com/351609538",
8 | "https://www.bilibili.com/video/BV1FZ4y1F7HH",
9 | "https://www.bilibili.com/video/BV1FX4y1g7u8",
10 | "https://www.bilibili.com/video/BV1aK4y1P7Cg",
11 | "https://www.bilibili.com/video/BV17A411V7Uh",
12 | "https://www.bilibili.com/video/BV1AV411v7er",
13 | "https://www.bilibili.com/video/BV1564y1173Q",
14 | "https://www.bilibili.com/video/BV1MX4y1N75X",
15 | "https://www.bilibili.com/video/BV17h411U71w",
16 | "https://www.bilibili.com/video/BV1ry4y1Y71t",
17 | "https://www.bilibili.com/video/BV1Sy4y1n7c4",
18 | "https://www.bilibili.com/video/BV1PN411X7QW",
19 | "https://www.bilibili.com/video/BV1Dp4y1H7iB",
20 | "https://www.bilibili.com/video/BV1bi4y1P7Eh",
21 | "https://www.bilibili.com/video/BV1vQ4y1Z7C2",
22 | "https://www.bilibili.com/video/BV1oU4y1h7Sc",
23 | "https://www.bilibili.com/video/BV1M64y1a7zh",
24 | "https://www.bilibili.com/video/BV1L5411w7eM",
25 | "https://www.bilibili.com/video/BV1HU4y1L7cF",
26 | "https://www.bilibili.com/video/BV1Pq4y1Z7aa",
27 | "https://www.bilibili.com/video/BV1x64y1Y7JR",
28 | "https://www.bilibili.com/video/BV1NL4y1a7KM",
29 | "https://www.bilibili.com/video/BV1n44y1b7G2",
30 | "https://www.bilibili.com/video/BV1EQ4y1z7WL",
31 | "https://www.bilibili.com/video/BV1sv411u78Q",
32 | "https://www.bilibili.com/video/BV1Lv411N7Bm",
33 | "https://www.bilibili.com/video/BV1eo4y1S79a",
34 | "https://www.bilibili.com/video/BV1Rq4y1p7sY",
35 | "https://www.bilibili.com/video/BV1T5411T7u8",
36 | "https://www.bilibili.com/video/BV1DU4y15767",
37 | "https://www.bilibili.com/video/BV1c5411u7Zv",
38 | "https://www.bilibili.com/video/BV1m54y1V7mX",
39 | "https://www.bilibili.com/video/BV1a44y1z71P",
40 | "https://www.bilibili.com/video/BV1sV41177qM",
41 | "https://www.bilibili.com/video/BV1go4y1y7kV",
42 | "https://www.bilibili.com/video/BV1JM4y157Tg",
43 | "https://www.bilibili.com/video/BV1e44y147nb",
44 | "https://www.bilibili.com/video/BV1Ur4y1y7RP",
45 | "https://www.bilibili.com/video/BV1kQ4y1i7LG",
46 | "https://www.bilibili.com/video/BV1Jq4y157r1",
47 | "https://www.bilibili.com/video/BV14q4y1K71L",
48 | "https://www.bilibili.com/video/BV1ty4y1V7k4",
49 | "https://www.bilibili.com/video/BV1B54y1V7Ta",
50 | "https://www.bilibili.com/video/BV1Mh411Y7vS",
51 | "https://www.bilibili.com/video/BV1L64y1z7Df",
52 | "https://www.bilibili.com/video/BV1p5411w71j",
53 | "https://www.bilibili.com/video/BV1b64y117Kk",
54 | "https://www.bilibili.com/video/BV1RB4y1T723",
55 | "https://www.bilibili.com/video/BV1HP4y1Y7kq",
56 | "https://www.bilibili.com/video/BV1vL4y1z7Fh",
57 | "https://www.bilibili.com/video/BV1764y1q7JA",
58 | "https://www.bilibili.com/video/BV1Kq4y1n7p4",
59 | "https://www.bilibili.com/video/BV1JA411G7Dk",
60 | "https://www.bilibili.com/video/BV14A411P7Tg",
61 | "https://www.bilibili.com/video/BV1vQ4y1Z7C2",
62 | "https://www.bilibili.com/video/BV1TV411H7uf",
63 | "https://www.bilibili.com/video/BV1kq4y1W7hW",
64 | "https://www.bilibili.com/video/BV1Eb4y1C7oJ",
65 | "https://www.bilibili.com/video/BV1dL411n7sY",
66 | "https://www.bilibili.com/video/BV18h411z7gh",
67 | "https://www.bilibili.com/video/BV1sv411j7W8",
68 | "https://www.bilibili.com/video/BV1JP4y1x73T",
69 | "https://www.bilibili.com/video/BV1CM4y1V7ho",
70 | "https://www.bilibili.com/video/BV1444y1z7EV",
71 | "https://www.bilibili.com/video/BV1Ah41167DS",
72 | "https://www.bilibili.com/video/BV1FN411o7nt",
73 | "https://www.bilibili.com/video/BV1Rb4y1k7F7",
74 | "https://www.bilibili.com/video/BV1AB4y1g7CQ",
75 | "https://www.bilibili.com/video/BV1Gq4y1W7wT",
76 | "https://www.bilibili.com/video/BV1z3411y7nP",
77 | "https://www.bilibili.com/video/BV14h411B7mE",
78 | "https://www.bilibili.com/video/BV1Uy4y1j7rN",
79 | "https://www.bilibili.com/video/BV1NX4y1w7JN",
80 | "https://www.bilibili.com/video/BV1464y1W7gv",
81 | "https://www.bilibili.com/video/BV19V411H7tn",
82 | "https://www.bilibili.com/video/BV1L54y1n7yA",
83 | "https://www.bilibili.com/video/BV1f64y1k7Ff",
84 | "https://www.bilibili.com/video/BV12b4y1X7S8",
85 | "https://www.bilibili.com/video/BV1QQ4y1272S",
86 | "https://www.bilibili.com/video/BV12f4y1F7jD",
87 | "https://www.bilibili.com/video/BV1sM4y1g7Dg",
88 | "https://www.bilibili.com/video/BV1tA411V7b5",
89 | "https://www.bilibili.com/video/BV15V411E7hr",
90 | "https://www.bilibili.com/video/BV1J64y1m7Eu",
91 | "https://www.bilibili.com/video/BV1W54y1V7bV",
92 | "https://www.bilibili.com/video/BV15v411e7qa",
93 | "https://www.bilibili.com/video/BV1gy4y147vp",
94 | "https://www.bilibili.com/video/BV1DA411c7U3",
95 | "https://www.bilibili.com/video/BV11b4y167Gc",
96 | "https://www.bilibili.com/video/BV1bQ4y1d7n6",
97 | "https://www.bilibili.com/video/BV1X5411K7W5",
98 | "https://www.bilibili.com/video/BV12V411E7sn",
99 | "https://www.bilibili.com/video/BV1wv411K7LT",
100 | "https://www.bilibili.com/video/BV1Eq4y197ho",
101 | "https://www.bilibili.com/video/BV1aP4y1s7Wy",
102 | "https://www.bilibili.com/video/BV1Y64y1U7FZ"
103 | ]
104 | }
105 |
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/logo.png
--------------------------------------------------------------------------------
/media/main.css:
--------------------------------------------------------------------------------
1 | html {
2 | box-sizing: border-box;
3 | font-size: 12px;
4 | }
5 |
6 | *,
7 | *:before,
8 | *:after {
9 | box-sizing: inherit;
10 | }
11 |
12 | body,
13 | h1,
14 | h2,
15 | h3,
16 | h4,
17 | h5,
18 | h6,
19 | p,
20 | ol,
21 | ul {
22 | margin: 0;
23 | padding: 0;
24 | font-weight: normal;
25 | }
26 |
27 | body {
28 | background-color: transparent;
29 | }
30 |
31 |
32 | /* new */
33 | .common-title {
34 | font-size: 16px;
35 | font-weight: 600;
36 | }
37 |
38 | .common-subtitle {
39 | font-size: 14px;
40 | font-weight: 500;
41 | }
42 |
43 | .common-bar {
44 | display: flex;
45 | flex-wrap: wrap;
46 | justify-content: space-between;
47 | align-items: center;
48 | }
49 |
50 | .common-bar+.common-bar {
51 | margin-top: 4px;
52 | }
53 |
54 | .common-button {
55 | min-width: 100px;
56 | width: 45%;
57 | margin-bottom: 6px;
58 | }
59 |
60 | /* 下载图片样式 */
61 | .download-img {
62 | width: 19%;
63 | cursor: pointer;
64 | }
65 |
66 | .download-img:hover {
67 | width: 20%;
68 | border: solid 1px white;
69 | }
--------------------------------------------------------------------------------
/media/main.js:
--------------------------------------------------------------------------------
1 | const vscode = acquireVsCodeApi();
2 | const MainOrigin = "vscode-file://vscode-app";
3 | function generateResources() {
4 | vscode.postMessage({ type: 'generateResources' });
5 | }
6 |
7 | function removeResources() {
8 | vscode.postMessage({ type: 'removeResources' });
9 | }
10 |
11 | function sendCommand(type, data) {
12 | window.top.postMessage({ type, data }, MainOrigin);
13 | }
14 |
15 | const receiveMessage = (event) => {
16 | const origin = event.origin || event.originalEvent.origin;
17 | if (origin !== MainOrigin)
18 | return;
19 | const { type, data } = event?.data || {};
20 | if (type)
21 | switch (type) {
22 | case 'live2d-asoul-initDownloadBackground':
23 | initDownloadBackground(data);
24 | break;
25 | default:
26 | break;
27 | }
28 | }
29 | window.addEventListener('message', receiveMessage, false);
30 |
31 | let background_time = 30;
32 | let background_opacity = 0.2;
33 | let background_mode = 'cover';
34 |
35 | function handleChangeTime(e) {
36 | const value = Number(e.target.value);
37 | if (value > 0) {
38 | background_time = value;
39 | }
40 | else e.target.value = '0.5';
41 | }
42 |
43 | function handleChangeOpacity(e) {
44 | let value = e.target.value;
45 | value = value === 0 ? 0 : value ? Number(value) : 0.2;
46 | if (value >= 0 && value <= 1) {
47 | background_opacity = value;
48 | }
49 | }
50 |
51 | function handleChangeMode(e) {
52 | background_mode = e.target.value;
53 | }
54 |
55 | function setEleBackgroundConfig(input, select) {
56 | const eleInput = document.getElementById('background-opacity-input');
57 | eleInput && (eleInput.value = input);
58 | background_opacity = input === undefined ? 0.2 : input;
59 | const eleSelect = document.getElementById('background-mode-select');
60 | eleSelect && (eleSelect.value = select || '');
61 | background_mode = select ? select : 'cover';
62 | }
63 |
64 | function restoreBgConfig() {
65 | setEleBackgroundConfig(undefined, '');
66 | modifyBackgroundConfig();
67 | }
68 |
69 | function modifyBackgroundConfig() {
70 | const config = { opacity: background_opacity, backgroundSize: background_mode };
71 | sendCommand('live2d-asoul-modifyBackgroundConfig', config);
72 | }
73 |
74 | function openBackgroundSetTime() {
75 | sendCommand('live2d-asoul-openBackgroundSetTime', background_time);
76 | }
77 |
78 | function closeBackgroundSetTime() {
79 | sendCommand('live2d-asoul-closeBackgroundSetTime');
80 | }
81 |
82 | function openAutoLodash() {
83 | sendCommand('live2d-asoul-openAutoLodash');
84 | }
85 | function closeAutoLodash() {
86 | sendCommand('live2d-asoul-closeAutoLodash');
87 | }
88 | function lodashLive2d() {
89 | sendCommand('live2d-asoul-lodash');
90 | }
91 | function closeLive2d() {
92 | sendCommand('live2d-asoul-close');
93 | }
94 | function setAnchor(type) {
95 | sendCommand('live2d-asoul-setAnchor', type);
96 | }
97 | function saveCurrentConfig() {
98 | sendCommand('live2d-asoul-saveCurrentConfig');
99 | }
100 | function resetPosition() {
101 | sendCommand('live2d-asoul-resetPosition');
102 | }
103 | function saveBackground() {
104 | sendCommand('live2d-asoul-saveBackground');
105 | }
106 | function loadBackground() {
107 | sendCommand('live2d-asoul-loadBackground');
108 | }
109 | // 背景图下载相关
110 | function downloadBackground() {
111 | sendCommand('live2d-asoul-downloadBackground');
112 | }
113 | function removeDownloadBackground() {
114 | const ele = document.getElementById('currentBackground');
115 | while (ele.firstChild) {
116 | ele.removeChild(ele.firstChild);
117 | }
118 | }
119 | function initDownloadBackground(list) {
120 | const ele = document.getElementById('currentBackground');
121 | while (ele.firstChild) {
122 | ele.removeChild(ele.firstChild);
123 | }
124 | list?.forEach(obj => {
125 | let eleImg = document.createElement("img");
126 | eleImg.src = obj.img;
127 | eleImg.classList.add('download-img')
128 | eleImg.onclick = () => downloadIamge(obj.img, obj.author);
129 | ele.appendChild(eleImg);
130 | })
131 | }
132 | //下载图片地址和图片名
133 | function downloadIamge(imgsrc, filename) {
134 | let image = new Image();
135 | // 解决跨域 Canvas 污染问题
136 | image.setAttribute("crossOrigin", "anonymous");
137 | image.onload = function () {
138 | let canvas = document.createElement("canvas");
139 | canvas.width = image.width;
140 | canvas.height = image.height;
141 | let context = canvas.getContext("2d");
142 | context.drawImage(image, 0, 0, image.width, image.height);
143 | let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
144 | let a = document.createElement("a"); // 生成一个a元素
145 | let event = new MouseEvent("click"); // 创建一个单击事件
146 | a.download = (filename || "photo") + new Date().getTime().toString(); // 设置图片名称
147 | a.href = url; // 将生成的URL设置为a.href属性
148 | a.dispatchEvent(event); // 触发a的单击事件
149 | };
150 | image.src = imgsrc;
151 | }
152 |
153 |
--------------------------------------------------------------------------------
/media/vscode.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --container-paddding: 20px;
3 | --input-padding-vertical: 6px;
4 | --input-padding-horizontal: 4px;
5 | --input-margin-vertical: 4px;
6 | --input-margin-horizontal: 0;
7 | }
8 |
9 | body {
10 | padding: 0 var(--container-paddding);
11 | color: var(--vscode-foreground);
12 | font-size: var(--vscode-font-size);
13 | font-weight: var(--vscode-font-weight);
14 | font-family: var(--vscode-font-family);
15 | background-color: var(--vscode-editor-background);
16 | }
17 |
18 | ol,
19 | ul {
20 | padding-left: var(--container-paddding);
21 | }
22 |
23 | body > *,
24 | form > * {
25 | margin-block-start: var(--input-margin-vertical);
26 | margin-block-end: var(--input-margin-vertical);
27 | }
28 |
29 | *:focus {
30 | outline-color: var(--vscode-focusBorder) !important;
31 | }
32 |
33 | a {
34 | color: var(--vscode-textLink-foreground);
35 | }
36 |
37 | a:hover,
38 | a:active {
39 | color: var(--vscode-textLink-activeForeground);
40 | }
41 |
42 | code {
43 | font-size: var(--vscode-editor-font-size);
44 | font-family: var(--vscode-editor-font-family);
45 | }
46 |
47 | button {
48 | border: none;
49 | padding: var(--input-padding-vertical) var(--input-padding-horizontal);
50 | width: 100%;
51 | text-align: center;
52 | outline: 1px solid transparent;
53 | outline-offset: 2px !important;
54 | color: var(--vscode-button-foreground);
55 | background: var(--vscode-button-background);
56 | }
57 |
58 | button:hover {
59 | cursor: pointer;
60 | background: var(--vscode-button-hoverBackground);
61 | }
62 |
63 | button:focus {
64 | outline-color: var(--vscode-focusBorder);
65 | }
66 |
67 | button.secondary {
68 | color: var(--vscode-button-secondaryForeground);
69 | background: var(--vscode-button-secondaryBackground);
70 | }
71 |
72 | button.secondary:hover {
73 | background: var(--vscode-button-secondaryHoverBackground);
74 | }
75 |
76 | input:not([type='checkbox']),
77 | textarea {
78 | display: block;
79 | width: 100%;
80 | border: none;
81 | font-family: var(--vscode-font-family);
82 | padding: var(--input-padding-vertical) var(--input-padding-horizontal);
83 | color: var(--vscode-input-foreground);
84 | outline-color: var(--vscode-input-border);
85 | background-color: var(--vscode-input-background);
86 | }
87 |
88 | input::placeholder,
89 | textarea::placeholder,
90 | select::placeholder {
91 | color: var(--vscode-input-placeholderForeground);
92 | }
93 |
94 |
95 | select {
96 | display: block;
97 | width: 100%;
98 | border: none;
99 | font-family: var(--vscode-font-family);
100 | padding: var(--input-padding-vertical) var(--input-padding-horizontal);
101 | color: var(--vscode-input-foreground);
102 | outline-color: var(--vscode-input-border);
103 | background-color: var(--vscode-input-background);
104 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vscode-live2d",
3 | "displayName": "A-SOUL-live2d",
4 | "description": "vscode插件-live2d看板娘。 默认角色会设置为asoul的嘉然",
5 | "version": "1.1.1",
6 | "author": "TheSecondAkari",
7 | "publisher": "TheSecondAkari",
8 | "license": "MIT",
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/TheSecondAkari/vscode-live2d"
12 | },
13 | "engines": {
14 | "vscode": "^1.95.3"
15 | },
16 | "keywords": [
17 | "vscode看板娘",
18 | "看板娘",
19 | "kanbanniang",
20 | "live2d",
21 | "asoul",
22 | "a-soul",
23 | "vtuber",
24 | "国内顶级偶像",
25 | "虚拟偶像"
26 | ],
27 | "icon": "logo.png",
28 | "categories": [
29 | "Other"
30 | ],
31 | "activationEvents": [
32 | "onView:vscode-live2d.live2dView"
33 | ],
34 | "main": "./out/extension.js",
35 | "contributes": {
36 | "views": {
37 | "explorer": [
38 | {
39 | "type": "webview",
40 | "id": "vscode-live2d.live2dView",
41 | "name": "live2d-A-Soul"
42 | }
43 | ]
44 | },
45 | "configuration": [
46 | {
47 | "title": "看板娘配置",
48 | "type": "Object",
49 | "properties": {
50 | "vscode-live2d-asoul.enabled": {
51 | "type": "boolean",
52 | "default": true,
53 | "description": "是否启用live2d-asoul"
54 | }
55 | }
56 | }
57 | ]
58 | },
59 | "scripts": {
60 | "vscode:prepublish": "yarn run compile",
61 | "compile": "tsc -p ./",
62 | "watch": "tsc -watch -p ./",
63 | "pretest": "yarn run compile && yarn run lint",
64 | "lint": "eslint src --ext ts",
65 | "test": "node ./out/test/runTest.js",
66 | "build": "vsce package"
67 | },
68 | "devDependencies": {
69 | "@types/vscode": "^1.47.0",
70 | "@types/glob": "^7.1.4",
71 | "@types/mocha": "^9.0.0",
72 | "@types/node": "14.x",
73 | "@typescript-eslint/eslint-plugin": "^4.31.1",
74 | "@typescript-eslint/parser": "^4.31.1",
75 | "eslint": "^7.32.0",
76 | "glob": "^7.1.7",
77 | "mocha": "^9.1.1",
78 | "typescript": "^4.4.3",
79 | "@vscode/test-electron": "^1.6.2"
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/res/live2d/assets/Ava.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/Ava.png
--------------------------------------------------------------------------------
/res/live2d/assets/Diana.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/Diana.png
--------------------------------------------------------------------------------
/res/live2d/assets/Eileen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/Eileen.png
--------------------------------------------------------------------------------
/res/live2d/assets/au.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/au.png
--------------------------------------------------------------------------------
/res/live2d/assets/beijixing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/beijixing.png
--------------------------------------------------------------------------------
/res/live2d/assets/border.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/border.png
--------------------------------------------------------------------------------
/res/live2d/assets/chong.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/chong.jpg
--------------------------------------------------------------------------------
/res/live2d/assets/jellyfish.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/jellyfish.png
--------------------------------------------------------------------------------
/res/live2d/assets/jiaxintang.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/jiaxintang.png
--------------------------------------------------------------------------------
/res/live2d/assets/naiqilin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/naiqilin.png
--------------------------------------------------------------------------------
/res/live2d/assets/pierce.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/pierce.png
--------------------------------------------------------------------------------
/res/live2d/assets/pin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/pin.png
--------------------------------------------------------------------------------
/res/live2d/assets/skate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/skate.png
--------------------------------------------------------------------------------
/res/live2d/assets/yigehun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/assets/yigehun.png
--------------------------------------------------------------------------------
/res/live2d/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "firstload": false
3 | }
--------------------------------------------------------------------------------
/res/live2d/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/res/live2d/lib/background.js:
--------------------------------------------------------------------------------
1 | // 背景图样式基础样式
2 | let backgroundCssNode;
3 | const typeList = [1, 2, 3, 4, 1, 2, 4, 1, 4]; // sort 参数的随机 1是浏览量,2是分享数,3是新发布,4是热门
4 | const pageList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
5 | var currentImgs = undefined;
6 | const IMGKEY = 'live2d-asoul-background';
7 | const BgConfKey = 'live2d-asoul-background-config';
8 | let backgroundConfig = JSON.parse(localStorage.getItem(BgConfKey) || '{}');
9 |
10 | const getRandom = (arr) => arr[Math.floor((Math.random() * arr.length))];
11 |
12 | const getRandomArray = (arr, num) => {
13 | let sData = arr.slice(0), i = arr.length, min = i - num, item, index;
14 | while (i-- > min) {
15 | index = Math.floor((i + 1) * Math.random());
16 | item = sData[index];
17 | sData[index] = sData[i];
18 | sData[i] = item;
19 | }
20 | return sData.slice(min);
21 | }
22 |
23 | function addBackgroundStyle(styleContent) {
24 | removeBackgroundStyle(); //先清除旧样式
25 | const topDocument = window.top.document;
26 | backgroundCssNode = topDocument.createElement('style');
27 | backgroundCssNode.appendChild(topDocument.createTextNode(styleContent))
28 | topDocument.head.appendChild(backgroundCssNode);
29 | }
30 |
31 | function removeBackgroundStyle() {
32 | if (backgroundCssNode) {
33 | backgroundCssNode.remove();
34 | backgroundCssNode = undefined;
35 | }
36 | }
37 |
38 | function getBackgroundStyleText(mainImgs, siderImgs) {
39 | const { opacity = 0.2, backgroundSize = 'cover' } = backgroundConfig;
40 | const commonStyle = `
41 | content: '';
42 | pointer-events: none;
43 | position: absolute;
44 | top: 0;
45 | left: 0;
46 | z-index: 99999;
47 | width: 100%;
48 | height: 100%;
49 | background-position: center center;
50 | background-repeat: no-repeat;
51 | background-size: ${backgroundSize};
52 | opacity:${opacity};
53 | `;
54 |
55 | const styleContent = `
56 | ${addMainImagesCss(mainImgs, commonStyle)}
57 | ${addSidebarImagesCss(siderImgs, commonStyle)}
58 | `;
59 |
60 | return styleContent;
61 | }
62 |
63 | function addMainImagesCss(images, commonStyle, loop) {
64 |
65 | // ------ 在前景图时使用 ::after ------
66 | const frontContent = '::after'; // useFront ? '::after' : '::before';
67 |
68 | // ------ 组合样式 ------
69 | const imageStyleContent = images
70 | .map((img, index) => {
71 | // ------ nth-child ------
72 | // nth-child(1)
73 | let nthChildIndex = index + 1 + '';
74 | // nth-child(3n + 1)
75 | if (loop) {
76 | nthChildIndex = `${images.length}n + ${nthChildIndex}`;
77 | }
78 |
79 | return (
80 | // code editor
81 | `[id="workbench.parts.editor"] .split-view-view:nth-child(${nthChildIndex}) ` +
82 | `.editor-container .editor-instance>.monaco-editor ` +
83 | `.overflow-guard>.monaco-scrollable-element${frontContent}{background-image: url('${img}') !important;${commonStyle}}` +
84 | '\n' +
85 | // home screen
86 | `[id="workbench.parts.editor"] .split-view-view:nth-child(${nthChildIndex}) ` +
87 | `.empty::before { background-image: url('${img}') !important;${commonStyle} }`
88 | );
89 | })
90 | .join('\n');
91 |
92 | const content = `
93 | ${imageStyleContent}
94 | [id="workbench.parts.editor"] .split-view-view .editor-container .editor-instance>.monaco-editor .overflow-guard>.monaco-scrollable-element>.monaco-editor-background{background: none;}
95 | `;
96 |
97 | return content;
98 | }
99 |
100 | const addSidebarImagesCss = function (images, commonStyle, loop) {
101 | const sidebarItems = [
102 | "workbench.view.explorer",
103 | "workbench.view.search",
104 | "workbench.view.scm",
105 | "workbench.view.debug",
106 | "workbench.view.extensions"
107 | ];
108 |
109 | // ------ 组合样式 ------
110 | const imageStyleContent = images
111 | .map((img, index) => {
112 | // ------ nth-child ------
113 | // nth-child(1)
114 | let nthChildIndex = index + 1 + '';
115 | // nth-child(3n + 1)
116 | if (loop) {
117 | nthChildIndex = `${images.length}n + ${nthChildIndex}`;
118 | }
119 | const Items = sidebarItems && sidebarItems.length ? sidebarItems : ['workbench.view.explorer'];
120 | // sidebar content css
121 | return (
122 | Items.map(
123 | id =>
124 | `[id="${id}"] .split-view-view:nth-child(${nthChildIndex}) ` +
125 | `.pane-body .monaco-list>.monaco-scrollable-element::before{background-image: url('${img}') !important;${commonStyle}}`
126 | ).join('\n') + '\n'
127 | );
128 | })
129 | .join('\n');
130 | return imageStyleContent;
131 | };
132 |
133 | function getAsoulImgs(callback) {
134 | fetch(`https://api.asoulfanart.com:9000/getPic?page=${getRandom(pageList)}&tag_id=0&sort=${getRandom(typeList)}&part=0&rank=0&ctime=0&type=1`, {
135 | cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
136 | credentials: "same-origin", // include, same-origin, *omit
137 | headers: {
138 | "user-agent": "Mozilla/4.0 MDN Example",
139 | "content-type": "application/json"
140 | },
141 | method: "GET", // *GET, POST, PUT, DELETE, etc.
142 | mode: "cors", // no-cors, cors, *same-origin
143 | redirect: "follow", // manual, *follow, error
144 | referrer: "no-referrer" // *client, no-referrer
145 | })
146 | .then(response => response.json())
147 | .then(function (myJson) {
148 | if (Array.isArray(myJson) && myJson.length > 0) {
149 | const imgs = myJson.map(item => ({ author: item.name || 'none', img: getRandom(item.pic_url).img_src }));
150 | const targets = getRandomArray(imgs, 10);
151 | callback && callback(targets);
152 | }
153 | });
154 | }
155 |
156 | // 切换背景的具体操作
157 | function changeAction(targets) {
158 | if (targets) {
159 | const imgs = targets.map(i => i.img);
160 | const sidebar = imgs.slice(0, 5);
161 | const coding = imgs.slice(5, 10);
162 | currentImgs = targets;
163 | const css = getBackgroundStyleText(sidebar, coding);
164 | addBackgroundStyle(css);
165 | }
166 | }
167 |
168 | // 设置背景图,从接口获取,随机设置
169 | const changeBackground = () => getAsoulImgs(changeAction)
170 |
171 | // 移除背景图
172 | function removeBackground() {
173 | removeBackgroundStyle();
174 | }
175 |
176 | // 保存背景图
177 | function saveBackground() {
178 | if (currentImgs)
179 | localStorage.setItem(IMGKEY, JSON.stringify(currentImgs));
180 | }
181 |
182 | // 加载背景图
183 | function loadBackground() {
184 | const str = localStorage.getItem(IMGKEY);
185 | if (str) {
186 | const imgs = JSON.parse(str);
187 | changeAction(typeof imgs[0] === 'string' ? imgs.map(img => ({ img })) : imgs);
188 | }
189 | }
190 |
191 | // 设置定时切换背景图
192 | let timer = undefined;
193 | function openBackgroundSetTime(time) {
194 | closeBackgroundSetTime();
195 | if (typeof time === 'number' && time > 0) {
196 | timer = setInterval(() => {
197 | changeBackground();
198 | }, 1000 * 60 * time)
199 | // 加入旋转样式
200 | document.getElementsByClassName('pio-background')[0].classList.add('normal-cycle');
201 | }
202 | }
203 |
204 | // 关闭定时切换背景图
205 | function closeBackgroundSetTime() {
206 | if (timer) {
207 | clearInterval(timer);
208 | timer = undefined;
209 | // 移除旋转样式
210 | document.getElementsByClassName('pio-background')[0].classList.remove('normal-cycle');
211 | }
212 | }
213 |
214 | // 修改背景图样式配置: 不透明度、适配模式
215 | function modifyBackgroundConfig(config) {
216 | backgroundConfig = config;
217 | localStorage.setItem(BgConfKey, JSON.stringify(config));
218 | if (currentImgs?.length) {
219 | changeAction(currentImgs)
220 | }
221 | }
--------------------------------------------------------------------------------
/res/live2d/lib/load.js:
--------------------------------------------------------------------------------
1 | // 通过读取远程配置文件,进行设置默认信息
2 | function getInitConfig(callback) {
3 | fetch(`https://cdn.jsdelivr.net/gh/TheSecondAkari/vscode-live2d@latest/live2dExtraConfig.json`, {
4 | cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
5 | credentials: "same-origin", // include, same-origin, *omit
6 | headers: {
7 | "user-agent": "Mozilla/4.0 MDN Example",
8 | },
9 | method: "GET", // *GET, POST, PUT, DELETE, etc.
10 | mode: "cors", // no-cors, cors, *same-origin
11 | redirect: "follow", // manual, *follow, error
12 | referrer: "no-referrer" // *client, no-referrer
13 | })
14 | .then(response => response.json())
15 | .then(function (myJson) {
16 | callback && callback(myJson)
17 | })
18 | .catch(e => {
19 | callback && callback()
20 | });
21 | }
22 |
23 | var 溜冰场;
24 |
25 | // ExtraInfo 是远程维护的配置信息
26 | getInitConfig((ExtraInfo) => {
27 | if (ExtraInfo) {
28 | const list = ExtraInfo["溜冰场"];
29 | if (Array.isArray(list) && list.length > 0) {
30 | 溜冰场 = list;
31 | }
32 | }
33 | })
34 |
35 | var 引流 = [
36 | "https://space.bilibili.com/672328094",
37 | "https://space.bilibili.com/672346917",
38 | "https://space.bilibili.com/672353429",
39 | "https://space.bilibili.com/672342685",
40 | "https://space.bilibili.com/351609538",
41 | "https://www.bilibili.com/video/BV1FZ4y1F7HH",
42 | "https://www.bilibili.com/video/BV1FX4y1g7u8",
43 | "https://www.bilibili.com/video/BV1aK4y1P7Cg",
44 | "https://www.bilibili.com/video/BV17A411V7Uh",
45 | "https://www.bilibili.com/video/BV1AV411v7er",
46 | "https://www.bilibili.com/video/BV1564y1173Q",
47 | "https://www.bilibili.com/video/BV1MX4y1N75X",
48 | "https://www.bilibili.com/video/BV17h411U71w",
49 | "https://www.bilibili.com/video/BV1ry4y1Y71t",
50 | "https://www.bilibili.com/video/BV1Sy4y1n7c4",
51 | "https://www.bilibili.com/video/BV1PN411X7QW",
52 | "https://www.bilibili.com/video/BV1Dp4y1H7iB",
53 | "https://www.bilibili.com/video/BV1bi4y1P7Eh",
54 | "https://www.bilibili.com/video/BV1vQ4y1Z7C2",
55 | "https://www.bilibili.com/video/BV1oU4y1h7Sc",
56 | "https://www.bilibili.com/video/BV1M64y1a7zh",
57 | "https://www.bilibili.com/video/BV1L5411w7eM",
58 | "https://www.bilibili.com/video/BV1HU4y1L7cF",
59 | "https://www.bilibili.com/video/BV1Pq4y1Z7aa",
60 | "https://www.bilibili.com/video/BV1x64y1Y7JR",
61 | "https://www.bilibili.com/video/BV1NL4y1a7KM",
62 | "https://www.bilibili.com/video/BV1n44y1b7G2",
63 | "https://www.bilibili.com/video/BV1EQ4y1z7WL",
64 | "https://www.bilibili.com/video/BV1sv411u78Q",
65 | "https://www.bilibili.com/video/BV1Lv411N7Bm",
66 | "https://www.bilibili.com/video/BV1eo4y1S79a",
67 | "https://www.bilibili.com/video/BV1Rq4y1p7sY",
68 | "https://www.bilibili.com/video/BV1T5411T7u8",
69 | "https://www.bilibili.com/video/BV1DU4y15767",
70 | "https://www.bilibili.com/video/BV1c5411u7Zv",
71 | "https://www.bilibili.com/video/BV1m54y1V7mX",
72 | "https://www.bilibili.com/video/BV1a44y1z71P",
73 | "https://www.bilibili.com/video/BV1sV41177qM",
74 | "https://www.bilibili.com/video/BV1go4y1y7kV",
75 | "https://www.bilibili.com/video/BV1JM4y157Tg",
76 | "https://www.bilibili.com/video/BV1e44y147nb",
77 | "https://www.bilibili.com/video/BV1Ur4y1y7RP",
78 | "https://www.bilibili.com/video/BV1kQ4y1i7LG",
79 | "https://www.bilibili.com/video/BV1Jq4y157r1",
80 | "https://www.bilibili.com/video/BV14q4y1K71L",
81 | "https://www.bilibili.com/video/BV1ty4y1V7k4",
82 | "https://www.bilibili.com/video/BV1B54y1V7Ta",
83 | "https://www.bilibili.com/video/BV1Mh411Y7vS",
84 | "https://www.bilibili.com/video/BV1L64y1z7Df",
85 | "https://www.bilibili.com/video/BV1p5411w71j",
86 | "https://www.bilibili.com/video/BV1b64y117Kk",
87 | "https://www.bilibili.com/video/BV1RB4y1T723",
88 | "https://www.bilibili.com/video/BV1HP4y1Y7kq",
89 | "https://www.bilibili.com/video/BV1vL4y1z7Fh",
90 | "https://www.bilibili.com/video/BV1764y1q7JA",
91 | "https://www.bilibili.com/video/BV1Kq4y1n7p4",
92 | "https://www.bilibili.com/video/BV1JA411G7Dk",
93 | "https://www.bilibili.com/video/BV14A411P7Tg",
94 | "https://www.bilibili.com/video/BV1vQ4y1Z7C2",
95 | "https://www.bilibili.com/video/BV1TV411H7uf",
96 | "https://www.bilibili.com/video/BV1kq4y1W7hW",
97 | "https://www.bilibili.com/video/BV1Eb4y1C7oJ",
98 | "https://www.bilibili.com/video/BV1dL411n7sY",
99 | "https://www.bilibili.com/video/BV18h411z7gh",
100 | "https://www.bilibili.com/video/BV1sv411j7W8",
101 | "https://www.bilibili.com/video/BV1JP4y1x73T",
102 | "https://www.bilibili.com/video/BV1CM4y1V7ho",
103 | "https://www.bilibili.com/video/BV1444y1z7EV",
104 | "https://www.bilibili.com/video/BV1Ah41167DS",
105 | "https://www.bilibili.com/video/BV1FN411o7nt",
106 | "https://www.bilibili.com/video/BV1Rb4y1k7F7",
107 | "https://www.bilibili.com/video/BV1AB4y1g7CQ",
108 | "https://www.bilibili.com/video/BV1Gq4y1W7wT",
109 | "https://www.bilibili.com/video/BV1z3411y7nP",
110 | "https://www.bilibili.com/video/BV14h411B7mE",
111 | "https://www.bilibili.com/video/BV1Uy4y1j7rN",
112 | "https://www.bilibili.com/video/BV1NX4y1w7JN",
113 | "https://www.bilibili.com/video/BV1464y1W7gv",
114 | "https://www.bilibili.com/video/BV19V411H7tn",
115 | "https://www.bilibili.com/video/BV1L54y1n7yA",
116 | "https://www.bilibili.com/video/BV1f64y1k7Ff",
117 | "https://www.bilibili.com/video/BV12b4y1X7S8",
118 | "https://www.bilibili.com/video/BV1QQ4y1272S",
119 | "https://www.bilibili.com/video/BV12f4y1F7jD",
120 | "https://www.bilibili.com/video/BV1sM4y1g7Dg",
121 | "https://www.bilibili.com/video/BV1tA411V7b5",
122 | "https://www.bilibili.com/video/BV15V411E7hr",
123 | "https://www.bilibili.com/video/BV1J64y1m7Eu",
124 | "https://www.bilibili.com/video/BV1W54y1V7bV",
125 | "https://www.bilibili.com/video/BV15v411e7qa",
126 | "https://www.bilibili.com/video/BV1gy4y147vp",
127 | "https://www.bilibili.com/video/BV1DA411c7U3",
128 | "https://www.bilibili.com/video/BV11b4y167Gc",
129 | "https://www.bilibili.com/video/BV1bQ4y1d7n6",
130 | "https://www.bilibili.com/video/BV1X5411K7W5",
131 | "https://www.bilibili.com/video/BV12V411E7sn",
132 | "https://www.bilibili.com/video/BV1wv411K7LT",
133 | "https://www.bilibili.com/video/BV1Eq4y197ho",
134 | "https://www.bilibili.com/video/BV1aP4y1s7Wy",
135 | "https://www.bilibili.com/video/BV1Y64y1U7FZ"
136 | ]
137 |
138 | const initConfig = {
139 | mode: "fixed",
140 | hidden: false,
141 | content: {
142 | link: 引流,
143 | welcome: ["Hi!"],
144 | touch: "",
145 | home: ["这里有很多好听的", "边听asoul的演唱边敲代码?"],
146 | skin: [["诶,想看看其他团员吗?", "嘉晚饭yyds", "嘉晚饭是真的"], "替换后入场文本"],
147 | background: ["要切换背景图吗?", "这次切背景图会切到我吗?", "换,换一下背景图也不是不可以啦",],
148 | },
149 | model: [
150 | "./models/Diana/Diana.model3.json",
151 | "./models/Ava/Ava.model3.json",
152 | ],
153 | tips: true,
154 | onModelLoad: onModelLoad
155 | }
156 |
157 | function 加载圣·嘉然() {
158 | pio_reference = new Paul_Pio(initConfig)
159 |
160 | pio_alignment = "left"
161 |
162 | // Then apply style
163 | pio_refresh_style()
164 | }
165 |
166 | function reSizeLive2d() {
167 | const defaultWidth = 280; // 默认宽度280px , zoom = 1
168 | const container = document.getElementById("pio-container");
169 | if (container)
170 | container.style.zoom = Math.round(window.innerWidth / defaultWidth * 100) / 100;
171 | }
172 |
173 | window.addEventListener("resize", reSizeLive2d);
174 |
175 | function onModelLoad(model) {
176 | const container = document.getElementById("pio-container")
177 | reSizeLive2d(); // 初始加载
178 | const canvas = document.getElementById("pio")
179 | const modelNmae = model.internalModel.settings.name
180 | const coreModel = model.internalModel.coreModel
181 | const motionManager = model.internalModel.motionManager
182 |
183 | let touchList = [
184 | {
185 | text: "点击展示文本1",
186 | motion: "Idle"
187 | },
188 | {
189 | text: "点击展示文本2",
190 | motion: "Idle"
191 | }
192 | ]
193 |
194 | function playAction(action) {
195 | action.text && pio_reference.modules.render(action.text)
196 | action.motion && pio_reference.model.motion(action.motion)
197 |
198 | if (action.from && action.to) {
199 | Object.keys(action.from).forEach(id => {
200 | const hidePartIndex = coreModel._partIds.indexOf(id)
201 | TweenLite.to(coreModel._partOpacities, 0.6, { [hidePartIndex]: action.from[id] });
202 | // coreModel._partOpacities[hidePartIndex] = action.from[id]
203 | })
204 |
205 | motionManager.once("motionFinish", (data) => {
206 | Object.keys(action.to).forEach(id => {
207 | const hidePartIndex = coreModel._partIds.indexOf(id)
208 | TweenLite.to(coreModel._partOpacities, 0.6, { [hidePartIndex]: action.to[id] });
209 | // coreModel._partOpacities[hidePartIndex] = action.to[id]
210 | })
211 | })
212 | }
213 | }
214 |
215 | window.live2d_playAction = playAction; // 挂载到window上,方便调用
216 |
217 | canvas.onclick = function () {
218 | if (motionManager.state.currentGroup !== "Idle") return
219 |
220 | const action = pio_reference.modules.rand(touchList)
221 | playAction(action)
222 | }
223 |
224 | if (modelNmae === "Diana") {
225 | container.dataset.model = "Diana"
226 | initConfig.content.skin[1] = ["我是吃货担当 嘉然 Diana~"]
227 | playAction({ motion: "Tap抱阿草-左手" })
228 |
229 | touchList = [
230 | {
231 | text: "嘉心糖屁用没有",
232 | motion: "Tap生气 -领结"
233 | },
234 | {
235 | text: "有人急了,但我不说是谁~",
236 | motion: "Tap= = 左蝴蝶结"
237 | },
238 | {
239 | text: "呜呜...呜呜呜....",
240 | motion: "Tap哭 -眼角"
241 | },
242 | {
243 | text: "想然然了没有呀~",
244 | motion: "Tap害羞-中间刘海"
245 | },
246 | {
247 | text: "阿草好软呀~",
248 | motion: "Tap抱阿草-左手"
249 | },
250 | {
251 | text: "不要再戳啦!好痒!",
252 | motion: "Tap摇头- 身体"
253 | },
254 | {
255 | text: "嗷呜~~~",
256 | motion: "Tap耳朵-发卡"
257 | },
258 | {
259 | text: "zzZ。。。",
260 | motion: "Leave"
261 | },
262 | {
263 | text: "哇!好吃的!",
264 | motion: "Tap右头发"
265 | },
266 | ]
267 |
268 | } else if (modelNmae === "Ava") {
269 | container.dataset.model = "Ava"
270 | initConfig.content.skin[1] = ["我是拉胯 Gamer担当 向晚 AvA~"]
271 | playAction({
272 | motion: "Tap左眼",
273 | from: {
274 | "Part15": 1
275 | },
276 | to: {
277 | "Part15": 0
278 | }
279 | })
280 |
281 | touchList = [
282 | {
283 | text: "水母 水母~ 只是普通的生物",
284 | motion: "Tap右手"
285 | },
286 | {
287 | text: "可爱的鸽子鸽子~我喜欢你~",
288 | motion: "Tap胸口项链",
289 | from: {
290 | "Part12": 1
291 | },
292 | to: {
293 | "Part12": 0
294 | }
295 | },
296 | {
297 | text: "好...好兄弟之间喜欢很正常啦",
298 | motion: "Tap中间刘海",
299 | from: {
300 | "Part12": 1
301 | },
302 | to: {
303 | "Part12": 0
304 | }
305 | },
306 | {
307 | text: "啊啊啊!怎么推流辣",
308 | motion: "Tap右眼",
309 | from: {
310 | "Part16": 1
311 | },
312 | to: {
313 | "Part16": 0
314 | }
315 | },
316 | {
317 | text: "你怎么老摸我,我的身体是不是可有魅力",
318 | motion: "Tap嘴"
319 | },
320 | {
321 | text: "AAAAAAAAAAvvvvAAA 向晚!",
322 | motion: "Tap左眼",
323 | from: {
324 | "Part15": 1
325 | },
326 | to: {
327 | "Part15": 0
328 | }
329 | }
330 | ]
331 | canvas.width = model.width * 1.2
332 | const hideParts = [
333 | "Part5", // 晕
334 | "neko", // 喵喵拳
335 | "game", // 左手游戏手柄
336 | "Part15", // 墨镜
337 | // "Part21", // 右手小臂
338 | // "Part22", // 左手垂下
339 | "gitar", // 吉他 !和 上面 part21 22 冲突
340 | "Part", // 双手抱拳
341 | "Part16", // 惊讶特效
342 | "Part12" // 小心心
343 | ]
344 | const hidePartsIndex = hideParts.map(id => coreModel._partIds.indexOf(id))
345 | hidePartsIndex.forEach(idx => {
346 | coreModel._partOpacities[idx] = 0
347 | })
348 | }
349 | }
350 |
351 |
352 | var pio_reference
353 | window.onload = 加载圣·嘉然
354 |
--------------------------------------------------------------------------------
/res/live2d/lib/pio/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/lib/pio/avatar.png
--------------------------------------------------------------------------------
/res/live2d/lib/pio/pio.css:
--------------------------------------------------------------------------------
1 | /* ----
2 |
3 | # Pio Plugin
4 | # By: Dreamer-Paul
5 | # Modify: journey-ad
6 | # Last Update: 2021.5.10
7 |
8 | 一个支持更换 Live2D 模型的 Typecho 插件。
9 |
10 | 本代码为奇趣保罗原创,并遵守 GPL 2.0 开源协议。欢迎访问我的博客:https://paugram.com
11 |
12 | ---- */
13 |
14 | .pio-container {
15 | bottom: 0;
16 | z-index: 52;
17 | color: #666;
18 | position: fixed;
19 | user-select: none;
20 | cursor: grab;
21 | font-size: 12px;
22 | /* 子元素的em动态调整 */
23 | }
24 |
25 | .pio-container:active {
26 | cursor: grabbing;
27 | }
28 |
29 | .pio-container .pio-show {
30 | left: -1.2em;
31 | bottom: -0.2em;
32 | width: 6em;
33 | height: 6.8em;
34 | display: none;
35 | cursor: pointer;
36 | position: absolute;
37 | transition: all .3s;
38 | background: url(avatar.png) center/contain;
39 | opacity: 0.7;
40 | }
41 |
42 | .pio-container.hidden .pio-show {
43 | display: block;
44 | }
45 |
46 | .pio-container.hidden .pio-show:hover {
47 | opacity: 0.9;
48 | transform: translateX(.5em);
49 | }
50 |
51 | .pio-container.hidden #pio {
52 | display: none;
53 | }
54 |
55 | .pio-container.hidden .pio-dialog {
56 | display: none;
57 | }
58 |
59 | .pio-container.left {
60 | left: 0
61 | }
62 |
63 | .pio-container.right {
64 | right: 0
65 | }
66 |
67 | .pio-container.active {
68 | cursor: move
69 | }
70 |
71 | .pio-container.static {
72 | pointer-events: none
73 | }
74 |
75 | .pio-container .pio-action {
76 | top: 1.2em;
77 | opacity: 0;
78 | position: absolute;
79 | transition: opacity .3s;
80 | }
81 |
82 | .pio-container.left .pio-action {
83 | right: 0
84 | }
85 |
86 | .pio-container.right .pio-action {
87 | left: 0
88 | }
89 |
90 | .pio-container:hover .pio-action {
91 | opacity: 1
92 | }
93 |
94 | .pio-action span {
95 | color: #fff;
96 | width: 2em;
97 | height: 2em;
98 | margin-bottom: 0.6em;
99 | display: block;
100 | cursor: pointer;
101 | text-align: center;
102 | margin-bottom: .5em;
103 | background-size: 100%;
104 | }
105 |
106 | .pio-action .pio-home {
107 | background-image: url("../../assets/yigehun.png");
108 | }
109 |
110 | .pio-action .pio-skin {
111 | background-image: url("../../assets/chong.jpg");
112 | }
113 |
114 | .pio-action .pio-skate {
115 | background-image: url("../../assets/jellyfish.png");
116 | }
117 |
118 | .pio-action .pio-info {
119 | background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 500 500' xmlns='http://www.w3.org/2000/svg'%3E%3Crect transform='rotate(45.001 238.211 363.575)' x='29.285' y='22.411' width='273.903' height='505.038' rx='70' ry='70' fill='%23dcdcdc'/%3E%3Cpath d='M218.543 249.999l-47.186 47.186c-8.987 8.988-8.987 22.47 0 31.457 8.988 8.988 22.47 8.988 31.457 0L250 281.456l15.728 15.729c17.976 17.976 17.976 46.063 0 64.038l-64.037 64.038c-17.976 17.975-46.063 17.975-64.038 0l-64.038-64.038c-17.975-17.975-17.975-46.062 0-64.038l64.038-64.037c17.975-17.976 46.062-17.976 64.038 0l16.852 16.851z' fill='%23fff'/%3E%3Cpath d='M281.457 249.999l47.186-47.186c8.988-8.987 8.988-22.469 0-31.457-8.987-8.987-22.469-8.987-31.457 0L250 218.542l-15.729-15.729c-17.975-17.975-17.975-46.062 0-64.037l64.038-64.038c17.975-17.975 46.062-17.975 64.038 0l64.037 64.038c17.977 17.975 17.977 46.062 0 64.037l-64.037 64.038c-17.976 17.976-46.063 17.976-64.038 0l-16.852-16.852z' fill='%2361a3e0'/%3E%3C/svg%3E");
120 | }
121 |
122 | .pio-action .pio-ava {
123 | background-image: url('../../assets/Ava.png');
124 | }
125 |
126 | .pio-action .pio-diana {
127 | background-image: url('../../assets/jiaxintang.png');
128 | }
129 |
130 | .pio-action .pio-eileen {
131 | background-image: url('../../assets/naiqilin.png');
132 | }
133 |
134 | /* 背景图图标是和eileen是一样的 */
135 | .pio-action .pio-background {
136 | background-image: url('../../assets/naiqilin.png');
137 | }
138 |
139 | .pio-action .pio-asoulfans {
140 | background-image: url('../../assets/beijixing.png');
141 | }
142 |
143 | .normal-cycle {
144 | animation: cycle 1s linear infinite;
145 | }
146 |
147 | @keyframes cycle {
148 | 0% {
149 | -webkit-transform: rotate(0deg);
150 | }
151 |
152 | 25% {
153 | -webkit-transform: rotate(90deg);
154 | }
155 |
156 | 50% {
157 | -webkit-transform: rotate(180deg);
158 | }
159 |
160 | 75% {
161 | -webkit-transform: rotate(270deg);
162 | }
163 |
164 | 100% {
165 | -webkit-transform: rotate(360deg);
166 | }
167 | }
168 |
169 | .pio-container .pio-dialog {
170 | top: -2.2em;
171 | opacity: 0;
172 | z-index: -1;
173 | font-size: 1.2em;
174 | min-width: 12em;
175 | background: #fff;
176 | padding: .75em 1em;
177 | border-radius: 1em;
178 | visibility: hidden;
179 | position: absolute;
180 | word-break: break-all;
181 | border: 1px solid #eee;
182 | transition: opacity .3s, visibility .3s;
183 | }
184 |
185 | .pio-container .pio-dialog.active {
186 | opacity: 1;
187 | visibility: visible;
188 | }
189 |
190 | .pio-container.left .pio-dialog {
191 | left: 1.5em
192 | }
193 |
194 | .pio-container.right .pio-dialog {
195 | right: 1.5em
196 | }
197 |
198 | #pio {
199 | vertical-align: middle;
200 | width: 22em;
201 | }
--------------------------------------------------------------------------------
/res/live2d/lib/pio/pio.js:
--------------------------------------------------------------------------------
1 | /* ----
2 |
3 | # Pio Plugin
4 | # By: Dreamer-Paul
5 | # Modify: journey-ad
6 | # Last Update: 2021.5.4
7 |
8 | 一个支持更换 Live2D 模型的 Typecho 插件。
9 |
10 | 本代码为奇趣保罗原创,并遵守 GPL 2.0 开源协议。欢迎访问我的博客:https://paugram.com
11 |
12 | ---- */
13 |
14 | var Paul_Pio = function (prop) {
15 | var that = this;
16 |
17 | // 音频实例,只维护一个
18 | var audioInstance = new Audio();
19 |
20 | var current = {
21 | idol: localStorage.getItem('live2d-asoul-model') ? Number(localStorage.getItem('live2d-asoul-model')) : 0,
22 | menu: document.querySelector(".pio-container .pio-action"),
23 | canvas: document.getElementById("pio"),
24 | body: document.querySelector(".pio-container"),
25 | root: document.location.protocol + '//' + document.location.hostname + '/'
26 | };
27 |
28 | /* - 方法 */
29 | var modules = {
30 | // 更换模型
31 | idol: function () {
32 | current.idol < (prop.model.length - 1) ? current.idol++ : current.idol = 0;
33 | return current.idol;
34 | },
35 | // 创建内容
36 | create: function (tag, prop) {
37 | var e = document.createElement(tag);
38 | if (prop.class) e.className = prop.class;
39 | return e;
40 | },
41 | // 随机内容
42 | rand: function (arr) {
43 | return arr[Math.floor(Math.random() * arr.length)];
44 | },
45 | // 播放音频
46 | audioPlay: function (url) {
47 | if (url && audioInstance) {
48 | audioInstance.pause();
49 | audioInstance.src = url;
50 | audioInstance.play().catch((e) => {
51 | if (e.toString() == 'NotSupportedError: Failed to load because no supported source was found.')
52 | this.render('vscode默认不支持html音频处理,如何开启可查看该插件简介')
53 | })
54 | }
55 | },
56 | // 创建对话框方法
57 | render: function (text) {
58 | if (text.constructor === Array) {
59 | dialog.innerHTML = modules.rand(text);
60 | }
61 | else if (text.constructor === String) {
62 | dialog.innerHTML = text;
63 | }
64 | else {
65 | dialog.innerHTML = "输入内容出现问题了 X_X";
66 | }
67 |
68 | dialog.classList.add("active");
69 |
70 | clearTimeout(this.t);
71 | this.t = setTimeout(function () {
72 | dialog.classList.remove("active");
73 | }, 3000);
74 | },
75 | // 是否为移动设备
76 | isMobile: function () {
77 | var ua = window.navigator.userAgent.toLowerCase();
78 | ua = ua.indexOf("mobile") || ua.indexOf("android") || ua.indexOf("ios");
79 |
80 | return window.innerWidth < 500 || ua !== -1;
81 | }
82 | };
83 | this.modules = modules;
84 |
85 | var elements = {
86 | home: modules.create("span", { class: "pio-home" }),
87 | background: modules.create("span", { class: "pio-background" }), // 用于切换背景图
88 | skin: modules.create("span", { class: "pio-skin" }),
89 | skate: modules.create("span", { class: "pio-skate" }),
90 | audio: modules.create("span", { class: "pio-diana" }), // 语音功能测试
91 | fans: modules.create("span", { class: "pio-asoulfans" }),
92 | info: modules.create("span", { class: "pio-info" }),
93 | // close: modules.create("span", { class: "pio-close" }),
94 | // show: modules.create("div", { class: "pio-show" })
95 | };
96 |
97 | var dialog = modules.create("div", { class: "pio-dialog" });
98 | current.body.appendChild(dialog);
99 | // current.body.appendChild(elements.show); // 自带的显示和关闭 注释掉
100 |
101 | /* - 提示操作 */
102 | var action = {
103 | // 欢迎
104 | welcome: function () {
105 | if (prop.tips) {
106 | var text, hour = new Date().getHours();
107 |
108 | if (hour > 22 || hour <= 5) {
109 | text = '你是夜猫子呀?这么晚还不睡觉,明天起的来嘛';
110 | }
111 | else if (hour > 5 && hour <= 8) {
112 | text = '早上好!';
113 | }
114 | else if (hour > 8 && hour <= 11) {
115 | text = '上午好!工作顺利嘛,不要久坐,多起来走动走动哦!';
116 | }
117 | else if (hour > 11 && hour <= 14) {
118 | text = '中午了,工作了一个上午,现在是午餐时间!';
119 | }
120 | else if (hour > 14 && hour <= 17) {
121 | text = '午后很容易犯困呢,今天的运动目标完成了吗?';
122 | }
123 | else if (hour > 17 && hour <= 19) {
124 | text = '傍晚了!窗外夕阳的景色很美丽呢,最美不过夕阳红~';
125 | }
126 | else if (hour > 19 && hour <= 21) {
127 | text = '晚上好,今天过得怎么样?';
128 | }
129 | else if (hour > 21 && hour <= 23) {
130 | text = '已经这么晚了呀,早点休息吧,晚安~';
131 | }
132 | else {
133 | text = "奇趣保罗说:这个是无法被触发的吧,哈哈";
134 | }
135 |
136 | modules.render(text);
137 | }
138 | else {
139 | modules.render(prop.content.welcome || "欢迎使用本插件,记得去B站关注a-soul!");
140 | }
141 |
142 | // 定时提醒,每一小时提示一下需要休息了
143 | setInterval(() => {
144 | modules.render('已经连续一个小时写代码了,请注意活动一下身体');
145 | }, 1000 * 60 * 60);
146 | },
147 | // 触摸
148 | touch: function () {
149 | current.canvas.onclick = function () {
150 | modules.render(prop.content.touch || ["你在干什么?", "再摸我就报警了!", "HENTAI!", "不可以这样欺负我啦!"]);
151 | };
152 | },
153 | // 右侧按钮
154 | buttons: function () {
155 | // asoulworld网站
156 | elements.home.onclick = function () {
157 | window.open('https://studio.asf.ink/');
158 | };
159 | elements.home.onmouseover = function () {
160 | modules.render(prop.content.home || "想查看更多A-Soul的信息吗?");
161 | };
162 | current.menu.appendChild(elements.home);
163 |
164 | // 更换背景图
165 | elements.background.onclick = function () {
166 | changeBackground && changeBackground();
167 | };
168 | elements.background.onmouseover = function () {
169 | modules.render(prop.content.background || "背景图?早该换换了");
170 | };
171 | current.menu.appendChild(elements.background);
172 |
173 | // 更换模型
174 | elements.skin.onclick = function () {
175 | const modelIndex = modules.idol();
176 | localStorage.setItem('live2d-asoul-model', modelIndex);
177 | that.model = loadlive2d("pio", prop.model[modelIndex], model => {
178 | prop.onModelLoad && prop.onModelLoad(model)
179 | prop.content.skin && prop.content.skin[1] ? modules.render(prop.content.skin[1]) : modules.render("新衣服真漂亮~");
180 | });
181 | };
182 | elements.skin.onmouseover = function () {
183 | prop.content.skin && prop.content.skin[0] ? modules.render(prop.content.skin[0]) : modules.render("想看看我的新衣服吗?");
184 | };
185 | if (prop.model.length > 1) current.menu.appendChild(elements.skin);
186 |
187 | // 溜冰场
188 | elements.skate.onclick = function () {
189 | const link = window.溜冰场 || prop.content.link;
190 | if (link) {
191 | if (Array.isArray(link))
192 | window.open(modules.rand(link))
193 | else if (typeof link === 'string')
194 | window.open(link);
195 | }
196 | else {
197 | window.open("https://paugram.com/coding/add-poster-girl-with-plugin.html");
198 | }
199 | };
200 | elements.skate.onmouseover = function () {
201 | const list = ["溜冰去咯", "随机挑战开启", "溜冰的意思不是让你咬咬牙溜十次八次,而是要上百次", "你想摸鱼???"]
202 | modules.render(list);
203 | };
204 | current.menu.appendChild(elements.skate);
205 |
206 |
207 | // 音频测试
208 | elements.audio.onclick = function () {
209 | if (current.idol === 0) {
210 | window.live2d_playAction({
211 | text: "嘉心糖屁都用没有",
212 | motion: "Tap生气 -领结"
213 | })
214 | // 播放音频
215 | modules.audioPlay(`./models/Diana/audio/jiaxintang-nouse.aac`);
216 | }
217 | else {
218 | modules.render('晚晚的语音测试未添加');
219 | }
220 | };
221 | elements.audio.onmouseover = function () {
222 | modules.render("音频测试");
223 | };
224 | current.menu.appendChild(elements.audio);
225 |
226 | // 一个魂们的二创
227 | elements.fans.onclick = function () {
228 | window.open("https://asoulfanart.com/pic");
229 | };
230 | elements.fans.onmouseover = function () {
231 | modules.render("想看更多一个魂们的二创吗?");
232 | };
233 | current.menu.appendChild(elements.fans);
234 |
235 | // 关于我
236 | elements.info.onclick = function () {
237 | window.open("https://www.bilibili.com/video/BV1FZ4y1F7HH");
238 | };
239 | elements.info.onmouseover = function () {
240 | modules.render(["想了解更多关于我的信息吗?", "模型来源"]);
241 | };
242 | current.menu.appendChild(elements.info);
243 | }
244 | };
245 |
246 | /* - 运行 */
247 | var begin = {
248 | static: function () {
249 | current.body.classList.add("static");
250 | },
251 | fixed: function () {
252 | action.touch(); action.buttons();
253 | },
254 | draggable: function () {
255 | action.touch(); action.buttons();
256 |
257 | var body = current.body;
258 | body.onmousedown = function (downEvent) {
259 | var location = {
260 | x: downEvent.clientX - this.offsetLeft,
261 | y: downEvent.clientY - this.offsetTop
262 | };
263 |
264 | function move(moveEvent) {
265 | body.classList.add("active");
266 | body.classList.remove("right");
267 | body.style.left = (moveEvent.clientX - location.x) + 'px';
268 | body.style.top = (moveEvent.clientY - location.y) + 'px';
269 | body.style.bottom = "auto";
270 | }
271 |
272 | document.addEventListener("mousemove", move);
273 | document.addEventListener("mouseup", function () {
274 | body.classList.remove("active");
275 | document.removeEventListener("mousemove", move);
276 | });
277 | };
278 | }
279 | };
280 |
281 | // 运行
282 | this.init = function (onlyText) {
283 | if (!(prop.hidden && modules.isMobile())) {
284 | if (!onlyText) {
285 | action.welcome();
286 | that.model = loadlive2d("pio", prop.model[current.idol], model => {
287 | prop.onModelLoad && prop.onModelLoad(model)
288 | });
289 | }
290 |
291 | switch (prop.mode) {
292 | case "static": begin.static(); break;
293 | case "fixed": begin.fixed(); break;
294 | case "draggable": begin.draggable(); break;
295 | }
296 |
297 | }
298 | };
299 |
300 | this.init();
301 | };
302 |
303 | // 请保留版权说明
304 | if (window.console && window.console.log) {
305 | console.log("%c Pio %c https://paugram.com ", "color: #fff; margin: 1em 0; padding: 5px 0; background: #673ab7;", "margin: 1em 0; padding: 5px 0; background: #efefef;");
306 | }
--------------------------------------------------------------------------------
/res/live2d/lib/pio/pio_sdk4.js:
--------------------------------------------------------------------------------
1 | /* ----
2 |
3 | # Pio SDK 2/3/4 support
4 | # By: jupiterbjy
5 | # Modify: journey-ad
6 | # Last Update: 2021.5.4
7 |
8 | To use this, you need to include following sources to your HTML file first.
9 | With this script, you don't have to include `l2d.js`. Testing is done without it.
10 | Basic usage is same with Paul-Pio.
11 |
12 | Make sure to call `pio_refresh_style()` upon changing styles on anything related to 'pio-container' and it's children.
13 |
14 | To change alignment, modify variable `pio_alignment` to either `left` or `right`, then call `pio_refresh_style()`.
15 |
16 |
17 |
18 |
19 |
20 |
21 | If you have trouble setting up this, check following example's sources.
22 | https://jupiterbjy.github.io/PaulPio_PIXI_Demo/
23 |
24 | ---- */
25 |
26 |
27 | function loadlive2d(canvas_id, json_object_or_url, on_load) {
28 | // Replaces original l2d method 'loadlive2d' for Pio.
29 | // Heavily relies on pixi_live2d_display.
30 |
31 | console.log("[Pio] Loading new model")
32 |
33 | const canvas = document.getElementById(canvas_id)
34 |
35 | // When pio was start minimized on browser refresh or reload,
36 | // canvas is set to 0, 0 dimension and need to be changed.
37 | if (canvas.width === 0) {
38 | canvas.removeAttribute("height")
39 | pio_refresh_style()
40 | }
41 |
42 | // Try to remove previous model, if any exists.
43 | try {
44 | app.stage.removeChildAt(0)
45 | } catch (error) {
46 |
47 | }
48 |
49 | let model = PIXI.live2d.Live2DModel.fromSync(json_object_or_url)
50 |
51 | model.once("load", () => {
52 | app.stage.addChild(model)
53 |
54 | const vertical_factor = canvas.height / model.height
55 | model.scale.set(vertical_factor)
56 |
57 | // match canvas to model width
58 | canvas.width = model.width
59 | canvas.height = model.height
60 | pio_refresh_style()
61 |
62 | // check alignment, and align model to corner
63 | if (document.getElementsByClassName("pio-container").item(0).className.includes("left")){
64 | model.x = 0
65 | } else {
66 | model.x = canvas.width - model.width
67 | }
68 |
69 | // Hit callback definition
70 | model.on("hit", hitAreas => {
71 | if (hitAreas.includes("body")) {
72 | console.log("[Pio] Touch on body (SDK2)")
73 | model.motion('tap_body')
74 |
75 | } else if (hitAreas.includes("Body")) {
76 | console.log("[Pio] Touch on body (SDK3/4)")
77 | model.motion("Tap")
78 |
79 | } else if (hitAreas.includes("head") || hitAreas.includes("Head")){
80 | console.log("[Pio] Touch on head")
81 | model.expression()
82 | }
83 | })
84 |
85 | on_load(model)
86 | })
87 |
88 | return model
89 | }
90 |
91 |
92 | function _pio_initialize_container(){
93 |
94 | // Generate structure
95 | let pio_container = document.createElement("div")
96 | pio_container.classList.add("pio-container")
97 | pio_container.id = "pio-container"
98 | document.body.insertAdjacentElement("beforeend", pio_container)
99 |
100 | // Generate action
101 | let pio_action = document.createElement("div")
102 | pio_action.classList.add("pio-action")
103 | pio_container.insertAdjacentElement("beforeend", pio_action)
104 |
105 | // Generate canvas
106 | let pio_canvas = document.createElement("canvas")
107 | pio_canvas.id = "pio"
108 | pio_container.insertAdjacentElement("beforeend", pio_canvas)
109 |
110 | console.log("[Pio] Initialized container.")
111 | }
112 |
113 |
114 | function pio_refresh_style(){
115 | // Always make sure to call this after container/canvas style changes!
116 | // You can set alignment here, but still you can change it manually.
117 |
118 | let pio_container = document.getElementsByClassName("pio-container").item(0)
119 |
120 | pio_container.classList.remove("left", "right")
121 | pio_container.classList.add(pio_alignment)
122 |
123 | // app.resizeTo = document.getElementById("pio")
124 | }
125 |
126 |
127 | function _pio_initialize_pixi() {
128 | // Initialize html elements and pixi app.
129 | // Must run before pio init.
130 |
131 | _pio_initialize_container()
132 |
133 | app = new PIXI.Application({
134 | view: document.getElementById("pio"),
135 | transparent: true,
136 | autoStart: true,
137 | })
138 |
139 | pio_refresh_style()
140 | }
141 |
142 |
143 | // change alignment to left by modifying this value in other script.
144 | // Make sure to call `pio_refresh_style` to apply changes!
145 | let pio_alignment = "right"
146 |
147 |
148 | let app
149 | window.addEventListener("DOMContentLoaded", _pio_initialize_pixi)
150 |
--------------------------------------------------------------------------------
/res/live2d/models/Ava/Ava.4096/texture_00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/models/Ava/Ava.4096/texture_00.png
--------------------------------------------------------------------------------
/res/live2d/models/Ava/Ava.moc3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/models/Ava/Ava.moc3
--------------------------------------------------------------------------------
/res/live2d/models/Ava/Ava.model3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "Bounds": {
4 | "Width": 9.772043,
5 | "Height": 11.08606,
6 | "CenterX": 0.1069689,
7 | "CenterY": -1.404058
8 | },
9 | "FileReferences": {
10 | "Moc": "Ava.moc3",
11 | "Textures": [
12 | "Ava.4096/texture_00.png"
13 | ],
14 | "Physics": "Ava.physics3.json",
15 | "PhysicsV2": {
16 | "File": "Ava.physics3.json"
17 | },
18 | "Motions": {
19 | "Idle": [{
20 | "Name": "待机",
21 | "File": "motions/Ava_idle.motion3.json"
22 | }],
23 | "Shake": [{
24 | "Name": "晕",
25 | "File": "motions/Ava_shake01.motion3.json",
26 | "Text": "啊呜...",
27 | "TextDuration": 2000
28 | }, {
29 | "File": "motions/Ava_shake02.motion3.json"
30 | }],
31 | "Tap左手": [{
32 | "Name": "吉他",
33 | "File": "motions/Ava_tap01.motion3.json",
34 | "Text": "可爱的鸽子鸽子~我喜欢你~",
35 | "TextDelay": 1200,
36 | "TextDuration": 5600
37 | }],
38 | "Tap右手": [{
39 | "Name": "游戏",
40 | "File": "motions/Ava_tap02.motion3.json",
41 | "Text": "来陪我玩游戏!",
42 | "TextDelay": 600,
43 | "TextDuration": 2500
44 | }],
45 | "Tap腰": [{
46 | "Name": "傲娇",
47 | "File": "motions/Ava_tap03.motion3.json",
48 | "Text": "哼,才不是傲娇大小姐",
49 | "TextDelay": 500,
50 | "TextDuration": 3000
51 | }],
52 | "Tap中间刘海": [{
53 | "Name": "害羞",
54 | "File": "motions/Ava_tap04.motion3.json",
55 | "Text": "好...好兄弟之间喜欢很正常啦",
56 | "TextDelay": 1500,
57 | "TextDuration": 3000
58 | }, {
59 | "Name": "害羞2",
60 | "File": "motions/Ava_tap04.motion3.json",
61 | "Text": "也...也不是不可以",
62 | "TextDelay": 2000,
63 | "TextDuration": 3000
64 | }],
65 | "Tap嘴": [{
66 | "Name": "傲娇",
67 | "File": "motions/Ava_tap03.motion3.json",
68 | "Text": "什么傲娇啦,我才没有",
69 | "TextDelay": 500,
70 | "TextDuration": 2200
71 | }],
72 | "Tap胸口项链": [{
73 | "Name": "笑",
74 | "File": "motions/Ava_tap05.motion3.json"
75 | }],
76 | "Tap脖子": [{
77 | "Name": "监督",
78 | "File": "motions/Ava_tap06.motion3.json",
79 | "Text": "嗯?老戳我干嘛,快去干正事啦 ",
80 | "TextDelay": 550,
81 | "TextDuration": 4000
82 | }],
83 | "Tap 右边头饰小花": [{
84 | "Name": "懒羊羊",
85 | "File": "motions/Ava_tap07.motion3.json",
86 | "Text": "顶晚人...顶晚人在哪里...",
87 | "TextDelay": 800,
88 | "TextDuration": 6000
89 | }],
90 | "Tap右头饰": [{
91 | "Name": "猫",
92 | "File": "motions/Ava_tap08.motion3.json",
93 | "Text": "neko panch!",
94 | "TextDelay": 500,
95 | "TextDuration": 2000
96 | }],
97 | "Tap右眼": [{
98 | "Name": "惊讶",
99 | "File": "motions/Ava_tap09.motion3.json",
100 | "Text": "啊",
101 | "TextDelay": 200,
102 | "TextDuration": 1000
103 | }],
104 | "Tap左眼": [{
105 | "Name": "墨镜",
106 | "File": "motions/Ava_tap10.motion3.json",
107 | "Text": "嗯哼~我超帅的",
108 | "TextDelay": 700,
109 | "TextDuration": 2000
110 | }],
111 | "Tap右马尾 ": [{
112 | "Name": "水母",
113 | "File": "motions/Ava_tap11.motion3.json"
114 | }],
115 | "Tap左马尾": [{
116 | "Name": "><",
117 | "File": "motions/Ava_shake02.motion3.json",
118 | "Text": "头发摸乱了啦~",
119 | "TextDelay": 500,
120 | "TextDuration": 2000
121 | }],
122 | "Tap右手臂": [{
123 | "File": "motions/Ava_tap06.motion3.json",
124 | "Text": "嗯?老戳我干嘛,快去干正事啦 ",
125 | "TextDelay": 550,
126 | "TextDuration": 4000
127 | }],
128 | "Tap左中马尾": [{
129 | "File": "motions/Ava_tap11.motion3.json"
130 | }]
131 | }
132 | },
133 | "Controllers": {
134 | "ParamHit": {},
135 | "ParamLoop": {},
136 | "KeyTrigger": {},
137 | "EyeBlink": {
138 | "MinInterval": 500,
139 | "MaxInterval": 6000,
140 | "Items": [{
141 | "Id": "ParamEyeLOpen",
142 | "Min": 0.0,
143 | "Max": 1.0,
144 | "BlendMode": 2,
145 | "Input": 0
146 | }, {
147 | "Id": "ParamEyeROpen",
148 | "Min": 0.0,
149 | "Max": 1.0,
150 | "BlendMode": 2,
151 | "Input": 0
152 | }, {
153 | "Id": "Param7",
154 | "Min": 0.0,
155 | "Max": 1.0,
156 | "BlendMode": 2,
157 | "Input": 0
158 | }, {
159 | "Id": "Param8",
160 | "Min": 0.0,
161 | "Max": 1.0,
162 | "BlendMode": 2,
163 | "Input": 0
164 | }],
165 | "Enabled": true
166 | },
167 | "LipSync": {
168 | "Gain": 5.0
169 | },
170 | "MouseTracking": {
171 | "SmoothTime": 0.15,
172 | "Items": [{
173 | "Id": "ParamAngleX",
174 | "Min": -30.0,
175 | "Max": 30.0,
176 | "DefaultValue": 0.0,
177 | "Weight": 0.359834284,
178 | "BlendMode": 1,
179 | "Input": 1
180 | }, {
181 | "Id": "ParamAngleY",
182 | "Min": -30.0,
183 | "Max": 30.0,
184 | "DefaultValue": 0.0,
185 | "Weight": 0.3398514,
186 | "BlendMode": 1,
187 | "Axis": 1,
188 | "Input": 2
189 | }, {
190 | "Id": "ParamAngleZ",
191 | "Min": -15.0,
192 | "Max": 15.0,
193 | "DefaultValue": 0.0,
194 | "Weight": 0.199971348,
195 | "BlendMode": 1,
196 | "Axis": 2,
197 | "Input": 1
198 | }, {
199 | "Id": "ParamBodyAngleX",
200 | "Min": -10.0,
201 | "Max": 10.0,
202 | "DefaultValue": 0.0,
203 | "Weight": 0.376962453,
204 | "BlendMode": 1,
205 | "Input": 1
206 | }, {
207 | "Id": "ParamBodyAngleZ",
208 | "Min": -10.0,
209 | "Max": 10.0,
210 | "DefaultValue": 0.0,
211 | "Weight": 0.365543664,
212 | "BlendMode": 1,
213 | "Axis": 2,
214 | "Input": 1
215 | }, {
216 | "Id": "Param46",
217 | "Min": -30.0,
218 | "Max": 30.0,
219 | "DefaultValue": 0.0,
220 | "Weight": 0.411218822,
221 | "BlendMode": 1,
222 | "Axis": 1,
223 | "Input": 2
224 | }, {
225 | "Id": "ParamEyeBallX",
226 | "Min": -1.0,
227 | "Max": 1.0,
228 | "DefaultValue": 0.0,
229 | "BlendMode": 1,
230 | "Input": 1
231 | }, {
232 | "Id": "ParamEyeBallY",
233 | "Min": -1.0,
234 | "Max": 1.0,
235 | "DefaultValue": 0.0,
236 | "BlendMode": 1,
237 | "Axis": 1,
238 | "Input": 2
239 | }],
240 | "Enabled": true
241 | },
242 | "AutoBreath": {
243 | "Enabled": true
244 | },
245 | "ExtraMotion": {
246 | "Enabled": true
247 | },
248 | "Accelerometer": {
249 | "Enabled": true
250 | },
251 | "Microphone": {},
252 | "Transform": {},
253 | "FaceTracking": {
254 | "Enabled": true
255 | },
256 | "ParamValue": {},
257 | "PartOpacity": {
258 | "Items": [{
259 | "Name": "猫耳",
260 | "Ids": ["Part23", "weiba_Skinning"]
261 | }, {
262 | "Name": "墨镜",
263 | "Ids": ["Part26"]
264 | }],
265 | "Enabled": true
266 | },
267 | "ArtmeshOpacity": {},
268 | "ArtmeshColor": {},
269 | "ArtmeshCulling": {
270 | "DefaultMode": 0
271 | },
272 | "IntimacySystem": {}
273 | },
274 | "HitAreas": [{
275 | "Name": "左手",
276 | "Id": "ArtMesh2"
277 | }, {
278 | "Name": "右手",
279 | "Id": "ArtMesh87"
280 | }, {
281 | "Name": "腰",
282 | "Id": "yao"
283 | }, {
284 | "Name": "中间刘海",
285 | "Id": "ArtMesh26"
286 | }, {
287 | "Name": "嘴",
288 | "Id": "ArtMesh35"
289 | }, {
290 | "Name": "胸口项链",
291 | "Id": "ArtMesh45"
292 | }, {
293 | "Name": "脖子",
294 | "Id": "ArtMesh52"
295 | }, {
296 | "Name": " 右边头饰小花",
297 | "Id": "hua2"
298 | }, {
299 | "Name": "右头饰",
300 | "Id": "ArtMesh19"
301 | }, {
302 | "Name": "右眼",
303 | "Id": "qiu"
304 | }, {
305 | "Name": "左眼",
306 | "Id": "ArtMesh42"
307 | }, {
308 | "Name": "右马尾 ",
309 | "Id": "R8"
310 | }, {
311 | "Name": "左马尾",
312 | "Id": "L4"
313 | }, {
314 | "Name": "右手臂",
315 | "Id": "ArtMesh48"
316 | }, {
317 | "Name": "左中马尾",
318 | "Id": "L6"
319 | }],
320 | "Options": {
321 | "TexFixed": true
322 | }
323 | }
--------------------------------------------------------------------------------
/res/live2d/models/Ava/motions/Ava_shake01.motion3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "Meta": {
4 | "Duration": 3.6,
5 | "Fps": 30.0,
6 | "Loop": true,
7 | "AreBeziersRestricted": true,
8 | "CurveCount": 67,
9 | "TotalSegmentCount": 88,
10 | "TotalPointCount": 201,
11 | "UserDataCount": 0,
12 | "TotalUserDataSize": 0
13 | },
14 | "Curves": [
15 | {
16 | "Target": "Parameter",
17 | "Id": "ParamAngleX",
18 | "Segments": [
19 | 0,
20 | 0,
21 | 1,
22 | 0.111,
23 | 0,
24 | 0.222,
25 | -1,
26 | 0.333,
27 | -1,
28 | 1,
29 | 0.444,
30 | -1,
31 | 0.556,
32 | 11,
33 | 0.667,
34 | 11,
35 | 1,
36 | 0.8,
37 | 11,
38 | 0.933,
39 | 5.553,
40 | 1.067,
41 | -1,
42 | 1,
43 | 1.222,
44 | -8.646,
45 | 1.378,
46 | -11,
47 | 1.533,
48 | -11,
49 | 1,
50 | 1.689,
51 | -11,
52 | 1.844,
53 | 2,
54 | 2,
55 | 2,
56 | 0,
57 | 3.6,
58 | 2
59 | ]
60 | },
61 | {
62 | "Target": "Parameter",
63 | "Id": "ParamAngleY",
64 | "Segments": [
65 | 0,
66 | -1,
67 | 1,
68 | 0.111,
69 | -1,
70 | 0.222,
71 | 9,
72 | 0.333,
73 | 9,
74 | 1,
75 | 0.444,
76 | 9,
77 | 0.556,
78 | 4.623,
79 | 0.667,
80 | -1,
81 | 1,
82 | 0.8,
83 | -7.747,
84 | 0.933,
85 | -10,
86 | 1.067,
87 | -10,
88 | 1,
89 | 1.222,
90 | -10,
91 | 1.378,
92 | -10.304,
93 | 1.533,
94 | -4,
95 | 1,
96 | 1.689,
97 | 2.304,
98 | 1.844,
99 | 30,
100 | 2,
101 | 30,
102 | 0,
103 | 3.6,
104 | 30
105 | ]
106 | },
107 | {
108 | "Target": "Parameter",
109 | "Id": "ParamAngleZ",
110 | "Segments": [
111 | 0,
112 | 0.101,
113 | 1,
114 | 0.211,
115 | 1.365,
116 | 0.422,
117 | 14,
118 | 0.633,
119 | 14,
120 | 1,
121 | 1.078,
122 | 14,
123 | 1.522,
124 | -15,
125 | 1.967,
126 | -15,
127 | 1,
128 | 2.511,
129 | -15,
130 | 3.056,
131 | 10,
132 | 3.6,
133 | 10
134 | ]
135 | },
136 | {
137 | "Target": "Parameter",
138 | "Id": "ParamBodyAngleX",
139 | "Segments": [
140 | 0,
141 | -2,
142 | 0,
143 | 3.6,
144 | -2
145 | ]
146 | },
147 | {
148 | "Target": "Parameter",
149 | "Id": "ParamBodyAngleY",
150 | "Segments": [
151 | 0,
152 | 0,
153 | 0,
154 | 3.6,
155 | 0
156 | ]
157 | },
158 | {
159 | "Target": "Parameter",
160 | "Id": "ParamBodyAngleZ",
161 | "Segments": [
162 | 0,
163 | 0,
164 | 1,
165 | 0.211,
166 | 0,
167 | 0.422,
168 | 10,
169 | 0.633,
170 | 10,
171 | 1,
172 | 1.078,
173 | 10,
174 | 1.522,
175 | -6,
176 | 1.967,
177 | -6,
178 | 1,
179 | 2.511,
180 | -6,
181 | 3.056,
182 | 2,
183 | 3.6,
184 | 2
185 | ]
186 | },
187 | {
188 | "Target": "Parameter",
189 | "Id": "ParamCheek",
190 | "Segments": [
191 | 0,
192 | 0,
193 | 0,
194 | 3.6,
195 | 0
196 | ]
197 | },
198 | {
199 | "Target": "Parameter",
200 | "Id": "Param12",
201 | "Segments": [
202 | 0,
203 | 0,
204 | 0,
205 | 3.6,
206 | 0
207 | ]
208 | },
209 | {
210 | "Target": "Parameter",
211 | "Id": "ParamEyeLOpen",
212 | "Segments": [
213 | 0,
214 | 1,
215 | 0,
216 | 3.6,
217 | 1
218 | ]
219 | },
220 | {
221 | "Target": "Parameter",
222 | "Id": "ParamEyeLSmile",
223 | "Segments": [
224 | 0,
225 | 0,
226 | 0,
227 | 3.6,
228 | 0
229 | ]
230 | },
231 | {
232 | "Target": "Parameter",
233 | "Id": "ParamEyeROpen",
234 | "Segments": [
235 | 0,
236 | 1,
237 | 0,
238 | 3.6,
239 | 1
240 | ]
241 | },
242 | {
243 | "Target": "Parameter",
244 | "Id": "ParamEyeRSmile",
245 | "Segments": [
246 | 0,
247 | 0,
248 | 0,
249 | 3.6,
250 | 0
251 | ]
252 | },
253 | {
254 | "Target": "Parameter",
255 | "Id": "ParamEyeBallX",
256 | "Segments": [
257 | 0,
258 | 0,
259 | 0,
260 | 3.6,
261 | 0
262 | ]
263 | },
264 | {
265 | "Target": "Parameter",
266 | "Id": "ParamEyeBallY",
267 | "Segments": [
268 | 0,
269 | 0,
270 | 0,
271 | 3.6,
272 | 0
273 | ]
274 | },
275 | {
276 | "Target": "Parameter",
277 | "Id": "ParamBrowLX",
278 | "Segments": [
279 | 0,
280 | 0,
281 | 0,
282 | 3.6,
283 | 0
284 | ]
285 | },
286 | {
287 | "Target": "Parameter",
288 | "Id": "ParamBrowLY",
289 | "Segments": [
290 | 0,
291 | 0,
292 | 0,
293 | 3.6,
294 | 0
295 | ]
296 | },
297 | {
298 | "Target": "Parameter",
299 | "Id": "ParamBrowRX",
300 | "Segments": [
301 | 0,
302 | 0,
303 | 0,
304 | 3.6,
305 | 0
306 | ]
307 | },
308 | {
309 | "Target": "Parameter",
310 | "Id": "ParamBrowRY",
311 | "Segments": [
312 | 0,
313 | 0,
314 | 0,
315 | 3.6,
316 | 0
317 | ]
318 | },
319 | {
320 | "Target": "Parameter",
321 | "Id": "ParamBrowLAngle",
322 | "Segments": [
323 | 0,
324 | -0.3,
325 | 0,
326 | 3.6,
327 | -0.3
328 | ]
329 | },
330 | {
331 | "Target": "Parameter",
332 | "Id": "ParamBrowRAngle",
333 | "Segments": [
334 | 0,
335 | -0.3,
336 | 0,
337 | 3.6,
338 | -0.3
339 | ]
340 | },
341 | {
342 | "Target": "Parameter",
343 | "Id": "ParamBrowRForm",
344 | "Segments": [
345 | 0,
346 | 0,
347 | 1,
348 | 0.067,
349 | 0,
350 | 0.133,
351 | -0.2,
352 | 0.2,
353 | -0.2,
354 | 0,
355 | 3.6,
356 | -0.2
357 | ]
358 | },
359 | {
360 | "Target": "Parameter",
361 | "Id": "ParamBrowLForm",
362 | "Segments": [
363 | 0,
364 | 0,
365 | 1,
366 | 0.067,
367 | 0,
368 | 0.133,
369 | -0.2,
370 | 0.2,
371 | -0.2,
372 | 0,
373 | 3.6,
374 | -0.2
375 | ]
376 | },
377 | {
378 | "Target": "Parameter",
379 | "Id": "ParamMouthForm",
380 | "Segments": [
381 | 0,
382 | -0.8,
383 | 1,
384 | 0.067,
385 | -0.8,
386 | 0.133,
387 | -1,
388 | 0.2,
389 | -1,
390 | 0,
391 | 3.6,
392 | -1
393 | ]
394 | },
395 | {
396 | "Target": "Parameter",
397 | "Id": "ParamMouthOpenY",
398 | "Segments": [
399 | 0,
400 | 0,
401 | 1,
402 | 0.067,
403 | 0,
404 | 0.133,
405 | 0.9,
406 | 0.2,
407 | 0.9,
408 | 0,
409 | 3.6,
410 | 0.9
411 | ]
412 | },
413 | {
414 | "Target": "Parameter",
415 | "Id": "Param26",
416 | "Segments": [
417 | 0,
418 | 0,
419 | 0,
420 | 3.6,
421 | 0
422 | ]
423 | },
424 | {
425 | "Target": "Parameter",
426 | "Id": "Param27",
427 | "Segments": [
428 | 0,
429 | 0,
430 | 0,
431 | 3.6,
432 | 0
433 | ]
434 | },
435 | {
436 | "Target": "Parameter",
437 | "Id": "Param28",
438 | "Segments": [
439 | 0,
440 | 0,
441 | 0,
442 | 3.6,
443 | 0
444 | ]
445 | },
446 | {
447 | "Target": "Parameter",
448 | "Id": "Param29",
449 | "Segments": [
450 | 0,
451 | 0,
452 | 0,
453 | 3.6,
454 | 0
455 | ]
456 | },
457 | {
458 | "Target": "Parameter",
459 | "Id": "Param15",
460 | "Segments": [
461 | 0,
462 | -30,
463 | 0,
464 | 0.033,
465 | -30,
466 | 1,
467 | 0.433,
468 | -30,
469 | 0.833,
470 | 30,
471 | 1.233,
472 | 30,
473 | 1,
474 | 1.678,
475 | 30,
476 | 2.122,
477 | -30,
478 | 2.567,
479 | -30,
480 | 1,
481 | 2.911,
482 | -30,
483 | 3.256,
484 | -0.217,
485 | 3.6,
486 | 17.382
487 | ]
488 | },
489 | {
490 | "Target": "PartOpacity",
491 | "Id": "Part23",
492 | "Segments": [
493 | 0,
494 | 0,
495 | 0,
496 | 3.6,
497 | 0
498 | ]
499 | },
500 | {
501 | "Target": "PartOpacity",
502 | "Id": "weiba_Skinning",
503 | "Segments": [
504 | 0,
505 | 0,
506 | 0,
507 | 3.6,
508 | 0
509 | ]
510 | },
511 | {
512 | "Target": "PartOpacity",
513 | "Id": "neko",
514 | "Segments": [
515 | 0,
516 | 0,
517 | 0,
518 | 3.6,
519 | 0
520 | ]
521 | },
522 | {
523 | "Target": "PartOpacity",
524 | "Id": "game",
525 | "Segments": [
526 | 0,
527 | 0,
528 | 0,
529 | 3.6,
530 | 0
531 | ]
532 | },
533 | {
534 | "Target": "PartOpacity",
535 | "Id": "gitar",
536 | "Segments": [
537 | 0,
538 | 0,
539 | 0,
540 | 3.6,
541 | 0
542 | ]
543 | },
544 | {
545 | "Target": "PartOpacity",
546 | "Id": "Part26",
547 | "Segments": [
548 | 0,
549 | 0,
550 | 0,
551 | 3.6,
552 | 0
553 | ]
554 | },
555 | {
556 | "Target": "PartOpacity",
557 | "Id": "Part15",
558 | "Segments": [
559 | 0,
560 | 1,
561 | 0,
562 | 3.6,
563 | 1
564 | ]
565 | },
566 | {
567 | "Target": "PartOpacity",
568 | "Id": "Part6",
569 | "Segments": [
570 | 0,
571 | 1,
572 | 0,
573 | 3.6,
574 | 1
575 | ]
576 | },
577 | {
578 | "Target": "PartOpacity",
579 | "Id": "Part",
580 | "Segments": [
581 | 0,
582 | 0,
583 | 0,
584 | 3.6,
585 | 0
586 | ]
587 | },
588 | {
589 | "Target": "PartOpacity",
590 | "Id": "things",
591 | "Segments": [
592 | 0,
593 | 0,
594 | 0,
595 | 3.6,
596 | 0
597 | ]
598 | },
599 | {
600 | "Target": "PartOpacity",
601 | "Id": "Part11",
602 | "Segments": [
603 | 0,
604 | 0,
605 | 0,
606 | 3.6,
607 | 0
608 | ]
609 | },
610 | {
611 | "Target": "PartOpacity",
612 | "Id": "Part12",
613 | "Segments": [
614 | 0,
615 | 0,
616 | 0,
617 | 3.6,
618 | 0
619 | ]
620 | },
621 | {
622 | "Target": "PartOpacity",
623 | "Id": "Part13",
624 | "Segments": [
625 | 0,
626 | 0,
627 | 0,
628 | 3.6,
629 | 0
630 | ]
631 | },
632 | {
633 | "Target": "PartOpacity",
634 | "Id": "Part14",
635 | "Segments": [
636 | 0,
637 | 0,
638 | 0,
639 | 3.6,
640 | 0
641 | ]
642 | },
643 | {
644 | "Target": "PartOpacity",
645 | "Id": "Part16",
646 | "Segments": [
647 | 0,
648 | 0,
649 | 0,
650 | 3.6,
651 | 0
652 | ]
653 | },
654 | {
655 | "Target": "PartOpacity",
656 | "Id": "Part2",
657 | "Segments": [
658 | 0,
659 | 1,
660 | 0,
661 | 3.6,
662 | 1
663 | ]
664 | },
665 | {
666 | "Target": "PartOpacity",
667 | "Id": "Part3",
668 | "Segments": [
669 | 0,
670 | 1,
671 | 0,
672 | 3.6,
673 | 1
674 | ]
675 | },
676 | {
677 | "Target": "PartOpacity",
678 | "Id": "hair",
679 | "Segments": [
680 | 0,
681 | 1,
682 | 0,
683 | 3.6,
684 | 1
685 | ]
686 | },
687 | {
688 | "Target": "PartOpacity",
689 | "Id": "eyebrows",
690 | "Segments": [
691 | 0,
692 | 1,
693 | 0,
694 | 3.6,
695 | 1
696 | ]
697 | },
698 | {
699 | "Target": "PartOpacity",
700 | "Id": "Part4",
701 | "Segments": [
702 | 0,
703 | 0,
704 | 0,
705 | 3.6,
706 | 0
707 | ]
708 | },
709 | {
710 | "Target": "PartOpacity",
711 | "Id": "mouth",
712 | "Segments": [
713 | 0,
714 | 1,
715 | 0,
716 | 3.6,
717 | 1
718 | ]
719 | },
720 | {
721 | "Target": "PartOpacity",
722 | "Id": "Part5",
723 | "Segments": [
724 | 0,
725 | 1,
726 | 0,
727 | 3.6,
728 | 1
729 | ]
730 | },
731 | {
732 | "Target": "PartOpacity",
733 | "Id": "Part20",
734 | "Segments": [
735 | 0,
736 | 0,
737 | 0,
738 | 3.6,
739 | 0
740 | ]
741 | },
742 | {
743 | "Target": "PartOpacity",
744 | "Id": "Part19",
745 | "Segments": [
746 | 0,
747 | 0,
748 | 0,
749 | 3.6,
750 | 0
751 | ]
752 | },
753 | {
754 | "Target": "PartOpacity",
755 | "Id": "Part18",
756 | "Segments": [
757 | 0,
758 | 1,
759 | 0,
760 | 3.6,
761 | 1
762 | ]
763 | },
764 | {
765 | "Target": "PartOpacity",
766 | "Id": "Part17",
767 | "Segments": [
768 | 0,
769 | 0,
770 | 0,
771 | 3.6,
772 | 0
773 | ]
774 | },
775 | {
776 | "Target": "PartOpacity",
777 | "Id": "Part7",
778 | "Segments": [
779 | 0,
780 | 0,
781 | 0,
782 | 3.6,
783 | 0
784 | ]
785 | },
786 | {
787 | "Target": "PartOpacity",
788 | "Id": "Leye",
789 | "Segments": [
790 | 0,
791 | 0,
792 | 0,
793 | 3.6,
794 | 0
795 | ]
796 | },
797 | {
798 | "Target": "PartOpacity",
799 | "Id": "face",
800 | "Segments": [
801 | 0,
802 | 1,
803 | 0,
804 | 3.6,
805 | 1
806 | ]
807 | },
808 | {
809 | "Target": "PartOpacity",
810 | "Id": "Part8",
811 | "Segments": [
812 | 0,
813 | 1,
814 | 0,
815 | 3.6,
816 | 1
817 | ]
818 | },
819 | {
820 | "Target": "PartOpacity",
821 | "Id": "body",
822 | "Segments": [
823 | 0,
824 | 1,
825 | 0,
826 | 3.6,
827 | 1
828 | ]
829 | },
830 | {
831 | "Target": "PartOpacity",
832 | "Id": "Part25",
833 | "Segments": [
834 | 0,
835 | 1,
836 | 0,
837 | 3.6,
838 | 1
839 | ]
840 | },
841 | {
842 | "Target": "PartOpacity",
843 | "Id": "Part24",
844 | "Segments": [
845 | 0,
846 | 1,
847 | 0,
848 | 3.6,
849 | 1
850 | ]
851 | },
852 | {
853 | "Target": "PartOpacity",
854 | "Id": "Part22",
855 | "Segments": [
856 | 0,
857 | 1,
858 | 0,
859 | 3.6,
860 | 1
861 | ]
862 | },
863 | {
864 | "Target": "PartOpacity",
865 | "Id": "Part21",
866 | "Segments": [
867 | 0,
868 | 1,
869 | 0,
870 | 3.6,
871 | 1
872 | ]
873 | },
874 | {
875 | "Target": "PartOpacity",
876 | "Id": "Part9",
877 | "Segments": [
878 | 0,
879 | 1,
880 | 0,
881 | 3.6,
882 | 1
883 | ]
884 | },
885 | {
886 | "Target": "PartOpacity",
887 | "Id": "Part10",
888 | "Segments": [
889 | 0,
890 | 1,
891 | 0,
892 | 3.6,
893 | 1
894 | ]
895 | },
896 | {
897 | "Target": "PartOpacity",
898 | "Id": "PartSketch0",
899 | "Segments": [
900 | 0,
901 | 1,
902 | 0,
903 | 3.6,
904 | 1
905 | ]
906 | }
907 | ]
908 | }
--------------------------------------------------------------------------------
/res/live2d/models/Ava/motions/Ava_tap09.motion3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "Meta": {
4 | "Duration": 2.4,
5 | "Fps": 30.0,
6 | "Loop": true,
7 | "AreBeziersRestricted": true,
8 | "CurveCount": 68,
9 | "TotalSegmentCount": 89,
10 | "TotalPointCount": 191,
11 | "UserDataCount": 0,
12 | "TotalUserDataSize": 0
13 | },
14 | "Curves": [
15 | {
16 | "Target": "Parameter",
17 | "Id": "ParamAngleX",
18 | "Segments": [
19 | 0,
20 | 0,
21 | 1,
22 | 0.144,
23 | 0,
24 | 0.289,
25 | 1,
26 | 0.433,
27 | 1,
28 | 0,
29 | 2.4,
30 | 1
31 | ]
32 | },
33 | {
34 | "Target": "Parameter",
35 | "Id": "ParamAngleY",
36 | "Segments": [
37 | 0,
38 | -1,
39 | 1,
40 | 0.144,
41 | -1,
42 | 0.289,
43 | 20,
44 | 0.433,
45 | 20,
46 | 0,
47 | 2.4,
48 | 20
49 | ]
50 | },
51 | {
52 | "Target": "Parameter",
53 | "Id": "ParamAngleZ",
54 | "Segments": [
55 | 0,
56 | 0,
57 | 0,
58 | 2.4,
59 | 0
60 | ]
61 | },
62 | {
63 | "Target": "Parameter",
64 | "Id": "ParamBodyAngleX",
65 | "Segments": [
66 | 0,
67 | 0,
68 | 0,
69 | 2.4,
70 | 0
71 | ]
72 | },
73 | {
74 | "Target": "Parameter",
75 | "Id": "ParamBodyAngleY",
76 | "Segments": [
77 | 0,
78 | 0,
79 | 1,
80 | 0.144,
81 | 0,
82 | 0.289,
83 | 10,
84 | 0.433,
85 | 10,
86 | 0,
87 | 2.4,
88 | 10
89 | ]
90 | },
91 | {
92 | "Target": "Parameter",
93 | "Id": "ParamBodyAngleZ",
94 | "Segments": [
95 | 0,
96 | 0,
97 | 0,
98 | 2.4,
99 | 0
100 | ]
101 | },
102 | {
103 | "Target": "Parameter",
104 | "Id": "ParamCheek",
105 | "Segments": [
106 | 0,
107 | 0,
108 | 0,
109 | 2.4,
110 | 0
111 | ]
112 | },
113 | {
114 | "Target": "Parameter",
115 | "Id": "Param12",
116 | "Segments": [
117 | 0,
118 | 0,
119 | 0,
120 | 2.4,
121 | 0
122 | ]
123 | },
124 | {
125 | "Target": "Parameter",
126 | "Id": "ParamEyeLOpen",
127 | "Segments": [
128 | 0,
129 | 0.944,
130 | 1,
131 | 0.144,
132 | 0.971,
133 | 0.289,
134 | 1,
135 | 0.433,
136 | 1,
137 | 1,
138 | 0.7,
139 | 1,
140 | 0.967,
141 | 1,
142 | 1.233,
143 | 1,
144 | 1,
145 | 1.278,
146 | 1,
147 | 1.322,
148 | 0,
149 | 1.367,
150 | 0,
151 | 1,
152 | 1.411,
153 | 0,
154 | 1.456,
155 | 1,
156 | 1.5,
157 | 1,
158 | 0,
159 | 2.4,
160 | 1
161 | ]
162 | },
163 | {
164 | "Target": "Parameter",
165 | "Id": "ParamEyeLSmile",
166 | "Segments": [
167 | 0,
168 | 0,
169 | 0,
170 | 2.4,
171 | 0
172 | ]
173 | },
174 | {
175 | "Target": "Parameter",
176 | "Id": "ParamEyeROpen",
177 | "Segments": [
178 | 0,
179 | 0.944,
180 | 1,
181 | 0.144,
182 | 0.971,
183 | 0.289,
184 | 1,
185 | 0.433,
186 | 1,
187 | 1,
188 | 0.7,
189 | 1,
190 | 0.967,
191 | 1,
192 | 1.233,
193 | 1,
194 | 1,
195 | 1.278,
196 | 1,
197 | 1.322,
198 | 0,
199 | 1.367,
200 | 0,
201 | 1,
202 | 1.411,
203 | 0,
204 | 1.456,
205 | 1,
206 | 1.5,
207 | 1,
208 | 0,
209 | 2.4,
210 | 1
211 | ]
212 | },
213 | {
214 | "Target": "Parameter",
215 | "Id": "ParamEyeRSmile",
216 | "Segments": [
217 | 0,
218 | 0,
219 | 0,
220 | 2.4,
221 | 0
222 | ]
223 | },
224 | {
225 | "Target": "Parameter",
226 | "Id": "ParamEyeBallX",
227 | "Segments": [
228 | 0,
229 | 0,
230 | 0,
231 | 2.4,
232 | 0
233 | ]
234 | },
235 | {
236 | "Target": "Parameter",
237 | "Id": "ParamEyeBallY",
238 | "Segments": [
239 | 0,
240 | 0,
241 | 0,
242 | 2.4,
243 | 0
244 | ]
245 | },
246 | {
247 | "Target": "Parameter",
248 | "Id": "ParamBrowLX",
249 | "Segments": [
250 | 0,
251 | 0,
252 | 0,
253 | 2.4,
254 | 0
255 | ]
256 | },
257 | {
258 | "Target": "Parameter",
259 | "Id": "ParamBrowLY",
260 | "Segments": [
261 | 0,
262 | 0,
263 | 1,
264 | 0.156,
265 | 0,
266 | 0.311,
267 | 0.5,
268 | 0.467,
269 | 0.5,
270 | 0,
271 | 2.4,
272 | 0.5
273 | ]
274 | },
275 | {
276 | "Target": "Parameter",
277 | "Id": "ParamBrowRX",
278 | "Segments": [
279 | 0,
280 | 0,
281 | 0,
282 | 2.4,
283 | 0
284 | ]
285 | },
286 | {
287 | "Target": "Parameter",
288 | "Id": "ParamBrowRY",
289 | "Segments": [
290 | 0,
291 | 0,
292 | 1,
293 | 0.156,
294 | 0,
295 | 0.311,
296 | 0.5,
297 | 0.467,
298 | 0.5,
299 | 0,
300 | 2.4,
301 | 0.5
302 | ]
303 | },
304 | {
305 | "Target": "Parameter",
306 | "Id": "ParamBrowLAngle",
307 | "Segments": [
308 | 0,
309 | -0.3,
310 | 0,
311 | 2.4,
312 | -0.3
313 | ]
314 | },
315 | {
316 | "Target": "Parameter",
317 | "Id": "ParamBrowRAngle",
318 | "Segments": [
319 | 0,
320 | -0.3,
321 | 0,
322 | 2.4,
323 | -0.3
324 | ]
325 | },
326 | {
327 | "Target": "Parameter",
328 | "Id": "ParamBrowRForm",
329 | "Segments": [
330 | 0,
331 | 0,
332 | 0,
333 | 2.4,
334 | 0
335 | ]
336 | },
337 | {
338 | "Target": "Parameter",
339 | "Id": "ParamBrowLForm",
340 | "Segments": [
341 | 0,
342 | 0,
343 | 0,
344 | 2.4,
345 | 0
346 | ]
347 | },
348 | {
349 | "Target": "Parameter",
350 | "Id": "ParamMouthForm",
351 | "Segments": [
352 | 0,
353 | -0.8,
354 | 1,
355 | 0.144,
356 | -0.8,
357 | 0.289,
358 | -0.5,
359 | 0.433,
360 | -0.5,
361 | 0,
362 | 2.4,
363 | -0.5
364 | ]
365 | },
366 | {
367 | "Target": "Parameter",
368 | "Id": "ParamMouthOpenY",
369 | "Segments": [
370 | 0,
371 | 0,
372 | 1,
373 | 0.144,
374 | 0,
375 | 0.289,
376 | 0.6,
377 | 0.433,
378 | 0.6,
379 | 0,
380 | 2.4,
381 | 0.6
382 | ]
383 | },
384 | {
385 | "Target": "Parameter",
386 | "Id": "Param26",
387 | "Segments": [
388 | 0,
389 | 0,
390 | 0,
391 | 2.4,
392 | 0
393 | ]
394 | },
395 | {
396 | "Target": "Parameter",
397 | "Id": "Param27",
398 | "Segments": [
399 | 0,
400 | 0,
401 | 0,
402 | 2.4,
403 | 0
404 | ]
405 | },
406 | {
407 | "Target": "Parameter",
408 | "Id": "Param28",
409 | "Segments": [
410 | 0,
411 | 0,
412 | 0,
413 | 2.4,
414 | 0
415 | ]
416 | },
417 | {
418 | "Target": "Parameter",
419 | "Id": "Param29",
420 | "Segments": [
421 | 0,
422 | 0,
423 | 0,
424 | 2.4,
425 | 0
426 | ]
427 | },
428 | {
429 | "Target": "Parameter",
430 | "Id": "Param24",
431 | "Segments": [
432 | 0,
433 | 30,
434 | 1,
435 | 0.089,
436 | 30,
437 | 0.178,
438 | -8,
439 | 0.267,
440 | -8,
441 | 0,
442 | 2.4,
443 | -8
444 | ]
445 | },
446 | {
447 | "Target": "Parameter",
448 | "Id": "Param17",
449 | "Segments": [
450 | 0,
451 | -22,
452 | 0,
453 | 0.267,
454 | -22,
455 | 1,
456 | 0.3,
457 | -22,
458 | 0.333,
459 | 30,
460 | 0.367,
461 | 30,
462 | 0,
463 | 2.4,
464 | 30
465 | ]
466 | },
467 | {
468 | "Target": "PartOpacity",
469 | "Id": "Part23",
470 | "Segments": [
471 | 0,
472 | 0,
473 | 0,
474 | 2.4,
475 | 0
476 | ]
477 | },
478 | {
479 | "Target": "PartOpacity",
480 | "Id": "weiba_Skinning",
481 | "Segments": [
482 | 0,
483 | 0,
484 | 0,
485 | 2.4,
486 | 0
487 | ]
488 | },
489 | {
490 | "Target": "PartOpacity",
491 | "Id": "neko",
492 | "Segments": [
493 | 0,
494 | 0,
495 | 0,
496 | 2.4,
497 | 0
498 | ]
499 | },
500 | {
501 | "Target": "PartOpacity",
502 | "Id": "game",
503 | "Segments": [
504 | 0,
505 | 0,
506 | 0,
507 | 2.4,
508 | 0
509 | ]
510 | },
511 | {
512 | "Target": "PartOpacity",
513 | "Id": "gitar",
514 | "Segments": [
515 | 0,
516 | 0,
517 | 0,
518 | 2.4,
519 | 0
520 | ]
521 | },
522 | {
523 | "Target": "PartOpacity",
524 | "Id": "Part26",
525 | "Segments": [
526 | 0,
527 | 0,
528 | 0,
529 | 2.4,
530 | 0
531 | ]
532 | },
533 | {
534 | "Target": "PartOpacity",
535 | "Id": "Part15",
536 | "Segments": [
537 | 0,
538 | 1,
539 | 0,
540 | 2.4,
541 | 1
542 | ]
543 | },
544 | {
545 | "Target": "PartOpacity",
546 | "Id": "Part6",
547 | "Segments": [
548 | 0,
549 | 1,
550 | 0,
551 | 2.4,
552 | 1
553 | ]
554 | },
555 | {
556 | "Target": "PartOpacity",
557 | "Id": "Part",
558 | "Segments": [
559 | 0,
560 | 0,
561 | 0,
562 | 2.4,
563 | 0
564 | ]
565 | },
566 | {
567 | "Target": "PartOpacity",
568 | "Id": "things",
569 | "Segments": [
570 | 0,
571 | 0,
572 | 2,
573 | 0.3,
574 | 1,
575 | 0,
576 | 2.4,
577 | 1
578 | ]
579 | },
580 | {
581 | "Target": "PartOpacity",
582 | "Id": "Part11",
583 | "Segments": [
584 | 0,
585 | 0,
586 | 0,
587 | 2.4,
588 | 0
589 | ]
590 | },
591 | {
592 | "Target": "PartOpacity",
593 | "Id": "Part12",
594 | "Segments": [
595 | 0,
596 | 0,
597 | 0,
598 | 2.4,
599 | 0
600 | ]
601 | },
602 | {
603 | "Target": "PartOpacity",
604 | "Id": "Part13",
605 | "Segments": [
606 | 0,
607 | 0,
608 | 0,
609 | 2.4,
610 | 0
611 | ]
612 | },
613 | {
614 | "Target": "PartOpacity",
615 | "Id": "Part14",
616 | "Segments": [
617 | 0,
618 | 0,
619 | 2,
620 | 0.3,
621 | 0,
622 | 0,
623 | 2.4,
624 | 0
625 | ]
626 | },
627 | {
628 | "Target": "PartOpacity",
629 | "Id": "Part16",
630 | "Segments": [
631 | 0,
632 | 0,
633 | 2,
634 | 0.3,
635 | 1,
636 | 0,
637 | 2.4,
638 | 1
639 | ]
640 | },
641 | {
642 | "Target": "PartOpacity",
643 | "Id": "Part2",
644 | "Segments": [
645 | 0,
646 | 1,
647 | 0,
648 | 2.4,
649 | 1
650 | ]
651 | },
652 | {
653 | "Target": "PartOpacity",
654 | "Id": "Part3",
655 | "Segments": [
656 | 0,
657 | 1,
658 | 0,
659 | 2.4,
660 | 1
661 | ]
662 | },
663 | {
664 | "Target": "PartOpacity",
665 | "Id": "hair",
666 | "Segments": [
667 | 0,
668 | 1,
669 | 0,
670 | 2.4,
671 | 1
672 | ]
673 | },
674 | {
675 | "Target": "PartOpacity",
676 | "Id": "eyebrows",
677 | "Segments": [
678 | 0,
679 | 1,
680 | 0,
681 | 2.4,
682 | 1
683 | ]
684 | },
685 | {
686 | "Target": "PartOpacity",
687 | "Id": "Part4",
688 | "Segments": [
689 | 0,
690 | 0,
691 | 0,
692 | 2.4,
693 | 0
694 | ]
695 | },
696 | {
697 | "Target": "PartOpacity",
698 | "Id": "mouth",
699 | "Segments": [
700 | 0,
701 | 1,
702 | 0,
703 | 2.4,
704 | 1
705 | ]
706 | },
707 | {
708 | "Target": "PartOpacity",
709 | "Id": "Part5",
710 | "Segments": [
711 | 0,
712 | 0,
713 | 0,
714 | 2.4,
715 | 0
716 | ]
717 | },
718 | {
719 | "Target": "PartOpacity",
720 | "Id": "Part20",
721 | "Segments": [
722 | 0,
723 | 0,
724 | 0,
725 | 2.4,
726 | 0
727 | ]
728 | },
729 | {
730 | "Target": "PartOpacity",
731 | "Id": "Part19",
732 | "Segments": [
733 | 0,
734 | 0,
735 | 0,
736 | 2.4,
737 | 0
738 | ]
739 | },
740 | {
741 | "Target": "PartOpacity",
742 | "Id": "Part18",
743 | "Segments": [
744 | 0,
745 | 0,
746 | 0,
747 | 2.4,
748 | 0
749 | ]
750 | },
751 | {
752 | "Target": "PartOpacity",
753 | "Id": "Part17",
754 | "Segments": [
755 | 0,
756 | 0,
757 | 0,
758 | 2.4,
759 | 0
760 | ]
761 | },
762 | {
763 | "Target": "PartOpacity",
764 | "Id": "Part7",
765 | "Segments": [
766 | 0,
767 | 1,
768 | 0,
769 | 2.4,
770 | 1
771 | ]
772 | },
773 | {
774 | "Target": "PartOpacity",
775 | "Id": "Leye",
776 | "Segments": [
777 | 0,
778 | 1,
779 | 0,
780 | 2.4,
781 | 1
782 | ]
783 | },
784 | {
785 | "Target": "PartOpacity",
786 | "Id": "face",
787 | "Segments": [
788 | 0,
789 | 1,
790 | 0,
791 | 2.4,
792 | 1
793 | ]
794 | },
795 | {
796 | "Target": "PartOpacity",
797 | "Id": "Part8",
798 | "Segments": [
799 | 0,
800 | 1,
801 | 0,
802 | 2.4,
803 | 1
804 | ]
805 | },
806 | {
807 | "Target": "PartOpacity",
808 | "Id": "body",
809 | "Segments": [
810 | 0,
811 | 1,
812 | 0,
813 | 2.4,
814 | 1
815 | ]
816 | },
817 | {
818 | "Target": "PartOpacity",
819 | "Id": "Part25",
820 | "Segments": [
821 | 0,
822 | 1,
823 | 0,
824 | 2.4,
825 | 1
826 | ]
827 | },
828 | {
829 | "Target": "PartOpacity",
830 | "Id": "Part24",
831 | "Segments": [
832 | 0,
833 | 1,
834 | 0,
835 | 2.4,
836 | 1
837 | ]
838 | },
839 | {
840 | "Target": "PartOpacity",
841 | "Id": "Part22",
842 | "Segments": [
843 | 0,
844 | 1,
845 | 0,
846 | 2.4,
847 | 1
848 | ]
849 | },
850 | {
851 | "Target": "PartOpacity",
852 | "Id": "Part21",
853 | "Segments": [
854 | 0,
855 | 1,
856 | 0,
857 | 2.4,
858 | 1
859 | ]
860 | },
861 | {
862 | "Target": "PartOpacity",
863 | "Id": "Part9",
864 | "Segments": [
865 | 0,
866 | 1,
867 | 0,
868 | 2.4,
869 | 1
870 | ]
871 | },
872 | {
873 | "Target": "PartOpacity",
874 | "Id": "Part10",
875 | "Segments": [
876 | 0,
877 | 1,
878 | 0,
879 | 2.4,
880 | 1
881 | ]
882 | },
883 | {
884 | "Target": "PartOpacity",
885 | "Id": "PartSketch0",
886 | "Segments": [
887 | 0,
888 | 1,
889 | 0,
890 | 2.4,
891 | 1
892 | ]
893 | }
894 | ]
895 | }
--------------------------------------------------------------------------------
/res/live2d/models/Ava/raw.ex.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "STM_1_0",
3 | "name": "向晚BY木果",
4 | "id": "1620044467713",
5 | "encrypt": "true",
6 | "version": "1.0",
7 | "list": [{
8 | "id": "",
9 | "character": "character",
10 | "avatar": "4a301072dec6b6a49050e5b294cd7983",
11 | "costume": [{
12 | "name": "costume",
13 | "path": "f01cf984f3e6783ccc8e88e0c8aff5cc.bin3"
14 | }]
15 | }]
16 | }
--------------------------------------------------------------------------------
/res/live2d/models/Ava/raw.model3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "Bounds": {
4 | "Width": 9.772043,
5 | "Height": 11.08606,
6 | "CenterX": 0.1069689,
7 | "CenterY": -1.404058
8 | },
9 | "FileReferences": {
10 | "Moc": "d5586be2b6f3c2d44034440a93f66115.bin3",
11 | "Textures": ["b0078e0cbfe20363c423f01873780c94.bin3"],
12 | "Physics": "09c3193669d8c580df3cea6922677818.bin3",
13 | "PhysicsV2": {
14 | "File": "09c3193669d8c580df3cea6922677818.bin3"
15 | },
16 | "Motions": {
17 | "Idle": [{
18 | "Name": "待机",
19 | "File": "930ccd3afc12a516e72bb864916c1e16.bin3"
20 | }],
21 | "Shake": [{
22 | "Name": "晕",
23 | "File": "45d49cbd99e34340f4e2a08e3aec9646.bin3",
24 | "Text": "啊呜...",
25 | "TextDuration": 2000
26 | }, {
27 | "File": "b77bfecb6a5dee8382906a34f3917255.bin3"
28 | }],
29 | "Tap左手": [{
30 | "Name": "吉他",
31 | "File": "4c70766cf8b2070eaa3f7b384cc266b9.bin3",
32 | "Text": "可爱的鸽子鸽子~我喜欢你~",
33 | "TextDelay": 1200,
34 | "TextDuration": 5600
35 | }],
36 | "Tap右手": [{
37 | "Name": "游戏",
38 | "File": "0f54599feff96877de0dbfb649caad58.bin3",
39 | "Text": "来陪我玩游戏!",
40 | "TextDelay": 600,
41 | "TextDuration": 2500
42 | }],
43 | "Tap腰": [{
44 | "Name": "傲娇",
45 | "File": "e2f024f08042e3ab1d03377bd19a0419.bin3",
46 | "Text": "哼,才不是傲娇大小姐",
47 | "TextDelay": 500,
48 | "TextDuration": 3000
49 | }],
50 | "Tap中间刘海": [{
51 | "Name": "害羞",
52 | "File": "e7e47270b0c9f7f1d6448b944392e0a0.bin3",
53 | "Text": "好...好兄弟之间喜欢很正常啦",
54 | "TextDelay": 1500,
55 | "TextDuration": 3000
56 | }, {
57 | "Name": "害羞2",
58 | "File": "e7e47270b0c9f7f1d6448b944392e0a0.bin3",
59 | "Text": "也...也不是不可以",
60 | "TextDelay": 2000,
61 | "TextDuration": 3000
62 | }],
63 | "Tap嘴": [{
64 | "Name": "傲娇",
65 | "File": "e2f024f08042e3ab1d03377bd19a0419.bin3",
66 | "Text": "什么傲娇啦,我才没有",
67 | "TextDelay": 500,
68 | "TextDuration": 2200
69 | }],
70 | "Tap胸口项链": [{
71 | "Name": "笑",
72 | "File": "5afa7a7ca7dc29f17325dcb8af964a35.bin3"
73 | }],
74 | "Tap脖子": [{
75 | "Name": "监督",
76 | "File": "7e263ff839def59c49d337048df5ce84.bin3",
77 | "Text": "嗯?老戳我干嘛,快去干正事啦 ",
78 | "TextDelay": 550,
79 | "TextDuration": 4000
80 | }],
81 | "Tap 右边头饰小花": [{
82 | "Name": "懒羊羊",
83 | "File": "0db0bd8ff7847014772caad0ae790ebf.bin3",
84 | "Text": "顶晚人...顶晚人在哪里...",
85 | "TextDelay": 800,
86 | "TextDuration": 6000
87 | }],
88 | "Tap右头饰": [{
89 | "Name": "猫",
90 | "File": "19c910845c10e04474236a7cb8f482c8.bin3",
91 | "Text": "neko panch!",
92 | "TextDelay": 500,
93 | "TextDuration": 2000
94 | }],
95 | "Tap右眼": [{
96 | "Name": "惊讶",
97 | "File": "d18b62e12feb89b0a7f603b0eb9efd30.bin3",
98 | "Text": "啊",
99 | "TextDelay": 200,
100 | "TextDuration": 1000
101 | }],
102 | "Tap左眼": [{
103 | "Name": "墨镜",
104 | "File": "23e132e412ad2cb5d1ecbcc8f256b3b0.bin3",
105 | "Text": "嗯哼~我超帅的",
106 | "TextDelay": 700,
107 | "TextDuration": 2000
108 | }],
109 | "Tap右马尾 ": [{
110 | "Name": "水母",
111 | "File": "583ba01a373b1abf564bf4963e3ab433.bin3"
112 | }],
113 | "Tap左马尾": [{
114 | "Name": "><",
115 | "File": "b77bfecb6a5dee8382906a34f3917255.bin3",
116 | "Text": "头发摸乱了啦~",
117 | "TextDelay": 500,
118 | "TextDuration": 2000
119 | }],
120 | "Tap右手臂": [{
121 | "File": "7e263ff839def59c49d337048df5ce84.bin3",
122 | "Text": "嗯?老戳我干嘛,快去干正事啦 ",
123 | "TextDelay": 550,
124 | "TextDuration": 4000
125 | }],
126 | "Tap左中马尾": [{
127 | "File": "583ba01a373b1abf564bf4963e3ab433.bin3"
128 | }]
129 | }
130 | },
131 | "Controllers": {
132 | "ParamHit": {},
133 | "ParamLoop": {},
134 | "KeyTrigger": {},
135 | "EyeBlink": {
136 | "MinInterval": 500,
137 | "MaxInterval": 6000,
138 | "Items": [{
139 | "Id": "ParamEyeLOpen",
140 | "Min": 0.0,
141 | "Max": 1.0,
142 | "BlendMode": 2,
143 | "Input": 0
144 | }, {
145 | "Id": "ParamEyeROpen",
146 | "Min": 0.0,
147 | "Max": 1.0,
148 | "BlendMode": 2,
149 | "Input": 0
150 | }, {
151 | "Id": "Param7",
152 | "Min": 0.0,
153 | "Max": 1.0,
154 | "BlendMode": 2,
155 | "Input": 0
156 | }, {
157 | "Id": "Param8",
158 | "Min": 0.0,
159 | "Max": 1.0,
160 | "BlendMode": 2,
161 | "Input": 0
162 | }],
163 | "Enabled": true
164 | },
165 | "LipSync": {
166 | "Gain": 5.0
167 | },
168 | "MouseTracking": {
169 | "SmoothTime": 0.15,
170 | "Items": [{
171 | "Id": "ParamAngleX",
172 | "Min": -30.0,
173 | "Max": 30.0,
174 | "DefaultValue": 0.0,
175 | "Weight": 0.359834284,
176 | "BlendMode": 1,
177 | "Input": 1
178 | }, {
179 | "Id": "ParamAngleY",
180 | "Min": -30.0,
181 | "Max": 30.0,
182 | "DefaultValue": 0.0,
183 | "Weight": 0.3398514,
184 | "BlendMode": 1,
185 | "Axis": 1,
186 | "Input": 2
187 | }, {
188 | "Id": "ParamAngleZ",
189 | "Min": -15.0,
190 | "Max": 15.0,
191 | "DefaultValue": 0.0,
192 | "Weight": 0.199971348,
193 | "BlendMode": 1,
194 | "Axis": 2,
195 | "Input": 1
196 | }, {
197 | "Id": "ParamBodyAngleX",
198 | "Min": -10.0,
199 | "Max": 10.0,
200 | "DefaultValue": 0.0,
201 | "Weight": 0.376962453,
202 | "BlendMode": 1,
203 | "Input": 1
204 | }, {
205 | "Id": "ParamBodyAngleZ",
206 | "Min": -10.0,
207 | "Max": 10.0,
208 | "DefaultValue": 0.0,
209 | "Weight": 0.365543664,
210 | "BlendMode": 1,
211 | "Axis": 2,
212 | "Input": 1
213 | }, {
214 | "Id": "Param46",
215 | "Min": -30.0,
216 | "Max": 30.0,
217 | "DefaultValue": 0.0,
218 | "Weight": 0.411218822,
219 | "BlendMode": 1,
220 | "Axis": 1,
221 | "Input": 2
222 | }, {
223 | "Id": "ParamEyeBallX",
224 | "Min": -1.0,
225 | "Max": 1.0,
226 | "DefaultValue": 0.0,
227 | "BlendMode": 1,
228 | "Input": 1
229 | }, {
230 | "Id": "ParamEyeBallY",
231 | "Min": -1.0,
232 | "Max": 1.0,
233 | "DefaultValue": 0.0,
234 | "BlendMode": 1,
235 | "Axis": 1,
236 | "Input": 2
237 | }],
238 | "Enabled": true
239 | },
240 | "AutoBreath": {
241 | "Enabled": true
242 | },
243 | "ExtraMotion": {
244 | "Enabled": true
245 | },
246 | "Accelerometer": {
247 | "Enabled": true
248 | },
249 | "Microphone": {},
250 | "Transform": {},
251 | "FaceTracking": {
252 | "Enabled": true
253 | },
254 | "ParamValue": {},
255 | "PartOpacity": {
256 | "Items": [{
257 | "Name": "猫耳",
258 | "Ids": ["Part23", "weiba_Skinning"]
259 | }, {
260 | "Name": "墨镜",
261 | "Ids": ["Part26"]
262 | }],
263 | "Enabled": true
264 | },
265 | "ArtmeshOpacity": {},
266 | "ArtmeshColor": {},
267 | "ArtmeshCulling": {
268 | "DefaultMode": 0
269 | },
270 | "IntimacySystem": {}
271 | },
272 | "HitAreas": [{
273 | "Name": "左手",
274 | "Id": "ArtMesh2"
275 | }, {
276 | "Name": "右手",
277 | "Id": "ArtMesh87"
278 | }, {
279 | "Name": "腰",
280 | "Id": "yao"
281 | }, {
282 | "Name": "中间刘海",
283 | "Id": "ArtMesh26"
284 | }, {
285 | "Name": "嘴",
286 | "Id": "ArtMesh35"
287 | }, {
288 | "Name": "胸口项链",
289 | "Id": "ArtMesh45"
290 | }, {
291 | "Name": "脖子",
292 | "Id": "ArtMesh52"
293 | }, {
294 | "Name": " 右边头饰小花",
295 | "Id": "hua2"
296 | }, {
297 | "Name": "右头饰",
298 | "Id": "ArtMesh19"
299 | }, {
300 | "Name": "右眼",
301 | "Id": "qiu"
302 | }, {
303 | "Name": "左眼",
304 | "Id": "ArtMesh42"
305 | }, {
306 | "Name": "右马尾 ",
307 | "Id": "R8"
308 | }, {
309 | "Name": "左马尾",
310 | "Id": "L4"
311 | }, {
312 | "Name": "右手臂",
313 | "Id": "ArtMesh48"
314 | }, {
315 | "Name": "左中马尾",
316 | "Id": "L6"
317 | }],
318 | "Options": {
319 | "TexFixed": true
320 | }
321 | }
--------------------------------------------------------------------------------
/res/live2d/models/Ava/raw.preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/models/Ava/raw.preview.png
--------------------------------------------------------------------------------
/res/live2d/models/Diana/Diana.4096/texture_00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/models/Diana/Diana.4096/texture_00.png
--------------------------------------------------------------------------------
/res/live2d/models/Diana/Diana.moc3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/models/Diana/Diana.moc3
--------------------------------------------------------------------------------
/res/live2d/models/Diana/Diana.model3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "FileReferences": {
4 | "Moc": "Diana.moc3",
5 | "Textures": [
6 | "Diana.4096/texture_00.png"
7 | ],
8 | "Physics": "Diana.physics3.json",
9 | "PhysicsV2": {
10 | "File": "Diana.physics3.json"
11 | },
12 | "Motions": {
13 | "Idle": [{
14 | "File": "motions/Diana_idle.motion3.json"
15 | }],
16 | "Tap生气 -领结": [{
17 | "File": "motions/Diana_tap01.motion3.json",
18 | "Text": "嘉心糖屁用没有",
19 | "TextDelay": 2000,
20 | "TextDuration": 3000
21 | }],
22 | "Tap= = 左蝴蝶结": [{
23 | "File": "motions/Diana_tap02.motion3.json",
24 | "Text": "有人急了,但我不说是谁~",
25 | "TextDelay": 1000,
26 | "TextDuration": 4000
27 | }],
28 | "Tap笑- 脸": [{
29 | "File": "motions/Diana_tap03.motion3.json",
30 | "Text": "hi!嘉心糖",
31 | "TextDelay": 2200,
32 | "TextDuration": 2300
33 | }],
34 | "Tap哭 -眼角": [{
35 | "File": "motions/Diana_tap04.motion3.json",
36 | "Text": "呜呜...呜呜呜....",
37 | "TextDelay": 3200,
38 | "TextDuration": 4000
39 | }],
40 | "Shake": [{
41 | "File": "motions/Diana_tap05.motion3.json",
42 | "Text": "别摇啦!",
43 | "TextDelay": 1000,
44 | "TextDuration": 2000
45 | }],
46 | "Tap害羞-中间刘海": [{
47 | "File": "motions/Diana_tap06.motion3.json",
48 | "Text": "想然然了没有呀~",
49 | "TextDelay": 1500,
50 | "TextDuration": 3000
51 | }],
52 | "Tap抱阿草-左手": [{
53 | "File": "motions/Diana_tap07.motion3.json",
54 | "Text": "阿草好软呀~",
55 | "TextDelay": 3000,
56 | "TextDuration": 2500
57 | }],
58 | "Tap摇头- 身体": [{
59 | "File": "motions/Diana_tap05.motion3.json",
60 | "Text": "不要再戳啦!好痒!",
61 | "TextDelay": 800,
62 | "TextDuration": 2500
63 | }],
64 | "Tap耳朵-发卡": [{
65 | "File": "motions/Diana_tap08.motion3.json",
66 | "Text": "嗷呜~~~",
67 | "TextDelay": 1500,
68 | "TextDuration": 3000
69 | }],
70 | "Tap打瞌睡- 呆毛": [{
71 | "File": "motions/Diana_tap09.motion3.json",
72 | "Text": "啊",
73 | "TextDelay": 7500,
74 | "TextDuration": 800
75 | }],
76 | "Leave": [{
77 | "File": "motions/Diana_tap09.motion3.json",
78 | "Text": "zzZ。。。",
79 | "TextDelay": 4000,
80 | "TextDuration": 4000
81 | }],
82 | "Tap左头发": [{
83 | "File": "motions/Diana_tap10.motion3.json"
84 | }],
85 | "Tap右头发": [{
86 | "File": "motions/Diana_tap11.motion3.json",
87 | "Text": "哇!好吃的!",
88 | "TextDelay": 500,
89 | "TextDuration": 3000
90 | }]
91 | }
92 | },
93 | "Controllers": {
94 | "ParamHit": {},
95 | "ParamLoop": {},
96 | "KeyTrigger": {},
97 | "EyeBlink": {
98 | "MinInterval": 500,
99 | "MaxInterval": 6000,
100 | "Enabled": true
101 | },
102 | "LipSync": {
103 | "Gain": 5.0
104 | },
105 | "MouseTracking": {
106 | "SmoothTime": 0.15,
107 | "Items": [{
108 | "Id": "ParamBodyAngleX",
109 | "Min": -10.0,
110 | "Max": 10.0,
111 | "DefaultValue": 0.0,
112 | "Weight": 0.76343286,
113 | "BlendMode": 1,
114 | "Input": 1
115 | }, {
116 | "Id": "ParamAngleX",
117 | "Min": -30.0,
118 | "Max": 30.0,
119 | "DefaultValue": 0.0,
120 | "Weight": 0.798328757,
121 | "BlendMode": 1,
122 | "Input": 1
123 | }, {
124 | "Id": "ParamBodyAngleZ",
125 | "Min": -10.0,
126 | "Max": 10.0,
127 | "DefaultValue": 0.0,
128 | "Weight": 0.6260679,
129 | "BlendMode": 1,
130 | "Input": 1
131 | }, {
132 | "Id": "ParamBodyAngleY",
133 | "Min": -10.0,
134 | "Max": 10.0,
135 | "DefaultValue": 0.0,
136 | "Weight": 0.8907613,
137 | "BlendMode": 1,
138 | "Axis": 1,
139 | "Input": 2
140 | }, {
141 | "Id": "ParamAngleY",
142 | "Min": -30.0,
143 | "Max": 30.0,
144 | "DefaultValue": 0.0,
145 | "Weight": 0.7521123,
146 | "BlendMode": 1,
147 | "Axis": 1,
148 | "Input": 2
149 | }],
150 | "Enabled": true
151 | },
152 | "AutoBreath": {
153 | "Enabled": true
154 | },
155 | "ExtraMotion": {
156 | "Enabled": true
157 | },
158 | "Accelerometer": {
159 | "Enabled": true
160 | },
161 | "Microphone": {},
162 | "Transform": {},
163 | "FaceTracking": {
164 | "Enabled": true
165 | },
166 | "ParamValue": {},
167 | "PartOpacity": {},
168 | "ArtmeshOpacity": {},
169 | "ArtmeshColor": {},
170 | "ArtmeshCulling": {
171 | "DefaultMode": 0
172 | },
173 | "IntimacySystem": {}
174 | },
175 | "HitAreas": [{
176 | "Name": "= = 左蝴蝶结",
177 | "Id": "ArtMesh15"
178 | }, {
179 | "Name": "笑- 脸",
180 | "Id": "ArtMesh51"
181 | }, {
182 | "Name": "哭 -眼角",
183 | "Id": "ArtMesh48"
184 | }, {
185 | "Name": "生气 -领结",
186 | "Id": "ArtMesh56"
187 | }, {
188 | "Name": "害羞-中间刘海",
189 | "Id": "ArtMesh10"
190 | }, {
191 | "Name": "抱阿草-左手",
192 | "Id": "L4"
193 | }, {
194 | "Name": "打瞌睡- 呆毛",
195 | "Id": "ArtMesh9"
196 | }, {
197 | "Name": "耳朵-发卡",
198 | "Id": "L3"
199 | }, {
200 | "Name": "摇头- 身体",
201 | "Id": "jiaran"
202 | }, {
203 | "Name": "左头发",
204 | "Id": "L5"
205 | }, {
206 | "Name": "右头发",
207 | "Id": "R5"
208 | }],
209 | "Options": {
210 | "TexFixed": true
211 | }
212 | }
--------------------------------------------------------------------------------
/res/live2d/models/Diana/audio/jiaxintang-nouse.aac:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/models/Diana/audio/jiaxintang-nouse.aac
--------------------------------------------------------------------------------
/res/live2d/models/Diana/motions/Diana_idle.motion3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "Meta": {
4 | "Duration": 7.667,
5 | "Fps": 30.0,
6 | "Loop": true,
7 | "AreBeziersRestricted": true,
8 | "CurveCount": 48,
9 | "TotalSegmentCount": 48,
10 | "TotalPointCount": 96,
11 | "UserDataCount": 0,
12 | "TotalUserDataSize": 0
13 | },
14 | "Curves": [
15 | {
16 | "Target": "Parameter",
17 | "Id": "Param2",
18 | "Segments": [
19 | 0,
20 | -30,
21 | 0,
22 | 7.667,
23 | -30
24 | ]
25 | },
26 | {
27 | "Target": "Parameter",
28 | "Id": "Param35",
29 | "Segments": [
30 | 0,
31 | -30,
32 | 0,
33 | 7.667,
34 | -30
35 | ]
36 | },
37 | {
38 | "Target": "Parameter",
39 | "Id": "Param3",
40 | "Segments": [
41 | 0,
42 | -30,
43 | 0,
44 | 7.667,
45 | -30
46 | ]
47 | },
48 | {
49 | "Target": "Parameter",
50 | "Id": "Param4",
51 | "Segments": [
52 | 0,
53 | -30,
54 | 0,
55 | 7.667,
56 | -30
57 | ]
58 | },
59 | {
60 | "Target": "Parameter",
61 | "Id": "Param5",
62 | "Segments": [
63 | 0,
64 | -30,
65 | 0,
66 | 7.667,
67 | -30
68 | ]
69 | },
70 | {
71 | "Target": "Parameter",
72 | "Id": "Param41",
73 | "Segments": [
74 | 0,
75 | -30,
76 | 0,
77 | 7.667,
78 | -30
79 | ]
80 | },
81 | {
82 | "Target": "Parameter",
83 | "Id": "Param46",
84 | "Segments": [
85 | 0,
86 | -30,
87 | 0,
88 | 7.667,
89 | -30
90 | ]
91 | },
92 | {
93 | "Target": "Parameter",
94 | "Id": "Param45",
95 | "Segments": [
96 | 0,
97 | -30,
98 | 0,
99 | 7.667,
100 | -30
101 | ]
102 | },
103 | {
104 | "Target": "Parameter",
105 | "Id": "Param",
106 | "Segments": [
107 | 0,
108 | -30,
109 | 0,
110 | 7.667,
111 | -30
112 | ]
113 | },
114 | {
115 | "Target": "Parameter",
116 | "Id": "Param8",
117 | "Segments": [
118 | 0,
119 | -30,
120 | 0,
121 | 7.667,
122 | -30
123 | ]
124 | },
125 | {
126 | "Target": "Parameter",
127 | "Id": "Param9",
128 | "Segments": [
129 | 0,
130 | -30,
131 | 0,
132 | 7.667,
133 | -30
134 | ]
135 | },
136 | {
137 | "Target": "Parameter",
138 | "Id": "Param10",
139 | "Segments": [
140 | 0,
141 | -30,
142 | 0,
143 | 7.667,
144 | -30
145 | ]
146 | },
147 | {
148 | "Target": "Parameter",
149 | "Id": "Param6",
150 | "Segments": [
151 | 0,
152 | -29,
153 | 0,
154 | 7.667,
155 | -29
156 | ]
157 | },
158 | {
159 | "Target": "Parameter",
160 | "Id": "Param7",
161 | "Segments": [
162 | 0,
163 | -30,
164 | 0,
165 | 7.667,
166 | -30
167 | ]
168 | },
169 | {
170 | "Target": "Parameter",
171 | "Id": "ParamBodyAngleX",
172 | "Segments": [
173 | 0,
174 | 0,
175 | 0,
176 | 7.667,
177 | 0
178 | ]
179 | },
180 | {
181 | "Target": "Parameter",
182 | "Id": "ParamBodyAngleY",
183 | "Segments": [
184 | 0,
185 | 0,
186 | 0,
187 | 7.667,
188 | 0
189 | ]
190 | },
191 | {
192 | "Target": "Parameter",
193 | "Id": "ParamBodyAngleZ",
194 | "Segments": [
195 | 0,
196 | 0,
197 | 0,
198 | 7.667,
199 | 0
200 | ]
201 | },
202 | {
203 | "Target": "Parameter",
204 | "Id": "ParamAngleX",
205 | "Segments": [
206 | 0,
207 | 0,
208 | 0,
209 | 7.667,
210 | 0
211 | ]
212 | },
213 | {
214 | "Target": "Parameter",
215 | "Id": "ParamAngleY",
216 | "Segments": [
217 | 0,
218 | 0,
219 | 0,
220 | 7.667,
221 | 0
222 | ]
223 | },
224 | {
225 | "Target": "Parameter",
226 | "Id": "ParamAngleZ",
227 | "Segments": [
228 | 0,
229 | 0,
230 | 0,
231 | 7.667,
232 | 0
233 | ]
234 | },
235 | {
236 | "Target": "Parameter",
237 | "Id": "ParamEyeLOpen",
238 | "Segments": [
239 | 0,
240 | 1,
241 | 0,
242 | 7.667,
243 | 1
244 | ]
245 | },
246 | {
247 | "Target": "Parameter",
248 | "Id": "ParamEyeLSmile",
249 | "Segments": [
250 | 0,
251 | 0,
252 | 0,
253 | 7.667,
254 | 0
255 | ]
256 | },
257 | {
258 | "Target": "Parameter",
259 | "Id": "ParamEyeROpen",
260 | "Segments": [
261 | 0,
262 | 1,
263 | 0,
264 | 7.667,
265 | 1
266 | ]
267 | },
268 | {
269 | "Target": "Parameter",
270 | "Id": "ParamEyeRSmile",
271 | "Segments": [
272 | 0,
273 | 0,
274 | 0,
275 | 7.667,
276 | 0
277 | ]
278 | },
279 | {
280 | "Target": "Parameter",
281 | "Id": "ParamEyeBallX",
282 | "Segments": [
283 | 0,
284 | 0,
285 | 0,
286 | 7.667,
287 | 0
288 | ]
289 | },
290 | {
291 | "Target": "Parameter",
292 | "Id": "ParamEyeBallY",
293 | "Segments": [
294 | 0,
295 | 0,
296 | 0,
297 | 7.667,
298 | 0
299 | ]
300 | },
301 | {
302 | "Target": "Parameter",
303 | "Id": "ParamBrowLY",
304 | "Segments": [
305 | 0,
306 | 0,
307 | 0,
308 | 7.667,
309 | 0
310 | ]
311 | },
312 | {
313 | "Target": "Parameter",
314 | "Id": "ParamBrowRY",
315 | "Segments": [
316 | 0,
317 | 0,
318 | 0,
319 | 7.667,
320 | 0
321 | ]
322 | },
323 | {
324 | "Target": "Parameter",
325 | "Id": "ParamBrowLX",
326 | "Segments": [
327 | 0,
328 | 0,
329 | 0,
330 | 7.667,
331 | 0
332 | ]
333 | },
334 | {
335 | "Target": "Parameter",
336 | "Id": "ParamBrowRX",
337 | "Segments": [
338 | 0,
339 | 0,
340 | 0,
341 | 7.667,
342 | 0
343 | ]
344 | },
345 | {
346 | "Target": "Parameter",
347 | "Id": "ParamBrowLAngle",
348 | "Segments": [
349 | 0,
350 | 0,
351 | 0,
352 | 7.667,
353 | 0
354 | ]
355 | },
356 | {
357 | "Target": "Parameter",
358 | "Id": "ParamBrowRAngle",
359 | "Segments": [
360 | 0,
361 | 0,
362 | 0,
363 | 7.667,
364 | 0
365 | ]
366 | },
367 | {
368 | "Target": "Parameter",
369 | "Id": "ParamBrowRForm",
370 | "Segments": [
371 | 0,
372 | 0,
373 | 0,
374 | 7.667,
375 | 0
376 | ]
377 | },
378 | {
379 | "Target": "Parameter",
380 | "Id": "ParamBrowLForm",
381 | "Segments": [
382 | 0,
383 | 0,
384 | 0,
385 | 7.667,
386 | 0
387 | ]
388 | },
389 | {
390 | "Target": "Parameter",
391 | "Id": "ParamMouthForm",
392 | "Segments": [
393 | 0,
394 | 0.1,
395 | 0,
396 | 7.667,
397 | 0.1
398 | ]
399 | },
400 | {
401 | "Target": "Parameter",
402 | "Id": "ParamMouthOpenY",
403 | "Segments": [
404 | 0,
405 | 0,
406 | 0,
407 | 7.667,
408 | 0
409 | ]
410 | },
411 | {
412 | "Target": "Parameter",
413 | "Id": "Param47",
414 | "Segments": [
415 | 0,
416 | -1,
417 | 0,
418 | 7.667,
419 | -1
420 | ]
421 | },
422 | {
423 | "Target": "Parameter",
424 | "Id": "ParamCheek",
425 | "Segments": [
426 | 0,
427 | 0,
428 | 0,
429 | 7.667,
430 | 0
431 | ]
432 | },
433 | {
434 | "Target": "Parameter",
435 | "Id": "Param48",
436 | "Segments": [
437 | 0,
438 | -30,
439 | 0,
440 | 7.667,
441 | -30
442 | ]
443 | },
444 | {
445 | "Target": "Parameter",
446 | "Id": "Param49",
447 | "Segments": [
448 | 0,
449 | -30,
450 | 0,
451 | 7.667,
452 | -30
453 | ]
454 | },
455 | {
456 | "Target": "Parameter",
457 | "Id": "Param29",
458 | "Segments": [
459 | 0,
460 | -30,
461 | 0,
462 | 7.667,
463 | -30
464 | ]
465 | },
466 | {
467 | "Target": "Parameter",
468 | "Id": "Param30",
469 | "Segments": [
470 | 0,
471 | 0,
472 | 0,
473 | 7.667,
474 | 0
475 | ]
476 | },
477 | {
478 | "Target": "Parameter",
479 | "Id": "Param37",
480 | "Segments": [
481 | 0,
482 | -30,
483 | 0,
484 | 7.667,
485 | -30
486 | ]
487 | },
488 | {
489 | "Target": "Parameter",
490 | "Id": "Param32",
491 | "Segments": [
492 | 0,
493 | -30,
494 | 0,
495 | 7.667,
496 | -30
497 | ]
498 | },
499 | {
500 | "Target": "Parameter",
501 | "Id": "Param36",
502 | "Segments": [
503 | 0,
504 | 0,
505 | 0,
506 | 7.667,
507 | 0
508 | ]
509 | },
510 | {
511 | "Target": "Parameter",
512 | "Id": "Param38",
513 | "Segments": [
514 | 0,
515 | -30,
516 | 0,
517 | 7.667,
518 | -30
519 | ]
520 | },
521 | {
522 | "Target": "Parameter",
523 | "Id": "Param39",
524 | "Segments": [
525 | 0,
526 | -30,
527 | 0,
528 | 7.667,
529 | -30
530 | ]
531 | },
532 | {
533 | "Target": "Parameter",
534 | "Id": "Param12",
535 | "Segments": [
536 | 0,
537 | -30,
538 | 0,
539 | 7.667,
540 | -30
541 | ]
542 | }
543 | ]
544 | }
--------------------------------------------------------------------------------
/res/live2d/models/Diana/motions/Diana_tap06.motion3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "Meta": {
4 | "Duration": 6.667,
5 | "Fps": 30.0,
6 | "Loop": true,
7 | "AreBeziersRestricted": true,
8 | "CurveCount": 25,
9 | "TotalSegmentCount": 120,
10 | "TotalPointCount": 319,
11 | "UserDataCount": 0,
12 | "TotalUserDataSize": 0
13 | },
14 | "Curves": [
15 | {
16 | "Target": "Parameter",
17 | "Id": "Param3",
18 | "Segments": [
19 | 0,
20 | -30,
21 | 0,
22 | 1.933,
23 | -30,
24 | 1,
25 | 2.444,
26 | -30,
27 | 2.956,
28 | 30,
29 | 3.467,
30 | 30,
31 | 1,
32 | 3.956,
33 | 30,
34 | 4.444,
35 | -30,
36 | 4.933,
37 | -30,
38 | 1,
39 | 5.356,
40 | -30,
41 | 5.778,
42 | 10,
43 | 6.2,
44 | 10,
45 | 0,
46 | 6.667,
47 | 10
48 | ]
49 | },
50 | {
51 | "Target": "Parameter",
52 | "Id": "Param4",
53 | "Segments": [
54 | 0,
55 | -30,
56 | 0,
57 | 6.667,
58 | -30
59 | ]
60 | },
61 | {
62 | "Target": "Parameter",
63 | "Id": "Param5",
64 | "Segments": [
65 | 0,
66 | -30,
67 | 0,
68 | 6.667,
69 | -30
70 | ]
71 | },
72 | {
73 | "Target": "Parameter",
74 | "Id": "ParamBodyAngleX",
75 | "Segments": [
76 | 0,
77 | 0,
78 | 1,
79 | 0.333,
80 | 0,
81 | 0.667,
82 | -2,
83 | 1,
84 | -2,
85 | 1,
86 | 1.267,
87 | -2,
88 | 1.533,
89 | -0.247,
90 | 1.8,
91 | 4,
92 | 1,
93 | 2.033,
94 | 7.716,
95 | 2.267,
96 | 10,
97 | 2.5,
98 | 10,
99 | 1,
100 | 2.711,
101 | 10,
102 | 2.922,
103 | 3,
104 | 3.133,
105 | 3,
106 | 1,
107 | 3.378,
108 | 3,
109 | 3.622,
110 | 8,
111 | 3.867,
112 | 8,
113 | 1,
114 | 4.111,
115 | 8,
116 | 4.356,
117 | -1,
118 | 4.6,
119 | -1,
120 | 1,
121 | 5.078,
122 | -1,
123 | 5.556,
124 | 2,
125 | 6.033,
126 | 2,
127 | 0,
128 | 6.667,
129 | 2
130 | ]
131 | },
132 | {
133 | "Target": "Parameter",
134 | "Id": "ParamBodyAngleY",
135 | "Segments": [
136 | 0,
137 | 0,
138 | 1,
139 | 0.333,
140 | 0,
141 | 0.667,
142 | 1,
143 | 1,
144 | 1,
145 | 1,
146 | 1.267,
147 | 1,
148 | 1.533,
149 | -4.759,
150 | 1.8,
151 | -5,
152 | 1,
153 | 2.733,
154 | -5.845,
155 | 3.667,
156 | -6,
157 | 4.6,
158 | -6,
159 | 0,
160 | 6.667,
161 | -6
162 | ]
163 | },
164 | {
165 | "Target": "Parameter",
166 | "Id": "ParamBodyAngleZ",
167 | "Segments": [
168 | 0,
169 | 0,
170 | 1,
171 | 0.333,
172 | 0,
173 | 0.667,
174 | -1,
175 | 1,
176 | -1,
177 | 1,
178 | 1.267,
179 | -1,
180 | 1.533,
181 | 7,
182 | 1.8,
183 | 7,
184 | 1,
185 | 2.733,
186 | 7,
187 | 3.667,
188 | 5,
189 | 4.6,
190 | 5,
191 | 1,
192 | 5.078,
193 | 5,
194 | 5.556,
195 | 8,
196 | 6.033,
197 | 8,
198 | 0,
199 | 6.667,
200 | 8
201 | ]
202 | },
203 | {
204 | "Target": "Parameter",
205 | "Id": "ParamAngleX",
206 | "Segments": [
207 | 0,
208 | 0,
209 | 1,
210 | 0.333,
211 | 0,
212 | 0.667,
213 | -0.078,
214 | 1,
215 | 2,
216 | 1,
217 | 1.267,
218 | 3.662,
219 | 1.533,
220 | 11,
221 | 1.8,
222 | 11,
223 | 1,
224 | 2.733,
225 | 11,
226 | 3.667,
227 | -6,
228 | 4.6,
229 | -6,
230 | 1,
231 | 5.078,
232 | -6,
233 | 5.556,
234 | 2,
235 | 6.033,
236 | 2,
237 | 0,
238 | 6.667,
239 | 2
240 | ]
241 | },
242 | {
243 | "Target": "Parameter",
244 | "Id": "ParamAngleY",
245 | "Segments": [
246 | 0,
247 | 1,
248 | 1,
249 | 0.333,
250 | 1,
251 | 0.667,
252 | 0.162,
253 | 1,
254 | -6,
255 | 1,
256 | 1.267,
257 | -10.929,
258 | 1.533,
259 | -19,
260 | 1.8,
261 | -19,
262 | 1,
263 | 2.733,
264 | -19,
265 | 3.667,
266 | -18.745,
267 | 4.6,
268 | -15,
269 | 1,
270 | 5.078,
271 | -13.083,
272 | 5.556,
273 | 0,
274 | 6.033,
275 | 0,
276 | 0,
277 | 6.667,
278 | 0
279 | ]
280 | },
281 | {
282 | "Target": "Parameter",
283 | "Id": "ParamAngleZ",
284 | "Segments": [
285 | 0,
286 | 0,
287 | 1,
288 | 0.6,
289 | 0,
290 | 1.2,
291 | 19,
292 | 1.8,
293 | 19,
294 | 1,
295 | 2.733,
296 | 19,
297 | 3.667,
298 | -25,
299 | 4.6,
300 | -25,
301 | 1,
302 | 5.078,
303 | -25,
304 | 5.556,
305 | -4,
306 | 6.033,
307 | -4,
308 | 0,
309 | 6.667,
310 | -4
311 | ]
312 | },
313 | {
314 | "Target": "Parameter",
315 | "Id": "ParamEyeLOpen",
316 | "Segments": [
317 | 0,
318 | 1,
319 | 0,
320 | 0.5,
321 | 1,
322 | 1,
323 | 0.544,
324 | 1,
325 | 0.589,
326 | 0,
327 | 0.633,
328 | 0,
329 | 1,
330 | 0.678,
331 | 0,
332 | 0.722,
333 | 1,
334 | 0.767,
335 | 1,
336 | 1,
337 | 0.811,
338 | 1,
339 | 0.856,
340 | 0,
341 | 0.9,
342 | 0,
343 | 1,
344 | 0.944,
345 | 0,
346 | 0.989,
347 | 1,
348 | 1.033,
349 | 1,
350 | 1,
351 | 1.333,
352 | 1,
353 | 1.633,
354 | 1,
355 | 1.933,
356 | 1,
357 | 1,
358 | 2.044,
359 | 1,
360 | 2.156,
361 | 0,
362 | 2.267,
363 | 0,
364 | 1,
365 | 2.589,
366 | 0,
367 | 2.911,
368 | 0,
369 | 3.233,
370 | 0,
371 | 1,
372 | 3.389,
373 | 0,
374 | 3.544,
375 | 1,
376 | 3.7,
377 | 1,
378 | 1,
379 | 4.078,
380 | 1,
381 | 4.456,
382 | 1,
383 | 4.833,
384 | 1,
385 | 1,
386 | 4.878,
387 | 1,
388 | 4.922,
389 | 0,
390 | 4.967,
391 | 0,
392 | 1,
393 | 5.011,
394 | 0,
395 | 5.056,
396 | 1,
397 | 5.1,
398 | 1,
399 | 1,
400 | 5.144,
401 | 1,
402 | 5.189,
403 | 0,
404 | 5.233,
405 | 0,
406 | 1,
407 | 5.278,
408 | 0,
409 | 5.322,
410 | 1,
411 | 5.367,
412 | 1,
413 | 0,
414 | 6.667,
415 | 1
416 | ]
417 | },
418 | {
419 | "Target": "Parameter",
420 | "Id": "ParamEyeROpen",
421 | "Segments": [
422 | 0,
423 | 1,
424 | 0,
425 | 0.5,
426 | 1,
427 | 1,
428 | 0.544,
429 | 1,
430 | 0.589,
431 | 0,
432 | 0.633,
433 | 0,
434 | 1,
435 | 0.678,
436 | 0,
437 | 0.722,
438 | 1,
439 | 0.767,
440 | 1,
441 | 1,
442 | 0.811,
443 | 1,
444 | 0.856,
445 | 0,
446 | 0.9,
447 | 0,
448 | 1,
449 | 0.944,
450 | 0,
451 | 0.989,
452 | 1,
453 | 1.033,
454 | 1,
455 | 1,
456 | 1.333,
457 | 1,
458 | 1.633,
459 | 1,
460 | 1.933,
461 | 1,
462 | 1,
463 | 2.044,
464 | 1,
465 | 2.156,
466 | 0,
467 | 2.267,
468 | 0,
469 | 1,
470 | 2.589,
471 | 0,
472 | 2.911,
473 | 0,
474 | 3.233,
475 | 0,
476 | 1,
477 | 3.389,
478 | 0,
479 | 3.544,
480 | 1,
481 | 3.7,
482 | 1,
483 | 1,
484 | 4.078,
485 | 1,
486 | 4.456,
487 | 1,
488 | 4.833,
489 | 1,
490 | 1,
491 | 4.878,
492 | 1,
493 | 4.922,
494 | 0,
495 | 4.967,
496 | 0,
497 | 1,
498 | 5.011,
499 | 0,
500 | 5.056,
501 | 1,
502 | 5.1,
503 | 1,
504 | 1,
505 | 5.144,
506 | 1,
507 | 5.189,
508 | 0,
509 | 5.233,
510 | 0,
511 | 1,
512 | 5.278,
513 | 0,
514 | 5.322,
515 | 1,
516 | 5.367,
517 | 1,
518 | 0,
519 | 6.667,
520 | 1
521 | ]
522 | },
523 | {
524 | "Target": "Parameter",
525 | "Id": "ParamEyeBallX",
526 | "Segments": [
527 | 0,
528 | 0,
529 | 0,
530 | 1.033,
531 | 0,
532 | 1,
533 | 1.3,
534 | 0,
535 | 1.567,
536 | -1,
537 | 1.833,
538 | -1,
539 | 0,
540 | 6.667,
541 | -1
542 | ]
543 | },
544 | {
545 | "Target": "Parameter",
546 | "Id": "ParamEyeBallY",
547 | "Segments": [
548 | 0,
549 | -0.1,
550 | 0,
551 | 1.033,
552 | -0.1,
553 | 1,
554 | 1.3,
555 | -0.1,
556 | 1.567,
557 | 1,
558 | 1.833,
559 | 1,
560 | 0,
561 | 6.667,
562 | 1
563 | ]
564 | },
565 | {
566 | "Target": "Parameter",
567 | "Id": "ParamBrowLY",
568 | "Segments": [
569 | 0,
570 | 0,
571 | 0,
572 | 6.667,
573 | 0
574 | ]
575 | },
576 | {
577 | "Target": "Parameter",
578 | "Id": "ParamBrowRY",
579 | "Segments": [
580 | 0,
581 | 0,
582 | 0,
583 | 6.667,
584 | 0
585 | ]
586 | },
587 | {
588 | "Target": "Parameter",
589 | "Id": "ParamBrowLX",
590 | "Segments": [
591 | 0,
592 | 0,
593 | 0,
594 | 6.667,
595 | 0
596 | ]
597 | },
598 | {
599 | "Target": "Parameter",
600 | "Id": "ParamBrowRX",
601 | "Segments": [
602 | 0,
603 | 0,
604 | 0,
605 | 6.667,
606 | 0
607 | ]
608 | },
609 | {
610 | "Target": "Parameter",
611 | "Id": "ParamBrowLAngle",
612 | "Segments": [
613 | 0,
614 | 0.1,
615 | 1,
616 | 0.611,
617 | 0.1,
618 | 1.222,
619 | 0.4,
620 | 1.833,
621 | 0.4,
622 | 0,
623 | 6.667,
624 | 0.4
625 | ]
626 | },
627 | {
628 | "Target": "Parameter",
629 | "Id": "ParamBrowRAngle",
630 | "Segments": [
631 | 0,
632 | 0,
633 | 1,
634 | 0.611,
635 | 0,
636 | 1.222,
637 | 0.4,
638 | 1.833,
639 | 0.4,
640 | 0,
641 | 6.667,
642 | 0.4
643 | ]
644 | },
645 | {
646 | "Target": "Parameter",
647 | "Id": "ParamBrowRForm",
648 | "Segments": [
649 | 0,
650 | 0,
651 | 1,
652 | 0.611,
653 | 0,
654 | 1.222,
655 | -0.6,
656 | 1.833,
657 | -0.6,
658 | 0,
659 | 6.667,
660 | -0.6
661 | ]
662 | },
663 | {
664 | "Target": "Parameter",
665 | "Id": "ParamBrowLForm",
666 | "Segments": [
667 | 0,
668 | 0,
669 | 1,
670 | 0.611,
671 | 0,
672 | 1.222,
673 | -0.4,
674 | 1.833,
675 | -0.4,
676 | 0,
677 | 6.667,
678 | -0.4
679 | ]
680 | },
681 | {
682 | "Target": "Parameter",
683 | "Id": "ParamMouthForm",
684 | "Segments": [
685 | 0,
686 | 0.1,
687 | 0,
688 | 1.267,
689 | 0.1,
690 | 1,
691 | 1.389,
692 | 0.1,
693 | 1.511,
694 | -0.5,
695 | 1.633,
696 | -0.5,
697 | 1,
698 | 1.656,
699 | -0.5,
700 | 1.678,
701 | -0.047,
702 | 1.7,
703 | 0,
704 | 1,
705 | 1.744,
706 | 0.095,
707 | 1.789,
708 | 0.1,
709 | 1.833,
710 | 0.1,
711 | 1,
712 | 1.9,
713 | 0.1,
714 | 1.967,
715 | -0.3,
716 | 2.033,
717 | -0.3,
718 | 1,
719 | 2.1,
720 | -0.3,
721 | 2.167,
722 | 0.4,
723 | 2.233,
724 | 0.4,
725 | 1,
726 | 2.322,
727 | 0.4,
728 | 2.411,
729 | 0,
730 | 2.5,
731 | 0,
732 | 1,
733 | 2.578,
734 | 0,
735 | 2.656,
736 | 0.1,
737 | 2.733,
738 | 0.1,
739 | 1,
740 | 2.811,
741 | 0.1,
742 | 2.889,
743 | 0,
744 | 2.967,
745 | 0,
746 | 1,
747 | 3.056,
748 | 0,
749 | 3.144,
750 | 0.2,
751 | 3.233,
752 | 0.2,
753 | 1,
754 | 3.311,
755 | 0.2,
756 | 3.389,
757 | 0.196,
758 | 3.467,
759 | 0.1,
760 | 1,
761 | 3.578,
762 | -0.038,
763 | 3.689,
764 | -0.2,
765 | 3.8,
766 | -0.2,
767 | 1,
768 | 4.389,
769 | -0.2,
770 | 4.978,
771 | 0.3,
772 | 5.567,
773 | 0.3,
774 | 0,
775 | 6.667,
776 | 0.3
777 | ]
778 | },
779 | {
780 | "Target": "Parameter",
781 | "Id": "ParamMouthOpenY",
782 | "Segments": [
783 | 0,
784 | 0,
785 | 0,
786 | 1.267,
787 | 0,
788 | 1,
789 | 1.389,
790 | 0,
791 | 1.511,
792 | 0.7,
793 | 1.633,
794 | 0.7,
795 | 1,
796 | 1.656,
797 | 0.7,
798 | 1.678,
799 | 0,
800 | 1.7,
801 | 0,
802 | 1,
803 | 1.744,
804 | 0,
805 | 1.789,
806 | 0.7,
807 | 1.833,
808 | 0.7,
809 | 1,
810 | 1.9,
811 | 0.7,
812 | 1.967,
813 | 0.707,
814 | 2.033,
815 | 0.6,
816 | 1,
817 | 2.1,
818 | 0.493,
819 | 2.167,
820 | 0.2,
821 | 2.233,
822 | 0.2,
823 | 1,
824 | 2.322,
825 | 0.2,
826 | 2.411,
827 | 0.6,
828 | 2.5,
829 | 0.6,
830 | 1,
831 | 2.578,
832 | 0.6,
833 | 2.656,
834 | 0.4,
835 | 2.733,
836 | 0.4,
837 | 1,
838 | 2.811,
839 | 0.4,
840 | 2.889,
841 | 0.6,
842 | 2.967,
843 | 0.6,
844 | 1,
845 | 3.056,
846 | 0.6,
847 | 3.144,
848 | 0.4,
849 | 3.233,
850 | 0.4,
851 | 1,
852 | 3.311,
853 | 0.4,
854 | 3.389,
855 | 0.5,
856 | 3.467,
857 | 0.5,
858 | 1,
859 | 3.578,
860 | 0.5,
861 | 3.689,
862 | 0,
863 | 3.8,
864 | 0,
865 | 1,
866 | 4.389,
867 | 0,
868 | 4.978,
869 | 0,
870 | 5.567,
871 | 0,
872 | 0,
873 | 6.667,
874 | 0
875 | ]
876 | },
877 | {
878 | "Target": "Parameter",
879 | "Id": "ParamCheek",
880 | "Segments": [
881 | 0,
882 | 0,
883 | 0,
884 | 1.067,
885 | 0,
886 | 1,
887 | 1.333,
888 | 0,
889 | 1.6,
890 | 1,
891 | 1.867,
892 | 1,
893 | 0,
894 | 6.667,
895 | 1
896 | ]
897 | },
898 | {
899 | "Target": "Parameter",
900 | "Id": "Param30",
901 | "Segments": [
902 | 0,
903 | 0,
904 | 1,
905 | 0.322,
906 | 0,
907 | 0.644,
908 | -16,
909 | 0.967,
910 | -16,
911 | 1,
912 | 1.3,
913 | -16,
914 | 1.633,
915 | 28,
916 | 1.967,
917 | 28,
918 | 0,
919 | 6.667,
920 | 28
921 | ]
922 | }
923 | ]
924 | }
--------------------------------------------------------------------------------
/res/live2d/models/Diana/motions/Diana_tap10.motion3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "Meta": {
4 | "Duration": 4.4,
5 | "Fps": 30.0,
6 | "Loop": true,
7 | "AreBeziersRestricted": true,
8 | "CurveCount": 9,
9 | "TotalSegmentCount": 43,
10 | "TotalPointCount": 102,
11 | "UserDataCount": 0,
12 | "TotalUserDataSize": 0
13 | },
14 | "Curves": [
15 | {
16 | "Target": "Parameter",
17 | "Id": "Param2",
18 | "Segments": [
19 | 0,
20 | -30,
21 | 0,
22 | 1.1,
23 | -30,
24 | 1,
25 | 1.3,
26 | -30,
27 | 1.5,
28 | 30,
29 | 1.7,
30 | 30,
31 | 1,
32 | 2.389,
33 | 30,
34 | 3.078,
35 | 30,
36 | 3.767,
37 | 30,
38 | 1,
39 | 3.9,
40 | 30,
41 | 4.033,
42 | -30,
43 | 4.167,
44 | -30,
45 | 0,
46 | 4.4,
47 | -30
48 | ]
49 | },
50 | {
51 | "Target": "Parameter",
52 | "Id": "ParamAngleX",
53 | "Segments": [
54 | 0,
55 | 0,
56 | 0,
57 | 1.1,
58 | 0,
59 | 1,
60 | 1.333,
61 | 0,
62 | 1.567,
63 | -1,
64 | 1.8,
65 | -1,
66 | 1,
67 | 2.567,
68 | -1,
69 | 3.333,
70 | 0,
71 | 4.1,
72 | 0,
73 | 0,
74 | 4.4,
75 | 0
76 | ]
77 | },
78 | {
79 | "Target": "Parameter",
80 | "Id": "ParamAngleY",
81 | "Segments": [
82 | 0,
83 | 0,
84 | 0,
85 | 1.1,
86 | 0,
87 | 1,
88 | 1.333,
89 | 0,
90 | 1.567,
91 | 4,
92 | 1.8,
93 | 4,
94 | 1,
95 | 2.567,
96 | 4,
97 | 3.333,
98 | 0,
99 | 4.1,
100 | 0,
101 | 0,
102 | 4.4,
103 | 0
104 | ]
105 | },
106 | {
107 | "Target": "Parameter",
108 | "Id": "ParamEyeLOpen",
109 | "Segments": [
110 | 0,
111 | 1,
112 | 0,
113 | 1.1,
114 | 1,
115 | 1,
116 | 1.333,
117 | 1,
118 | 1.567,
119 | 0,
120 | 1.8,
121 | 0,
122 | 1,
123 | 2.467,
124 | 0,
125 | 3.133,
126 | 0,
127 | 3.8,
128 | 0,
129 | 1,
130 | 3.944,
131 | 0,
132 | 4.089,
133 | 1,
134 | 4.233,
135 | 1,
136 | 0,
137 | 4.4,
138 | 1
139 | ]
140 | },
141 | {
142 | "Target": "Parameter",
143 | "Id": "ParamEyeLSmile",
144 | "Segments": [
145 | 0,
146 | 0,
147 | 0,
148 | 1.1,
149 | 0,
150 | 1,
151 | 1.333,
152 | 0,
153 | 1.567,
154 | 1,
155 | 1.8,
156 | 1,
157 | 1,
158 | 2.467,
159 | 1,
160 | 3.133,
161 | 1,
162 | 3.8,
163 | 1,
164 | 1,
165 | 3.944,
166 | 1,
167 | 4.089,
168 | 0,
169 | 4.233,
170 | 0,
171 | 0,
172 | 4.4,
173 | 0
174 | ]
175 | },
176 | {
177 | "Target": "Parameter",
178 | "Id": "ParamEyeROpen",
179 | "Segments": [
180 | 0,
181 | 1,
182 | 0,
183 | 1.1,
184 | 1,
185 | 1,
186 | 1.333,
187 | 1,
188 | 1.567,
189 | 0,
190 | 1.8,
191 | 0,
192 | 1,
193 | 2.467,
194 | 0,
195 | 3.133,
196 | 0,
197 | 3.8,
198 | 0,
199 | 1,
200 | 3.944,
201 | 0,
202 | 4.089,
203 | 1,
204 | 4.233,
205 | 1,
206 | 0,
207 | 4.4,
208 | 1
209 | ]
210 | },
211 | {
212 | "Target": "Parameter",
213 | "Id": "ParamEyeRSmile",
214 | "Segments": [
215 | 0,
216 | 0,
217 | 0,
218 | 1.1,
219 | 0,
220 | 1,
221 | 1.333,
222 | 0,
223 | 1.567,
224 | 1,
225 | 1.8,
226 | 1,
227 | 1,
228 | 2.467,
229 | 1,
230 | 3.133,
231 | 1,
232 | 3.8,
233 | 1,
234 | 1,
235 | 3.944,
236 | 1,
237 | 4.089,
238 | 0,
239 | 4.233,
240 | 0,
241 | 0,
242 | 4.4,
243 | 0
244 | ]
245 | },
246 | {
247 | "Target": "Parameter",
248 | "Id": "ParamMouthForm",
249 | "Segments": [
250 | 0,
251 | -0.2,
252 | 0,
253 | 1.1,
254 | -0.2,
255 | 1,
256 | 1.311,
257 | -0.2,
258 | 1.522,
259 | 0.3,
260 | 1.733,
261 | 0.3,
262 | 1,
263 | 2.444,
264 | 0.3,
265 | 3.156,
266 | 0.3,
267 | 3.867,
268 | 0.3,
269 | 1,
270 | 4.022,
271 | 0.3,
272 | 4.178,
273 | -0.2,
274 | 4.333,
275 | -0.2,
276 | 0,
277 | 4.4,
278 | -0.2
279 | ]
280 | },
281 | {
282 | "Target": "Parameter",
283 | "Id": "ParamMouthOpenY",
284 | "Segments": [
285 | 0,
286 | 0,
287 | 0,
288 | 1.1,
289 | 0,
290 | 1,
291 | 1.311,
292 | 0,
293 | 1.522,
294 | 1,
295 | 1.733,
296 | 1,
297 | 1,
298 | 2.444,
299 | 1,
300 | 3.156,
301 | 1,
302 | 3.867,
303 | 1,
304 | 1,
305 | 4.022,
306 | 1,
307 | 4.178,
308 | 0,
309 | 4.333,
310 | 0,
311 | 0,
312 | 4.4,
313 | 0
314 | ]
315 | }
316 | ]
317 | }
--------------------------------------------------------------------------------
/res/live2d/models/Diana/raw.ex.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "STM_1_0",
3 | "name": "嘉然BY木果",
4 | "id": "1618880670036",
5 | "encrypt": "true",
6 | "version": "1.0",
7 | "list": [{
8 | "id": "",
9 | "character": "character",
10 | "avatar": "4a301072dec6b6a49050e5b294cd7983",
11 | "costume": [{
12 | "name": "costume",
13 | "path": "39561a673b6fe68918affd77d3ad8ae2.bin3"
14 | }]
15 | }]
16 | }
--------------------------------------------------------------------------------
/res/live2d/models/Diana/raw.model3.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 3,
3 | "FileReferences": {
4 | "Moc": "8c4420bd232902f08f41b59bbc36462f.bin3",
5 | "Textures": ["4df2dbd71a468fc2f91b62afcb63f994.bin3"],
6 | "Physics": "2b5fa038da3354fd73a58456408f27e9.bin3",
7 | "PhysicsV2": {
8 | "File": "2b5fa038da3354fd73a58456408f27e9.bin3"
9 | },
10 | "Motions": {
11 | "Idle": [{
12 | "File": "8251a6de2a03ea12eaf8c1f879d759b9.bin3"
13 | }],
14 | "Tap生气 -领结": [{
15 | "File": "18624d01175dda6605c3eafa341bac02.bin3",
16 | "Text": "嘉心糖屁用没有",
17 | "TextDelay": 2000,
18 | "TextDuration": 3000
19 | }],
20 | "Tap= = 左蝴蝶结": [{
21 | "File": "be67f42e9c965290406d52b64fb878bd.bin3",
22 | "Text": "有人急了,但我不说是谁~",
23 | "TextDelay": 1000,
24 | "TextDuration": 4000
25 | }],
26 | "Tap笑- 脸": [{
27 | "File": "d1cf83c4f56a2d02a8f0a3ae2f46028f.bin3",
28 | "Text": "hi!嘉心糖",
29 | "TextDelay": 2200,
30 | "TextDuration": 2300
31 | }],
32 | "Tap哭 -眼角": [{
33 | "File": "721720d60a83a9f4b7f2b1065b49d6c8.bin3",
34 | "Text": "呜呜...呜呜呜....",
35 | "TextDelay": 3200,
36 | "TextDuration": 4000
37 | }],
38 | "Shake": [{
39 | "File": "a475c108ed9162233c132446a237c700.bin3",
40 | "Text": "别摇啦!",
41 | "TextDelay": 1000,
42 | "TextDuration": 2000
43 | }],
44 | "Tap害羞-中间刘海": [{
45 | "File": "f6123a070d9897ef1e6475e740b13e08.bin3",
46 | "Text": "想然然了没有呀~",
47 | "TextDelay": 1500,
48 | "TextDuration": 3000
49 | }],
50 | "Tap抱阿草-左手": [{
51 | "File": "e31f07da7854f78c21a271ada7416412.bin3",
52 | "Text": "阿草好软呀~",
53 | "TextDelay": 3000,
54 | "TextDuration": 2500
55 | }],
56 | "Tap摇头- 身体": [{
57 | "File": "a475c108ed9162233c132446a237c700.bin3",
58 | "Text": "不要再戳啦!好痒!",
59 | "TextDelay": 800,
60 | "TextDuration": 2500
61 | }],
62 | "Tap耳朵-发卡": [{
63 | "File": "fa1918fc04af73a1a08aaac6e2556fbb.bin3",
64 | "Text": "嗷呜~~~",
65 | "TextDelay": 1500,
66 | "TextDuration": 3000
67 | }],
68 | "Tap打瞌睡- 呆毛": [{
69 | "File": "d9be6b6f1b3bc23ef6539025acedd923.bin3",
70 | "Text": "啊",
71 | "TextDelay": 7500,
72 | "TextDuration": 800
73 | }],
74 | "Leave": [{
75 | "File": "d9be6b6f1b3bc23ef6539025acedd923.bin3",
76 | "Text": "zzZ。。。",
77 | "TextDelay": 4000,
78 | "TextDuration": 4000
79 | }],
80 | "Tap左头发": [{
81 | "File": "ec36cfef1f589764902d770d0cca2e9e.bin3"
82 | }],
83 | "Tap右头发": [{
84 | "File": "0aeecad899bb18f93a519617dfe76f26.bin3",
85 | "Text": "哇!好吃的!",
86 | "TextDelay": 500,
87 | "TextDuration": 3000
88 | }]
89 | }
90 | },
91 | "Controllers": {
92 | "ParamHit": {},
93 | "ParamLoop": {},
94 | "KeyTrigger": {},
95 | "EyeBlink": {
96 | "MinInterval": 500,
97 | "MaxInterval": 6000,
98 | "Enabled": true
99 | },
100 | "LipSync": {
101 | "Gain": 5.0
102 | },
103 | "MouseTracking": {
104 | "SmoothTime": 0.15,
105 | "Items": [{
106 | "Id": "ParamBodyAngleX",
107 | "Min": -10.0,
108 | "Max": 10.0,
109 | "DefaultValue": 0.0,
110 | "Weight": 0.76343286,
111 | "BlendMode": 1,
112 | "Input": 1
113 | }, {
114 | "Id": "ParamAngleX",
115 | "Min": -30.0,
116 | "Max": 30.0,
117 | "DefaultValue": 0.0,
118 | "Weight": 0.798328757,
119 | "BlendMode": 1,
120 | "Input": 1
121 | }, {
122 | "Id": "ParamBodyAngleZ",
123 | "Min": -10.0,
124 | "Max": 10.0,
125 | "DefaultValue": 0.0,
126 | "Weight": 0.6260679,
127 | "BlendMode": 1,
128 | "Input": 1
129 | }, {
130 | "Id": "ParamBodyAngleY",
131 | "Min": -10.0,
132 | "Max": 10.0,
133 | "DefaultValue": 0.0,
134 | "Weight": 0.8907613,
135 | "BlendMode": 1,
136 | "Axis": 1,
137 | "Input": 2
138 | }, {
139 | "Id": "ParamAngleY",
140 | "Min": -30.0,
141 | "Max": 30.0,
142 | "DefaultValue": 0.0,
143 | "Weight": 0.7521123,
144 | "BlendMode": 1,
145 | "Axis": 1,
146 | "Input": 2
147 | }],
148 | "Enabled": true
149 | },
150 | "AutoBreath": {
151 | "Enabled": true
152 | },
153 | "ExtraMotion": {
154 | "Enabled": true
155 | },
156 | "Accelerometer": {
157 | "Enabled": true
158 | },
159 | "Microphone": {},
160 | "Transform": {},
161 | "FaceTracking": {
162 | "Enabled": true
163 | },
164 | "ParamValue": {},
165 | "PartOpacity": {},
166 | "ArtmeshOpacity": {},
167 | "ArtmeshColor": {},
168 | "ArtmeshCulling": {
169 | "DefaultMode": 0
170 | },
171 | "IntimacySystem": {}
172 | },
173 | "HitAreas": [{
174 | "Name": "= = 左蝴蝶结",
175 | "Id": "ArtMesh15"
176 | }, {
177 | "Name": "笑- 脸",
178 | "Id": "ArtMesh51"
179 | }, {
180 | "Name": "哭 -眼角",
181 | "Id": "ArtMesh48"
182 | }, {
183 | "Name": "生气 -领结",
184 | "Id": "ArtMesh56"
185 | }, {
186 | "Name": "害羞-中间刘海",
187 | "Id": "ArtMesh10"
188 | }, {
189 | "Name": "抱阿草-左手",
190 | "Id": "L4"
191 | }, {
192 | "Name": "打瞌睡- 呆毛",
193 | "Id": "ArtMesh9"
194 | }, {
195 | "Name": "耳朵-发卡",
196 | "Id": "L3"
197 | }, {
198 | "Name": "摇头- 身体",
199 | "Id": "jiaran"
200 | }, {
201 | "Name": "左头发",
202 | "Id": "L5"
203 | }, {
204 | "Name": "右头发",
205 | "Id": "R5"
206 | }],
207 | "Options": {
208 | "TexFixed": true
209 | }
210 | }
--------------------------------------------------------------------------------
/res/live2d/models/Diana/raw.preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheSecondAkari/vscode-live2d/1e7a4fc4e610ec0e76ee6035e25fc572d048eb85/res/live2d/models/Diana/raw.preview.png
--------------------------------------------------------------------------------
/src/extension.ts:
--------------------------------------------------------------------------------
1 | // The module 'vscode' contains the VS Code extensibility API
2 | // Import the module and reference it with the alias vscode in your code below
3 | import * as vscode from 'vscode';
4 | import {activateLive2d} from './live2dView';
5 | import {activateModify} from './live2dModify'
6 |
7 | // this method is called when your extension is activated
8 | // your extension is activated the very first time the command is executed
9 | export function activate(context: vscode.ExtensionContext) {
10 |
11 | // 注册live2d webView
12 | activateLive2d(context);
13 |
14 | // 注册修改文件操作
15 | activateModify(context);
16 |
17 | }
18 |
19 | // this method is called when your extension is deactivated
20 | export function deactivate() {}
21 |
--------------------------------------------------------------------------------
/src/live2dModify/Dom.ts:
--------------------------------------------------------------------------------
1 | import * as vscode from 'vscode';
2 | import * as path from 'path';
3 | import * as fs from 'fs';
4 | import FileType from './FileType';
5 | import vsHelp from './vsHelp';
6 | import getNewContent from './getJs';
7 | import {
8 | Uri,
9 | window,
10 | InputBoxOptions,
11 | commands,
12 | env,
13 | } from 'vscode';
14 |
15 | export class Dom {
16 | //当前用户配置
17 | private config: any;
18 | //配置名称
19 | private configName: string;
20 | //要修改的文件路径
21 | private filePath: string;
22 | //插件版本号
23 | private version: string;
24 | //插件名称
25 | private extName: string;
26 |
27 |
28 | //初始化参数
29 | public constructor(
30 | configName: string,
31 | filePath: string,
32 | version: string,
33 | extName: string,
34 | ) {
35 | this.configName = configName;
36 | this.filePath = filePath;
37 | this.version = version;
38 | this.extName = extName;
39 |
40 | this.config = vscode.workspace.getConfiguration(this.configName);
41 | let firstload = this.checkFirstload(); // 是否初次加载插件
42 | let fileType = this.getFileType(); // 文件目前状态
43 | // 如果是第一次加载插件,或者旧版本
44 | if (firstload || fileType === FileType.isOld) {
45 | this.generateResources();
46 | }
47 | }
48 |
49 | /**
50 | * 生成资源文件到特定目录--live2d的内容,增加 js 文件处理代码
51 | *
52 | * @public
53 | * @param {boolean} [notice] 是否需要结果通知
54 | * @returns {void}
55 | */
56 | public generateResources(notice?: boolean): void {
57 | try {
58 | const base = env.appRoot;
59 | copy(path.join(__dirname, '../../res/'), path.join(base,'out', 'vs', 'code', 'electron-sandbox', 'workbench'));
60 | this.install(true);
61 | notice && vsHelp.showInfo('资源文件配置成功');
62 | } catch (e) {
63 | notice && vsHelp.showInfo('资源文件配置出错:' + e.toString());
64 | }
65 | }
66 |
67 | /**
68 | * 移除该插件所有依赖
69 | *
70 | * @public
71 | * @param {boolean} [notice] 是否需要结果通知
72 | * @returns {void}
73 | */
74 | public removeResources(notice?: boolean): void {
75 | try {
76 | const base = env.appRoot;
77 | removeFiles(path.join(base,'out', 'vs', 'code', 'electron-sandbox', 'workbench', 'live2d'));
78 | this.uninstall();
79 | notice && vsHelp.showInfoRestart('资源文件移除成功');
80 | } catch (e) {
81 | notice && vsHelp.showInfo('资源文件移除出错:' + e.toString());
82 | }
83 | }
84 |
85 | /**
86 | * 安装插件,hack
87 | *
88 | * @private
89 | * @param {boolean} [refresh] 需要更新
90 | * @returns {void}
91 | */
92 | public install(refresh?: boolean): void {
93 |
94 | let lastConfig = this.config; // 之前的配置
95 | let config = vscode.workspace.getConfiguration(this.configName); // 当前用户配置
96 |
97 |
98 | // 1.如果配置文件改变到时候,当前插件配置没有改变,则返回
99 | if (!refresh && JSON.stringify(lastConfig) === JSON.stringify(config)) {
100 | return;
101 | }
102 |
103 | // 之后操作有两种:1.初次加载 2.配置文件改变
104 |
105 | // 2.两次配置均为,未启动插件
106 | if (!lastConfig.enabled && !config.enabled) {
107 | return;
108 | }
109 |
110 | // 3.保存当前配置
111 | this.config = config; // 更新配置
112 |
113 | // 4.如果关闭插件
114 | if (!config.enabled) {
115 | this.uninstall();
116 | vsHelp.showInfoRestart(this.extName + '已关闭插件,请重新启动!');
117 | return;
118 | }
119 |
120 | // 5.hack 样式
121 |
122 | // 自定义的样式内容
123 | let content = getNewContent(config, this.extName, this.version).replace(/\s*$/, ''); // 去除末尾空白
124 |
125 | // 添加代码到文件中,并尝试删除原来已经添加的
126 | let newContent = this.getContent();
127 | newContent = this.clearJSContent(newContent);
128 | newContent += content;
129 |
130 | this.saveContent(newContent);
131 | vsHelp.showInfoRestart(this.extName + ' 已更新配置,请重新启动!');
132 |
133 | }
134 |
135 |
136 | /**
137 | * 获取文件内容
138 | * @var mixed
139 | */
140 | private getContent(): string {
141 | return fs.readFileSync(this.filePath, 'utf-8');
142 | }
143 |
144 | /**
145 | * 设置文件内容
146 | *
147 | * @private
148 | * @param {string} content
149 | */
150 | private saveContent(content: string): void {
151 | fs.writeFileSync(this.filePath, content, 'utf-8');
152 | }
153 |
154 | /**
155 | * 清理已经添加的代码
156 | *
157 | * @private
158 | * @param {string} content
159 | * @returns {string}
160 | */
161 | private clearJSContent(content: string): string {
162 | var re = new RegExp("\\/\\*ext-" + this.extName + "-start\\*\\/[\\s\\S]*?\\/\\*ext-" + this.extName + "-end\\*" + "\\/", "g");
163 | content = content.replace(re, '');
164 | content = content.replace(/\s*$/, '');
165 | content += '\n'
166 | return content;
167 | }
168 |
169 | /**
170 | * 卸载
171 | *
172 | * @private
173 | */
174 | private uninstall(): boolean {
175 | try {
176 | let content = this.getContent();
177 | content = this.clearJSContent(content);
178 | this.saveContent(content);
179 | return true;
180 | }
181 | catch (ex) {
182 | return false;
183 | }
184 | }
185 |
186 | /**
187 | * 检测是否初次加载,并在初次加载的时候提示用户
188 | *
189 | * @private
190 | * @returns {boolean} 是否初次加载
191 | */
192 | private checkFirstload(): boolean {
193 | const configPath = path.join(__dirname, '../../res/live2d/config.json');
194 | let info: { firstload: boolean } = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
195 |
196 | if (info.firstload) {
197 | // 提示
198 | vsHelp.showInfo('插件: ' + this.extName + '已启动! ');
199 | // 标识插件已启动过
200 | info.firstload = false;
201 | fs.writeFileSync(configPath, JSON.stringify(info, null, ' '), 'utf-8');
202 |
203 | return true;
204 | }
205 |
206 | return false;
207 | }
208 |
209 | /**
210 | * 获取文件状态
211 | *
212 | * @private
213 | * @returns {FileType}
214 | */
215 | private getFileType(): FileType {
216 | let jsContent = this.getContent();
217 | // 未 hack 过
218 | let ifUnInstall: boolean = !~jsContent.indexOf(`ext.${this.extName}.ver`);
219 |
220 | if (ifUnInstall) {
221 | return FileType.empty;
222 | }
223 |
224 | // hack 过的旧版本
225 | let version = jsContent.match(new RegExp(`ext\\.${this.extName}\\.ver\\.(\\d+\\.\\d+\\.\\d+)`));
226 |
227 | if (version && this.version > version[1]) {
228 | return FileType.isOld;
229 | }
230 |
231 | // hack 过的新版本
232 | return FileType.isNew;
233 | }
234 |
235 | }
236 |
237 | function copy(src: string, dst: string) {
238 | let paths = fs.readdirSync(src); //同步读取当前目录
239 | paths.forEach(function (path) {
240 | var _src = src + '/' + path;
241 | var _dst = dst + '/' + path;
242 | fs.stat(_src, function (err, stats) {
243 | //stats 该对象 包含文件属性
244 | if (err) { throw err; }
245 | if (stats.isFile()) {
246 | //如果是个文件则拷贝
247 | let readable = fs.createReadStream(_src); //创建读取流
248 | let writable = fs.createWriteStream(_dst); //创建写入流
249 | readable.pipe(writable);
250 | }
251 | else if (stats.isDirectory()) {
252 | //是目录则 递归
253 | checkDirectory(_src, _dst, copy);
254 | }
255 | });
256 | });
257 | }
258 |
259 | function checkDirectory(src: string, dst: string, callback?: Function) {
260 | fs.access(dst, fs.constants.F_OK, (err) => {
261 | if (err) {
262 | fs.mkdirSync(dst);
263 | callback && callback(src, dst);
264 | }
265 | else {
266 | callback && callback(src, dst);
267 | }
268 | });
269 | }
270 |
271 | /**
272 | * 删除文件内容
273 | *
274 | * @private
275 | * @param {string} path
276 | */
277 | function removeFiles(path: string) {
278 | var files = [];
279 | if (fs.existsSync(path)) {
280 | files = fs.readdirSync(path);
281 | files.forEach(function (file, index) {
282 | var curPath = path + "/" + file;
283 | if (fs.statSync(curPath).isDirectory()) { // recurse
284 | removeFiles(curPath);
285 | } else { // delete file
286 | fs.unlinkSync(curPath);
287 | }
288 | });
289 | fs.rmdirSync(path);
290 | }
291 | }
--------------------------------------------------------------------------------
/src/live2dModify/FileType.ts:
--------------------------------------------------------------------------------
1 | enum FileType {
2 | /**
3 | * 未修改的文件
4 | */
5 | empty,
6 | /**
7 | * hack 过的旧版本文件
8 | */
9 | isOld,
10 | /**
11 | * hack 过的新版本的文件
12 | */
13 | isNew
14 | }
15 |
16 | export default FileType;
--------------------------------------------------------------------------------
/src/live2dModify/Main.ts:
--------------------------------------------------------------------------------
1 |
2 | import * as vscode from 'vscode';
3 | import * as path from 'path';
4 | import version from './version';
5 | import { Dom } from './Dom';
6 | import {
7 | Uri,
8 | window,
9 | InputBoxOptions,
10 | commands,
11 | env,
12 | } from 'vscode';
13 |
14 |
15 | export class Main {
16 | static Instance?: Dom;
17 |
18 | public static watch(): vscode.Disposable {
19 | const base = env.appRoot;
20 | const filePath = path.join(base,'out','vs', 'code', 'electron-sandbox', 'workbench', 'workbench.js');
21 | const configName = 'vscode-live2d-asoul';
22 | const extName = "TheSecondAkari-vscode-live2d";
23 | let DomApi = new Dom(configName, filePath, version, extName);
24 | Main.Instance = DomApi;
25 | return vscode.workspace.onDidChangeConfiguration(() => DomApi.install());
26 | }
27 | }
--------------------------------------------------------------------------------
/src/live2dModify/getJs.ts:
--------------------------------------------------------------------------------
1 | export default function (config: any, extName: string, version: string): string {
2 | return `
3 | /*ext-${extName}-start*/
4 | /*ext.${extName}.ver.${version}*/
5 | class Live2d {
6 | live2dWrapper = undefined; // live2d html最外层节点div
7 | live2dIframe = undefined; // live2d 的具体 iframe页面
8 | anchorCore = 'br'; // live2d div 定位依赖,初始默认为右下角, 一共有四个情况: tl,tr,bl,br
9 | KEY = 'live2d-asoul-config'; // 用于localstorage存储信息的key
10 |
11 | constructor() {
12 | // 添加postmessage事件监听
13 | const receiveMessage = (event) => {
14 | const origin = event.origin || event.originalEvent.origin;
15 | if (origin !== "vscode-webview://webviewview-vscode-live2d-live2dview" && !origin.startsWith('vscode-webview://'))
16 | return;
17 | const { type, data } = event?.data || {};
18 | if(type)
19 | switch (type) {
20 | case 'live2d-asoul-openAutoLodash':
21 | this.saveConfig({ autoLodash: true });
22 | break;
23 | case 'live2d-asoul-closeAutoLodash':
24 | this.saveConfig({ autoLodash: false });
25 | break;
26 | case 'live2d-asoul-lodash':
27 | this.createLive2d();
28 | break;
29 | case 'live2d-asoul-close':
30 | this.deleteLive2d();
31 | break;
32 | case 'live2d-asoul-setAnchor':
33 | this.anchor = data;
34 | break;
35 | case 'live2d-asoul-resetPosition':
36 | this.resetPosition();
37 | break;
38 | case 'live2d-asoul-saveCurrentConfig':
39 | this.saveCurrentConfig();
40 | break;
41 | case 'live2d-asoul-saveBackground':
42 | this.saveBackground();
43 | break;
44 | case 'live2d-asoul-loadBackground':
45 | this.loadBackground();
46 | break;
47 | case 'live2d-asoul-openBackgroundSetTime':
48 | this.openBackgroundSetTime(data);
49 | break;
50 | case 'live2d-asoul-closeBackgroundSetTime':
51 | this.closeBackgroundSetTime();
52 | break;
53 | case 'live2d-asoul-modifyBackgroundConfig':
54 | this.modifyBackgroundConfig(data);
55 | break;
56 | case 'live2d-asoul-downloadBackground':
57 | event.source.postMessage({type: 'live2d-asoul-initDownloadBackground', data: this.live2dIframe?.contentWindow?.currentImgs }, origin);
58 | break;
59 | default:
60 | break;
61 | }
62 | }
63 | window.addEventListener('message', receiveMessage, false);
64 |
65 | // 从localstorage中获取配置信息,进行对应处理
66 | const config = this.getConfig();
67 | if (config.autoLodash === true)
68 | this.createLive2d();
69 | this.anchor = config.anchor;
70 | }
71 |
72 | get anchor() {
73 | return this.anchorCore;
74 | }
75 |
76 | set anchor(value) {
77 | if (['tl', 'tr', 'bl', 'br'].includes(value)) {
78 | this.anchorCore = value;
79 | this.saveConfig({anchor: value});
80 | this.resetLocationDependency(this.live2dWrapper, value); // 恢复目标定位依赖
81 | }
82 | }
83 |
84 | // 会进行校验,最多只允许创建一个
85 | createLive2d = () => {
86 | // if (document.getElementById('live2d-wrapper'))
87 | // return;
88 | if (this.live2dWrapper) {
89 | document.body.appendChild(this.live2dWrapper);
90 | return;
91 | }
92 | this.live2dWrapper = document.createElement('div');
93 | this.live2dWrapper.id = 'live2d-wrapper';
94 | Object.assign(this.live2dWrapper.style, this.getConfig().style);
95 | // 显示iframe, live2d
96 | const iframe = this.initIframe();
97 | if (!iframe)
98 | return;
99 | this.live2dIframe = iframe;
100 | this.live2dWrapper.appendChild(iframe);
101 | // 控制按钮
102 | const controlBar = this.initControlBar(this.live2dWrapper);
103 | controlBar && this.live2dWrapper.appendChild(controlBar);
104 | this.addWrapperStyle();
105 | document.body.appendChild(this.live2dWrapper);
106 | }
107 |
108 | // 只是将 live2dWrapper 整个节点从body移除,依旧存在内存中,因为还存在事件的引用
109 | deleteLive2d = () => {
110 | if (this.live2dWrapper) {
111 | this.live2dWrapper.remove();
112 | // this.live2dWrapper = undefined;
113 | }
114 | }
115 |
116 | // 外壳wrapper基础样式
117 | addWrapperStyle = () => {
118 | let styleNode = document.createElement('style');
119 | let styleContent = \`
120 | div#live2d-wrapper {
121 | width: 280px;
122 | height: 300px;
123 | position: fixed;
124 | bottom: 50px;
125 | right: 50px;
126 | z-index: 100;
127 | }
128 | .live2d-wrapper-controller-wrapper {
129 | pointer-events:auto;
130 | position: absolute;
131 | right: 1px;
132 | top: 2px;
133 | display:flex;
134 | opacity: 0;
135 | transition: all 0.2s;
136 | }
137 | div#live2d-wrapper:hover .live2d-wrapper-controller-wrapper {
138 | opacity: 1;
139 | }
140 | .live2d-wrapper-controller-icon {
141 | width:16px;
142 | height:16px;
143 | cursor: pointer;
144 | transition: all 0.3s;
145 | }
146 | .live2d-wrapper-controller-icon:hover {
147 | width:20px;
148 | height:20px;
149 | }
150 | .live2d-wrapper-controller-corner {
151 | width: 10px;
152 | height: 10px;
153 | background-color: #faa;
154 | position: absolute;
155 | }
156 | \`;
157 | styleNode.appendChild(document.createTextNode(styleContent))
158 | document.head.appendChild(styleNode);
159 | }
160 |
161 | // iframe, 初始化具体live2d的页面
162 | initIframe = () => {
163 | const str = window.location.href;
164 | if (!str.includes('workbench.html'))
165 | return
166 | const iframe = document.createElement('iframe');
167 | iframe.style.cssText = 'width:100%; height:100%; border:0;';
168 | iframe.src = str.replace('workbench.html', 'live2d/index.html');
169 | return iframe;
170 | }
171 |
172 | // 控制图标,三个图标 调整大小,点击穿透,拖拽位置
173 | initControlBar = (container) => {
174 | const controlEles = document.createElement('div');
175 | controlEles.classList.add("live2d-wrapper-controller-wrapper");
176 |
177 | const borderIconDiv = document.createElement('div');
178 | borderIconDiv.title = '调整大小';
179 | const borderIcon = document.createElement('img');
180 | borderIcon.src = './live2d/assets/border.png';
181 | borderIcon.classList.add("live2d-wrapper-controller-icon");
182 | borderIcon.addEventListener('click', (() => {
183 | let hasBorder = false;
184 | let corners;
185 | return () => {
186 | hasBorder = !hasBorder;
187 | if (hasBorder)
188 | corners = this.addBorderCorner(container, corners);
189 | else
190 | corners.forEach(ele => ele.remove());
191 | // container.style.border = hasBorder ? 'solid 4px white' : '0';
192 | }
193 | })());
194 | borderIconDiv.appendChild(borderIcon);
195 | controlEles.appendChild(borderIconDiv);
196 |
197 | const penetrateIconDiv = document.createElement('div');
198 | penetrateIconDiv.title = '是否允许点击穿透';
199 | penetrateIconDiv.style.cssText = 'margin: 0 6px;';
200 | const penetrateIcon = document.createElement('img');
201 | penetrateIcon.src = './live2d/assets/pierce.png';
202 | penetrateIcon.classList.add("live2d-wrapper-controller-icon");
203 | penetrateIcon.addEventListener('click', (() => {
204 | let isPenetrate = false;
205 | return () => {
206 | isPenetrate = !isPenetrate;
207 | controlEles.style.opacity = isPenetrate ? '1' : '';
208 | container.style.pointerEvents = isPenetrate ? 'none' : 'auto';
209 | }
210 | })());
211 | penetrateIconDiv.appendChild(penetrateIcon);
212 | controlEles.appendChild(penetrateIconDiv);
213 |
214 | const dragIconDiv = document.createElement('div');
215 | dragIconDiv.title = '鼠标按住拖拽移动';
216 | const dragIcon = document.createElement('img');
217 | dragIcon.src = './live2d/assets/pin.png';
218 | dragIcon.classList.add("live2d-wrapper-controller-icon");
219 | document.addEventListener("mousedown", e => {
220 | // 这里过滤掉非目标元素
221 | if (e.target !== dragIcon) {
222 | return;
223 | }
224 | const disx = e.pageX - container.offsetLeft;//获取鼠标相对元素距离
225 | const disy = e.pageY - container.offsetTop;
226 |
227 | // 防止鼠标移动到iframe上,使得鼠标移动事件丢失
228 | const iframe = container.getElementsByTagName('iframe')[0];
229 | iframe && (iframe.style.pointerEvents = 'none');
230 |
231 | const handleMove = (event) => {
232 | container.style.left = event.pageX - disx + 'px';
233 | container.style.top = event.pageY - disy + 'px';
234 | };
235 | const tempMouseUp = () => {
236 | iframe && (iframe.style.pointerEvents = 'inherit');
237 | this.resetLocationDependency(container, this.anchor); // 恢复目标定位依赖
238 | document.removeEventListener("mousemove", handleMove);
239 | document.removeEventListener("mouseup", tempMouseUp);
240 | }
241 | document.addEventListener("mousemove", handleMove);
242 | document.addEventListener("mouseup", tempMouseUp);
243 | e.preventDefault();//阻止浏览器的默认事件
244 | });
245 | dragIconDiv.appendChild(dragIcon);
246 | controlEles.appendChild(dragIconDiv);
247 |
248 | return controlEles;
249 | }
250 |
251 | // 初始化4个角落点,用于后续拖拽缩放大小
252 | initCorner = () => {
253 | // 来4个元素
254 | const eles = Array.from({ length: 4 }).map(() =>
255 | document.createElement("div")
256 | );
257 | eles.forEach(x => x.classList.add("live2d-wrapper-controller-corner"));
258 | // 分别在topleft、topright、bottomleft、bottomright位置
259 | const [tl, tr, bl, br] = eles;
260 |
261 | // 每一个角都移动半个身位
262 | Object.assign(tl.style, {
263 | top: "-5px",
264 | left: "-5px",
265 | cursor: "nw-resize"
266 | });
267 | Object.assign(tr.style, {
268 | top: "-5px",
269 | cursor: "ne-resize",
270 | right: "-5px"
271 | });
272 | Object.assign(bl.style, {
273 | bottom: "-5px",
274 | cursor: "sw-resize",
275 | left: "-5px"
276 | });
277 | Object.assign(br.style, {
278 | bottom: "-5px",
279 | cursor: "se-resize",
280 | right: "-5px"
281 | });
282 | return { eles };
283 | }
284 |
285 | // 给4个角落点挂载事件
286 | drag = (ele, container, type) => {
287 | if (!type)
288 | return;
289 | document.addEventListener("mousedown", e => {
290 | // 这里过滤掉非目标元素
291 | if (e.target !== ele) {
292 | return;
293 | }
294 |
295 | const { width, height } = container.getBoundingClientRect();
296 |
297 | // 固定container元素,以使不同定位角可以拉动, 因为是对角拖拽,所以需要用对角定位
298 | const antiType = (type[0] == 't' ? 'b' : 't') + (type[1] == 'l' ? 'r' : 'l');
299 | this.resetLocationDependency(container, antiType);
300 |
301 | // 防止鼠标移动到iframe上,使得鼠标移动事件丢失
302 | const iframe = container.getElementsByTagName('iframe')[0];
303 | iframe && (iframe.style.pointerEvents = 'none');
304 |
305 | const disx = e.pageX;//获取鼠标相对元素距离
306 | const disy = e.pageY;
307 |
308 | let factorWidth = (type === 'tl' || type === 'bl') ? -1 : 1;
309 | let factorHeight = (type === 'tl' || type === 'tr') ? -1 : 1;
310 | const Live2dResize = (event) => {
311 | const newWidth = width + (event.pageX - disx) * factorWidth;
312 | const newHeight = height + (event.pageY - disy) * factorHeight;
313 | // 最小宽高
314 | if (newWidth >= 75)
315 | container.style.width = newWidth + 'px';
316 | if (newHeight >= 75)
317 | container.style.height = newHeight + 'px';
318 | };
319 |
320 | const tempMouseUp = () => {
321 | iframe && (iframe.style.pointerEvents = 'inherit');
322 | this.resetLocationDependency(container, this.anchor); // 恢复目标定位依赖
323 | document.removeEventListener("mousemove", Live2dResize);
324 | document.removeEventListener("mouseup", tempMouseUp);
325 | }
326 | document.addEventListener("mousemove", Live2dResize);
327 | document.addEventListener("mouseup", tempMouseUp);
328 | e.preventDefault();//阻止浏览器的默认事件
329 | });
330 | }
331 |
332 | addBorderCorner = (target, corners) => {
333 | if (!target)
334 | return;
335 | // 获取四个角——eles
336 | if (!corners) {
337 | const { eles } = this.initCorner();
338 | const [tl, tr, bl, br] = eles;
339 | target.appendChild(tl);
340 | this.drag(tl, target, 'tl');
341 | target.appendChild(tr);
342 | this.drag(tr, target, 'tr');
343 | target.appendChild(bl);
344 | this.drag(bl, target, 'bl');
345 | target.appendChild(br);
346 | this.drag(br, target, 'br');
347 | return eles;
348 | }
349 | else {
350 | corners.forEach(ele => target.appendChild(ele));
351 | return corners;
352 | }
353 | }
354 |
355 | // 重置元素对于某个角落的定位, target目标元素 , type定位角落
356 | resetLocationDependency = (target, type) => {
357 | if (target && type) {
358 | const { top, bottom, left, right } = target.getBoundingClientRect();
359 |
360 | const pageWidth = document.documentElement.clientWidth;
361 | const pageHeight = document.documentElement.clientHeight;
362 |
363 | if (type === 'tl') {
364 | target.style.top = top + 'px';
365 | target.style.left = left + 'px';
366 | target.style.right = '';
367 | target.style.bottom = '';
368 | }
369 | else if (type === 'tr') {
370 | target.style.top = top + 'px';
371 | target.style.left = '';
372 | target.style.right = pageWidth - right + 'px';
373 | target.style.bottom = '';
374 | }
375 | else if (type === 'bl') {
376 | target.style.top = '';
377 | target.style.left = left + 'px';
378 | target.style.right = '';
379 | target.style.bottom = pageHeight - bottom + 'px';
380 |
381 | }
382 | else if (type === 'br') {
383 | target.style.top = '';
384 | target.style.left = '';
385 | target.style.right = pageWidth - right + 'px';
386 | target.style.bottom = pageHeight - bottom + 'px';
387 | }
388 | }
389 | }
390 |
391 | resetPosition = () => {
392 | if (this.live2dWrapper) {
393 | const style = this.live2dWrapper.style;
394 | style.top = '';
395 | style.right = '';
396 | style.bottom = '';
397 | style.left = '';
398 | style.width = '';
399 | style.height = '';
400 | }
401 | }
402 |
403 | saveCurrentConfig = () => {
404 | if (this.live2dWrapper) {
405 | const { top, right, bottom, left, width, height } = this.live2dWrapper.style;
406 | const style = { top, right, bottom, left, width, height };
407 | this.saveConfig({ style })
408 | }
409 | }
410 |
411 | saveConfig = (newData) => {
412 | const str = localStorage.getItem(this.KEY);
413 | const data = str ? JSON.parse(str) : { autoLodash: false, anchor: 'br', style: {} };
414 | localStorage.setItem(this.KEY, JSON.stringify({ ...data, ...newData }));
415 | }
416 |
417 | getConfig = () => {
418 | const str = localStorage.getItem(this.KEY);
419 | return str ? JSON.parse(str) : { autoLodash: false, anchor: 'br', style: {} };
420 | }
421 |
422 | saveBackground = () => {
423 | const fn = this.live2dIframe?.contentWindow?.saveBackground;
424 | fn && fn();
425 | }
426 |
427 | loadBackground = () => {
428 | const fn = this.live2dIframe?.contentWindow?.loadBackground;
429 | fn && fn();
430 | }
431 |
432 | openBackgroundSetTime = (time) => {
433 | const fn = this.live2dIframe?.contentWindow?.openBackgroundSetTime;
434 | fn && fn(time);
435 | }
436 |
437 | closeBackgroundSetTime = () => {
438 | const fn = this.live2dIframe?.contentWindow?.closeBackgroundSetTime;
439 | fn && fn();
440 | }
441 |
442 | modifyBackgroundConfig = (config) => {
443 | const fn = this.live2dIframe?.contentWindow?.modifyBackgroundConfig;
444 | fn && fn(config);
445 | }
446 | }
447 |
448 | let live2dInstance = new Live2d();
449 |
450 | /*ext-${extName}-end*/
451 | `;
452 | }
--------------------------------------------------------------------------------
/src/live2dModify/index.ts:
--------------------------------------------------------------------------------
1 | import * as vscode from 'vscode';
2 | import { Main } from './Main';
3 |
4 | export function activateModify(context: vscode.ExtensionContext) {
5 | context.subscriptions.push(Main.watch());
6 | }
7 |
8 | export function deactivateModify() { }
--------------------------------------------------------------------------------
/src/live2dModify/uninstall.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as fs from 'fs';
3 | import {
4 | Uri,
5 | window,
6 | InputBoxOptions,
7 | commands,
8 | env,
9 | } from 'vscode';
10 |
11 | const base = process.cwd();
12 | // 文件路径
13 | const filePath = path.join(base, 'resources', 'app', 'out', 'vs', 'code', 'electron-sandbox', 'workbench', 'workbench.js');
14 | const extName = "vscode-live2d";
15 |
16 |
17 | //执行清理
18 | main();
19 |
20 | //清理内容
21 | function main() {
22 | try {
23 | let content = getContent();
24 | const base = env.appRoot;
25 | content = clearCssContent(content);
26 | saveContent(content);
27 | removeFiles(path.join(base,'out', 'vs', 'code', 'electron-sandbox', 'workbench', 'live2d'));
28 | return true;
29 | }
30 | catch (ex) {
31 | return false;
32 | }
33 | }
34 |
35 |
36 | /**
37 | * 获取文件内容
38 | * @var mixed
39 | */
40 | function getContent(): string {
41 | return fs.readFileSync(filePath, 'utf-8');
42 | }
43 |
44 |
45 | /**
46 | * 清理已经添加的代码
47 | *
48 | * @private
49 | * @param {string} content
50 | * @returns {string}
51 | */
52 | function clearCssContent(content: string): string {
53 | var re = new RegExp("\\/\\*ext-" + extName + "-start\\*\\/[\\s\\S]*?\\/\\*ext-" + extName + "-end\\*" + "\\/", "g");
54 | content = content.replace(re, '');
55 | content = content.replace(/\s*$/, '');
56 | content += '\n';
57 | return content;
58 | }
59 |
60 |
61 | /**
62 | * 设置文件内容
63 | *
64 | * @private
65 | * @param {string} content
66 | */
67 | function saveContent(content: string): void {
68 | fs.writeFileSync(filePath, content, 'utf-8');
69 | }
70 |
71 |
72 | /**
73 | * 删除文件内容
74 | *
75 | * @private
76 | * @param {string} path
77 | */
78 | function removeFiles(path: string) {
79 | var files = [];
80 | if (fs.existsSync(path)) {
81 | files = fs.readdirSync(path);
82 | files.forEach(function (file, index) {
83 | var curPath = path + "/" + file;
84 | if (fs.statSync(curPath).isDirectory()) { // recurse
85 | removeFiles(curPath);
86 | } else { // delete file
87 | fs.unlinkSync(curPath);
88 | }
89 | });
90 | fs.rmdirSync(path);
91 | }
92 | }
--------------------------------------------------------------------------------
/src/live2dModify/version.ts:
--------------------------------------------------------------------------------
1 | export default '0.1.12';
--------------------------------------------------------------------------------
/src/live2dModify/vsHelp.ts:
--------------------------------------------------------------------------------
1 | import * as vscode from 'vscode';
2 |
3 | const vsHelp = {
4 | /**
5 | * 展示信息提示框
6 | *
7 | * @param {string} content 提示内容
8 | * @returns {Thenable}
9 | */
10 | showInfo(content: string): Thenable {
11 | return vscode.window.showInformationMessage(content);
12 | },
13 |
14 | /**
15 | * 提示信息并重启
16 | *
17 | * @param {any} content 提示内容
18 | * @returns {Thenable}
19 | */
20 | showInfoRestart(content: any): Thenable {
21 | return vscode.window.showInformationMessage(content, { title: "重新加载" })
22 | .then(function (item) {
23 | if (!item) { return; }
24 | vscode.commands.executeCommand('workbench.action.reloadWindow');
25 | });
26 | }
27 | };
28 |
29 | export default vsHelp;
--------------------------------------------------------------------------------
/src/live2dView/index.ts:
--------------------------------------------------------------------------------
1 | import * as vscode from "vscode";
2 | import { Main } from "../live2dModify/Main";
3 |
4 | export function activateLive2d(context: vscode.ExtensionContext) {
5 | const provider = new Live2dViewProvider(context.extensionUri);
6 |
7 | context.subscriptions.push(
8 | vscode.window.registerWebviewViewProvider(
9 | Live2dViewProvider.viewType,
10 | provider
11 | )
12 | );
13 | }
14 |
15 | class Live2dViewProvider implements vscode.WebviewViewProvider {
16 | public static readonly viewType = "vscode-live2d.live2dView";
17 |
18 | private _view?: vscode.WebviewView;
19 |
20 | constructor(private readonly _extensionUri: vscode.Uri) {}
21 |
22 | public resolveWebviewView(
23 | webviewView: vscode.WebviewView,
24 | context: vscode.WebviewViewResolveContext,
25 | _token: vscode.CancellationToken
26 | ) {
27 | this._view = webviewView;
28 |
29 | webviewView.webview.options = {
30 | // Allow scripts in the webview
31 | enableScripts: true,
32 | localResourceRoots: [this._extensionUri],
33 | };
34 |
35 | webviewView.webview.html = this._getHtmlForWebview(webviewView.webview);
36 |
37 | webviewView.webview.onDidReceiveMessage((data) => {
38 | switch (data.type) {
39 | case "generateResources":
40 | Main.Instance && Main.Instance.generateResources();
41 | break;
42 | case "removeResources":
43 | Main.Instance && Main.Instance.removeResources(true);
44 | break;
45 | }
46 | });
47 | }
48 |
49 | private _getHtmlForWebview(webview: vscode.Webview) {
50 | // Get the local path to main script run in the webview, then convert it to a uri we can use in the webview.
51 | const scriptUri = webview.asWebviewUri(
52 | vscode.Uri.joinPath(this._extensionUri, "media", "main.js")
53 | );
54 |
55 | // Do the same for the stylesheet.
56 | const styleVSCodeUri = webview.asWebviewUri(
57 | vscode.Uri.joinPath(this._extensionUri, "media", "vscode.css")
58 | );
59 | const styleMainUri = webview.asWebviewUri(
60 | vscode.Uri.joinPath(this._extensionUri, "media", "main.css")
61 | );
62 |
63 | // Use a nonce to only allow a specific script to be run.
64 | const nonce = getNonce();
65 |
66 | return `
67 |
68 |
69 |
70 |
71 |
72 | Live 2d
73 |
74 |
75 |
76 |
基本操作:
77 |
78 | 启动live2d
79 | 关闭live2d
80 |
81 |
82 |
86 | 保存当前配置
87 |
88 | 重置默认位置
89 |
90 |
91 |
92 |
配置信息:
93 |
自启动:
94 |
95 | 开启
96 | 关闭
97 |
98 |
102 |
定位依赖:
103 |
104 | 左上角
105 | 右上角
106 | 左下角
107 | 右下角
108 |
109 |
插件依赖文件:
110 |
111 |
115 | 生成
116 |
117 |
121 | 移除
122 |
123 |
124 |
125 |
背景图相关功能失效
126 |
因为获取图片的接口没了
127 |
背景图:(需要先启动live2d人物)
128 |
129 | 保存背景图
130 | 加载背景图
131 |
132 |
定时切换(分钟):
133 |
134 |
135 | 开启
136 | 关闭
137 |
138 |
背景图配置:(会默认使用最近配置)
139 |
143 |
144 |
适配样式:
145 |
146 | 背景图适配样式,默认是覆盖
147 | 覆盖
148 | 适应
149 |
150 |
151 |
152 | 确认
153 | 恢复默认
154 |
155 |
156 |
157 |
测试功能:
158 |
下载当前背景图(勿短时间内多次点击):
159 |
160 | 获取当前背景
161 | 移除下载展示
162 |
163 |
164 |
165 |
166 |
167 |
168 | `;
169 | }
170 | }
171 |
172 | function getNonce() {
173 | let text = "";
174 | const possible =
175 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
176 | for (let i = 0; i < 32; i++) {
177 | text += possible.charAt(Math.floor(Math.random() * possible.length));
178 | }
179 | return text;
180 | }
181 |
182 | //
183 |
--------------------------------------------------------------------------------
/src/test/runTest.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 |
3 | import { runTests } from '@vscode/test-electron';
4 |
5 | async function main() {
6 | try {
7 | // The folder containing the Extension Manifest package.json
8 | // Passed to `--extensionDevelopmentPath`
9 | const extensionDevelopmentPath = path.resolve(__dirname, '../../');
10 |
11 | // The path to test runner
12 | // Passed to --extensionTestsPath
13 | const extensionTestsPath = path.resolve(__dirname, './suite/index');
14 |
15 | // Download VS Code, unzip it and run the integration test
16 | await runTests({ extensionDevelopmentPath, extensionTestsPath });
17 | } catch (err) {
18 | console.error('Failed to run tests');
19 | process.exit(1);
20 | }
21 | }
22 |
23 | main();
24 |
--------------------------------------------------------------------------------
/src/test/suite/extension.test.ts:
--------------------------------------------------------------------------------
1 | import * as assert from 'assert';
2 |
3 | // You can import and use all API from the 'vscode' module
4 | // as well as import your extension to test it
5 | import * as vscode from 'vscode';
6 | // import * as myExtension from '../../extension';
7 |
8 | suite('Extension Test Suite', () => {
9 | vscode.window.showInformationMessage('Start all tests.');
10 |
11 | test('Sample test', () => {
12 | assert.strictEqual(-1, [1, 2, 3].indexOf(5));
13 | assert.strictEqual(-1, [1, 2, 3].indexOf(0));
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/src/test/suite/index.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as Mocha from 'mocha';
3 | import * as glob from 'glob';
4 |
5 | export function run(): Promise {
6 | // Create the mocha test
7 | const mocha = new Mocha({
8 | ui: 'tdd',
9 | color: true
10 | });
11 |
12 | const testsRoot = path.resolve(__dirname, '..');
13 |
14 | return new Promise((c, e) => {
15 | glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {
16 | if (err) {
17 | return e(err);
18 | }
19 |
20 | // Add files to the test suite
21 | files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
22 |
23 | try {
24 | // Run the mocha test
25 | mocha.run(failures => {
26 | if (failures > 0) {
27 | e(new Error(`${failures} tests failed.`));
28 | } else {
29 | c();
30 | }
31 | });
32 | } catch (err) {
33 | console.error(err);
34 | e(err);
35 | }
36 | });
37 | });
38 | }
39 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "ES2020",
5 | "outDir": "out",
6 | "lib": [
7 | "ES2020"
8 | ],
9 | "sourceMap": true,
10 | "rootDir": "src",
11 | "strict": false /* enable all strict type-checking options */
12 | /* Additional Checks */
13 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
14 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
15 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
16 | },
17 | "exclude": [
18 | "node_modules",
19 | ".vscode-test"
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/vsc-extension-quickstart.md:
--------------------------------------------------------------------------------
1 | # Welcome to your VS Code Extension
2 |
3 | ## What's in the folder
4 |
5 | * This folder contains all of the files necessary for your extension.
6 | * `package.json` - this is the manifest file in which you declare your extension and command.
7 | * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin.
8 | * `src/extension.ts` - this is the main file where you will provide the implementation of your command.
9 | * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`.
10 | * We pass the function containing the implementation of the command as the second parameter to `registerCommand`.
11 |
12 | ## Get up and running straight away
13 |
14 | * Press `F5` to open a new window with your extension loaded.
15 | * Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`.
16 | * Set breakpoints in your code inside `src/extension.ts` to debug your extension.
17 | * Find output from your extension in the debug console.
18 |
19 | ## Make changes
20 |
21 | * You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`.
22 | * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes.
23 |
24 |
25 | ## Explore the API
26 |
27 | * You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`.
28 |
29 | ## Run tests
30 |
31 | * Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`.
32 | * Press `F5` to run the tests in a new window with your extension loaded.
33 | * See the output of the test result in the debug console.
34 | * Make changes to `src/test/suite/extension.test.ts` or create new test files inside the `test/suite` folder.
35 | * The provided test runner will only consider files matching the name pattern `**.test.ts`.
36 | * You can create folders inside the `test` folder to structure your tests any way you want.
37 |
38 | ## Go further
39 |
40 | * Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension).
41 | * [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace.
42 | * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration).
43 |
--------------------------------------------------------------------------------