卡片翻转效果(css3+angularjs)
前段时间写公司业务需求需要去根据后台的数据去渲染页面元素然后对页面元素进行翻卡片的对里面的值进行判断的效果,其实网上也有一些demo。我根据一些demo,改进下并写成适合于angular类似的mvc的框架渲染页面并对进行数据操作的需求。
基本需求:后台获取到json数据,渲染不同卡片的内容。并进行各个卡片的进行操作记录,进行数据处理。
第一步:创建html,建立angular的app。
<body ng-controller="myCrtl"> <div ng-repeat="n in data" class="wrap"> <div id="box" class="box viewport-flip" ><!--翻转的容器--> <a class="list flip dd {{state[$index].isFan}}" ng-click="fan($index)"><span class="back"></span></a><!--卡片背面--> <a class="list flip {{state[$index].isZheng}}" ng-click="fan($index)" ><span class="face">{{n}}</span></a><!--卡片正面--> </div> </div> </body>
第二歩:写出样式表控制卡
.box { width: 355px; height: 400px; padding-top: 30px; padding-bottom: 30px; margin-left: auto; margin-right: auto; position: relative; } .wrap{ width: 355px; height: 400px; float: left; margin: 20px 50px; } .list { position: absolute; } .viewport-flip{ -webkit-perspective:1000px; } .in { -webkit-animation-timing-function: ease-out; -webkit-animation-duration: 850ms; animation-timing-function: ease-out; animation-duration: 850ms; } .out { -webkit-animation-timing-function: ease-in; -webkit-animation-duration: 500ms; animation-timing-function: ease-in; animation-duration: 500ms; } .flip { -webkit-backface-visibility: visible; -webkit-transform: translateX(0); /* Needed to work around an iOS 3.1 bug that causes listview thumbs to disappear when -webkit-visibility:hidden is used. */ backface-visibility: visible; transform: translateX(0); } .flip.out { -webkit-transform: rotateY(-90deg) scale(.9); -webkit-animation-name: flipouttoleft; transform: rotateY(-90deg) scale(.9); animation-name: flipouttoleft; } .flip.in { -webkit-animation-name: flipintoright; -webkit-animation-duration: 225ms; animation-name: flipintoright; animation-duration: 225ms; } @-webkit-keyframes flipouttoleft { from { -webkit-transform: rotateY(0); } to { -webkit-transform: rotateY(-90deg) scale(.9); } } @keyframes flipouttoleft { from { transform: rotateY(0); } to { transform: rotateY(-90deg) scale(.9); } } @-webkit-keyframes flipintoright { from { -webkit-transform: rotateY(90deg) scale(.9); } to { -webkit-transform: rotateY(0); } } @keyframes flipintoright { from { transform: rotateY(90deg) scale(.9); } to { transform: rotateY(0); } } .dd{ display: none; } .show{ display: block; } span{ display: inline-block; } .back{ width: 355px; height: 400px; background-color: wheat; } .face{ width: 355px; height: 400px; background-color: pink; font-size: 200px; text-align: center; line-height: 400px; }
第三歩:控制器的中js代码动点击不同元素,改变相应的元素的状态
var app=angular.module('myApp',[]); app.controller('myCrtl',function($scope){ $scope.data=[1,2,3,4];//模拟后台返回的数据,不同业务需要肯定数据结构是不一样的,我就做最基本的方便看。 $scope.state = [];//对后台返回的数据,每个不同的数据内容进行状态绑定。 for(var i=0;i<$scope.data.length;i++){//初始化不同的数据内容进行状态绑定。 var obj={"isFan":"out","isZheng":"","nm":0,"isClick":false}; $scope.state[i]=obj; } $scope.fan = function (index) { if(!$scope.state[index].isClick){//判断翻转是否开始,防止连续点击 $scope.state[index].isClick=true; setTimeout(function(){//翻转结束改变isClick的状态值 $scope.state[index].isClick=false; },850); if ($scope.state[index].nm == 0) {//nm的值表示真实正面的位置,nm==0的时候代表真实正面处于当前正面 $scope.state[index].isZheng = 'out';//给背面添加向外翻转样式,进行动画。 setTimeout(function () {//给正面添加向内翻转的样式,进行动画。 angular.element(document.getElementsByClassName('wrap')).eq(index).find('a').eq(0).removeClass('dd').addClass('show'); $scope.state[index].isFan = 'in'; $scope.$apply(); // 重新确定正反元素 }, 500); $scope.state[index].nm = 1; } else {//nm的值表示真实正面的位置,nm==1的时候代表真实正面处于当前反面 $scope.state[index].isFan = 'out';//给背面添加向外翻转样式,进行动画。 angular.element(document.getElementsByClassName('wrap')).eq(index).find('a').eq(0).removeClass('dd').addClass('show'); setTimeout(function () {//给正面添加向内翻转的样式,进行动画。 $scope.state[index].isZheng = 'in'; $scope.$apply(); // 重新确定正反元素 }, 500); $scope.state[index].nm = 0; } } } });
说明下需要注意的问题
1,
.box { width: 355px; height: 400px; padding-top: 30px; padding-bottom: 30px; margin-left: auto; margin-right: auto; position: relative; }
和卡片正反两面的高宽必须是一样的否则会出现,翻转到90度的时候还是,还是看的到卡片正面,非常丑陋了。
2,每次翻转后就必须重新确定当前正反面。
3,通过angular的双向数据绑定的功能,可以把后台给的json数据渲染成相应的卡片,并对每个卡片赋予相应的状态,并相互不影响。
完整的demo的例子大家可以复值下来试试
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>angular实现翻卡片</title> <script src="http://zhouwei007.web3v.com/js/angular.js"></script> <style> .box { width: 355px; height: 400px; padding-top: 30px; padding-bottom: 30px; margin-left: auto; margin-right: auto; position: relative; } .wrap{ width: 355px; height: 400px; float: left; margin: 20px 50px; } .list { position: absolute; } .viewport-flip{ -webkit-perspective:1000px; } .in { -webkit-animation-timing-function: ease-out; -webkit-animation-duration: 850ms; animation-timing-function: ease-out; animation-duration: 850ms; } .out { -webkit-animation-timing-function: ease-in; -webkit-animation-duration: 500ms; animation-timing-function: ease-in; animation-duration: 500ms; } .flip { -webkit-backface-visibility: visible; -webkit-transform: translateX(0); /* Needed to work around an iOS 3.1 bug that causes listview thumbs to disappear when -webkit-visibility:hidden is used. */ backface-visibility: visible; transform: translateX(0); } .flip.out { -webkit-transform: rotateY(-90deg) scale(.9); -webkit-animation-name: flipouttoleft; transform: rotateY(-90deg) scale(.9); animation-name: flipouttoleft; } .flip.in { -webkit-animation-name: flipintoright; -webkit-animation-duration: 225ms; animation-name: flipintoright; animation-duration: 225ms; } @-webkit-keyframes flipouttoleft { from { -webkit-transform: rotateY(0); } to { -webkit-transform: rotateY(-90deg) scale(.9); } } @keyframes flipouttoleft { from { transform: rotateY(0); } to { transform: rotateY(-90deg) scale(.9); } } @-webkit-keyframes flipintoright { from { -webkit-transform: rotateY(90deg) scale(.9); } to { -webkit-transform: rotateY(0); } } @keyframes flipintoright { from { transform: rotateY(90deg) scale(.9); } to { transform: rotateY(0); } } .dd{ display: none; } .show{ display: block; } span{ display: inline-block; } .back{ width: 355px; height: 400px; background-color: wheat; } .face{ width: 355px; height: 400px; background-color: pink; font-size: 200px; text-align: center; line-height: 400px; } </style> </head> <body ng-controller="myCrtl"> <div ng-repeat="n in data" class="wrap"> <div id="box" class="box viewport-flip" ><!--翻转的容器--> <a class="list flip dd {{state[$index].isFan}}" ng-click="fan($index)"><span class="back"></span></a><!--卡片背面--> <a class="list flip {{state[$index].isZheng}}" ng-click="fan($index)" ><span class="face">{{n}}</span></a><!--卡片正面--> </div> </div> </body> <script> var app=angular.module('myApp',[]); app.controller('myCrtl',function($scope){ $scope.data=[1,2,3,4];//模拟后台返回的数据,不同业务需要肯定数据结构是不一样的,我就做最基本的方便看。 $scope.state = [];//对后台返回的数据,每个不同的数据内容进行状态绑定。 for(var i=0;i<$scope.data.length;i++){//初始化不同的数据内容进行状态绑定。 var obj={"isFan":"out","isZheng":"","nm":0,"isClick":false}; $scope.state[i]=obj; } $scope.fan = function (index) { if(!$scope.state[index].isClick){//判断翻转是否开始,防止连续点击 $scope.state[index].isClick=true; setTimeout(function(){//翻转结束改变isClick的状态值 $scope.state[index].isClick=false; },850); if ($scope.state[index].nm == 0) {//nm的值表示真实正面的位置,nm==0的时候代表真实正面处于当前正面 $scope.state[index].isZheng = 'out';//给背面添加向外翻转样式,进行动画。 setTimeout(function () {//给正面添加向内翻转的样式,进行动画。 angular.element(document.getElementsByClassName('wrap')).eq(index).find('a').eq(0).removeClass('dd').addClass('show'); $scope.state[index].isFan = 'in'; $scope.$apply(); // 重新确定正反元素 }, 500); $scope.state[index].nm = 1; } else {//nm的值表示真实正面的位置,nm==1的时候代表真实正面处于当前反面 $scope.state[index].isFan = 'out';//给背面添加向外翻转样式,进行动画。 angular.element(document.getElementsByClassName('wrap')).eq(index).find('a').eq(0).removeClass('dd').addClass('show'); setTimeout(function () {//给正面添加向内翻转的样式,进行动画。 $scope.state[index].isZheng = 'in'; $scope.$apply(); // 重新确定正反元素 }, 500); $scope.state[index].nm = 0; } } } }); </script> </html>