• 来点不一样的:前端手指操


    看见题目可能有点好奇,不过看下去你就知道什么叫手指操了~

    目录

    • 引言
    • 原理
    • 核心库
    • 实现
      • 关键帧/图片调整
      • spritesheet
      • progressbar
    • 可能会遇到的问题
    • 相关工具
    • 访问地址

    • 核心库

      为了实现上述的效果,选择了skrollr这个库,使用这个库,懂CSS就可以玩出这个效果了,用关键帧加CSS就可以了
      <section class="scene1 fullpage" 
                data-6300="transform:translate3d(0,0%,0);display:block"  
                data-10000="transform:translate3d(0,-100%,0);display:block" 
                data-30000="transform:translate3d(0,-100%,0);display:block" 
                data-33000="transform:translate3d(0,-130%,0);display:none">
      </section>
      总的来说,共使用了
      • skrollr
        • 多用于桌面端,用在了移动端效果也不错,用起来很方便
      • zepto
        • 不用多说
      • imagesloaded
        • 图片预加载 相当简单nice

    • 实现

      • 关键帧/图片调整

        skrollr初始化之前,需要对图片进行一些调整,首先选好了图片之 后,得保证显示在手机上不变形,因而需要根据不同的手机屏幕大小调整 图片的大小,然后再根据所得的图片设置一下结束的关键帧。

        background是设置结束关键帧
        ratio是设置背景图片的比例

        $.plug.background(true,".scene1-1",6700,$.plug.ratio(true,1080,1920,".scene1-1"));
        $.plug.background(false,".scene2-1",18000,$.plug.ratio(false,4500,1667,".scene2-1"));
        $.plug.background(false,".scene2-2",22000,$.plug.ratio(false,4500,1667,".scene2-2"));
        $.plug.background(false,".scene3-1",42000,$.plug.ratio(false,3840,2160,".scene3-1"));
        $.plug.background(false,".scene3-2",48000,$.plug.ratio(false,3840,2160,".scene3-2"));
        $.plug.background(false,".scene4-1",58000,$.plug.ratio(false,2560,1496,".scene4-1"));
        $.plug.background(false,".scene4-2",62000,$.plug.ratio(false,2560,1496,".scene4-2"));
        $.plug.background(false,".scene5-1",76000,$.plug.ratio(false,2857,1216,".scene5-1"));
        $.plug.background(false,".scene6-1",112000,$.plug.ratio(false,800,800,".scene6-1"));
        $.plug.background(true,".scenev-1-1",94000,$.plug.ratio(true,600,1200,".scenev-1-1"));
        $.plug.background(true,".scenev-1-2",98000,$.plug.ratio(true,600,1200,".scenev-1-2"));
        $.plug.background(true,".scenev-1-3",102000,$.plug.ratio(true,600,1200,".scenev-1-3"));

        如下所示,对于横向图片,以手机高度为准,先根据手机高度设置图片高 度,再根据图片比例设置图片的长度,对于纵向显示的图片,以屏幕宽度为准,手法类似,代码非常简单。


        横向图片
        (function($){
         function ratio(iswidth,width,height,dom,scale,isback){
             var ratioo=scale||1;
             var ratio=width/height;
              if(iswidth){          
                  var wi=window.innerWidth*ratioo;
                  var numb=Math.round(wi/ratio);
                  var _pxheight=numb+"px";
                  document.querySelector(dom).style.height=_pxheight;
                  return numb;
              }
              else{
                  var he=window.innerHeight*ratioo;
                  var numb=Math.round(he*ratio);
                  var _pxwidth=numb+"px";    
                document.querySelector(dom).style.width=_pxwidth;
                return numb;
              }        
        }
          if(!$.plug)$.plug={};
         $.plug.ratio=ratio;        
        })($)

        一开始确定好容器大小,初始化一些白色的小型div,再通过CSS3动画让他们不停旋转,即是星星的感觉。
        再根据前景和背景的运动速度不同,造成视差滚动。
        对于动画,大多使用transform:translate3d,且以百分比做动画,
        以百分比做动画意味着是以自身元素为参照,不是父级元素,因而为了避免有些小型元素移动100%的距离只相当于移动了它自身大小的问题,将所有的元素都套在一个fullpage的div中:

        .fullpage{
        width: 100%;
        height: 100%;    
        position: absolute;
        left: 0;
        top:0
        }

        对这个嵌套元素进行移动,下面是各背景与前景,使他们以不同速度移动,可以通过设置不同的data-number值实现。

        前景
         
        背景
         
         
         
        前景
         
        背景

      • spritesheet

        对游戏制作的同学不会肯定不会陌生

        行走


        这样的代码一大堆,我贴个自己实现的,简单再说一下
        对于这个5793*158的spritesheet,如果在手机上显示高度为100px,则宽度为5793/1.58=3666px,则每次spritesheet移动的距离为3666px/36(动画一共有36帧)=102px,对应下面的JS代码中的interval参数,同时为了停止有个缓冲,加了个停止帧stopframe参数。

        (function($){
           function animate(totaltime,dom,parts,interval,stopframe){
                   var temp=0;
                   var stop_flag=false;
                   var timer=null;
                       var num=temp*(interval);
                       $(dom).css({"background-position-x":num+"px"});
                       temp++;
                       if(stop_flag&&temp===stopframe){
                           clearInterval(timer),timer=null
                           stop_flag=false;
                       }
                       if(temp===parts)temp=0;
        
                   return {
                       animating:function(){return timer!==null?true:false},
                       stop:function(va){
                           stop_flag=true;
                           //clearInterval(timer),timer=null
                       },
                       resume:function(){
                               if(timer!==null)return
                               var str=$(dom).css("background-position-x");
                               var matched=str.match(/-?[0-9]+/);
                               var num=parseInt(matched[0]);
                               temp=num/interval;
                               timer=setInterval(function(){
                               var num=temp*(interval);
                               $(dom).css({"background-position-x":num+"px"});
                               temp++;
                               if(stop_flag&&temp===stopframe){
                                   clearInterval(timer),timer=null
                                   stop_flag=false;
                               }
                               if(temp===parts)temp=0
                           },totaltime/parts);
                       }
        
                   }
                   //$(dom)
               }        
               if(!$.plug)$.plug={};
               $.plug.animate=animate;
        
        })($)

      • progressbar

        progressbar的实现使用了2个半圆的形式
        利用border-radius:50%做一个圆,再利用clip: rect(0,auto,auto,50px)裁切为半圆。

        右半圆旋转

        之后再从垂直正中开始裁切clip: rect(0,auto,auto,50px);

        clip裁切


        左半圆类似:

        左半圆旋转
        clip裁切


        将2个区域合并:

        饼图效果


        加一个背景色相同的mask覆盖在中间,这样的好处是圆环宽度可以方便调整:

        加个背景颜色相同的覆盖在中间

        之后就可以通过代码设置其百分比:

               (function($){
                      function circleprogress(dom,value){                                     
                        $(dom).each(function(index, el) {
                        var num = value * 3.6;
                        num=Math.round(num);
                        if (num<=180) {
                            $(this).find('.right').css('-webkit-transform', "rotate(" + num + "deg) translateZ(0px)");
                            $(this).find('.right').css('transform', "rotate(" + num + "deg) translateZ(0px)");
                             $(this).find('.left').css('-webkit-transform', "rotate("+0+ "deg) translateZ(0px)");
                            $(this).find('.left').css('transform', "rotate("+0+ "deg) translateZ(0px)");
                        } else {
                            $(this).find('.right').css('-webkit-transform', "rotate(180deg) translateZ(0px)");
                            $(this).find('.left').css('-webkit-transform', "rotate(" + (num - 180) + "deg) translateZ(0px)");
                            $(this).find('.right').css('transform', "rotate(180deg) translateZ(0px)");
                            $(this).find('.left').css('transform', "rotate(" + (num - 180) + "deg) translateZ(0px)");
                        };
                    });
                }        
                if(!$.plug)$.plug={};
                $.plug.circleprogress=circleprogress;
        
        })($)

        在滑动的过程中,配置好滑动的区间即可:

               if(data.curTop>=20000 && data.curTop<25000){
                                var num=Math.round((data.curTop-20000)/55);
                                $('.circle-1').find('span.value').text(num);
                                $.plug.circleprogress('.circle-1',num);
                            }

    • 可能会遇到的问题

      对于配置稍低的手机,比如我的4S,在场景越来越多,图片越来越多的情况下,不管是在微信中打开还是原生浏览器中打开,都会把微信和浏览器弄崩溃。。期间尝试了各种优化,把所有关于layoutpaint的动画部分都替换,情况稍微好一些,但是还是有崩溃的现象。最后发现网页加载时要对所有的场景进行渲染,即便这些场景一开始并不需要出现。所以根据动画情况,将需要出现的场景动态显示,且在css中加入下面的语句,让所有场景及信息一开始都不渲染。
          .scene1,.scene2,.scene3,.scene4,.scene5,.scene6,.infomation{
            display: none;
            }
      最后根据skrollr的值来选择显示的场景。

      通过这样的做,我的4s终于再也不崩溃了,即便在有些低配手机还是有点卡。



  • 相关阅读:
    duilib框架分析:几个回调(C++11)
    duilib框架分析(一)概述
    图解JVM--(二)垃圾回收
    图解jvm--(一)jvm内存结构
    4 (计算机网络) DHCP与PXE:IP是怎么来的,又是怎么没的?
    3(计算机网络)ifconfig:最熟悉又陌生的命令行
    2 (计算机网络)理解网络协议的工作模式
    1 (计算机网络)我们常用的网络协议有哪些?
    阿里云配置mysql
    深入Spring Boot:那些注入不了的Spring占位符(${}表达式)
  • 原文地址:https://www.cnblogs.com/07lyt/p/5582231.html
Copyright © 2020-2023  润新知