zoukankan      html  css  js  c++  java
  • 视差滚动效果原理解析和效果实现

    【定义】

    所谓的视差滚动,就是在页面滚动过程中,多层次的元素进行不同程度的位移,带来立体的视差效果。还有很多的奇思妙想的展现方式,都是滚动页面触发的,也可称为视差滚动视差滚动里面最基础的就是切换背景,这点其实一个CSS就满足了。

    视差滚动原理一】

    1 background-attachment: fixed || scroll || local

    默认是scroll,内容跟着背景走,而视差滚动页面里用fixed,背景相对页面固定而不跟内容滚动

    很快地我就做出了一个demo出来,还特意配上几张优雅的图片和极富内涵的词句,女神一定会因为我的文采而爱上我的,而且,那些看似简单的“我是内容”不断重复,其实只要细心就会发现里面隐藏着我的表白,情商如此之高的女神,一定会发现,然后我们就可以幸福的在一起,在爱情的滋润下,我很快就能升职加薪,当上总经理,出任CEO,赢取白富美,走上人生巅峰。哈哈哈哈哈哈哈哈,诶?好像不用赢取白富美,那就挑战白富美。

    视差滚动原理二】

    当然要来写非常酷的动画效果。
    在原理的demo1的基础上,我在scroll事件上添加一些动画事件。

    window.addEventListener('scroll',function(e){
            var scrollTop = window.scrollY;
            if(scrollTop > 0 && scrollTop < articleHeight){
                title1.classList.add('title-anim');
                content1.classList.add('content-anim');
            }else if(scrollTop >= articleHeight && scrollTop < articleHeight*2){
                title2.classList.add('title-anim');
                content2.classList.add('content-anim');
            }else if(scrollTop >= articleHeight*2 && scrollTop < articleHeight*3){
                title3.classList.add('title-anim2');
                content3.classList.add('content-anim');
            }
        })

    视差滚动的表现方式非常多,滚动到页面某个值后会触发一个CSS3动画,这也是众多视差滚动中常见的一种。

    demo2_anim

    (这个Demo使用了CSS3动画,请使用现代浏览器查看)

    【视差滚动原理三】
    视差滚动中最突出的内容就是立体的视差效果,最具有说明代表性的就是超级玛丽的游戏场景

    视差滚动效果原理解析和效果实现

    当玩家操作马里奥移动时,水管和墙块更马里奥在同一水平层,移动速度最快。天上的白云为中层背景图,移动速度中等。而小山丘是最远的背景图,移动速度最慢。三个层次内容按不同速度移动,就会带来一种立体的视差效果。

    在dom结构上,把同一层的dom元素都放到一个div里面,html结构如下。

    <div id="scene_back" class="scene">
        <img id="pokemon1" src="./img/001.png">
        <img id="pokemon4" src="./img/004.png">
        <img id="pokemon7" src="./img/007.png">
    </div>
    <div id="scene_center" class="scene">
        <img id="pokemon2" src="./img/002.png">
        <img id="pokemon5" src="./img/005.png">
        <img id="pokemon8" src="./img/008.png">
    </div>
    <div id="scene_front" class="scene">
        <img id="pokemon3" src="./img/003.png">
        <img id="pokemon6" src="./img/006.png">
        <img id="pokemon9" src="./img/009.png">
    </div>

       在页面滚动过程中,我们获取页面的scrollTop的值,根据不同参数值去设置各自scene的top值,这样滚动页面的时候,不同的速度就出来了

    var sceneBack = document.getElementById('scene_back'),
        sceneCenter = document.getElementById('scene_center'),
        sceneFront = document.getElementById('scene_front');
    var old_top1 = 0,
        old_top2 = 200,
        old_top3 = 700;
     
    addEvent(window,'scroll',onScroll);
    onScroll();
     
    function onScroll(e){
        var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
        sceneBack.style.top = old_top1+scrollTop*.9+'px';
        sceneCenter.style.top = old_top2+scrollTop*.7+'px';
        sceneFront.style.top = old_top3+scrollTop*.3+'px';  
    }
     
    function addEvent(eventTarget, eventType, eventHandler) {
        if (eventTarget.addEventListener) {
            eventTarget.addEventListener(eventType, eventHandler, false);
        } else {
            if (eventTarget.attachEvent) {
                eventType = "on" + eventType;
                eventTarget.attachEvent(eventType, eventHandler);
            } else {
                eventTarget["on" + eventType] = eventHandler;
            }
        }
    }

    【视差滚动一种效果实现】
    上下颠倒出现,这个跟原理三是一样的,唯独就是不是所有的元素都是往上升,而是一些元素上升,一些元素下沉。在计算top值的时候,不是“加上”,变成“减去”scrollTop就会有相应的效果。亲自试了一下,效果就出来了,但是很明显有个问题,就是上升元素和下沉元素在同一水平线上的时候,这时却不是在页面正中间。这时候思考一下问题所在就好了。计算top的公式是下面

    newTop1 = oldTop1 + scrollTop * x1 ;   (x是个系数)
    newTop2 = oldTop2 - scrollTop * x2 ;   (x是个系数)

    我们假设,oldTop为-1000,oldTop2为1000,我们希望滚动到500的时候,两者在同一水平线上,这时newTop1和newTop2都相同为500才能再页面中心(注意不是0,自个想想就明白)。这样得到x1为2,x2为0。代码如下。

    var sona = document.getElementById('sona'),
        ahri = document.getElementById('ahri');
    var old_top1 = -1000,
        old_top2 = 1000;
     
    addEvent(window,'scroll',onScroll);
        onScroll();
     
    function onScroll(e){
        var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
        sona.style.top = old_top1+scrollTop*2+'px';
        ahri.style.top = old_top2-scrollTop*0+'px';
    }
     
    function addEvent(eventTarget, eventType, eventHandler) {
         if (eventTarget.addEventListener) {
             eventTarget.addEventListener(eventType, eventHandler, false);
         } else {
             if (eventTarget.attachEvent) {
                eventType = "on" + eventType;
                eventTarget.attachEvent(eventType, eventHandler);
             } else {
                 eventTarget["on" + eventType] = eventHandler;
             }
        }
    }
  • 相关阅读:
    收藏篇基础命令
    itchat+图灵机器人实现python登录微信并自动回复
    四级物理实验
    天行数据网易云热评接口python脚本模板运行出错||socket.gaierror: [Errno 11001] getaddrinfo failed
    每日一道: 两数之和 简单
    每日一道:求和
    每日一道:四数之和
    每日一道:最接近的三数之和
    每日一道:盛最多水的容器
    MySQL中GRANT和IDENTIFIED同时使用时出现near 'IDENTIFIED BY...” at line 1错误
  • 原文地址:https://www.cnblogs.com/xs-yqz/p/4972902.html
Copyright © 2011-2022 走看看