How to implement flipping effect using AnuglarJS animations?

What would be the best way to achieve a flip effect using AngularJS animation?

I would like the click effect to happen on click. Each time he clicked, he should roll over to the other side.

Ideally, I think I'm looking for a directory implementation that uses Angular animation.

+6
source share
8 answers

PLNKR is the seed of the custom angular directive that provides the 3d flip function function. I see no good reason to use ngAnimate for this.

basic use

 <flip flip-width="200px" flip-height="100px"> <flip-panel> content-front </flip-panel> <flip-panel> content-back </flip-panel> </flip> 

Comments

  • He adds CSS styles on his own to be completely independent.
  • In a proper, general directive all names must be customizable.
  • flip-width and flip-height sets the flip style and both flip-panels .
  • The directive does some basic checking if both front and back .
  • The first flip-panel is front , and the second is back .
  • Due to the use of transclusion contents of the flip-panel may be arbitrary html. (you are right, Misha doesn’t need switching)
  • It only works on -webkit . ( update to make it work in Firefox, just duplicate all fragments with -webkit without a prefix - you don't need -moz )

UPDATE

PLNKR is an updated and enhanced version. It shows what I meant by setting up the directive. In details:

  • Introduced flipConfig through provider , which allows you to install in app.config :
    • default sizes
    • css class names
    • transition speed
    • if the flip action is triggered by clicking on the panel
  • The flip-show attribute has been introduced, which indicates which side to show.
  • By changing flip-show , we can call the flip action from outside the directive.
  • It works in Firefox and [almost :-)] in IE11.

(btw: it’s just seed , and it can be improved in many ways. For example: specifying the axis, specifying the start of the transformation, specifying the radius and edges of the panels, allowing you to flip on hover, the default values ​​of colors, fields, etc.)

+13
source

I had the same usecase recently for an angular memory game.

My implementation is the same with the idea of ​​the other answers. I also released flipping code along with DEMO .

Github: https://github.com/zwacky/angular-flippy

Ps: Looks like I'm late for the party;)

+7
source

You can use ng-click and ng-class to add a class when you click on the flip container.

 <div class="flip-container" ng-click="flip = !flip" ng-class="{'flip': flip}"> <div class="flipper"> <div class="front" style="background: lightblue;"> front </div> <div class="back" style="background: lightgreen;"> back </div> </div> </div> 

This is essentially an angular way of doing what Walsh suggested in his article:

Adding the flip class to a container element will flip the map using JavaScript - no user freeze required. Comment on JavaScript such as document.querySelector ("# myCard"). ClassList.toggle ("flip") will flip!

The only change by David Walsh css removed the selector :hover - the html structure has not changed. It works fine in chrome and firefox .. but flip is not so good in IE.

Here is a working demo: http://plnkr.co/edit/0dn775vpuoOeh2PS1T6k?p=preview

Update
I created a simple directive to encapsulate this basic technique. This allows you to flip the black map to show the image on the other side.

 app.directive("flipReveal", function() { return { restrict: 'E', replace: true, templateUrl: 'template.html', scope: { url: '=', flip: '=' } } }) 

Here is the link to the new demo: http://plnkr.co/X4pSav

demo

+2
source

Disclaimer Based on @ artur's answer fooobar.com/questions/967722 / ... , but I hope they have simplified it and made it more flexible.

A custom directive is a path that can be used as:

 <flip flip-side="{{side}}"> <flip-front> Front side contents </flip-front> <flip-back> Rear contents </flip-back> </flip> 

I think it should have certain properties:

  • Attribute-driven software. In this case, a string equal to 'front' or 'back'

     <flip flip-side="{{side}}">....</flip> 

    this will allow programmatic access through the surrounding area.

  • Integrated with ngAnimate / $animate . In particular, if ngAnimate is removed or disabled, the animation should not occur, but detection of the other side occurs immediately. Using $animate.addClass / $animate.removeClass , you will achieve this by adding / removing the flip-visible class along with the display:block and display:none styles to make sure the right side is visible / hidden when the animation is turned off.

     flip > flip-front, flip > flip-back { display: none; } flip > .flip-visible { display: block; } 
  • Controlled by CSS, with default settings. Therefore, if you want to change the duration of the flip, this is the addition of CSS, not Javascript.

    This way, it will have a stylesheet to add the styles needed for the various CSS animation steps $animate.addClass / $animate.removeClass explained in Year of Moo and $ animate docs . The class will be flip-visible , so additional classes will be .flip-visible-add , .flip-visible-add-active , .flip-visible-remove and .flip-visible-remove-active classes.

    A full set of styles can be seen at http://plnkr.co/edit/bbYbMhiURnm6FqC9patp?p=preview , but the basic design is:

     .flip-visible-add { // Initial setup: time and initial, pre-animation, transform } .flip-visible-add.flip-visible-add-active { // Target transform } 

Combining all this, the directive is pretty short:

 app.directive("flip", function($animate) { return { restrict : "E", controller: function($scope, $element, $attrs) { var elements = { 'front': $element.find('flip-front'), 'back': $element.find('flip-back') }; $attrs.$observe('flipSide', function(visibleSide) { visibleSide = visibleSide || 'front'; var otherSide = visibleSide == 'front' ? 'back' : 'front'; $animate.removeClass(elements[otherSide], 'flip-visible'); $animate.addClass(elements[visibleSide], 'flip-visible'); }); } } }); 

All this can be seen in the example along with the style sheets so that it all works: http://plnkr.co/edit/bbYbMhiURnm6FqC9patp?p=preview

+2
source

I understand that there is the advantage of not integrating with the $animate service and having a purely class solution.

If you use $animate with addClass and removeClass , but interrupt the animation (for example, quickly and repeatedly click on an element), the animation will be a “jerk” to its end / starting point, and then animate from this position, at least in Chrome. Using pure CSS solutions avoids this problem and always animate the exact current point, providing a smoother effect.

An additional advantage is also a solution, and you do not need a special directive.

For example, HTML may be as follows:

 <flip class="{{side === 'front' ? 'flip-front' : 'flip-back'}}"> <flip-front> Front side contents </flip-front> <flip-back> Rear contents </flip-back> </flip> 

I use custom elements, but they do not need to have any directives: they are only for CSS:

 flip > flip-front, flip > flip-back { -webkit-backface-visibility: hidden; backface-visibility: hidden; /* Time can be overriden */ transition: -webkit-transform 0.5s; transition: transform 0.5s; } /* Front visible */ flip > flip-front { -webkit-transform: perspective(800px) rotateY(0); transform: perspective(800px) rotateY(0); } flip > flip-back { -webkit-transform: perspective(800px) rotateY(180deg); transform: perspective(800px) rotateY(180deg); } /* Back visible */ flip.flip-back > flip-front { -webkit-transform: perspective(800px) rotateY(-180deg); transform: perspective(800px) rotateY(-180deg); } flip.flip-back > flip-back { -webkit-transform: perspective(800px) rotateY(0); transform: perspective(800px) rotateY(0); } 

This can be seen in the demo version of http://plnkr.co/edit/A7IeGa1JEsZishmTDTaK?p=preview

+2
source

I would just add / remove the class on click.

If you want to connect to the angular animation system, then look at $ animate service , specifically add/remove/setClass() . A service is commonly used in directives. You might want to create a directive that responds to a click event and triggers an animation. You even get information when the animation is complete.

Most likely, this is not worth it;)

+1
source

You need to create 3 divs.

 <div class="wrapper"> <div class="front"></div> <div class="back"></div> </div> 

Then you put it back behind with z-index and flip it upside down using rotateX (-180deg or so). Also set the transition to a wrapper.

Then, when you click the wrapper, rotateX (+ 180deg). This will almost endlessly turn him over.

** Update: for angular, click and use setClass to switch between two classes on the wrapper, one on rotateX (0deg), the other on rotateX (180deg)

+1
source

Here is a slightly modified version of artur answer :

Demo

 angular.module('FlipDemo', []).directive("flip", function() { return { restrict : "A", scope: true, link: function(scope, element) { var $panels = element.css({ position: 'relative' }).children().addClass("flip-panel"); var frontPanel = $panels.eq(0); var backPanel = $panels.eq(1); scope.showFrontPanel = function() { frontPanel.removeClass("flip-hide-front-panel"); backPanel.addClass("flip-hide-back-panel"); }; scope.showBackPanel = function() { backPanel.removeClass("flip-hide-back-panel"); frontPanel.addClass("flip-hide-front-panel"); }; scope.showFrontPanel(); } } }); 
 .flip-panel { position: absolute; width: 100%; height: 100%; -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; -webkit-transition: -webkit-transform .4s; -moz-transition: -moz-transform .4s; -webkit-transform: perspective(800px) rotateY(0deg); -moz-transform: perspective(800px) rotateY(0deg); } .flip-hide-back-panel { -webkit-transform: perspective(800px) rotateY(180deg); -moz-transform: perspective(800px) rotateY(180deg); } .flip-hide-front-panel { -webkit-transform: perspective(800px) rotateY(-180deg); -moz-transform: perspective(800px) rotateY(-180deg); } 
 <!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.1/angular.min.js"></script> <meta charset="utf-8"> <title>JS Bin</title> </head> <body ng-app="FlipDemo"> <div style="width: 100px; height: 150px"> <div flip style="width: 100%; height: 100%"> <div style="background-color: green"> <div>Front</div> <button ng-click="showBackPanel()">Show Back</button> </div> <div style="background-color: blue"> <div>Back</div> <button ng-click="showFrontPanel()">Show Front</button> </div> </div> </div> <br> <div style="width: 150px; height: 100px"> <div flip style="width: 100%; height: 100%"> <div style="background-color: green"> <div>Front</div> <button ng-click="showBackPanel()">Show Back</button> </div> <div style="background-color: blue"> <div>Back</div> <button ng-click="showFrontPanel()">Show Front</button> </div> </div> </div> </body> </html> 

The main differences:

  • Works in Chrome and Firefox.
  • More flexibility when flip occurs.
  • Only one directive, not two. Less code.
  • I took CSS outside of the directive for more clarity.
+1
source

All Articles