Skip to main content
Legend
February 8, 2023
Answered

[ExtendScript] Moving an artboard to the center of a canvas

  • February 8, 2023
  • 2 replies
  • 1065 views

I would like to move one artboard at the edge of Illustrator's largest area (the canvas) to the center along with its contents via scripting. Is there a clever way to do this?

 

I currently have the following two algorithms in mind and have been successful in getting them to work.

 

  1. Patiently move the items using a method of getting the canvas coordinates developed by OMOTI

     

  2. Generate temporary artboards before and after the target artboard, center them with Document.rearrangeArtboards, and then delete the temporary artboards

     

var doc = app.documents[0] ;
var docArtboards = doc.artboards ;
var targetArtboard = docArtboards[0] ;
var rect = [0, 0, 1, -1] ;
var tempArtboards = [docArtboards.add(rect), docArtboards.add(rect)] ;

doc.rearrangeArtboards(DocumentArtboardLayout.Row) ;
for(var i = tempArtboards.length - 1 ; i >= 0 ; i--) {
  tempArtboards[i].remove() ;
}

 

However, these methods have the following problems.

  • Opacity masks do not follow the move (1)
  • Document with width and height of 16383 pt will stop with an error (2)
  • If not careful about the position of the temporary artboard, the artboard to which PageItem belongs changes, causing an unintended move (2)

 

Conditions:

  • Support Illustrator CS6 (16) through Illustrator 2023 (27)
  • Always only one artboard in a document
This topic has been closed for replies.
Correct answer femkeblanco

I think the only way to move opacity masks is with copy and paste. This is an experiment to do that (the drawback of which is that grouping will move all the items to one layer).

 

var doc = app.activeDocument;
var ABs = doc.artboards;
doc.selectObjectsOnActiveArtboard();
app.executeMenuCommand("group");
var bounds = app.selection[0].geometricBounds;
var ABR = ABs[0].artboardRect;
var w = bounds[2] - bounds[0];
var h = bounds[3] - bounds[1];
var dx = w / 2 + (bounds[0] - ABR[0]);
var dy = h / 2 + (bounds[1] - ABR[1]);
app.cut();
var ABR0 = -doc.width / 2;
var ABR1 = doc.height / 2;
var ABR2 = ABR0 + doc.width;
var ABR3 = ABR1 - doc.height;
ABs[0].artboardRect = [ABR0, ABR1, ABR2, ABR3];
ABR = ABs[0].artboardRect;
doc.views[0].centerPoint = [ABR[0] + dx, ABR[1] + dy];
app.paste();
app.executeMenuCommand("ungroup");

 

2 replies

sttk3Author
Legend
February 12, 2023

As for opacity masks, that was pretty much the same as this topic in 2016.
Scripts Don’t Move Opacity Masks

 

Thank you for your response. I’ll pick the best answer, but if anyone comes up with ideas beyond these, please post them here at any time.

femkeblanco
femkeblancoCorrect answer
Legend
February 8, 2023

I think the only way to move opacity masks is with copy and paste. This is an experiment to do that (the drawback of which is that grouping will move all the items to one layer).

 

var doc = app.activeDocument;
var ABs = doc.artboards;
doc.selectObjectsOnActiveArtboard();
app.executeMenuCommand("group");
var bounds = app.selection[0].geometricBounds;
var ABR = ABs[0].artboardRect;
var w = bounds[2] - bounds[0];
var h = bounds[3] - bounds[1];
var dx = w / 2 + (bounds[0] - ABR[0]);
var dy = h / 2 + (bounds[1] - ABR[1]);
app.cut();
var ABR0 = -doc.width / 2;
var ABR1 = doc.height / 2;
var ABR2 = ABR0 + doc.width;
var ABR3 = ABR1 - doc.height;
ABs[0].artboardRect = [ABR0, ABR1, ABR2, ABR3];
ABR = ABs[0].artboardRect;
doc.views[0].centerPoint = [ABR[0] + dx, ABR[1] + dy];
app.paste();
app.executeMenuCommand("ungroup");

 

sttk3Author
Legend
February 9, 2023

Set View.centerPoint to wherever desired and paste. Interesting! Thanks for the idea.

 

As for the opacity mask, it can be done with dynamic actions. I am just wondering if there is an easier way to do it. I will be open to ideas for a little while longer.

 

 

function toRealString(num) {
  return num.toFixed(11) ;
}

function toIntegerString(num) {
  return parseInt(Number(num), 10).toString() ;
}

/**
  * Translate selection using action
  *  {Number} deltaX distance to translate in X direction
  *  {Number} deltaY distance to translate in Y direction
  *  {Boolean} transformObject whether to transform the object
  *  {Boolean} transformPattern whether to transform the pattern
  *  {Boolean} withCopying whether to copy
  *  なし
*/
function translateAction(deltaX, deltaY, transformObject, transformPattern, withCopying) {
  var actionCode = '''/version 3
/name [ 31
	5f5f7374746b335f6d696e696d756d417265615f7472616e736c6174655f5f
]
/isOpen 1
/actionCount 1
/action-1 {
	/name [ 9
		7472616e736c617465
	]
	/keyIndex 0
	/colorIndex 0
	/isOpen 1
	/eventCount 1
	/event-1 {
		/useRulersIn1stQuadrant 0
		/internalName (adobe_move)
		/localizedName [ 6
			e7a7bbe58b95
		]
		/isOpen 1
		/isOn 1
		/hasDialog 1
		/showDialog 0
		/parameterCount 5
		/parameter-1 {
			/key 1752136302
			/showInPalette 4294967295
			/type (unit real)
			/value ''' + toRealString(deltaX) + '''
			/unit 592476268
		}
		/parameter-2 {
			/key 1987339116
			/showInPalette 4294967295
			/type (unit real)
			/value ''' + toRealString(deltaY) + '''
			/unit 592476268
		}
		/parameter-3 {
			/key 1868720756
			/showInPalette 4294967295
			/type (boolean)
			/value ''' + toIntegerString(transformObject) + '''
		}
		/parameter-4 {
			/key 1885434990
			/showInPalette 4294967295
			/type (boolean)
			/value ''' + toIntegerString(transformPattern) + '''
		}
		/parameter-5 {
			/key 1668247673
			/showInPalette 4294967295
			/type (boolean)
			/value ''' + toIntegerString(withCopying) + '''
		}
	}
}
''' ;

  // [run dynamic action](https://sttk3.com/blog/tips/illustrator/dynamic-generate-action.html)
  tempAction(actionCode, function(actionItems) {
    actionItems[0].exec(false) ;
  }) ;
}