diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index aecb0c6..a16863d 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -72,8 +72,12 @@ export default defineConfig({ link: '/guide/implements/skill' }, { - text: '自定义按键', + text: '新增按键', link: '/guide/implements/hotkey' + }, + { + text: '动画效果', + link: '/guide/implements/animate' } ] } diff --git a/docs/guide/implements/animate.md b/docs/guide/implements/animate.md new file mode 100644 index 0000000..6935815 --- /dev/null +++ b/docs/guide/implements/animate.md @@ -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 () => ; +}); +``` + +注意 `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 () => ( + + {/* 将 value.ref.value 赋值给 alpha 属性 */} + + + ); +}); +``` + +## 执行动画 + +最后,在我们需要的时候执行动画即可,使用 `value.set`: + +```tsx +export const MyCom = defineComponent(() => { + // 定义动画属性 + const value = transitioned(1, 500, hyper('sin', 'out'))!; + + // 例如在 UI 挂载完毕后执行 + onMounted(() => { + // 动画属性调成 0,效果就是矩形逐渐从不透明变成完全透明 + value.set(0); + }); + + return () => ( + + + + ); +}); +``` + +## 拓展-颜色动画 + +除了一般数值的动画外,样板还支持颜色动画,使用 `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 () => ( + + {/* 将 fillStyle 赋值为 color.ref.value */} + + + ); +}); +``` + +颜色目前仅支持输入 `#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 () => ( + + + + ); +}); +``` + +### 点击切换状态 + +鼠标点击或触碰点击后高亮,再次点击恢复: + +```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 () => ( + + + + ); +}); +``` + +## 拓展-API 参考 + +参考[此 API 文档](../../api/user-client-modules/functions.md#transitioned)。 diff --git a/docs/guide/implements/hotkey.md b/docs/guide/implements/hotkey.md index c439e10..43b2bfc 100644 --- a/docs/guide/implements/hotkey.md +++ b/docs/guide/implements/hotkey.md @@ -1,4 +1,4 @@ -# 自定义按键 +# 新增按键 在 2.B 中新增按键很方便,且可以为你的 UI 单独配置按键信息,玩家也可以修改快捷键设置。 @@ -91,8 +91,8 @@ gameKey ```tsx {7-13} // 引入 useKey 接口 -// 文件在 packages-user/client-modules/src/render/utils/use.ts,注意路径关系 -import { useKey } from '../utils/use'; // [!code ++] +// 文件在 packages-user/client-modules/src/render/use.ts,注意路径关系 +import { useKey } from '../use'; // [!code ++] // UI 模板及如何编写 UI 参考 “新增 UI” 需求指南,这里只给出必要的修改部分,模板部分不再给出 export const MyCom = defineComponent(props => { @@ -113,7 +113,7 @@ export const MyCom = defineComponent(props => { 我们会有一些通用按键,例如确认、关闭,这些按键我们不希望每个 UI 或场景都定义一遍,一来写代码不方便,二来玩家如果要自定义的话需要每个界面都设置一遍,很麻烦。此时我们建议按键复用。与一般的按键一致,我们直接实现 `exit` `confirm` 等按键即可,不需额外操作: ```tsx {12-21} -import { useKey } from '../utils/use'; +import { useKey } from '../use'; // UI 模板及如何编写 UI 参考 “新增 UI” 需求指南,这里只给出必要的修改部分,模板部分不再给出 export const MyCom = defineComponent(props => { diff --git a/docs/guide/ui-elements.md b/docs/guide/ui-elements.md index 73b19a0..7ede13b 100644 --- a/docs/guide/ui-elements.md +++ b/docs/guide/ui-elements.md @@ -750,3 +750,7 @@ const themeStyle = { ``` + +## API 参考 + +参考[API 文档](../api/motajs-render-vue/index.md),这里有更细致的 API 介绍。 diff --git a/docs/guide/ui-system.md b/docs/guide/ui-system.md index e20b98a..05e63f1 100644 --- a/docs/guide/ui-system.md +++ b/docs/guide/ui-system.md @@ -2,12 +2,18 @@ 本节将会讲解 2.B 的渲染树与 UI 系统的工作原理,以及一些常用 API。 +:::info +**这部分可以选择性阅读,多数功能一般场景下用不到。** +::: + ## 创建一个自己的 UI 管理器 样板提供 `UIController` 类,允许你在自己的一个 UI 中创建自己的 UI 管理器,例如在样板中,游戏画面本身包含一个 UI 管理器,分为了封面、加载界面、游戏界面三种,其中游戏界面里面还有一个游戏 UI 管理器,我们常用的就是最后一个游戏 UI 管理器。 多数情况下,样板自带的 UI 管理器已经足够,不需要自己创建 UI 管理器。我们最常用的管理器就是 `mainUIController`,它控制了游戏界面下的 UI。 +这里为了教程的完整性,简单讲述一下如何创建一个自己的 UI 管理器。 + ### 创建 UIController 实例 我们从 `@motajs/system-ui` 引入 `UIController` 类,然后对其实例化: diff --git a/docs/guide/ui.md b/docs/guide/ui.md index 353d7f4..eba6198 100644 --- a/docs/guide/ui.md +++ b/docs/guide/ui.md @@ -8,7 +8,7 @@ lang: zh-CN ## 创建 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 模板 @@ -87,7 +87,7 @@ export const MyBook = defineComponent(props => { }, myBookProps); ``` -除此之外,我们还可以在任意渲染端模块中引入 `ui/controller` 来获取到根组件的 UI 控制器,注意跨文件夹引入时需要引入 `@user/client-modules`。例如,我们可以在其他文件中控制这个 UI 的开启与关闭: +除此之外,我们还可以在任意渲染端模块中引入 `ui/controller` 来获取到根组件的 UI 控制器。例如,我们可以在其他文件中控制这个 UI 的开启与关闭: ```ts import { mainUIController, MyBookUI } from './ui'; @@ -132,7 +132,7 @@ const mainUIController = UIController.getController('main-ui'); ```tsx return () => ( - {/* 显示绿史莱姆图标,位置在 (32, 32),循环播放动画 */} + {/* 显示绿史莱姆图标,位置在 (32, 32),animate 表示循环播放动画 */} ); diff --git a/package.json b/package.json index 658197e..9f3b386 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,7 @@ "type": "module", "scripts": { "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", - "update": "tsx script/update.ts", "declare": "tsx script/declare.ts", "type": "vue-tsc --noEmit", "lines": "tsx script/lines.ts packages packages-user",