實現phaser版的animate.css動效庫

首先介紹phaser和animate.cssjavascript

animate.css相信大部分作前端的同窗都用過,是一款強大的css動畫庫,裏面有上百種經常使用小動效。簡單的加一個類名就可讓咱們寫的頁面變得生動有趣起來。是由css的keyframes來實現的。css

phaser是一款js遊戲引擎,基於canvas和webgl。內置各類功能,好比精靈,spine,音視頻,dragonBones,物理引擎,粒子效果等等。不向cocos,白鷺等是一個大生態全家桶,phaser很靈活,很容易插入到現有項目中。我以前深刻使用過一段時間,怎麼碩呢,若是你是我的玩票性質想寫點有意思的小東西仍是很推薦的,官方例子不少,照着例子就能拼出一個不錯的遊戲。可是若是要重度使用,作一個功能複雜,大而全的遊戲,仍是不推薦了,由於他的文檔實在是太太太太爛了,我摸索了很久才弄明白它那自動生成的文檔應該怎麼看。還有就是一個隱藏bug,遇到了真是很難繞過去,好比cpu佔用太高、資源清理不掉、切換場景時候全局註冊插件失效、第三方插件的兼容等等。還有phaser生態不行,官方論壇發帖量少的可憐。另外phaser4立刻要出了,估計又是一次斷代更新。。。html

爲何要寫這個庫?
由於phaser寫一個小動效真的比較麻煩。
1.動效無非就是對元素進行縮放、位移、漸變。只要這三個變量組合得當就能夠得出舒服的效果,咱們要本身寫,沒有專業的ui、ue來幫咱們走查,很難控制好時間和幅度,而animte.css中的全部動畫,若是你讀了一下源碼,就知道必定是一個專業的動效師設計的。時間都精確到了小數點後兩位,位移曲線也不是用的css默認提供的那些。
2.phaser是純js的。用css寫一個左右晃動的動畫很簡單,只須要寫簡單幾行便可前端

@keyframes shake{
    0%{ transform: translateX(-10px); }
    100%{ transform: translateX(10px); }
}
.shake{
    animation: shake 1s ease;
}

而phaser一個gameObject沒有基於自己的座標,咱們要基於世界座標來進行位移。而且也沒有提供不少默認的量供選擇,要進行手動轉換,好比translateX就須要對x座標進行改變,translateY須要對y座標進行改變,rotate須要改變angle值。java

實現步驟
1.對animate.css中全部css文件進行遍歷轉換爲js對象,我寫了一個postCSS插件來實現這個功能。
好比bounce動畫本來是這樣的git

@keyframes bounce {
  from,
  20%,
  53%,
  to {
    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    transform: translate3d(0, 0, 0);
  }

  40%,
  43% {
    animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
    transform: translate3d(0, -30px, 0) scaleY(1.1);
  }

  70% {
    animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
    transform: translate3d(0, -15px, 0) scaleY(1.05);
  }

  80% {
    transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    transform: translate3d(0, 0, 0) scaleY(0.95);
  }

  90% {
    transform: translate3d(0, -4px, 0) scaleY(1.02);
  }
}

.bounce {
  animation-name: bounce;
  transform-origin: center bottom;
}

轉換完是這樣的github

module.exports = {
    "common": {
        "animation-name": "bounce",
        "transform-origin": "center bottom"
    },
    "list": {
        "0": [
            {
                "animation-timing-function": "cubic-bezier(0.215, 0.61, 0.355, 1)"
            },
            {
                "transform": "translate3d(0, 0, 0)"
            }
        ],
        "20": [
            {
                "animation-timing-function": "cubic-bezier(0.215, 0.61, 0.355, 1)"
            },
            {
                "transform": "translate3d(0, 0, 0)"
            }
        ],
        "40": [
            {
                "animation-timing-function": "cubic-bezier(0.755, 0.05, 0.855, 0.06)"
            },
            {
                "transform": "translate3d(0, -30px, 0) scaleY(1.1)"
            }
        ],
        "43": [
            {
                "animation-timing-function": "cubic-bezier(0.755, 0.05, 0.855, 0.06)"
            },
            {
                "transform": "translate3d(0, -30px, 0) scaleY(1.1)"
            }
        ],
        "53": [
            {
                "animation-timing-function": "cubic-bezier(0.215, 0.61, 0.355, 1)"
            },
            {
                "transform": "translate3d(0, 0, 0)"
            }
        ],
        "70": [
            {
                "animation-timing-function": "cubic-bezier(0.755, 0.05, 0.855, 0.06)"
            },
            {
                "transform": "translate3d(0, -15px, 0) scaleY(1.05)"
            }
        ],
        "80": [
            {
                "transition-timing-function": "cubic-bezier(0.215, 0.61, 0.355, 1)"
            },
            {
                "transform": "translate3d(0, 0, 0) scaleY(0.95)"
            }
        ],
        "90": [
            {
                "transform": "translate3d(0, -4px, 0) scaleY(1.02)"
            }
        ],
        "100": [
            {
                "animation-timing-function": "cubic-bezier(0.215, 0.61, 0.355, 1)"
            },
            {
                "transform": "translate3d(0, 0, 0)"
            }
        ]
    }
}

插件代碼在這裏web

2.得到了包含css屬性的對象後,就須要寫一個轉換的映射關係,將每一個css屬性和對應的值解析爲phaser中tween動畫支持的參數,而後調用tween動畫來實現
映射關係代碼在這裏
此處有幾個小難點。一是不少動畫的timingFunc是二次貝塞爾曲線,須要使用bezier-easing這個庫來計算,才能保證動畫速率保真。二是有些屬性想要轉換比較困難,我尚未想怎麼去作(主要是懶)。已知的有transform-originskew,由於phaser的實例中沒有關於這兩個屬性的概念。因此要本身手動實現。
3.關於結束狀態,是forwards仍是backwards要注意。npm

使用
DEMOcanvas

NPM

相關文章
相關標籤/搜索