Raphael Ammann
Raphael Ammann

Reputation: 1

Swap Items using basiljs

I am pretty new to the whole basiljs world. So this might be a very basic question. I wasn't able to figure it out on my own however… 

I am trying to create a simple script that swaps two Items that are selected on the same page.

I was able to get the image frame to swap, however it leaves the frames content in the same position. Here is waht it looks like:

#includepath "~/Documents/;%USERPROFILE%Documents";
#include "basiljs/bundle/basil.js";

function draw() {

    var selItems = b.selections();
    var selItems0x = b.itemX(selItems[0]);
    var selItems1x = b.itemX(selItems[1]);
    var selItems0y = b.itemY(selItems[0]);
    var selItems1y = b.itemY(selItems[1]);

    
    b.itemX(selItems[0], selItems1x);
    b.itemX(selItems[1], selItems0x);   
    b.itemY(selItems[0], selItems1y);
    b.itemY(selItems[1], selItems0y);   
    

}
b.go();

Now my question is: How can I call on the frames content. Obviously I want that one the move the same with the frame.

Thanks for your help, I am eager to learn more! Raphy

Upvotes: 0

Views: 106

Answers (2)

fabianmoronzirfas
fabianmoronzirfas

Reputation: 4131

Even though it is not the "basiliy" way I suggest using InDesign build in functions. You can mix them with Basil Code. Basil doesn't care. There is the possibility to fit elements into its frame or center them.

Try this snippet:

#includepath "~/Documents/;%USERPROFILE%Documents";
#include "basiljs/bundle/basil.js";

function setup(){
  var sel = b.selections();
  var gb0 = sel[0].geometricBounds;
  var gb1 = sel[1].geometricBounds;
  // swap them
   sel[0].geometricBounds = gb1;
   sel[1].geometricBounds = gb0;
  // see the different fit options
  // http://yearbook.github.io/esdocs/#/InDesign/FitOptions
  sel[0].fit(FitOptions.CENTER_CONTENT);
  sel[0].fit(FitOptions.PROPORTIONALLY); 
  }

b.go();

Upvotes: 1

mdomino
mdomino

Reputation: 1235

The problem is that in InDesign a (image) graphic and its containing frame are treated as two separate objects, which means, if you only move the frame, the graphic in it does not move along.

In basil.js you have the method b.transformImage() to move a frame along with its graphic, but it is rather cumbersome to use, as you need to pass along the position as well as the scale of the image.

Alternatively you could move the graphic in a second step. Make sure first that the item actually contains a graphic (instead of being a simple oval etc.) and if that's the case move it to the same position as its parent frame. You can access a frames graphic by using frame.graphics[0].

The script would look like this then:

#includepath "~/Documents/;%USERPROFILE%Documents";
#include "basiljs/bundle/basil.js";

function draw() {

    var selItems = b.selections();

    var selItems0x = b.itemX(selItems[0]);
    var selItems1x = b.itemX(selItems[1]);
    var selItems0y = b.itemY(selItems[0]);
    var selItems1y = b.itemY(selItems[1]);


    b.itemX(selItems[0], selItems1x);
    b.itemY(selItems[0], selItems1y);

    if(selItems[0].graphics.length > 0) {
      b.itemX(selItems[0].graphics[0], selItems1x);
      b.itemY(selItems[0].graphics[0], selItems1y);
    }

    b.itemX(selItems[1], selItems0x);
    b.itemY(selItems[1], selItems0y);

    if(selItems[1].graphics.length > 0) {
      b.itemX(selItems[1].graphics[0], selItems0x);
      b.itemY(selItems[1].graphics[0], selItems0y);
    }

}
b.go();

Note that this will not work if the top left corner of the image is cropped by the frame. In this case you would need to figure out where the top left corner of the graphic actually is and then offset the graphic accordingly after moving it.

Btw., the basil.js team is aware that the transforming of images is somewhat overly complicated and there is a plan to simplify this process in the future.

Upvotes: 0

Related Questions