Jump to content
Search Community

Getting best timing in an animation of alpha rendering

yanivab test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hello,

 

I'm trying to code a flickering animation, where a canvas and an image flicker on and off intermittently.

I'm trying to get the timing of the flickering as accurate as possible: the canvas (multicoloured "mondrian" in the codepen) should be presented for 67 ms (4 frames at 60Hz) and the image ("stimulus" in the codepen) for 34ms (2 frames at 60Hz). 

 

I coded it using only autoalpha, drawing everything before the animation starts. The presentation times are recorded into an object called "vbl" in the codepen.

 

On my macbook with chrome, animation works almost perfectly. But testing this animation on a few different setups (weaker windows machines, all chrome or firefox), I'm getting a considerable amount of mistiming: Especially in the first flickers in the sequence. Both the canvas and the image might be presented for too short or too long (0-100ms in range, though mean and median are close to wanted values).

 

As timing is the most important issue for me, I am willing to use almost any trick to get it better. Any ideas? I'm fine with long (~0.7 second) loading times.

 

Many thanks,

Yaniv

See the Pen KQPZyW?editors=1111 by yanivab (@yanivab) on CodePen

Link to comment
Share on other sites

A few thoughts...

  1. performance.now() is expensive, FYI. You might want to limit your use of that. 
  2. I probably wouldn't use autoAlpha since you're toggling values so frequently which is making the browser do more work flipping back and forth the two values (opacity and visibility). Any reason you didn't want to just use either opacity or visibility? I suspect that since opacity can be GPU-accelerated, that'd deliver the best results. 
  3. The very first render of any tween (and a set() is just a zero-duration tween) is the most expensive since it must read/record the starting and ending values. You've got things set up in a relatively expensive way, with a BUNCH of tweens in the timeline that instantiate in quick succession. 
  4. If I were you, I'd consider using a single tween with an ease that controls the oscillation. Here's a CustomEase I created for you that oscillates any number of times: 

Does that help at all? 

  • Like 6
Link to comment
Share on other sites

That is tremendous help! Thank you! I will give it a try.

 

Just to make sure - since I want a flickering animation, my ease should be a square wave function. I could crate that with vertical and horizontal lines in svg. But I see you avoid vertical lines. The idea is that the svg path has to be a function, right? (ie, no two x points with the same y value).

In that case, horizontal lines with slightly diagonal lines connecting them is the way to go?

  • Like 1
Link to comment
Share on other sites

So this is working great for me.

 

I do want the option to measure the animation's performance as it plays - that is save the timing of each flicker of the image.

 

(The reason being I am using this to code a psychology experiment, for which timing is important).

 

Is that possible with an ease, and if so, what is the most efficient way?

I saw that the ease has an onUpdate property - though that fires on every screen refresh - that is every 16.67ms if everything is OK. Getting that is useful, but I would actually like to know how long each images has been presented on screen. I could probe the opacity value of the image every onUpdate, but that sounds expensive.

If my ease would simultaneously change the value of a javascript variable with the image opacity, would probing and recording that be reliable / reasonable? 

 

Thanks again!

Link to comment
Share on other sites

On 2/4/2018 at 7:32 AM, yanivab said:

I saw that the ease has an onUpdate property - though that fires on every screen refresh - that is every 16.67ms if everything is OK. Getting that is useful, but I would actually like to know how long each images has been presented on screen. I could probe the opacity value of the image every onUpdate, but that sounds expensive

 

Yep, it sounds like an onUpdate is your best bet. Querying element.style.opacity is probably no slower than creating another proxy element and animating the values simultaneously and checking that object instead. You're doubling the memory in that case, and adding another set of calculations on each tick. I doubt it'd help much, but you could ONLY do the proxy object thing and then inside your onUpdate, that is where you'd apply it to element.style.opacity (just so that there's only one thing animating, the simple proxy object, and you're merely applying that value to the element in the onUpdate. But again, I kinda doubt you're gonna notice much of an improvement with that strategy. 

 

Good luck with your experiment. 

  • Like 5
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...