Using Google application script, I am generating a grid with selected elements. In this example below - I gave input rows 2 and columns 3 to generate the order of the grid. My logic seems to be the production of wrong rows and columns.
Issue : number of rows and columns are wrong.
function grid() {
var selection = SlidesApp.getActivePresentation().getSelection();
var pageElements = selection.getPageElementRange().getPageElements();
//init
var numRows = 2;
var horizontalSpace = 5;
var numColumns = 3;
var verticalSpace = 10;
/*get Left, Top, width, height of ist shape.*/
var shape0Left = pageElements[0].asShape().getLeft(),
shape0Top = pageElements[0].asShape().getTop(),
shape0Width = pageElements[0].asShape().getWidth(),
shape0Height = pageElements[0].asShape().getHeight();
/*Set the element properties*/
var elemLeft = shape0Left,
elemTop = shape0Top,
elemWidth = 0,
elemHeight = 0;
/*Iterate the page selected elements*/
pageElements.forEach(function(item, index) {
pageElements[index]
.asShape()
.setLeft(elemLeft)
.setTop(elemTop);
/*Something wrong with the logic*/
if ((index + 1) % numRows == 0) {
/*update the properties of each shape to place in row column order */
elemTop = shape0Top + pageElements[index].asShape().getHeight() + 10;
elemLeft = shape0Left;
} else {
elemLeft = shape0Left + pageElements[index].asShape().getWidth() + 10;
}
});
}
Coming Result
Expected output:
With the strategy you are taking, you should update the elemTop
and elemLeft
variables using the +=
operator to be sure to include the old value where appropriate.
Also, you've set these nice verticalSpace
and horizontalSpace
constants; use them!
If you need to break out of the element loop early because you only want to manipulate the first 6 elements, you cannot use forEach
on the entire array (at least not without a if (index >= 6) return;
guard). You can just loop through with a regular for
loop and test that i < rumRows * numColumns
, or you can get just the first n elements with pageElements.slice(0, n)
and use forEach
on that array.
Lastly, the way you have set this up we need to check if we are at the last column or not. To check the current column number (zero indexed), you can use var col = i % numColumns
.
With a for
loop:
/*Iterate the page selected elements*/
for (var i = 0; i < numRows * numColumns; ++i) {
pageElements[i].asShape().setLeft(elemLeft).setTop(elemTop);
var col = i % numColumns;
if ((col+1) % numColumns == 0) {
elemTop += pageElements[i].asShape().getHeight() + verticalSpace;
elemLeft = shape0Left;
} else {
elemLeft += pageElements[i].asShape().getWidth() + horizontalSpace;
}
}
Using slice
and forEach
:
pageElements.slice(0, numRows * numColumns).forEach(function(item, index){
item.asShape().setLeft(elemLeft).setTop(elemTop);
var col = index % numColumns;
if ((col+1) % numColumns == 0) {
elemTop += item.asShape().getHeight() + verticalSpace;
elemLeft = shape0Left;
} else {
elemLeft += item.asShape().getWidth() + horizontalSpace;
}
});