如何使用AngularJS动画实现翻转效果?

时间:2014-04-15 06:27:18

标签: angularjs css3 angularjs-animation

使用AngularJS动画实现flip over effect的最佳方式是什么?

我想在点击时发生翻转效果。每次点击它都应该转到另一边。

理想情况下,我想,我正在寻找使用Angular动画的指令实现。

8 个答案:

答案 0 :(得分:13)

PLNKR - 这是一个可配置角度指令的种子,提供3d翻转功能。我没有看到任何的原因,为什么要使用ngAnimate

基本用法

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

评论

  1. 它自己附加css样式,完全独立。
  2. 在适当的通用directive中,所有名称都应该是可配置的。
  3. flip-widthflip-height设置flipflip-panels两种风格。
  4. 如果设置了frontback
  5. 指令会进行一些基本检查。
  6. 首先flip-panelfront,第二个是back
  7. 由于transclusion的{​​{1}}内容的使用可能是任意的html。(你是对的Misha不需要翻译)
  8. 仅适用于flip-panel。 (更新以使其在Firefox中有效,只需复制-webkit没有前缀的所有部分 - 您不需要-webkit
  9. 更新

    PLNKR - 这是一个更新和扩展的版本。它通过使指令可配置来显示我的意思。更多细节:

    1. 通过-moz引入flipConfig,允许在provider中设置:
      • 默认尺寸
      • css班级名称
      • 过渡速度
      • 如果通过面板上的点击触发翻转操作
    2. 引入app.config属性,指定要显示的一面。
    3. 更改flip-show我们可以从指令外部触发翻转操作
    4. 它可以在Firefox中使用,在IE11中可以使用[almost :-)]。
    5. (顺便说一下:它只是一个种子,它可以在很多方面得到改善。例如:指定轴,指定变换的原点,指定面板的半径和边距,允许翻转悬停,默认颜色,边距等)

答案 1 :(得分:7)

最近我有一个角度记忆游戏的用法。

我的实现与其他答案的想法相同。我还发布了翻转代码以及DEMO

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

P.s:看起来我迟到了;)

答案 2 :(得分:2)

单击翻转容器时,您可以使用ng-clickng-class添加类。

<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>

这基本上是在他的文章中做Walsh suggested的角色方式:

  

将翻转类添加到容器元素将使用JavaScript翻转卡片 - 无需用户悬停。像document.querySelector这样的JavaScript注释(&#34; #myCard&#34;)。classList.toggle(&#34; flip&#34;)将会翻转!

David Walsh's css的唯一更改是删除:hover选择器 - html结构未更改。它在chrome和firefox中工作得很好..但在IE浏览器中它的效果并不好。

这是一个有效的演示:http://plnkr.co/edit/0dn775vpuoOeh2PS1T6k?p=preview

<强>更新
我创建了一个简单的指令来封装这个基本技术。它允许您翻转黑卡,在另一侧显示图片。

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

以下是新演示的链接:http://plnkr.co/X4pSav

demo

答案 3 :(得分:2)

  

免责声明基于@ artur的回答https://stackoverflow.com/a/23139242/1319998,但希望这些都得到简化并变得更加灵活。

自定义指令是可行的方法,可以用作:

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

我认为它应该具有某些属性:

  • 由属性以编程方式控制。在这种情况下,一个字符串等于'front'或'back'

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

    这将允许通过周围范围进行编程访问。

  • ngAnimate / $animate合并。具体来说,如果删除或禁用ngAnimate,则不应发生动画,但会立即显示另一方的显示。使用$animate.addClass / $animate.removeClass可实现此目的,添加/删除flip-visible类以及display:blockdisplay:none样式,以确保右侧可见/隐藏当动画被禁用时。

    flip > flip-front, flip > flip-back {
      display: none;
    }
    flip > .flip-visible {
      display: block;
    }
    
  • 由CSS控制,默认值为。因此,如果你想改变翻转的持续时间,那就是CSS,而不是Javascript,添加。

    因此,它会有一个样式表来添加$animate.addClass / $animate.removeClass CSS动画在Year of Moo$animate docs处理的各个阶段所需的样式。该课程为flip-visible,因此额外的课程将为.flip-visible-add.flip-visible-add-active.flip-visible-remove.flip-visible-remove-active课程。

    可以在http://plnkr.co/edit/bbYbMhiURnm6FqC9patp?p=preview看到完整的样式集,但主要结构形式如下:

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

把所有这些放在一起,指令很短:

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');
      });
    }
  }
});

http://plnkr.co/edit/bbYbMhiURnm6FqC9patp?p=preview

中,可以在一个示例中看到这一点以及样式表以使其全部工作

答案 4 :(得分:2)

我意识到$animate服务集成并拥有纯粹的基于类的解决方案是有好处的。

如果您将$animateaddClassremoveClass一起使用,但是中断动画(例如,通过快速重复点击该元素),动画将“猛拉”到其结尾/起点,然后从该位置动画,至少在Chrome上。使用纯CSS解决方案可以避免这个问题,并且始终从精确的当前点开始动画,从而产生更平滑的效果。

另一个好处是解决方案也更简单,您不需要自定义指令。

例如,HTML可以如下:

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

我使用自定义元素,但它们不需要附加任何指令:它们只是用于挂钩的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);   
}

这可以在http://plnkr.co/edit/A7IeGa1JEsZishmTDTaK?p=preview

的演示中看到

答案 5 :(得分:1)

我只需点击即可添加/删除课程。

如果您想要挂钩角度动画系统,请查看$animate service,特别是add/remove/setClass()。该服务通常用于指令中。您可能希望创建一个对click事件做出反应并触发动画的指令。您甚至可以在动画完成时获得通知。

有可能它不值得;)

答案 6 :(得分:1)

您将要创建3个div。

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

然后使用z-index将其放回到前面,并使用rotateX(-180deg左右)将其翻转过来。也可以在包装器上设置转换。

然后,点击包装,旋转X(+ 180度)。这将非常无限地翻转它。

**更新:对于angular,绑定到click并使用setClass在包装器上的两个类之间切换,一个在rotateX(0deg),另一个在rotateX(180deg)

答案 7 :(得分:1)

以下是artur's answer的略微修改版本:

DEMO

&#13;
&#13;
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();
    }
  }
});
&#13;
.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);
}
&#13;
<!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>
&#13;
&#13;
&#13;

主要差异:

  • 适用于Chrome和Firefox。
  • 翻转时更灵活。
  • 只有一个指令而不是两个。少了代码。
  • 为了清楚起见,我把CSS带到了指令之外。