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 技巧