2012-08-09 79 views
-2

我試圖找到一個JavaScript庫來動畫像done here這樣的元素。請看看介紹,然後從頂部菜單應用一些過濾器,並嘗試調整瀏覽器窗口的大小。Mountain Dew網站上的元素動畫是如何完成的?

我沒有找到任何能完成像這樣的流體佈局的任何東西。那裏使用的那種動畫是否有名字?你知道它是如何被編碼的嗎?

+2

該頁面上只包含一個JavaScript文件,並且它包含所有包含的庫的列表:http://mountaindew.com/js/main.js – JJJ 2012-08-09 21:07:15

+0

我知道,但它是否存在任何庫在應用過濾器時做塊動畫? – fliim 2012-08-09 21:27:01

+2

你可以試着對你說的話有點模糊嗎? – dqhendricks 2012-08-09 21:30:16

回答

0

不能,要在瀏覽器調整大小時具有自動佈局功能,也可以在觸摸設備上使用,請使用this plugin here。那麼,MTN的東西是一塊蛋糕。這個插件可以製作動畫,隨機播放並做出一些動作,但您也可以對它進行排序和過濾。

13

我是Mountain Dew site的主要開發人員。我從頭開始編碼整個過濾和網格邏輯,但Isotope是一個很好的通用庫,可以完成您想要的任務。我沒有使用它,因爲我有很多特定的需求(主要原因是因爲我點擊一個項目後不得不拆分網格)。以下簡要說明Mountain Dew網站上的網格如何工作以及如何完成排序。

如果所有項目都具有相同的大小,則邏輯非常簡單,您只需要計算一條線上可以放置多少個項目並相應地定位它們。

var nCols = Math.floor(lineSize/itemWidth); 

如果項目有不同的大小,你可能需要一些packing algorithm但對於這種情況,因爲我知道可能的大小,它們都符合同一電網(1×1,×2,2×2,3×2),他們有亂它們之間的間距(沒有重疊),並且我們還有一些關於產品和促銷位置的非常具體的規則,我必須編寫我自己的算法。我做了一個簡單的解釋(大致爲bin packing first-fit algorithm):

  1. 獲取瀏覽器窗口的尺寸。
  2. 檢查我們可以有多少列。
  3. 從數組中獲得一個隨機項。
  4. 將其插入當前行的下一個可用bin
  5. 如果它不能適合當前行,我們將創建新行,直到我們有足夠的分檔以適合該項目。
  6. 根據需要重複步驟3至5多次。

有關激浪網格一些注意事項:

  • 瓶不能插入彼此相鄰。
  • 如果一個存儲桶被標記爲接管它應該位於網格頂部。
  • 過濾掉的物品應該放到網格的底部。
  • 任何過濾器應用後接管和瓶子可能放置在網格上的任何地方。
  • 如果它是網格的最後一行,我們沒有更多的物品,瓶子可以彼此相鄰(避免創建不必要的行)。
  • 瓶子應該均勻分佈在網格上,但是在僞隨機位置。
  • 網格上的瓶子數量與網格上的物品數量相關(每12個物品大約1個)。
  • 項目應該是隨機間隔的,並應儘可能避免重疊(這使得比項目像普通網格定位更難)。

排序是有穩定排序做 - Array#sort不是在v8穩定,所以I implemented a merge sort這是穩定的。只需通過陣列上的所有項目需要循環並執行以下操作:

//native array sort isn't stable on chrome so we use amd-utils instead 
grid.items = sort(grid.items, function(item, next){ 
    // move inactive items to the end of list 
    // if return zero it keeps items at the same relative position 
    if (next.active) { 
     return (item.active)? 0 : 1; 
    } else { 
     return (item.active)? 0 : -1; 
    } 
}); 

後,我們決定項目應該如何排序,這只是一個尋找項目的適當位置,並設置element.style.top和事element.style.left

// positioning can be calculated based on item index if all items have 
// same size. not same logic used on mdew since on mdew we have a 
// random gutter between items and they shouldn't overlap each other 
var colIndex = itemIndex % (nCols - 1); 
var rowIndex = Math.floor(itemIndex/nCols); 
var destX = colIndex * colWidth; 
var destY = rowIndex * rowHeight; 

如果瀏覽器支持CSS轉換和所有項目具有相同的延遲/持續時間,我們可以設置樣式表的動畫:

.grid-item { 
    -webkit-transition: all 500ms ease; 
     -moz-transition: all 500ms ease; 
      transition: all 500ms ease; 
} 

但在激浪網站,因爲我們需要爲每個項目隨機延遲和持續時間(因爲它看起來更好),我使用JavaScript設置過渡:

function randomizeSpeed(){ 
    var delayProp = vendorPrefix.style('transitionDelay'); 
    var durationProp = vendorPrefix.style('transitionDuration'); 
    $('.grid-item').each(function(i, el){ 
     var duration = rand(SLOWEST_TRANSITION, FASTEST_TRANSITION); 
     var delay = map(duration, FASTEST_TRANSITION, SLOWEST_TRANSITION, MIN_DELAY, MAX_DELAY); 
     if (delayProp) { 
      el.style[delayProp] = delay +'s'; 
      el.style[durationProp] = duration +'s'; 
     } else { 
      // store delay/duration for JS fallback 
      $(el).data({ delay: delay, duration: duration }); 
     } 
    }); 
} 

在上面的代碼,我使用的方法math/maprandom/randamd-utils。我還有一些代碼可用於根據功能檢測獲取供應商前綴樣式屬性(mozTransitionDelay,webkitTransitionDelay,transitionDelay)。如果瀏覽器不支持CSS轉換我退卻到一些JavaScript做動畫:

if (USE_TRANSFORM && USE_TRANSITION) { 
    el.css({translateY: destY, translateX: destX}); 
} else if (USE_TRANSITION) { 
    el.css({top: destY, left: destX}); 
} else { 
    TweenLite.to(el, el.data('duration'), { 
     css : { top : destY, left: destX }, 
     delay : el.data('delay'), 
     ease : Expo.easeOut 
    }); 
} 

我刪除了過渡動畫在IE 7-8,由於性能,網格元素過於複雜,我們有太多許多項目。

0

不是,山。露水代碼更好。同位素將在網格中間留下孔。特別是如果你的細胞像山一樣隨機放置在一起。露。