0
点赞
收藏
分享

微信扫一扫

iPhone 12 页面卷动逐行滑入效果


在这里也特别声明一下,这个教学里用到的图片素材都是由 Apple 网站中获取,图片版权归 Apple 所有,这里只用作教学演示用途,大家千万不要将这些图片用于真实的网页中。

HTML 的部分

打开 CodePen 编辑器,在 HTML 的部份加入标题。由于它有一个副标题,所以我会用

标签去装着它。然后加入一个

id 名为 iphone,里面新增两个

id 分别是

hardware

ui

hardware 会用来显示 iPhone 的机身和边框,而

ui 则会显示画面里面的内容。

iPhone 12 页面卷动逐行滑入效果_选择器

CSS 的部分

先定义一些 CSS,让我们更加清楚知道在做什么。加入 :root 选择器,定义一些变量和样式:

  • --device-width770px
  • --device-height1336px
  • --ui-width640px
  • 基础文字大小是 15px

然后加入 #iphone 选择器,设定 positionrelative,宽度和高度的值从变量中获取。

iPhone 12 页面卷动逐行滑入效果_ci_02

再加入 #hardware 选择器,设定宽度和高度是 100%,然后背景图片,载入 iPhone 的机身图片,为了支援 Retina Display 高清屏幕,这张图片的尺寸是两倍大小,所以设定 background-size,宽度和高度同样等于变量的设定值。

好了,在这里想介绍一个图片遮罩的 CSS 属性,大家会发现现在 iPhone 的四周,圆型边框背后有个黑色背景:

iPhone 12 页面卷动逐行滑入效果_CSS_03

而我发现 Apple 特地准备了一张遮罩图片,画出了 iPhone 的外型,用白色填充,而圆型边框的四周是透明的:

iPhone 12 页面卷动逐行滑入效果_ci_04

我们可以通过 mask-image 这个属性将遮罩图片套用上去。由于这个 CSS 属性还在试验阶段,所以要加上 -webkit 前缀的版本,与背景图片一样,图片是两倍大小,所以同样需要将遮罩的大小设定一下,将 mask-size 设定为变量的值,并且加上 -webkit 前缀的版本。

iPhone 12 页面卷动逐行滑入效果_选择器_05

现在可以看到遮罩已经成功套用上,iPhone 的黑色背景不见了。至于为何 Apple 不直接将 iPhone 图片的背景设定为透明?我估计是为了优化图片的大小,因为透明底的图片需要用到 PNG 格式,而这么大张的彩色 PNG 图片容量上比起 JPG 会大不少,所以 Apple 就采用了高压缩比的 JPG 格式作为 iPhone 图片,再准备一张只有单色的 PNG 图片来做遮罩,这样的确可以省下不少网络频宽。

好了,介绍完这个属性,可以加入 body 选择器,将背景颜色设定为黑色,margin 设定为 0,然后将网页的内容上下左右置中:

  • display 设定为 flex
  • flex-direction 设定为 column
  • justify-content 设定为 center
  • align-items 设定为 center
  • min-height 设定为 100vh

字体设定为 Helvetica,再加入一些 padding,设定上下是 4rem,左右是 0

iPhone 12 页面卷动逐行滑入效果_CSS_06

再设定一下标题的样式,加入 h2 选择器,文字颜色设定为灰色,text-align 设定为 center 将它置中,文字大小设定为 4.5rem,文字粗度是 600。然后 margin 设定为上下 6rem,左右 0

加入 h2 p 选择器,设定副标题的样式,margin 设定为 0,文字颜色设定为白色就可以了。

iPhone 12 页面卷动逐行滑入效果_选择器_07

框架大置上设定好了,下一步就设定 iPhone 画面的内容。

#ui 里面加入一张图片,是画面顶部的 UI,然后就是每一行资料的图片,我会用

列表去建构它,加入

  • ,内容是一张图片,总共有 7 行。

回到 CSS 的部份,加入 #ui 选择器,position 设定为 absolutetop 设定为 0。然后要将它左右置中,先将 left 设定为 50%,再将 transform 设定为 translateX(-50%) 就可以了。

加入 #ui .top-ui 选择器,设定顶部 UI 图片的定位。display 设定为 block,宽度从变量中获取,高度是 auto,然后 margin,设定上方是 70px,左右是 auto,下方是 0。再加一点 padding-bottom,设定为 30px,以及一条下边框线。

来到列表的部份,加入 #ui ul 选择器,将 list-style 设定为 none,取消列表的样式,marginpadding 设定为 0

再设定里面的图片的样式,加入 #ui ul li img 选择器,设定 displayblock,宽度从变量中获取,高度是 automargin 设定为上下 10px,左右 autopadding-bottom10px,然后再加一条下边框线。

现在界面基本上已设定好了,接下来处理动画的部份。

动画的部分

我们先了解一下这个动画的原理,它是在页面卷动的时候,一行一行的由大至小滑入至列表中,先试试在 CSS 中将效果实现出来。

加入 #ui ul li img:hover 选择器,设定 transformscale(1.8),然后 opacity 设定为 0。在 #ui ul li img 选择器内加入 transition: .25s transform ease-in-out;,现在试试将游标移至其中一行,就可以实现将图片由放大至缩小,回到列表中的效果。

再加一些位移,例如 translateY() 设定为 -60px,效果大致上是这样:

不过这个动画并不是由游标触发,是随着页面卷动时触发,并且可以通过卷动控制动画的进度,所以我会通过 JavaScript 计算目前页面卷动了多少,然后再设定对应行数的 transformopacity

为了简化 JavaScript 对 CSS 样式的设定,我想先在 CSS 这边做一个设定值,用来控制一行动画的进度。

先将 hovertransition 的设定值移除,然后在 HTML 里面,在第一个 li 那里加入 style,设定 --progress0.5

--progress 是我自己定义的 CSS 变量,我想在它的设定值为 0 时将 scale() 设定为 1.8,以及 opacity 设定为 0;而在它的设定值为 1 的时候,将 scale() 设定为 1opacity 设定为 1。做到像是一个动画的开关的功能,那么我们在 JavaScript 那边,只需要调整这个 --progress 就可以控制动画。

#ui ul li img 里面,加入 transform,先设定 scale(),将 1.8 减去 0.8 * var(--progress),这样在 --progress1 的时候,scale 就是 1;而 --progress0 的时候,scale 就是 1.8 了。

再来 translateY(),将 -60px 乘以 1 - var(--progress),这样在 --progress1 时,translateY 就是 0;而 --progress0 的时候,translateY 就是 -60px

再将 opacity 直接设定为 --progress 的值,0 的时候会将它隐藏,1 的时候它就会显示。试试调整一下 --progress 的值,大家就可以看到这个设定值的具体作用了。

然后将

  • 上的设定值移除,在 #ui ul 里将 --progress 初始化为 0 就可以了。

JavaScript 的部分

最后,就是用 JavaScript 控制动画。

首先定义一个名为 rows 的常量,将每一个

  • 获取回来,再定义一个名为 html 的常量,赋值为 document.documentElement,因为稍后会有几次引用 document.documentElement 的。 加入 document.addEventListener,监听 scroll 页面卷动,定义一个变量,scrolled 等于 html.scrollTop 除以 html.scrollHeight 减去 html.clientHeight
    这样会得出一个由 01 之间的值,页面卷动到最顶时是 0,卷动到最底时是 1

接下来要将每一个

  • ,一个接着一个,将 --progress 设定为 1。 新增一个 for of 回圈,将每一个
  • 获取出来,由于动画是一个接着一个,而页面卷动了多少可以经由 scrolled 获取,所以我们要计算每一个
  • 01 之间的所属区间。 定义一个名为 total 的变量,将 1 除以
  • 的总数,然后计算两个值,一个是 start,将 total 乘以 index,另一个是 end,将 total 乘以 index1,通过 console.log(),将每一个
  • 的区间输出一下看看。

有了这些资料,我们可以计算每一个

  • --progress 的值了。定义变量 progress,将 scrolledstart 除以 endstart;然后如果 progress 大于等于 1 的话,将 progress 设定为 1;少于等于 0 的话,就设定为 0。 最后,将 progress 的值通过 setProperty 设定到
  • 上。

我们来看看这个案例的完成效果

以上,就是今集要介绍的全部内容。

这个案例的源代码在:https://codepen.io/stevenlei/pen/ExydYqp

– EOF –

举报

相关推荐

0 条评论