快来体验 Spring!React Spring 完整指南。🧵
嘿,你是那个热衷于探索胡克定律新可能性的人吗?还记得下面这张告诉我们弹性如何运作的图片吗?
好吧,我不是物理学教授,无法向您介绍弹簧和钩子的工作原理,但我可以向您展示如何通过一个非常流行的库React Spring在基于 React 的应用程序上实现相同级别的灵活性。😍
React Spring 是什么?🤔
React Spring 是一个基于弹簧物理的动画库,它通过提供给我们的不同插值和过渡提供了制作简单而强大的动画和交互所需的所有工具。
所以是的,您可以获得您想要的组件或元素的所有缓和和平滑度。
了解春天🧐
在开始编码之前,我们先花点时间了解一下物理学(我超爱这门学科🥺)。“spring”这个术语与这个库密切相关。
就像我们对连接到某个点“A”的弹簧施加以下不同的力一样:
- 重力。
- 重力加速度。
- 弹簧力。
此外,我们以同样的方式将React Spring 库中的spring描述为:
没有明确的曲线或设定的持续时间。
因此,所有动画都是基于时间和曲线完成的。这就是 React Spring 发挥作用的地方。通常,我们会@keyframes
在 CSS 中使用常规动画,这些动画基本上是基于时间的动画。在这里,由于采用了自然风格的缓动效果,动画看起来更加自然。
我们会做什么?😏
首先,我们将进行这个基本的转变来了解事情是如何运作的:
让我们开始吧!😎
步骤1:安装
创建新的 React 项目后,打开终端窗口并运行以下命令:
npm install react-spring
这应该安装与库相关的所有必要文件。
步骤 2:切换组件
在项目的src/文件夹下创建一个名为Toggle.jsx的新文件。
从常见的东西开始,比如导出组件并返回一个div
有两个子项的容器;首先是<h1>
标题“Hello”,接下来是<button>
“Toggle”。
这里没什么特别的。所以,只需添加“特别”即可。我们将使用useState
Hook 来处理切换开关的状态。首先导入它并赋予它state 变量。由于我们不希望切换开关状态一开始就显示出来,因此isToggled
需要设置状态的初始值。false
const [isToggled, setIsToggled] = useState(false);
接下来,要开始使用 React Spring,我们需要导入useSpring
钩子。这会将元素的正常值转换为动画值。
我们将动画命名为淡入淡出,并在useSpring
钩子对象内部定义所需的所有动画。如您在上面的演示中所见,单击切换按钮时,文本会发生变化:
- 其颜色从黑色变为绿色。
- 其字体大小从小到大。
- 它的位置。
正如您在文档中看到的,该useSpring
钩子像普通的 CSS 代码一样接受各种属性。但是这里我们也有一个 React Hook,因此我们将color
、transform
和fontSize
属性(注意与 CSS 相比语法上的变化!)与变量一起传递isToggled
。
因此,如果切换按钮的状态没有改变,那么color
将会是,#000
否则当它改变时(按下按钮时),我们将其设置为green
。
对于我们想要动画的另外两个属性也是如此:
const fade = useSpring({
color: isToggled ? '#000' : 'green',
transform: isToggled
? 'translate3d(0, 15px, 0)'
: 'translate3d(0, 15px, 0)',
fontSize: isToggled ? '2rem' : '3rem',
});
好的,但是现在我们还没有编写<button>
功能!让我们来编写它。我们添加一个onClick
事件,该事件传入setIsToggled
Hook 函数,该函数的作用是简单地更改isToggled
变量的布尔值。
<button onClick={() => setIsToggled(!isToggled)}>Toggle</button>
最后,我们使用animated
库提供的 prop(确保导入它)。我们将此 prop 添加到我们想要动画的元素中。这里,当点击“Toggle”按钮时,我们希望标题动画,因此我们将标签从<h1>
改为<animated.h1>
。
步骤 3:添加切换组件
最后,只需返回App.js文件并返回新创建的组件即可。您还可以根据需要添加一些样式。
function App() {
return <Toggle />
}
完成后,您就可以使用新创建的弹簧动画了!注意,您不必关心缓动效果 :)
更进一步🚀
我们继续前进并实现这个目标怎么样?
看起来很刺激吧?不过其实有点复杂,我们需要做以下事情:
我们将在App.js内部编写代码。首先导入库。
import { useSpring, animated } from 'react-spring';
在该return()
方法中,我们有一个单独的<animated.div />
方法,它接收两个React 的鼠标合成事件:onMouseMove
和,onMouseLeave
用于我们需要执行的操作。它们接收当前视口/容器内的x
和坐标。y
return (
<animated.div
onMouseMove={({ clientX: x, clientY: y }) => set({ xys: calcXY(x, y) })}
onMouseLeave={() => set({ xys: [0, 0, 1] })}
style={{ transform: props.xys.interpolate(perspective) }}
/>
);
这里我们传入clientX
和clientY
来让函数进行计算calcXY()
。
这calcXY
是一个简单的函数,它接受x
和y
作为参数,并使用 DOM 的Window
接口来获取相应的width
和height
。
const calcXY = (x, y) => [
-(y - window.innerHeight / 2) / 15,
(x - window.innerWidth / 2) / 15,
1.0,
];
为了根据需要设置的值xys
,我们创建一个新的全局常量并使用perspective()
、rotateX()
和属性rotateY()
。scale()
const perspective = (x, y, s) =>
`perspective(500px)
rotateX(${x}deg)
rotateY(${y}deg)
scale(${s})`;
注意,我们使用JavaScript 的模板字面量来动态更改相应的值。但仅仅声明新的perspective
常量是行不通的。我们需要在标签style
的属性中使用它<animated.div />
,如下所示:
style={{ transform: props.xys.interpolate(perspective) }}
我们将传递到函数perspective
内部interpolate()
。根据文档:
插值函数可以接受一个函数或一个构成范围的对象作为参数。
插值还可以形成链式运算,这样你就可以将一个计算路由到另一个计算中,或者重复使用它们。
现在又到了讲物理知识的时候了(再次!)。在 中,useSpring()
我们首先传入默认xys
值(简单地转换为三维中的 X、Y 和 Z 坐标),然后使用属性,我们可以手动定义元素可以包含config
多少mass
、tension
和!friction
是不是非常激动人心?这一切都归功于 React Spring 的Common API。你可以在他们的网站上查看所有示例以及一个交互式演示。
至于样式,可以使用 CSS 轻松实现:
.card {
width: 30rem;
height: 30rem;
border-radius: 15px;
background-image: url(https://images.pexels.com/photos/4870974/pexels-photo-4870974.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260);
background-size: cover;
background-position: center center;
box-shadow: 0px 10px 30px -5px rgba(0, 0, 0, 0.3);
transition: box-shadow 0.5s;
}
.card:hover {
box-shadow: 0px 30px 100px -10px rgba(0, 0, 0, 0.4);
}
以下是我们的整个 Spring 代码:
const calcXY = (x, y) => [
-(y - window.innerHeight / 2) / 15,
(x - window.innerWidth / 2) / 15,
1.0,
];
const perspective = (x, y, s) =>
`perspective(500px) rotateX(${x}deg) rotateY(${y}deg) scale(${s})`;
function App() {
const [props, set] = useSpring(() => ({
xys: [0, 0, 0.5],
config: { mass: 5, tension: 200, friction: 100 },
}));
return (
<animated.div
className='card'
onMouseMove={({ clientX: x, clientY: y }) => set({ xys: calcXY(x, y) })}
onMouseLeave={() => set({ xys: [0, 0, 1] })}
style={{ transform: props.xys.interpolate(perspective) }}
/>
);
}
希望以上内容能帮助你理解如何在 React Spring 中为组件添加动画,这个库还有很多其他的可能性。点击此处查看所有示例。
谢谢阅读,我非常感激!祝你拥有美好的一天。(✿◕‿◕✿)
你的 IDE 可能处于黑暗模式,但你的 Windows 操作系统和相关应用也适合深夜使用吗?👀 了解更多信息:https://t.co/ww6fY8HUju
— 英国微软开发者 (@msdevUK) 2020 年 9 月 28 日
图片来源:https://t.co/cB3ntpgxIq #DevHumour #DarkMode #Developer pic.twitter.com/Xz4Y4FAlI6