UNPKG

swiper

Version:

Most modern mobile touch slider and framework with hardware accelerated transitions

197 lines (168 loc) 6.53 kB
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } /* eslint no-bitwise: ["error", { "allow": [">>"] }] */ import { nextTick, bindModuleMethods } from '../../utils/utils'; var Controller = { LinearSpline: function LinearSpline(x, y) { var binarySearch = function search() { var maxIndex; var minIndex; var guess; return function (array, val) { minIndex = -1; maxIndex = array.length; while (maxIndex - minIndex > 1) { guess = maxIndex + minIndex >> 1; if (array[guess] <= val) { minIndex = guess; } else { maxIndex = guess; } } return maxIndex; }; }(); this.x = x; this.y = y; this.lastIndex = x.length - 1; // Given an x value (x2), return the expected y2 value: // (x1,y1) is the known point before given value, // (x3,y3) is the known point after given value. var i1; var i3; this.interpolate = function interpolate(x2) { if (!x2) return 0; // Get the indexes of x1 and x3 (the array indexes before and after given x2): i3 = binarySearch(this.x, x2); i1 = i3 - 1; // We have our indexes i1 & i3, so we can calculate already: // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1 return (x2 - this.x[i1]) * (this.y[i3] - this.y[i1]) / (this.x[i3] - this.x[i1]) + this.y[i1]; }; return this; }, // xxx: for now i will just save one spline function to to getInterpolateFunction: function getInterpolateFunction(c) { var swiper = this; if (!swiper.controller.spline) { swiper.controller.spline = swiper.params.loop ? new Controller.LinearSpline(swiper.slidesGrid, c.slidesGrid) : new Controller.LinearSpline(swiper.snapGrid, c.snapGrid); } }, setTranslate: function setTranslate(_setTranslate, byController) { var swiper = this; var controlled = swiper.controller.control; var multiplier; var controlledTranslate; var Swiper = swiper.constructor; function setControlledTranslate(c) { // this will create an Interpolate function based on the snapGrids // x is the Grid of the scrolled scroller and y will be the controlled scroller // it makes sense to create this only once and recall it for the interpolation // the function does a lot of value caching for performance var translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate; if (swiper.params.controller.by === 'slide') { swiper.controller.getInterpolateFunction(c); // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid // but it did not work out controlledTranslate = -swiper.controller.spline.interpolate(-translate); } if (!controlledTranslate || swiper.params.controller.by === 'container') { multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate()); controlledTranslate = (translate - swiper.minTranslate()) * multiplier + c.minTranslate(); } if (swiper.params.controller.inverse) { controlledTranslate = c.maxTranslate() - controlledTranslate; } c.updateProgress(controlledTranslate); c.setTranslate(controlledTranslate, swiper); c.updateActiveIndex(); c.updateSlidesClasses(); } if (Array.isArray(controlled)) { for (var i = 0; i < controlled.length; i += 1) { if (controlled[i] !== byController && controlled[i] instanceof Swiper) { setControlledTranslate(controlled[i]); } } } else if (controlled instanceof Swiper && byController !== controlled) { setControlledTranslate(controlled); } }, setTransition: function setTransition(duration, byController) { var swiper = this; var Swiper = swiper.constructor; var controlled = swiper.controller.control; var i; function setControlledTransition(c) { c.setTransition(duration, swiper); if (duration !== 0) { c.transitionStart(); if (c.params.autoHeight) { nextTick(function () { c.updateAutoHeight(); }); } c.$wrapperEl.transitionEnd(function () { if (!controlled) return; if (c.params.loop && swiper.params.controller.by === 'slide') { c.loopFix(); } c.transitionEnd(); }); } } if (Array.isArray(controlled)) { for (i = 0; i < controlled.length; i += 1) { if (controlled[i] !== byController && controlled[i] instanceof Swiper) { setControlledTransition(controlled[i]); } } } else if (controlled instanceof Swiper && byController !== controlled) { setControlledTransition(controlled); } } }; export default { name: 'controller', params: { controller: { control: undefined, inverse: false, by: 'slide' // or 'container' } }, create: function create() { var swiper = this; bindModuleMethods(swiper, { controller: _extends({ control: swiper.params.controller.control }, Controller) }); }, on: { update: function update(swiper) { if (!swiper.controller.control) return; if (swiper.controller.spline) { swiper.controller.spline = undefined; delete swiper.controller.spline; } }, resize: function resize(swiper) { if (!swiper.controller.control) return; if (swiper.controller.spline) { swiper.controller.spline = undefined; delete swiper.controller.spline; } }, observerUpdate: function observerUpdate(swiper) { if (!swiper.controller.control) return; if (swiper.controller.spline) { swiper.controller.spline = undefined; delete swiper.controller.spline; } }, setTranslate: function setTranslate(swiper, translate, byController) { if (!swiper.controller.control) return; swiper.controller.setTranslate(translate, byController); }, setTransition: function setTransition(swiper, duration, byController) { if (!swiper.controller.control) return; swiper.controller.setTransition(duration, byController); } } };