Skip to main content
Known Participant
April 1, 2021
Answered

Call Image.prototype.onDraw() only once?

  • April 1, 2021
  • 2 replies
  • 1048 views

I have created a ScriptUI dialog that displays an image who's size can be manipulated by changing some settings of the native Image class like so just before the image is rendered:

Image.prototype.onDraw() = function() {
...
this.graphics.drawImage(this.image, xy[0], xy[1], imageSize[0], imageSize[1])
}

This works perfectly, my image looks great and fits exactly how I want it to inside the dialog box. But for some reason the onDraw() method keeps getting called repeatedly and I don't know how to stop it. Whenever an image is about to be rendered I expect this method to only be called once. I can't understand why this method would keep getting executed if I have only tried to display a single image once. This infinite loop of method calling causes the performance of the dialog box to be reduced/becomes laggy as the image keeps getting redrawn 50 or so times every second. The lag isn't terrible though as the dialog window is still usable and can serve it's purpose. I just want to get rid of this infinite loop since it's causing the lag and making adding other features difficult.

 

Any ideas how to make it so that onDraw() only happends once? Or is there another solution?

Thanks!

This topic has been closed for replies.
Correct answer femkeblanco

This is from Peter Kahrel's ScriptUI documentation and it works fine for me. 

Image.prototype.onDraw = function()
{ // written by Marc Autret
// "this" is the container; "this.image" is the graphic
if( !this.image ) return;
var WH = this.size,
wh = this.image.size,
k = Math.min(WH[0]/wh[0], WH[1]/wh[1]),
xy;
// Resize proportionally:
wh = [k*wh[0],k*wh[1]];
// Center:
xy = [ (WH[0]-wh[0])/2, (WH[1]-wh[1])/2 ];
this.graphics.drawImage(this.image,xy[0],xy[1],wh[0],wh[1]);
WH = wh = xy = null;
}
var w = new Window ("dialog", "Bouquet");
var flowers = w.add ("image", undefined, File ("/d/scriptui/bouquet.jpg"));
flowers.size = [50,50];
w.show ();

 

2 replies

femkeblanco
femkeblancoCorrect answer
Legend
April 1, 2021

This is from Peter Kahrel's ScriptUI documentation and it works fine for me. 

Image.prototype.onDraw = function()
{ // written by Marc Autret
// "this" is the container; "this.image" is the graphic
if( !this.image ) return;
var WH = this.size,
wh = this.image.size,
k = Math.min(WH[0]/wh[0], WH[1]/wh[1]),
xy;
// Resize proportionally:
wh = [k*wh[0],k*wh[1]];
// Center:
xy = [ (WH[0]-wh[0])/2, (WH[1]-wh[1])/2 ];
this.graphics.drawImage(this.image,xy[0],xy[1],wh[0],wh[1]);
WH = wh = xy = null;
}
var w = new Window ("dialog", "Bouquet");
var flowers = w.add ("image", undefined, File ("/d/scriptui/bouquet.jpg"));
flowers.size = [50,50];
w.show ();

 

ariffjeffAuthor
Known Participant
April 1, 2021

Weird, I actually based my code off of this snippet myself. I must be doing something simple that's wrong. I'll only be able to take another look again at my work on Monday though. 

ariffjeffAuthor
Known Participant
April 7, 2021

Just fixed my endless looping issue. I had written my set up in a really unorthodox way when I didn't need to where I was preemtively rendering a placeholder image and then trying to immediately replace it with a needed image. That's not the full story as I don't fully understand why the looping happened but essentially I had made it unecessarily complicated and somehow that was creating an infinite loop of redrawing the image by trying to change it, even though I wasn't explicitly calling anything multiple times.

 

For future reference, if anyone needs to change the image after it has been added then just do something like this:

var w = new Window("dialog", undefined, undefined, {closeButton: false}); 

// add the intial image object into the dialog
var myImage = w.add("image", undefined, File("path/to/image1.jpg"));

// change image to something else
myImage.image = "path/to/image2.jpg"

w.show()

The line that changes the image to some other image would be in a callback function or something so that it can execute after w.show() while the dialog is on screen, therefore actually being useful instead of needlessly changing an image that hasn't even been rendered yet in this example code snippet.

m1b
Community Expert
Community Expert
April 1, 2021

Edit: ignore this post. See femkeblanco's answer. 🙂

 

I'm no expert on ScriptUI, but I seems strange to be drawing the image inside the onDraw() function. I would think that you'd put that code inside a draw() function. The infinite loop could be because when the image is about to be drawn, it draws itself and triggers the onDraw event again. I mean it seems plausible that the drawImage function calls the onDraw method.

 

Would it work to put the drawImage line inside your code for constructing the scriptUI window? In that case it will only be called once, when you show() the window. I think.