使用AngularJS动画实现flip over effect的最佳方式是什么?
我想在点击时发生翻转效果。每次点击它都应该转到另一边。
理想情况下,我想,我正在寻找使用Angular动画的指令实现。
答案 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>
directive
中,所有名称都应该是可配置的。flip-width
和flip-height
设置flip
和flip-panels
两种风格。front
和back
,flip-panel
是front
,第二个是back
。transclusion
的{{1}}内容的使用可能是任意的html。flip-panel
。 (更新以使其在Firefox中有效,只需复制-webkit
没有前缀的所有部分 - 您不需要-webkit
)PLNKR - 这是一个更新和扩展的版本。它通过使指令可配置来显示我的意思。更多细节:
-moz
引入flipConfig
,允许在provider
中设置:
app.config
属性,指定要显示的一面。flip-show
我们可以从指令外部触发翻转操作。(顺便说一下:它只是一个种子,它可以在很多方面得到改善。例如:指定轴,指定变换的原点,指定面板的半径和边距,允许翻转悬停,默认颜色,边距等)
答案 1 :(得分:7)
最近我有一个角度记忆游戏的用法。
我的实现与其他答案的想法相同。我还发布了翻转代码以及DEMO。
Github:https://github.com/zwacky/angular-flippy
P.s:看起来我迟到了;)
答案 2 :(得分:2)
单击翻转容器时,您可以使用ng-click
和ng-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
答案 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:block
和display: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');
});
}
}
});
中,可以在一个示例中看到这一点以及样式表以使其全部工作
答案 4 :(得分:2)
我意识到不与$animate
服务集成并拥有纯粹的基于类的解决方案是有好处的。
如果您将$animate
与addClass
和removeClass
一起使用,但是中断动画(例如,通过快速重复点击该元素),动画将“猛拉”到其结尾/起点,然后从该位置动画,至少在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);
}
的演示中看到
答案 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的略微修改版本:
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;
主要差异: