Repository URL to install this package:
|
Version:
1.1.21 ▾
|
"use strict";
// at least this only requires utils... the others all inject
const utils = require("./utils"); // -------------------------- requestAnimationFrame -------------------------- //
// get rAF, prefixed, if present
var requestAnimationFrame = typeof window === 'object' && (window.requestAnimationFrame || window.webkitRequestAnimationFrame); // fallback to setTimeout
var lastTime = 0;
if (!requestAnimationFrame) {
requestAnimationFrame = function requestAnimationFrame(callback) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = setTimeout(callback, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
} // -------------------------- animate -------------------------- //
var proto = {};
proto.startAnimation = function () {
if (this.isAnimating) {
return;
}
this.isAnimating = true;
this.restingFrames = 0;
this.animate();
};
proto.animate = function () {
this.applyDragForce();
this.applySelectedAttraction();
var previousX = this.x;
this.integratePhysics();
this.positionSlider();
this.settle(previousX); // animate next frame
if (this.isAnimating) {
var _this = this;
requestAnimationFrame(function animateFrame() {
_this.animate();
});
}
};
var transformProperty = function () {
var style = document.documentElement.style;
if (typeof style.transform == 'string') {
return 'transform';
}
return 'WebkitTransform';
}();
proto.positionSlider = function () {
var x = this.x; // wrap position around
if (this.options.wrapAround && this.cells.length > 1) {
x = utils.modulo(x, this.slideableWidth);
x = x - this.slideableWidth;
this.shiftWrapCells(x);
}
x = x + this.cursorPosition; // reverse if right-to-left and using transform
x = this.options.rightToLeft && transformProperty ? -x : x;
var value = this.getPositionValue(x); // use 3D tranforms for hardware acceleration on iOS
// but use 2D when settled, for better font-rendering
this.slider.style[transformProperty] = this.isAnimating ? 'translate3d(' + value + ',0,0)' : 'translateX(' + value + ')'; // scroll event
var firstSlide = this.slides[0];
if (firstSlide) {
var positionX = -this.x - firstSlide.target;
var progress = positionX / this.slidesWidth;
this.dispatchEvent('scroll', null, [progress, positionX]);
}
};
proto.positionSliderAtSelected = function () {
if (!this.cells.length) {
return;
}
this.x = -this.selectedSlide.target;
this.positionSlider();
};
proto.getPositionValue = function (position) {
if (this.options.percentPosition) {
// percent position, round to 2 digits, like 12.34%
return Math.round(position / this.size.innerWidth * 10000) * 0.01 + '%';
} else {
// pixel positioning
return Math.round(position) + 'px';
}
};
proto.settle = function (previousX) {
// keep track of frames where x hasn't moved
if (!this.isPointerDown && Math.round(this.x * 100) == Math.round(previousX * 100)) {
this.restingFrames++;
} // stop animating if resting for 3 or more frames
if (this.restingFrames > 2) {
this.isAnimating = false;
delete this.isFreeScrolling; // render position with translateX when settled
this.positionSlider();
this.dispatchEvent('settle');
}
};
proto.shiftWrapCells = function (x) {
// shift before cells
var beforeGap = this.cursorPosition + x;
this._shiftCells(this.beforeShiftCells, beforeGap, -1); // shift after cells
var afterGap = this.size.innerWidth - (x + this.slideableWidth + this.cursorPosition);
this._shiftCells(this.afterShiftCells, afterGap, 1);
};
proto._shiftCells = function (cells, gap, shift) {
for (var i = 0; i < cells.length; i++) {
var cell = cells[i];
var cellShift = gap > 0 ? shift : 0;
cell.wrapShift(cellShift);
gap -= cell.size.outerWidth;
}
};
proto._unshiftCells = function (cells) {
if (!cells || !cells.length) {
return;
}
for (var i = 0; i < cells.length; i++) {
cells[i].wrapShift(0);
}
}; // -------------------------- physics -------------------------- //
proto.integratePhysics = function () {
this.x += this.velocity;
this.velocity *= this.getFrictionFactor();
};
proto.applyForce = function (force) {
this.velocity += force;
};
proto.getFrictionFactor = function () {
return 1 - this.options[this.isFreeScrolling ? 'freeScrollFriction' : 'friction'];
};
proto.getRestingPosition = function () {
// my thanks to Steven Wittens, who simplified this math greatly
return this.x + this.velocity / (1 - this.getFrictionFactor());
};
proto.applyDragForce = function () {
if (!this.isPointerDown) {
return;
} // change the position to drag position by applying force
var dragVelocity = this.dragX - this.x;
var dragForce = dragVelocity - this.velocity;
this.applyForce(dragForce);
};
proto.applySelectedAttraction = function () {
// do not attract if pointer down or no cells
if (this.isPointerDown || this.isFreeScrolling || !this.cells.length) {
return;
}
var distance = this.selectedSlide.target * -1 - this.x;
var force = distance * this.options.selectedAttraction;
this.applyForce(force);
};
module.exports = proto;