<!DOCTYPE html>
<html ng-app="plunker">
<head>
<link data-require="animate.css@1.0.0" data-semver="1.0.0" rel="stylesheet" href="//raw.github.com/daneden/animate.css/master/animate.min.css" />
<script data-require="jquery@*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="http://code.angularjs.org/1.2.16/angular.js"></script>
<script src="http://code.angularjs.org/1.2.16/angular-touch.js"></script>
<script src="http://code.angularjs.org/1.2.16/angular-animate.js"></script>
<script src="item-swipe.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainCtrl">
<div class="container">
<p>Turn on "Emulate touch events" for best effect</p>
<a target="_blank" href="https://github.com/FavishInc/swipe-to-remove">Fork me on github</a>
<button ng-click="resetThings()">Reset things</button>
<div class="animate-repeat" ng-repeat="thing in things">
<div class="test" item-swipe="" on-remove="removeThing(thing)">
{{thing.name}} swipe me right.
</div>
</div>
</div>
</body>
</html>
var app = angular.module('plunker', ['itemSwipe', 'ngAnimate']);
app.controller('MainCtrl', function ($scope, Things) {
$scope.removeThing = function(thing){
$scope.things.splice($scope.things.indexOf(thing), 1);
};
$scope.resetThings = function(){
$scope.things = Things();
};
$scope.resetThings();
});
app.value('Things', function () {
return [{name: 1}, {name: 2}, {name: 3}, {name: 4}, {name: 5}];
});
body {
background: #D5D5D5;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #333;
}
.container {
zoom: 1;
width: 100%;
max-width: 100%;
overflow: hidden;
}
.swiper {
width: 100%;
height: 70px;
background: whitesmoke;
margin: 4px 12px;
zoom: 1;
}
.animate-repeat.ng-move,
.animate-repeat.ng-enter,
.animate-repeat.ng-leave {
-webkit-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-moz-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-ms-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-o-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
position: relative;
display: block;
overflow: hidden;
text-overflow: clip;
white-space:nowrap;
}
.animate-repeat.ng-leave.ng-leave-active,
.animate-repeat.ng-move,
.animate-repeat.ng-enter {
opacity:0;
max-height:0;
}
.animate-repeat.ng-leave,
.animate-repeat.ng-move.ng-move-active,
.animate-repeat.ng-enter.ng-enter-active {
opacity:1;
max-height:40px;
}
'use strict';
angular.module('itemSwipe', ['ngTouch'])
.directive('itemSwipe', ['$swipe', '$document', '$window', '$timeout',
function($swipe, $document, $window, $timeout) {
return {
transclude: true,
template: '<div class="item-swipe-wrapper" style="position: relative">' +
'<div class="swiper" ng-style="swiperStyle" ng-transclude style="position: relative"></div>' +
'<div class="undo-div" ng-style="undoStyle" ng-click="proceed = false">Undo</div>' +
'</div>',
link: {
post: function postLink(scope, iElement, iAttrs, controller) {
var startCoords, threeD, $swiper;
$swiper = angular.element('.swiper', iElement);
scope.proceed = false;
scope.undoStyle = {
opacity: 0,
width: '100%',
position: 'absolute',
left: '70%',
top: '0',
};
function fullSwipe(coords){
return coords.x - startCoords.x > $swiper.width()*(1/3) ? true : false;
}
function cssPrefix(property, value){
var vendors = ['', '-o-','-moz-','-ms-','-khtml-','-webkit-'];
var styles = {};
for (var i = vendors.length - 1; i >= 0; i--) {
styles[vendors[i] + property] = value;
}
return styles;
}
function updateElementPosition(pos){
if('threeD' in iAttrs){
$swiper.css(cssPrefix('transform', 'translate(' + pos + 'px)'));
}else{
$swiper.css('left', pos);
}
}
scope.$watch('proceed', function(val){
if(val){
scope.undoStyle.opacity = 1;
scope.eliminateItem = $timeout(function() {
scope.proceed = false;
return scope.$eval(iAttrs.onRemove);
}, 1220);
}else{
scope.undoStyle.opacity = 0;
$timeout.cancel(scope.eliminateItem);
updateElementPosition(0);
}
});
$swipe.bind($swiper, {
'start': function(coords) {
startCoords = coords;
scope.swiperStyle = {opacity: 0.5};
scope.$apply();
},
'cancel': function() {
scope.swiperStyle = cssPrefix('transition', 'all 0.2s ease-in-out');
scope.swiperStyle.opacity = 1;
scope.$apply();
},
'move': function(coords) {
updateElementPosition(coords.x - startCoords.x);
},
'end': function(endCoords) {
if (fullSwipe(endCoords)) {
scope.proceed = true;
updateElementPosition($document.width());
}else {
scope.proceed = false;
updateElementPosition(0);
}
scope.swiperStyle = cssPrefix('transition', 'all 0.2s ease-in-out');
scope.swiperStyle.opacity = 1;
scope.$apply();
}
});
}
}
};
}]);