有大量用于动画库的 CSS 和 JavaScript 库。 事实上,如此之多,以至于为您的项目选择正确的一个似乎是不可能的。 这就是我决定建立一个 在线纸牌游戏. 我知道我需要一个动画库,但哪个是正确的选择?
在本文中,我将介绍我做了哪些考虑、需要注意什么,并向您介绍一些最流行的可用库。 我将与你一起通过一些真实的例子来说明我的观点,最后,希望当我第一次不得不选择动画库时,你会比我更有能力。
当然,您对这个建议的了解可能会有所不同。 我在这里分享的所有内容都特定于我想要构建的东西。 您的项目可能有完全不同的要求和优先级,这没关系。 我认为这里重要的是获得第一手资料 像前端开发人员一样思考 有一个特定的目标。
说到这一点,我确实认为自己是一名前端开发人员,但我的设计背景非常重。 所以我知道代码,但不是 JavaScript 工程师的程度。 只是想澄清一下,因为经验肯定会影响最终决定。
这是目标
在我们做出任何决定之前,让我们先看看我需要在这个 CSS-Tricks 化版本的游戏中制作的各种动画:
@media(最大宽度:800px){
#solitaire_embed > div {
padding-bottom: 90% !important; /* 在移动设备上更改纵横比 */
}
}
@media(最大宽度:568px){
#solitaire_embed > div {
padding-bottom: 100% !important; /* 在移动设备上更改纵横比 */
}
}
@media(最大宽度:414px){
#solitaire_embed > div {
padding-bottom: 120% !important; /* 在移动设备上更改纵横比 */
}
}
很甜蜜,对吧? 这些动画没有什么是微不足道的。 有很多事情发生——有时是同时发生的——还有很多事情要安排。 此外,大多数动画都是由用户交互触发的。 因此,这让我在做出决定时有几个优先事项:
- 流畅的动画: 动画的应用方式会对它们是否流畅运行或显示出一点波动产生很大影响。
- 性能: 采用任何库都会增加项目的重量,我希望我的游戏尽可能精简。
- 方便: 我想要一个漂亮、干净的语法,可以更轻松地编写和管理动画。 如果它允许我编写更好、更易于维护的代码,我什至会用一点额外的便利换取一点性能成本。 同样,这对于设计师转为开发人员来说是个好兆头。
- 浏览器支持: 当然,我希望我的游戏能够使用某种形式的渐进增强在任何现代浏览器上运行,以防止旧版浏览器完全失效。 另外,我绝对想要一些面向未来的东西。
这就是我在寻找适合这项特定工作的合适工具时随身携带的东西。
在 CSS 或 JavaScript 之间进行选择 动画库
在选择动画库时,我首先考虑的是选择基于 CSS 的库还是基于 JavaScript 的库。 有很多 很棒的 CSS 库,其中许多具有出色的性能,这对我来说是重中之重。 我正在寻找一些重型动画,例如对动画进行排序和在动画完成时获得回调的能力。 使用纯 CSS 完全可以做到这一点——不过,它比大多数 JavaScript 库提供的流畅度要低得多。
让我们看看一个简单的序列动画在 CSS 中的样子,并将它与 jQuery 进行比较,后者有很多内置的动画助手:
动画看起来相同,但创建方式不同。 要制作 CSS 动画,首先,我们必须在 CSS 中定义关键帧动画并将其附加到一个类:
.card.move {
animation : move 2s;
}
@keyframes move {
0% { left: 0 }
50% { left: 100px }
100% { left: 0 }
}
然后我们使用 JavaScript 执行动画并监听元素上的 CSS 回调:
var cardElement = document.getElementsByClassName("card")[0];
var statusElement = document.getElementsByClassName("status")[0];
cardElement.classList.add("move");
statusElement.innerHTML = "Animating"
var animationEndCallback = function() {
cardElement.classList.remove("move");
statusElement.innerHTML = "Inactive"
}
cardElement.addEventListener("webkitAnimationEnd", animationEndCallback);
cardElement.addEventListener("oAnimationEnd", animationEndCallback);
cardElement.addEventListener("antionend", animationEndCallback);
在像这样的简单示例中,让事情发生在不同的地方可能很好,但是一旦事情变得更复杂,它就会变得非常混乱。
将此与使用 jQuery 完成动画的方式进行比较:
$(".status").text("Animating")
$( ".card" ).animate({
left: "100px"
}, 1000);
$( ".card" ).animate({
left: 0
}, 1000, function() {
$(".status").text("Inactive")
});
在这里,一切都发生在同一个地方,如果将来动画变得更加复杂,事情就会变得更简单。
很明显,JavaScript 库是正确的选择,但我的纸牌游戏应该选择哪一个? 我的意思是,jQuery 很棒而且 即使在今天仍然被广泛使用,但这不是我想挂在上面的东西。 有很多 JavaScript 动画库,所以我想考虑专门为处理我想到的重型动画类型而构建的东西。
选择 JavaScript 动画库
我很快就明白,不乏 JavaScript 动画库和 令人兴奋的新技术. 它们都有优点和缺点,所以让我们来看看我考虑过的一些以及为什么。
网络动画 API 未来可能会取代许多 JavaScript 动画库就是这样一种情况。 有了它,您将能够创建复杂的交错动画,而无需加载任何外部库,并且具有与 CSS 动画相同的性能。 唯一的缺点是 并非所有浏览器都支持它.
<canvas>
element 提供了另一个令人兴奋的机会。 在其中,我们可以像使用 DOM 一样使用 JavaScript 为事物制作动画,但是动画被渲染为光栅,这意味着我们可以制作一些高性能动画。 唯一的缺点是 canvas 元素本质上是在 DOM 中呈现为图像,所以如果我们正在寻找像素完美,我们可能会不走运。 作为一个对设计有着敏锐洞察力的人,这对我来说是一个交易破坏者。
我需要一些经过尝试和测试的东西,所以我知道我可能不得不使用众多 JavaScript 库之一。 我开始查看图书馆并将选择范围缩小到 动漫.js 和 GSAP. 他们似乎都很好地处理了复杂的动画,并且在性能方面都有出色的表现。 Anime 是一个维护良好的库,在 GitHub 上有超过 42.000 颗星,而 GSAP 是一个超级流行、久经考验的库,拥有一个蓬勃发展的社区。
一个活跃的社区对我来说至关重要,因为我需要一个寻求帮助的地方,而且我不想使用一个以后可能会被遗弃的图书馆。 我认为这是我的便利要求的一部分。
排序动画和回调
一旦我缩小了选择范围,下一步就是使用我的两个库来实现一个复杂的动画。 纸牌游戏中的循环动画是卡片移动到某处然后翻转的动画,所以让我们看看它的外观:
两个动画看起来都很棒! 它们很流畅,实现它们都非常简单。 两个图书馆都有一个 时间线功能 这使得创建序列变得轻而易举。 这是 AnimeJS 中的实现方式:
var timeline = anime.timeline({
begin: function() {
$(".status").text("Animating")
},
complete: function() {
$(".status").text("Inactive")
}
});
timeline.add({
targets: '.card',
left: [0, 300],
easing: 'easeInOutSine',
duration: 500
}).add({
targets: '.card .back',
rotateY: [0, 90],
easing: 'easeInSine',
duration: 200
}).add({
targets: '.card .front',
rotateY: [-90, 0],
easing: 'easeOutSine',
duration: 200
})
动漫的 timeline()
功能 内置了动画开始和结束的回调,创建序列就像附加序列动画一样简单。 首先,我移动卡片,然后将背面图像旋转 90 度,使其消失,然后将正面图像旋转 90 度,使其进入视野。
使用 GSAP 的相同实现 timeline()
功能 看起来非常相似:
var timeline = gsap.timeline({
onStart: function() {
$(".status").text("Animating")
},
onComplete: function() {
$(".status").text("Inactive")
}
});
timeline.fromTo(".card", {
left: 0
}, {
duration: 0.5,
left: 300
}).fromTo(".card .back", {
rotationY: 0
}, {
rotationY: 90,
ease: "power1.easeIn",
duration: 0.2
}).fromTo(".card .front", {
rotationY: -90
}, {
rotationY: 0,
ease: "power1.easeOut",
duration: 0.2
})
决定时间
Anime 和 GSAP 之间的主要区别似乎是语法,其中 GSAP 可能更复杂一些。 我被两个功能非常相似的优秀库困住了,它们能够处理复杂的动画,并且拥有一个蓬勃发展的社区。 好像我打了一场平局!
优先 | 动漫 | GSAP |
平滑的动画 | ✅ | ✅ |
性能 | ✅ | ✅ |
方便 | ✅ | ✅ |
浏览器支持 | ✅ | ✅ |
那么,是什么让我选择了一个图书馆而不是另一个?
我非常担心图书馆在压力下会如何行动。 在像纸牌这样的游戏中拥有滞后的动画会极大地影响玩游戏的乐趣。 我知道在我创建游戏之前我无法完全了解库的表现。 幸运的是,GSAP 做了一个 压力测试 将不同的动画库相互比较,包括动漫。
从这一点来看,GSAP 无疑是处理大量复杂动画的优秀库。 GSAP 给了我每秒 26 帧以上的动画,动画只能达到 19 帧。在阅读了更多关于 GSAP 并查看他们的论坛之后,很明显性能是这些家伙的最高优先级落后于 GSAP。
尽管 GSAP 和 Anime 都已经存在了一段时间,但 Anime 的 repo 已经休眠了几年,而 GSAP 在过去几个月里已经做出了承诺。
我最终使用了 GSAP,并且没有后悔我的决定!
你呢? 这是否与您评估和比较前端工具的方式有关? 在这样的项目中,您可能考虑过其他优先事项(例如可访问性等)吗? 或者你有一个项目,你必须从一堆不同的选项中减少你的选择? 请在评论中分享,因为我想知道!
哦,如果你想看看它在为一整副纸牌制作动画时的样子,你可以前往我的网站并 玩纸牌游戏。 玩的开心!