I have several animations on a window, using a Timer and Visibility bindings. Initially I had a rotating widget that I changed the angle on with the timer value. Timer runs 0-9, and the expression changed the angle by Timer.Value*36. Because of all the bugs and problems with wandering widgets and dynamic rotation not maintaining centers I had to abandon this. So, I created 10 static images, each with a different angle, and linked each one with a visibility of the Timer.Value = x. Grouped the images on top of each other.
The timer is set to 500ms, but the actual time itās incrementing is much slower. And Iāve now noticed that all the animations are slow, the navigation is slow, and I see the circle busy element on most any operation. This is a very minimal application that Iāve just started. Only about 300 tags used. Using the angle rotation method, the response was fast.
I am doing this development and testing across the customerās VPN, so could it be a screen refresh issue? Or is there a limitation within Ignition about using a number of visibility animations? Thereās 10 to 15 of these grouped stacks on a window.
Sounds like you are doing gateway calls (tags, db, etc) in the foreground thread. Donāt do this. Use asynchronous bindings for such things, and react to the propertyChange when the value arrives. Cache your images. Donāt go to the gateway to get them at every step. Use project script modules with top level dictionaries to hold your cached objects.
I have no idea what you just said, LOLā¦Sorry, new to Ignition and not yet clear on all the terminologies. If there is a document/help area to read that you could point me to, that would be helpful.
Iāll explain better. I have 10 widgets in a group. Each widget in the group has a visibility based on a local timer component in that window. I would assume that timer is local to the client and there is no need for any Gateway traffic. The entire group has its visible property binded to an OPC tag. If I put 15 of these groups on a window, the animations come to a grinding halt. As soon as I delete them, everything goes back to normal. But to me that should only be 15 tags that are being monitored, so no heavy lifting at all.
Now, I just realized that in those 10 widget visible bindings (inside the group) I also added the System tags (({[System]Client/System/SystemFlags} & 1 ) && !({[System]Client/System/SystemFlags} & 2)
so that the widgets donāt disappear in development mode. Could that possibly be the culprit? Again, I apologize for not being up to speed on what is and isnāt Gateway traffic.
I removed any reference to any tags. All Iām using is a local timer component on the window that times from 0 to 9. 10 widgets with visibility bound to timer.value=0, 1, 2, etc. Stack these widgets (center H/V), group them and it shows a turning wheel. As soon as I add more than 5 instances of this widget to a blank window with the timer, the timer and screen start to slow down. Go to 10 instances, and itās severely hampered and unusable.
So to reiterate, no Tagsā¦just using the timer property value bound to the visible property of each widget within a group.
When Phil said donāt use tags in the foreground thread, he meant donāt use the Tag() expression function and instead bind any tags you need to custom properties with tag or indirect tag bindings. You should use the same for all of your project
Iāve used custom properties and bindings for indirectsā¦on a pop-up for example. But in this case its an image widget. I have 10 individual images. Each one I click on, goto expression, enter property of timer.value=x where x is 0 to 9 for the 10 widgets. I then geoup these 10 together in one stack. Thats it. If I put 5 of these on an empty screen the timer starts to slow down. Granted thatās 50 images with a visibility binding tied to property timer.value. But why would that slow everything down. In this test, no tags are used.
I going to guess your widget isnāt smart enough to cache the image and is getting it from the gateway every time it becomes visible. Youāll have to use another technique. Iād use the paintable canvas.
3rd time the charmā¦i only used this method because of the issues with rotation wandering and losing its center reference. Showing a turning image shouldnāt be so challenging:)
Well, hang on. Are you able to post a project export, or at least the window + images youāre using?
Something about this seems very fishy - you should have absolutely no performance issues from toggling component visibility.
Yes sir, I can export the test window with 10 of them showing the slowdown. Ill do so later tonight or in the morning. Ill try to take a video too if that helps.
Oof. Okay, so, I can tell you what the problem is, but thereās no great fix.
So, the problem isnāt toggling the visibility - the problem is the fact that each of your animation āframesā is angled - that means each time itās drawn, Java Swing (Visionās underlying rendering layer) has to render the image, then rotate it X degrees - and because Swing is both old and takes great pains to be cross-compatible, it does that rotation entirely on the CPU (thereās no āhardware accelerationā, if youāre familiar with the term). So each group you create is just that many more rotation operations to perform, and Swing is going to do them all on the main GUI thread, which increases āperceivedā slowdown.
So, what can you do?
Probably the easiest thing would be to manually ācacheā the rotations - you could recreate the graphic you want in a tool like Inkscape, then export pre-rotated SVG or PNG images to use for your individual component frames.
Or, you could also start with the original graphic from Symbol Factory, at a reasonable size, on a blank window. Then rotate it through as many frames as you want, taking a screen capture/using system.print.printToImage for each.
As an alternative to toggling visibility on a bunch of individual components, you could also then upload them all to image management, and just use an Image component with a dynamic path (bound to a timer/signal generator) for each frame.
For another option, you could pack those frames into a .gif directly - you wonāt have dynamic control over the speed, but itās guaranteed to have constant performance. You could toggle between a static graphic and the .gif if you want to show running/halted.
For yet another option, use a Paintable Canvas as Phil suggested - youāll have ultimate control over the presentation, but itās a steep learning curve.
Thank you for the detailed response. Probably easiest and most straightforward is I can easily modify the original image in a 3rd party editor and paste them back. I could do it from Symbol Factory direct, but the properties for SF donāt seem to be exposed. Symbol Factory has properties like angle, size, color, etc. that Iāve used in the past on other SCADA, but I donāt see them within ignition.
Anyway, at least I know the direction I need to head. Thanks!!
Have you tried just binding the angle property of the symbol to the timer?
I just tested this on 7.9.16 using a symbol factory gear and a timer.
Set the timer to 500 ms Delay, step 10, Bound 360
Then I bound the gears angles to the timer value.
I have 30 of them on a vision window with no slowdown.