Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

[Script Idea] Background Image Configurator

February 03 (4 years ago)

Edited February 03 (4 years ago)
Jordan C.
Pro
API Scripter

So, recently I have been adding a bunch of background images to my game since I really enjoy the ability to set the scene dynamically in Roll20 outside of just combat maps. My main method has been grouping similar sized images into separate rollable tables/multisided tokens and using text on the GM layer to tell me what images are where. It works well enough for my purposes but when adding new photos it gets repetitive and the time involved is somewhat of a deterrent.

That led me to an idea for a script; however, I am sure someone has come up with an efficient solution already that I haven't discovered/read yet. If that is the case, please point me in that direction! In the case that there isn't a simple, effective solution yet I had a few ideas on how to make the process easier for me and would like some input on them as well as gauge if this is even something that would benefit other users at all.

Original Idea -

  • Have a single page that the script 'listens' to and triggers any time an image is dragged to the map layer from the library.
  • The page deletes any previous image on the map layer and changes the page dimensions to match that of the image's native resolution.
  • I believe this would have the obstacle of native resolution not being used when images are imported so this may not even be remotely possible.
  • A possible workaround is to ask for the desire image resolution when dragged out but that's less desirable and probably already possible with things like the Resizer script.
  • Another possible solution is to require file names to have the dimensions listed in a specific format such as "Mountain Landscape --800x600" for the script to parse the dimensions from there and set both the page and the image. I think this is likely where it would end up and requires a little more legwork during upload than I'd like but would require no further input when dragging an image to the map page for future uses.

Again, I'd love to hear any input/criticism/suggestions so I can get a better idea of whether this is something worth spending time on or if this already exists!


February 03 (4 years ago)

Edited February 03 (4 years ago)

This sounds similar to Keith Curtis's Theater of the Mind trick, which I have happily adopted. I'd be interested to see what you could come up with in a dedicated script.

February 03 (4 years ago)
keithcurtis
Forum Champion
Marketplace Creator
API Scripter

I'm a Cargo Cultist. I take the cool toys left behind by the gods and make my own stuff out of them.

That being said, I recommend that trick that Jay posted the link to. Not only does it swap out the background, if you have Roll20AM installed, it can even supply an appropriate soundscape.

February 03 (4 years ago)

Edited February 03 (4 years ago)
Jordan C.
Pro
API Scripter

Ah! That is a very useful way of doing it. I may adopt exactly that, though leads me to a few thoughts -

I'm curious how easy it would be to also change the page size with Resizer and the same amount of inputs. I'm rather particular and find extra whitespace a bit unpleasant visually.

Also, it still has the same caveat I have now where I have to recreate the token each time a new scene is added, which is one of the tasks I would like to avoid. And it still requires a bit of setup/clutter as new scenes get added in general. The idea I had for the script would be to eliminate the need for tables/macros/resetting tokens and adapt dynamically to selecting a simple photo.

That actually is something I didn't address originally but in my head I would be able to see all of the scenes I'm selecting from in an images folder and drag from there where as right now I have text descriptions of the scenes which it sounds like the button menu would have as well and would quickly clutter a chat menu if images were included.

End goal, I would like for the steps from downloading an image on the internet to having a visually pleasing scene be as simple as:

  • Save file as particular name (I do this anyway)
  • Drag to background page
  • (Optionally) Sort file into a backgrounds folder and be able to repeat the second step in the future from that folder
February 03 (4 years ago)
keithcurtis
Forum Champion
Marketplace Creator
API Scripter

You can add scenes programatically, even using the same macro. Instead of choosing sides with tokenmod, you would choose imgsrc. The only caveat is that the image would need to be in your art library. You can get the url by placing the image on your VTT and pressing Z for the preview. Rightclick and copy the url. I actually find it simpler to just add the image to the rollable token.

This is easier than it sounds. If you add the image to the token, you just assign that token to the Scenes character, and press any scene choice in the chat menu. That will size it appropriately.

For the background, I suggest removing the grid from the page and setting the background to black. That gets rid of all distraction nicely.


The difficulties in writing the script as you lay it out are several:

  • The API has no idea about image dimensions or control over or access to the Art Library. It could set a width and height, but cannot know what the intended aspect ratio is.
  • Likewise, it cannot look into the Art Library to do any organization or to infer anything from the folder structure.
  • It cannot place an image from the Art Library that would require it to find the image using the above criteria. You could hard code the URL using the steps above and store it in a state variable but that's a manual step for every image.


The chat menu could be fiddled with to include a short text description for every image. I do something similar with the NPC Directory and Slideshow macro generator. 

February 03 (4 years ago)

Edited February 03 (4 years ago)
Jordan C.
Pro
API Scripter

The end goal section in the last post was meant to be the required manual steps I would have to take, not what the script would do. As it stands right now, I download a picture, give it a file name (which I can change to end with "--800x600" for example with little additional effort), then drag the image to the table top. From there I manually add it to the backgrounds folder I have with my images. These are all things I already do for all images so I am imagining a scenario where the only extra manual step taken would be to navigate to the script's background page and drag the image there instead of a random page. 


The black border is a solution, but still not preferable for me and I do disable grids for all background pages.


As for the API part, the option I think is most practical is that the script could determine those dimensions from the file name and once dragged to the board it resizes the page AND the image without any further user input, it just parses the name based on whatever image was dragged to the page. The way I would like to write it is that the script wouldn't care where the image is from or any other information, it just sees that an image was dragged to the board, grabs the ID and handles it from there. (I am fine with the marketplace caveat, that's a separate problem imo).


So with that being the case, I would only ever need to look in my existing background images folder to visually scan what I want. 


I do like your solution, and I can easily implement it, but it doesn't solve the issues I currently have with my previous method of having to add even more items and reset a token each time I want to upload a new scene. The chat descriptions are nice but I know my mind would much more quickly navigate the images than the text. And for reference I have dozens and dozens of background images and more to be added so it would quickly overwhelm/clutter the chat menu.

February 03 (4 years ago)
keithcurtis
Forum Champion
Marketplace Creator
API Scripter


Jordan C. said:

As for the API part, the option I think is most practical is that the script could determine those dimensions from the file name and once dragged to the board it resizes the page AND the image without any further user input, it just parses the name based on whatever image was dragged to the page. 

This is what I was trying to communicate above. The API has no access to the file structure of the Art Library. This includes reading the title of the image. It also knows nothing about the internal data of the image, such as native pixel dimensions. And since the image is given a roll20 URL when it is uploaded, it can't even read what the file was originally named before it was uploaded. There are all kinds of neat things that could be done if this were readable (such as dragging in maps already sized).

February 03 (4 years ago)
Jordan C.
Pro
API Scripter
Ah, I didn't realize that included the name written for the image, I understood it can't manipulate or read from the library, but assumed the title travelled with it once it became an object, apologies for misunderstanding. And I assumed it couldn't read internal data like that which is why the idea was predicated on image names to define it. But since that's not available I shall settle for the manual process.
February 03 (4 years ago)

Edited February 03 (4 years ago)
Jordan C.
Pro
API Scripter

Hmmm, thinking more on this - Maybe rollable table item names could store that information? Is the API capable of reading a tokens current side and determining which table item is displayed by the side found?

Edit: You can! 

February 03 (4 years ago)
keithcurtis
Forum Champion
Marketplace Creator
API Scripter

Cool, that is news to me. Can you share your technique?

February 03 (4 years ago)

Edited February 03 (4 years ago)
Jordan C.
Pro
API Scripter

Of course! Sorry I wanted to make it clean enough to post without being ashamed lol. 

Here is the snippet of my testing so far - 

on('ready', () => {
     on('chat:message', (msg) => {
        if (msg.type !== 'api' || msg.content !== '!test') return;
            let backgroundToken = findObjs({
                type: 'graphic',
                subtype: 'token',
                name: 'Background Script'
            })[0];

            // Get img URL from token's current side
            let currentSide = backgroundToken.get('currentSide');
            let imageURL = backgroundToken.get('sides')
              .split('|')[currentSide]
              .replace('%3A',':')
              .replace('%3F','?');

            // Grab Table Item by img
            let tableItem = findObjs({
                type:'tableitem',
                avatar:imageURL
            });

            // Get Table Item Name
            let itemName = (tableItem[0].get('name'));
            log(itemName);

            // Parse Table Item Name
     });
});

Right now it just logs the table item name that has the same URL as the token that is named 'Background Script'. 

I need to think about how I would want to parse it. If I end up down this rabbit hole I'll start thinking of what steps to take to make the actions  isolated to a specific page and error handling for instances of multiple tokens, etc.
February 04 (4 years ago)

I wanted to achieve something akin, but then to autosize images dropped from my collection of bought art sets. 

It boils down to storing all dimensions in a script and the using the image id as a key to test.

https://app.roll20.net/forum/post/9707488/script-artresizer-solution-to-automatically-resize-art-when-dropped-on-the-map/?pageforid=9707488#post-9707488


As you state to already encode the size of images in the name, you could do the same based on the filename in the art sidebar. This would require some scrolling down to load the full list and then doing some funky stuff in the browser developer tab.


February 04 (4 years ago)
Jordan C.
Pro
API Scripter

Ooooh, I saw that in passing when you posted I think; That definitely looks like it would accomplish my intended outcome. 

I may still futz around with this project in my free time but I am keen to try out your solution! Seems like the simplest avenue at the moment.

February 04 (4 years ago)
Gold
Forum Champion

Interesting to me...

Although I have the opposite philosophy of Page Layout as Jordan.  I like to make very large dark (black) margins around the image,inside the canvas. Sometimes called Matting on art-framing. I like Large pages, with plenty of room around the central image.  Hate having images that extend all the way to the border, causing me to scroll into the bright-gray borderlands behind the canvas and/or causing overlap of the Zoom Slider, Tool Bar, and Player Avatars over the image I'm trying to see.

Following the discussion

February 04 (4 years ago)
Jordan C.
Pro
API Scripter

Ah, I admit I do use stylus to change the grey background to a darker format (and eliminate zoom bar etc.) which may be the source of my preference. 

I would make sure to consider those preferences and create options so that it accommodates that and preferences for users/players that aren't using stylus. And actually it may be better to just make that the default since after thinking about it, one issue I currently have is not being able to center the canvas browser since it locks to the top left, which may be remedied with stylus but is certainly addressed with black margins. 

February 04 (4 years ago)
Gold
Forum Champion

Yes, Jordan, the Centering problem is fixed by Page Size: 50x50*, black background, everyone pan to the middle (GM can force-ping them to the proper starting spot), thus avoiding the dependance on Top Left and avoiding seeing Canvas background (light grey hatch pattern).

Stylus is cool but as you know that only fixes Your View on your own personal browser, not your Player's view.  Unless they all install & configure Stylus like yours, they'll be getting the overly-bright background.

* Note personally I do much larger than 50x50, such as regularly doing 120x180 or even 250x250, but 50x50 is the point at which Roll20 will start to issue the automatic warning about 'Large pages may not load properly'.