How to update a views coordinates between animations

animation

#1

How does the Animation Class manage translation coordinates?

Picture the following.

You have a Label that is offset on the x axis by 200 via its left property. Then a swipe gesture triggers an animation on the Label, which translates its x axis by -200.

Now, it makes sense to me that if translate is called again on the same Label that it will translate from its original offset. Which is what happens.

However I thought if I update the Labels’ left property immediately after the first transition, any following transition would work from the new parameter. But it doesn’t. Translate always references back to the Labels’ original coordinate.

From what I can tell this is set in stone during the navigatedTo event. I say that because that’s when I’m seeting the x axis offest that’s always referenced.

Is there some deeper level method (beyond view.set(“left”, x) for resetting a views coordinates for future translate calls to reference?

Otherwise I’m thinking I’ll either need to store an accumulative translated value somewhere, so I know what future values to pass into translate.

Or after each animation, create a new Label that’s coordinates are set to the existing Labels’ and swop them over. Which just sounds stupid.

I’m sure there’s a real simple solution here, but I can’t see it (or find it in the docs).

Cheers.


#2

Post animation if you want to modify the X value modified by animator, you must do it through translateX property.


#3

There are a few different ways to animate and which method you use really depends on what are you trying to achieve. As you found out already, animation does not operate by changing the object’s top/left coordinates, but instead by modifying its 2D transformation matrix.

When you look at the Animation API constructor (URL: https://docs.nativescript.org/api-reference/classes/ui_animation.animation) you see that it takes an optional boolean called “playSequentially”. What I found is that depending on whether this param is true or false, the object will snap back to its original (top/left) coordinates after the animation is finished - or not.

I don’t know at the top of my head, but (if I recall correctly) if this param is true, then every time you translate the object, the object will translate from the last value stored in its transform matrix.

Example: Object is at starting position (top/left) 0,0. Translate x=200, y=200. Now the object “appears” at 200,200 and it stops at that location. However, the object’s coordinate (top,left) is still 0,0. It’s transform matrix value is 200,200. So if you later want to animate the object from this point on, you just have to animate it relative to its current transform matrix value (200,200). This way you can actually do fancy animations all over the place without touching the object’s original top/left coordinates.

However, if the “playSequentially” value is false (or possibly the other way around :slight_smile: ) then if you animate the object’s transform value from 0,0 to 200,200, once the animation finished, the object will “jump back” to its original position (0,0).

So depending on how you want to animate the object, you can pass true or false for this param and animate it accordingly.


#4

Thanks for chiming in @manojdcoder and @pentool

Sorry for the confusion, I wasn’t actually having any trouble getting the animation up and running. It was more a case of wanting to know how (if possible) I could impact the data animation stores for any view it’s called on.

For the animation I’m implementing there are multiple views that need to be handled. Depending on what’s already happened each view may need to translate on the x or y axis, and scale up or down proportionately.

In this case it’s not a major issue because I’m only dealing with 4 views. But I could see that if it had to handle considerably more views, the animation could become quite janky. What with all that math.

But if I could just update each views width and height, and top and left coordinates, then all I’d need to do for the animation is tell it if we were adding of subtraction a set value for scale and translate.

Because you can’t change the top/left coordinates of a view, and have those changes reflected in future animations I figure the Animation Class must be storing this data under some unique id for each view. And this data must be immutable, at least the coordinates part.

If we could access that, we could detach the view data from the memory block used by the Class when the animation ends. So each animation call becomes the first.

Does that make (any) sense?


playSequentially

This value defaults to false, meaning each item in the array will play at once (if no delay is set).

I’ve also found it to deliver some very unexpected results when true, so I tend to opt for setting a delay prop to fake sequential animation. Or break it up into different sequences.

I also note when using the Animation constructor, opposed to view.animate(...) the constructor doesn’t seem to handle multiple items with the same target very well. So this is another instance where it’s handy to use chaining.


#5

I suggest some sample code may be with playground, explains your issue better than text.