Vue 中的可组合 CSS 动画与 AnimXYZ
已发表: 2022-03-10在本文中,您将学习如何使用 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"
已应用于父元素。
AnimXYZ 可以轻松地为子元素设置与其父元素不同的动画。 为此,将具有不同动画变量和不同实用程序的xyz
属性添加到子元素,这将重置它从其父元素继承的所有动画属性。
实用程序
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
:
没有stagger
:
在 HTML 和 CSS 中使用 AnimXYZ
让我们用 AnimeXYZ 制作一张卡片并添加一些很酷的动画。
首先,我们需要将 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
元素将淡入页面。
接下来,我们有一张id
为glass
的卡片,具有以下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
组件时,我们需要关心的只是appear
、 appear-visible
、 duration
和mode
道具。
如需更详细的指南,请查看官方文档。
让我们使用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
组件时,我们需要关心的只是appear
、 appear-visible
、 duration
和tag
。 以下内容来自文档:
<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 的基础知识以及如何将它与纯 HTML 和 Vue.js 一起使用。 我们还实现了一些演示项目,让我们可以一瞥 CSS 动画的范围,只需添加此工具包提供的可组合实用程序类即可创建,而且所有这些都无需编写任何 CSS 关键帧。 希望本教程为您提供了坚实的基础,可以将一些时尚的 CSS 动画添加到您自己的项目中,并随着时间的推移在它们的基础上进行构建以满足您的任何需求。
最后的演示在 GitHub 上。 随意克隆它并亲自试用该工具包。
目前为止就这样了! 在下面的评论部分让我知道您对本文的看法。 我在 Twitter 和 GitHub 上很活跃。 感谢您的阅读,敬请期待。
资源
- 文档,AnimXYZ
- AnimXYZ、Chris Coyier、CSS 技巧