paint-brush
我使用 Tailwind 和 CSS 创建了一个用于动画的 React 实用组件:AnimateIn经过@johnpolacek
1,769 讀數
1,769 讀數

我使用 Tailwind 和 CSS 创建了一个用于动画的 React 实用组件:AnimateIn

经过 John Polacek5m2024/01/17
Read on Terminal Reader
Read this story w/o Javascript

太長; 讀書

<AnimateIn/> 是一个可重用的 React 组件,每当我想快速向我的项目添加一些动画效果时,我都会插入它。一个简单的实用组件,它将 CSS 动画与 Tailwind 类相结合,以最少的努力创建流畅、引人注目的动画。
featured image - 我使用 Tailwind 和 CSS 创建了一个用于动画的 React 实用组件:AnimateIn
John Polacek HackerNoon profile picture


<AnimateIn/> 演示页面动画


一段时间以来,我一直在我的项目中使用相同的动画模式来将元素动画显示到屏幕上。在最简单的形式中,您将拥有一个不透明度为零的元素,然后将样式更改为不透明度为 1,CSS 过渡为一秒。


我们可以在此基础上添加其他过渡属性、更改持续时间、添加延迟或设置自定义缓动。


<AnimateIn/>是一个可重用的 React 组件,每当我想快速向我的项目添加一些动画效果时,我都会插入它。一个简单的实用组件,它将 CSS 动画与 Tailwind 类相结合,以最少的努力创建流畅、引人注目的动画。


我们来看看它是如何使用的。导入组件后,使用 Tailwind 类定义fromto状态。将目标元素包裹在<AnimateIn/>中以查看动画的效果。


 import AnimateIn from '../animation/AnimateIn'; <AnimateIn from="opacity-0 scale-90" to="opacity-100 scale-100" duration={500} > <YourComponent /> </AnimateIn>


这是一个稍微复杂的示例,它使用更多属性在标题和副标题中设置动画。

 import AnimateIn from '../animation/AnimateIn'; <header> <AnimateIn as="h1" from="opacity-0 translate-y-32" to="opacity-100 translate-y-0" delay={500} duration={300} className="text-4xl" style={{transitionTimingFunction:"cubic-bezier(0.25, 0.4, 0.55, 1.4)"}} > My Big Headline </AnimateIn> <AnimateIn as="h2" from="opacity-0 scale-0" to="opacity-100 scale-100" delay={800} duration={500} className="text-lg" > This is a subtitle below the headline </AnimateIn> </header>


在标题示例中, <AnimateIn/>用于创建与淡入相结合的滑动效果。以下是每个属性对动画的贡献:


  • as属性:通过设置as="h1" ,我们告诉 AnimateIn 将动画渲染为<h1>元素。


  • fromto属性: from属性使标题在屏幕外开始( translate-y-32 ,向下移动 32 个单位)并且不可见( opacity-0 )。然后, to属性将标题带到最终位置(返回到translate-y-0 )并使其完全可见( opacity-100 )。


  • duration属性:动画设置为立即开始,没有延迟,并快速运行 300 毫秒。


  • className属性: className="text-4xl"应用 Tailwind 的实用程序类来设置字体大小,使标题更加突出。


  • style属性:自定义的transitionTimingFunctioncubic-bezier(0.25, 0.4, 0.55, 1.4) )为动画添加了独特的缓和效果,赋予其类似弹跳的效果。


副标题使用一组不同的动画来补充标题,创建一个有凝聚力的视觉流。

  • as属性:这里, as="h2"将组件呈现为<h2>元素,适合字幕。


  • fromto属性:字幕开始缩小到零 ( scale-0 ) 和不可见 ( opacity-0 ),然后放大到其自然大小 ( scale-100 ) 并变得完全可见 ( opacity-100 )。这种缩放效果与淡入相结合,增加了动画的深度。


  • delayduration属性:字幕也会在 800 毫秒延迟后开始,以便在标题完全动画化后开始。这种交错的方法确保每个元素都获得焦点。


  • className属性: className="text-lg"设置副标题的字体大小,使其小于标题,但仍然很重要。


为了更好地理解发生了什么,让我们看看Github 上<AnimateIn/>的源代码:


<AnimateIn/>使用useState钩子通过from属性初始化动画状态,该属性应该是一个或多个 Tailwind 实用程序类,在任何动画发生之前为动画的起点设置舞台。


组件中的第一个useEffect挂钩用于尊重用户对减少运动的偏好。通过监听(prefers-reduced-motion: reduce)媒体查询,动画行为基于用户的系统设置。如果首选减少运动,则完全跳过动画,直接将动画状态设置为to属性,从而实现无障碍体验。


第二个useEffect挂钩是动画逻辑所在的位置。如果用户没有指示减少运动的偏好,则该组件会设置一个计时器,在指定的延迟后将动画状态从初始from值更改为最终to值。这种过渡创建了动画的视觉效果。


该钩子的清理函数(返回语句)会清除计时器,防止潜在的内存泄漏,例如组件在动画完成之前卸载。


React.createElement函数调用是组件的渲染机制。它基于as属性动态创建 HTML 元素,允许跨不同的 HTML 元素使用该组件。 className是使用shadcn 普及的cn函数构造的,它结合了 Tailwind 的实用程序类、作为 prop 传递的自定义className以及当前的动画状态。这种动态类分配将所需的样式和转换应用于元素。


此外,还有一个style属性可以传入以直接在动画容器上设置样式属性。 transitionDuration是根据duration属性设置的,但如果用户喜欢减少运动,它会智能地切换到0ms ,从而有效地禁用动画,同时保持组件的功能。


如果您想在自己的项目中使用<AnimateIn/>并且它已经使用shadcn ,那么您已经拥有所需的一切,只需下载 AnimateIn.tsx并将其添加到您的组件中即可。


否则,您需要安装 Tailwind以及mxcn (用于合并 tailwind 类的有用实用程序)


与 shadcn 一样,<AnimateIn/> 是一个可重用的组件,您可以将其复制并粘贴到应用程序中并根据您的需求进行自定义。代码是你的。


另外,我还整理了一个很好的演示页面,用于在animate-in.vercel.app上使用<AnimateIn/>创建不同的动画。


也发布在这里