Categories
Power Apps

Animations using Timer

Sometimes you may want to add a little extra bells and whistles to make your app look professional. This post details how you can use a timer to animate objects in your app.

In order for people to adopt your Powerapp, you need to pay attention to the design and user experience. Apps with few bells and whistles are easier to understand, and focusing on alignment, relative styling, screen transitions, and notifications will help you build a good-looking application. But sometimes, you may want to add that little extra to your app to make it look professional. This post details how you can use a timer to animate objects in your app.

The timer object

You can access the timer object from the Insert Ribbon, under Input controls. It appears as a button-like object, with the text 00:00:00 (corresponding to hh:mm:ss).

Timer object is found under Insert > Input > Timer

The timer has a few key concepts that makes it really useful.

  • AutoStart/AutoPause: Decides whether the control automatically starts/pauses when the user navigates to/from the screen that contains the object.
  • Duration: The maximum amount of milliseconds the timer can count to. Maximum value is 24 hours, and default is 60 seconds.
  • OnTimerEnd: Tells the application how to react when timer reaches the duration-time.
  • Repeat: Boolean for whether the timer restarts upon timer end
  • Start: Boolean whether the timer starts

The last function requires some further explanation. This is the function that we can use to trigger the timer from another control, say e.g. a button. In order to do this, we have to use a context that takes a boolean (true/false) value.

The following example sets up the context _timerStart in OnStart for the screen that has a timer and a button to start and pause the timer.

//Set up the context in OnVisible
OnVisible = UpdateContext({_timerStart: false})
//Code the button to alternately start and pause the timer
OnSelect = If(_timerStart, 
    UpdateContext({_timerStart: false}),
    UpdateContext({_timerStart: true}))
//Set the Start-function on the Timer to fit the context
Start = _timerStart
How it looks when you activate a timer from a button

Moving objects with timer

Let’s say that we want a label that we can turn like a page, by clicking a Next-button below. We want to label to disappear to the right, and then a “new” page to enter from the left.

Add three objects to a new screen: one label that we will move, and two buttons that will move the label to the left or right (I have used the ChevronLeft and ChevronRight icons in this example). Lastly, add a timer object.

Format of my example objects

To make the object move left or right, we can change the X-property of the label, which defines how many pixels from the left edge of the screen the object starts to form. If you want to place the object in the center, you can use the following code:

X = Screen1.Width/2 - Self.Width/2

Decomposed, this first puts the left edge of the object in the center of the screen, then moves it half the length of the object’s width further to the left.

This is static, which is a good place to keep it when we’re not clicking buttons. To make it move when we click a button, we must set the X-property relative to the Timer’s value.

Start with setting the Duration of the Timer, which in this example will determine how long the animation will take. I will use 600, i.e. 0,6 seconds. Make sure the AutoStart-property is set to false.

If I click the right button, I would like the label to swoosh out over the right edge, and then reappear coming in from the left. And vice versa for the left button. We will hence have three stages for the label: stationary, going out right, and returning from the left. To facilitate that, we will have an If-statement, the following states

//Not yet functional IF-statement for Label X-property
X = Screen1.Width/2 - Self.Width/2 + 
If(
Timer1.Value > 0 && Timer1.Value <= 300, //Out right func.,
Timer1.Value > 300 && Timer1.Value <=600, //From left func,
0)

Here, I want to send my regards to the PowerApps-team here for allowing for Elseif-gates in the If-fuction, so that we don’t need to work with a bunch of nested If-functions. Note that when Timer1.Value = 0, the align-center function is default.

To make the label move from the center to the left, we want X to go from [Half screen width ] – [Half label width] to [Full screen width]. So we need to add [Half screen width] + [Half label width] in the time 0ms to 300ms

//Adding the function to add [Half screen width] + [Half label width] over 300 milliseconds to above If-statement

X = Screen1.Width/2 - Self.Width/2 + 
If(
Timer1.Value > 0 && Timer1.Value <= 300, 
   (Screen1.Width/2 + Self.Width/2)*(Timer1.Value/300),
Timer1.Value > 300 && Timer1.Value <=600, //From left func,
0)

As Timer1.Value goes from 0 to 300, the factor (Timer1.Value/300) goes from 0 to 1, which will uniformly move the label to the left.

Once the Timer reaches 300, we want the right edge of the label to be just outside of the screen’s left edge, and then uniformly move in towards the center. So we need to start with X = – Self.Width as Timer1.Value = 300 and go to X = Screen1.Width/2 – Self.Width/2 as Timer1.Value = 600. Hence, the full function looks something like:

//Full function that moves Label to the right for the first 300 milliseconds, then in from the left for another 300 milliseconds

X = Screen1.Width/2 - Self.Width/2 + 
If(
Timer1.Value > 0 && Timer1.Value <= 300, 
   (Screen1.Width/2 + Self.Width/2)*(Timer1.Value/300),
Timer1.Value > 300 && Timer1.Value <=600, 
   -(Screen1.Width/2 + Self.Width/2)*(1-(Timer1.Value-
   300)/300),
0)

The first factor will place the label outside the left edge of the screen as Timer1.Value = 300. The second factor will go from 1 to 0 as Timer1.Value goes from 300 to 600, moving the label uniformly to the center.

Finally, to connect this to the buttons below, set the ChevronRight-icon’s OnSelect-propert to a boolean context, e.g. _timerStart, and update the Timer’s Start-property to that context

//Making the ChevronRight-icon start the timer

//OnSelect for icon:
OnSelect = UpdateContext({_timerStart: true})

//Start for timer:
Start = _timerStart

In addition, change the OnTimerEnd-property for the timer to revert the boolean context back to false:

//OnTimerEnd for timer:
OnTimerEnd = UpdateContext({_timerStart: false})

The principles for making it go in the opposite direction are the same, and we can separate the two actions either by a context or with another timer. I think the context-solution is a bit more elegant, so I’ll outline it briefly.

Firstly, we add a string-context, e.g. _direction, that can take on the values left or right. The ChevronLeft-icon will change the value to left and the ChevronRight-icon will change it to right.

//OnSelect property for ChevronRight-icon:
OnSelect = UpdateContext({_timerStart: true, _direction: "right"})

//OnSelect property for ChevronLeft-icon
OnSelect = UpdateContext({_timerStart: true, _direction: "left"})

To move it in reverse fashion, the code will be:

//Full function that moves Label either to the right or to the left, and then enter from the opposite edge

X = Screen1.Width/2 - Self.Width/2 + 
If(_direction = "right", 
   If(
   Timer1.Value > 0 && Timer1.Value <= 300, 
      (Screen1.Width/2 + Self.Width/2)*(Timer1.Value/300),
   Timer1.Value > 300 && Timer1.Value <=600, 
      -(Screen1.Width/2 + Self.Width/2)*(1-(Timer1.Value-
      300)/300),
   0),
_direction = "left",
   If(
   Timer1.Value > 0 && Timer1.Value <= 300, 
      -(Screen1.Width/2 + Self.Width/2)*(Timer1.Value/300),
   Timer1.Value > 300 && Timer1.Value <=600, 
      (Screen1.Width/2 + Self.Width/2)*(1-(Timer1.Value-
   300)/300),
0), 0)

Below is what you should be able to achieve:

Animated label that moves left or right

Leave a Reply

Your email address will not be published. Required fields are marked *