We’ve heard a lot about user experience and I don’t think that’s a coincidence. I think we’re clearly a community that gets the value of user experience and it flows directly out of some of the core ember values right. We work hard on shared solutions in infrastructure so that we spend progressively less and less time on that minutia and then the work that’s left over the work we never get rid of is the hard stuff right.
It’s deciding how to generate that great experience for our users and when you think about user experience, design, most people think right away about building experiences for end-users right if you’re a front end dev. That’s you do that a lot! Maybe you work with somebody whose title is actually user experience designer and those people are awesome. They help an awful lot, but I want to argue that every developer period, full stop is always a user experience designer.
Sometimes your user is an end user. Sometimes your user is another developer who’s going to have to interact with your code, sometimes that user is your future self that you’re either helping or punishing when you’re going to come back to that code months later, to look at it all right. So so this talk today is going to talk, i’m talking about user experience and there’s two key audiences whose experience, but I want to talk about today.
The first is the end users that we’re serving and building great experiences for them, but the second, of course, is the great experience for Amber developers right and those are two sides of the same client. I don’t think you can have one without the other. So so that’s that’s the kind of big picture of where I’m going with this talk, so so computers right there like they’re, really abstract and that’s what’s awesome about them, they’re, almost infinitely flexible right, you’re.
The kind of things that you can present to the user are limited almost just by your imagination and that’s one of the things that makes them awesome. But it’s also exactly why computers are so intimidating and frustrating for so many users, and so many people, because we have all this amazing machinery in our heads in our eyes, for processing the physical world right. The physical world is what our brains evolved to process.
We have all these cues and hints that we take advantage of and take completely for granted that almost every human being can do, and it makes its ways of thinking ways of perceiving ways of understanding where you are and what you’re doing. What’s going on around you and when you take human beings and you drop them into a screen world with very abstract shapes and things that don’t behave physically, they get lost and all of a sudden, you actually disabled help chunks of their own ability to think and Perceive all right there’s a lot of different ways, humans think and perceive, and we leave a lot of that behind when we limit ourselves to a very abstract, visual kind of in the square box.
Now, that’s that’s. Actually, a really big problem, that’s bigger than anything. We can address right now here we’re going we’re going to talk about attacking that problem and chipping away at it. The larger problem is one that we’re all going to work on over the long term as we build better and better interface technologies. But we can talk about at least making the visual piece that we do have control over much closer to physical reality.
And we do that by bringing in constraints, so your computer can’t show anything right. You don’t have to pretend that the objects on the screen have mass or momentum or that they cast shadows right. They can go anywhere. They want, when they’re not on screen they’re, not really anywhere right, but that’s deeply weird to get to human beings, and so when we constrain ourselves and we put in the extra effort to pretend work ago – that’s the underlying reason.
We see all these, that’s why we feel so great about the user experiences of more physical. You is so so. Some of our earlier talks have already mentioned Google’s material design, spec material design is or it’s a wonderful document. You should check it out and look Lauren tan said to us yesterday. Remember that design is not about how it looks right, it’s about how it works, and so, even if you have no interest in making your app look like googles apps that they write when they design with material design.
The principles in there are extremely good stuff and they touch directly on what my earlier point about physical constraints. So here’s a quote from the introduction to material design – and I highlighted in big bold letters without breaking the rules of physics and the doctor goes into a lot more detail about what they mean by that. But there’s you know the kind of examples are things like to fit? Two objects should not really be able to pass through each other, or you know things that are on top of each other, actually do cast shadows or things don’t accelerate instantly from zero to going fast right.
All these little things, the fundamentals of light, surface and movement. Here, there’s that word movement again right motion respects and reinforces the user as the prime mover. So this is why we care about motion right. We had a great demo of all those polymer driven animations. That’s exactly what I’m talking about the reason that stuff is so appealing the reason we immediately get. It is because it’s appealing to that part of our mind that makes these things seem more physical to us.
So then, of course, the key question is how does this fall into embers, broader architecture, and this is where we switched switch. The focus from the experience of the end users to the experience of the other developer, all right, the the challenge that we always have. If we develop ember and we evolve it together, as a community is to find great ap is that we cannot live with and work together with and build great conventions and tools and move on to build the next great thing.
So, let’s so we’re, if I’m going to talk about today, is where you fit all this stuff to the other architecture and how you do it so animations and motion in general right when I so I guess I should first point out right. I’m kind of using the terms interchangeably animation can mean a lot of things. Remember the principle I just had on last slide about the user. Is the prime mover right? That’s really the kind of animation we’re talking about the user does something, and then we have smooth motion in reaction to the user, as opposed to the kind of animation that we have has had in terms of like flash ads where you have to whack the monkey Or you know, that’s not the kind of animation of talking about so animations really live in the gaps between what was and then what becomes all right.
The animation is what’s happening in between what they were seeing, what the state was and what the state becomes, and so it’s not really something. That’s a property of your save, for example, a template and number, because the template is the static thing at the end right. You have a template before you have a template after and that’s the conventions that were great for us, so you need to find a place for the animation that is neither here nor there, but in between, and so that was the kind of key inside that led Me to publish the liquid firing animation library back in July, which came out of some great conversations, and you know talks that I did a Denver cop last year.
So I’m going to do a I’m going to launch into a little demo of some of the good fire stuff and talk about how we, how we find a place in the upper architecture for all these kinds of rich behaviors. So the first step, of course, is installing it and yay for Amber add-ons. We just have one command to install it right now. We do have two branches because of all the evolution in ember island. This is a project that I care a lot about, supporting across the whole wide range, so it actually is tested in CI against everything for a member 18, all the way through the canary we’re committed to supporting that, and I’m really excited to be announcing of 10.
Alongside in verse, 20 this summer and yeah, that’s really good right, yeah. Thank you, and – and that’s really kind of my point about this whole demo, which is that we want this to be something that every ember app can do, and it shouldn’t be that it shouldn’t be a big extra deal right. The goal is to make it so easy that it’s almost, why would you not build rich interactive applications right, so I’m going to show a demo here and I guess I’ll turn up my font size.
So do I fit okay? This is an ember app. The Ember cap website is not actually a number out now did not have the source code to it. I just decided it was kind of a nice example data to play with so I web scraped it and I put India tiran like W get before I got on the plane to fly out here, so I would have it all, and this is kind of fun Trick you do with ember. Actually, you could take somebody else’s website, grab all the static output, not even knowing how it was assembled on the server or whatever drop it into your application, template boot of ember CLI, and you have an embryo right and you can start to very incremental eerie factor.
It into an actual member app you could take out the pieces start to make them templates start to take the repetitive data out infinitive models as well. What I did to put this together. So it’s very simple right. We have our list of speakers here and oh, I already have the fancy stuff turned on. I wasn’t intending to do that way. Let’s see we’re going to go back a bunch of commits, ok, ok, so this is a very stock amber app.
The point of this is to say, there’s nothing up my sleeve. Ok, this is a standard, ember app, that’s doing very standard number things you’re going to see the tempest in a minute, but we have a speaker’s list. They do have this nice little physical Balki nest right now. That’s very simple right, that’s one CSS rule to say on hover, translate up a little bit all right! That’s nicely self-contained right! This is the kind of there’s a lot of little subtle details in building physical design that are self-contained enough, that you don’t need to go use some big library to do it right.
A lot of these are little details that you just have to get right as you design and as you build, and those ones are the easy ones because they’re not there’s their local right. We’re going to talk about some of the less local things um. I have a shuffle button here that just reorders the people – okay and we can go and see the details of each of these people and I’ve also just to give us something else to play with.
I put an inline editor in here, where you can click and edit right in and change something and save in go back. Okay. So that’s our simple demo app right. So we want to give some nice to Richard reach your interactions to this, and so so we do the NPM install liquid fire right. I have that already. Let’s move up one more Kim it here, so my the first thing I’m going to do, I may be switching back and forth to the code and the demo someone’s will just do it like this.
Let’s see so. The first thing I’m going to do is this is my so I have my top level. Route of this is called Enver, kotta HPS, and I had an outlet before between a header and a footer component that I this is just the stuff I copied off the website right. I put me to not lit i’m switching it to a liquid outlet. That comes from the library and that’s not going to change any of my behavior yet well, it can do one subtle thing: let’s take a look to see if you notice.
So when I go to the next view, I have one little subtle bit of motion. My foot is going up and down. So that’s the first observation about what we’re doing here. One of the tricky things about putting animation into your existing application is the management of context and flow in your document right. Well, no matter what kind of animations you’re trying to put in whether you’re implementing them on the web animations API on, I my default when I use in this library philosophy j/s, where they’re using CSS transforms a lot of these things work best.
If you are absolutely positioning your content, but that’s a real pain in the butt, when you’re just laying out your normal flows, you want to be able to take advantage of all the kind of layout that you do normally in your your templates in CSS. So this the first thing you’ll notice, is that the liquid outlet is is a smart container for us, it is actually not interrupting our flow at all. You’ll notice.
I was able to drop it in. I didn’t have to change these style sheets, but it also has this behavior a notices that stuff’s changing inside of it and it’ll measure the before and after States has smoothly changed so that I’m already doing being a little less jumping right. But it’s not doing anything. Anything cooler yet so the next thing we’re going to do go into my next change. Geez. I need to find a way better way to switch between these.
Can you guys see them okay at this size? If I don’t go, fullscreen? Ok, ok! So I could zoom in a way there we go. So the next thing I’m going to do is I’m creating a new file called app / transition cas, and this is a conventional thing from the library it’s there. So your transitions file you can think of it. Analogous to your router map, its intended to be a global place to gather up rules about how your application behaves, and this is a kind of important thing.
You’ll notice that I didn’t go into the liquid outlet that I added and set a bunch of configuration about how it should animate. I think that’s the wrong place because that outlet, but right now it might only be running these two routes, but as our application grows right, we still want to have that great experience of being able to reflect an understanding grow, and you can have very sophisticated reasons For animating different ways at different times, much more than you can express just by setting a few properties on that component.
So that’s why I came up with this idea of having a separate transition map that can let you lay out logically in a kind of imaginary physical space, where all your, where are your routes and components, have used how they relate with each other. So in this case, I’m using to constrict constraints of from route constraint and to route constraint, and I’m saying and then I was saying what animation to use in a moment we’ll show you where the innovations come from, so already we’re going to do better.
Now, right we’re going to fade nicely from one to the next you’ll notice that the fade happens. When I go from the list of all to the detail, it doesn’t happen on the return. Yet that’s because my rules here are directional right. I said that the from route has to be the speakers so because this is but because this is directional and because directionals very common thing, we have a shortcut for that right.
Where can we can swap it so that we now have separate things for both the forward and the reverse? So, let’s see now we go back and forth okay. So the important thing here is that we have a way to declare separate from our our content and notice. I haven’t touched my templates. This was a totally stock application, I’m beginning to add this behavior without polluting those templates with complexity.
Okay, now, let’s talk about where that fade animation comes from and how its implemented, because this is actually one of the things I don’t think people have appreciated, even some people who use liquid fire. So, let’s see make you bigger. This is the wrong one. There we go another super simple one transitions, so I wanted to show you a kind of minimalist example of how you implement animations, because I think a lot of people, even those of you who might have tried out this library, tend to be using the handful of Built-In animations that I have fade to left to right up and that’s great that’s what they’re there for, but one of my goals is to get us to arrive on a very comfortable API where we have composable extensible ways to define animations and literally just drop them Into Enver add-ons and UVA, you could actually right a cool animation put in a number out on and publishing.
Somebody else could just import it to their app and put it in their transition up and use it right. So this is an example here of a very straightforward fade animation in this case i’m using velocity, which is a pretty nice animation library to do the actual animation. But you know liquid: fire is not an animation library. Really. All it is is a way to organize ember applications and give you a place to put your animation calls, and so, in this case i’m using velocity, but that’s not at all required.
You can use your css3 transform here. You can use your web animation api just like the polymer stuff we saw on that other talk. All those kind of things can go right in here, so your call – all it has to do is its receiving a context that has things like the old element and the new element they’re both already in the Dom the new one is invisible and and they’re already Absolutely positioned for you, based on where they’re going to end up in their final flow, all right, that’s the hot! That’s a lot of the hard scut work of building.
One of these kind of behaviors is getting that all set up, and that’s really the point of what liquid fire is doing. It’s getting you set up to do an animation and then letting you drop in something that’s going to do it in this case. We’re going to animate the old saying to opacity, zero and then, once the promise resolves we’re going to animate the new thing to opacity, one and that visibility visible.
That’s a shorthand that the velocity gives us to bring it, bring it visible at the starting animation. So we don’t get any flicker, so let’s do the next thing so up so now. This is stuff. People have probably seen if they, if they checked out the library, but now i’m going to start show some newer things. So I mentioned really wanting to be able to compose rich behaviors out of smaller pieces, and I think now, as we approach a 10 API, I’m settling on a much simpler way to implement this stuff.
Here’s an example of a new transition called explode. Now, explode doesn’t buy itself, actually move things around, but what it does is it gives you the ability to then add a basically the animate separate pieces of your page separately right, we’re going to explode the old. The new views pick new here means, for the new view, find an image and then use the two up transition on it, and then the kind of the two left at the bottom is for everything else that didn’t match right.
So now, when I go over that image, the final image you’ll notice is coming up from the bottom. Okay, let’s slow it down, so we could see it better. I think that’s my next commit yeah so, and this will show you that all of these animations they can take parameters to right. We pass them through when you implement animations, they can just receive arguments. Just the wave function should so now they should go slower and you can see a little better.
What they’re doing okay. So now, let’s take a look at because we have this explode capability. Explode is really remember that every transition has both an old in a new element that we’re comparing and explode is no different, so it can match up elements on the old and elements on the new. So let’s switch to unjust new match by okay. So it looks like this i’m going to say match by data speaker ID now.
That’s just an attribute that I put on my elements where I’ve gone the speaker ID into the Dom. So it’s nicely accessible and did I get a rillo Janet there? We go right. So, there’s that here are transmitted transition. Let’s make it work both directions right so, let’s add the the reverse. The reverse is very similar: we’re still going to explode, match match by data speaker ID fly to your partner used to, but we’re going to switch the underlying one for all the background stuff to the other direction.
So now we’ll have it to a right and they’re going to match right up right, so you notice, I didn’t do anything into my templates again. This is still stock, and so, when I’m designing those bed before stayed in that after state, I don’t have to think about my animation. I can go in, add them afterward and I could refactor this whole layout and as long as I still have those elements they’re still going to match all right, there’s no more work to do so, and so this fly to animation.
Actually, you know it’s implemented. The same as that fade, when I showed you the point of it is just that it’s going to measure the initial and final positions of those elements and do a nice smooth transition across. So after the great polymer talk, we saw showing all these in transitions. You know our speaker, Brian, pointed out that you know why don’t want people use this web animations API, it’s really cool, so I said yeah, that’s a good idea, so I reimplemented my while I was sitting in the back just now.
I reimplemented the fly to on that API instead and this is, it doesn’t really kind of fit on one screen, the web print. It’s actually kind of more verbose API than velocities and biggest reason, for it is that a velocity lets you break out all the separate pieces of the transform property and you animate them separately, and it does the merging for you and in this API you don’t also. I have do the promise wrapping myself, but let’s go just drop over to our transitions map and instead of saying fly to, we could say web flights.
You and yes, please save anyway right yeah the reverse. Well, one of them is going one way and the others go in the other, all right, they’re using different api’s in both directions, but they look pretty close to actually there’s a little bit of subtle weirdness in the web. Api went just because it’s using a different easing function, then my background is using right now I would be easy to fix. This is pretty good for doing it in like 10 minutes in the back of the room right, uh yeah you so, let’s, let’s do some different things now so so far I showed you one liquid outlet and that’s an example of the template helper.
That is, you always have some topmost thing that is stable right. That’s that’s kind of your pivot point that you’re going that’s going to. Let you be able to animate at all, there’s some some topmost point. That is the entry point for all the things below it that are going to move around. Sometimes I might even be like the whole page. It might be s, be your top most view, but there’s always someone, and so liquid outlet is one of those and i’m here i’m at inserting a liquid width, which is another now all of these are named in an analogous to the built-in helpers and ember outlet.
With, if we’ll get to those – and they have the same basic semantics, the point of liquid width is, you can actually think of this you’ll see that it’s right here, it’s using the block print syntax to yield up current model right liquid with model as current model. Now this is using really nice new stuff that the block crimes unlocks for us. You could think of this actually internally, as it runs in each it’s going to yield more than once with different versions of that model, as they’ve changed.
That’s how we get multiple things in the Dom together, so by wrapping our list of the model here. This is our list of speakers right. The model is our list by putting it in a liquid each now, I’m going to have the ability to target that list. For animation, so let’s jump up the next commit, and oh actually this was me changing. Let’s see was this just the reverse fly to you. Still, let’s see what we have well, there we go yeah, I didn’t show you the rule.
Yet I skipped that part. That’s good, so we need a transition rule to actually. I think i’ve skipped ahead, yeah that wasn’t supposed to be so cool, yet hmm, yeah. Okay, I don’t know, I guess it’s cooler than I thought it was. I was going to do an intermediate one. That was like more boring, but I’ll go to the cool one, so yeah so, and these guys. So all I’m doing here when I click shuffle right, all I’m doing is putting on a new list that’s sort of differently and the liquid width is because it’s bound to the list.
It’s going to say: oh, this list is changing. I’m going to hold on to the old one: keep it in the Dom render the new one invisible, then delegate to the transition, mapping service and say I’ve got all this stuff. Do you want to animate it right, and so, in this case the transition rule is. Is this one, so here I’m using a different kind of mapping? I don’t say this is no not routes involved right.
I’m saying for a child of the speaker, icons element, use explode, match by speaker ID and then fly to each other right. So this is all the configured tapes to do that. That thing – and we have this easing function here – that’s why they bounce nicely. This is just the syntax velocity uses to give spring values, basically so that when it gets their final location, they bounce a little right. Pretty nice yeah, so let’s um, let’s show off one more thingy, so I mentioned that we have this just interaction here right where we can edit.
Let’s make that a little nicer too. So, let’s see now, I don’t know where I was in my commits. I’m going to have to just live code huh see. I was trying to avoid that. Hmm. Okay, that looks good well yeah. So here’s here’s the rule already that’s going to do it, I’m going to write a transition for the liquid. If helper so – and one thing I want to clarify so all of these things, where I’m saying what, when to do, what these are all constraints in helper to model child of route from all right, all of these are just constraints and a rule matches when all The constraints match so in this case I find in helper liquid if and I’m going to the state.
True, okay, the model in the case of an, if is the predicate you’re passing nvidia, it’s going to true use up. If it’s not it’s going from true, that’s the reverse state will use to Dan and so then in the template. Let’s see speak your details here so before I had, if editing we’re just going to liquid, if editing so that now this element will respect the transition map right and it’ll go find that rule.
Did I reload already there we go yeah so alright. So mr., that’s mr. To you right! So so that’s that’s the demo. So that’s the point of the way we’re trying to bake this stuff in so that it’s not just a great experience but users, but a great expanse for Amber developers, and so I’m very excited to be moving this toward a 10 API. I think I showed you these co2 vide, yeah, oh and so that’s the liquid.
If and so here’s my and I didn’t mention – there’s one other projects did want to mention which is called m / paper. That’s a project started to try to give you out-of-the-box components that have the the google material design features. It doesn’t have a lot of the really rich, complicated motion stuff that I was showing, but I would love to get those all together and make it actually work for people who are interested in doing that kind of stuff.
It’s a cool project. You should check it out. They have some really neat already have things like inputs and radio buttons and buttons that have those nice, nice behaviors, where you see the radiating action out and when you touch them definitely check out. Let me do the science back like I said it’s worth, reading in detail and definitely check out liquid fire. We and I’m really excited to have people contributing.
We’ve had really great contributions already and it’s a wonderful to see people filing issues fixing issues it’s great. So I would have actually said a few days ago. I would have said that I think I knew exactly what the 10 API was and that we were done and it was ready to go, but glimmer is really exciting. It’s actually going to unlock some newer things. I think that might let us simplify even further and be able to possibly cut down the number of different kind of helpers.
You need to just one so so read for great things before we do the beta in June. Before we hit the 10 – and I hope you try it out – and I hope you contribute thanks –