Ionic Swipe Cards

Embed Size (px)

Citation preview

  • 8/16/2019 Ionic Swipe Cards

    1/10

    Ionic Swipe Cards 

    Index.html 

    Help Out

    Swipe down for a new card

    {{card.title}}

    AnswerDecline

  • 8/16/2019 Ionic Swipe Cards

    2/10

    App.js

    // Ionic Starter App

    // angular.module is a global place for creating, registering and retrieving Angular modules// 'starter' is the name of this angular module example (also set in a attribute in index.html)// the 2nd parameter is an array of 'requires'

    angular.module('starter', ['ionic', 'ionic.contrib.ui.cards'])

    .run(function($ionicPlatform) {$ionicPlatform.ready(function() {// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard// for form inputs)if (window.cordova && window.cordova.plugins.Keyboard) {cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);

    }if (window.StatusBar) {StatusBar.styleDefault();

    }});

    })

    .directive('noScroll', function($document) {

    return {restrict: 'A',link: function($scope, $element, $attr) {

    $document.on('touchmove', function(e) {e.preventDefault();

    });}

    }})

    .controller('CardsCtrl', function($scope, $ionicSwipeCardDelegate) {var cardTypes = [{title: 'Swipe down to clear the card',image: 'img/pic.png'

    }, {title: 'Where is this?',image: 'img/pic.png'

    }, {title: 'What kind of grass is this?',image: 'img/pic2.png'

    }, {title: 'What beach is this?',image: 'img/pic3.png'

    }, {title: 'What kind of clouds are these?',

    image: 'img/pic4.png'}];

    $scope.cards = Array.prototype.slice.call(cardTypes, 0, 0);

    $scope.cardSwiped = function(index) {$scope.addCard();

    };

    $scope.cardDestroyed = function(index) {$scope.cards.splice(index, 1);

  • 8/16/2019 Ionic Swipe Cards

    3/10

    };

    $scope.addCard = function() {var newCard = cardTypes[Math.floor(Math.random() * cardTypes.length)];newCard.id = Math.random();$scope.cards.push(angular.extend({}, newCard));

    }

    })

    .controller('CardCtrl', function($scope, $ionicSwipeCardDelegate) {$scope.goAway = function() {var card = $ionicSwipeCardDelegate.getSwipebleCard($scope);card.swipe();

    };});

    Ionic.swipecards.js

    (function(ionic) {

    // Get transform origin polyvar d = document.createElement('div');var transformKeys = ['webkitTransformOrigin', 'transform-origin', '-webkit-transform-origin', 'webkit-transform-origin',

    '-moz-transform-origin', 'moz-transform-origin', 'MozTransformOrigin', 'mozTransformOrigin'];

    var TRANSFORM_ORIGIN = 'webkitTransformOrigin';for(var i = 0; i < transformKeys.length; i++) {if(d.style[transformKeys[i]] !== undefined) {TRANSFORM_ORIGIN = transformKeys[i];

     break;}

    }

    var transitionKeys = ['webkitTransition', 'transition', '-webkit-transition', 'webkit-transition','-moz-transition', 'moz-transition', 'MozTransition', 'mozTransition'];

    var TRANSITION = 'webkitTransition';for(var i = 0; i < transitionKeys.length; i++) {if(d.style[transitionKeys[i]] !== undefined) {TRANSITION = transitionKeys[i];

     break;}

    }

    var SwipeableCardController = ionic.views.View.inherit({initialize: function(opts) {this.cards = [];

    var ratio = window.innerWidth / window.innerHeight;

    this.maxWidth = window.innerWidth - (opts.cardGutterWidth || 0);this.maxHeight = opts.height || 300;this.cardGutterWidth = opts.cardGutterWidth || 10;this.cardPopInDuration = opts.cardPopInDuration || 400;this.cardAnimation = opts.cardAnimation || 'pop-in';

    },/*** Push a new card onto the stack.*/

  • 8/16/2019 Ionic Swipe Cards

    4/10

     pushCard: function(card) {var self = this;

    this.cards.push(card);this.beforeCardShow(card);

    card.transitionIn(this.cardAnimation);

    setTimeout(function() {card.disableTransition(self.cardAnimation);}, this.cardPopInDuration + 100);

    },/*** Set up a new card before it shows.*/

     beforeCardShow: function() {var nextCard = this.cards[this.cards.length-1];if(!nextCard) return;

    // Calculate the top left of a default card, as a translated posvar topLeft = window.innerHeight / 2 - this.maxHeight/2;console.log(window.innerHeight, this.maxHeight);

    var cardOffset = Math.min(this.cards.length, 3) * 5;

    // Move each card 5 pixels down to give a nice stacking effect (max of 3 stacked)nextCard.setPopInDuration(this.cardPopInDuration);nextCard.setZIndex(this.cards.length);

    },/*** Pop a card from the stack*/

     popCard: function(animate) {var card = this.cards.pop();if(animate) {card.swipe();

    }return card;

    }});

    var SwipeableCardView = ionic.views.View.inherit({/*** Initialize a card with the given options.*/initialize: function(opts) {opts = ionic.extend({}, opts);

    ionic.extend(this, opts);

    this.el = opts.el;

    this.startX = this.startY = this.x = this.y = 0;

    this.bindEvents();},

    /*** Set the X position of the card.*/setX: function(x) {this.el.style[ionic.CSS.TRANSFORM] = 'translate3d(' + x + 'px,' + this.y + 'px, 0)';

  • 8/16/2019 Ionic Swipe Cards

    5/10

    this.x = x;this.startX = x;

    },

    /*** Set the Y position of the card.*/

    setY: function(y) {this.el.style[ionic.CSS.TRANSFORM] = 'translate3d(' + this.x + 'px,' + y + 'px, 0)';this.y = y;this.startY = y;

    },

    /*** Set the Z-Index of the card*/setZIndex: function(index) {this.el.style.zIndex = index;

    },

    /*** Set the width of the card

    */setWidth: function(width) {this.el.style.width = width + 'px';

    },

    /*** Set the height of the card*/setHeight: function(height) {this.el.style.height = height + 'px';

    },

    /*** Set the duration to run the pop-in animation*/

    setPopInDuration: function(duration) {this.cardPopInDuration = duration;

    },

    /*** Transition in the card with the given animation class*/transitionIn: function(animationClass) {var self = this;

    this.el.classList.add(animationClass + '-start');this.el.classList.add(animationClass);this.el.style.display = 'block';setTimeout(function() {self.el.classList.remove(animationClass + '-start');

    }, 100);},

    /*** Disable transitions on the card (for when dragging)*/disableTransition: function(animationClass) {this.el.classList.remove(animationClass);

    },

  • 8/16/2019 Ionic Swipe Cards

    6/10

    /*** Swipe a card out programtically*/swipe: function() {this.transitionOut();

    },

    /*** Fly the card out or animate back into resting position.*/transitionOut: function() {var self = this;

    if(this.y < 0) {this.el.style[TRANSITION] = '-webkit-transform 0.2s ease-in-out';this.el.style[ionic.CSS.TRANSFORM] = 'translate3d(' + this.x + ',' + (this.startY) + 'px, 0)';setTimeout(function() {self.el.style[TRANSITION] = 'none';

    }, 200);} else {// Fly outvar rotateTo = (this.rotationAngle + (this.rotationDirection * 0.6)) || (Math.random() * 0.4);

    var duration = this.rotationAngle ? 0.2 : 0.5;this.el.style[TRANSITION] = '-webkit-transform ' + duration + 's ease-in-out';this.el.style[ionic.CSS.TRANSFORM] = 'translate3d(' + this.x + ',' + (window.innerHeight * 1.5) + 'px, 0) rotate(' + rotateTo

    + 'rad)';this.onSwipe && this.onSwipe();

    // Trigger destroy after card has swiped outsetTimeout(function() {self.onDestroy && self.onDestroy();

    }, duration * 1000);}

    },

    /*** Bind drag events on the card.

    */ bindEvents: function() {

    var self = this;ionic.onGesture('dragstart', function(e) {var cx = window.innerWidth / 2;if(e.gesture.touches[0].pageX < cx) {self._transformOriginRight();

    } else {self._transformOriginLeft();

    }ionic.requestAnimationFrame(function() { self._doDragStart(e) });

    }, this.el);

    ionic.onGesture('drag', function(e) {ionic.requestAnimationFrame(function() { self._doDrag(e) });

    }, this.el);

    ionic.onGesture('dragend', function(e) {ionic.requestAnimationFrame(function() { self._doDragEnd(e) });

    }, this.el);},

    // Rotate anchored to the left of the screen _transformOriginLeft: function() {

    this.el.style[TRANSFORM_ORIGIN] = 'left center';

  • 8/16/2019 Ionic Swipe Cards

    7/10

    this.rotationDirection = 1;},

     _transformOriginRight: function() {this.el.style[TRANSFORM_ORIGIN] = 'right center';this.rotationDirection = -1;

    },

     _doDragStart: function(e) {var width = this.el.offsetWidth;var point = window.innerWidth / 2 + this.rotationDirection * (width / 2)var distance = Math.abs(point - e.gesture.touches[0].pageX);// - window.innerWidth/2);console.log(distance);

    this.touchDistance = distance * 10;

    console.log('Touch distance', this.touchDistance);//this.touchDistance, width);},

     _doDrag: function(e) {var o = e.gesture.deltaY / 3;

    this.rotationAngle = Math.atan(o/this.touchDistance) * this.rotationDirection;

    if(e.gesture.deltaY < 0) {this.rotationAngle = 0;

    }

    this.y = this.startY + (e.gesture.deltaY * 0.4);

    this.el.style[ionic.CSS.TRANSFORM] = 'translate3d(' + this.x + 'px, ' + this.y + 'px, 0) rotate(' + (this.rotationAngle || 0) +'rad)';

    }, _doDragEnd: function(e) {

    this.transitionOut(e);}

    });

    angular.module('ionic.contrib.ui.cards', ['ionic'])

    .directive('swipeCard', ['$timeout', function($timeout) {return {restrict: 'E',template: '',require: '^swipeCards',replace: true,transclude: true,scope: {onCardSwipe: '&',onDestroy: '&'

    },compile: function(element, attr) {return function($scope, $element, $attr, swipeCards) {var el = $element[0];

    // Instantiate our card viewvar swipeableCard = new SwipeableCardView({el: el,onSwipe: function() {

    $timeout(function() {$scope.onCardSwipe();

  • 8/16/2019 Ionic Swipe Cards

    8/10

    });},onDestroy: function() {

    $timeout(function() {$scope.onDestroy();

    });},

    });$scope.$parent.swipeCard = swipeableCard;

    swipeCards.pushCard(swipeableCard);

    }}

    }}])

    .directive('swipeCards', [ '$rootScope', function($rootScope) {return {restrict: 'E',template: '',replace: true,

    transclude: true,scope: {},controller: function($scope, $element) {var swipeController = new SwipeableCardController({});

    $rootScope.$on('swipeCard.pop', function(isAnimated) {swipeController.popCard(isAnimated);

    });

    return swipeController;}

    }}])

    .factory('$ionicSwipeCardDelegate', ['$rootScope', function($rootScope) {return { popCard: function($scope, isAnimated) {

    $rootScope.$emit('swipeCard.pop', isAnimated);},getSwipebleCard: function($scope) {return $scope.$parent.swipeCard;

    }}

    }]);

    })(window.ionic);

    Style.css

    /* Your app's CSS, go crazy, make it your own */

    .ionic-logo {display: block;margin: 15px auto;width: 96px;height: 96px;

    }

  • 8/16/2019 Ionic Swipe Cards

    9/10

    .pane { background-color: #333;

    }

    .bar.bar-transparent { background-color: transparent;

     background-image: none; border: none;}

    .bar .title {color: #eee;

    }

    .swipe-cards { position: fixed;

    }

    .swipe-card {display: none;

     position: fixed;

    -webkit-transform: scale(1,1);left: 50%;top: 50%;width: 300px;height: 300px;margin-left: -150px;margin-top: -150px;

     box-sizing: border-box; background-color: rgb(255,255,255); border-radius: 4px;overflow: hidden;-webkit-animation-fill-mode: forwards;

    }

    .swipe-card .title {

    height: 40px; padding: 5px;line-height: 30px;color: #444;

    }.swipe-card .image {

    overflow: hidden;max-height: 210px;

    }.swipe-card .button { border: none;

    }.swipe-card .image img {

    width: 100%; border-radius: 0px 0px 4px 4px;

    }

    #start-card {color: #fff;

     background-color: #30BD8A;line-height: 300px;word-wrap: break-word;

     border: 6px solid #4CD68E;text-align: center;

    }

  • 8/16/2019 Ionic Swipe Cards

    10/10

    10 

    #start-card span {display: inline-block;line-height: 40px;width: 200px;font-size: 30px;vertical-align: middle;

    }

    #footer .button {color: #fff;

    }

    @-webkit-keyframes bounceIn {0% {-webkit-transform: scale(0,0);

    }70% {-webkit-transform: scale(1.2,1.2);

    }100% {-webkit-transform: scale(1,1);

    }

    }

    .swipe-card.pop-in-start {-webkit-transform: scale(0,0);

    }.swipe-card.pop-in {

    -webkit-animation: bounceIn 0.4s ease-out;}