Help with Creating a Vanishing Point Plugin for Photoshop CC 2025

Hello Community,

My name is Laszlo, also known as Nexeth. I am a digital painter from Germany and Photoshop is my passion. I hope this will be posted in the right Area/Topic.

Unfortunately, I have no experience with programming, but with the assistance of ChatGPT, I aim to create a plugin that makes vanishing points easier and more intuitive to use for myself and potentially other artists. Once completed, I plan to make the plugin freely available and include credits for everyone who helps directly in the plugin.

The Plugin’s Functionality:

1. Vanishing Point Grid Creation:

  • The user creates two paths on a path layer in Photoshop using the Pen Tool.
  • The plugin determines the intersection point of these paths and sets it as the central point for the vanishing point grid.
  • A prompt appears asking, “How many lines should the vanishing point grid have?” (e.g., 10 to 100 lines).
  • Optionally (if feasible): Another prompt opens a color picker, allowing the user to select the grid’s color.
  • The grid is created using the Polygon Tool as a star-shaped structure (as a Shape Path or Pixels).
    • Settings for the Polygon Tool:
      • Number of sides: Corresponds to the number of lines (10–100).
      • Path Options: Draw from center, Star Ratio 1%.
  • The grid should fill the entire canvas.

2. Grid Color:

  • If the color picker is not feasible, the plugin window should provide options to change the grid color (e.g., Red, Blue, Green, etc.).
    • For Shape Paths: Adjust the stroke color.
    • For Pixels: Change the color via Layer Properties.

The Problem:

I have attempted to use the UXP API for Photoshop to access paths using batchPlay and pathItems, but I’ve encountered several issues:

  1. The plugin doesn’t correctly detect paths or returns empty data.
  2. I am uncertain if I am using the correct method to read the anchor points of the paths.
  3. The logic for creating the grid isn’t functioning as expected, particularly when determining the intersection point of the paths.

What I Need:

  1. Help with accessing active paths in Photoshop to retrieve anchor coordinates.
  2. Assistance with implementing the logic to create the vanishing point grid.
  3. General advice or guidance on using batchPlay or other suitable methods for this project.

If anyone is interested, I would be incredibly grateful for your support. I am happy to share the current code to help troubleshoot or refine the plugin.

Thank you so much in advance for your time and assistance!

Best regards,
Nexeth


Source Code:

PS: the manifest file works fine and i only can post 2 links as new member, i hope this doesnt cause any problems while helping. :slight_smile:

I assume point 1 is what you have in the shared main.js
Can you share what you actually tried for points 2 and 3?

P. S. You can use code blocks to share code directly here on the forum

1 Like

Thank you for your help, just as information for you… i talked to my assistent GPT! I will try to clarify our points 2 and 3 as requested:

Point 2 - Reading Anchor Points of the Paths:

To read the anchor points, we initially tried accessing “pathItems” from the “activeDocument”. The specific code looks like this:

const paths = activeDoc.pathItems;
console.log("Paths found:", paths);

const path1 = paths[0]?.pathPoints || [];
const path2 = paths[1]?.pathPoints || [];
console.log("Path1:", path1, "Path2:", path2);

However, when I log pathPoints, I either get an empty array or undefined. I guess this output means i might not access the data correctly. I am not sure if I should be using different method, such as batchPlay, to get the path anchor points or if there’s another correct approach.

Point 3 - Determining the Intersection Point and Grid Creation:

Once the anchor points are accessible, the plan is to calculate the intersection point of the two selected paths and use that as the vanishing point. However, since the data for anchor points isn’t retrieved properly, I haven’t been able to proceed to this logic yet.

Here is the placeholder logic I currently have for the grid creation:

console.log("Intersection and grid logic here...");
// Calculate intersection
// Generate a star-shaped grid using a loop based on the number of lines (10–100)
// Draw the grid on a new layer

Like I said, this is currently just placeholder logic; the real logic isn’t implemented yet. It will be added later once I receive the correct data from the paths. At this stage, I am primarily stuck on figuring out how to correctly retrieve the path anchor points and use them for further processing.

I hope this clarifies my actuall process and problem! If there’s a recommended method for accessing pathItems or their anchor points, I’d greatly appreciate your guidance. Thank you again for your time and help!

Btw… eventually the full main.js code with coments will help to get an overview. Thanks also for the Tip with the integrated Code Block.

console.log("Plugin loaded!");

// Main function to create the vanishing point grid
async function createVanishingPointGrid() {
    try {
        console.log("Start creating vanishing point grid...");

        const activeDoc = app.activeDocument;
        if (!activeDoc) {
            throw new Error("No active document found.");
        }
        console.log("Active Document:", activeDoc.title);

        // Fetch path data using batchPlay
        console.log("Fetching path data with batchPlay...");
        const result = await batchPlay(
            [
                {
                    _obj: "get",
                    _target: [
                        { _ref: "document", _id: app.activeDocument._id },
                        { _ref: "path" }
                    ],
                }
            ],
            {}
        );

        console.log("Path data received:", result);

        if (!result || result.length < 2) {
            throw new Error("At least two paths must be present in the document.");
        }

        // Extract the paths
        const path1 = result[0]?.path?.pathPoints || [];
        const path2 = result[1]?.path?.pathPoints || [];
        console.log("Path1:", path1, "Path2:", path2);

        if (path1.length < 2 || path2.length < 2) {
            throw new Error("Each path must have at least two points.");
        }

        // Placeholder for intersection and grid creation
        console.log("Intersection and grid logic here...");
        // Example logic for grid creation (not functional yet):
        // Calculate the intersection of the two paths and draw the grid
    } catch (error) {
        console.error("Error while creating vanishing point grid:", error);
    }
}

// Event listener for the "Create Grid" button
document.getElementById("createGridButton").addEventListener("click", async () => {
    console.log("Create Grid Button clicked!");
    await core.executeAsModal(createVanishingPointGrid, { commandName: "Create Vanishing Point Grid" });
});

// Plugin initialization
document.addEventListener("DOMContentLoaded", () => {
    console.log("Plugin loaded and initialized!");
    const createGridButton = document.getElementById("createGridButton");

    if (!createGridButton) {
        console.error("Create Grid Button not found!");
        return;
    }
    console.log("Create Grid Button found!");
});

Ups, i realised i answered wrong. Hope you still see this. If not here is a little reminder i did answer X)

It might be hard with GPT to make a plugin. It has very little to learn from. And it has even fewer working snippets to learn from. It might hallucinate a lot unlike e.g. in React.

3 Likes

I absolutely understand your point. However, I’ve already created a plugin with GPT that works fine. That’s why I’m just trying to create something simple to streamline my workflow.

This plugin wouldn’t even be necessary if Adobe hadn’t changed its system. Unfortunately, I bought a plugin years ago that isn’t being updated anymore and only works in Photoshop on a Mac under Rosetta. The issue is that I don’t want to constantly switch between the native Photoshop Silicon version and the Rosetta version, as that would be very inconvenient.

That’s why I’m trying to create this plugin. It significantly simplifies the workflow for 3D painting by providing quick vanishing points. Let’s just say, my day would be much easier if I could get this plugin running for my painting process.

If you have any suggestions, alternative approaches, or resources that could help me, I’d be more than happy to hear them. I’m also open to learning more about the UXP platform or better ways to implement this functionality. Your expertise and guidance would mean a lot to me!

Thanks alot

This is good starting point if you haven’t see it already: https://www.youtube.com/watch?v=zAOUBpDjc1Q&list=PLRR5kmVeh43alNtSKHUlmbBjLqezgwzPJ

2 Likes

thanks alot i will check it out =))

just wanted to give an update. This helped alot and ive managed it to run. got my plugin and i am a happy artist now. Have a good one and cheers :slight_smile:

2 Likes

I’m happy for you, if you publish the plugin put a link.