Issue with detecting timeline direction inside a symbol instance

Hi Folks

I have an issue with detecting timeline direction inside a symbol instance with an if/else statement.

In my project, I have a symbol instance with a timeline named 'Progress'. The timeline includes a simple progress bar that is advanced by clicking the forward button and reversed by clicking the reverse button.

In the middle of the 'Progress' timeline, I placed a trigger that is supposed to run the check_timeline() function. This function is a simple if/else statement which is supposed to check the direction of the timeline. If the timeline is running forward the button above the timeline is supposed to turn green but if it is running in reverse the button is supposed to turn red.

Here is the statement:

if (hypeDocument.currentDirectionForTimelineNamed('Progress') == hypeDocument.kDirectionForward) {
document.getElementById("light").style.backgroundColor = "LimeGreen";
} else {
document.getElementById("light").style.backgroundColor = "Red";
}

This only works if the timeline is running forward and nothing happens when it is running in reverse. So then, I changed the first condition to this:

symbolInstance.currentDirectionForTimelineNamed('Progress') == hypeDocument.kDirectionForward

and then nothing is working anymore.

What is also strange that this statement works fine if the timeline is not inside a symbol but when I turn it into a persistent symbol then is stops working.

As always any pointers will be greatly appreciated.

Thanks!

Timeline direction.zip (21.7 KB)

It looks like you didn't give… symbolInstance …any data to work with.

hypeDocument.getSymbolInstanceById('id')

…where "id" is the ID name of the symbol that you want to work with.

1 Like

Aaaaaaa ok :joy:

I did not know symbols can also have an ID

Now it works:

var symbol = hypeDocument.getSymbolInstanceById('Progress_bar');

if (symbol.currentDirectionForTimelineNamed('Progress') == hypeDocument.kDirectionForward) {
document.getElementById("light").style.backgroundColor = "LimeGreen";
} else {
document.getElementById("light").style.backgroundColor = "Red";
}

Nice! :slightly_smiling_face:

I tried doing this from scratch, as a general “direction” example…

 function rAF() {
      var d = hypeDocument.currentDirectionForTimelineNamed("Main Timeline");
      if (!d) {
           hypeDocument.getElementById("direction").innerText = "Forwards";
      } else {
           hypeDocument.getElementById("direction").innerText = "Backwards";
      }
      requestAnimationFrame(rAF);
 }

 rAF();

direction.zip (29.3 KB)

First… hypeDocument.currentDirectionForTimelineNamed("Main Timeline") …appears to be a boolean. So, that simplifies the conditional.

Next… I used requestAnimationFrame to have it constantly checking. Not super efficient, but I had some fun playing with backdrop filter effects.

Finally… @jonathan …did you want… hypeDocument.currentDirectionForTimelineNamed("Main Timeline") …to return a value of zero (0) when moving forward? That's what the console log showed… a zero or a one. It seemed backwards to me, as I thought 1 would be normal. (Although, I suppose it is confusing either way.)

Regardless, the instructions are different…

Returns the playback direction of the specified timeline.

Possible return values:
hypeDocument.kDirectionForward
hypeDocument.kDirectionReverse

That doesn't seem like the values I saw in the log.

I think this would be better if the API had function names that were more specific as a boolean… hypeDocument.currentDirectionForTimelineNamed("Main Timeline").forward …and then return true or false.

Eh, it's minor, but I thought that was confusing when reading the API notes.

1 Like

Without diving too much into API design, this is entirely intended.

The direction is a property and not a boolean. Just because something is forward doesn't necessarily indicate it is reverse. A boolean API would be hypeDocument.isPlayingInForwardDirectionForTimelineNamed(timelineName). It seems to be an assumption that false indicates reverse, when we have not defined "reverse" anywhere in the API as a feature of timelines. To do it this way also would indicate we'd need a vaguely redundant and similarly hypeDocument.isPlayingInReverseDirectionForTimelineNamed(timelineName) which implies there could be 4 states (TT, TF, FT, FF), which is nonsensical.

I'd say a proposal of returning an object that has .forward or .reverse fields would be just as confusing. I personally do not expect an object here and the 4 state issue is still a problem.

One could argue we should have returned string values instead of a number corresponding to a defined constant, but then there's other subtle issues like: inconsistent constant usage in the API, taking up more runtime size, localization, etc.

There's basically always tradeoffs where it will be confusing one way or another to someone :slight_smile:.

1 Like

I wanted to use the Math function tracking to monitor the timeline.

( just as a refresher)
But because doing that with symbols we would need a way (in this example at least ) to know which symbol we are using with the Math function.,

doing it this way is probably way over complex when you can just use symbol ids and do it as @Photics and @grzesiek.rogala have done it.

But hey was wanting to see if it would work.

Works for Multi symbols persistent or Standard, independently

Timeline directionMHv1 2.hype.zip (28.5 KB)

2 Likes

The k prefix for constants in programming, especially within Apple's early development environments using C and Objective-C, likely originated in the 1980s. It may stand for "konstant" (German for constant) or "key," reflecting its use in key-value pairs. Apple's widespread adoption of this convention in its APIs and frameworks helped popularize its use among developers, making k a recognized marker for constants in various programming contexts.

In Hype, the use of k to mark constants serves a practical purpose, making the API more human-readable and easier to work with. Rather than dealing with arbitrary numeric return values, which in earlier times of computing might have been returned as single bytes for efficiency and could involve complex bitmask operations, we can use descriptive constants.

Example:

if (hypeDocument.getTimelineDirection('myTimeline') === hypeDocument.kDirectionForward) {
    console.log('The timeline is playing forward.');
} else if (hypeDocument.getTimelineDirection('myTimeline') === hypeDocument.kDirectionReverse) {
    console.log('The timeline is playing in reverse.');
}
1 Like