Is there any way to control guides (rules of third) in a Google Slides presentation. As far as I have read the Google Apps Script documentation, there is no method to control the guides.
I already tried lines that would behave like guides (rules of third), but these are not "real" guides. The user can delete these lines, and these lines are limited to the slide page area.
See the picture to get the difference between lines and guides (rules of third):
To enable the guides (rules of third) go here:
A feature request to allow guides to be controlled via
SlidesApp
or Slides API is submitted to the issue tracker. Please star it if you find that the feature would be useful.
Short answer
As already mentioned, unfortunately, this is not currently possible either via the SlidesApp
service or the Slides API.
Workaround
It is actually possible to make lines stretch outside of the slide bounds by passing a negative integer as an argument of insertLine
. As for being able to delete the lines, guides can also be "deleted" by user if they drag the guide out of the slide boundaries.
The only property of the guides that I could not emulate is hiding them when presenting (as real guides are hidden).
Below is a workaround similar to your approach (creating a grid of Line
s):
Guides
/**
* @summary emulates adding guides to the Slide
*
* @param {{
* rows : (number|1),
* deleteOld : (boolean|true),
* cols : (number|1),
* color : string
* }}
*/
const showGuides = ({ deleteOld = true, rows = 1, cols = 1, color = "#d3d3d3" } = {}) => {
const presentation = SlidesApp.getActivePresentation();
const currPage = presentation.getSelection().getCurrentPage();
const prop = "guides";
const store = PropertiesService.getUserProperties();
/** @type {string[]} */
let guideRefs = JSON.parse(store.getProperty(prop) || "[]");
const lines = currPage.getLines();
const oldLines = lines.filter((line) => guideRefs.includes(line.getObjectId()));
if (deleteOld) {
oldLines.forEach(line => line.remove());
guideRefs = removeElements(guideRefs, oldLines.map(l => l.getObjectId()));
}
const currWidth = presentation.getPageWidth();
const currHeight = presentation.getPageHeight();
const xStep = Math.floor(currWidth / cols);
const yStep = Math.floor(currHeight / rows);
const newGuides = [];
const maxScreen = 4096;
for (let x = 0; x <= cols; x++) {
const line = currPage.insertLine(
SlidesApp.LineCategory.STRAIGHT,
xStep * x, -maxScreen, xStep * x, currHeight + maxScreen
);
const fill = line.getLineFill();
fill.setSolidFill(color);
const oid = line.getObjectId();
guideRefs.push(oid);
newGuides.push(line);
}
for (let y = 0; y <= rows; y++) {
const line = currPage.insertLine(
SlidesApp.LineCategory.STRAIGHT,
-maxScreen, yStep * y, currWidth + maxScreen, yStep * y
);
const fill = line.getLineFill();
fill.setSolidFill(color);
const oid = line.getObjectId();
guideRefs.push(oid);
newGuides.push(line);
}
store.setProperty(prop, JSON.stringify(guideRefs));
};
Utilities
/**
* @summary removes elements from an array
* @param {any[]} arr
* @param {...any} elems
* @returns {any[]}
*/
const removeElements = (arr, ...elems) => arr.filter((elem) => !elems.includes(elem));
Demo