How to selectively edit a node on a particular artboard?

I have created a artboard which contains two rectangles. I used commands.duplicate() to duplicate the artboard. Now, I need to selectively change the co-ordinates of the rectangle in the duplicated artboard.

Here is my code for now :



let dialog;
const commands = require("commands");
function quickStuff() {
  const html = `<style>
        #title{
          margin-bottom: 20px;
          font-weight: strong;
        }
        </style>
        <form method="dialog" id="main">
        <header class="row" id="title">
            <span font-size="30px">Quick Stuff</span>
        </header>
        </br>
        <section>
        <div class="row break">
            <label class="row" id="bg">
            <span>Choose Background</span>
            <button id="bg-b" type="button" uxp-variant="cta">Choose</button>
            </label>
        </br>
        </section>
        <section>
        <div class="row break">
            <label class="row" id="fg">
            <span>Choose Foreground</span>
            <button id="fg-b" type="button" uxp-variant="cta">Choose</button>
            </label>
        </br>
        </section>
        <section>
        <div class="row break">
            <label class="row" id="txt">
            <span>Foreground Text</span>
            <input type="text" uxp-quiet="true" id="txt_bx" value="" placeholder=""/>
            <button id="txt-b" type="button" uxp-variant="cta">Insert</button>
            </label>
        </br>
        </section>    
        </div>
        </div>
        <footer>
        <button id="ok" type="submit" uxp-variant="primary">Create</button>
        <button id="cancel" type="submit" uxp-variant="secondary" background-color:"#E54C4C" >Cancel</button>
        </footer>
        </form>
        `

      async function bgImage () {
          
         // User picks an image file
          const storage = require("uxp").storage;
          const fs = storage.localFileSystem;
          let imageFile = await fs.getFileForOpening({ types: storage.fileTypes.images });
        
        // Create ImageFill for this image
          const ImageFill = require("scenegraph").ImageFill;
          let fill = new ImageFill(imageFile);
        
          const {Rectangle} = require("scenegraph");
          const bgRect = new Rectangle();
          bgRect.width = 1920;
          bgRect.height = 1080;
        
          
        // Set fill of first selected item
          bgRect.fill = fill;
          const { selection} = require("scenegraph");
          selection.insertionParent.addChild(bgRect);
          selection.items = [bgRect];
        }
        
        async function fgImage () {
          
          // User picks an image file
           const storage = require("uxp").storage;
           const fs = storage.localFileSystem;
           let imageFile = await fs.getFileForOpening({ types: storage.fileTypes.images });
         
         // Create ImageFill for this image
           const ImageFill = require("scenegraph").ImageFill;
           let fill = new ImageFill(imageFile);
         
           const {Rectangle} = require("scenegraph");
           const fgRect = new Rectangle();
           fgRect.width = 1920;
           fgRect.height = 1080;
         
           
         // Set fill of first selected item
           fgRect.fill = fill;
           const { selection} = require("scenegraph");
           selection.insertionParent.addChild(fgRect);
           selection.items = [fgRect];
           
         }

         function createText(text, { color = "white" } = {}) {
          const { selection} = require("scenegraph");
          const { Text, Color } = require("scenegraph");
          const text = document.querySelector('#txt_bx').value;
          const newText = new Text(text);
          newText.fill = new Color(color);
        
          selection.insertionParent.addChild(newText);
          newText.placeInParentCoordinates({x: 0, y: 0}, selection.insertionParent.localCenterPoint);
        
          return newText;
        }
        
        function parallFinal(){
          const { selection} = require("scenegraph");
          const {Rectangle} = require("scenegraph");
          let maskShape = new Rectangle();
            maskShape.width = 1920;
            maskShape.height = 1080;
        selection.insertionParent.addChild(maskShape);
        selection.items = [selection.focusedArtboard]
        let commands = require("commands");
        commands.duplicate();
        selection.items = [fgRect];
        fgRect.moveInParentCoordinates( 0, -1070);

        }

        if (!dialog) {
          dialog = document.createElement("dialog");
          dialog.innerHTML = html;
          document.appendChild(dialog);
          document.querySelector("#bg-b").addEventListener("click", bgImage);
          document.querySelector("#fg-b").addEventListener("click", fgImage);
          document.querySelector('#txt-b').addEventListener('click', evt => createText(evt.target.value));
          document.querySelector("#ok").addEventListener("click", parallFinal);

      }
      return dialog.showModal()
  }

module.exports = {
  commands: {
    quickStuff
  }
}; 

Short explanation:
My plugin contains two buttons which lets the user import images over the rectangle using imageFill() in a artboard.
I duplicated the Artboard with those rectangles.
Now I need to selectively move the nodes of Duplicated artboard alone.
In my code, You could see the parallFinal() function in which I do the duplication process and I select the “fgRect” [ which I created in fgImage() function ] and try to move them in certain co-ordinates.
But the Plugin does the duplication process alone! and does not selectively move the rectangle in the duplicated artboard.
Can we give any specific name for the duplicated artboard and will the selection of rectangle work?
Is there any way to sort this out?

1 Like

:slightly_frowning_face:
May I know whether the topic is active ? @pklaschka

It is active. I did, however, not get to looking at it, yet. I am currently in the middle of exams at university, which is why my time for XD stuff is fairly limited.

When I find the time, I’ll take a look at it (the same probably applies for someone else), but since it is relatively long, I assume I’ll need some time for answering, which is why I, personally, haven’t been able to provide an answer, yet :slightly_smiling_face:.

I’m not entirely sure I follow here, but commands.duplicate() will select the newly documented object. From the looks of it, you’re instead trying to move the original element instead.

What I usually do in these cases (if I want to do something to a duplicated item), I’ll do this:

commands.duplicate();
const [ dup ] = selection.items; // assumes we were only duplicating one object
dup.moveInParentCoordinates(10, 10);

In your case, you’d need to dig into the artboard to find the duplicated element; it’s not going to be what fgRect is pointing to at this point (that’s the original element instead).

As to why nothing is moving, it’s because fgRect is not in scope – it’s defined locally to the async function fgImage, which means it isn’t available to other functions. So JavaScript is instead throwing an error (probably fgRect is not defined) and terminating execution of the function early.

1 Like

Thanks for that! It helps. But how do I Find the duplicated element ? How do I particularly select the “duplicated” rectangle alone ( How do I dig into the artboard in my code ? ) or What should I do ? :slight_smile:

You’d need to traverse the scenegraph to find the equivalent node. You could use the node’s label or some other identifying feature to detect that it’s the same object you’re looking for. See https://adobexdplatform.com/plugin-docs/reference/scenegraph.html#scenenodechildren--scenenodelist for info on how to dig into a node’s children. (The same page also lets you see the node’s parent if you need to go up a level.)

2 Likes

This worked ! Thanks a lot <3