press-swiper
Version:
适配多端的高自定义轮播组件,多种3D效果。全面对标swiperjs。
198 lines (179 loc) • 5.66 kB
JavaScript
import { nextTick } from "../../shared/utils.js";
export default function Controller({ swiper, extendParams, on }) {
extendParams({
controller: {
control: undefined,
inverse: false,
by: "slide", // or 'container'
},
});
swiper.controller = {
control: undefined,
};
function LinearSpline(x, y) {
const binarySearch = (function search() {
let maxIndex;
let minIndex;
let guess;
return (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;
let i1;
let i3;
this.interpolate = function interpolate(x2) {
if (!x2) return 0;
i3 = binarySearch(this.x, x2);
i1 = i3 - 1;
return (
((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) /
(this.x[i3] - this.x[i1]) +
this.y[i1]
);
};
return this;
}
function getInterpolateFunction(c) {
swiper.controller.spline = swiper.params.loop
? new LinearSpline(swiper.slidesGrid, c.slidesGrid)
: new LinearSpline(swiper.snapGrid, c.snapGrid);
}
function setTranslate(_t, byController) {
const controlled = swiper.controller.control;
let multiplier;
let controlledTranslate;
const Swiper = swiper.constructor;
function setControlledTranslate(c) {
if (c.destroyed) return;
const translate = swiper.rtlTranslate
? -swiper.translate
: swiper.translate;
if (swiper.params.controller.by === "slide") {
getInterpolateFunction(c);
controlledTranslate = -swiper.controller.spline.interpolate(-translate);
}
if (!controlledTranslate || swiper.params.controller.by === "container") {
multiplier =
(c.maxTranslate() - c.minTranslate()) /
(swiper.maxTranslate() - swiper.minTranslate());
if (Number.isNaN(multiplier) || !Number.isFinite(multiplier)) {
multiplier = 1;
}
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 (let 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);
}
}
function setTransition(duration, byController) {
const Swiper = swiper.constructor;
const controlled = swiper.controller.control;
let i;
function setControlledTransition(c) {
if (c.destroyed) return;
c.setTransition(duration, swiper);
if (duration !== 0) {
c.transitionStart();
if (c.params.autoHeight) {
nextTick(() => {
c.updateAutoHeight();
});
}
}
}
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);
}
}
function removeSpline() {
if (!swiper.controller.control) return;
if (swiper.controller.spline) {
swiper.controller.spline = undefined;
delete swiper.controller.spline;
}
}
on("beforeInit", () => {
try {
if (
typeof window !== 'undefined' && // eslint-disable-line
(typeof swiper.params.controller.control === "string" ||
swiper.params.controller.control instanceof HTMLElement)
) {
const controlElement = document.querySelector(
swiper.params.controller.control
);
if (controlElement && controlElement.swiper) {
swiper.controller.control = controlElement.swiper;
} else if (controlElement) {
const onControllerSwiper = (e) => {
swiper.controller.control = e.detail[0];
swiper.update();
controlElement.removeEventListener("init", onControllerSwiper);
};
controlElement.addEventListener("init", onControllerSwiper);
}
return;
}
} catch (err) {
//
}
swiper.controller.control = swiper.params.controller.control;
});
on("update", () => {
removeSpline();
});
on("resize", () => {
removeSpline();
});
on("observerUpdate", () => {
removeSpline();
});
on("setTranslate", (_s, translate, byController) => {
if (!swiper.controller.control || swiper.controller.control.destroyed)
return;
swiper.controller.setTranslate(translate, byController);
});
on("setTransition", (_s, duration, byController) => {
if (!swiper.controller.control || swiper.controller.control.destroyed)
return;
swiper.controller.setTransition(duration, byController);
});
Object.assign(swiper.controller, {
setTranslate,
setTransition,
});
}