No object for linear gradient fill functions


#1

I am trying to create a plugin using the LinearGradientFill class and I cannot for the life of me figure out how to great a LinearGradientFill object. I don’t often work in JavaScript, but I do understand a fair bit. I am unsure whether or not I am making a mistake or there is an issue with the documentation.

According to this:
https://adobexdplatform.com/plugin-docs/reference/LinearGradientFill.html#new-lineargradientfill
page of the API Reference, there is a

new LinearGradientFill

method, which I assume would be the creation of an object, yet when I call this using

var fill = new LinearGradientFill()

or any similar operation,I get the resulting error:

Plugin TypeError: LinearGradientFill is not a constructor

Am I making a stupid mistake? I just wish to apply a fill to the user’s selected object, but I have no idea where to go from here.


#2

Hi @Prime,

Since LinearGradientFill is an exported member of the scenegraph module, you’ll first need to import it (similar to how e.g., Color works) from the scenegraph module:

const { LinearGradientFill } = require('scenegraph');

After that, the constructor should work as you’ve used it.

Hope this helps,
Happy Coding,
Pablo


#3

Thank you for the reply @pklaschka . unfortunately, I still can’t seem to get it to work.

I have tried multiple different variations and I still get the same error.

const { LinearGradientFill } = require('scenegraph');

function gradientHandlerFunction(selection) {
    console.log("Plugin command is running!");

    gradient = new LinearGradientFill();
}

module.exports = {
    commands: {
        gradiate: gradientHandlerFunction
    }
};

I have changed this format around in various ways, such as moving the location of the require, trying different assignment methods for the object, etc. But nothing seems to work still.


#4

Ok. Do you still get the same error message (LinearGradientFill is not a constructor)? The code you posted would be invalid (since you need some sort of declaration of your variable, i.e., replacing gradient with let gradient, const gradient or something similar), but that could also be a result of

Could you try the following code and “report back” any error messages (and other console output) you might get:

const { LinearGradientFill } = require('scenegraph');

function gradientHandlerFunction(selection) {
    console.log("Plugin command is running!");
    console.log('LinearGradientFill', LinearGradientFill);

    let gradient = new LinearGradientFill();

    console.log('Gradient created: ', gradient);
    console.log('The end ;-)');
}

module.exports = {
    commands: {
        gradiate: gradientHandlerFunction
    }
};

Thank you very much in advance :+1:


#5

I tried running the code you provided and it still does not seem to be working. I ran it both with and without the log for console.log('LinearGradientFill', LinearGradientFill);.

Here is the resultant console output:

Unloading plugin C:\Users\Ryan\AppData\Local\Packages\Adobe.CC.XD_adky2gkssdxte\LocalState\develop\832cf2c1
Loading plugin C:\Users\Ryan\AppData\Local\Packages\Adobe.CC.XD_adky2gkssdxte\LocalState\develop\832cf2c1
Plugin command is running!
Plugin TypeError: LinearGradientFill is not a constructor
at gradientHandlerFunction (C:\Users\Ryan\AppData\Local\Packages\Adobe.CC.XD_adky2gkssdxte\LocalState\develop\832cf2c1\main.js:7:20)
at Object.execScenegraphEdit (plugins/ScenegraphGuard.js:1:2515)
at BaseCommand._invokePluginCommand [as _commandFn] (plugins/PluginLoader.js:1:3150)
at BaseCommand.execute (lib/BaseCommand.js:1:929)
at Commands._execute (lib/Commands.js:1:1935)
at Commands.executeAsGesture (lib/Commands.js:1:2088)


#6

Ok – I was now able to test this myself and can confirm that it doesn’t appear to be working.

Tested on XD 16, Windows 10, with the following code:

const { LinearGradientFill } = require('scenegraph');

console.log(LinearGradientFill);
const fill = new LinearGradientFill();

It first logs undefined to the console and then (which in this case makes sense) throws the same error as for @Prime about (in this case undefined) it not being a constructor.

This leaves me to believe that LinearGradientFill is no longer an exported member of the scenegraph module (unlike, e.g., Color), leaving the question of where the LinearGradientFill and thereby its constructor can get found. Also, this really makes resolving this issue a necessity since with unexpected behavior like LinearGradientFill not behaving like Color, the question of which class can get found where isn’t even implied anymore (like it was before, with everything of this sort just being an exported member of scenegraph).

@kerrishotts @ashryan @peterflynn Sorry to tag you (I’m usually not the kind of person to do that :wink:), but this seems pretty important (since unclear), and with hopefully some (or many) new developers getting “on board” the next few days with the three Hello, XD Plugin workshops, I think that this might be worth taking a look at if you can find the time (since I look at all changes to the docs and check all branches day-in, day-out to keep the typings up to date (and have read every bit in detail at least once), I think it’s safe to say that I know the docs better than many plugin developers (not meaning this in a bragging way, I really would be worried if someone checked the docs repo for updates as often as I do without the justification of staying up to date to update the typings :laughing:), meaning it probably isn’t a good sign that I have no idea where LinearGradientFill can currently be found…).


#7

Thanks @Prime and @pklaschka.

I can confirm the same thing on Mac. We’re all meeting in just a few minutes to head to the workshop venue in London, so I’ll bring this up for discussion on the way.


#8

@ashryan Perfect, thank you. Also: Have a great time at the workshops in London and Amsterdam – I’ll see you in Mannheim in a few days :+1:


#9

@Prime and @pklaschka:

The docs are incorrect. It should be:

const { LinearGradient } = require("scenegraph");

We’ll get this fixed. Thanks for reporting it!


#10

Reported as issue here:


#11

It should additionally be noted that in order to create a new LinearGradient and assign it as fill, one first has to create an “empty” LinearGradient object, then assign at least two color stops and then assign it as fill:

const { LinearGradient, Color } = require('scenegraph'); // Import classes
let gradient = new LinearGradient(); // Create "empty" gradient"
gradient.colorStops = [
    {stop: 0.0, color: new Color('#ff0000')},
    {stop: 1.0, color: new Color('#ff00ff')},
]; // Assign colors to gradient
node.fill = gradient; // Assign gradient as fill

It might be wise to put some example code into the docs to make this clear (currently, it isn’t obvious how this can be achieved).

Edit: I made adding a note about how LinearGradients can get created an issue in the plugin-docs repo: https://github.com/AdobeXD/plugin-docs/issues/180


#12

@pklaschka @ashryan Thank you both for the support! As a side note, I don’t wish to open a whole new topic for this: some reason my console opens up empty and i have to restart my entire PC for the developer console to actually load my plugins sometimes. Any ideas as to why this is?


#13

Also - how do I go about setting the current selection as the node? I assumed it would be selection.fill but it appears not. Sorry if these are documented in the API reference, this is my first time going through an API so I am trying to get a hold of it :slight_smile:


#14

That does sound like it’s worth opening a new topic in the API Feedback / Bugs section to me – I’ve never experienced this, meaning it’s likely really some sort of bug :wink:


#15

selection actually is a SceneNodeList – cf. https://adobexdplatform.com/plugin-docs/reference/SceneNodeList.html. You can iterate through the selected nodes/layers e.g., by using something like

selection.forEach((node) => { 
    /* Do stuff here */ 
});