mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-08-28 05:13:57 +08:00
docs: 动画指南
This commit is contained in:
parent
a10af04b79
commit
c26ae39060
@ -72,8 +72,12 @@ export default defineConfig({
|
|||||||
link: '/guide/implements/skill'
|
link: '/guide/implements/skill'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '自定义按键',
|
text: '新增按键',
|
||||||
link: '/guide/implements/hotkey'
|
link: '/guide/implements/hotkey'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '动画效果',
|
||||||
|
link: '/guide/implements/animate'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
182
docs/guide/implements/animate.md
Normal file
182
docs/guide/implements/animate.md
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
# 动画效果
|
||||||
|
|
||||||
|
2.B 提供了专门的动画接口,允许你用短短几行就可以做出一个效果不错的动画。本节主要讲述的是 UI 中的动画。
|
||||||
|
|
||||||
|
## 定义动画属性
|
||||||
|
|
||||||
|
我们以一个自定义 UI 为例,来讲述如何编写一段动画。自定义 UI 参考[此指南](./new-ui.md)和[此教程](../../guide/ui.md)。
|
||||||
|
|
||||||
|
假设自定义 UI 在 `packages-user/client-modules/src/render/ui` 文件夹下,我们需要引入 `transitioned` 接口,并调用它定义动画属性:
|
||||||
|
|
||||||
|
```tsx {8-13}
|
||||||
|
// 引入接口,如果文件夹不同,注意路径关系
|
||||||
|
import { transitioned } from '../use';
|
||||||
|
// 从 mutate-animate 库中引入速率曲线函数
|
||||||
|
import { hyper } from 'mutate-animate';
|
||||||
|
|
||||||
|
// UI 模板及如何编写 UI 参考 “新增 UI” 需求指南,这里只给出必要的修改部分,模板部分不再给出
|
||||||
|
export const MyCom = defineComponent(() => {
|
||||||
|
// 定义动画属性
|
||||||
|
const value = transitioned(
|
||||||
|
1, // 初始值是 1
|
||||||
|
500, // 动画时长 500ms
|
||||||
|
hyper('sin', 'out') // 速率曲线是双曲正弦函数(此曲线观感较好)
|
||||||
|
)!;
|
||||||
|
// 上一行的感叹号为非空断言,因为此接口在组件或 UI 外调用会返回 null,
|
||||||
|
// 而我们在 UI 内,因此我们需要断言其不可能为 null
|
||||||
|
|
||||||
|
return () => <container></container>;
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
注意 `transitioned` 只能在 UI 或组件的顶层调用,不能在 UI 的函数内调用,也不可在 UI 外调用,在其他地方调用会返回 `null`!
|
||||||
|
|
||||||
|
## 添加到元素属性
|
||||||
|
|
||||||
|
定义属性后,我们需要把属性添加到元素上,直接使用 `value.ref.value` 即可,这里以不透明度 `alpha` 属性为例:
|
||||||
|
|
||||||
|
```tsx {9}
|
||||||
|
// UI 模板及如何编写 UI 参考 “新增 UI” 需求指南,这里只给出必要的修改部分,模板部分不再给出
|
||||||
|
export const MyCom = defineComponent(() => {
|
||||||
|
// 定义动画属性
|
||||||
|
const value = transitioned(1, 500, hyper('sin', 'out'))!;
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<container>
|
||||||
|
{/* 将 value.ref.value 赋值给 alpha 属性 */}
|
||||||
|
<g-rect rect={[0, 0, 100, 100]} alpha={value.ref.value} />
|
||||||
|
</container>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## 执行动画
|
||||||
|
|
||||||
|
最后,在我们需要的时候执行动画即可,使用 `value.set`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
export const MyCom = defineComponent(() => {
|
||||||
|
// 定义动画属性
|
||||||
|
const value = transitioned(1, 500, hyper('sin', 'out'))!;
|
||||||
|
|
||||||
|
// 例如在 UI 挂载完毕后执行
|
||||||
|
onMounted(() => {
|
||||||
|
// 动画属性调成 0,效果就是矩形逐渐从不透明变成完全透明
|
||||||
|
value.set(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<container>
|
||||||
|
<g-rect rect={[0, 0, 100, 100]} alpha={value.ref.value} />
|
||||||
|
</container>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## 拓展-颜色动画
|
||||||
|
|
||||||
|
除了一般数值的动画外,样板还支持颜色动画,使用 `transitionedColor` 接口,用法与 `transitioned` 基本一致:
|
||||||
|
|
||||||
|
```tsx {23}
|
||||||
|
// 引入接口,如果文件夹不同,注意路径关系
|
||||||
|
import { transitionedColor } from '../use'; // [!code ++]
|
||||||
|
// 从 mutate-animate 库中引入速率曲线函数
|
||||||
|
import { hyper } from 'mutate-animate';
|
||||||
|
|
||||||
|
export const MyCom = defineComponent(() => {
|
||||||
|
// 定义颜色动画
|
||||||
|
const color = transitionedColor(
|
||||||
|
'#fff', // 初始颜色,设定为白色 // [!code ++]
|
||||||
|
1000, // 动画时长 1s
|
||||||
|
hyper('sin', 'out') // 动画速率曲线
|
||||||
|
)!;
|
||||||
|
|
||||||
|
// 例如在 UI 挂载完毕后执行
|
||||||
|
onMounted(() => {
|
||||||
|
// 颜色调成纯黑
|
||||||
|
color.set('#000'); // [!code ++]
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<container>
|
||||||
|
{/* 将 fillStyle 赋值为 color.ref.value */}
|
||||||
|
<g-rect rect={[0, 0, 100, 100]} fillStyle={color.ref.value} />
|
||||||
|
</container>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
颜色目前仅支持输入 `#RGB` `#RGBA` `#RRGGBB` `#RRGGBBAA` `rgb(r,g,b)` `rgba(r,g,b,a)` 几种格式的字符串。
|
||||||
|
|
||||||
|
## 拓展-配合交互
|
||||||
|
|
||||||
|
我们可以配合交互实现以下几种功能:
|
||||||
|
|
||||||
|
### 鼠标移入移出
|
||||||
|
|
||||||
|
当鼠标移入时高亮,当移出时恢复:
|
||||||
|
|
||||||
|
```tsx {8-11,19-20}
|
||||||
|
import { transitionedColor } from '../use';
|
||||||
|
import { hyper } from 'mutate-animate';
|
||||||
|
|
||||||
|
export const MyCom = defineComponent(() => {
|
||||||
|
// 初始颜色为灰色
|
||||||
|
const color = transitionedColor('#aaa', 200, hyper('sin', 'out'))!;
|
||||||
|
|
||||||
|
/** 鼠标移入时变成白色 */
|
||||||
|
const enter = () => color.set('#fff');
|
||||||
|
/** 鼠标移出时恢复为灰色 */
|
||||||
|
const leave = () => color.set('#aaa');
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<container>
|
||||||
|
<g-rect
|
||||||
|
rect={[0, 0, 100, 100]}
|
||||||
|
fillStyle={color.ref.value}
|
||||||
|
// 监听 enter 和 leave 事件
|
||||||
|
onEnter={enter}
|
||||||
|
onLeave={leave}
|
||||||
|
/>
|
||||||
|
</container>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 点击切换状态
|
||||||
|
|
||||||
|
鼠标点击或触碰点击后高亮,再次点击恢复:
|
||||||
|
|
||||||
|
```tsx {8-15,23}
|
||||||
|
import { transitionedColor } from '../use';
|
||||||
|
import { hyper } from 'mutate-animate';
|
||||||
|
|
||||||
|
export const MyCom = defineComponent(() => {
|
||||||
|
// 初始颜色为灰色
|
||||||
|
const color = transitionedColor('#aaa', 200, hyper('sin', 'out'))!;
|
||||||
|
|
||||||
|
let highlight = false;
|
||||||
|
/** 点击时触发 */
|
||||||
|
const click = () => {
|
||||||
|
// 如果已经高亮,那么恢复为灰色,否则高亮为白色
|
||||||
|
color.set(highlight ? '#aaa' : '#fff');
|
||||||
|
// 切换状态
|
||||||
|
highlight = !highlight;
|
||||||
|
};
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<container>
|
||||||
|
<g-rect
|
||||||
|
rect={[0, 0, 100, 100]}
|
||||||
|
fillStyle={color.ref.value}
|
||||||
|
// 监听 click 事件
|
||||||
|
onClick={click}
|
||||||
|
/>
|
||||||
|
</container>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## 拓展-API 参考
|
||||||
|
|
||||||
|
参考[此 API 文档](../../api/user-client-modules/functions.md#transitioned)。
|
@ -1,4 +1,4 @@
|
|||||||
# 自定义按键
|
# 新增按键
|
||||||
|
|
||||||
在 2.B 中新增按键很方便,且可以为你的 UI 单独配置按键信息,玩家也可以修改快捷键设置。
|
在 2.B 中新增按键很方便,且可以为你的 UI 单独配置按键信息,玩家也可以修改快捷键设置。
|
||||||
|
|
||||||
@ -91,8 +91,8 @@ gameKey
|
|||||||
|
|
||||||
```tsx {7-13}
|
```tsx {7-13}
|
||||||
// 引入 useKey 接口
|
// 引入 useKey 接口
|
||||||
// 文件在 packages-user/client-modules/src/render/utils/use.ts,注意路径关系
|
// 文件在 packages-user/client-modules/src/render/use.ts,注意路径关系
|
||||||
import { useKey } from '../utils/use'; // [!code ++]
|
import { useKey } from '../use'; // [!code ++]
|
||||||
|
|
||||||
// UI 模板及如何编写 UI 参考 “新增 UI” 需求指南,这里只给出必要的修改部分,模板部分不再给出
|
// UI 模板及如何编写 UI 参考 “新增 UI” 需求指南,这里只给出必要的修改部分,模板部分不再给出
|
||||||
export const MyCom = defineComponent(props => {
|
export const MyCom = defineComponent(props => {
|
||||||
@ -113,7 +113,7 @@ export const MyCom = defineComponent(props => {
|
|||||||
我们会有一些通用按键,例如确认、关闭,这些按键我们不希望每个 UI 或场景都定义一遍,一来写代码不方便,二来玩家如果要自定义的话需要每个界面都设置一遍,很麻烦。此时我们建议按键复用。与一般的按键一致,我们直接实现 `exit` `confirm` 等按键即可,不需额外操作:
|
我们会有一些通用按键,例如确认、关闭,这些按键我们不希望每个 UI 或场景都定义一遍,一来写代码不方便,二来玩家如果要自定义的话需要每个界面都设置一遍,很麻烦。此时我们建议按键复用。与一般的按键一致,我们直接实现 `exit` `confirm` 等按键即可,不需额外操作:
|
||||||
|
|
||||||
```tsx {12-21}
|
```tsx {12-21}
|
||||||
import { useKey } from '../utils/use';
|
import { useKey } from '../use';
|
||||||
|
|
||||||
// UI 模板及如何编写 UI 参考 “新增 UI” 需求指南,这里只给出必要的修改部分,模板部分不再给出
|
// UI 模板及如何编写 UI 参考 “新增 UI” 需求指南,这里只给出必要的修改部分,模板部分不再给出
|
||||||
export const MyCom = defineComponent(props => {
|
export const MyCom = defineComponent(props => {
|
||||||
|
@ -750,3 +750,7 @@ const themeStyle = {
|
|||||||
<g-rect fill {...themeStyle} />
|
<g-rect fill {...themeStyle} />
|
||||||
<g-circle stroke {...themeStyle} />
|
<g-circle stroke {...themeStyle} />
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## API 参考
|
||||||
|
|
||||||
|
参考[API 文档](../api/motajs-render-vue/index.md),这里有更细致的 API 介绍。
|
||||||
|
@ -2,12 +2,18 @@
|
|||||||
|
|
||||||
本节将会讲解 2.B 的渲染树与 UI 系统的工作原理,以及一些常用 API。
|
本节将会讲解 2.B 的渲染树与 UI 系统的工作原理,以及一些常用 API。
|
||||||
|
|
||||||
|
:::info
|
||||||
|
**这部分可以选择性阅读,多数功能一般场景下用不到。**
|
||||||
|
:::
|
||||||
|
|
||||||
## 创建一个自己的 UI 管理器
|
## 创建一个自己的 UI 管理器
|
||||||
|
|
||||||
样板提供 `UIController` 类,允许你在自己的一个 UI 中创建自己的 UI 管理器,例如在样板中,游戏画面本身包含一个 UI 管理器,分为了封面、加载界面、游戏界面三种,其中游戏界面里面还有一个游戏 UI 管理器,我们常用的就是最后一个游戏 UI 管理器。
|
样板提供 `UIController` 类,允许你在自己的一个 UI 中创建自己的 UI 管理器,例如在样板中,游戏画面本身包含一个 UI 管理器,分为了封面、加载界面、游戏界面三种,其中游戏界面里面还有一个游戏 UI 管理器,我们常用的就是最后一个游戏 UI 管理器。
|
||||||
|
|
||||||
多数情况下,样板自带的 UI 管理器已经足够,不需要自己创建 UI 管理器。我们最常用的管理器就是 `mainUIController`,它控制了游戏界面下的 UI。
|
多数情况下,样板自带的 UI 管理器已经足够,不需要自己创建 UI 管理器。我们最常用的管理器就是 `mainUIController`,它控制了游戏界面下的 UI。
|
||||||
|
|
||||||
|
这里为了教程的完整性,简单讲述一下如何创建一个自己的 UI 管理器。
|
||||||
|
|
||||||
### 创建 UIController 实例
|
### 创建 UIController 实例
|
||||||
|
|
||||||
我们从 `@motajs/system-ui` 引入 `UIController` 类,然后对其实例化:
|
我们从 `@motajs/system-ui` 引入 `UIController` 类,然后对其实例化:
|
||||||
|
@ -8,7 +8,7 @@ lang: zh-CN
|
|||||||
|
|
||||||
## 创建 UI 文件
|
## 创建 UI 文件
|
||||||
|
|
||||||
首先,我们打开 `packages-user/client-modules/render` 文件夹,这里是目前样板的 UI 目录(之后可能会修改),我们可以看到 `components` `legacy` `ui` 三个文件夹,其中 `component` 是组件文件夹,也就是所有 UI 都可能用到的组件,例如滚动条、分页、图标等,这些东西不会单独组成一个 UI,但是可以方便 UI 开发。`legacy` 文件夹是将要删除或重构的内容,不建议使用里面的内容。`ui` 就是 UI 文件夹,这里面存放了所有的 UI,我们在这里创建一个文件 `myUI.tsx`。
|
首先,我们打开 `packages-user/client-modules/render` 文件夹,这里是目前样板的 UI 目录(之后可能会修改),我们可以看到 `components` `ui` 等文件夹,其中 `component` 是组件文件夹,也就是所有 UI 都可能用到的组件,例如滚动条、分页、图标等,这些东西不会单独组成一个 UI,但是可以方便 UI 开发。`ui` 就是 UI 文件夹,这里面存放了所有的 UI,我们在此文件夹下创建一个文件 `myUI.tsx`。
|
||||||
|
|
||||||
## 编写 UI 模板
|
## 编写 UI 模板
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ export const MyBook = defineComponent<MyBookProps>(props => {
|
|||||||
}, myBookProps);
|
}, myBookProps);
|
||||||
```
|
```
|
||||||
|
|
||||||
除此之外,我们还可以在任意渲染端模块中引入 `ui/controller` 来获取到根组件的 UI 控制器,注意跨文件夹引入时需要引入 `@user/client-modules`。例如,我们可以在其他文件中控制这个 UI 的开启与关闭:
|
除此之外,我们还可以在任意渲染端模块中引入 `ui/controller` 来获取到根组件的 UI 控制器。例如,我们可以在其他文件中控制这个 UI 的开启与关闭:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { mainUIController, MyBookUI } from './ui';
|
import { mainUIController, MyBookUI } from './ui';
|
||||||
@ -132,7 +132,7 @@ const mainUIController = UIController.getController('main-ui');
|
|||||||
```tsx
|
```tsx
|
||||||
return () => (
|
return () => (
|
||||||
<container>
|
<container>
|
||||||
{/* 显示绿史莱姆图标,位置在 (32, 32),循环播放动画 */}
|
{/* 显示绿史莱姆图标,位置在 (32, 32),animate 表示循环播放动画 */}
|
||||||
<icon icon="greenSlime" loc={[32, 32]} animate />
|
<icon icon="greenSlime" loc={[32, 32]} animate />
|
||||||
</container>
|
</container>
|
||||||
);
|
);
|
||||||
|
@ -5,10 +5,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "tsx script/dev.ts",
|
"dev": "tsx script/dev.ts",
|
||||||
"build": "vue-tsc && vite build && tsx script/build.ts dist",
|
|
||||||
"build-local": "vue-tsc && vite build && tsx script/build.ts local",
|
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"update": "tsx script/update.ts",
|
|
||||||
"declare": "tsx script/declare.ts",
|
"declare": "tsx script/declare.ts",
|
||||||
"type": "vue-tsc --noEmit",
|
"type": "vue-tsc --noEmit",
|
||||||
"lines": "tsx script/lines.ts packages packages-user",
|
"lines": "tsx script/lines.ts packages packages-user",
|
||||||
|
Loading…
Reference in New Issue
Block a user