Playback widget

Hi guys, I’m working on something to replace the typical animation toolbar.

The old toolbar looked like this:

OldToolbar.png

I have a new thing called the “Playback” widget. It pops up looking like this:

Playback1.png

The bottom-left is “Reset” (same as before). On the right is faster/slower, same as before. The large middle button acts as a play/pause toggle, or really a pause/un-pause toggle where “un-pause” puts you back into whatever mode you might have been in before pause (rewind, realtime, etc).

The upper-left button is called “Shuttle ring.” Clicking it results in this:

Playback2.png

The shuttle ring is may look familiar to folks who have used video editing systems. It is a ring offering a continuous control of forward and backward speeds. You can slide the “green glow” indicator smoothly around its entire edge, like this:

There is also a button tucked under the top-center of the ring, called the realtime button. It sets the time to “now” (from the computer’s own clock) and animates along at real time. Pausing this mode for a length of time, and then un-pausing via the center button, will cause it to jump forward to catch up with realtime. Using the shuttle ring will pop out of realtime as you expect, and animate forwards or backwards from there.

This functionality is available for testing now on my “playback” branch of Cesium. It’s implemented in SVG and works on mobile (FF & Chrome for Android), although currently you can only tap, not slide the shuttle ring on mobile (touch events not hooked up yet, pending resolution of the camera & pinch-zoom branches, that’s a different story). But once the other branches are worked out you can be sure I’ll be hooking up touch events for this, in the meantime you can still test it as a work-in-progress on mobile and of course more fully test it on a desktop/laptop.

One remaining needed feature is “themeing,” how important is that to everyone? Currently it’s just hard-coded to a dark theme, but I was talking with some of the other Cesium devs about adding a CSS style sheet, reading values from that sheet in JS, and constructing my SVG gradients based on the values read. This would allow simple CSS styling of something that otherwise would require changes to SVG-generating JS code.

Anyway what does everyone think of all this? Does it seem like an improvement over the Dojo toolbar? The new widget chips away a little more Dojo dependency by the way, it uses only plain JS and SVG, not Dojo to implement the widget. We have a separate debate going as to how much effort to put into our own native widgets like this one, vs how much to rely on 3rd party widget sets, but that’s a topic for another thread.

          --Ed.

Ed,

Thanks for sharing this. I think it is a huge improvement. The current timeline with it’s buttons and time label take up a lot of real estate, which is especially noticeable when Cesium is embedded in a blog or a website, even the demo on http://cesium.agi.com/. Just like modern web browser’s UI, we should keep everything out of the way except what is commonly needed.

I really dig the shuttle ring. However, I didn’t know to drag instead of just click so perhaps an (automatic) tooltip the first time the shuttle ring comes up will be good for novice users. After that, they will never look back; it is too slick.

I’m not sure that we need all the buttons on the left when the shuttle is not shown. We are providing two ways to do the same thing. Also, I don’t know that operations like increase/decrease time step are common enough to justify prime screen real estate. If you’re looking for suggestions, I can come up with some.

As for full touch support, it is going to be awesome, but I don’t consider it a requirement to merge this into master.

For themes, I am definitively interested in users being able to change the appearance but again, don’t think that it is a requirement before merging this into master, especially if it is not a breaking - or significantly breaking - change.

I’m curious how will/did we write tests for this?

Regards,

Patrick

Playback2.png

Playback1.png

OldToolbar.png

I talked to Ed in person with my initial feedback, since I was confused about behavior at first (and didn’t know how best to articulate it). While I think me and him are on the same page, I’ll try to recap everything here for everyone’s benefit.

Let me start by saying this is an awesome effort, and I appreciate the work Ed has put in so far.

  1. When I first started to use the new UI, I was really confused because the shuttle ring has what looks like buttons on it (for play/pause/reverse/faster/slower), but clicking on them did nothing and instead caused the clock multiplier to jump.

  2. It’s not intuitive to me that big button is play/pause. What was particular confusing is that clicking on it with the shuttle ring up seemed to make the shuttle ring go away but not play/pause the clock.

  3. I like the “jump to real-time” button, but I think it’s confusing that when you pause it and then un-pause it “jumps” to real-time rather than picking up where you left off. If the user wants to go back to real-time, they should just hit the real-time button again, not play.

  4. I wanted to stay in shuttle ring mode and it kept going away.

So it was at this point that I went over and grabbed Ed to have him explain things to me and found out the shuttle ring “buttons” where just graphics and all my assumptions were wrong.

After thinking about it and talking to Ed, here’s what I propose.

  1. Get rid of the dual nature of the control and just have it always be in “shuttle ring” mode.

  2. Clicking on what I thought were buttons on the shuttle ring should actually be buttons. So you can easily hit play/pause/reverse/slower/faster from there. Click-dragging would change the clock multiplier slider just like it does now.

  3. Real-time button works the same way it does now, but pausing leaves real-time mode and resuming picks up where you left off.

  4. Change the “big button” in the center so that it brings up advanced options panel that let’s you manually and fully configure the clock, such as current/start/stop, whether it’s bounded, looping, etc. These settings are important, but not as often accessed, so the big button would be a good way to allow them to be configured.

  5. Add tooltips for everything.

Obviously, these are just my opinions. I strongly recommend everyone to actually try the new widget hands-on, to see how you feel. I made the mistake of assuming too much based on how it looked, and you really have to do it hands on to get a feel for it. When designing UIs like this we need everyone to pitch in.

As for non-usability issues, here are some additional thoughts.

  1. I’m fine with trying to keep as much of the code as possible “toolkit independent”. Cesium itself doesn’t rely on third-party toolkits and there is no clear standard in the marker.

  2. That being said, we absolutely should not be re-inventing the wheel with our own mini-toolkit. The moment something is complicated enough to need a toolkit, we need to have an abstraction layer that lets the toolkit handle it.

  3. Theming is a much (in my opinion). If I build an app with a dojo theme, I want my UI to follow that theme completely. That doesn’t mean we need to actively support different themes, it just means we need to have the capability for a developer to theme/skin the control when needed (preferably via CSS).

  4. The code all needs to be as unit-testable as possible.

What I recommend is that we follow something akin to the Model-View-ViewModel pattern. Essentially, all of the “business logic” is toolkit-free and placed in a “ViewModel” object. This object exists purely as a state machine to drive the GUI. It’s written using the core Cesium “Model” objects. Then, we create a “View” for each toolkit we support which is wired up to the ViewModel via event notification. This means no business logic is in the View and it should be trivial to support multiple toolkits with a single ViewModel. There’s no need to unit test the View because there’s no logic in it. Instead, you simply write unit tests against the ViewModel and that covers all of the code you care about.

I’ve gone on long enough, thanks for making it this far (if you’re still reading). I haven’t looked at the code proper yet, but I’m sure we’ll have active discussion in the coming weeks to get this new tool ready to come into master.

Thanks again Ed!

Matt

Playback2.png

Playback1.png

OldToolbar.png

Thanks for the feedback so far. I’ll try to address some questions here, starting with architecture.

In master we have a ‘Clock’ object and an ‘AnimationController.’ The new playback widget is built on the AnimationController, you must pass one in for construction of the widget. The widgets various operations control the animationController, and the widget knows how to update its visual state to match the animationController without redundant DOM modifications. The widget has some new operations like the realtime button, but on this branch both Clock and AnimationController have new API points, with new unit tests, to support the new buttons. So, you can access this new functionality via new API on AnimationController. I’ve tried to make certain there are no playback-type operations carried out in the widget itself. The widget has some SVG logic for the display, but its functionality is just to manipulate an AnimationController object.

A good test of this is the Two-widget demo in Sandcastle (a reference to two CesiumViewerWidgets, each with their own playback widget). You can see that manipulating one playback widget affects both of them simultaneously. Because they’re sharing an AnimationController, both of their update routines respond to changes made from either one, and respond to changes made by the timeline widget etc. Note this is different behavior from master, where the Dojo toolbar can show the play button highlighted in one window with the pause button highlighted in another, because Dojo is maintaining obsolete state instead of querying the AnimationController (fixable of course).

The next challenge I think will be to visually make the ring look like it has a piece that rotates. This is slightly complicated by the fact that the ring isn’t circular, it’s designed to be wider than tall for space reasons. But enough new users have said they didn’t realize that you could drag it, the labels on it look too much like stand-alone buttons etc. I’m concerned that actually making the labels act like buttons will only exacerbate the problem, and obfuscate the true purpose of the ring. Instead, I’m thinking that (a) the “green glow” needs to look more like a dial’s pointer somehow, more obviously rotate-able in some way, and/or (b) clicking the ring could have the glow or pointer swing around to the new position instead of instantly jumping there.

In other news, the ring has its own close button now, so it won’t disappear unexpectedly anymore. It turns out the faster/slower buttons do have a purpose alongside the ring, as they allow you to go slower than realtime (the ring does not) and faster than the ring’s maximum speed (although these faster/slower functions are currently unbounded, which causes its own problems, maybe they too should be bounded to some reasonable range larger than the ring). We may have to do some real usability testing with people who are more interested in interacting with the scene, rather than poking at a new widget, to see if they end up needing both the buttons and the ring.

Keep the feedback coming! Thanks,

                --Ed.

Ed,

Without actually looking at the code, layering the widget over AnimationController sounds right on.

(b) clicking the ring could have the glow or pointer swing around to the new position instead of instantly jumping there.

I just ran your branch again, and I totally agree.

I also agree that we should do some usability testing. I think we will find that having two modes (ring vs. no ring) confuses folks and that hiding the play/pause button behind the time text hides one of the most common operations. Make the easy things obvious, and the hard things possible. I’d like to see the ring up by default, but scaled based on the window size to minimize real estate. Don’t believe me though - do the usability testing. We really need to do some usability testing for Track Santa too.

Regards,

Patrick

Hi guys,

Our Clock/AnimationController objects have three playback modes: Loop, Clamped, and Unbounded. In “loop” mode, playing forward past the end time loops back to the start time. Here’s an odd question: Would anyone mind if playing reverse to the start time paused (clamped) there instead of looping to the end time?

We made Loop bi-directional mostly because the name implies it, not because users need to ever loop in reverse. We have a separate “Reset” button to take you to the start time, which allows you to emulate the effect of clamping there without leaving loop mode.

If we make “Loop” mode a uni-directional loop, then we can get rid of the Reset button. Playing backwards (with the always-open ring) will hit the start time and pause there, without a reset button. Also in “Unbounded” mode the Reset button doesn’t make sense as the start and end times are unused (The Realtime button makes more sense than Reset in that mode).

Having the shuttle ring permanently open takes space away from other buttons. But the faster/slower functions are what the ring is for, the “open ring” button isn’t needed with a permanent ring, and the only remaining button is Reset, which itself is redundant since you can so easily play super-fast-reverse with a permanent ring.

So I’m proposing that we redefine Loop mode (on my branch) to be a one-way loop, end to start only. Then I can kill the Reset button and have a permanent ring. What do you think? Yes we’ll do the usability testing – I’m asking what do you think about making Loop mode one-way, could you live with that in the API as long as it was fully documented?

  --Ed.

Ed,

I’m the wrong person to ask, but I don’t know any use cases for looping backwards. Looping forward, of course, is very useful when demoing. Perhaps a rename, like ForwardLoop would be useful. However, I’d get more input. Amato and Kevin probably have ideas.

Patrick

OK. Shuttle ring looks different now, and doesn’t hide or go away at all. I didn’t do the looping thing yet (still planned). Take a look:

NewShuttleRing.jpg

  --Ed.

Ed, I tried the latest head of the playback branch and while I appreciate that you are trying to simplify and streamline the widget, I unfortunately find it much less usable. Here are my thoughts in no particular order.

  1. Rather than have the needle jump to the pause location when pause is clicked, can’t we keep it where it is, this way I still no how fast it will animated when I start back up? Right now it also makes it hard to click the button again when the arrow is on it.

  2. Can we turn the pause button into play when it’s not animating (and vice versa).

  3. I believe it’s a common use case to slow down to slower than 1x in order to see an event (such as an access) that only happens for a fraction of a second. It looks like you’ve eliminated this feature in the new GUI. I also don’t think I like the cycle “through” pause, for lack of a better way to describe it.

  4. Similar to 3, since you eliminated the forward/reverse buttons, it’s now impossible to easily animate backwards in one click. For example, if I’m watching at 30x and I miss something and I want to go backward at 30x to see it, I can’t do that anymore, I have to cycle through all of the other modes with the buttons. Trying to simply click 30x on the scroll is too inaccurate.

  5. As for your animating backwards comment earlier, I have no problem with stopping at the beginning when animating backwards. If we ever need to add the feature, we could take a play out of STK’s book and make the loop/stop setting settable independently for stop and start (but that’s seems like overhead for something people will never use, so lets not add it until we need to)

A new widget is great, but we need the same level of functionality that we already had. Part of me things that having all buttons (Reset/Pause/Play/Reverse/Faster/Slower/Realtime) simply laid our horizontally and enveloped by the ring would be the better way to go, since you didn’t like the idea of the buttons on the ring being clickable and removed them instead.

Hopefully that all made sense. Let me know what you think.

Matt

NewShuttleRing.jpg

Ed,

I was also just looking at this:

  • The common case should be easy, right? It wasn’t clear to me how to start animation. I had to guess that the fast-forward button would start playing.
  • Run Viewer and resize it to the size of the demo at cesium.agi.com. Doesn’t the ring look big? Can we scale it? Also, the leftmost date on the timeline is cutoff.
  • Aesthetics: Will the ring be transparent like the timeline? Will the arrow slide on click, not jump?
  • Amato already said it, but there should be a way to control the speed range and deltas.
  • You might have already mentioned it, but I didn’t know how to reset the animation.

Although I think Amato and I are providing pretty good input, I’m not sure that our process is all that efficient. I really like your idea of doing some usability testing. If you gather a handful of volunteers, perhaps a STK power-user or two, I suspect you will converge on something awesome and usable. Make the common thing’s easy and the hard things possible.

Patrick

NewShuttleRing.jpg

Hi guys, thanks for the feedback. I’ll start with Amato’s points.

1 & 2: keep the needle where it is and show the play icon on the pause toggle. Yes, that should be fairly easy.

  1. My two testers so far (more to come) liked the cycle-through-pause after I told them to do it, but neither of them discovered it on their own. Not good. I’ll probably remove it in favor of the incrementally smaller time multipliers. We’ll do more testing once that’s back in, but I suspect the new buttons won’t work exactly like the old speed up / down buttons, because the ring puts slow at the top and fast at the bottom. I’m going to try them with their current left / right style minus the ability to pause using them.

  2. Are we certain that some users need the ability to animate backwards at exactly the speed they had going forward? Especially if they blew past something, maybe they should grab the ring and walk backwards a little more slowly. I’m not opposed to re-adding these buttons, but I would like to avoid having them take away real estate for the best part of the ring (which is where their labels were in the previous incarnation). One option is to add a “reverse” button in the upper-left alongside the ring, that turns into a “forward” button when you’re going in reverse. Maybe I’ll mock that up to see what it looks like.

  3. What happened to five?

  4. Sounds good.

Cozzi’s comments:

  1. This should be fixed with Amato’s item 1 (the pause button will look like a play button while paused, in the next version).

  2. The new widget is a little taller at 200 x 132 CSS pixels. It replaces the anim toolbar, about 267 x 38, the hover-only, mobile-unfriendly speed indicator, about 172 x 38 (while paused), and also the clock display, 256 x 38. So the total area is similar even though the widget has a whole new ring surface that the others don’t offer. The new widget also doesn’t hide part of itself (speed indicator) on mouse-out, and because it’s unified it can displace part of the timeline widget (saving an additional 200 x 25 pixels). Long story short, it’s new functionality with a bit of total space savings, taller but not nearly as wide. It takes one corner of the screen instead of most of the bottom row with both bottom corners. The original intention was to have the ring hide away when not used, saving even more space, but usability won that one.

  3. There’s a line of commented-out CSS to make the ring transparent. You can see the misplaced Bing logo behind it when this happens, because of Issue 361. Other than that it looks very cool.

3b. I’ll work on the ring-click-slide thing after the bigger issues here have settled out.

  1. Configurable speeds: Probably useful. Not implemented yet.

  2. New reset ability: Not implemented yet. Still planned.

      --Ed.
    

NewShuttleRing.jpg

OK. I think we’re close to a solution here.

NewShuttleRing2.jpg

The reverse / pause / play buttons show the current mode, and the “old speed” is not only visible in pause mode, but you can actually adjust the speed while in pause before resuming.

Clicking on or near the green “pointer” on the ring lets you click & drag it just like before. Clicking farther away on the ring acts like the speed control buttons (which after a dozen iterations have finally been ejected from the layout).

The realtime button now uses the word “Today” because multiple people confuse realtime with 1x. It’s been moved to the left side so that the slower speeds are more accessible. You can get even slower speeds by using the incremental ring clicks instead of dragging.

No visible reset button, but I implemented the one-way loop, so in a CZML scene with start and end times you can get to the start time by animating back.

I’ve contaminated you all with this because you’re already contaminated by previous iterations and expectations from this email chain anyway. I’ve been finding virgin testers here and a number of usability issues have been smoothed out as a result. I’ll keep this process going tomorrow.

      --Ed.

Hello guys i have an issue with the cesium clock reverse ,forward ,pause and shuttle ring arrow svg images not getting loaded on FF 52.6, but the functionality is running fine.
I tried every single way but still couldn't solve the issue.
Works fine in chrome and IE.

I need a solution for this. this should be done by not upgrading the FF version (that's my limitation) and already tried cesium versions but same with all.

It might be an error with the CSS. You can override the default Cesium styles with your own additional CSS. Use the browser developer tools to inspect which classes are on each element, or look at the Widget source code.

Thanks,

Gabby

Hey Gabby actually i found the reason it is due to the Firefox requesting the svg image without using basePath.
Since am using Angular 2 application i used the LocationStrategy that solves by setting basePath.

Thank you

Awesome, thanks for following up with your solution!