Skip to main content
Martin Dedron
Inspiring
May 21, 2022
Answered

Export separately every step of the blend tool

  • May 21, 2022
  • 3 replies
  • 3649 views

Good afternoon,

 

I want to export SEPARATELY every step of a blend between two shapes and then apply them to different pages of a book.

The request is pretty simple: I want to have one straight line evolving in a subtle way to a wavy line. To do so, I have my starting path and my arrival path. I can use the blend tool to create as many steps as I need (matching the number of pages of the book).

 

However, if I want to export, I would have to select one by one each one of those paths to then "export selection". Which is a huge lot of clicking and clicking while I am sure there is a script to fit each of those objects into a different artboard.

I am looking for such a script, that would save me a lot of time.

 

Then I will have the question on how to datamerge into an existing document that includes a main text block, but I think the biggest issue is about the Illustrator export being fastidious. 

 

Any help is welcomed.

Thank you, 

Martin Dedron

This topic has been closed for replies.
Correct answer Martin Dedron

I thought Monika mentioned a script, but it was a plug-in.

This script should work exporting to PDF (just make sure that your PDF export does not open Acrobat).

http://www.ericson.net/content/2011/06/export-illustrator-layers-andor-artboards-as-pngs-and-pdfs/


Thank you ! 

I went with @m1b 's method and, with a bit of a struggle, managed to obtain what I wanted. But I will look at that for sure.

3 replies

m1b
Community Expert
Community Expert
May 21, 2022

Hi @Martin Dedron, sounds like a fun project. 🙂 Is your book going to be made in Illustrator or Indesign?

- Mark

m1b
Community Expert
Community Expert
May 22, 2022

Hi @Martin Dedron, I had an idea for a script that might really help your project.

 

To use it, first start with a blend and expand it then ungroup it and keep all the paths selected. Then run my script. It will create a new illustrator document, then create new artboards that match the size of the artboard in the original document, and then duplicate each selected page item to the new document, positioned on the corresponding artboard.

- Mark

 

Here's the script—everything really happens in the first function and the rest of the functions are just little utility functions that make things convenient.

 

/*
    Duplicate Items To New Doc Artboards.js
    for Adobe Illustrator 2022

    by m1b
    here: https://community.adobe.com/t5/illustrator-discussions/export-separately-every-step-of-the-blend-tool/m-p/12956749

*/


duplicateItemsToNewDocArtboards(app.activeDocument.selection, 10, -1);


/**
 * duplicateItemsToNewDocArtboards
 * creates a new document and then
 * duplicates each item to a new
 * artboard on that document
 * @param {Array[PageItem]} items - the page items to duplicate
 * @param {[Number]} gap - spacing in points between artboards
 */
function duplicateItemsToNewDocArtboards(items, gap, direction) {
    if (items == undefined)
        return;

    gap = gap || 0;
    direction = direction || 1;

    var masterArtboard = getArtboardsOfItem(items[0])[0];

    if (masterArtboard == undefined)
        masterArtboard = getParentDocument(items[0]).artboards[0];

    var newArtboards = [],
        sideLength = Math.ceil(Math.sqrt(items.length)),
        w = masterArtboard.artboardRect[2] - masterArtboard.artboardRect[0],
        h = -(masterArtboard.artboardRect[3] - masterArtboard.artboardRect[1]),
        tx = masterArtboard.artboardRect[0],
        ty = masterArtboard.artboardRect[1],
        dx = (w + gap) * sideLength / 2,
        dy = (h + gap) * sideLength / 2,
        newDoc = app.documents.add();

    if (direction == -1) {
        reversedItems = [];
        for (var i = items.length - 1; i >= 0; i--)
            reversedItems.push(items[i]);
        items = reversedItems;
    }

    for (var i = 0; i < items.length; i++) {
        var x = i % sideLength,
            y = Math.floor(i / sideLength),
            xpos = (w + gap) * x - dx,
            ypos = (h + gap) * y - dy;

        newArtboards[i] = newDoc.artboards.add([xpos, -ypos, xpos + w, -(ypos + h)]);

        var dup = items[i].duplicate(newDoc, ElementPlacement.PLACEATBEGINNING);
        dup.position = [items[i].left + xpos - tx, items[i].top - ypos - ty];
    }
    newDoc.artboards[0].remove();
}



/**
 * getArtboardsOfItem
 * returns array of artboards that intersect the item
 * @param {PageItem} item - a page item
 * @param {[Array[Artboard]]} _artboards - artboards to search, if undefined, search all
 * @param {[Boolean]} preferIndex - if true, returns array of artboard indices {Array[Number]}
 * @returns {Array[Artboard]} - array of artboards
 */
function getArtboardsOfItem(item, _artboards, preferIndex) {
    var doc = getParentDocument(item);
    _artboards = _artboards || doc.artboards;
    var bounds = getItemBounds(item);
    var result = [];
    for (var i = 0; i < _artboards.length; i++) {
        if (boundsDoIntersect(bounds, _artboards[i].artboardRect))
            result.push(preferIndex
                ? i
                : _artboards[i]
            );
    }
    return result
}



/**
 * getItemBounds
 * attempts to calculate items bounds
 * including correct bounds of clipped group
 * @param {PageItem} item - a page item
 * @param {Boolean} geometric - false = visibleBounds, true = geometricBounds
 * @param {Array[4]} bounds - [l,t,r,b]
 */
function getItemBounds(item, geometric, bounds) {
    if (item == undefined) return;
    var newBounds = [];
    if (item.typename == 'GroupItem') {

        var children = item.pageItems,
            contentBounds = [];
        if (item.hasOwnProperty('clipped') && item.clipped == true) {
            // item is clipping group
            var clipBounds;
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                if (child.hasOwnProperty('clipping') && child.clipping == true) {
                    // the clipping item
                    clipBounds = child.geometricBounds;
                } else {
                    // a clipped content item
                    var b = expandBounds(getItemBounds(child, geometric, bounds), contentBounds);
                }
            }
            if (clipBounds != undefined)
                newBounds = intersectionOfBounds([clipBounds, contentBounds]);
            else
                newBounds = contentBounds;
        }

        else {
            // item is a normal group
            for (var i = 0; i < children.length; i++) {
                var b = expandBounds(getItemBounds(children[i], geometric, bounds), contentBounds);
            }
            newBounds = contentBounds;
        }
    } else {
        // item is not clipping group
        newBounds = geometric ? item.geometricBounds : item.visibleBounds;
    }
    if (bounds == undefined) {
        bounds = newBounds;
    } else {
        bounds = expandBounds(newBounds, bounds);
    }
    return bounds;
}



/**
 * expandBounds
 * returns bounds that encompass two bounds
 * @param {Array[4]} b1 - bounds [l,t,r,b]
 * @param {Array[4]} b2 - bounds [l,t,r,b]
 * @returns {Array[4]} [l,t,b,r]
 */
function expandBounds(b1, b2) {
    var expanded = b2;
    for (var i = 0; i < 4; i++) {
        if (b1[i] != undefined && b2[i] == undefined) expanded[i] = b1[i];
        if (b1[i] == undefined && b2[i] != undefined) expanded[i] = b2[i];
        if (b1[i] == undefined && b2[i] == undefined) return;
    }
    if (b1[0] < b2[0]) expanded[0] = b1[0];
    if (b1[1] > b2[1]) expanded[1] = b1[1];
    if (b1[2] > b2[2]) expanded[2] = b1[2];
    if (b1[3] < b2[3]) expanded[3] = b1[3];
    return expanded;
}


/**
 * intersectionOfBounds
 * calculates intersecting rectangle
 * @param {Array[Array[4]]} arrayOfBounds - array of [l,t,b,r] arrays
 * @returns {Array[4]} [l,t,b,r]
 */
function intersectionOfBounds(arrayOfBounds) {
    bounds = arrayOfBounds.slice(0).sort(function (a, b) { return b[0] - a[0] || a[1] - b[1] });
    var intersection = bounds.shift();
    while (b = bounds.shift()) {
        if (!boundsDoIntersect(intersection, b)) return;
        var l = Math.max(intersection[0], b[0]),
            t = Math.min(intersection[1], b[1]),
            r = Math.min(intersection[2], b[2]),
            b = Math.max(intersection[3], b[3]);
        intersection = [l, t, r, b];
    }
    return intersection;
}

/**
 * boundsDoIntersect
 * returns true when bounds intersect
 * @param {Array[4]} b1 - bounds [l,t,r,b]
 * @param {Array[4]} b2 - bounds [l,t,r,b]
 * @returns {boolean}
 */
function boundsDoIntersect(b1, b2) {
    return !(
        b2[0] > b1[2] ||
        b2[2] < b1[0] ||
        b2[1] < b1[3] ||
        b2[3] > b1[1]
    );
}


/**
 * getParentDocument
 * @param {PageItem} obj - a page item
 * @returns {Document} the page item's document
 */
function getParentDocument(obj) {
    while (obj.hasOwnProperty('parent') && obj.constructor.name != 'Document')
        obj = obj.parent;
    return obj;
}

 

EDIT: fixed positioning bug and removed error when first item isn't on any artboard.

Martin Dedron
Inspiring
May 23, 2022

Thank you !

 

As I use graphics and photographs, Illustrator and Photoshop are part of the project but it is mainly being done in InDesign.

 

I have a problem with your script: it doesn't fit the content to the artboards and it seems that there are some artboards missing ? 😕😕

Ton Frederiks
Community Expert
Community Expert
May 21, 2022

As Monika said you can make layers from the blend.

Expand the blend, ungroup and use Release to Layers (Sequence)

They will become sublayers. Select all the sublayers and drag them above the main layer.

Delete the main layer and use the script.

Martin Dedron
Inspiring
May 23, 2022

Thank you ! But I cannot run the script

Ton Frederiks
Community Expert
Community Expert
May 23, 2022

I thought Monika mentioned a script, but it was a plug-in.

This script should work exporting to PDF (just make sure that your PDF export does not open Acrobat).

http://www.ericson.net/content/2011/06/export-illustrator-layers-andor-artboards-as-pngs-and-pdfs/

Monika Gause
Community Expert
Community Expert
May 21, 2022

There is a script to export layers. You could use the Make layers function in the layers panel menu to get layers for objects.

Or you could use the Export for screens feature (but then you would need a reference object to get the size and position in the layout correctly.

 

https://github.com/TomByrne/IllustratorSmartExport

Martin Dedron
Inspiring
May 23, 2022

Thank you ! I cannot install the script (it says to use a ZXP file but there is none in the content, maybe it's because it's written in the readme that it won't be updated anymore ?)