滚动驱动动画的animation-ranges动画范围备忘录

原文:So many ranges, so little time: A cheatsheet of animation-ranges for your next scroll-driven animation

作者:Saron Yitbarek

前言

如果你是滚动驱动动画的新手,开始之前,不妨先阅读这篇面向初学者的滚动驱动动画介绍,然后再深入本指南。我在那篇文章中简要提到了animation-range,这里我会更深入地探讨,涵盖不同的值及其含义。

让我们开始吧!🚀

首先,快速回顾一下 animation-range 是什么。

animation-rangeview()时间轴是最佳拍档!如果你希望动画在用户滚动且元素在视口中可见时才开始执行,这对组合简直是神器。

但说元素"在视口中可见"可没那么简单,这里面学问大了!以下是几种不同的解释方式:

假设你要动画的元素是一张高度为 300px 的照片。

"在视口中可见" 是指:

  • 照片第一个像素刚露脸就开始动画?(急性子模式)
  • 等到整个照片都可见时才开始?(完美主义模式)
  • 照片滚到页面中间时开始?(中庸之道模式)
  • 照片快离开但还没完全离开时停止动画?(恋恋不舍模式)

选择困难症都要犯了?别慌!animation-range就是来拯救你的选择困难的!它能让你精确到极致,想让动画啥时候开始就啥时候开始,想啥时候结束就啥时候结束。😎

定义

animation-range其实是两个属性的简写:animation-range-startanimation-range-end

animation-range-start负责指定动画何时开始,animation-range-end负责声明动画何时结束。在本文中,我们主要关注简写形式。

简写形式可以接受两种类型的值:timeline-range-namelength-percentage。让我们先深入了解timeline-range-name

timeline-range-name根据元素相对于视口的位置来定义动画的开始和结束。

举个栗子🌰:

假设你有一张300x200px的图片,放在一个1000px宽的容器中。你希望图片从最右侧开始,随着滚动滑到容器的左侧。

以下是该动画的CSS:

css 复制代码
img {
  animation: slideIn;
  animation-timeline: view();
}

@keyframes slideIn {
  0% {
    transform: translateX(700px);
  }
  100% {
    transform: translateX(0px);
  }
}

现在问题来了------你想在哪个确切的点开始这场滑动表演?

cover:急性子的选择

如果你想在图片的第一个像素刚进入视口时就喊"Action!",那么cover就是你的菜!单独使用时,它会将时间轴的开始(0%)设置为图片刚进入视图的那一刻。

css 复制代码
img {
  animation: slideIn;
  animation-timeline: view();
  animation-range: cover;
}

它会让你的照片一路滑到左侧,直到时间轴的结束(100%),也就是最后一个像素从视图中消失的那一刻才喊"Cut!"。

这意味着即使只有一小部分照片在视图中,它也会坚持表演。就算一半的照片已经消失,它仍然会继续,直到完全离开舞台。

contain:完美主义者的福音

如果你希望动画在图像完全可见后才开始,并且在它开始退出前就结束,那么contain就是为你量身定制的!

css 复制代码
img {
  animation: slideIn;
  animation-timeline: view();
  animation-range: contain;
}

让我们看看这是什么效果:

在这里,动画不会在第一个像素出现时就急着开始------它会等到完全可见后才优雅登场。当你的图像到达顶部并且第一个像素开始消失时,动画就会完美谢幕。

Entry:只在入场时表演

如果你希望整个动画,包括开始和结束,都只在照片进入视口时发生呢?也就是说,当第一个像素出现在屏幕上时,动画开始;当最后一个像素完全进入视口时,动画结束。这就是entry的拿手好戏!

css 复制代码
img {
  animation: slideIn;
  animation-timeline: view();
  animation-range: entry;
}

效果如下:

Entry-crossing(vs. Entry):高个子的特殊待遇

还有一个与entry相关的范围叫做entry-crossing。它与entry的工作方式类似,但有一个关键区别。entry在图像的第一个像素进入视口时开始动画(标记为时间轴的0%),当最后一个像素完全进入视口时结束动画(标记为时间轴的100%)。

但是当图像的高度大于视口的高度时会发生什么?我们时间轴的结束点(100%),是设置为图像首次填满视口的那一刻(即使还有部分隐藏)?还是要等到最后一个像素完全进入视口?

这时候,entryentry-crossing就派上用场了:

  • 如果你选择entry,当图像填满视口时,就到达了时间轴的末尾(100%)并结束动画。 效果如下:

  • 如果你选择entry-crossing,100%会被设置为图像中的最后一个像素穿过入口并进入视口的时刻:

    css 复制代码
    img {
      animation: slideIn;
      animation-timeline: view();
      animation-range: entry-crossing;
    }

    效果如下:

Exit:退场也要有仪式感

exit遵循与entry相同的理念,但它不是在图像进入视口时设置0%和100%,而是在图像退出视口时设置。

效果如下:

Exit-crossing(vs. exit):高个子退场的讲究

exit-crossingentry-crossing的理念相同。当图像的高度大于视口时,exit-crossingexit之间的区别最容易理解,让我们看个例子:

  • 当你对高度大于视口的图像使用exit时,0%设置为最后一个像素进入视口的时刻,100%设置为最后一个像素消失、离开视口的时刻:

    css 复制代码
    img {
      animation: slideIn;
      animation-timeline: view();
      animation-range: exit;
    }

    效果如下:

  • 而对于exit-crossing,0%设置为第一个像素开始退出视口、穿过视口边缘的时刻,100%设置为最后一个像素消失的时刻:

    css 复制代码
    img {
      animation: slideIn;
      animation-timeline: view();
      animation-range: exit-crossing;
    }

    效果如下:

以上就是不同timeline-range-name的全部介绍。它们让你能够像导演一样,精确控制动画开始和结束的每一个瞬间!

为了获得更多创意空间,你还可以混合搭配这些值。比如,如果你想在图像首次完全可见时开始动画,但希望动画继续直到最后一个像素离开,你可以这样做:

css 复制代码
img {
  animation: slideIn;
  animation-timeline: view();
  animation-range: contain exit;
}

你可能记得前面提到过animation-range是一个简写属性,所以这里第一个值用于animation-range-start,第二个值用于animation-range-end。这样就能实现你想要的效果啦!

Length-percentage:自定义你的时间轴

如果你想更进一步定制动画,比如不想在图像完全可见之前开始时间轴(保持contain),但希望动画在时间轴的中途(50%)开始,该怎么办?

这时候,你需要在animation-range中明确设置<length-precentage>值:

css 复制代码
img {
  animation: slideIn;
  animation-timeline: view();
  animation-range: contain 50% exit;
}

效果可能是这样的:

<length-precentage>值类型可以接受百分比或任何单位的长度,为你的创意提供无限可能!

选项总结

如果你想完全掌控animation-range的每个方面,你可以分别定义animation-range-startanimation-range-end,为每个属性声明一个timeline-range-namelength-percentage值。

让我们复习一下timeline-range-name的所有可能值:

  • cover:从第一个像素进入到最后一个像素离开
  • contain:从完全可见到开始退出
  • entry:从第一个像素进入到完全进入(或填满视口)
  • entry-crossing:从第一个像素进入到最后一个像素完全进入
  • exit:从完全进入到最后一个像素离开
  • exit-crossing:从第一个像素开始离开到最后一个像素离开

如果不声明任何<length-percentage>值,它们默认为开始0%和结束100%。如果不声明timeline-range-name,它将默认为开始entry和结束exit

现在,轮到你发挥创意了!你会用滚动驱动动画做出什么炫酷效果呢?

相关推荐
迷曳19 分钟前
28、鸿蒙Harmony Next开发:不依赖UI组件的全局气泡提示 (openPopup)和不依赖UI组件的全局菜单 (openMenu)、Toast
前端·ui·harmonyos·鸿蒙
爱分享的程序员31 分钟前
前端面试专栏-工程化:29.微前端架构设计与实践
前端·javascript·面试
上单带刀不带妹35 分钟前
Vue3递归组件详解:构建动态树形结构的终极方案
前端·javascript·vue.js·前端框架
-半.37 分钟前
Collection接口的详细介绍以及底层原理——包括数据结构红黑树、二叉树等,从0到彻底掌握Collection只需这篇文章
前端·html
90后的晨仔1 小时前
📦 Vue CLI 项目结构超详细注释版解析
前端·vue.js
@大迁世界1 小时前
用CSS轻松调整图片大小,避免拉伸和变形
前端·css
一颗不甘坠落的流星1 小时前
【JS】获取元素宽高(例如div)
前端·javascript·react.js
白开水都有人用1 小时前
VUE目录结构详解
前端·javascript·vue.js
if时光重来1 小时前
axios统一封装规范管理
前端·vue.js
m0dw1 小时前
js迭代器
开发语言·前端·javascript