Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Commit

Permalink
update(slider): discrete sliders now support live dragging between di…
Browse files Browse the repository at this point in the history
…screte values and snap-to animate to closest discrete value.
  • Loading branch information
ThomasBurleson committed Sep 27, 2014
1 parent fd7697d commit 1d99105
Showing 1 changed file with 50 additions and 6 deletions.
56 changes: 50 additions & 6 deletions src/components/slider/slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ function SliderDirective() {
'$element',
'$attrs',
'$$rAF',
'$timeout',
'$window',
'$materialEffects',
'$aria',
Expand Down Expand Up @@ -99,7 +98,7 @@ function SliderDirective() {
* We use a controller for all the logic so that we can expose a few
* things to unit tests
*/
function SliderController(scope, element, attr, $$rAF, $timeout, $window, $materialEffects, $aria) {
function SliderController(scope, element, attr, $$rAF, $window, $materialEffects, $aria) {

this.init = function init(ngModelCtrl) {
var thumb = angular.element(element[0].querySelector('.slider-thumb'));
Expand Down Expand Up @@ -136,6 +135,7 @@ function SliderController(scope, element, attr, $$rAF, $timeout, $window, $mater
hammertime.on('hammer.input', onInput);
hammertime.on('panstart', onPanStart);
hammertime.on('pan', onPan);
hammertime.on('panend', onPanEnd);

// On resize, recalculate the slider's dimensions and re-render
var updateAll = $$rAF.debounce(function() {
Expand Down Expand Up @@ -282,18 +282,28 @@ function SliderController(scope, element, attr, $$rAF, $timeout, $window, $mater
* Slide listeners
*/
var isSliding = false;
var isDiscrete = false;

function onInput(ev) {
if (!isSliding && ev.eventType === Hammer.INPUT_START &&
!element[0].hasAttribute('disabled')) {

isSliding = true;
isDiscrete = angular.isDefined(attr.discrete);

element.addClass('active');
element[0].focus();
refreshSliderDimensions();
doSlide(ev.center.x);

onPan(ev);

} else if (isSliding && ev.eventType === Hammer.INPUT_END) {

if ( isDiscrete ) onPanEnd(ev);

isSliding = false;
isDiscrete = false;

element.removeClass('panning active');
}
}
Expand All @@ -303,8 +313,26 @@ function SliderController(scope, element, attr, $$rAF, $timeout, $window, $mater
}
function onPan(ev) {
if (!isSliding) return;
doSlide(ev.center.x);

// While panning discrete, update only the
// visual positioning but not the model value.

if ( isDiscrete ) doPan( ev.center.x );
else doSlide( ev.center.x );

ev.preventDefault();
ev.srcEvent.stopPropagation();
}

function onPanEnd(ev) {
if ( isDiscrete ) {
// Updating the model and slide position
// and perform an animated snap-to operation
doSlide( ev.center.x );
ngModelRender();

ev.srcEvent.stopPropagation();
}
}

/**
Expand All @@ -314,9 +342,25 @@ function SliderController(scope, element, attr, $$rAF, $timeout, $window, $mater
this._onPanStart = onPanStart;
this._onPan = onPan;

function doSlide(x) {
/**
* Slide the UI by changing the model value
* @param x
*/
function doSlide( x ) {
var percent = (x - sliderDimensions.left) / (sliderDimensions.width);

scope.$evalAsync( function() {
setModelValue(min + percent * (max - min));
});
}

/**
* Slide the UI without changing the model (while dragging/panning)
* @param x
*/
function doPan( x ) {
var percent = (x - sliderDimensions.left) / (sliderDimensions.width);
scope.$evalAsync(function() { setModelValue(min + percent * (max - min)); });
setSliderPercent( percent );
}

};
Expand Down

0 comments on commit 1d99105

Please sign in to comment.