Vue 中的可组合 CSS 动画与 AnimXYZ

已发表: 2022-03-10
快速总结↬大多数动画库,如 GSAP 和 Framer Motion 都是纯粹使用 JavaScript 或 TypeScript 构建的,不像 AnimXYZ,它被标记为“第一个可组合的 CSS 动画工具包”,主要使用 SCSS 构建。 虽然是一个简单的库,但它可以用来在很短的时间和很少的代码中实现很多很棒的网络动画。

在本文中,您将学习如何使用 AnimXYZ 工具包在 Vue.js 和纯 HTML 中创建独特的、交互式的、视觉上引人入胜的动画。 在本文结束时,您将了解如何向 Vue.js 组件中的元素添加一些 CSS 类可以让您对这些元素在 DOM 中的移动方式进行大量控制。

本教程将对有兴趣使用几行代码创建交互式动画的读者有所帮助。

注意本文需要对 Vue.js 和 CSS 有基本的了解。

什么是动画XYZ?

AnimXYZ 是一个由 CSS 变量驱动的可组合、高性能和可定制的 CSS 动画工具包。 它旨在使您无需编写一行 CSS 关键帧即可创建出色且独特的动画。 在底层,它使用 CSS 变量来创建自定义 CSS 属性。 AnymXYZ 的优点在于它的声明性方法。 元素可以通过以下两种方式之一进行动画处理:进入或离开页面时。 如果您想使用此工具包为 HTML 元素设置动画,添加一个xyz-out类会将项目动画移出页面,而xyz-in将动画组件放入页面。

这个很棒的工具包可以用在常规的 HTML 项目中,也可以用在 Vue.js 或 React 应用程序中。 但是,截至撰写本文时,对 React 的支持仍在开发中。

跳跃后更多! 继续往下看↓

为什么使用 AnimXYZ?

可组合的

通过在标记中添加描述性的类名称,可以使用 AnimXYZ 制作动画。 这使得编写复杂的 CSS 动画变得容易,而无需编写复杂的 CSS 关键帧。 将元素动画化到页面中就像在组件中添加一个xyz-in类并声明一个描述性属性一样简单。

 <p class="xyz-in" xyz="fade">Composable CSS animation with AnimXYZ</p>

上面的代码将使段落元素淡入页面,而下面的代码将使元素淡出页面。 只是一个强大的类。

 <p class="intro xyz-out" xyz="fade">Composable CSS animation with AnimXYZ</p>

可定制

对于简单的动画,您可以使用开箱即用的实用程序,但 AnimXYZ 可以做的更多。 通过设置驱动所有 AnimXYZ 动画的 CSS 变量,您可以自定义和控制 AnimXYZ 以准确创建您想要的动画。 我们将在本教程后面创建一些自定义动画。

高性能

使用 AnimXYZ,您可以开箱即用地创建强大而流畅的动画,其基本功能的大小仅为 2.68 KB,如果包含方便的实用程序,则为 11.4 KB。

易于学习和使用

AnimXYZ 与常规 HTML 和 CSS 完美配合,并且可以使用内容交付网络 (CDN) 链接集成到项目中。 它也可以在 Vue.js 和 React 中使用,尽管对 React 的支持仍在开发中。 此外,与 GSAP 和 Framer Motion 等动画库相比,使用此工具包的学习曲线并不陡峭,而且官方文档很容易上手,因为它简单地解释了包的工作原理。

AnimXYZ 中的关键概念

上下文

当您希望将特定的动画流应用于相关的元素组时, xyz属性提供了上下文。 假设您希望三个div在进入页面时以相同的方式进行动画处理。 您所要做的就是将xyz属性添加到父元素,以及您想要应用的可组合实用程序和变量。

 <div class="shape-wrapper xyz-in" xyz="fade flip-up flip-left"> <div class="shape"></div> <div class="shape"></div> <div class="shape"></div> </div>

上面的代码将对所有具有shape类的div应用相同的动画。 所有子元素都将淡入页面并翻转到左上角,因为属性xyz="fade flip-up flip-left"已应用于父元素。

请参阅 Ejiro Asiuwhu 的钢笔 [AnimXYZ 中的上下文](https://codepen.io/smashingmag/pen/abyoqdY)。

请参阅 Ejiro Asiuwhu 的 AnimXYZ 中的钢笔上下文。

AnimXYZ 可以轻松地为子元素设置与其父元素不同的动画。 为此,将具有不同动画变量和不同实用程序的xyz属性添加到子元素,这将重置它从其父元素继承的所有动画属性。

请参阅 Ejiro Asiuwhu 的 Pen [Override Parent contexts in AnimXYZ](https://codepen.io/smashingmag/pen/porzayR)。

请参阅 Ejiro Asiuwhu 在 AnimXYZ 中的 Pen Override Parent 上下文。

实用程序

AnimXYZ 带有许多实用程序,可以让您创建引人入胜且功能强大的 CSS 动画,而无需编写任何自定义 CSS。

 xyz="fade up in-left in-rotate-left out-right out-rotate-right"

例如,上面的代码有一个fade up实用程序,它会使元素在进入页面时从上到下淡出。 它会从左边进来并旋转。 当元素离开页面时,它将向右旋转并旋转出页面。

使用开箱即用的实用程序,您可以将一组元素向右翻转,并在离开页面时使它们淡出。 使用这些实用程序可以实现的可能性是无穷无尽的。

惊人的

stagger实用程序控制列表中每个元素的animation-delay CSS 属性,以便它们的动画一个接一个地触发。 它指定在将动画应用于元素和开始执行动画之间等待的时间量。 本质上,它是用来排队动画,以便元素可以按顺序进行动画处理。

 <div class="shape-wrapper" xyz="fade up-100% origin-top flip-down flip-right-50% rotate-left-100% stagger"> <div class="shape xyz-in"></div> <div class="shape xyz-in"></div> <div class="shape xyz-in"></div> <div class="shape xyz-in"></div> </div>

通过添加stagger实用程序,父div中的每个元素将从左到右依次设置动画。 可以使用stagger-rev来尊重订单。

stagger

请参阅 Ejiro Asiuwhu 的 Pen [Staggering with AnimXYZ](https://codepen.io/smashingmag/pen/abyoqNG)。

请参阅 Ejiro Asiuwhu 的 AnimXYZ 的 Pen Staggering。

没有stagger

请参阅 Ejiro Asiuwhu 的钢笔 [!Staggering Animation - AnimXYZ](https://codepen.io/smashingmag/pen/BadBYzN)。

看钢笔!惊人的动画 - Ejiro Asiuwhu 的 AnimXYZ。

在 HTML 和 CSS 中使用 AnimXYZ

让我们用 AnimeXYZ 制作一张卡片并添加一些很酷的动画。

请参阅 Ejiro Asiuwhu 的 Pen [Animxyz 演示](https://codepen.io/smashingmag/pen/jOLNZrV)。

请参阅 Ejiro Asiuwhu 的 Pen Animxyz 演示。

首先,我们需要将 AnimXYZ 工具包添加到我们的项目中。 最简单的方法是通过 CDN。 获取 CDN,并将其添加到 HTML 文档的head

将以下代码行添加到您的 HTML 中。

 <p class="intro xyz-in" xyz="fade">Composable CSS Animation with Animxyz</p> <div class="glass xyz-in" xyz="fade flip-down flip-right-50% duration-10"> <img src="https://cdn.dribbble.com/users/238864/screenshots/15043450/media/7160a9f4acc18f4ec2cbe38eb167de62.jpg" alt="" class="avatar xyz-in"> <p class="des xyz-in">Image by Jordon Cheung</p> </div>

这就是魔法发生的地方。 在页面的顶部,我们有一个带有xyz-in类的段落标签和一个带有fade值的xyz属性。 这意味着p元素将淡入页面。

接下来,我们有一张idglass的卡片,具有以下xyz属性:

 xyz="fade flip-down flip-right-50% duration-10"

上面的可组合实用程序将使卡片淡入页面。 flip-down值将设置卡片从底部翻入页面, flip-right值将卡片在离开页面时翻转 50%。 动画持续时间为10 (即 1 秒)设置动画完成一个周期所需的时间长度。

在 Vue.js 中集成 AnimXYZ

搭建一个 Vue.js 项目

使用 Vue.js 命令行界面 (CLI),运行以下命令以生成应用程序:

 vue create animxyz-vue

安装 VueAnimXYZ

 npm install @animxyz/vue

这将安装核心包和 Vue.js 包。 安装后,我们必须将VueAnimXYZ包导入到我们的项目中,并将插件全局添加到我们的 Vue.js 应用程序中。 为此,请打开您的main.js文件,并相应地添加以下代码块:

 import VueAnimXYZ from '@animxyz/vue' // import AnimXZY vue package import '@animxyz/core' // import AnimXZY core package Vue.use(VueAnimXYZ)

XyzTransition组件

XyzTransition组件构建在 Vue.js 的transition组件之上。 它用于将单个元素动画化进出页面。

这是一个演示如何在 Vue.js 中使用XyzTransition组件。

请注意,Vue.js 的transition组件带来的许多复杂性已被抽象出来,以降低复杂性并提高效率。 在使用XyzTransition组件时,我们需要关心的只是appearappear-visibledurationmode道具。

如需更详细的指南,请查看官方文档。

让我们使用XYZTransition组件在单击按钮时为元素设置动画。

 <div> <button @click="isAnimate = !isAnimate">Animate</button> <XyzTransition appear xyz="fade up in-left in-rotate-left out-right out-rotate-right" > <div class="square" v-if="isAnimate"></div> </XyzTransition> </div>

注意我们打算转换的元素是如何包装在XYZTransition组件中的。 这很重要,因为子元素<div class="square" v-if="isAnimate"></div>将继承应用于XYZTransition组件的实用程序。 当isAnimate设置为true时,子元素也会有条件地呈现。 单击按钮时,具有square类的子元素将切换进出 DOM。

XyzTransitionGroup

XyzTransitionGroup组件构建在 Vue.js 的transition-group组件之上。 它用于动画元素组进出页面。

下图展示了如何在 Vue.js 中使用XyzTransitionGroup组件。 再次注意,Vue.js 的transition-group组件带来的许多复杂性已被抽象出来,以降低复杂性并提高效率。 在使用XyzTransitionGroup组件时,我们需要关心的只是appearappear-visibledurationtag 。 以下内容来自文档:

 <XyzTransitionGroup appear={ boolean } appear-visible={ boolean | IntersectionObserverOptions } duration={ number | 'auto' | { appear: number | 'auto', in: number | 'auto', out: number | 'auto' } } tag={ string } > <child-component /> <child-component /> <child-component /> </XyzTransitionGroup>

使用 AnimXYZ 和 Vue.js 构建动画模式

让我们构建模态组件,在它们进入和离开 DOM 时进行动画处理。

这是我们将要构建的演示:

演示
演示

通过将xyz="fade out-delay-5"属性添加到XyzTransition组件,模态将淡出。

请注意,我们将.xyz-nested添加到模态组件的几乎所有子元素中。 这是因为我们想在模态组件的元素打开时触发它们的动画。

我们添加到对话框容器中的ease-out-back属性将在对话框打开和关闭时添加轻微的过冲。

给modal组件的子元素添加in-delay会让动画感觉更自然,因为元素会一直延迟到modal的其他内容都动画进来了:

 <section class="xyz-animate"> <div class="alerts__wrap copy-content"> <div class="alert reduced-motion-alert"> <p> AnimXYZ animations are disabled if your browser or OS has reduced-motion setting turned on. <a href="https://web.dev/prefers-reduced-motion/" target="_blank"> Learn more here. </a> </p> </div> </div> <h1>Modal Animation With AnimXYZ and Vue.js</h1> <button class="modal-toggle modal-btn-main" data-modal-text="Open Modal" data-modal-title="Title" data-modal-close-text="Close" aria-haspopup="dialog" ref="openButton" @click="open" autofocus > Open Modal </button> <span class="simple-modal-overlay" data-background-click="enabled" title="Close this window" v-if="isModal" @click="close" > <span class="invisible">Close this window</span> </span> <div role="dialog" class="simple-modal__wrapper" aria-labelledby="modal-title" > <XyzTransition duration="auto" xyz="fade out-delay-5"> <section aria-labelledby="modal1_label" aria-modal="true" class="modal xyz-nested" xyz="fade small stagger ease-out-back" v-if="isModal" tabindex="-1" ref="modal" @keydown.esc="close" > <div class="modal_top flex xyz-nested" xyz="up-100% in-delay-3"> <header class="modal_label xyz-nested" xyz="fade right in-delay-7" > Join our community on Slack </header> <button type="button" aria-label="Close" xyz="fade small in-delay-7" class="xyz-nested" @click="close" title="Close" > <svg viewBox="0 0 24 24" focusable="false" aria-hidden="true"> <path fill="currentColor" d="M.439,21.44a1.5,1.5,0,0,0,2.122,2.121L11.823,14.3a.25.25,0,0,1,.354,0l9.262,9.263a1.5,1.5,0,1,0,2.122-2.121L14.3,12.177a.25.25,0,0,1,0-.354l9.263-9.262A1.5,1.5,0,0,0,21.439.44L12.177,9.7a.25.25,0,0,1-.354,0L2.561.44A1.5,1.5,0,0,0,.439,2.561L9.7,11.823a.25.25,0,0,1,0,.354Z" ></path> </svg> </button> </div> <div class="modal_body xyz-nested" xyz="up-100% in-delay-3"> <div class="modal_body--top flex justify_center align_center"> <img src="../assets/slack.png" alt="slack logo" class="slack_logo" /> <img src="../assets/plus.png" alt="plus" class="plus" /> <img src="../assets/discord.png" alt="discord logo" class="discord_logo" /> </div> <p><span class="bold">929</span> users are registered so far.</p> </div> <form class="modal_form" autocomplete> <label for="email" ><span class="sr-only">Enter your email</span></label > <input type="email" placeholder="[email protected]" autocomplete="email" class="modal_input" required /> <button type="submit" class="modal_invite_btn"> Get my invite </button> <p>Already joined?</p> <button type="button" class=" modal_slack_btn flex align_center justify_center xyz-nested " xyz="fade in-right in-delay-7" > <span ><img src="../assets/slack.png" alt="slack logo" role="icon" /></span> Open Slack </button> </form> </section> </XyzTransition> </div> </section>

然后,在我们的模态中,我们将使用v-if="isModal"指令来指定我们希望模态在默认情况下从页面中隐藏。 然后,当单击按钮时,我们通过调用open()方法打开模式,该方法将isModal属性设置为true 。 这将显示页面上的模式,并应用我们使用 AnimXYZ 的内置实用程序指定的动画属性。

 <script> export default { data() { return { isModal: false, }; }, methods: { open() { if (!this.isModal) { this.isModal = true; this.$nextTick(() => { const modalRef = this.$refs.modal; console.log(modalRef); modalRef.focus(); }); } }, close() { if (this.isModal) { this.isModal = false; this.$nextTick(() => { const openButtonRef = this.$refs.openButton; openButtonRef.focus(); }); } }, }, }; </script>

当浏览器或操作系统中的减少运动设置打开时,AnimXYZ 的动画将被禁用。 让我们向选择减少运动的用户显示帮助消息。

使用@media screen and (prefers-reduced-motion)媒体查询,我们将显示一条消息,通知这些用户他们已关闭我们模态组件中的动画功能。 为此,请将以下代码块添加到您的样式中:

 <style> @media (prefers-reduced-motion: reduce) { .alerts__wrap { display: block; } } </style> 
启用减少运动设置时的 AnimXYZ 动画
启用减少运动设置时的 AnimXYZ 动画。

结论

我们已经了解了 AnimXYZ 的基础知识以及如何将它与纯 HTML 和 Vue.js 一起使用。 我们还实现了一些演示项目,让我们可以一瞥 CSS 动画的范围,只需添加此工具包提供的可组合实用程序类即可创建,而且所有这些都无需编写任何 CSS 关键帧。 希望本教程为您提供了坚实的基础,可以将一些时尚的 CSS 动画添加到您自己的项目中,并随着时间的推移在它们的基础上进行构建以满足您的任何需求。

最后的演示在 GitHub 上。 随意克隆它并亲自试用该工具包。

目前为止就这样了! 在下面的评论部分让我知道您对本文的看法。 我在 Twitter 和 GitHub 上很活跃。 感谢您的阅读,敬请期待。

资源

  • 文档,AnimXYZ
  • AnimXYZ、Chris Coyier、CSS 技巧