# Cancel system.gui.transform

**URL:** <https://forum.inductiveautomation.com/t/cancel-system-gui-transform/29041>\
**Category:** Ignition\
**Created:** [October 12, 2019, 12:34am UTC](https://forum.inductiveautomation.com/t/cancel-system-gui-transform/29041 "2019-10-12T00:34:30Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tim](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/tim/32/3361_2.png) [@Tim](https://forum.inductiveautomation.com/u/Tim)\
**Post date:** [October 12, 2019, 12:34am UTC](https://forum.inductiveautomation.com/t/cancel-system-gui-transform/29041/1 "2019-10-12T00:34:30Z")

</div>

I’m using system.gui.transform with a duration to move a container to X,Y positions supplied by PLC tags. This works, except when I begin a new movement with another system.gui.transform before the previous move has completed its duration. Then I see erratic behavior with the container quickly bouncing back and forth between the two destinations before ultimately landing on the newest one. Is there a way I can cancel the transformation in process before executing a new one? Or another method to handle this case?

Function I am using:  
system.gui.transform(container, newX, newY, duration=5000, acceleration= 4)

Ignition 7.9.12

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 12, 2019, 2:53pm UTC](https://forum.inductiveautomation.com/t/cancel-system-gui-transform/29041/2 "2019-10-12T14:53:30Z")

</div>

One of the original applications for [objectScript()](https://www.automation-pros.com/simaids/doc/expression.objectscript.html) (from [Simulation Aids](https://inductiveautomation.com/moduleshowcase/module/automation-professionals-llc-simulation-aids)) was precisely this sort of animation. (Animation via system.gui.transform() didn’t exist yet.) Instead of computing a complete series of steps and applying them unconditionally on a fixed pace, the approach with `objectScript()` is to maintain a state machine and compute each step as it occurs. It is more complicated to implement, but handles any change in target gracefully. You can even model the acceleration on a curve from one target to the next. The demo project has an example (without accel) on the last tab.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 12, 2019, 5:42pm UTC](https://forum.inductiveautomation.com/t/cancel-system-gui-transform/29041/3 "2019-10-12T17:42:50Z")

</div>

I created and posted a 40-second video using the SimAids demo project showing the animation:

[https://www.automation-pros.com/simaids/SimAids-MotionDemo.mkv](https://www.automation-pros.com/simaids/SimAids-MotionDemo.mkv)

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [October 13, 2019, 7:20am UTC](https://forum.inductiveautomation.com/t/cancel-system-gui-transform/29041/4 "2019-10-13T07:20:56Z")

</div>

From the manual ([system.gui.transform](https://docs.inductiveautomation.com/display/DOC79/system.gui.transform)):

> - Returns  
> PyObject animation - An animation object that the script can use to pause(), resume(), or cancel() the transformation.

Is that what you're looking for?

---

<div class="post-metadata">

**Author:** ![Tim](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/tim/32/3361_2.png) [@Tim](https://forum.inductiveautomation.com/u/Tim)\
**Post date:** [October 14, 2019, 3:48pm UTC](https://forum.inductiveautomation.com/t/cancel-system-gui-transform/29041/5 "2019-10-14T15:48:10Z")

</div>

Thank you Phil. I’m on the road this week, but will examine this module when I return.

---

<div class="post-metadata">

**Author:** ![Tim](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/tim/32/3361_2.png) [@Tim](https://forum.inductiveautomation.com/u/Tim)\
**Post date:** [October 14, 2019, 3:48pm UTC](https://forum.inductiveautomation.com/t/cancel-system-gui-transform/29041/6 "2019-10-14T15:48:50Z")

</div>

It may very well be, but I could not figure out how to implement it.

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [October 15, 2019, 7:39am UTC](https://forum.inductiveautomation.com/t/cancel-system-gui-transform/29041/7 "2019-10-15T07:39:56Z")

</div>

Well, it shouldn’t be so hard… 😉

1. Create client project script in ‘Scripting/Project Library/’ (Ignition8) or ‘Project/Scripts/Script Library’ (Ignition7.9) with the name ‘global\_variables’
2. Put this inside:

```auto
_transformObject = None

```

1. On the Vision window put rectangle box and 4 buttons.
2. Name buttons as ‘Start’, ‘Pause’, ‘Resume’ and ‘Cancel’.
3. In the ‘Start’ button ‘ActionPerformed’ event put this code:

```auto
event.source.parent.getComponent('Rectangle').relX = 50
project.global_variables._transformObject = system.gui.transform(component=event.source.parent.getComponent('Rectangle'), newX=710, duration=10000, acceleration=system.gui.ACCL_FAST_TO_SLOW)

```

1. In the ‘Pause’ button ‘ActionPerformed’ event put this code:

```auto
if project.global_variables._transformObject is not None:
	project.global_variables._transformObject.pause()

```

1. In the ‘Resume’ button ‘ActionPerformed’ event put this code:

```auto
if project.global_variables._transformObject is not None:
	project.global_variables._transformObject.resume()

```

1. In the ‘Cancel’ button ‘ActionPerformed’ event put this code:

```auto
if project.global_variables._transformObject is not None:
	project.global_variables._transformObject.cancel()

```

And that’s it…

 ![transformCancelResume](https://us1.discourse-cdn.com/inductiveautomation/original/2X/f/ff2ebe9122c12aacd21daa2e5c16485aeb31ce35.gif)

---

<div class="post-metadata">

**Author:** ![Tim](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/tim/32/3361_2.png) [@Tim](https://forum.inductiveautomation.com/u/Tim)\
**Post date:** [October 21, 2019, 6:54pm UTC](https://forum.inductiveautomation.com/t/cancel-system-gui-transform/29041/8 "2019-10-21T18:54:33Z")

</div>

This is a great example. Thanks. I had some time today to attempt this, but I do have 50 objects moving on my screen utilizing this method and I still see too much erratic behavior. I am able to significantly decrease this behavior by doing the transform with a newX and newY without a duration (so it happens immediately and is over). Some examples of the problems I see in addition to the jerky movement are the containers being briefly invisible and also them falling behind other objects even though they are on top.
