Set viewport to show current selection?

Is there a command to have the viewport zoom in or zoom out to show the current selection?

1 Like

This seems to work:

/**
 * Scroll artboards into view. May also work with scene nodes
 * @param {Array} artboards array of artboards to scroll to
 * @param {Boolean} zoom option to zoom out or zoom in to fit 
 */
function scrollArtboardsIntoView(artboards, zoom = true) {
	const viewport = require("viewport");
	var x = 0;
	var y = 0;
	var width = 0;
	var height = 0;
	
	for (let index = 0; index < artboards.length; index++) {
		const artboard = artboards[index];

		if (artboard.globalBounds.x<x) {
			x = artboard.globalBounds.x;
		}
		if (artboard.globalBounds.y<y) {
			y = artboard.globalBounds.y;
		}
		if (artboard.globalBounds.x+artboard.globalBounds.width>width) {
			width = artboard.globalBounds.x+artboard.globalBounds.width;
		}
		if (artboard.globalBounds.y+artboard.globalBounds.height>height) {
			height = artboard.globalBounds.y+artboard.globalBounds.height;
		}
	}

	viewport.scrollIntoView(x, y, width, height);

	if (zoom) {
		viewport.zoomToRect(x, y, width, height);
	}
}
2 Likes

Thanks, that’s useful!

1 Like

This one seems to work for scene nodes

/**
 * Scroll scene nodes into view
 * @param {Array} sceneNodes array of scene nodes to scroll to
 * @param {Boolean} zoom option to zoom out or zoom in to fit 
 */
function scrollSceneNodesIntoView(sceneNodes, zoom = true) {
	const viewport = require("viewport");
	var x = 0;
	var y = 0;
	var width = 0;
	var height = 0;
	var nodeX = 0;
	var nodeY = 0;
	var nodeWidth = 0;
	var nodeHeight = 0;
	var artboard = null;
	
	for (let index = 0; index < sceneNodes.length; index++) {
		/** @type {SceneNode} */
		const sceneNode = sceneNodes[index];

		nodeX = sceneNode.globalBounds.x;
		nodeY = sceneNode.globalBounds.y;
		nodeWidth = sceneNode.globalBounds.x + sceneNode.globalBounds.width;
		nodeHeight = sceneNode.globalBounds.y + sceneNode.globalBounds.height;

		if ((sceneNode instanceof Artboard)==false) {
			var parent = sceneNode.parent;

			while (parent!=null) {

				if (parent instanceof Artboard) {
					artboard = parent;
					nodeX += artboard.globalBounds.x;
					nodeY += artboard.globalBounds.y;
					nodeWidth += artboard.globalBounds.x+artboard.globalBounds.width;
					nodeHeight += artboard.globalBounds.y+artboard.globalBounds.height;
					break;
				}
				else {
					parent = parent.parent;
				}
			}
		}

		if (nodeX<x) {
			x = nodeX;
		}
		if (nodeY<y) {
			y = nodeY;
		}
		if (nodeWidth>width) {
			width = nodeWidth;
		}
		if (nodeHeight>height) {
			height = nodeHeight;
		}
	}

	//log("",{x:x, y:y, width:width, height:height});

	viewport.scrollIntoView(x, y, width, height);

	if (zoom) {
		viewport.zoomToRect(x, y, width, height);
	}
}
2 Likes

FYI If the view is not scrolled correctly you may need to zoom first and then scroll. In other words switch the last two statements:

if (zoom) {
	viewport.zoomToRect(x, y, width, height);
}

viewport.scrollIntoView(x, y, width, height);

Haven’t had a chance to spend more time on this but it didn’t work as expected a few times and I think it was for this reason.

Do you have to have permission to use scroll into view?

Plugin Error: Plugin is not permitted to make changes from the background. Use editDocument() for panel UI handlers, or return a Promise to extend an edit operation asynchronously.
    at convertPluginErrorToString (plugins/PluginErrorUtil.js:1:198)
    at safeGetStackTrace (plugins/PluginErrorUtil.js:1:339)
    at internalFormatPluginError (plugins/PluginErrorUtil.js:1:1073)
    at internalReportPluginError (plugins/PluginErrorUtil.js:1:1171)
    at Object.reportPluginError (plugins/PluginErrorUtil.js:1:1680)
    at Object.checkAllowedToEdit (plugins/ScenegraphGuard.js:1:1676)
    at Object.t.zoomToRect (plugins/ViewportWrapper.js:1:778)
    at scrollSceneNodesIntoView ()
Plugin Error: Plugin is not permitted to make changes from the background. Use editDocument() for panel UI handlers, or return a Promise to extend an edit operation asynchronously.
    at convertPluginErrorToString (plugins/PluginErrorUtil.js:1:198)
    at safeGetStackTrace (plugins/PluginErrorUtil.js:1:339)
    at internalFormatPluginError (plugins/PluginErrorUtil.js:1:1073)
    at internalReportPluginError (plugins/PluginErrorUtil.js:1:1171)
    at Object.reportPluginError (plugins/PluginErrorUtil.js:1:1680)
    at Object.checkAllowedToEdit (plugins/ScenegraphGuard.js:1:1676)
    at Object.t.scrollIntoView (plugins/ViewportWrapper.js:1:300)
    at scrollSceneNodesIntoView ()

It looks like it accepts a scene node as an argument.

https://adobexdplatform.com/plugin-docs/reference/viewport.html#viewport

Here’s an updated to include support for single selection and multiple selected items:

/**
 * Scroll scene nodes into view
 * @param {SceneNode|Array} sceneNodes a scene node or an array of scene nodes to scroll to
 * @param {Boolean} zoom option to zoom out or zoom in to fit 
 */
 function scrollSceneNodesIntoView(sceneNodes, zoom = true) {
	const viewport = require("viewport");
	var x = 0;
	var y = 0;
	var width = 0;
	var height = 0;
	var nodeX = 0;
	var nodeY = 0;
	var nodeWidth = 0;
	var nodeHeight = 0;
	var artboard = null;
 	var isArray = Array.isArray(sceneNodes);
	var items = sceneNodes && isArray==false ? [sceneNodes] : sceneNodes.concat();
	
	for (let index = 0; index < items.length; index++) {
		/** @type {SceneNode} */
		const sceneNode = items[index];

		nodeX = sceneNode.globalBounds.x;
		nodeY = sceneNode.globalBounds.y;
		nodeWidth = sceneNode.globalBounds.x + sceneNode.globalBounds.width;
		nodeHeight = sceneNode.globalBounds.y + sceneNode.globalBounds.height;

		if ((sceneNode instanceof Artboard)==false) {
			var parent = sceneNode.parent;

			while (parent!=null) {

				if (parent instanceof Artboard) {
					artboard = parent;
					nodeX += artboard.globalBounds.x;
					nodeY += artboard.globalBounds.y;
					nodeWidth += artboard.globalBounds.x+artboard.globalBounds.width;
					nodeHeight += artboard.globalBounds.y+artboard.globalBounds.height;
					break;
				}
				else {
					parent = parent.parent;
				}
			}
		}

		if (nodeX<x) {
			x = nodeX;
		}
		if (nodeY<y) {
			y = nodeY;
		}
		if (nodeWidth>width) {
			width = nodeWidth;
		}
		if (nodeHeight>height) {
			height = nodeHeight;
		}
	}

  if (items.length==1) {

    if (zoom) {
      viewport.zoomToRect(items[0]);
    }
  
    viewport.scrollIntoView(items[0]);
  }
  else {

    if (zoom) {
      viewport.zoomToRect(x, y, width, height);
    }
  
    viewport.scrollIntoView(x, y, width, height);
  }
}

Shouldn’t need any permissions; sounds like it’s part of the edit document check – not sure why that would be. @DavidXD Any reason why scrolling the viewport should have to be part of editDocumetn()?