來點不同的:前端手指操

看見題目可能有點好奇,不過看下去你就知道什麼叫手指操了~php

目錄

  • 引言
  • 原理
  • 核心庫
  • 實現
    • 關鍵幀/圖片調整
    • 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初始化以前,須要對圖片進行一些調整,首先選好了圖片之 後,得保證顯示在手機上不變形,於是須要根據不一樣的手機屏幕大小調整 圖片的大小,而後再根據所得的圖片設置一下結束的關鍵幀。web

      background是設置結束關鍵幀
      ratio是設置背景圖片的比例api

      $.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終於不再崩潰了,即使在有些低配手機仍是有點卡。



相關文章
相關標籤/搜索