zoukankan      html  css  js  c++  java
  • 那些H5用到的技术(5)——视差滚动效果

    前言

    视差滚动(Parallax Scrolling)是指让多层背景以不同的速度移动,形成立体的运动效果,带来非常出色的视觉体验。
    目前最火热的视差开源库为parallax.js
    官方地址:https://github.com/wagerfield/parallax
    体验地址:http://matthew.wagerfield.com/parallax/

    原理

    视差滚动原理其实并不难,parallax.js的源码也仅有600行,大致讲解一下
    1、默认情况通过requestAnimationFrame方式做数值计算,否则用setTimeout

    1. if (!window.requestAnimationFrame) {
    2. window.requestAnimationFrame = function(callback, element) {
    3. var currTime = new Date().getTime();
    4. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
    5. var id = window.setTimeout(function() { callback(currTime + timeToCall); },
    6. timeToCall);
    7. lastTime = currTime + timeToCall;
    8. return id;
    9. };
    10. }

    2、优先通过DeviceOrientationEvent判断是否支持陀螺仪,否则通过mousemove事件监听鼠标移动

    1. Plugin.prototype.enable = function() {
    2. if (!this.enabled) {
    3. this.enabled = true;
    4. if (this.orientationSupport) {
    5. this.portrait = null;
    6. window.addEventListener('deviceorientation', this.onDeviceOrientation);
    7. setTimeout(this.onOrientationTimer, this.supportDelay);
    8. } else {
    9. this.cx = 0;
    10. this.cy = 0;
    11. this.portrait = false;
    12. window.addEventListener('mousemove', this.onMouseMove);
    13. }
    14. window.addEventListener('resize', this.onWindowResize);
    15. this.raf = requestAnimationFrame(this.onAnimationFrame);
    16. }
    17. };

    3、css动画优先采用transform的translate3d,否则使用translate进行平移

    1. if (this.transform3DSupport) {
    2. this.css(element, 'transform', 'translate3d('+x+','+y+',0)');
    3. } else if (this.transform2DSupport) {
    4. this.css(element, 'transform', 'translate('+x+','+y+')');
    5. }

    4、通过设置CSS让浏览器开启GPU加速

    1. Plugin.prototype.accelerate = function($element) {
    2. for (var i = 0, l = $element.length; i < l; i++) {
    3. var element = $element[i];
    4. this.css(element, 'transform', 'translate3d(0,0,0)');
    5. this.css(element, 'transform-style', 'preserve-3d');
    6. this.css(element, 'backface-visibility', 'hidden');
    7. }
    8. };

    5、层运动的计算规则

    • 每一个层的运动量依赖于3个因素:
    • scalarX和scalarY的值
    • 父DOM元素的尺寸大小
    • 一个parallax场景中层的depth值

    计算的公式如下:

    1. xMotion = parentElement.width * (scalarX / 100) * layerDepth
    2. yMotion = parentElement.height * (scalarY / 100) * layerDepth

    例如在场景中一个data-depth为0.5的层,它的scalarX和scalarY值都为10(默认值),它的父容器的尺寸为1000px x 1000px,那么这个层在x和y方向的总运动量就为:

    1. xMotion = 1000 * (10 / 100) * 0.5 = 50 # 50px of positive and negative motion in x
    2. yMotion = 1000 * (10 / 100) * 0.5 = 50 # 50px of positive and negative motion in y

    使用方式

    非常简单,官方建议使用ul+li标签的无序列表(当然你用div或者其他标签都行),你只需要给它们一个class layer和一个data-depth属性来指定该层的深度。深度为0的层将是固定不动的,深度为1的层运动效果最激烈的层。0-1之间的层会根据值来相对移动。

    1. <ul id="scene">
    2. <li class="layer" data-depth="0.00"><img src="layer1.png"></li>
    3. <li class="layer" data-depth="0.20"><img src="layer2.png"></li>
    4. <li class="layer" data-depth="0.40"><img src="layer3.png"></li>
    5. <li class="layer" data-depth="0.60"><img src="layer4.png"></li>
    6. <li class="layer" data-depth="0.80"><img src="layer5.png"></li>
    7. <li class="layer" data-depth="1.00"><img src="layer6.png"></li>
    8. </ul>

    别忘了设置样式

    1. ul {
    2. list-style: none;
    3. display: block;
    4. padding: 0;
    5. margin: 0;
    6. }
    7. . scene,
    8. . scene .layer {
    9. height: 100%;
    10. width: 100%;
    11. position: absolute;
    12. }
    1. //jquery.parallax.js
    2. $('. scene').parallax();
    3. //parallax.js
    4. var scene = document.getElementById('scene');
    5. var parallax = new Parallax(scene);

    一般这样使用就足够了,除非是比较复杂的效果,要设置一些特定参数,调用API,具体内容参见官方文档

    结合swiper.js

    使用方式上不变,只不过需要把需要视差的元素再包裹一层

    1. <div class="swiper-slide">
    2. <ul class="parallax">
    3. <li class="layer" data-depth="0.5"><img style="position: absolute;left:0;top: 5%" class="ani" swiper-animate-effect="fadeInUp" swiper-animate-duration="1s" swiper-animate-delay="0.3s" src="./img/5.jpg" alt=""></li>
    4. <li class="layer" data-depth="0.2">
    5. <video id="video" style="width: 80%;left: 10%;top: 20%" src="./video/test.mp4" preload autoplay controls>
    6. </video>
    7. </li>
    8. </ul>
    9. </div>

    最终效果图:

    demo地址:
    https://github.com/leestar54/h5-demo/blob/master/parallax.html

  • 相关阅读:
    《ODAY安全:软件漏洞分析技术》学习心得-----shellcode的一点小小的思考
    关于《加密与解密》的读后感----对dump脱壳的一点思考
    React-Native(四):React Native之View学习
    React-Native(二):React Native开发工具vs code配置
    SqlServer优化:当数据量查询不是特别多,但数据库服务器的CPU资源一直100%时,如何优化?
    React-Native(一):React Native环境搭建
    游戏资源收集
    Java-NIO(九):管道 (Pipe)
    Java-NIO(八):DatagramChannel
    Java-NIO(七):阻塞IO与非阻塞IO
  • 原文地址:https://www.cnblogs.com/leestar54/p/6786752.html
Copyright © 2011-2022 走看看