Animate to Random Frame

(gleb) #1

Hi, just wondering if anyone can provide a solution. I feel like I’m quite close in that there is some random timing in the animation, but it’s not quite right.
What I am trying to achieve is have a column of blocks, like LEDs on a graphic equaliser, and for them to animate, fade in to a random height, so 3 blocks light up, then 5, then 2, then 8, then x, y, z… etc.
I have set up an animation where each block is animated from off to on in succession, bottom block first, then second, then third, fourth, fifth etc.
What I would like to do through code is for the script be triggered at the first frame of the animation. At this point I know the total animation length, get a random frame number from start to end. Play the animation. When the random number is reached the animation is continued in reverse, until the first frame is reached, a new random number is generated and the process is repeated. I have placed text elements in the scene to see if the current frame number and random number is being updated… and they are. But somewhere they random number gets stuck close to 0 and then behaves wildly, jumping quickly to different digits.

Thanks for any help.


var AniName = 'LED_Random';
var AniLength = hypeDocument.durationForTimelineNamed(AniName);
var RandomFrame = Math.floor(Math.random() * AniLength);


var CurrentFrame = Math.floor(hypeDocument.currentTimeInTimelineNamed(AniName));
hypeDocument.getElementById("length").innerHTML = CurrentFrame;
hypeDocument.getElementById("random").innerHTML = RandomFrame;

if (CurrentFrame > RandomFrame) {
hypeDocument.continueTimelineNamed(AniName, hypeDocument.kDirectionReverse); 
}, 1000);

(gleb) #2

Okay, I think I found the solution! The line below was the problem.
All I had to do was delete the “var” and now it works! Guess something to do with global variables?

(gleb) #3

I am continuing to play around with this and sharing my progress with a few questions.
Randomisation = Working!
Adding randomisation to Symbol = Working!
Weird quirks however, probably because I am not a coder so not sure how to make it simpler.

I have commented out the Text1 and Text2 because it seems to break everything and stop it from working. Don’t know why. There must be a more concise way of doing this, perhaps in a for loop, but again my attempts have stopped the script from working.

At the moment each EQ column is a symbol, each symbol has a unique id. At the first frame on the LED_Random timeline the javascript is run, but I am guessing it is being run by each symbol so the script must be running 6 times.

Although it’s working, I’m wondering whether there is a much better way of doing this.

Thanks for any insights.

var Text1 = hypeDocument.getElementById('length');
var Text2 = hypeDocument.getElementById('random');

SymbolName1 = hypeDocument.getSymbolInstanceById('EQ_Column1');
SymbolName2 = hypeDocument.getSymbolInstanceById('EQ_Column2');
SymbolName3 = hypeDocument.getSymbolInstanceById('EQ_Column3');
SymbolName4 = hypeDocument.getSymbolInstanceById('EQ_Column4');
SymbolName5 = hypeDocument.getSymbolInstanceById('EQ_Column5');
SymbolName6 = hypeDocument.getSymbolInstanceById('EQ_Column6');

MyAniName = 'LED_Random';
MyAniLength = SymbolName1.durationForTimelineNamed(MyAniName);

MyRandomFrame1 = (Math.random() * MyAniLength)+0.1;
MyRandomFrame2 = (Math.random() * MyAniLength)+0.1;
MyRandomFrame3 = (Math.random() * MyAniLength)+0.1;
MyRandomFrame4 = (Math.random() * MyAniLength)+0.1;
MyRandomFrame5 = (Math.random() * MyAniLength)+0.1;
MyRandomFrame6 = (Math.random() * MyAniLength)+0.1;


 CurrentFrame1 = SymbolName1.currentTimeInTimelineNamed(MyAniName);
 CurrentFrame2 = SymbolName2.currentTimeInTimelineNamed(MyAniName);
 CurrentFrame3 = SymbolName3.currentTimeInTimelineNamed(MyAniName);
 CurrentFrame4 = SymbolName4.currentTimeInTimelineNamed(MyAniName);
 CurrentFrame5 = SymbolName5.currentTimeInTimelineNamed(MyAniName);
 CurrentFrame6 = SymbolName6.currentTimeInTimelineNamed(MyAniName);
// Text1.innerHTML = CurrentFrame.toFixed(2);
// Text2.innerHTML = RandomFrame.toFixed(2);

if (CurrentFrame1 > MyRandomFrame1) {
SymbolName1.continueTimelineNamed(MyAniName, hypeDocument.kDirectionReverse);

if (CurrentFrame2 > MyRandomFrame2) 
SymbolName2.continueTimelineNamed(MyAniName, hypeDocument.kDirectionReverse);

if (CurrentFrame3 > MyRandomFrame3) 
SymbolName3.continueTimelineNamed(MyAniName, hypeDocument.kDirectionReverse);

if (CurrentFrame4 > MyRandomFrame4) 
SymbolName4.continueTimelineNamed(MyAniName, hypeDocument.kDirectionReverse);

if (CurrentFrame5 > MyRandomFrame5) 
SymbolName5.continueTimelineNamed(MyAniName, hypeDocument.kDirectionReverse);
 if (CurrentFrame6 > MyRandomFrame6) 
SymbolName6.continueTimelineNamed(MyAniName, hypeDocument.kDirectionReverse);

}, 1000);

(Mark Hunte) #4


Can you post an example project.

(Mark Hunte) #5

So I had a play at seeing what I could come up with.

This does not use symbols for the rows. Each one has it’s own timleline.

All the timelines fire the same single function.

We use the event.timelineName to distinguish between which timeline is calling the function.

The random Function:

 var ranDom =  (Math.random() * 1.30) + 0.04;
	var theRand =  Math.round( ranDom * 10 ) / 10;
var tl = hypeDocument.currentTimeInTimelineNamed(event.timelineName);

 var theTL = Math.round( tl * 10 ) / 10;
   if (  theTL <  theRand ){
  hypeDocument.continueTimelineNamed(event.timelineName, hypeDocument.kDirectionForward);
  }  else if (  theTL >  theRand ){
  hypeDocument.continueTimelineNamed(event.timelineName, hypeDocument.kDirectionReverse);
  }  else {

This means we can use a single Function to run the random numbers.

On each timeline when a LED is lit a timeline action to pause and call the javascript is used.
We force the function to loop from within itself and we tell each timeline to start itself at its beginning and end (reverse).
So any time the timeline would normally stop it restarts. This means we do not need a timer.

All timelines are initially started by a main timeline action, which runs a function to start them.
The reason for doing this in a function rather than in the action is because it is actually easier than trying to add a long list in the action. (28.3 KB)

(gleb) #6

Thanks for looking into it Mark. I am going to test your suggestions!
I have attached the LED scene the way I had it set up for you and others to have a look at or tinker with.
Mine is done with each column of LEDs as a symbol. (52.7 KB)

(Mark Hunte) #7


I will look at it when I get back to am Mac with HPro on.