2011-04-29 37 views
7

這更像是一個數學相關的問題。JavaScript:自動對角線排列可變多維數組

我試圖用jQuery創建一個可愛的衰落效果,通過拆分一定數量的塊中的一個元素,然後淡化其中的每一個,但延遲基於另一個數組的衰落效果。

所以創建塊表我有兩個變量:

var rows = 4, 
    cols = 10; 

這將劃分元素到像塊:

   0 1 2 3 4 5 6 7 8 9 
      10 11 12 13 14 15 16 17 18 19 
      20 21 22 23 24 25 26 27 28 29 
      30 31 32 33 34 35 36 37 38 39 

然後我創建另一個陣列,其決定如何塊將動畫。例如,對於一個左到右對角線動畫此陣看起來像:

order = [0, 10, 1, 20, 11, 2, 30, 21, 12, 3, 31, 22, 13, 4, 32, 23, 14, 5, 33, 24, 15, 6, 34, 25, 16, 7, 35, 26, 17, 8, 36, 27, 18, 9, 37, 28, 19, 38, 29, 39]; 

,併爲它的工作原理是特定的情況下:d

我的問題是我怎麼能自動創建order陣列,不是手動的,基於塊的數量(行x列),哪些可以改變?

謝謝

+0

它會始終是從左到右的對角動畫嗎? – Diego 2011-04-29 14:46:24

+0

不,我想也做這個r-t-l對角線,或者從中心等旋轉。但是現在我想知道我該怎麼做這個案例,l-t-r對角線 – Alexandra 2011-04-29 14:49:04

回答

4

這將做到這一點:

var arr = []; 

var rows = 4; 
var cols = 10; 

for(var i = 0; i < rows + cols - 1; i++){ 

    for(var j = Math.min(rows, i + 1) - 1; j >= Math.max(0, i - cols + 1); j--){ 
     arr.push((j * cols) + i - j); 
    } 

} 

小提琴:http://jsfiddle.net/BmXpy/

編輯:這是我在解釋我是如何想出了這樣的嘗試。重要的是,使用上面的數字表來可視化,如果需要,打印它並繪出對角線。

首先,想想我們想要什麼,它基本上是對角線。在上面的例子中,第一個對角線是0,然後是10,1,然後是20,11,2,然後是30,21,12,3等等。現在,如果您考慮有多少對角線,那麼它就是rows + cols - 1。那就是我們得到第一個循環的地方:

for(var i = 0; i < rows + cols - 1; i++){ 

現在,忽略第二個邊界。在一般情況下(整個中心),每個對角線都是「行」。由於我們想要自下而上,我們需要一個反向循環。這看起來像這樣的內部循環:

for(var j = rows - 1; j >= 0; j--){ 

現在,我們必須處理這兩個邊界(左和右)。

對於左邊界,如果我們查看長度小於「行」的對角線數,我們將看到它是rows - 1。對於這些對角線,我們會看到每個對角線的長度爲i + 1。下面的內循環將處理一般情況下和左boundry:

for(var j = Math.min(rows, i + 1) - 1; j >= 0; j--){ 

你會看到,對角0,這將運行一次,1它將運行兩次,等。而對於一般情況(i >= rows )它會運行「行」次。

現在,右邊界。如果我們看右側的哪條對角線比「行」短,我們將會看到它的所有對角線都大於「cols」(在cols爲10,0索引的情況下,即10行及以後)。替換j >= 0j >= Math.max(0, i - cols + 1)將針對一般情況和左邊界運行至0,但縮短右邊界。我們得到這個:

for(var j = Math.min(rows, i + 1) - 1; j >= Math.max(0, i - cols + 1); j--){ 

最後,實際計算每個位置的數字。 i代表對角線,j代表對角線上的數字索引j = 0如果您正在查看張貼的數字表格,它是最大的數字。對於j = 0(最上面一行數字),數字只是i,對於頂部以下的每一行,我們需要將數字乘以「cols」以便直接得到第一行數字之下的數字,那麼數字需要是調整到左邊。這通過減去作爲行號的j來完成。因此,對於j = 1(第二行),我們需要將數字左移1(減1)。所以我們有i作爲第一行的水平位置,+ (j * cols)將它向下移動到合適的行,然後-j將其調整爲對角線(如果您繪製了對角線,請找出它們中的一個以獲得良好的效果視覺)。我們得到這個:

(j * cols) + i - j 

把它放在一起,你得到我的最終代碼上面。希望這是有道理的。

+0

輝煌..太好了! – 2011-04-29 15:25:57

+0

@kingjiv:非常好!順便說一下,建議使用'[]'而不是'Array()' – Diego 2011-04-29 15:33:29

+0

美麗!但請解釋對我來說,我完全失去了'我 Alexandra 2011-04-29 15:46:47

1

這裏還有另外一個代碼http://jsfiddle.net/paska/FhLnu/3/

var rows = 4, 
    cols = 10, 
    getValue = function(x, y) { 
     return (y * cols) + x; 
    }, 
    addValue = function(x, y) { 
     $("#arr").append(getValue(x, y) + ", "); 
    }, 
    max = rows + cols - 1, 
    updateRow = 0; 

for(var i = 0; i < max; i++) { 
    if(i >= rows) 
     updateRow++; 
    for(var x = 0; x <= i; x++) { 
     //$("#arr").append(x + " " + (i - x) + "<br />"); 
     var row = (i - x), 
      col = x; 
     if(updateRow) { 
      row = row - updateRow; 
      col = col + updateRow; 
     } 
     if(col >= cols) 
      break; 
     if(row >= 0 && col >= 0) 
      addValue(col, row); 
    } 
} 

我知道@kingjiv代碼的工作,我只是想補充這樣做的另一種方式。

2

另一種方式來做到這一點。

function diagonalized_block (rows, cols) { 
    blocks = []; 
    for (var i = 0; i < rows * cols; i++) { 
     blocks.push(i); 
    } 
    blocks.sort(function (a, b) {return a/cols + a%cols - b/cols - b%cols}); 
    return blocks; 
} 

這個想法很簡單。寫出所有塊的明顯數組,然後按照您想要的順序升序的塊的函數進行排序。該功能是x/cols + x%cols。這是row + ascending error on diagonal + col。所以你首先根據對角線對其進行排序,然後在對角線上上升。

對於其他模式,您將不得不尋找正確排序的其他函數。 (或者寫一個更加複雜的排序函數,它完全符合你想要做的事情。)