Angular Material Design Animation
Asked Answered
P

1

11

I'm currently developing a mobile web application with AngularJS, ngAnimate, Angular-Material and UI-Router. I'm following Google Material Design specifications for the UI/UX part.

I'd like to animate a state change 'the Angular way' and especially this 'Parent to child' animation

I've no idea on how to achieve this 'lift & expand' animation.

Thanks for your help !

Pazpaza answered 16/5, 2015 at 23:18 Comment(0)
A
7

You have to do it yourself, I guess.

Angular-material is not a magic wand that replicates the animation guidelines of Material Design. Material Design guidelines are simply guidelines, and are loose enough to be hacked — or strictly followed, in the case of Google's Android apps (in-house or not).
My feeling is the angular material team is already pushing like maniacs to bring this awesome tool to 1.0, and will take advantage of the new routing system in Angular 2 to provide some animations like the one you wish to attain out of the box. But it's the bleeding edge of the bleeding edge, at least for the time being. Good news seem to be that routes will have their own viewports and sibling viewports.

AngularJS somewhat starts to embrace Polymer's web components concept. Scroll to "Show me the magic!" on this page, and check these demos. Polymer's ecosystem provides a lot of already-made components to build your app with. It's quite large, and makes you wonder why Polymer doesn't get the same momentum as AngularJS. But I digress...

Option 1

  1. create a custom-made function that gets triggered on a list element being clicked/tapped, to place in your controller (or directive).

  2. Once the user clicks/taps the list element, it triggers the function (console test).

  3. The function should :

    • retrieve the id of the clicked/tapped item (pass it to the function)
    • animate : here you have several choices, but here's one : use a ui-router absolute named view (@view_name), and wrap it in a div container with overflow:hidden, that has inital dimensions corresponding to the dimensions of a list item.
    • Detect the x-y position of the list element that has been clicked (an example, assuming you use AngularJS with jQuery), and you pass it to the "item detail" route (see above), so the rectangle grows with origins corresponding exactly to where the UI is a the moment of the click/tap. The animation shown in the video seems pretty complex: the "item detail page" grows slower on the bottom and faster on the top, when the bottom item is clicked.

Why an absolute named view? Because it will allow, with z-indexing, for the list to stay underneath the "item detail" view, so when the user closes/leaves it, you can roll back your animation, and the rectangle will shrink back to exactly the dimensions and position of the list item. Finally, you transition the opacity:0 and leave the route.

Option 2

Here's a rough mockup of a technique stretching/scrolling an ion-item. It would require to detect the y position of the item, and use ionicScrollDelegate to scroll to it. Also, you would freeze the main scroll so the user get "stucked", until he closes the "detail view", which then releases the scroll.

    $scope.toggleStretchedMode = function(itemID) {

    $scope.stretched = $scope.stretched === false ? true: false;


    if(!$scope.stretched){
        $('ion-item').removeClass('stretched');
        $ionicScrollDelegate.freezeAllScrolls(false);
    }
      else
    {
        $location.hash(itemID);
        $ionicScrollDelegate.$getByHandle('mainScroll').anchorScroll(true);
        $ionicScrollDelegate.freezeAllScrolls(true);
        $('#'+itemID).addClass('stretched');
     };

  }

A very basic JSFiddle, which needs to be refined (clicked item should scroll to the middle of the screen, then expand).

Note that the JSFiddle only blocks the mousewheel scroll. If seems to block the first swipe, but then the ng-click releases it, so as it is it's far from perfect. You should not only block the list scrolling, but the up and down swipe events.

Also it initalizes badly, only works the second time. But the concept could be something like this.

Afoul answered 17/5, 2015 at 2:14 Comment(3)
Thanks for your answer ! Correct me if I'm wrong but you're suggesting that I perform the animation using JS/jQuery ? I believed it was possible to do it using CSS animations/transitions.Pazpaza
It was just for the concept. Basically you just need to detect the x and y coordinates of the object. Or simpler : you intercept the click, and you turn the clicked list item to 100vh, with transitioning.Afoul
This is also interesting : rich-harris.co.uk/ramjet - The only thing is, for now it is not so easy to think in terms of a div, that morphs into another one, because then we have to fill this last state with some data, once the animation is finished. And also have some mechanism that triggers a state, without changing routes. We're dealing here with one of the challenges of HTML5 pages today : transform stuff while retaining the state of the transformations, and the app context.Afoul

© 2022 - 2024 — McMap. All rights reserved.