Is this correct to use image fill

due to lack of timeout api some js operations are hard implement due to js is single threaded

There’s no other way – once you start doing anything that involves an asynchronous operation (file IO, network IO, renditions), you’ll need to be in the land of promises, and one unbroken chain all the way back to the menu handler.

If async/await is easier for you to use, that works too:

module.exports = {
    commands: {
        someCommand: async function(selection) {
            const doSomethingAsync = await someOtherAsyncFunction();
            // can still do things to the scenegraph
            // throw if you want them to be undone
        }
    }
}

(Async/await is built on top of promises, so XD can work with async functions too.)

1 Like

I tried promise function, still not able to fix “xxxx is not permitted to make changes from the background. Return a Promise to continue execution asynchronously.”

Can you please give an example to handle this problem

@realvjy make sure to return inside your Promise block

Hey steve,
Thank you for quick response. Still not luck to solve this problem. I’m not too aware of promise/await/async fx.
Can you please check this code?

// Get Rectangle and oval Shapes
async function fillImages(selection, allImages) {
  var imageCount = allImages.length;
  if (imageCount != 0 && imageCount >= selection.items.length) {
    for (var i = 0; i < selection.items.length; i++) {
      if (selection.items[i] instanceof scenegraph.Rectangle || selection.items[i] instanceof scenegraph.Ellipse) {
        try {
          var imgObj = await getImage(allImages[i]);
          fillSelectionWithImage(selection.items[i], imgObj);
        } catch (e) {
          console.log(e);
        }
      } else {
        console.log('please select elipse or rectangle');
      }
    }
  } else {
    console.log('too many selection');
  }
}

// Check image
function getImage(selectedImage) {
  return new Promise((resolve, reject) => {
    if (selectedImage) {
      try {
        const image = selectedImage;
        resolve(image);
      } catch (e) {
        reject('could not load image')
      }
    } else {
      reject('had an error')
    }
  });
}

// Fill selected shape with image
function fillSelectionWithImage(selectedPath, image) {
  const imageFill = new ImageFill(image);
  selectedPath.fill = imageFill;
}

Higher func i.e func provided in exports to a menu item of your plugin to be a promise to make changes for a scenegraph

See this reply

1 Like

Hey @realvjy Looks like you are working on the XD port of your sketch plugin uiLogos.

@bantya yeah, I’m working on it and struggling with new syntax await/promise/async. :grinning:

@PramUkesh thanks! It works like charm :grinning:

Looking forward to it. Then complete it and release it fast. Best wishes for that. :smile:

Here it is - https://github.com/realvjy/uilogos-XD/releases (Download .xdx file and double click to install)
Can you please test it and share your feedback?

2 Likes

For perfect squares, Logomarks, work flawlessly:

image

But for Logotypes it just stumbles:

image

According to me, the logo should just fit in the container, independent of the size and shape of the container (be it square or vertical/horizontal rectangles)

@bantya This was intended to change the width of container to respect ratio of original logo.

Idea behind logotype here -
Logotype have different dimension (height and width can’t fixed for all logo).
Possible solution:

  1. Center fill or fit logo inside the original container/rectangle (Problem: Logo should be visible completely, it’s not general image)
  2. Just picked height of rectangle/container and change the width of container respect to the ratio of original logotype. (Problem: If have group of container/rectangle, will stumbles :grinning:)

Solution 2 is best for logo related stuff. So, I used this approach. We can re-arrange logos with the help of align distribute.

PS: Added border for comparison

1 Like

Completely agree with you bhai. Lage raho…

1 Like

Is there a way to hardcode a path to a directory of images without using the picker?

If the images are part of the plugin’s data folder, plugin bundle, or in a temporary folder, you can use getDataFolder, getPluginFolder, or getTemporaryFolder, which won’t require a picker. Access outside of these locations, however, does require a picker at this time.

If you only want the picker to show once during a session, you can store a reference to the picker globally, and the access continues for as long as the document is actively open. (Plugin global state is maintained).

3 Likes

@shawn IIRC there’s a set number of persistent file references an application can use (on OSX? or Windows?). I had not heard of this before but if plugins need to keep their own file references that uses up the total allotted file count for the application.

@kerrishotts Do you know how this works? Should we open a feature request for plugins to keep persistent file references (between application close and open).

I think persistent file references without a security layer are undesirable: When a reference can “easily” get stored, it can also get manipulated by a plugin. This would allow for bad things again (if a developer abuses it) and therefore create a security risk (which we’ve already debated about in Run External Application from XD Plugin :wink: ).

Instead, I think XD plugins could use a permission system (similar to how mobile apps handle permissions). It could then include all those “tricky” things like access to the whole file system (without explicit permission by a user), running external applications and so on (later, when technically feasible, leaving the editing context, etc.). With it, things like hard-coded paths wouldn’t be a problem anymore since the user got warned before that the plugin wants to access stuff that might be harmful (if the developer cannot be trusted). Therefore, it would be up to the user to decide him- or herself what the plugin is allowed to do (resolving the issue of plugins being able to do stuff that could be potentially harmful silently).

All in all, hard-coded (and therefore maybe “saveable” paths) aren’t something I’m against (quite the opposite, in fact). I want to propose creating a security layer like a permission system for it beforehand to not make it the fault of plugins in general (and therefore harmful for all developers) if there should be a black sheep distributing malware (undetectable by Adobe’s review) at some point in time.

2 Likes

I guess I’m thinking of internal use more than creating a public plugin. I do a lot of scripting for AE and PPRO and I’m able to hardcode an internal folder structure for assets.

I understand the security risk for a public plugin but it would be nice to have the ability to do both.

2 Likes

Well, if you install the plugin it’s inferred that you at least read the description. People aren’t wildly installing plugins. There’s no drinking game where if you get a question wrong that you have to install a random XD plugin. Second, if you know what the plugin does (Export a layer to a GIF plugin)
and then in the plugin dialog there’s a button that says “Choose an export folder” it’s expected that if you want to export again in the future you don’t need to keep choosing that same folder.

Having said that I like having a permission system similar to what the browsers are using. The site runs fine up to point and when it requires a privileged system, for example, if it wants to give you notifications, the browser pops up a permission dialog for that privilege. You can grant it that specific permission and later at anytime you can revoke it.

The app world permissions on the other hand are mostly awful when you have to grant all permissions at install. It’s especially awful when you have something like a drawing app that wants GPS, network, and microphone access. Uh no thanks. I’ll use pen and paper. A per privilege permission system would fix apps like these. In a perfect world desktop, mobile and browsers would have per privilege permissions.

2 Likes