其實是依托Css3的功勞,先上一個例子 
代碼地址:鏈接: https://pan.baidu.com/s/1sldhljJ 密碼: i6qh

這動畫縱有萬般變化,也離不開以下幾個屬性

  • transform (元素2D 3D轉(zhuǎn)換)

    translate,3d,X,Y,Z (移動距離)
    scale,3d,X,Y,Z (縮放比例)
    rotate,3d,X,Y,Z (旋轉(zhuǎn)角度)
    skew,X,Y (傾斜角度)

  • transform-origin (允許被轉(zhuǎn)換元素位置)

    left center right length %

  • transform-style (被嵌套元素在3D空間中顯示)

    flat (2d) presever-3d (3d)

  • perspective (3D元素透視效果 俗稱"景深")

    number

  • perspective-origin (設(shè)置3D基數(shù)位置 x,y)

    top center right length %

  • backface-visibility (元素不面對屏幕是否可見)

    visible hidden



這里寫一個變化的例子,幫助理解

以上例子只是單一的變化 如果多個變化一起執(zhí)行 遵守 “慢寫的先執(zhí)行
比如:
原始圖片
iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

"translateX(150px) rotateY(180deg)": 先旋轉(zhuǎn)再移動
iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

"rotateY(180deg) translateX(150px)": 先移動再旋轉(zhuǎn)
iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

為什么兩者只是前后順序不同 結(jié)果卻是相反的呢?
這就涉及到了 中心點的問題 transform-origin
transform-origin 變換原點 center center;

關(guān)鍵字: top bottom center left right;
具體的長度單位(em,rem,px...)

會受到原點影響的變換有:rotate、skew、scale
translate不受影響

第一個是先根據(jù)中心原點旋轉(zhuǎn)180度 再向右移動150pxbr 
第二個向右移動150px 中心點未改變 再旋轉(zhuǎn)180deg

還有一點需要注意:

在js中沒有辦法 通過計算后樣式 獲取到 transform中的相關(guān)操作,只能獲取到矩陣

getComputedStyle(XX)['transform'] 得到的是 matrix3d(...)

關(guān)于 transform的所有操作,通過封裝cssTransform來進行操作,
在 cssTransform 中來記錄 對transform的每一步操作,相當于對象賦值。獲取的時候,就獲取 cssTransform中的記錄

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

function css(element, attr , val){    // 通過判斷 歸納transform 屬性 直接跳到cssTramsform 剩下的直接常規(guī)方法處理
    if(attr == "rotate" || attr == "rotateX" 
    || attr == "rotateY" ||attr == "rotateZ" 
    || attr == "scale" || attr == "scaleX"
    || attr == "scaleY" || attr == "skewX"
    || attr == "skewY" || attr == "translateX"
    || attr == "translateY" || attr == "translateZ" ){        return cssTransform(element, attr, val);
    }    if(arguments.length == 2){        var val = getComputedStyle(element)[attr];        if(attr=='opacity'){
            val = Math.round(val*100);
        }        return parseFloat(val);
    } 
    if(attr == "opacity") {
        element.style.opacity= val/100;
    } else {
        element.style[attr]= val + "px";    
    }
}function cssTransform(el, attr, val) {    if(!el.transform){
        el.transform = {}
    }    // 如果val為空 為獲取值
    if(typeof val == "undefined"){        if(typeof el.transform[attr] == "undefined"){            switch(attr) {                case "scale":                case "scaleX":                case "scaleY":
                    el.transform[attr] = 100;                    break;                default:
                    el.transform[attr] = 0;    
            }
        }        return el.transform[attr];
    } else {        // 設(shè)置值 原理就是對象的賦值
        var transformVal = "";
        el.transform[attr] = Number(val);        for(var s in el.transform){            switch(s){                case "rotate":                case "rotateX":                case "rotateY":                case "rotateZ":                case "skewX":                case "skewY":
                    transformVal += " "+s+"("+el.transform[s]+"deg)";                    break;                case "translateX":                case "translateY":                case "translateZ":
                    transformVal += " "+s+"("+el.transform[s]+"px)";                    break;                case "scale":                case "scaleX":                case "scaleY":
                    transformVal += " "+s+"("+el.transform[s]/100+")";                    break;
            }
        }
        el.style.WebkitTransform = el.style.transform = transformVal;
    }
}

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

加下來介紹核心庫:m.Tween.js運動函數(shù)
使用如下:

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

MTween({
    el: div, // 目標元素
    target: { // 期望最后變化的值
        scale: 200,
        translateX: 200,
        translateY: 200,
        rotate: 360
    },
    time: 1000, // 動畫執(zhí)行時間
    type: "backOut", // 動畫特效 貝塞爾曲線
    callBack: function(){ // 動畫執(zhí)行結(jié)束的回調(diào)
        console.log("動畫執(zhí)行完了");
    },
    callIn: function(){ // 動畫執(zhí)行過程的回調(diào)
        console.log("動畫執(zhí)行中");
    }
})

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 


實現(xiàn)的代碼也很簡單

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

function MTween(init){    var t = 0;    var b = {};    var c = {};    var d = init.time / 20;    for(var s in init.target){ 
        b[s] = css(init.el, s); 
        c[s] = init.target[s] - b[s];
    }
    clearInterval(init.el.timer); 
    init.el.timer = setInterval(        function(){
            t++;            if(t>d){
                clearInterval(init.el.timer);
                init.callBack&&init.callBack.call(init.el);
            } else {
                init.callIn&&init.callIn.call(init.el);                for(var s in b){                    var val = (Tween[init.type](t,b[s],c[s],d)).toFixed(2);
                    css(init.el, s, val);
                }
            }
        },20);
}

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

以上只是基礎(chǔ)知識,為下面的教程鋪墊

正文開始:

1、安踏圖標轉(zhuǎn)動,來回變化,消失

2、碎片,云朵不規(guī)則圓柱轉(zhuǎn)動

3、主體,浮層 圓柱形滾動入場

4、移動事件,陀螺儀,橫豎屏事件

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

// 整體Html結(jié)構(gòu)<div id="pageBg"></div>
<div id="view">
    <div id="logo1">
        <div class="logoImg">
            <img src="load/logo.png">
        </div>
        <p class="logoText">已加載 0%</p>
    </div>
    <div id="main">
        <div id="tZ">
            <div id="panoBg"></div>
            <div id="cloud"></div>
            <div id="pano"></div>
        </div>
    </div>
</div>

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

1、安踏圖標轉(zhuǎn)動,來回變化,消失

 

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

分析: 安踏圖標有三個 分別為 logo1 logo2 logo3 (logo2 logo3 為動態(tài)生成,并提前賦值屬性,加上360度旋轉(zhuǎn)動畫) 
logo1 使用css3動畫animation 360度轉(zhuǎn)動 1s后透明度為0 并刪除 
logo2 由 translateZ : -1000 經(jīng)過300ms 變?yōu)? 向前移動;接著經(jīng)過800ms 變?yōu)?1000 向后移動 
logo3 在logo2 刪除后出現(xiàn) 由遠到近 再接著消失

其實代碼很簡單 就是用下面的模型代碼實現(xiàn)

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

MTween({
    el: logo1,
    target: {
      opacity: 0 // 將要最終變化的值    },
    time: 1000,
    type: 'easeOut',
    callBack: function() { // 運動結(jié)束的執(zhí)行動作      view.removeChild(logo1)
      css(logo2, 'opacity', 100) // 顯示logo2
      // 接下來做logo2動作 以此類推      MTween({
        el: logo2,
        target: {
          translateZ: 0
        },
        time: 300,
        type: 'easeBoth',
        callBack: anmt2 
      })
    }
  })

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

2、碎片,云朵不規(guī)則圓柱轉(zhuǎn)動

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

分析:將9張碎片圖片乘3 然后設(shè)置隨機的 rotateY rotateX translateZ translateY 變成一個隨機圓柱排布,然后在碎片的主層加上 rotateY 旋轉(zhuǎn)動畫,再用動畫控制translateZ 向后移動
祥云入場: 利用 sin cos R 計算translateX translateZ,然后在云層主層加上 rotateY 旋轉(zhuǎn)動畫,再用動畫控制translateZ 向后移動

碎片代碼

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

//基礎(chǔ)框架版本 排成一圈for (var i = 0; i < 27; i++) {    var R = 10 + Math.round(Math.random()*240);    var deg =  Math.round(Math.random()*360)
    css(span, 'rotateY', deg)
    css(span, 'translateZ', R)
}// 添加上下分布css(logo4, "translateZ", -2000)
css(logo4, "scale", 0)for (var i = 0; i < 27; i++) {    var xR = 20 + Math.round(Math.random() * 240) // 圓柱碎片的X半徑
    var xDeg = Math.round(Math.random() * 360)    var yR = 10 + Math.round(Math.random() * 240) // 圓柱碎片的Y半徑
    var yDeg = Math.round(Math.random() * 360)
    css(span, "rotateY", xDeg);
    css(span, "translateZ", xR);
    css(span, "rotateX", yDeg);
    css(span, "translateY", yR)
}// 從遠到近的移動MTween({
    el: logo4,
    target: {
      translateZ: 0,
      scale: 100
    },
    time: 500,
    type: "easeOutStrong",
    callBack: function() {
      setTimeout(function() { //從近到遠        MTween({
          el: logo4,
          target: {
            translateZ: -1000,
            scale: 20
          },
          ...
          })

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

祥云代碼
這里需要每一片云朵都面對我們自己
iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 


這里知道每一個R deg,便能求得x, z
x = Math.sin(deg * Math.PI / 180) * R 
z = Math.cos(deg * Math.PI / 180) * R

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

  var span = document.createElement("span");
    span.style.backgroundImage = 'url(' + imgData.cloud[i % 3] + ')';    var R = 200 + (Math.random() * 150) // 設(shè)置隨機半徑
    var deg = (360 / 9) * i // 圓柱各個角度
    var x = Math.sin(deg * Math.PI / 180) * R // sin求得X
    var z = Math.cos(deg * Math.PI / 180) * R // cos求得Z
    var y = (Math.random() - .5) * 200 // 上下分布
    css(span, "translateX", x)
    css(span, "translateZ", z)
    css(span, "translateY", y)
    ...    // 設(shè)置動畫    MTween({
    el: cloud,
    target: {
      rotateY: 540
    },
    time: 3500,
    type: "easeIn",
    callIn: function() { // 這里需要用到運動過程的回調(diào) 將祥云外層的角度賦予內(nèi)層祥云的每個角度
      var deg = -css(cloud, "rotateY");      for (var i = 0; i < cloud.children.length; i++) {
        css(cloud.children[i], "rotateY", deg);
      }
    }
  })

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

3、主體,浮層 圓柱形滾動入場

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)
這里的圖片是由20張分割好的寬129px的圖片組成
iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 


每張圖片的角度deg為360/20,這樣就能得到中心點距離每張圖片的距離,利用數(shù)學(xué)的tan公式 R = (width / 2) / Math.tan((deg/ 2 )* Math.PI / 180) 
iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

var panoBg = document.querySelector('#panoBg')var width = 129 // 一張圖片寬度var deg = 360 / imgData.bg.length // 圓柱圖片角度var R = parseInt((width / 2) / Math.tan((deg/ 2 )* Math.PI / 180) - 1) // tan@ = 對邊(R) / 臨邊(W/2)var startDeg = 180; // 開始角度for (var i = 0; i < imgData.bg.length; i++) {  var span = document.createElement("span");
  css(span, 'rotateY', startDeg)
  css(span, 'translateZ', -R)
  span.style.backgroundImage = "url(" + imgData.bg[i] + ")";
  panoBg.appendChild(span);
  startDeg -= deg // 每張圖片角度遞減}

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

設(shè)置主體從遠到近 類似畫軸顯示出來,在span初始化時候都設(shè)置display="none",然后設(shè)置定時器依次打開

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

var timer = setInterval(function() {
  panoBg.children[num].style.display = "block";
  num++  if (num >= panoBg.children.length) {
    clearInterval(timer)
  }
}, 3600 / 2 / 20)

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

設(shè)置漂浮層 
漂浮層相對簡單一些,動態(tài)創(chuàng)建漂浮層,設(shè)置初始translateX translateZ,遍歷對應(yīng)的浮層,設(shè)置上面求得的半徑距離,角度

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

  var pano = document.querySelector('#pano'); // 浮層容器
  var deg = 18; // 差值角度
  var R = 406; // 上圖計算的R
  var nub = 0; // 計數(shù)
  var startDeg = 180; // 初始角度 
  css(pano, "rotateX", 0);
  css(pano, "rotateY", -180);
  css(pano, "scale", 0);  var pano1 = document.createElement("div");
  pano1.className = "pano";
  css(pano1, "translateX", 1.564);
  css(pano1, "translateZ", -9.877);  for (var i = 0; i < 2; i++) {    var span = document.createElement("span");
    span.style.cssText = "height:344px;margin-top:-172px;";
    span.style.background = "url(" + imgData["pano"][nub] + ")";
    css(span, "translateY", -163); // 設(shè)定固定的值
    css(span, "rotateY", startDeg); // 角度逐級遞減
    css(span, "translateZ", -R);
    nub++;
    startDeg -= deg;
    pano1.appendChild(span)
  }  var pano2 = document.createElement("div");
  pano2.className = "pano";
  css(pano2, "translateX", 20.225);
  css(pano2, "translateZ", -14.695);  for (var i = 0; i < 3; i++) {    var span = document.createElement("span");
    span.style.cssText = "height:326px;margin-top:-163px;";
    span.style.background = "url(" + imgData["pano"][nub] + ")";
    css(span, "translateY", 278);
    css(span, "rotateY", startDeg);
    css(span, "translateZ", -R);
    nub++;
    startDeg -= deg;
    pano2.appendChild(span)
  }

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

4、移動事件,陀螺儀,橫豎屏事件

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

http://www.cnblogs.com/QRL909109/p/7041898.html