From de7915feefc84a8a1aaf6d5b277d7483e1989491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?U=C4=9Fur=20Korfal=C4=B1?= Date: Mon, 16 Mar 2015 22:06:23 +0200 Subject: [PATCH] Fix for closing problem from the right If you choose to place the drawer to the right by using side attribute, while dragging the drawer to close it, it closes to the left again. --- ionic.contrib.drawer.js | 374 +++++++++++++++++++++------------------- 1 file changed, 194 insertions(+), 180 deletions(-) diff --git a/ionic.contrib.drawer.js b/ionic.contrib.drawer.js index b2f5815..2fe5c0d 100644 --- a/ionic.contrib.drawer.js +++ b/ionic.contrib.drawer.js @@ -1,189 +1,203 @@ -(function() { - -'use strict'; - -/** - * The ionic-contrib-frosted-glass is a fun frosted-glass effect - * that can be used in iOS apps to give an iOS 7 frosted-glass effect - * to any element. - */ -angular.module('ionic.contrib.drawer', ['ionic']) - -.controller('drawerCtrl', ['$element', '$attrs', '$ionicGesture', '$document', function($element, $attr, $ionicGesture, $document) { - var el = $element[0]; - var dragging = false; - var startX, lastX, offsetX, newX; - var side; - - // How far to drag before triggering - var thresholdX = 15; - // How far from edge before triggering - var edgeX = 40; - - var LEFT = 0; - var RIGHT = 1; - - var isTargetDrag = false; - - var width = $element[0].clientWidth; - - var enableAnimation = function() { - $element.addClass('animate'); - }; - var disableAnimation = function() { - $element.removeClass('animate'); - }; - - // Check if this is on target or not - var isTarget = function(el) { - while(el) { - if(el === $element[0]) { - return true; - } - el = el.parentNode; - } - }; - - var startDrag = function(e) { - disableAnimation(); - - dragging = true; - offsetX = lastX - startX; - console.log('Starting drag'); - console.log('Offset:', offsetX); - }; - - var startTargetDrag = function(e) { - disableAnimation(); - - dragging = true; - isTargetDrag = true; - offsetX = lastX - startX; - console.log('Starting target drag'); - console.log('Offset:', offsetX); - }; - - var doEndDrag = function(e) { - startX = null; - lastX = null; - offsetX = null; - isTargetDrag = false; - - if(!dragging) { - return; - } - - dragging = false; - - console.log('End drag'); - enableAnimation(); - - ionic.requestAnimationFrame(function() { - if(newX < (-width / 2)) { - el.style.transform = el.style.webkitTransform = 'translate3d(' + -width + 'px, 0, 0)'; - } else { - el.style.transform = el.style.webkitTransform = 'translate3d(0px, 0, 0)'; - } - }); - }; +(function () { - var doDrag = function(e) { - if(e.defaultPrevented) { - return; - } + 'use strict'; - if(!lastX) { - startX = e.gesture.touches[0].pageX; - } + /** + * The ionic-contrib-drawer is an Android like drawer widget + * that can be used in Android apps (or in any other platforms if it is convenient) + */ + angular.module('ionic.contrib.drawer', ['ionic']) - lastX = e.gesture.touches[0].pageX; + .controller('drawerCtrl', ['$element', '$attrs', '$ionicGesture', '$document', function ($element, $attr, $ionicGesture, $document) { - if(!dragging) { + var el = $element[0]; + var dragging = false; + var startX, lastX, offsetX, newX; + var side; - // Dragged 15 pixels and finger is by edge - if(Math.abs(lastX - startX) > thresholdX) { - if(isTarget(e.target)) { - startTargetDrag(e); - } else if(startX < edgeX) { - startDrag(e); - } - } - } else { - console.log(lastX, offsetX, lastX - offsetX); - newX = Math.min(0, (-width + (lastX - offsetX))); - ionic.requestAnimationFrame(function() { - el.style.transform = el.style.webkitTransform = 'translate3d(' + newX + 'px, 0, 0)'; - }); - - } - - if(dragging) { - e.gesture.srcEvent.preventDefault(); - } - }; - - side = $attr.side == 'left' ? LEFT : RIGHT; - console.log(side); - - $ionicGesture.on('drag', function(e) { - doDrag(e); - }, $document); - $ionicGesture.on('dragend', function(e) { - doEndDrag(e); - }, $document); - - - this.close = function() { - enableAnimation(); - ionic.requestAnimationFrame(function() { - if(side === LEFT) { - el.style.transform = el.style.webkitTransform = 'translate3d(-100%, 0, 0)'; - } else { - el.style.transform = el.style.webkitTransform = 'translate3d(100%, 0, 0)'; - } - }); - }; - - this.open = function() { - enableAnimation(); - ionic.requestAnimationFrame(function() { - if(side === LEFT) { - el.style.transform = el.style.webkitTransform = 'translate3d(0%, 0, 0)'; - } else { - el.style.transform = el.style.webkitTransform = 'translate3d(0%, 0, 0)'; - } - }); - }; -}]) - -.directive('drawer', ['$rootScope', '$ionicGesture', function($rootScope, $ionicGesture) { - return { - restrict: 'E', - controller: 'drawerCtrl', - link: function($scope, $element, $attr, ctrl) { - $element.addClass($attr.side); - $scope.openDrawer = function() { - console.log('open'); - ctrl.open(); + var swipeOpen = false; + + // How far to drag before triggering + var thresholdX = 15; + // How far from edge before triggering + var edgeX = 40; + + var LEFT = 0; + var RIGHT = 1; + + var isTargetDrag = false; + + var width = $element[0].clientWidth; + + var enableAnimation = function () { + $element.addClass('animate'); + }; + var disableAnimation = function () { + $element.removeClass('animate'); + }; + + // Check if this is on target or not + var isTarget = function (el) { + while (el) { + if (el === $element[0]) { + return true; + } + el = el.parentNode; + } + }; + + var startDrag = function (e) { + disableAnimation(); + + dragging = true; + offsetX = lastX - startX; + console.log('Starting drag'); + console.log('Offset:', offsetX); }; - $scope.closeDrawer = function() { - console.log('close'); - ctrl.close(); + + var startTargetDrag = function (e) { + disableAnimation(); + + dragging = true; + isTargetDrag = true; + offsetX = lastX - startX; + console.log('Starting target drag'); + console.log('Offset:', offsetX); }; - } - } -}]); - -.directive('drawerClose', ['$rootScope', function($rootScope) { - return { - restrict: 'A', - link: function($scope, $element) { - $element.bind('click', function() { - var drawerCtrl = $element.inheritedData('$drawerController'); - drawerCtrl.close(); - }); - } - } -}]); + + var doEndDrag = function (e) { + startX = null; + lastX = null; + offsetX = null; + isTargetDrag = false; + + if (!dragging) { + return; + } + + dragging = false; + + console.log('End drag'); + enableAnimation(); + + + ionic.requestAnimationFrame(function () { + var dragWidth = side ? width : -width, + closeThreshold = Math.floor(dragWidth / 1.4), + closeCondition = side ? newX > closeThreshold : newX < closeThreshold; + + if (closeCondition) { + el.style.transform = el.style.webkitTransform = 'translate3d(' + dragWidth + 'px, 0, 0)'; + } else { + el.style.transform = el.style.webkitTransform = 'translate3d(0px, 0, 0)'; + } + }); + }; + + var doDrag = function (e) { + if (e.defaultPrevented) { + return; + } + + if (!lastX) { + startX = e.gesture.touches[0].pageX; + } + + lastX = e.gesture.touches[0].pageX; + + if (!dragging) { + + // Dragged 15 pixels and finger is by edge + if (Math.abs(lastX - startX) > thresholdX) { + if (side ? startX < lastX : startX > lastX) { + if (isTarget(e.target)) { + startTargetDrag(e); + } else if (startX < edgeX && swipeOpen) { + startDrag(e); + } + } + } + } else { + + var dragWidth = side ? 0 : -width, + currentX = (dragWidth + (lastX - offsetX)); + + newX = side ? Math.max(0, currentX) : Math.min(0, currentX); + + ionic.requestAnimationFrame(function () { + el.style.transform = el.style.webkitTransform = 'translate3d(' + newX + 'px, 0, 0)'; + }); + + } + + if (dragging) { + e.gesture.srcEvent.preventDefault(); + } + }; + + side = $attr.side == 'left' ? LEFT : RIGHT; + console.log(side); + + + $ionicGesture.on('drag', function (e) { + doDrag(e); + }, $document); + $ionicGesture.on('dragend', function (e) { + doEndDrag(e); + }, $document); + + + this.close = function () { + enableAnimation(); + ionic.requestAnimationFrame(function () { + if (side === LEFT) { + el.style.transform = el.style.webkitTransform = 'translate3d(-100%, 0, 0)'; + } else { + el.style.transform = el.style.webkitTransform = 'translate3d(100%, 0, 0)'; + } + }); + }; + + this.open = function () { + enableAnimation(); + ionic.requestAnimationFrame(function () { + if (side === LEFT) { + el.style.transform = el.style.webkitTransform = 'translate3d(0%, 0, 0)'; + } else { + el.style.transform = el.style.webkitTransform = 'translate3d(0%, 0, 0)'; + } + }); + }; + }]) + + .directive('drawer', ['$rootScope', '$ionicGesture', function ($rootScope, $ionicGesture) { + return { + restrict: 'E', + controller: 'drawerCtrl', + link: function ($scope, $element, $attr, ctrl) { + $element.addClass($attr.side); + $rootScope.openDrawer = function () { + console.log('open'); + ctrl.open(); + }; + $rootScope.closeDrawer = function () { + console.log('close'); + ctrl.close(); + }; + } + } + }]) + + .directive('drawerClose', ['$rootScope', function ($rootScope) { + return { + restrict: 'A', + link: function ($scope, $element) { + $element.bind('click', function () { + var drawerCtrl = $element.inheritedData('$drawerController'); + drawerCtrl.close(); + }); + } + } + }]); })();