Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
|
|
@ -0,0 +1,209 @@
|
|||
'use strict';
|
||||
|
||||
/* globals GestureDetector */
|
||||
/* exported Swipeable */
|
||||
|
||||
(function(exports) {
|
||||
var Swipeable = function(container, eltSelector, options) {
|
||||
this._container = container.querySelector('.swipeable-container');
|
||||
this._eltSelector = eltSelector;
|
||||
|
||||
this.updateElements();
|
||||
this._createProgress();
|
||||
|
||||
this._gestureDetector = new GestureDetector(this._container,
|
||||
{ holdEvents: false });
|
||||
this._panHandler = e => this._handlePan(e);
|
||||
this._swipeHandler = e => this._handleSwipe(e);
|
||||
|
||||
this._container.addEventListener('tap', (e) => {
|
||||
if(this._tapCallback) {
|
||||
this._tapCallback(this._elts[this._activeEltIdx].id);
|
||||
}
|
||||
});
|
||||
|
||||
options = options || {};
|
||||
this._elWidth = options['element-width'] || this._elts[0].offsetWidth;
|
||||
this._triggerPoint = options['auto-scroll-trigger'] || this._triggerPoint;
|
||||
this._minSpeed = options['min-speed'] || this._minSpeed;
|
||||
};
|
||||
|
||||
Swipeable.prototype = {
|
||||
_gestureDetector: null,
|
||||
_container: null,
|
||||
_eltSelector: null,
|
||||
_elts: [],
|
||||
_progressElts: null,
|
||||
|
||||
_elWidth: 0,
|
||||
_triggerPoint: 0.25,
|
||||
_minSpeed: 1.0,
|
||||
|
||||
_inTransition: false,
|
||||
_offset: 0,
|
||||
_activeEltIdx: 0,
|
||||
|
||||
_tapCallback: null,
|
||||
_swipeCallback: null,
|
||||
_vertSwipeCallback: null,
|
||||
|
||||
set ontap(callback) {
|
||||
this._tapCallback = callback;
|
||||
},
|
||||
|
||||
set onswipe(callback) {
|
||||
this._swipeCallback = callback;
|
||||
},
|
||||
|
||||
set onvertswipe(callback) {
|
||||
this._vertSwipeCallback = callback;
|
||||
},
|
||||
|
||||
enable: function() {
|
||||
this._gestureDetector.startDetecting();
|
||||
this.unpauseSwipe();
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
this._gestureDetector.stopDetecting();
|
||||
},
|
||||
|
||||
pauseSwipe: function() {
|
||||
this._container.removeEventListener('pan', this._panHandler);
|
||||
this._container.removeEventListener('swipe', this._swipeHandler);
|
||||
},
|
||||
|
||||
unpauseSwipe: function() {
|
||||
this._container.addEventListener('pan', this._panHandler);
|
||||
this._container.addEventListener('swipe', this._swipeHandler);
|
||||
},
|
||||
|
||||
updateElements: function() {
|
||||
var nodeList = this._container.querySelectorAll('.swipeable > ' + this._eltSelector);
|
||||
this._elts = Array.prototype.slice.call(nodeList);
|
||||
},
|
||||
|
||||
_createProgress: function() {
|
||||
if(!this._elts || !this._elts.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var progressDiv = this._container.querySelector('.swipeable-progress');
|
||||
if(!progressDiv) {
|
||||
return;
|
||||
}
|
||||
|
||||
var progressFragment = document.createDocumentFragment();
|
||||
this._progressElts = this._elts.map(() => {
|
||||
var div = document.createElement('div');
|
||||
progressFragment.appendChild(div);
|
||||
return div;
|
||||
});
|
||||
|
||||
this._progressElts[0].classList.add('swipeable-progress-active');
|
||||
progressDiv.innerHTML = '';
|
||||
progressDiv.appendChild(progressFragment);
|
||||
},
|
||||
|
||||
_updateProgress: function() {
|
||||
this._progressElts.forEach((elt, idx) => {
|
||||
if(idx === this._activeEltIdx) {
|
||||
elt.classList.add('swipeable-progress-active');
|
||||
} else if(elt.classList.contains('swipeable-progress-active')) {
|
||||
elt.classList.remove('swipeable-progress-active');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
progressSelect: function progressSelect(idx, select) {
|
||||
var pElt = this._progressElts[idx];
|
||||
if(!pElt) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(select) {
|
||||
pElt.classList.add('swipeable-progress-selected');
|
||||
} else if(pElt.classList.contains('swipeable-progress-selected')) {
|
||||
pElt.classList.remove('swipeable-progress-selected');
|
||||
}
|
||||
},
|
||||
|
||||
_handlePan: function(event) {
|
||||
if(this._inTransition) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Math.abs(event.detail.relative.dx) > Math.abs(event.detail.relative.dy)) {
|
||||
this._offset += event.detail.relative.dx;
|
||||
this._animate();
|
||||
}
|
||||
},
|
||||
|
||||
_handleSwipe: function(event) {
|
||||
if(this._vertSwipeCallback &&
|
||||
['up', 'down'].indexOf(event.detail.direction) !== -1) {
|
||||
var id = this._elts[this._activeEltIdx].id;
|
||||
this._vertSwipeCallback(event.detail.direction, id);
|
||||
}
|
||||
|
||||
var elPos = Math.abs(this._offset)%this._elWidth;
|
||||
var triggerPassed = elPos > this._elWidth * this._triggerPoint;
|
||||
|
||||
var velocity = event.detail.vx;
|
||||
var fastEnough = Math.abs(velocity) > this._minSpeed;
|
||||
|
||||
var direction = (event.detail.direction === 'left') ? 1 : -1;
|
||||
var newIdx = this._computeNewIndex(direction);
|
||||
|
||||
// Make sure that that the speed and pan amount are in the same direction
|
||||
//var samedirection = velocity === 0 || this._offset / velocity >= 0;
|
||||
|
||||
if((triggerPassed || fastEnough) && newIdx !== this._activeEltIdx) {
|
||||
var speed = Math.max(Math.abs(velocity), this._minSpeed);
|
||||
var time = (this._elWidth - Math.abs(this._offset%this._elWidth)) / speed;
|
||||
|
||||
this._activeEltIdx = newIdx;
|
||||
this._performScroll(time);
|
||||
this._updateProgress();
|
||||
if (this._swipeCallback) {
|
||||
this._swipeCallback(this._activeEltIdx);
|
||||
}
|
||||
} else if(this._offset !== 0){
|
||||
var time = Math.abs(this._offset%this._elWidth) / this._minSpeed;
|
||||
this._performScroll(time);
|
||||
if (this._swipeCallback) {
|
||||
this._swipeCallback(this._activeEltIdx);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_animate: function(time) {
|
||||
var handler = (e) => {
|
||||
e.target.style.transition = null;
|
||||
e.target.removeEventListener('transitionend', handler);
|
||||
};
|
||||
this._elts.forEach((el) => {
|
||||
if(time) {
|
||||
el.style.transition = 'transform ' + time + 'ms ease';
|
||||
el.addEventListener('transitionend', handler);
|
||||
}
|
||||
el.style.transform = 'translate3d('+this._offset+'px,0,0)';
|
||||
});
|
||||
},
|
||||
|
||||
_performScroll: function(time) {
|
||||
this._inTransition = true;
|
||||
this._offset = -1 * this._activeEltIdx * this._elWidth;
|
||||
this._animate(time);
|
||||
setTimeout(() => { this._inTransition = false; }, time);
|
||||
},
|
||||
|
||||
_computeNewIndex: function(direction) {
|
||||
var index = this._activeEltIdx + direction;
|
||||
var offBounds = index < 0 || index >= this._elts.length;
|
||||
return offBounds ? this._activeEltIdx : index;
|
||||
}
|
||||
};
|
||||
|
||||
exports.Swipeable = Swipeable;
|
||||
}((typeof exports === 'undefined') ? window : exports));
|
||||
Loading…
Reference in a new issue