Skip to content
This repository has been archived by the owner on Apr 15, 2020. It is now read-only.

Commit

Permalink
Merge pull request #36 from reco/master
Browse files Browse the repository at this point in the history
Prevent double snap
  • Loading branch information
joelmukuthu committed Nov 10, 2016
2 parents 8d36e65 + a579fc7 commit 411345d
Show file tree
Hide file tree
Showing 8 changed files with 328 additions and 52 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## next release

### Fixes
- On trackpads with high sensitivity (e.g. Macs), swiping once does not lead to
a double snap anymore (thanks @reco). There's a 1 second delay that prevents the
next snap, which can be changed (or disabled) with
[`prevent-double-snap-delay`](DOCS.md#prevent-double-snap-delay)

## 1.0.0

### Breaking changes
Expand Down
15 changes: 15 additions & 0 deletions DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,18 @@ the default value:
angular.module('myapp', ['snapscroll'])
.value('defaultSnapscrollResizeDelay', 400);
```

#### prevent-double-snap-delay
In order to prevent snapping twice in the same direction on trackpads with high
sensitivity, there is a 1 second delay that disables snapping to the same
direction. This can be altered using this attribute or disabled altogether by
passing `false`.
```html
<div snapscroll="" prevent-double-snap-delay="400"> ... </div>
```
the scroll-delay can also be changed for all snapscroll instances by changing
the default value:
```javascript
angular.module('myapp', ['snapscroll'])
.value('defaultSnapscrollPreventDoubleSnapDelay', 400);
```
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,6 @@ for an example (the demo uses angular-swipe).
Have a look at the [docs](DOCS.md) for all the configuration options. For more
examples, view the source on the [demo site](http://joelmukuthu.github.io/angular-snapscroll/).

### Known issue and workaround
Swiping on a trackpad with high sensitivity (i.e. on a Mac) may cause a snapscroll
instance to snap twice in the same direction. The workaround for this is to set
`defaultSnapscrollSnapDuration` or `snap-duration` to a higher value (try 1000ms
or 1200ms).

### Todo's
- snapscroll as an element - would allow use of templates and ngAnimate for
animations. Currently this repo has a (rather outdated) 'as-element' branch for
Expand Down
35 changes: 34 additions & 1 deletion dist/angular-snapscroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@
snapHeight: '=?',
beforeSnap: '&',
afterSnap: '&',
snapAnimation: '=?'
snapAnimation: '=?',
preventDoubleSnap: '=?'
};

var controller = ['$scope', function ($scope) {
Expand Down Expand Up @@ -263,6 +264,9 @@
return scrollie.to.apply(scrollie, args).then(function () {
scope.snapDirection = undefined;
bindScrollAfterDelay();
if (args[1] !== 0) {
scope.preventSnap = true
}
});
}

Expand Down Expand Up @@ -415,6 +419,22 @@
return;
}

if(scope.scrollStopTimeout) {
$timeout.cancel(scope.scrollStopTimeout);
}

if (scope.preventDoubleSnap) {
scope.scrollStopTimeout = $timeout(function(){
scope.scrollStopTimeout = null;
scope.preventSnap = false
console.log('scrollstop');
}, 100);

if (scope.preventSnap) {
return;
}
}

if (scope.snapDirection === direction) {
return true;
}
Expand Down Expand Up @@ -453,12 +473,20 @@
function bindWheel() {
wheelie.bind(element, {
up: function (e) {
if (Math.abs(e.wheelDelta) > scope.oldWheelDelta ) {
scope.preventSnap = false;
}
scope.oldWheelDelta = Math.abs(e.wheelDelta)
e.preventDefault();
if (snapUp()) {
e.stopPropagation();
}
},
down: function (e) {
if (Math.abs(e.wheelDelta) > scope.oldWheelDelta ) {
scope.preventSnap = false;
}
scope.oldWheelDelta = Math.abs(e.wheelDelta)
e.preventDefault();
if (snapDown()) {
e.stopPropagation();
Expand Down Expand Up @@ -674,6 +702,11 @@
}
scope.snapDuration = snapDuration;

var preventDoubleSnap = attributes.preventDoubleSnap;
if (preventDoubleSnap === 'true') {
scope.preventDoubleSnap = true
}

// TODO: perform initial snap without animation
if (isUndefined(scope.snapAnimation)) {
scope.snapAnimation = true;
Expand Down
67 changes: 59 additions & 8 deletions src/directives/snapscroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
'defaultSnapscrollScrollDelay',
'defaultSnapscrollSnapDuration',
'defaultSnapscrollBindScrollTimeout',
'defaultSnapscrollPreventDoubleSnapDelay',
function (
$timeout,
$document,
Expand All @@ -40,7 +41,8 @@
defaultSnapscrollScrollEasing,
defaultSnapscrollScrollDelay,
defaultSnapscrollSnapDuration,
defaultSnapscrollBindScrollTimeout
defaultSnapscrollBindScrollTimeout,
defaultSnapscrollPreventDoubleSnapDelay
) {
return {
restrict: 'A',
Expand Down Expand Up @@ -187,9 +189,27 @@
return scrollie.to.apply(scrollie, args).then(function () {
scope.snapDirection = undefined;
bindScrollAfterDelay();
allowNextSnapAfterDelay();
});
}

function allowNextSnapAfterDelay() {
function allowNextSnap() {
scope.preventUp = false;
scope.preventDown = false;
}
if (scope.preventUp || scope.preventDown) {
if (scope.preventDoubleSnapDelay === false) {
allowNextSnap();
} else {
$timeout(
allowNextSnap,
scope.preventDoubleSnapDelay
);
}
}
}

function isScrollable() {
var snapHeight = getSnapHeight();
if (!snapHeight) {
Expand Down Expand Up @@ -334,15 +354,22 @@
return compositeIndex;
}

function snap(direction) {
function snap(direction, source) {
if (!isScrollable()) {
return;
}

direction === 'up' && (scope.preventDown = false);
direction === 'down' && (scope.preventUp = false);

if (scope.snapDirection === direction) {
return true;
}

if (scope.preventUp || scope.preventDown) {
return true;
}

var snapIndex = scope.compositeIndex[0];
var innerSnapIndex = scope.compositeIndex[1];
var newInnerSnapIndex;
Expand All @@ -358,33 +385,39 @@
return;
}

if (source === 'wheel') {
direction === 'up' && (scope.preventUp = true);
direction === 'down' && (scope.preventDown = true);
}

scope.$apply(function () {
scope.compositeIndex = rectifyCompositeIndex(
newCompositeIndex
);
});

return true;
}

function snapUp() {
return snap('up');
function snapUp(source) {
return snap('up', source);
}

function snapDown() {
return snap('down');
function snapDown(source) {
return snap('down', source);
}

function bindWheel() {
wheelie.bind(element, {
up: function (e) {
e.preventDefault();
if (snapUp()) {
if (snapUp('wheel')) {
e.stopPropagation();
}
},
down: function (e) {
e.preventDefault();
if (snapDown()) {
if (snapDown('wheel')) {
e.stopPropagation();
}
}
Expand Down Expand Up @@ -585,6 +618,24 @@
scope.scrollDelay = scrollDelay;
}

var preventDoubleSnapDelay = (
attributes.preventDoubleSnapDelay
);
if (preventDoubleSnapDelay === 'false') {
scope.preventDoubleSnapDelay = false;
} else {
preventDoubleSnapDelay = parseInt(
preventDoubleSnapDelay,
10
);
if (isNaN(preventDoubleSnapDelay)) {
preventDoubleSnapDelay = (
defaultSnapscrollPreventDoubleSnapDelay
);
}
scope.preventDoubleSnapDelay = preventDoubleSnapDelay;
}

var snapEasing = attributes.snapEasing;
if (isDefined(snapEasing)) {
scope.snapEasing = scope.$parent.$eval(snapEasing);
Expand Down
3 changes: 2 additions & 1 deletion src/snapscroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
.value('defaultSnapscrollScrollDelay', 250)
.value('defaultSnapscrollSnapDuration', 800)
.value('defaultSnapscrollResizeDelay', 400)
.value('defaultSnapscrollBindScrollTimeout', 400);
.value('defaultSnapscrollBindScrollTimeout', 400)
.value('defaultSnapscrollPreventDoubleSnapDelay', 1000);
})();
Loading

0 comments on commit 411345d

Please sign in to comment.