Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
"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;