欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

[我能行]掌握几招轻松实现苹果产品页面特效

最编程 2024-05-03 07:35:29
...

好事多磨,经历了延期,苹果春季发布会终于与我们相见,无论是搭载了满血M1的iPad Pro还是成功“瘦身”成超大号ipad的iMac,既有意料之中,又有惊喜。不过对于一个前端爱好者来说,发布会后第一时间打开官网不是为了买买买,而是为了看看苹果的设计师又造出了什么让人眼前一亮的页面效果。

Snipaste_2021-04-21_23-36-42.png

一直很喜欢 @CodingStartup起码课 老师的教程,所以这次也翻看了一下苹果的官网,学习了一下里面用到的某些技巧,希望能够总结一下,和大家分享讨论一下。期待各位掘友的鼓励支持以及讨论点拨,谢谢❤

有些gif图可能因为达到了循环限制而停止不动,感兴趣的话欢迎点击大图查看哦~

中间分享到的文章因为篇幅原因就不做摘录啦,如果感兴趣的话欢迎阅读一下以支持原作者~

随着页面滚动显示动画

随着页面的滚动,页面的文字,图片也会随着进行改变,这样可以营造一种动感的效果,给用户的购买欲赋能(?)
下面以可以随着移动动态改变背景颜色的文字为例来尝试一下吧
原网页

Animation5.gif

首先有一个这样的页面结构,一个大小为100vh*100%的container元素中有两个高度为100vh的flexBox。第一个flexBox文字id为 pt1 ,里面的文字水平垂直居中。

    <div id="pt1" style="display: none;" class="module-content">
        <div class="section-content ">
            <p class="gradient-text">
                Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quasi quo, tempora ipsa excepturi culpa quis possimus nisi, sed at hic assumenda.
            </p>  
        </div>    
    </div>
#pt1 {
    height: 100vh;
    display: flex;
    align-items: center;
}
.module-content .section-content {
    font-size: 48px;
    line-height: 1.1;
    font-weight: 600;
    letter-spacing: -0.009em;
    max-width: 590px;
    margin-left: auto;
    margin-right: auto;
    text-align: center;
}

实现页面滚动监听

在着手实现之前,先得知道元素究竟滚动了多少,才能根据这个调整动画进行的百分比。在这里,我对整个页面进行监听,然后分别对每个元素进行处理。

获得元素滚动高度

首先,使用getBoundingClientRect获得元素相对于显示窗口的窗口坐标。获得元素的窗口坐标后,top属性就是其底部相当于浏览器顶部的距离了。

摘自 元素坐标-javascript.info

方法 elem.getBoundingClientRect() 返回最小矩形的窗口坐标,该矩形将 elem 作为内建 DOMRect 类的对象。

主要的 DOMRect 属性:

x/y — 矩形原点相对于窗口的 X/Y 坐标, width/height — 矩形的 width/height(可以为负)。 此外,还有派生(derived)属性:

top/bottom — 顶部/底部矩形边缘的 Y 坐标, left/right — 左/右矩形边缘的 X 坐标。

Snipaste_2021-04-22_10-40-12.png

获得元素显示高度

然后,获取父元素 pt1 的元素高度,使用 clientHeight 来获得其实际内容可以显示的高度。这样,我们就可以得到元素滚动离开屏幕究竟离开了百分之多少了。

摘自 元素大小和滚动-javascript.info
Snipaste_2021-04-22_10-46-28.png

将计算的百分比应用于CSS变量

得到了百分比后,我们可以直接计算元素样式的数值并且直接修改,不过除了依次计算并修改各个属性之外,既然所有属性都是根据百分比进行变化,那么可以直接使用CSS变量来统一。其以 -- 开头,使用的时候用var()引用。在这里,我们分别定义四个变量a,b,c,d,表示渐变中每个颜色的位置。

关于CSS变量的使用技巧,请看这里

//pt1.js
function handlePt1Scroll(){
    const heightPt1 = pt1.clientHeight;
    let scrolledPt1 = Math.abs(pt1.getBoundingClientRect().top);
    if(scrolledPt1>heightPt1){
        return;
    }
    let scrollPercentPt1 =scrolledPt1/heightPt1;
    const textPt1 = pt1.querySelector(".gradient-text");
    textPt1.style.setProperty('--a', (-150+scrollPercentPt1*200)+'%');
    textPt1.style.setProperty('--b', (-50+scrollPercentPt1*200)+'%');
    textPt1.style.setProperty('--c', (75+scrollPercentPt1*200)+'%');
    textPt1.style.setProperty('--d', (150+scrollPercentPt1*200)+'%');
}

实现文字彩色背景

最后,让我们给文字染上色彩。

image.png

  1. 使用 background-image: linear-gradient(to right, var(--mid) var(--a), var(--start) var(--b), var(--mid) var(--c), var(--end) var(--d));创建动态背景,中间使用a,b,c,d四个css变量让其可以随着滚动而改变。

  2. 使用 -webkit-background-clip:text;background-clip: text; 以文字创建蒙版以透过背景内容。同理,把背景换成视频/图片/canvas可以实现各种漂亮的文字效果。

  3. 最后使用 text-fill-color: transparent;-webkit-text-fill-color: transparent; 把文字改成透明的,大功告成!当然,如果把背景换成黑白渐变,然后使用 background-position-x进行移动,就可以实现文字渐变淡入淡出的效果了。

image.png

为了让文字效果可以复用(例如苹果首页有多处使用了相同效果,但是背景颜色不同的文字),可以把渐变效果放到一个公共的类内,然后把百分比,颜色作为CSS变量对于每个元素分别指定。
的确挺好看的,不过主要还是得归功于font-family: "Helvetica"

sticky 的应用

既然页面的效果基于滚动,在根据滚动距离调整元素显示的时候,如何让标题等需要常驻显示的元素不被滚动上去呢?这时候,就要使用 sticky + top 来让元素在到达某一高度时停驻,直到下一个元素将其顶上。

下面的页面结构为例,左边的是正常滚动的文字描述列表,而右边的电脑则需要停驻,并且随着滚动距离切换显示的内容,那么就可以这么设计:

image.png

完成文字描述部分的结构

使用设定 <p> 的高度使其有滚动距离,通常会设计成 100vh ,这样每个部分就可以有更加多的滚动距离留给动画的过渡。这里的垂直居中我使用了 flex ,然后使用加上左边的 padding 就实现了有充分滚动高度以及靠左的文字区域。
Snipaste_2021-04-22_09-09-07.png

让文字在靠近窗口中间的时候淡入,远离的时候淡出

依旧是使用变量属性,使用元素选择器获得各个元素,然后依次计算百分比。使用will-change:opacity;来让浏览器进行优化。

#pt2 .pt2-list p{
    --opac:0;
    opacity: var(--opac);
    height:50vh;
    display: flex;
    flex-direction: column;
    justify-content:center;
    align-items: flex-start;
    padding-left: 100px;
    font-size: 28px;
    line-height: 1.14286;
    font-weight: 600;
    letter-spacing: .007em;
    will-change:opacity;
    font-family: "SF Pro Display","SF Pro Icons","Helvetica Neue","Helvetica","Arial",sans-serif;
}

实现显示屏的内容

使用 sticky 来使其停留在顶部。 top 使用CSS计算属性 calc 进行计算,以实现显示器垂直居中的效果。如果元素本身有高度的话,其不脱离文档流,也就是说会把文字内容往下挤开。因此需要把高度设为0,然后再在里面加一个脱离文档流的容器。

因为图片素材宽度很大,因此还可以设置容器的宽度,overflow 设为 hidden 来实现显示器靠边,只显示一半的效果。至于显示器的内容则使用绝对定位+CSS变量的方式进行切换。

#pt2 .pt2-preview{
    position:sticky;
    top: calc(50vh - 250px);
}
#pt2 .pt2-preview img{
    width:633px;
    height:574px;
    position: absolute;
    top:0px;
    right: -150px;
}
.pt2-preview-container{
    width:485px;
    height:574px;
    position: absolute;
    top:0px;
    overflow-x:hidden ;
    right: 0px;
}
.pt2-preview-content{
position: absolute;
right: -135px;
top:17px;
width:602px;
height:365px;
background-color: red;
}

大功告成,不过...苹果官网的文字切换的滚动距离并没有这么大(例如我这里是 50vh ),并且文字的移动距离也不会因为文字量(文字块高度)的不同而改变,也就是说得换换新的思路了。
苹果官网效果:

Animation2.gif

变形金刚-transform: matrix

其实分析可以发现,这个部分的滚动高度并不是靠文字 <p> 的大小撑起的,其都是 position:absolute 的高为 100vh 的容器,其中文字垂直居中,也就是说三个文字是重叠在一起的,通过切换透明度而实现淡入淡出的效果。

image.png
淡入淡出好办,之前也是这么做的,但是文字上下的滚动效果又是如何实现的呢?答案是使用transform动态切换其上下位置。下面的三篇文章在我学习的时候给予了帮助,想和大家分享一下

transform的语法请参考这里
transform中间的矩阵究竟是什么请参考这里,我不想写线代啊(被拖走)
为什么不用absolute?主要是为了实现硬件加速带来的性能优化,原理是什么?请参考这里
可以说,中间很多效果都是使用变形来实现的,例如下面的视频区域,就是先使用sticky使得视频随着滚动置顶,然后再根据滚动距离调整大小,使得iMac从屏幕外缩放到中间。

Animation3.gif

叠叠乐

就像砰然爆发的礼花会给人惊喜一样,把各个素材叠加在一起然后突然展开也会给人带来眼前一亮的体验。无论是产品的部件介绍还是切换展示内容,把通过把素材叠在然后分开展示不但可以层次清晰,还可以实现更加特别的动画效果。

想要了解CSS中的层叠上下文请看这里

以下面的文字效果为例,出自今天的苹果地球日宣传网页

image.png
image.png

其实际是两个文字进行叠加,其中底部的作为基底不加处理,然后上面的增加滤镜(虚化)实现了文字掉落的拖影效果。 translateY 使其偏上,子元素使用 translateX 放大10倍后施加模糊滤镜再进行缩放回0.1可以使得模糊效果中的线条更加明显。下图的对比中,左边是直接加滤镜的效果,右边则是先X轴拉伸10倍再加滤镜的效果。

image.png

//阴影的父元素
    position: absolute;
    filter: blur(0.5rem);//加模糊滤镜
    transform: translateY(-0.1em) scaleX(0.1);//缩放
    ________________
  //阴影中文字本身
      transform: scaleX(10);//先放大
    display: inline-block;
    opacity: 0.8;

在网页中,随处可见叠加+矩阵变换的效果,例如下面随着滚动ipad各个元器件“喷薄而出”的效果,其实也是图层叠加+垂直变换实现的。虽然这里是直接触发整个动画,但是既然核心都是脚本修改style,如何实现都是自己决定的。

Animation4.gif

闲话

在浏览网页的时候,特别惊艳我的一点还在于其页面响应性,其考虑到了很多使用场景,并且会根据操作的不同改变页面布局。不过其切换后不能复原,估计主要还是用脚本实现元素类的转换,媒体查询只是负责修改一下元素大小吧。

其实原本还想写一下如何实现文字放大->透过文字切换到视频/图片背景的,不过Steven老师已经写过一篇了,十分推荐->这里

同理,中间iMac的颜色切换效果也是有讲过的,在这里

同样的技术,配以苹果的图片就会特别高大上,换成自己的素材就一言难尽,果然一个人的,不仅要看,还要看(略)

这篇文章只是介绍了一下原理和一些简单实现,主要还是总结,如果有一些别的值得说道的知识点恳请各位掘友指导,学习一直在路上,非常感谢!