动效案例:纯手工写一个滚动视差效果
一、什么是滚动视差?
视差滚动(Parallax Scrolling)是指让多层背景以不同的速度移动,形成立体的运动效果,带来非常出色的视觉体验。作为网页设计的热点趋势,越来越多的网站应用了这项技术。
视差效果,原本是一个天文学术语,当我们观察星空时,离我们远的星星移动速度较慢,离我们近的星星移动速度则较快。当我们坐在车上向车窗外 看时,也会有这样的感觉,远处的群山似乎没有在动,而近处的稻田却在飞速掠过。许多游戏中都使用视差效果来增加场景的立体感。说的简单点就是网页内的元素在滚动屏幕时发生的位置的变化,然而各个不同的元素位置变化的速度不同,导致网页内的元素有层次错落的错觉,这和我们人体的眼球效果很像。我看到多家产品商用视差滚动效果来展示产品,从不同的空间角度和用户体验,起到了非常不错的效果。
本内容来自百度百科
二、案例的效果展示
你可能迫不及待的想知道我们要做个什么样的效果,如下视频所示,我们滚动往下滑动浏览器的滚动条,月亮往左边移动,高山往上移动,文字往下移动,最终随着滚动条的滚动,淡出我们的视野,如下视频所示:
三、涉及到知识点
1、mix-blend-mode
你可能注意到了我们界面上的图片色调基本一致,其实原图片是有色彩的,那么问题来了,是如何实现这个效果呢,我们在所有的图片上层盖了一个背景色,这里用到 mix-blend-mode:color 的属性进行与图片的颜色进行混合。这是 CSS3 新增的属性,其中 mix 和 blend 的中文意译均为混合,那么这个属性的作用直译过来就是混合混合模式,当然,我们我们通常称之为混合模式。
混合模式最常见于 photoshop 中,是 PS 中十分强大的功能之一。当然,瞎用乱用混合模式谁都会,利用混合模式将多个图层混合得到一个新的效果,只是要用到恰到好处,或者说在 CSS 中利用混合模式制作出一些效果则需要对混合模式很深的理解及不断的尝试。
mix-blend-mode: normal; // 正常 mix-blend-mode: multiply; // 正片叠底 mix-blend-mode: screen; // 滤色 mix-blend-mode: overlay; // 叠加 mix-blend-mode: darken; // 变暗 mix-blend-mode: lighten; // 变亮 mix-blend-mode: color-dodge; // 颜色减淡 mix-blend-mode: color-burn; // 颜色加深 mix-blend-mode: hard-light; // 强光 mix-blend-mode: soft-light; // 柔光 mix-blend-mode: difference; // 差值 mix-blend-mode: exclusion; // 排除 mix-blend-mode: hue; // 色相 mix-blend-mode: saturation; // 饱和度 mix-blend-mode: color; // 颜色 mix-blend-mode: luminosity; // 亮度
为了更好理解这个属性,我们可以借鉴PS混合图层
2、window属性:scrollY
在这里我们使用JS脚本动态更新相关图片在界面的位置,这是我们制作滚动视差的关键。我们通过window的scrollY属性来充当因子变量,控制各图片在平面移动的距离,来回滚动又能恢复原先各自的位置。
Window接口的只读scrollY属性返回文档当前垂直滚动的像素数。这个值在现代浏览器中是亚像素精确的,这意味着它不一定是整数。您可以从scrollX属性中获取文档水平滚动的像素数。实际上,返回值是一个双精度浮点值,表示文档当前从原点垂直滚动的像素数,其中正值表示内容向上滚动。
四、准备图片素材
首先我们先准备下四张素材图片,分别对应星空、月亮、高山、奔驰在山间小路的小车,请注意这四张图片的大小一定要保持一致,尽量png图片,方便图片叠加成一张大图,图片资源可以在文末源码下载链接里进行获取。
五、创建HTML结构
HTML结构非常简单,我们依次排列图片,放在 section 标签区域即可,示例代码如下:
<section> <img src="./images/bg.jpg" id="bg" /> <img src="./images/moon.png" id="moon" style="z-index: 3;" /> <img src="./images/mountain.png" id="mountain" /> <img src="./images/road.png" id="road" /> <h2 id="text">Moon Light</h2> </section>
六、编写CSS部分
1、首先我们来定义全局属性,引用字体Poppins,设定背景色为墨兰色,视口高度为150Vh, 让浏览器出现滚动条,示例代码如下:
@import url('https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700,800,900&display=swap'); * { margin: 0; padding: 0; font-family: 'Poppins', sans-serif; } body { background: #0a2a43; min-data-height: 150vh; }
2、接下来我们来定义 section 区域为弹性盒子容器,并定义position: relative; 让内部的图片参照其进行位置浮动,改变其正常流的布局方式。
section { position: relative; data-width: 100%; data-height: 100vh; overflow: hidden; display: flex; justify-content: center; align-items: center; } section img { position: absolute; top: 0; left: 0; data-width: 100%; data-height: 100%; object-fit: cover; pointer-events: none; }
3、接下来我们使用伪元素 ::before 和 ::after 来在section区域在所有的图片上覆盖一层墨蓝色的背景,使用mix-blend-mode: color 属性让图片的颜色保持一致性,给人一种月色已晚高冷的感觉,并在图片下方绘制一种线性渐变的背景色,让其自然过渡到非图片区域。示例代码如下:
section::before { content: ''; position: absolute; bottom: 0; data-width: 100%; data-height: 100px; background: linear-gradient(to top, #0a2a43, transparent); z-index: 10000; } section::after { content: ''; position: absolute; top: 0; left: 0; data-width: 100%; data-height: 100%; background: #0a2a43; z-index: 10000; mix-blend-mode: color; }
4、最后为了让文字有一种夹在高山和山间小路之间的感觉,让文字往下移动时,被山间小路图片盖住,这里我们需要更改 z-index属性,示例代码如下:
#text { position: relative; color: #fff; font-size: 10em; z-index: 1; } #road { z-index: 2; }
到这里我们的CSS部分就结束了,是不是很简单呢,最后我们来编写JS脚本。
七、编写脚本
JS脚本为本示例的核心部分,这里通过定义变量获取window.scrollY的属性,作为变量因子,更改各图片的移动位置,并能进行恢复各自初始的位置,脚本代码如下:
let bg = document.getElementById("bg"); let moon = document.getElementById("moon"); let mountain = document.getElementById("mountain"); let road = document.getElementById("road"); let text = document.getElementById("text"); window.addEventListener('scroll', function () { var value = window.scrollY; bg.style.top = value * 0.5 + 'px'; moon.style.left = -value * 0.5 + 'px'; mountain.style.top = -value * 0.15 + 'px'; road.style.top = value * 0.15 + 'px'; text.style.top = value * 1 + 'px'; });
八、源码及效果展示
最终的效果体验,大家可以点击文末 原文链接 进行体验(高清宽屏大图,请耐心等待下载,手机横屏体验),由于文章篇幅有限,完整的源码大家可以点击以下链接下载:
链接:https://pan.baidu.com/s/1kMu94YYvgJNVauLV6dNsEA
密码:et62