Only running a timeline once ever

Are you saying you want your animation to not play again when refreshing the page? (But it should play once on first visit?)

Sorry for bring up an old post, but your comment is very relevant to a project I am currently working on. Is it possible to achieve what you have mentioned above, and stop a specific timeline from playing if the page has been refreshed or revisited?

Thanks

To get beyond a refresh boundary, you would need to save and read the state in localStorage or in a cookie, using JavaScript. I’d probably use a single Run JavaScript function on the On Enter Viewport action that looks at the state flag and if it is not set, runs the timeline and sets the flag. It would be something like:

	var hasRunTimeline = localStorage.getItem('hasRunTimeline');
	if(hasRunTimeline != "true") {
		hypeDocument.startTimelineNamed('Untitled Timeline');
		localStorage.setItem('hasRunTimeline',  "true");
	}
1 Like

Thanks for your reply Jonathan, as you have mentioned local storage seems it would be the best solution.

I have been playing around with the project but struggling to implement what you have described. I have two timelines currently. The first timeline is called ‘Intro’ and plays when the scene is visited for the first time.

The ‘Intro’ timeline plays when the scene is loaded and when the animation is finished the various animated content fades to 0% opacity and visibility is turned to hidden, which then reveals other content in the scene. The newly revealed content is controlled and animated by the second timeline called ‘Images’.

The second timeline ‘Images’ and has two buttons controlling the direction which the timeline is played to reveal a selection of images shown one at a time.

I currently have some javascript so when the scene is refreshed through flexible layouts or revisited the “Images” timeline remains in the same place.

So I just need to make sure on a second visit or refresh the first timeline ‘Intro’ doesn’t play for a second time, and sounds localStorage could be the answer?

Thanks for your help

I think the solution I posted would work by simply changing Untitled Timeline to Intro as long as it is on an Enter Viewport action… what behavior are you seeing/can you post an example of it not working?

Hi Jonathan, when you say ‘an Enter Viewport action’ the only way to access that action would be with an element, is that correct? Normally I use on scene load, is that another alternative?

Correct, but you could use that code anywhere to only run the specified timeline once, ever.

I’m still struggling to get this to function correctly. The ‘Intro’ timeline I’m trying to play only once just plays as normal when the scene is revisited. I will get an example document put together and when convenient if you wouldn’t mind taking a look to see where I’ve gone wrong, that would be really appreciated.

Thank you.

I have attached a simple example project which copies my main project I am currently working on.

As mentioned before I have two timelines, the ‘Intro’ timeline plays when the scene is loaded and animates to fade to 0% opacity and visibility turned to hidden, revealing other content in the scene.

The revealed content is controlled and animated by the second timeline called ‘Images’. I have some javascript running so when the scene is refreshed through flexible layouts or revisited the ‘Images’ timeline remains in the same place.

I have included your solution above changing Untitled Timeline to Intro as an On Layout Load and unfortunately not getting it to function as I hoped. Hopefully with the example file you will be able to see where I have gone wrong. (I am still very new to javascript.)

Thanks Jonathan for your help here.

Example.zip (19.7 KB)

(I’ve moved this to a new topic, since it seems that it doesn’t have to do with viewport actions.)

There are two main problems:

  1. You have an On Scene Load action to run the Intro timeline. Therefore it will always run. This needs to be removed.
  2. But now everything is dark because the intro timeline has not been played. You actually need to “run” the timeline in some capacity; simply going to the end point would be enough.

I believe the root of your misunderstanding is probably reflected in the function name that you gave the code, “DisableTimelineFromPlaying.” This code does not disable it from playing, more specifically it plays the timeline if it has not been played before.

Stepping through the code:

var hasRunTimeline = localStorage.getItem('hasRunTimeline');

This first line fetched the flag from storage to see if it has or has not been run before.

if(hasRunTimeline != "true") {

This code is a conditional to ask, have we not been run?

    hypeDocument.startTimelineNamed('Intro');

So if we haven’t been run, then let’s run the timeline.

    localStorage.setItem('hasRunTimeline',  "true");

And also lets set the flag to say that we have been run, so should we run the function again, we won’t enter into this block of code and start the timeline.

}

(end of conditional)

So now if you want to modify it to jump to the end of the timeline if we have been run before, you would just include an else clause that does the Go To Timeline:

	var hasRunTimeline = localStorage.getItem('hasRunTimeline');
	if(hasRunTimeline != "true") {
		hypeDocument.startTimelineNamed('Intro');
		localStorage.setItem('hasRunTimeline',  "true");
	} else {
		var endTime = hypeDocument.durationForTimelineNamed('Intro');
		hypeDocument.goToTimeInTimelineNamed(endTime, 'Intro');
	}

Secondarily you may also want to have the “Images” timeline restore its position? If so, you can likewise use localStorage to store the value instead of setting on the global window object, which will not persist across reloads.

So you would change the fetches for this value from:

window.currentTimeForScene1

to:

localStorage.getItem("currentTimeForScene1");

And the setter from:

window.currentTimeForScene1 = hypeDocument.currentTimeInTimelineNamed('Images');

to:

localStorage.setItem("currentTimeForScene1", hypeDocument.currentTimeInTimelineNamed('Images'));
2 Likes

Jonathan thank you for such a clear explanation!

I have edited the example project and all is now working, so will follow this for use in my main project.

Thank you again for your help on this! So pleased to have this solved.

1 Like

Great, glad you were able to get it!

Had another quick thought when progressing today with this project. Is there some additional code which can be added into the javascript above so that when the ‘Intro’ timeline has been detected as played another timeline is triggered to start?

Had a look into adding something like hypeDocument.PlayTimelineNamed('Next Timeline', hypeDocument.kDirectionForward);

but with my little knowledge of javascript I couldn’t seem to combine the two to get anything functioning.

Thanks again.

It is hard to say what is going wrong, but I would guess that you are not using the correct code since “PlayTimelineNamed” is not a function. It should probably look like:

hypeDocument.startTimelineNamed('Next Timeline', hypeDocument.kDirectionForward);

This would go in the “else” block so that it plays if the Intro timeline does not. You probably would also want to add a timeline action to the Intro timeline itself to start the timeline when it is done, that way it will run in either case, but just at different times.

1 Like

Thanks, now resolved and all working with the line of code you added. :wink:

1 Like