Is there an ultra-simple animation helper function?

Let’s say I wanted to show an Auto-Saved Indicator on a program. Every time the program saves something to disk, the Indicator would “flash” in some respect. I might have a Canvas Control somewhere that is normally looking pretty empty and then when the program auto-saves, I might want to show, say, a DISK symbol for some amount of milliseconds. In days of old, you might use pseudo-code such as:

Draw Disk Image in Canvas Control
Delay X# milliseconds
Erase Canvas Control

But, these days, things are more complicated (I think?) A Delay is probably frowned upon (even if short) because nothing else gets done until the delay is over, and again, these days, the drawing of the disk image in the canvas might not even get drawn when you think it is, because the drawing may only get drawn when the canvas is Invalidated, or control was never relinquished to the system to handle the drawing of invalidated canvases, etc.

So, I’m guessing the (possibly) proper way to do this is to use a Timer…such as…

Draw Disk Image in Canvas Control
set a flag indicating the disk image is drawn
Set a Timer to remind me 100 milliseconds from now to erase the disk image

if flag is set, erase the disk image

Anyway, somehow this seems rather complicated. I’ve done such simple animations (using Timers) before, but just wondering if there’s a simpler way to do such ultra-simple animations? All I want to do is draw something, wait an instant, and erase it. Is there no built-in support for such simple animations (if that’s even what you’d call it)?


Had an interesting idea, feeling inspired.
Give me a few minutes, and I shall be back.

Back! I made a canvas subclass that does this all for you :slight_smile:

Easy to use and re-use! Drag the BlinkPic instance to your interface, and set it’s Picture and Delay in the IDE.
Then, any time you want to “blink” just use .Show, it will handle the rest.

Well, someone was feeling ambitious today! Heh-heh! Thanks Tim. I’ll have a look.

I have two options for you, both from my website

First, my Animation Kit will allow you to do all kinds of animation. It may be a little overkill, but should be pretty quick to put together what you’re looking for.

Alternatively, my Artisan Kit has a canvas subclass (ArtisanKit.Control) which has some built-in animation functions. You still have to draw yourself, of course, but it handles all of the timing. This makes it real easy to add animation if you’re already familiar with drawing to a canvas.

I think Animation Kit might be the way to do it though. You can setup a sprite sheet for each frame of the animation, using Photoshop for example. Then you can have the sprites flushed to the canvas over x amount of time.

Thanks Thom. I’ll definitely take a look at both of your suggestions. Thanks for replying. I guess you (and Tim earlier) both answered my question, if indirectly. I was really curious if there was some kind of built-in support in Xojo for such a simple animation as I had suggested that I was missing. I guess the answer is NO. Obviously, though, there is a wealth of methods to handle such animations by using creative Xojo coding, but apparently nothing already built-in.

If I may, the example you showed with linear programming could be blurring your idea of what could be built in Xojo.

Fundamentally, event based programming takes places when something happens, would that be your auto save, or a timer action event. In between, it is perfectly possible that nothing occurs at all, so no code executes. Note that saves a lot of CPU power in the process, as compared to linear programming.

The timer is the essence of creating an event ,so again, code executes. It is as natural and important to event programming as can be, and should never be dismissed. Someone on this forum described them as “hackish” once ; that is simply ridiculous.

That said, events happen all the time, at least while the user interacts with the program, through the mouse or the keyboard. That can be used to check against Microseconds or Ticks and update the disk chart. But while entirely possible, I cannot help but to find that unnecessary complex.

Hi Michel…thanks for the thoughts. I don’t disagree. And I don’t mind anyone keeping me on my toes either. Do please bear in mind, though, I’m not dismissing event programming, well, not really. I’m just sort of lamenting that what could be trivially simple now needs re-thinking. Remember, all I wanted to do was put up a disk symbol (as an auto-saved indicator), and then erase it some milliseconds later. Now, as far as I (the programmer) am concerned, it’s not a real concern if nothing else gets done in those few milliseconds (however “rude” that may be!), it’s not like I’m permanently hogging computer time. And, if that’s the case, I just lament I can’t simply program something like “draw it, wait a few milliseconds, erase it”. Again, it’s not that I’m unaware of the more proper way to handle such things, just that I wish there were a built-in function to help accomplish it. Anyway, thanks Michel, I know what you mean.

BTW, putting all this an another perspective, it just means the debate will never end on what functions should be part of Xojo proper, and what will always be added as user-generated functions, or added in external libraries of functions, etc. To me, it reminds me of simple drawing. Even though there are built-in functions for drawing a line, there are also built in functions for drawing a rectangle. There didn’t have to be. The user could certainly create a rectangle by drawing 4 lines, but it’s a real convenience when a rectangle drawing function is built-in to Xojo. I was just hoping Xojo had built-in some simple function that allowed “draw this, wait, erase it”.

Ken, I am coming from the prehistoric times of the Apple II, so believe me, I had to leave behind linear programming a while ago. Since then, I came to appreciate timers as a very effective mean of doing things.

Mind you, linear programming has no disappeared from Xojo : DoEvents allows all sorts of polling and loops familiar to the ancient world.

This will be met with cries of horror, but it does exactly what you described in your OP. Disk is an icon from the FatCow collection I dragged in the project.

Canvas1.Visible = True Canvas1.Backdrop = disk dim starttick as double = ticks while ticks < starttick+30 app.DoEvents wend Canvas1.Visible = False

Note that without App.DoEvents, it would never work. And we have been warned time and again about the potentially detrimental effect of that command on Xojo programs, so take that as just an intellectual exercise.

In that case try App.SleepCurrentThread to do the waiting. Your app will be totally non-responsive during the wait.

[code]Sub Action()
dim p As new Picture(Canvas1.Width, Canvas1.Height, 32)

Canvas1.Backdrop = p
Canvas1.Refresh //force a draw before waiting

//wait 6 seconds

Canvas1.Backdrop = nil

End Sub

These forums are just great! Thanks to all! And, Michel and Will, thanks for the two suggestions. Both much appreciated. 100 programmers will have 100 ways to do the same thing. Gotta love it. (And, yes, Michel, I go back as well, my first real published software was for the Apple II, though I go back even further to the days of 6502 programming, Kim-1, Sym-1, etc. And, an IBM360 mainframe too with punch cards and all if you really want to go back!)

It works, but on Mac you get the beachball of death during the wait. Under Windows 10, this kind of thing becomes an alert saying the app has become unresponsive.

Meanwhile your method uses App.DoEvents which Xojo, Inc strongly suggests against.

The point both of you were trying to make is that the linear method is an absolutely terrible idea for this purpose. I’m glad Will’s method shows the effect that the other method hides with App.DoEvents

Indeed, an innocuous single timer will avoid these pitfalls.

subclass the button
add a timer purely in code & respond to the event using addhandler
that timer can change the image on the button one or more times
I suspect it should do so AFTER the save has actually happened

Yup! “An innocuous single timer”…is exactly what I’ve come back to myself. I really appreciate all the back and forth, I’m forever learning.

It also seems like Xojo.Core.Timer.CallLater might do what you want.

One factor that may influence the engineers’ decision to implement a feature xplatform is its general availability. You will find graphics routines for lines and rectangles on all supported platforms and with a more or less similar API syntax. Animation features are quite different. On iOS, basically every visible property change on a control is animated by default. On OS X, some properties are animatable if you address a proxy object of the instance, or you can use different advanced animation features (you can in iOS too.) I don’t have the faintest about Windows animations but I wouldn’t be surprised if their design were completely different.

In other words: Even for something simple like a color animation the engineers would have to address a multitude of different API features and come up with a Xojo method that combines the platforms ’ lowest common denominators. Which could still look different on different platforms. Much easier to undercut the APIs and use timers on the available properties or a solution like Animation Kit. Or, of course, if your project is not xplatform use the native animation features for the target via declare or plug-in.

If I am not mistaken, Animation Kit uses timers to do its magic.

Oh sure, it does. It contributes to a more native look and feel by a lot of transition schemes, like ease in/out. That’s why I mentioned it individually.