Smooth "animation" using system.gui.transform in Vision

Hello everyone I am Miguel, I've been working on this issue for the last 2 days. I think I almost have it figured out but I want a clean and smooth "animation" out of my components.

In short, I am working on a Vision ignition project for the company. We need away to represent the state of a line, is it up and running or is it down, and we want the state of the line running to be represented with moving components. If the line is running, we want the component to move from one place to another using the system.gui.transform function and then use that same function to place the component back in its home spot.


  • I created a custom property on a component.
  • I tied that property to the number of units we produce, we produce one every 10 seconds.
  • I am using the component propertychange to trigger the script, it should trigger once every 10 seconds.
  • Realistically I would like to have the custom property bound to a Boolean tag that indicates the state of the line, but I couldn't get that rolling and Ignition does not like while loops with the system.gui.transform.

The issue:

  • When I run the program, the component will move up like it should for just a second... Then it spazzes out and starts moving up and down erratically.
  • I can not use client events to trigger the script because it doesn't have access to the components and their properties.
  • I would love to rely on the Boolean state of the line and not the number of units they've produced. But, like I said i haven't been able to get that running in a while loop.

Here is the code I am using:

top = system.gui.getParentWindow(event).getComponentForPath('Root Container.Top')

def telTop():
	system.gui.transform(top, 1088,1531)
system.gui.transform(top, 1088, 1089, duration=1500)

system.util.invokeLater( telTop)

The invokeLater function is going to run almost immediately if you don't specify a delay, and this is the cause of your erratic behavior. You need to add a delay to your invoke later that is at least as long as the duration timer of your transform.

What you want use for this is the timer component. You can fire this script and check your bound property from the component's action performed event handler. Your script will look something like this:

# Run script every two seconds 
if event.source.value > 1:
	# Get the animated component
	top = system.gui.getParentWindow(event).getComponentForPath('Root Container.Top')
	# Define the delayed reset function
	def telTop():
		system.gui.transform(top, 1088,1531)
	# Animate the component for a duration of 1.5 seconds
	system.gui.transform(top, 1088, 1089, duration=1500)
	# Que the reset to run after the transformation has completed
	system.util.invokeLater(telTop, 1500)
	# Reset the timer for the next two second interval
	event.source.value = 0

With a timer component, you won't need this. Simply bind the timer's Running? property directly to your Boolean tag.

Thanks for your input, I really appreciate it.

Orignally I did have a duration on the system.util.invokeLater(telTop, 1500) function. I removed and played around with the duration to see if it would make the animation any better, it did not. Here's a video of what it currently looks like.

Again, it's not being triggered several times, it's getting triggered once every 10 or so seconds.



I tied the script to a button, if I press it once, it works just as intended. Which confuses me as to why it acts any different when being triggered by a binded tag value. Also, it's way smoother than what it looks like in the video, my screen recorder isn't the best.

Have you made any progress on this?

I have not :frowning:

One thing we haven't considered for this problem is the paintable canvas. Here is a template I created that resembles what you are depicting: (9.5 KB)

Here is what it looks like in an actual client session:

The template has a custom property called "triggerEvent." Setting this to True will trigger the animation. The property will automatically set itself back to false once the animation has completed. There is also a custom property called "pixelsPerSecond" that will set the speed of the animation [in pixels per second]. The canvas is transparent, so simply position it directly over the existing conveyor, and when the event is triggered, the component will be painted and animated as depicted above.


Thank you so much, I've never imported a template nor used one, I will start googling right now. But, if it's not too much trouble, can you give me some instructions on how to do it?

1 Like

In the designer:
File --> Import

Navigate to and select the file in the popup that appears.
Then, click Open:

The template will be imported

From there, find it in the project browser, and simply drag it and drop it onto your window: