enter image description here I want to join multiple lines in Illustrator. The images shows on top the lines I would like to join. If I select them all and join them (path > join) then the result is as the 2nd image and I would like the result of the 3rd image instead. Is there someone who knows to do the trick? The starting point have to be the first image on top, so only lines not a filled shape.

EDIT: It must work also when the endpoints of the lines are not on a straight line. The following image hopefully shows what I need:

Drawing the rectangle works in this case, but if the bottom is in curve?

  • 1
    What is the starting point though? I look at the third image and I'm thinking I would make a rectangle, duplicate it a bunch of times and then transform it to be slanted like that.
    – Joonas
    Oct 24, 2018 at 10:17
  • 1
    A function has to do something. What it does was defined by whoever wrote the function. Join does not do this, yes that is entirely intentional it wast meant to do this. Could a function do this sure, no problem. But who would write this function? In a perfect world you would.
    – joojaa
    Oct 24, 2018 at 14:44
  • I understand that there are times when the starting point (or anchors, forgive the pun) you have are inviolable, and that either project or client constraints may prevent you from changing element locations - there are some kinds of work where that is simply a fact of life; many illustrators or graphic designers cannot resonate with those constraints being inviolable, as they wouldn't choose to work that way. Also worth your considering that depending upon requirements, time and workflow, it might be better to keep a locked reference layer and redraw per Danielillo or Billy's suggestions. Oct 24, 2018 at 15:18
  • 1
    @GerardFalla i dont know but if you look the original question its a bit different form this one and quite frankly worse. But its really what the asker is in fact asking how to do his job. While i dont think the qeustion is bad per see...
    – joojaa
    Oct 24, 2018 at 15:53
  • 2
    @GerardFalla The question changed radically after the first answer, a bad vice that leads to generate a step-by-step tutorial as the question-answer advances and there should be some way to stop it.
    – user120647
    Oct 24, 2018 at 17:07

5 Answers 5


Select 2 lines with the Selection Tool, hit Command/Ctrl+j twice. Select 2 more lines, repeat...repeat.. repeat.. repeat.

enter image description here

  • 1
    I would like to thank everybody for their support! The way I have been doing this until now, is as Scott shows in his example. Until now this still seems the way to do it, despite the fact I have hundreds of these shapes to come to the final design. To the commends of some of you, this is my first post, so sorry if the first question was not clear enough.
    – user128585
    Oct 25, 2018 at 11:16
  • Sometimes there's really not a "shortcut" for something. It often can suck :)
    – Scott
    Oct 25, 2018 at 16:41
  • Create a rectangle wider than the lines, the same height
  • Select all and use the Shape Builder Tool > click on the intersections to create the new shapes
  • Delete the surplus paths


  • Hi Danielillo, Thank a lot. I did not know this trick. Is there a faster way of doing this? What I would have like that in step two the JOIN function off Illustrator did this as I show in step three. Drawing the rectangle works in this case, but if the bottom is in curve?
    – user128585
    Oct 24, 2018 at 12:12
  • 1
    This answer works perfectly for the original question. Maybe it will not work for the present and future editions. If a question is asked and as answers arise the content is changed, you can get an entire tutorial, and this is not how this site works. I propose you to create a new question with the new changes.
    – user120647
    Oct 24, 2018 at 12:23

Simply put, with your listed constraints (not being able to transform the lines, not wanting to duplicate them - merely act upon them in their preset configuration) [working from CAD base maybe?] the shortest, simplest answer is to forgo trying to do it all in one bulk step: select each line pair separately to perform your Join action - then everything flows simply and quickly.

Lines unjoined enter image description here

Grab a pair, Join, grab another pair, Join enter image description here

One all pairs are Joined once (making U shapes), repeat: reselect the now Joined open U shapes one at a time, and again Join - Illustrator will now close the open ends enter image description here

Complete the process flow enter image description here

All separate elements, joined and closed as needed. enter image description here

I used to do a lot of illustrative site plans, streetscape plans and specific plans for the architecture and planning firm for which I worked - this is exactly how I handled pedestrian crossings coming from the CAD bases.

Excerpt below from one of my produced planning illustrative specific plans - started as sheer CAD lines imported into Illustrator via PDF output from ACad - all subsequent work accomplished in Adobe Illustrator CS2:

enter image description here

For further similar examples see my behance portfolio.


  • 2
    Might be faster if you joined the pair 2 times on the first pass then you wouldn't have to select them again
    – joojaa
    Oct 24, 2018 at 15:55
  • @joojaa - agreed. I was hoping to emphasize with this approach the do-it-one-at-a-time workflow - so many folks seem to want a "magic button" and i wanted to perhaps over-illustrate that operations being separate is often not only a good workflow but essential to certain tools in Illustrator. Oct 24, 2018 at 16:14

1) Press Ctrl+F12 and select zebra_from_lines.jsx script file.

2) Select two or more open paths.

3) Click Combine paths by pairs button.

Zebra from lines script in action

Just copy-paste this code to zebra_from_lines.jsx file using your preffered text editor (in my case it is Notepad++):

//@target illustrator
//@targetengine main

// zebra_from_lines.jsx

// This script connects selected open paths by pairs.
// The paths sequence order follows their z-order.

// Made specially for https://graphicdesign.stackexchange.com/q/116396/128685
// by oshatrk, 2018.

(function(undefined) {

    var combineSelected = function() {

        var haveIntersection = function (p1, p2, p3, p4) {
            var p1x = p1.anchor[0], p1y = p1.anchor[1];
            var p2x = p2.anchor[0], p2y = p2.anchor[1];
            var p3x = p3.anchor[0], p3y = p3.anchor[1];
            var p4x = p4.anchor[0], p4y = p4.anchor[1];
            var d = (p1x - p2x) * (p4y - p3y) - (p1y - p2y) * (p4x - p3x);
            var da = (p1x - p3x) * (p4y - p3y) - (p1y - p3y) * (p4x - p3x);
            var db = (p1x - p2x) * (p1y - p3y) - (p1y - p2y) * (p1x - p3x);
            var ta = da / d;
            var tb = db / d;
            return (ta >= 0 && ta <= 1 && tb >= 0 && tb <= 1);

        var combinePaths = function (obj1, obj2) {
            var pps1 = obj1.pathPoints;
            var pps2 = obj2.pathPoints;
            var n1 = pps1.length;
            var n2 = pps2.length;

            pps1[0].pointType = PointType.CORNER;
            pps1[0].leftDirection = pps1[0].anchor;
            pps1[n1-1].pointType = PointType.CORNER;
            pps1[n1-1].rightDirection = pps1[n1-1].anchor;
            pps2[0].pointType = PointType.CORNER;
            pps2[0].leftDirection = pps2[0].anchor;
            pps2[n2-1].pointType = PointType.CORNER;
            pps2[n2-1].rightDirection = pps2[n2-1].anchor;

            if(haveIntersection(pps1[0],pps2[0],pps1[n1-1],pps2[n2-1])) {
                for(var i = 0; i < n2; ++i) {
                    var p1 = pps1.add();
                    var p2 = pps2[i];
                    p1.anchor = p2.anchor;
                    p1.rightDirection = p2.rightDirection;
                    p1.leftDirection = p2.leftDirection;
                    p1.pointType = p2.pointType;
            } else {
                for(var i = n2-1; i >= 0; --i) {
                    var p1 = pps1.add();
                    var p2 = pps2[i];
                    p1.anchor = p2.anchor;
                    p1.rightDirection = p2.leftDirection;
                    p1.leftDirection = p2.rightDirection;
                    p1.pointType = p2.pointType;

            obj1.closed = true;

        var sel = app.selection;
        if( sel === undefined || sel.length === undefined) return;

        for(var i = 0, n = sel.length; i < n; ++i) {
            var obj1 = sel[i];
            if(obj1.pathPoints === undefined || obj1.closed == true) continue;

            var obj2 = undefined;
            for(++i; i < n; ++i) {
                obj2 = sel[i];
                if(obj2.pathPoints !== undefined || obj2.closed == true) {
                    combinePaths(obj1, obj2);

    var bt = new BridgeTalk;  
    bt.target = BridgeTalk.appSpecifier; // "illustrator-[current version]"  
    bt.body = '('+combineSelected+')();';  

    var w = new Window (
    "palette {text:'Zebra from lines',\
        btn: Button {text:'Combine paths by pairs'}\

    w.btn.onClick = function() {



Note: This script is quite simple one. So it appologizes all paths are simple and are in correct z-order. Feel free to adapt this script with your requirements.

It was tested with multiple versions of Illustrator: CS5, CS6 and CC 2019.

There are few tricks shown in this script:

  1. The targetengine directive is used to prevent immediate deletion of a palette window. Without it the palette is just garbage collected within a second.

  2. All the processing code is placed into one function (in this case it is in combineSelected variable). Then this function is stringified and sended via BridgeTalk to Illustrator which evaluates this string. It looks this process is the only working way to execute something from palette window.

Also when a function is executed in this way it can not be debugged step by step in ExtendScript Toolkit. So for development it is more usefull at first to write a script without such modeless window. There are two options at this point: witout UI at all, or use modal dialog window (just use "dialog" instead of "palette" in Window() constructor). And after the script becomes stable the modeless palette can be implemented as in this script.

Usefull links:

  • Hey oshatrk, welcome to GD.SE. This is a really great answer, thanks for your contribution and enjoy the site!
    – Welz
    Oct 26, 2018 at 20:27
  • Thanks for greating, @WELZ ! And many thanks for animated Gif image!
    – oshatrk
    Oct 26, 2018 at 20:43

Draw one rectangle, then use the Selection Tool (V) to Alt+Shift+click+drag to make one copy, then CTRL+D to repeat as many times as you want.

Then use the Free Transform Tool, using the Free Distort option

enter image description here

For the one with the curve, use Object > Envelope Distort > Make with Mesh. Use a 1 row, 1 column distort, and tweak the Bézier handles until you have the distortion you want

enter image description here

An Envelope Mesh allows quite a lot of freedom when distorting.

enter image description here

  • Hi Billy, Thanks for the tip! But I have lines that are fixed and no free transform available. Is there a way to deal with it as it is? I have many complex shapes like these which are based on fixes anchors.
    – user128585
    Oct 24, 2018 at 13:44
  • 2
    @user128585 - the reason I posted these methods is because I think the way you are going about it is kind of inefficient. You've given yourself too much work because of the way you have drawn the lines separately, and now there's nothing that will work automatically. Gerard Falla's answer provides a manual method. That's about as good as it gets. Sorry about that.
    – Billy Kerr
    Oct 24, 2018 at 17:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.