塞尔达传说 BOTW 入门版
完整演示
https://www.gameuionweb.com/zelda-botw
文章链接:
堆
- 反应
- 顺风
- Framer-motion(测试版)
Tailwind 的有用链接:
在本系列文章中,我们将学习如何在网络上复制《塞尔达传说:荒野之息》的菜单库存界面!
这将是一系列 3 篇文章:
中级前端开发人员。
如果你经验更丰富,可能学不到太多东西(至少对于第一部分来说),但这仍然是一个有趣的练习。
我发现 GameUI 非常鼓舞人心,它们与 Web 界面存在一些共同的问题,也存在一些类似的问题。GameUI 的设计通常不会妨碍玩家的游戏体验(《塞尔达传说:终极版》就是一个很好的例子)。Web 在这方面也没什么不同。我们设计网站实际上是在构建一种体验,界面只是与这种体验互动的方式。
此外,GameUI 通常充满了许多小细节,这些细节并非总是应该一眼就能注意到,但它们却是构成一个令人愉悦的界面的重要组成部分。
该界面基本上是两列布局。
界面上有很多动画,它们都有各自的用途:
前 3 个动画最为明显,起到了指示作用(这是一个 UX 术语,来自《日常设计》的作者唐纳德·诺曼),可以帮助玩家了解他可以在界面上执行的操作。
起初我只想提供一些带有解释的代码示例,但我认为这没什么价值。
你可能已经意识到,作为开发者,我们通过积极实践才能学得更好。这就是为什么本系列会积极鼓励你编写你自己版本的 Zelda BOTW 界面。
我会在每个步骤中设定一个目标,并提供实现目标的线索。
如果你遇到困难或者只是想继续阅读,每个步骤的解决方案都会在单独的要点中提供。
我已经建立了一个包含所有资源的基础存储库,以便你立即开始:
https://www.gameuionweb.com/zelda-botw
Tailwind 的有用链接:
该存储库是用 Typescript 设置的,但这里没有义务,您可以根据需要使用 ts 或 js。
本系列文章基于以下技术栈:
如果你已经熟悉 Tailwind,可以跳过此部分
w-full
Tailwind 是一个 CSS 实用框架,它提供了一组类似forwidth: 100%
或flex
for 的低责任的 css 类display: flex
。
这些类是基于 JS 配置文件生成的。在这个文件中,你可以定义一些设计标记,例如颜色、间距等等,然后 Tailwind 会根据你定义的设计约束生成所有 CSS 类。
您可以在此处找到此文件的结构:默认配置
我选择 Tailwind 作为本系列文章的框架,因为它允许我提前准备好设计配置,以便您专注于最有趣的部分。
此外,我还可以将所需的 Tailwind 类直接添加到文章提供的架构中,从而简化实现过程。
如果这是您第一次使用 Tailwind,您可以使用此备忘单来帮助您在开始时找到课程:https
://nerdcave.com/tailwind-cheat-sheet 我还强烈建议安装一个插件来实现 Tailwind 课程的自动完成功能(请参阅入门自述文件中的链接)。
我们将从创建界面的基础布局开始。
我们想要的是一个响应式布局,并遵循以下约束:
一旦你的布局完成,你可以将bg-zelda-darkGreen
类添加到你的主 div 中,这对该部分很有帮助。
资源:
解决方案:
https://gist.github.com/flagrede/e440ac5c56f21ef9b9db37d1c780ad20
我们现在将创建ItemsGrid和Item组件。
我们希望创建一个 5 列的网格,使用 css-grid 实现,在移动设备上缩减为 3 列,并在每个单元格中显示一个 Item 组件。
要创建 Item 组件,我们需要查看 中可用的数据src/data/items.js
。Item 数据如下所示:
{
name: "Tree Branch",
category: "weapon",
icon: "/zelda-botw/items/weapons/BotW_Tree_Branch_Icon.png",
value: "2",
isNew: true,
description:
"Wooden branches such as this are pretty common, but it's surprisingly well-balanced. It doesn't do much damage but can serve as a weapon in a pinch.",
}
现在,我们的组件只需显示其图标、值以及图像标题的名称。
我们的项目应该如下所示:
数据集中的项目主要分为weapons
、shields
和三个类别armors
。目前我们只需要显示一个类别,因此我们可以先以weapons
项目为例。我们可以创建一个getItems
函数来检索该类别,并用一个空的项目对象填充数组的其余部分,以达到所需的单元格数量。
资源:
解决方案:
项目:https://gist.github.com/flagrede/dc21859cc3020454cd1dc3c6f5afabdb
物品网格:https://gist.github.com/flagrede/f752e3e2de8cbb6a7edf1609dc42f9b7
getItems:https://gist.github.com/flagrede/4471044563611d572707c96546d64635
现在,我们希望能够通过应用以下类来单击来选择一个项目。
此时我们的应用程序结构应如下所示:
<App>
<ItemsGrid>
<Item>
我们需要: - 使用组件
存储所选项目的索引位置 - 创建一个上下文来存储位置和前一个-使用钩子 检索组件内的上下文值。 - 使用实用程序和上下文中的值 从上面激活选定的类。React.useSate
App
React.createContext
selectedItem
setSelectedItem
useState
Item
useContext
classnames
资源:
解决方案:
https://gist.github.com/flagrede/d0627032cb459166dd454110337a1ab1
在这一部分中,我们需要将元素的索引位置转换为 5x4 矩阵位置,然后再转换为另一个矩阵位置来还原它。
网格位置应该如下所示:
因此,我们需要一个转换为的方法,例如6
,另一个转换为{x:1 ,y:1}
的方法, 第一个方法签名应该是:{x:1 ,y:1}
6
(index: number) => {x:number, y:number}
第二种方法签名应该是:
({x:number, y:number}) => number
然后,我们将需要四种方法来根据方向计算新的位置,goUp, goRight, goLeft, goBottom
我强烈建议对这些方法进行测试,但这里没有义务。
测试示例:
it("should convert 6 to x:1, y:1 position", () => {
// Given
const index = 6;
// When
const result = convertIndexToPosition(index);
// Then
expect(result).toEqual({ x: 1, y: 1 });
});
最后,组件handleKeyPressed
内部有一个函数App
来处理根据按下的键执行的行为。
注意:键盘导航预计仅适用于 5 列网格(因为移动布局有 3 列)。
资源:
解决方案:
为了结束第一部分,我们将使用 framer-motion 添加一些动画。
现在,我们将在所选项目的边缘添加三角形并为其添加动画。
这些三角形将使用 CSS 完成。创建三角形的 CSS 类已经可用,您可以访问zelda-botw-triangle-up
和zelda-botw-triangle-bottom
。
我们需要创建两个组件:
Triangle
具有以下属性的组件:
type Props {
animateParams: {
rotate: string,
x: [number, number, number],
y: [number, number, number]
},
className: string
}
rotate
应该是这样的"-10deg"
x
应该类似于[8, 2, 4]
,它将通过数组中提供的值来使三角形在 x 轴上移动。这里给出的值是随机的,我让你自己找到正确的值。y
相同,x
但用于y
轴className
将用于应用 CSS 类列表一个TrianglesBox
没有 props 但显示 4 个Triangle
组件的组件。
absolute
在它们上面应用一个位置,并relative
在父级上应用一个位置Item
。要为triangle
组件添加动画效果,我们必须使用motion
framer-motion 的 API。import { motion } from "framer-motion";
const DummyComponent ({ animateParams }) => (
<motion.div
animate={animateParams}
/>
);
我们还需要应用过渡参数来motion.div
获得所需的效果。
资源:
解决方案:
https://gist.github.com/flagrede/8143023838936fb4b7cf81eae1c52d54
https://gist.github.com/flagrede/9587f518c4cf7f8ca991c63a8144b75b
恭喜您完成第一部分,希望您喜欢!
在第二部分中,我们将实现项目类别之间的分页、页面过渡动画以及显示有关项目的附加数据。如果您遇到任何问题或有任何反馈,请在这里或在Twitter
上告诉我,我会很乐意尽力解决!
笔记
所有图谱均使用 Excalidraw 绘制。感谢团队免费提供如此优秀的工具。
文章来源:https://dev.to/flagrede/how-to-replicate-the-zelda-botw-interface-with-react-tailwind-and-framer-motion-part-1-298g