paint-brush
Vue Amsterdam 2022:第七部分 - 使用 Vue 制作动画经过@mohsenv
377 讀數
377 讀數

Vue Amsterdam 2022:第七部分 - 使用 Vue 制作动画

经过 Mohsen Vaziri10m2022/07/21
Read on Terminal Reader
Read this story w/o Javascript

太長; 讀書

这是 Vue Amsterdam 2022 系列的第七部分。

Companies Mentioned

Mention Thumbnail
Mention Thumbnail

Coin Mentioned

Mention Thumbnail
featured image - Vue Amsterdam 2022:第七部分 - 使用 Vue 制作动画
Mohsen Vaziri HackerNoon profile picture


欢迎!很高兴在我的 Vuejs 阿姆斯特丹会议 2022 总结系列的第七部分见到你,我在其中与你分享所有谈话的总结。


你可以在这里阅读我的 JSWorld Conference 2022 总结系列(分为四个部分),我总结了第一天的所有演讲。您还可以在我的博客中找到 2022 年 Vue 阿姆斯特丹会议之前的演讲。

(经常性)介绍

两年半之后,JSWorld 和 Vue 阿姆斯特丹会议于 6 月 1 日至 3 日再次在阿姆斯特丹剧院举行,这是我第一次有机会参加这个会议。我学到了很多东西,遇到了很多很棒的人,与优秀的开发人员交谈,度过了愉快的时光。第一天举行了 JSWorld 会议,第二天和第三天举行了 Vue Amsterdam。


会议充满了信息,有很多很棒的演讲者,他们每个人都教会了我一些有价值的东西。他们都想与其他开发人员分享他们的知识和信息。所以我想如果我能继续分享它并帮助其他人使用它会很棒。


起初,我尝试分享一些笔记或幻灯片,但我觉得还不够好,至少不如演讲者与我分享的那么好。所以我决定重新观看每一次演讲,深入了解他们,搜索,做笔记并将它们与他们的幻灯片甚至他们演讲中的确切单词结合起来,然后与你分享,这样我与你分享的内容至少是与我从他们那里学到的水平相同。

非常重要的一点

你在这几篇文章中读到的一切都是演讲者自己努力和时间的结果,我只是试图学习它们,以便将它们变成这些文章。甚至这些文章中写的许多句子正是他们所说的或他们在幻灯片中写的。这意味着如果你学到了新东西,那是因为他们的努力。


最后但并非最不重要的一点是,我可能不会在一些演讲中深入研究每一个技术细节或实时编码。但是如果您有兴趣并需要更多信息,请告诉我,我会尝试单独写一篇更详细的文章。另外,不要忘记查看他们的 Twitter/Linkedin。


在这里您可以找到会议的程序。


使用 Vue 制作动画

Ramona Biscoveanu - SAP 的前端开发人员

有时我们的应用程序需要一点点“哇”,我们可以通过一些“运动”来做到这一点,这正是使它们更有活力的完美数量。


我们将研究如何使用 Vue 的魔力来创建令人敬畏的动画,从简单的动画到更复杂的动画,结合 Vue 和动画库。

90 年代网站

在 90 年代的网站上,有时会有很多动作和颜色。但当时我们制作动画的唯一方法是使用 gif。试想一下那些 gif 在拨号互联网时代消耗的带宽!所以我们最终得到了一些微小的低帧 gif 来限制带宽消耗,结果如下:


为什么动画?

如今,甚至在当时,我们使用动画的原因之一是为了吸引用户的注意力和注意力。想想我们有多少分心,我们手机上的通知,网站上的弹出窗口,或者 macOS 上 Dock 上的跳跃图标。


我们还可以欺骗用户认为我们的网站速度更快。通过放置加载器和进度条,我们让他们认为我们的 API 更快。研究表明,如果您有自定义加载程序,您就有机会让人们在我们网站上停留更长时间。


有时我们会尝试有效地通知我们的用户。也许我们的网站上发生了很多事情,我们想通过动画按钮告诉用户应用程序流程的下一步是什么。


其他时候,我们需要营销材料的交互式内容来留住用户。

当您尝试讲故事时,动画也很强大。

Vue <Transition />

在 Vanilla JavaScript 或 jQuery 中,您需要手动计算时间和延迟,并决定何时添加或删除类。但是在 Vue 中,我们将目标元素包装到<Transition />组件中,它会自动完成许多困难的事情。这是一个简单的淡入淡出动画:


 <transition name="fade"> <p v-if="show">hello</p> </transition>


 .fade-enter-active, .fade-leave-active { transition: opacity .5s; } .fade-enter-from, .fade-leave-to opacity: 0; }


这就是 Vue 的处理方式:


Vue <TransitionGroup />

<TransitionGroup>是一个内置组件,旨在为列表中呈现的元素或组件的插入、删除和顺序更改设置动画。

这是一些在屏幕上滑动的图块的简单示例:


 <transition-group tag="div" class="tile-section" name="list" appear> <TileComp v-for="(tile, i) in tiles" :key="i + 'tile'" :header="tile.title" :content="tile.content" :footer="tile.footer" ></TileComp> </transition-group>


 .list-enter-active, .list-leave-active { transition: all 1s ease; } .list-enter-from, .list-leave-to { opacity: 0; transform: translateY(70px); } 


JavaScript 钩子

CSS 很棒,我们可以用它做很多事情,但有时还不够。

Vue 在<Transition />组件上提供了一些钩子。


 <Transition @before-enter="onBeforeEnter" @enter="onEnter" @after-enter="onAfterEnter" @enter-cancelled="onEnterCancelled" @before-leave="onBeforeLeave" @leave="onLeave" @after-leave="onAfterLeave" @leave-cancelled="onLeaveCancelled" > <!-- ... --> </Transition>

绿袜 GSAP

GreenSock 动画平台(简称GSAP )是一个强大的 JavaScript 库,使前端开发人员和设计人员能够创建强大的基于时间轴的动画。

在 GSAP 中你会经常听到的最重要的事情之一是 Tween。


一个 Tween 是所有动画工作的东西——把它想象成一个高性能的属性设置器。您输入目标(您想要动画的对象)、持续时间和您想要动画的任何属性,当它的播放头移动到新位置时,它会计算出该点的属性值并相应地应用它们。


创建 Tween 的常用方法(所有这些方法都返回 Tween 实例):

对于简单的动画(没有花哨的排序),上面的方法就是你所需要的!


 gsap.to(".selector", {toVars}); gsap.from(".selector", {fromVars}); gsap.fromTo(".selector", {fromVars}, {toVars}); // special properties (duration, ease, etc.) go in toVar


现在让我们将 GSAP 添加到我们的图块示例中:


 <div class="tile-section"> <TileComp v-for="(tile, i) in tiles" :key="i + 'tile'" :header="tile.title" :content="tile.content" :footer="tile.footer" ></TileComp> </div>


 import gsap from "gsap"; ... mounted() { gsap.from(".tile", { duration: 0.5, opacity: 0, scale: 0, y: 200, ease: "power2", stagger: 0.1, }); }, 


Vue 动画计数器

另一个使用 GSAP 制作漂亮动画的简单示例是庆祝反动画。在这里你可以看到它的样子:


我们在模板中拥有的只是一个 h1 元素,我们在其中传递了格式化的值和一个重置按钮。


 <div> <h1 ref="celebrate" class="counter" :class="{ celebrate: isCelebrate }"> {{ this.numberWithCommas(value) }} </h1> <button class="restart" @click="restart">Restart</button> </div>


我们需要使用 GSAP 的timeline功能。将其视为对动画进行排序的工具。


 import gsap from "gsap"; import confetti from "canvas-confetti"; const tl = gsap.timeline(); const start = 100000; const end = 3240074; export default { props: { msg: String, }, data() { return { isCelebrate: false, value: start, }; }, mounted() { tl.fromTo( ".counter", { innerText: start, scale: 0.8, }, { innerText: end, snap: { innerText: 1 }, duration: 4, ease: "linear", onUpdate: () => { this.$refs.celebrate.innerText = this.numberWithCommas( this.$refs.celebrate.innerText ); }, onComplete: () => { this.celebrate(); }, } ); }, methods: { celebrate() { this.isCelebrate = true; confetti({ particleCount: 150, spread: 100, origin: { y: 0.6 }, colors: ["#647eff", "#42d392"], disableForReducedMotion: true, }); }, numberWithCommas(x) { return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); }, restart() { tl.restart(); this.isCelebrate = false; }, }, };

页面转换

在 Vue Router 4 中,转换页面的语法发生了一些变化。我们不再将路由器包装到转换组件中。相反,我们使用v-slot


 <router-view v-slot="{ Component }"> <transition name="fade"> <component :is="Component" /> </transition> </router-view>


以下是页面转换的示例:


为了构建这个页面转换,我们需要 enter 钩子:


 <router-view v-slot="{ Component }"> <transition :key="$route.path" @enter="onEnter" :css="false" > <component :is="Component" /> </transition> </router-view>


然后我们需要从 GSAP 注册SplitText插件:


 import gsap from "gsap"; import SplitText from "gsap/SplitText"; gsap.registerPlugin(SplitText); gsap.defaults({ duration: 1, ease: "power3.inOut", });


然后使用插件我们拆分文本以便能够对其进行动画处理:


 mySplitText(el) { return new SplitText(el, { type: "words,chars,lines" }); },


我们来看看onEnter钩子:


 onEnter(el, done) { const masterTL = gsap.timeline({ onComplete: () => { done; }, }); masterTL.add( this.enterContentTextAnimation( mySplitText(".content-text-header").chars ) ); masterTL.add( this.enterContentTextAnimation(".content-text-body"), "-=0.9" //overlap with previous by 0.9s ); masterTL.add(this.imgScaleOut(".content img"), "<"); //The start of previous animation },


在这里您可以看到如何嵌套 GSAP 时间线以及enterContentTextAnimationimgScaleOut函数的作用:


 enterContentTextAnimation(id) { const tl = gsap.timeline(); tl.fromTo( id, { yPercent: "100", opacity: 0, }, { yPercent: "0", opacity: 1, stagger: 0.03, } ); }, imgScaleOut(id) { const tl = gsap.timeline(); tl.from(id, { scale: 1.5, }); return tl; },

SVG

动画图表可以是 SVG 动画的一个很好的例子:



这是使该图表动画成为可能的代码部分:


 watch: { data(newValue, oldValue) { newValue.map((data, index) => { var id = "#arc" + index; var d = this.calculateArc(data, index); var oldValueD = this.calculateArc(oldValue[index]); const tl = gsap.timeline(); tl.fromTo( id, { attr: { d: oldValueD }, }, { duration: 0.5, attr: { d: d }, yoyo: true, } ); }); }, },


不要滥用您网站上的动画,这一点很重要。有时它们很有用,但有时它们会杀死你的听众。



第七讲结束

我希望你喜欢这部分,它对你和对我一样有价值。

在接下来的几天里,我将与你分享剩下的谈话。敬请关注…