Delaying an Edge Animate asset until visible - Part 3

This post is more than 2 years old.

Surprisingly, my blog posts (see the Related Entries section below) on Edge Animate and delaying animations were much more popular than I thought. In the comments section folks came up with some interesting questions and discussions about the techniques I presented. One of them was rather fascinating - and like all good questions - led to some interesting code.

A reader had created a vertically large animation. The animation was more than large enough to require scrolling to see the entire thing. What he wanted to then was to have internal items, i.e. animations inside the core animation, that would delay their animation until visible.

In order to demo this, I created a new Edge Animate animation and edited the stage to be very large vertically. I then created a Symbol and defined an animation on the symbol itself. Lastly, I set the autoplay to false.

So... now came the interesting part. I assumed I could do something similar to my previous entries. Wait for the element to be visible and then start the animation.

I began by working with the creationComplete event. I should point out that symbols have their own events as well. I'm not convinced I know what best to use here. I assumed that that the creationComplete on the stage made the most sense since to me, it meant that everything was ready. I then wrote code to get my symbol and used the same logic as before:

Pardon the somewhat wonky spacing there. If you read the previous entries then you know isScrolledIntoView is a utility function I included to see if the DOM item was visible.

Here is where things broke down. My item was being reported as always in view, even when it certainly was not! I added some logging, and discovered that when the web page loaded, my symbol had a "page x" and "page y" of 0,0!

And then things got crazy. For the heck of it, I added a setTimeout call for one second. When I did that and reported the position of my symbol, it was correct.

What. The. Heck. (And that's not what I said. ;)

Luckily I've got friends in high places. I spoke a bit with Josh Hatwich, a principal scientist on the Edge Animate team, and he suggested checking the display property of the symbol. When I did that, I found that my symbol had a display value of none initially, and then block in my setTimeout. This is why the positioning was so screwy.

What he recommended then was a simple fix - force the display property on the item and then check if it is visible. Here is the version I went with - there is only one line different:

And this works. (There is a demo link at the bottom.) Speaking more with Josh, he agreed that this use case may need some additional help from the JS API to work better in the future. So please note that what you see here may be better handled in a future EA update. I've included a zip of my code - but know that the .an file is not working correctly. I'm looking into that as well.

When you view this demo, you'll see a very tall pink box. In theory, you will not see a yellow box. When you scroll down and you see it, it should begin to move to the right. Please be sure you are sitting. My design skills are so incredible you may fall to the ground and I do not wish to be the cause of any physical damage.

Download attached file.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by rob boerman posted on 8/13/2013 at 12:58 AM

awesome! keep up the great work you doing

Comment 2 by Chris Jones posted on 8/13/2013 at 2:56 PM

Hi Raymond,

Thanks for taking the time to write another article on this!
I have tried to copy you instructions word for word in a new doc but mine just fails to play.

I have attached the link to my Edge file.
https://www.dropbox.com/sh/...

I know you had an error with your file so i cant access the 'creation complete' to see if mine matches up to yours in the Edge files and also i noticed your referencing the symbol "Symbol_12" but the asset in the library is named 'Symbol_1'.

Maybe this is to do with why my file isnt working and your file is braking? (it comes up with syntax error in the actions when I try to open any in your actions.

Again any help would be greatly appreciated Ray!

Many Thanks,
Chris

Comment 3 by Raymond Camden posted on 8/13/2013 at 2:59 PM

You have 2 of these:

Symbol.bindSymbolAction(compId, symbolName, "creationComplete", function(sym, e) {

Remove one.

Comment 4 by Chris Jones posted on 8/13/2013 at 5:48 PM

Hi Raymond,

Im not sure why it put that in as i only input this once into creation complete, but i deleted from 'test4_edgeActions' manually but still to no avail :(.

think i might have to give this up unless you have any other suggestions!?

thanks,
Chris

Comment 5 by Raymond Camden posted on 8/13/2013 at 5:53 PM

Can you put it online so I can run it as you have it?

Comment 6 by Chris Jones posted on 8/13/2013 at 6:15 PM

Hi Raymond,

Of course it is

https://www.dropbox.com/sh/...

Comment 7 by Raymond Camden posted on 8/13/2013 at 6:29 PM

I meant online as in _running_ online. :) But i downloaded it.

You have 3 issues:

1) I opened the HTML file, opened Chrome Dev Tools, and immediately saw this:

Uncaught SyntaxError: Unexpected token }

This is from test5_edgeactions.js, line 51.

You have an extra }); on line 35.

2) As you mentioned, your symbol name was _1, not _12, so I changed this:

mysym=sym.getSymbol("Symbol_1");

3) Finally, and this is partially my fault. I mentioned here (I think) that you should reference the earlier blog entries, and the isScrolledIntoView function. You need to include that in your code. I didn't include it above as it didn't change for this entry.

See this Gist for a complete working example:

https://gist.github.com/cfj...

Comment 8 by Chris Jones posted on 8/13/2013 at 7:00 PM

sorry i didn't realize you meant working online apologies!
Raymond thanks I love you it works!

one more thing, now i have done with "Symbol_1"
Could i hypothetically get this working on multiple symbols by adding another line like below for "symbol_2"? or is it another way?

Symbol.bindSymbolAction(compId, symbolName, "creationComplete", function(sym, e) {

console.log("Ready");
mysym=sym.getSymbol("Symbol_1");
mysym=sym.getSymbol("Symbol_2");

P.S i think this help deserves an item being ticked off your Amazon wishlist!

Comment 9 by Chris Jones posted on 8/13/2013 at 7:03 PM

Actually i just tried this and then it only plays the second symbol when in view!

Comment 10 by Raymond Camden posted on 8/13/2013 at 7:09 PM

Let me whip up another example with 2 symbols.

FYI - iTunes is having a huge sale on movies today so I'd much rather have an emailed iTune cert instead. Or a PayPal donation. And yeah, that's totally crass for me to even ask. But that's how I roll!

Comment 11 by Raymond Camden posted on 8/13/2013 at 7:28 PM

Ok, the solution. I'm writing this a bit quickly as I have an appointment, so forgive any rough edges. Also note - in general- the code could be tightened up a bit.

I added another symbol, symbol2. This was a bit higher and moved up and to the right. Look at this Gist for the full code:

https://gist.github.com/cfj...

There's some things you should note.

Obviously I duplicate the code to set the second symbol to block.

I use 2 variables, mysym1Started and mysym2Started as a way to remember which guys have already started. This will be explained in a second.

Look in the scroll handlers now. First, I check to see if this one already started, and if so, I leave.

I then set the started flag to true.

The final mod is - I don't kill the scroll handler unless BOTH were started. This ensures that if I scroll slowly and see my new one first (remember I built it higher) then it can start and finish, and when I scroll deeper, I see the other one.

TO BE CLEAR: I think this JS code needs to be refactored. I'm going to follow this up with something a bit more generic.

You can find a zip of the project here:

https://dl.dropboxuserconte...

Comment 12 by Chris Jones posted on 8/13/2013 at 7:43 PM

Thanks Raymond I'll go through this tomorrow see if it works for me, and make a donation also!

Comment 13 by Chris Jones posted on 8/15/2013 at 3:27 PM

Hi Raymond,

So i have got my simple file working correctly with this method, now i am trying to input the same code into my infographic, and it seems buggy, I have attached the infographic file im working on if you can help?

https://www.dropbox.com/sh/...

Two steps foward one step back! nearly there ;).
Paypal donation made!

thanks,
Chris

Comment 14 by Chris Jones posted on 8/15/2013 at 3:28 PM

oh yer one other thing adding my web address to the website button on your comment form crashes my internet not sure whats going on there!

Comment 15 by Raymond Camden posted on 8/15/2013 at 7:14 PM

Thank you for the donation. To your last comment, you say it crashes your internet - what does that mean?

To your issue: I opened up Chrome Dev Tools and looked at the console messages. From what I can see, it looks like the first (highest) symbol "works" but it keeps restarting. The second symbol (lowest) works right. It runs once. Digging now.

Comment 16 by Raymond Camden posted on 8/15/2013 at 7:18 PM

It was a typo. My code had this:

mysysm1Started=true;

Notice the extra s? It should be

mysym1Started=true;

Fixing this in the Gist right now. (In case you read the comment in the next 60 seconds and beat me.)

Comment 17 by Chris Jones posted on 8/19/2013 at 1:24 PM

Hi Raymond,

This works now perfectly by the look of it, Thanks for all your help this will definitely be a valuable asset in my Infographic to help give it the 'Wow' factor visually.

as for the issue in you comment box, the 'website' type box is always red even when i have typed a valid web address in (the others boxes ((Name, email etc)) are obviously blue) and if i try to submit a comment with a website input into it, it just crashes my browser and asks to restart. i have to delete or leave this box empty to make a comment :).

thanks!
Chris

Comment 18 by Raymond Camden posted on 8/19/2013 at 6:00 PM

What website did you enter? And what browser are you using? I can't imagine anything I've got here crashing it.

Comment 19 by Chris Jones posted on 8/19/2013 at 6:31 PM

just my website www.chrisjcreative.co.uk, i am using Chrome, just tried in FF and they both just stay red,

also tried www.msn.com just to see that also stays red, didnt crash when i just tried it just blocks me from posting if i have anything input into the website box.

Comment 20 by Raymond Camden posted on 8/19/2013 at 6:43 PM

You know those aren't valid URLs though, right? You need http:// in front.

Comment 21 by Chris Jones posted on 8/19/2013 at 7:13 PM

Ah ok I see, I just personally never put the Http:// infront when putting my address down, so i guess my fault!

Comment 22 by Raymond Camden posted on 8/19/2013 at 7:17 PM

I could make it more explicit. :)

Comment 23 by fagan posted on 5/30/2014 at 5:45 AM

I'd love to use this - but I get "There are JavaScript syntax errors in this Edge Animate composition's actions. Event Handlers cannot be created until these problems are fixed."

with your demo files. I think this may be due to your source files being out of date. Do you still think this is the best method?

Comment 24 by fagan posted on 5/30/2014 at 9:39 AM

Could please update your source files because I cannot find a way to get into the actions to edit the code. No matter what I do I get that error above.

Comment 25 by Raymond Camden posted on 5/30/2014 at 6:02 PM

You can try the code w/ Part 4 and see if that works better. I also have an updated one being published at Adobe in the next few weeks. (Hopefully.)

Comment 26 by Fagan Wilcox posted on 6/1/2014 at 3:55 PM

Hey there - I managed to actually get this working now! I do have one last question. Can you please make a suggestion regarding reversing the animations upon scrolling upwards. Scrolling down triggers the play - scrolling up triggers a reverse. If reverse is too tricky I'd really appreciate even just knowing how to reset them once out of view. Thanks in advance.

Comment 27 by Raymond Camden posted on 6/2/2014 at 6:04 PM

Well, you have a scroll event you can listen to. You could use that to notice the change, see if it is in the upwards direction, and reverse the animation.

Comment 28 by Fagan posted on 6/5/2014 at 3:24 AM

Thanks Ray - I believe I have it working however when I group all my symbols in a div it fails to trigger in my HTML page. When I release them from the div it works fine. Does the 'isScrolledIntoView' only work on top level element symbols? I'm guessing because it's a child in my setup now I need a way of drilling down eg; mysym=sym.getSymbol("SomeID/Symbol_1"); .. but nothing I try is working. Any ideas?

Comment 29 by Fagan posted on 6/5/2014 at 5:56 AM

The other thing is I have multiple instances of Edge Animate compositions on the page. Do I add the above script in each composition or just once?. I assume I need to give each symbol OR each Div a unique ID name?

Comment 30 by Raymond Camden posted on 6/5/2014 at 4:35 PM

The isScolledIntoView is focused on one particular DOM item. I think that answers your question, but not sure.

To your second one - the code is built for ONE particular DOM item, so you would need to use it multiple times for multiple items. I believe I covered this though in one of the blog posts in this series.

Comment 31 by Fagan Wilcox posted on 6/6/2014 at 7:56 AM

Thanks Ray! very big help. Here is my site now http://steaklab.com.au/ctm/...

I'm getting really inconsistent results with triggering the animations. Sometimes it works and other times not. I have a feeling this may be how I have set it up. You will see I put the 'isScrolledIntoView' into a separate js file so it loads once. But each edge asset has the remaining code relative to itself. I'm wondering if I should be consolidating this down into a single file?

Comment 32 by Fagan Wilcox posted on 6/6/2014 at 8:54 AM

Sorry I worked it out. It works just fine for small screens - but when it sees both compositions at the same time issues arise. I'll try adding all the my if(isScrolledIntoView(mysym.element) && isScrolledIntoView(mysym2.element).. into them and see how we go.

Comment 33 by Fagan Wilcox posted on 6/6/2014 at 9:11 AM

Ok Guys - that worked!! .. thanks again Ray for these.

Comment 34 by Raymond Camden posted on 6/6/2014 at 4:37 PM

Glad you got it. :)

Comment 35 by Mohammed Salman posted on 8/10/2014 at 1:45 PM

Hi Raymond,

Its very nice script and work fine but i had been trying to make a full page with adobe edge and without <p></p> tag in HTML page i mean pure edge that auto generated from it and i defined in actions side (creationComplete) if one symbol working fine but if i repeat it its will not work can you advice me in this case?

Thanks

Comment 36 by Raymond Camden posted on 8/12/2014 at 5:32 AM

I'm having a hard time understanding you, but it sounds like you want the same logic for N animations. if so, you should be able to repeat the code for each symbol.

Comment 37 by Mohammed Salman posted on 8/12/2014 at 8:40 AM

Hi Raymond,

If I repate it only one symbol work?? Otherwise nothing work.

Thanks

Comment 38 by Raymond Camden posted on 8/12/2014 at 2:48 PM

It should work is what I'm saying. I don't have a demo available on me. I thought I covered it in one of the later entries. You should check them.

Comment 39 by Mohammed Salman posted on 8/13/2014 at 10:43 PM

Sorry, I obviously wasn't clear enough I'll sent you an email with a demo to a test page i mean to figure out the issue I built to show you the issue. I appreciate your help!

Comment 40 by Mohammed Salman posted on 8/14/2014 at 2:22 AM

Finally, I just repeat the ("Symbol_2");and rename to ("Symbol_3")and its working fine with me, No need to figure out any issue Mr.raymond i know the logic of this script know ;)

if(isScrolledIntoView(mysym3.element)) {
mysym3.play(0);
} else {
$(window).on("scroll", function(e) {
if(mysym3Started) return;
if(isScrolledIntoView(mysym3.element)) {
console.log('Start me up 3');
mysym3Started=true;
mysym3.play(0);
//only disable if both visible
if(isScrolledIntoView(mysym.element) && isScrolledIntoView(mysym3.element)) {
$(window).off("scroll");
}
}
});
}

Awesome & Awesome & Awesome !!!

Thanks raymond for this article.

Advice to everyone should follow and read each steps and comments as well.