Как я могу группировать и анимировать отдельные строки на этом полотне Рафаэля? - PullRequest
0 голосов
/ 16 ноября 2011

Следующий код создает сетку 10 x 15 из квадратов по 40 пикселей. Я хотел бы иметь возможность сгруппировать квадраты в ряды для анимации позже. В частности, я хочу анимировать строки, падающие на дно, а затем применить к ним анимированные преобразования матрицы. В конце концов они просто скопируют ту же сетку в новом месте.

 <script type="text/javascript">

    var squares = [];
    var paperHeight = 600;
    var paperWidth = 400;
    var squareSize = 40;

    var cols = paperWidth / squareSize;
    var rows = paperHeight / squareSize;

    var paper = Raphael($("#grid-test")[0],paperWidth,paperHeight);
        for (var i = 0; i < cols; i++) {
            // Begin loop for rows
            for (var j = 0; j < rows; j++) {

              // Scaling up to draw a rectangle at (x,y)
              var x = i * squareSize;
              var y = j * squareSize;

              // For every column and row, a square is drawn at an (x,y) location 
              paper.rect(x,y,squareSize,squareSize); 
            }
        }

</script>

Ответы [ 2 ]

2 голосов
/ 16 ноября 2011

Вы можете отслеживать элементы с помощью двумерного массива [row][column]. Затем выполните итерацию по каждому столбцу в строке, чтобы получить соответствующие элементы; тогда просто оживите их. Обратите внимание, что вам нужно поменять местами i / j при булдинге; в настоящее время вы строите [column][row].

http://jsfiddle.net/7ncHM/

var rowsArr = [];

for (var i = 0; i < cols; i++) {
    // Begin loop for rows
    rowsArr[i] = [];

    for (var j = 0; j < rows; j++) {

      // Scaling up to draw a rectangle at (x,y)
      var x = j * squareSize; // swap i/j
      var y = i * squareSize;

      // For every column and row, a square is drawn at an (x,y) location 
      rowsArr[i][j] = paper.rect(x,y,squareSize,squareSize);
      // draw and store directly, isn't that elegant? :)
    }
}

function animateRow(i) {
    var row = rowsArr[i];
    for(var j = 0; j < row.length; j++) { // iterate elements in row
        row[j].animate({y: 400}, 2000);
    }
}

animateRow(2);
2 голосов
/ 16 ноября 2011

Вам будет трудно анимировать отдельные строки, если вы не сохраните ссылку на квадраты, составляющие строку (предположительно, для этого используется неиспользуемый массив squares[] ...)

Каждый раз, когда вы вызываете paper.rect, присваиваете результат элементу в squares[]

. Тогда у вас может быть функция, которая берет данную строку вашего массива и применяет .animate Рафаэля к каждому квадрату, создавая впечатлениеанимации всего ряда.

http://raphaeljs.com/reference.html#Element.animate

В ответ на ваш комментарий - вы можете добавить элементы к Рафаэлю set, а затем анимировать set -eg ...

var squares = [];
var paperHeight = 600;
var paperWidth = 400;
var squareSize = 40;

var cols = paperWidth / squareSize;
var rows = paperHeight / squareSize;

var paper = Raphael($("#grid-test")[0],paperWidth,paperHeight);

var rowSets = [];

// *** GRID CONSTRUCTION CODE STARTS ***///
// I have swapped the usage of i and j within the loop so that cells
// in a row are drawn consecutively. 
// Previously, it was column cells which were drawn
// consecutively
for (var i = 0; i < rows; i++) {
    //create a new set which will hold this row
    rowSets[i] = paper.set();
    squares[i] = [];

    // Begin loop for cells in row
    for (var j = 0; j < cols; j++) {

      // Scaling up to draw a rectangle at (x,y)
      var x = j * squareSize;
      var y = i * squareSize;

      // For every column and row, a square is drawn at an (x,y) location 
      var newRect = paper.rect(x,y,squareSize,squareSize); 
      // add the new cell to the row
      rowSets[i].push(newRect);
      squares[i][j] = newRect;
    }
}
// *** GRID CONSTRUCTION CODE ENDS ***

squares[5][5].attr({fill : '#f00'});            // colour an individual cell
rowSets[6].attr({fill : '#00f'});               // colour an entire row                 
rowSets[6].animate({y : 10 * squareSize},400);  // animate an enitre row

Это означает, что вы можете построить set строк (и столбцов) и анимировать их как отдельные единицы.

ОБНОВЛЕНИЕ

* * * Как Рафаэль set - это просто способ объединения элементов, чтобы обеспечить простой способ массового применения операций. не работает так же, как, например, "Группа" в Visio - т.е. они все еще являются отдельными элементами и будут анимированы независимо.

Рафаэль не найдет центр set, чтобы сделать вращение вокруг.Каждый элемент набора будет вращаться вокруг своего центра.

Эту проблему можно решить с помощью path, чтобы определить всю строку сразу как путь SVG.Однако это означает, что строки теперь являются «одной сущностью», и вам будет трудно обратиться к одной ячейке или одному столбцу.Однако вы можете переключить отдельные ячейки на «путь строки» перед выполнением преобразования.Пользователь / игрок, надеюсь, не заметит.

Вы можете заменить код // *** GRID CONSTRUCTION *** следующим кодом, чтобы построить строки в виде путей ... (JSFiddle Demo)

//Build a row path - this path will be used as the basis of all the rows
var sPath = "lpw 0 l0 sq l-pw 0 l0 -sq " //outline of the whole row
for (var cell = 1; cell < cols; cell++){
    sPath += "msq 0 l0 sq Z ";           //insert an "upright" cell separator
};    
sPath = sPath.replace(/sq/g,squareSize).replace(/pw/g,paperWidth);

//we have no 'for' loop for columns now as we are creating entire row .paths
for (var j = 0; j < rows; j++) {

    //we apply the 'M' (Move) offset here to the beginning of the path
    //This is simply to adjust the Y-offset of the start of the path
    //ie to put the the path in a new row position
    rowSets[j] = paper.path("M0 " + j * squareSize + sPath); 
}
...