implement slide to pay
This commit is contained in:
parent
039712fa54
commit
777c2efc32
22 changed files with 659 additions and 50 deletions
|
|
@ -162,23 +162,4 @@ angular.module('copayApp.directives')
|
|||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.directive('accept', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'views/includes/acceptSlide.html',
|
||||
scope: {},
|
||||
link: function(scope, element, attrs) {
|
||||
scope.$on("$ionicSlides.sliderInitialized", function(event, data) {
|
||||
scope.slider = data.slider;
|
||||
});
|
||||
|
||||
scope.$on("$ionicSlides.slideChangeEnd", function(event, data) {
|
||||
if (data.slider.activeIndex == 0) {
|
||||
scope.slider.slideNext();
|
||||
scope.$emit('accepted');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
249
src/js/directives/slideToAccept.js
Normal file
249
src/js/directives/slideToAccept.js
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.directives')
|
||||
.directive('slideToAccept', function($timeout, $window, $q) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'views/includes/slideToAccept.html',
|
||||
transclude: true,
|
||||
scope: {
|
||||
sendStatus: '=slideSendStatus',
|
||||
onConfirm: '&slideOnConfirm'
|
||||
},
|
||||
link: function(scope, element, attrs) {
|
||||
|
||||
var KNOB_WIDTH = 71;
|
||||
var MAX_SLIDE_START_PERCENTAGE = 50;
|
||||
var FULLY_SLID_PERCENTAGE = 72;
|
||||
var PERCENTAGE_BUMP = 5;
|
||||
var JIGGLE_EASING = linear;
|
||||
var JIGGLE_DURATION = 100;
|
||||
var RECEDE_DURATION = 250;
|
||||
var INITIAL_TAP_EASE_DURATION = 75;
|
||||
|
||||
var elm = element[0];
|
||||
var isSliding = false;
|
||||
var curSliderPct = getKnobWidthPercentage();
|
||||
var curBitcoinPct = 0;
|
||||
var curTextPct = 0;
|
||||
var currentEaseStartTime;
|
||||
var bezier = $window.BezierEasing(0.175, 0.885, 0.320, 1.275);
|
||||
|
||||
scope.isSlidFully = false;
|
||||
scope.displaySendStatus = '';
|
||||
|
||||
scope.$watch('sendStatus', function() {
|
||||
if(scope.sendStatus === 'success') {
|
||||
scope.displaySendStatus = '';
|
||||
reset();
|
||||
} else {
|
||||
scope.displaySendStatus = scope.sendStatus;
|
||||
}
|
||||
});
|
||||
|
||||
function easePosition(fromPct, pct, duration, easeFx, animateFx) {
|
||||
var deferred = $q.defer();
|
||||
currentEaseStartTime = Date.now();
|
||||
var startTime = currentEaseStartTime;
|
||||
var initialPct = fromPct;
|
||||
var distance = pct - fromPct;
|
||||
function ease() {
|
||||
if(startTime !== currentEaseStartTime) {
|
||||
return;
|
||||
}
|
||||
$window.requestAnimationFrame(function() {
|
||||
var now = Date.now();
|
||||
var elapsed = now - startTime;
|
||||
var normalizedElapsedTime = elapsed/duration;
|
||||
var newVal = easeFx(normalizedElapsedTime);
|
||||
var newPct = newVal*distance + initialPct;
|
||||
animateFx(newPct);
|
||||
scope.$digest();
|
||||
if(elapsed < duration) {
|
||||
ease();
|
||||
} else {
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
ease();
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function linear(t) {
|
||||
return t;
|
||||
}
|
||||
|
||||
function easeInOutBack(t) {
|
||||
return bezier(t);
|
||||
}
|
||||
|
||||
function reset() {
|
||||
$timeout(function() {
|
||||
scope.isSlidFully = false;
|
||||
isSliding = false;
|
||||
setNewSliderStyle(getKnobWidthPercentage());
|
||||
setNewBitcoinStyle(0);
|
||||
setNewTextStyle(0);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function setNewSliderStyle(pct) {
|
||||
var knobWidthPct = getKnobWidthPercentage();
|
||||
var translatePct = pct - knobWidthPct;
|
||||
if(isSliding) {
|
||||
translatePct += 0.35*pct;
|
||||
}
|
||||
scope.sliderStyle = getTransformStyle(translatePct);
|
||||
curSliderPct = pct;
|
||||
}
|
||||
|
||||
function setNewBitcoinStyle(pct) {
|
||||
var translatePct = -2.25*pct;
|
||||
scope.bitcoinStyle = getTransformStyle(translatePct);
|
||||
curBitcoinPct = pct;
|
||||
}
|
||||
|
||||
function setNewTextStyle(pct) {
|
||||
var translatePct = -0.1*pct;
|
||||
scope.textStyle = getTransformStyle(translatePct);
|
||||
curTextPct = pct;
|
||||
}
|
||||
|
||||
function getTransformStyle(translatePct) {
|
||||
return {'transform': 'translateX(' + translatePct + '%)'};
|
||||
}
|
||||
|
||||
function getKnobWidthPercentage() {
|
||||
var knobWidthPct = (KNOB_WIDTH/elm.clientWidth)*100;
|
||||
return knobWidthPct;
|
||||
}
|
||||
|
||||
function setSliderPosition(pct) {
|
||||
setNewSliderStyle(pct);
|
||||
setNewBitcoinStyle(pct);
|
||||
setNewTextStyle(pct);
|
||||
}
|
||||
|
||||
function easeSliderPosition(pct) {
|
||||
var duration = INITIAL_TAP_EASE_DURATION;
|
||||
easePosition(curSliderPct, pct, duration, JIGGLE_EASING, function(pct) {
|
||||
setNewSliderStyle(pct);
|
||||
});
|
||||
easePosition(curBitcoinPct, pct, duration, JIGGLE_EASING, function(pct) {
|
||||
setNewBitcoinStyle(pct);
|
||||
});
|
||||
easePosition(curTextPct, pct, duration, JIGGLE_EASING, function(pct) {
|
||||
setNewTextStyle(pct);
|
||||
});
|
||||
}
|
||||
|
||||
function jiggleSlider() {
|
||||
var pct = getKnobWidthPercentage() + PERCENTAGE_BUMP;
|
||||
var duration = JIGGLE_DURATION;
|
||||
var p1 = easePosition(curSliderPct, pct, duration, JIGGLE_EASING, function(pct) {
|
||||
setNewSliderStyle(pct);
|
||||
});
|
||||
var p2 = easePosition(curBitcoinPct, pct, duration, JIGGLE_EASING, function(pct) {
|
||||
setNewBitcoinStyle(pct);
|
||||
});
|
||||
|
||||
$q.all([p1, p2]).then(function() {
|
||||
recede();
|
||||
});
|
||||
}
|
||||
|
||||
function recede() {
|
||||
var duration = RECEDE_DURATION;
|
||||
easePosition(curSliderPct, getKnobWidthPercentage(), duration, easeInOutBack, function(pct) {
|
||||
setNewSliderStyle(pct);
|
||||
});
|
||||
easePosition(curBitcoinPct, 0, duration, easeInOutBack, function(pct) {
|
||||
setNewBitcoinStyle(pct);
|
||||
});
|
||||
easePosition(curTextPct, 0, duration, easeInOutBack, function(pct) {
|
||||
setNewTextStyle(pct);
|
||||
});
|
||||
}
|
||||
|
||||
function alertSlidFully() {
|
||||
scope.isSlidFully = true;
|
||||
scope.onConfirm();
|
||||
}
|
||||
|
||||
function getTouchXPosition($event) {
|
||||
var x;
|
||||
if($event.touches || $event.changedTouches) {
|
||||
if($event.touches.length) {
|
||||
x = $event.touches[0].clientX;
|
||||
} else {
|
||||
x = $event.changedTouches[0].clientX;
|
||||
}
|
||||
} else {
|
||||
x = $event.clientX;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
function getSlidPercentage($event) {
|
||||
var x = getTouchXPosition($event);
|
||||
var width = elm.clientWidth;
|
||||
var pct = (x/width)*100;
|
||||
if(x >= width) {
|
||||
pct = 100;
|
||||
}
|
||||
return pct;
|
||||
}
|
||||
|
||||
scope.onTouchstart = function($event) {
|
||||
if(scope.isSlidFully) {
|
||||
return;
|
||||
}
|
||||
if(!isSliding) {
|
||||
var pct = getSlidPercentage($event);
|
||||
if (pct > MAX_SLIDE_START_PERCENTAGE) {
|
||||
jiggleSlider();
|
||||
return;
|
||||
} else {
|
||||
isSliding = true;
|
||||
var knobWidthPct = getKnobWidthPercentage();
|
||||
if(pct < knobWidthPct) {
|
||||
pct = knobWidthPct;
|
||||
}
|
||||
pct += PERCENTAGE_BUMP;
|
||||
easeSliderPosition(pct);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
scope.onTouchmove = function($event) {
|
||||
if(!isSliding || scope.isSlidFully) {
|
||||
return;
|
||||
}
|
||||
var pct = getSlidPercentage($event);
|
||||
var knobWidthPct = getKnobWidthPercentage();
|
||||
if(pct < knobWidthPct) {
|
||||
pct = knobWidthPct;
|
||||
}
|
||||
pct += PERCENTAGE_BUMP;
|
||||
currentEaseStartTime = null;
|
||||
setSliderPosition(pct);
|
||||
};
|
||||
|
||||
scope.onTouchend = function($event) {
|
||||
if(scope.isSlidFully) {
|
||||
return;
|
||||
}
|
||||
var pct = getSlidPercentage($event);
|
||||
if(isSliding && pct > FULLY_SLID_PERCENTAGE) {
|
||||
pct = 100;
|
||||
setSliderPosition(pct);
|
||||
alertSlidFully();
|
||||
} else {
|
||||
recede();
|
||||
}
|
||||
isSliding = false;
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
31
src/js/directives/slideToAcceptSuccess.js
Normal file
31
src/js/directives/slideToAcceptSuccess.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.directives')
|
||||
.directive('slideToAcceptSuccess', function($timeout) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'views/includes/slideToAcceptSuccess.html',
|
||||
transclude: true,
|
||||
scope: {
|
||||
isShown: '=slideSuccessShow',
|
||||
onConfirm: '&slideSuccessOnConfirm'
|
||||
},
|
||||
link: function(scope, element, attrs) {
|
||||
var elm = element[0];
|
||||
elm.style.display = 'none';
|
||||
scope.$watch('isShown', function() {
|
||||
if(scope.isShown) {
|
||||
elm.style.display = 'flex';
|
||||
$timeout(function() {
|
||||
scope.fillScreen = true;
|
||||
}, 10);
|
||||
}
|
||||
});
|
||||
scope.onConfirmButtonClick = function() {
|
||||
scope.onConfirm();
|
||||
scope.fillScreen = false;
|
||||
elm.style.display = 'none';
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue