iPhone12页面卷动逐行滑入效果

(给前端大全加星标,提升前端技能)

转自:掘金-CodingStartup起码课

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

HTML的部分

打开CodePen编辑器,在HTML的部份加入标题。由于它有一个副标题,所以我会用p标签去装着它。然后加入一个div,id名为iphone,里面新增两个div,id分别是hardware和ui;hardware会用来显示iPhone的机身和边框,而ui则会显示画面里面的内容。

CSS的部分

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

--device-width是px--device-height是px--ui-width是px基础文字大小是15px

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

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

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

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

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

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

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

display设定为flexflex-direction设定为columnjustify-content设定为centeralign-items设定为centermin-height设定为vh

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

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

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

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

在#ui里面加入一张图片,是画面顶部的UI,然后就是每一行资料的图片,我会用ul列表去建构它,加入li,内容是一张图片,总共有7行。

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

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

来到列表的部份,加入#uiul选择器,将list-style设定为none,取消列表的样式,margin和padding设定为0。

再设定里面的图片的样式,加入#uiulliimg选择器,设定display是block,宽度从变量中获取,高度是auto,margin设定为上下10px,左右auto。padding-bottom是10px,然后再加一条下边框线。

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

动画的部分

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

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

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

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

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

先将hover和transition的设定值移除,然后在HTML里面,在第一个li那里加入style,设定--progress是0.5:

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

在#uiulliimg里面,加入transform,先设定scale(),将1.8减去0.8*var(--progress),这样在--progress为1的时候,scale就是1;而--progress为0的时候,scale就是1.8了。

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

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

然后将li上的设定值移除,在#uiul里将--progress初始化为0就可以了。

JavaScript的部分

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

首先定义一个名为rows的常量,将每一个li获取回来,再定义一个名为html的常量,赋值为document.documentElement,因为稍后会有几次引用document.documentElement的。

加入document.addEventListener,监听scroll页面卷动,定义一个变量,scrolled等于html.scrollTop除以html.scrollHeight减去html.clientHeight。

这样会得出一个由0至1之间的值,页面卷动到最顶时是0,卷动到最底时是1。

接下来要将每一个li,一个接着一个,将--progress设定为1。

新增一个forof回圈,将每一个li获取出来,由于动画是一个接着一个,而页面卷动了多少可以经由scrolled获取,所以我们要计算每一个li在0至1之间的所属区间。

定义一个名为total的变量,将1除以li的总数,然后计算两个值,一个是start,将total乘以index,另一个是end,将total乘以index加1,通过console.log(),将每一个li的区间输出一下看看。

有了这些资料,我们可以计算每一个li的--progress的值了。定义变量progress,将scrolled减start除以end减start;然后如果progress大于等于1的话,将progress设定为1;少于等于0的话,就设定为0。

最后,将progress的值通过setProperty设定到li上。

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

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

这个案例的源代码在:



转载请注明地址:http://www.wangbuliuxinga.com/wxbm/9075.html
  • 上一篇文章:
  • 下一篇文章:
  • 热点文章

    • 没有热点文章

    推荐文章

    • 没有推荐文章