bannerScrub

Create Click and Touch Draggable Scrubbers with Edge Animate CC

Ever want to control your timeline animations in Animate with a scrubber? Here’s the sample to do so! Download the below files to learn how to create draggable scrubbers (both horizontal and vertical) so you can drag to control the timeline of symbols in Edge Animate CC. Use this technique to create scrubbable timelines, infographics, guide your audience through a story or anything else you can think of. These samples work for both touch and mouse events so they’re mobile and desktop friendly.

To get started, download the sample files. The code is well commented and broken down to explain how everything works.

View a super simple demo

…and I’ve made two “pretty” sample files which you can view here;

View the Sample File (horizontal scrubber)

View the Sample File (vertical scrubber)

Download All Sample Files

How it Works

(Disclaimer: It’s alllllll code from here)

When you download the sample files, you’ll notice three elements on the stage;

  • scrubber – this is the grabbable element used to drag the timeline
  • bar – this is the region used to constrain the scrub region of the scrubber
  • timelinePlay – this is the symbol timeline which will be controlled by the scrubber

All the code is contained inside the compositionReady event. Let’s break it down.

Several variables are set up which will be used as reference later in the code. Let’s start from the top:

var symDur = sym.getSymbol(“timelinePlay”).getDuration();

Using the Animate getDuration api, we’re able to grab the length of the timeline of the symbol “timelinePlay”. This is used to set the scrubber to control the entire duration of timelinePlay, regardless of the length of the scrubber region itself.

var mySymbol = sym.getSymbol(“timelinePlay”);

This variable is used to reference the symbol “timelinePlay” throughout the code. The following two lines for “scrubber” and “bar” are set to reference those elements.

sym.$(“mobileHit”).hide();

The scrubber was proving to be a little too tiny to consistently grab on mobile, so I created an invisible div (“mobileHit”) to increase the hit region. Sometimes the best solutions are the simplest.

Now for the Fun Stuff

I’ve set several bindings to initiate events for mousedown, mouseup and mousemove. One thing that may stand out is mousedown is bound to the scrubber, while mouseup and mousemove are bound to the document. This is because when bound to the scrubber I was getting undesirable jittery results; binding to the document after initiating the mouseodown event for the scrubber seemed to clear that right up. (*shrug* I don’t get to make the rules).

Let’s Make Some Scrubbing Magic

$(document).mousemove(function (e) { // Make the magic happen on mousemove
if (dragme) {
var possibleX = e.pageX;
var leftX = bar.offset().left;
var rightX = (leftX + bar.width()) – scrubber.width();
var scrubWidth = rightX – leftX;

Translation: When the mouse moves across the x axis of the page, use jQuery .offset to get the position of the bar element. Calculate the width of the bar to define the width of the scrubbable area.


// Confine the scrubber to the width of the bar
if (possibleX < leftX) {
possibleX = leftX;
}

if (possibleX > rightX) {
possibleX = rightX;
}

scrubber.offset({
left: possibleX
});

Translation: Calculate the scrubbable width defined by the bar and confine the scrubber to the width of the bar.

var relativeX = possibleX – leftX;
var stopTimeline = Math.ceil((relativeX / scrubWidth) * symDur);
mySymbol.stop(stopTimeline);

Translation: Grab the scrubbable region we just defined and do some math to stop the timeline of “timelinePlay” when the scrubber is released.

Make it Work on Mobile

All the code proceeding the above chunk is essentially duplicated, but to use touch events instead of mouse events. This function is wrapped in the following code:


if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)) {

Translation: If this is a mobile device, run the code to work for touch events.

In all fairness sniffing out the user agent isn’t always the optimal way to detect mobile vs. desktop, but it’s the method I’ve chosen to use here. If you have another method of preference hack it in!

All the code hereafter is moreorless a duplicate of the above methods but with touch events swapped for mouse.

The best way to learn is by getting your hands dirty, so go ahead and download the sample files and play around for yourself.

Special thanks to Darrell Heath and Jack Pitsker from the Animate community forums for putting together a fair chunk of the code used in these files!


143,575 total views, 10 views today

Posted on November 8, 2013 by Sarah · 39 comments

39 comments

  1. Daniel Echeverri
    - Reply

    Great post!! Im using it for an interactive info graphic. Im using your code to scrub on two symbols… the first one is an image transitioning to another… works perfectly, but the other one is a text that changes as the user scrubs. Im using a trigger on the timeline for each text change with the following code:

    sym.$(“Informes”).html(“2 Percent”);

    However, when I use the scrubber, the text doesn’t change. What am I missing??

    1. Sarah Author
      - Reply

      Ahh, unfortunately the scrubber seeks the timeline only and doesn’t pick up the triggers along the way.

      What you could try is creating multiple text divs and having the proper text hide and reveal with display keyframes (or use transitions). Good luck!

    1. Sarah Author
      - Reply

      Hey there,

      You can add a custom cursor to the element by using jQuery .css:

      Add the following to your compositionReady event for the stage.
      sym.$(“myElement”).css({
      “cursor”:”url(images/cursor.png),default”
      });
      Where myElement is the name of the element you want to target.
      You can also use e.target if you want to use the cursor on a mouseover/mouseenter event (or any event, really)

      Sarah

  2. Felix
    - Reply

    Hey Sarah!
    First of, GREAT post!
    Do you know why the scrubber jumps to the right of the cursor when you drag it?
    I need the scrubber to smoothly start my project!
    Big thanks!

  3. Felix
    - Reply

    One more question:
    Is it possible to make a element play when the scrubber gets to a specific position on the bar?
    http://weideryd.se/port/time/om.html
    In this case I want the “plane element” to play (fly) when the scrubber reach the third level bar.
    In the timeline i have set the “playback” to play after 3 seconds but nothing happens.
    But if i make the “timelinePlay” to autoplay (http://weideryd.se/port/time/auto/om.html) the plane starts to fly.
    Cheers!

  4. Uwe
    - Reply

    Hi there,
    I got a problem with the scrubber in combination with the new feature of edge animate to create responsive designs. The scrubber always seems to go beyond the bar when i start to resize the window.
    I think the problem is in this line of code:
    var rightX = (leftX + bar.width()) – scrubber.width();
    is there a way to somehow calculate the width of the bar by not using bar.width() because the width of the bar doesn’t seem to change when resizing the window with the new responsive design feature in edge animate??
    thanks..!

    1. Sarah Author
      - Reply

      Unfortunately I’ll have to rewrite the code to work with responsive scaling, as it’s looking for absolutely pixel values. On my todo list!

      1. Guy
        - Reply

        Hi Sarah, I am having the same issue with responsive scaling for the scrubber bar. Ideas on how to make the scrubber bar scale as well?

        1. vijay vanecha
          - Reply

          Hi,

          I have same problem, I found solution for responsive scrubbers.

          below is code,

          var el = document.getElementById(“Stage”);
          var st = window.getComputedStyle(el, null);
          var tr = st.getPropertyValue(“-webkit-transform”) ||
          st.getPropertyValue(“-moz-transform”) ||
          st.getPropertyValue(“-ms-transform”) ||
          st.getPropertyValue(“-o-transform”) ||
          st.getPropertyValue(“transform”) ||
          “FAIL”;

          var values = tr.split(‘(‘)[1].split(‘)’)[0].split(‘,’);
          var a = values[0];
          var b = values[1];
          var c = values[2];
          var d = values[3];

          var scale = Math.sqrt(a*a + b*b);
          var sin = b/scale;
          var angle = Math.round(Math.atan2(b, a) * (180/Math.PI));

          ——————————————————————————–
          now replace below code of rightX,
          var rightX = (leftX + (bar.width()*scale)) – scrubber.width();

          Hope it helps you.

    2. Dan
      - Reply

      Hi Uwe (and anyone else who finds this useful,

      I’ve found a solution to the scaling issue… replace line a) with line b) in both places – i.e. the touch area and the mouse area of the code.

      a)
      var rightX = (leftX + bar.width()) – scrubber.width();

      b)
      var scaleFactor = document.getElementById(‘Stage’).style.transform;
      scaleFactor = scaleFactor.replace(“scale”,””);
      scaleFactor = scaleFactor.replace(“(“,””);
      scaleFactor = scaleFactor.replace(“)”,””);
      var rightX = ((leftX + (bar.width() * scaleFactor)) – (scrubber.width() * scaleFactor));

      I hope this helps!

      If anyone finds a more elegant solution please let us know!

      Cheers,

      Dan

  5. Nate Maggio
    - Reply

    Thanks for this! It is exactly what we were looking for. Question: I tried it on mobile and although it works, I found it to be very choppy. Is there a way to make it more fluid? Thanks!

  6. Justin Hall
    - Reply

    This is exactly what I have been looking for for weeks, thanks.

    Two quick questions:

    1) How can I make it start at the mid-point of my symbol timeline rather than the start?

    2) How can I make it reset to that mid-point on mouseUp /touchEnd?

    Thanks again for an excellent piece of code

    1. Sarah Author
      - Reply

      Hey Justin,

      To do this you’ll have to do two things:

      1) On the Animate stage, move your scrubber to the place on the bar you want (let’s say the middle).
      2) In the compositionReady event, stop your symbol from the time that aligns with the new marker. i.e., sym.getSymbol(“timelinePlay”).stop(1000);

      Might take a little fiddling but this was the easiest solution I found :)

      Sarah

      Cheers,
      Sarah

      1. Justin Hall
        - Reply

        Thanks Sarah,

        I have done this and it sort of works. My biggest problem just now is that my scrubber is invisible and full screen (so as to make the whole page pan. Do you know how to prevent the scrubber from jumping to the cursor? I want to be able to drag from anywhere on the screen.

        Also, is there a simple way to reset the scrubber position on release?

        Thanks for your help,
        Justin

      2. Justin Hall
        - Reply

        Hey Sarah,

        I was wanting to use this method again but using the vertical scrubber. However, I want to be able to scrub from bottom to top. At the moment when I start the drag the scrubber and timeline jump to the end and I can’t scrub at all.

        Is there something I need to invert in the code to make it work backwards?

        Thanks

  7. Justin Hall
    - Reply

    @ Martin; Yes, you can replace the targeted symbol with your own, that is what I have done. Just make sure to either name your symbol “timelinePlay” or replace “timelinePlay” in the code with whatever your symbol is named

  8. Mimmo
    - Reply

    Hi, thank you for this grey work!
    I’m tring to inert this script in a page where i’d like to transform one div on the page from this:
    sym.$(“avati-green”).css(“display”, “none”);
    to
    sym.$(“avati-green”).css(“display”, “block”);
    when the scrubber is at 70% of the timeline.
    Could you help me?
    Thank you!

  9. Guy
    - Reply

    Hi, I used the horizontal scrubber file posted as a base for a timeline scrubber. All is going okay, but when I move the scrubber left to right or right to left, it auto highlights the text on the page at the same time. How can I keep this from happening?

    Thanks for any insight.

    Guy

  10. Guy
    - Reply

    I figured out my question above.

    But, I have a new question:
    When I set the file to Responsive Scaling, the “Bar” that the scrubber moves on does not scale as the rest of the page does. Is there a solution for this? Otherwise, the scrubber moves off the page when the window is scaled down.

  11. christopher
    - Reply

    Hi Sarah. I just wanted to put in another wish list, and I wish this worked with responsive design. You did an awesome job and thanks for including the files. <3

  12. Fagan
    - Reply

    Hi Sarah. Thank you for this demonstration.

    I’ve figured most things out but one I cannot solve. If I set timeline triggers, will they work when scrubbing the bar?

    Thanks in advance

  13. Peter Small
    - Reply

    Sarah,
    Thank you so much for sharing with us the click and touch draggable scrubbers. It is exactly what I needed for a new project I’m working on (a virtual reality Market Place).
    As I’m new to Edge Animator, it took me a little while to adapt your code to my project, but I managed to get it working perfectly on my IMac and on my IPad. However, it did not work on my android phone (Sony Xperia Z1) or my Kindle Fire. Any ideas why this might be so?

    Thank you again

    Peter Small
    peter@stigmergicsystems.com

  14. Paul Neff
    - Reply

    Hi,

    I thought I posted this question already, but I don’t see it. FOrgiveme if it shows up twice.

    First off, this his slider works really well, thank you! I need to add up and down buttons to it to create an old-school scrollbar. I’m very new to EA and a lot of this is still Greek to me. Looking at the code I’d think it’d be fairly simple to add the buttons, but I just don’t know the language well enough to do it without help.

    Any help would be much appreciated!

    -Paul

  15. Carlos
    - Reply

    Hello Sarah,

    I was wondering if this was possible in EA and you answered my question. I want to know if there’a a way to make the slide work in both computers and touch screens at the same time. I’m not the most experienced with JS but I suspect the “if” “else” statements are controlling how to interact with the slider.

    What I’m looking is to be able to control it with both mouse and touch actions. Is this possible? Again thank you for your wonderful work

  16. Carlos
    - Reply

    Hello Sarah and everyone else,

    I guess my question also disappeared, so I’m sorry if it shows again.
    I was wondering it’s possible to enable the draggable actions for both touch and click events.
    I’m trying your tutorial on a SurfacePro3 and can’t drag the scrubber by dragging on the screen.

    Thank you for your time
    -Carlos

  17. Pat Broderick
    - Reply

    I’m wondering if there’s a way to add a play/pause button in addition to the to the scrub bar so that the scrubber would move automatically in time with the animation when “play” is hit, and would stop in place when “pause” is hit. The idea being that someone could pause the animation halfway through, grab the scrubber and move backward or forward manually as needed. I can get the animation to play/pause with a button, but can’t figure out how to tie the scrubber to the animation without a touch and drag.

  18. Thisara J. Udawela
    - Reply

    Thank you very much. I was looking for this kind of thing fast week all over the internet. finally got this. thank you again.

Leave a Comment

Your email address will not be published. Required fields are marked *