会员权益

This commit is contained in:
2026-04-29 15:33:58 +08:00
commit 54965243da
2787 changed files with 242809 additions and 0 deletions

View File

@@ -0,0 +1,210 @@
import {
nextTick
} from '../../shared/utils.js';
export default function Autoplay({
swiper,
extendParams,
on,
emit
}) {
let timeout;
swiper.autoplay = {
running: false,
paused: false
};
extendParams({
autoplay: {
enabled: false,
delay: 3000,
waitForTransition: true,
disableOnInteraction: true,
stopOnLastSlide: false,
reverseDirection: false,
pauseOnMouseEnter: false
}
});
function run() {
const $activeSlideEl = swiper.slides[swiper.activeIndex];
let delay = swiper.params.autoplay.delay;
clearTimeout(timeout);
timeout = nextTick(() => {
let autoplayResult;
if (swiper.params.autoplay.reverseDirection) {
if (swiper.params.loop) {
swiper.loopFix();
autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
emit('autoplay');
} else if (!swiper.isBeginning) {
autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
emit('autoplay');
} else if (!swiper.params.autoplay.stopOnLastSlide) {
autoplayResult = swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true);
emit('autoplay');
} else {
stop();
}
} else if (swiper.params.loop) {
swiper.loopFix();
setTimeout(() => {
autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
}, 30)
emit('autoplay');
} else if (!swiper.isEnd) {
autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
emit('autoplay');
} else if (!swiper.params.autoplay.stopOnLastSlide) {
autoplayResult = swiper.slideTo(0, swiper.params.speed, true, true);
emit('autoplay');
} else {
stop();
}
if (swiper.params.cssMode && swiper.autoplay.running) run();
else if (autoplayResult === false) {
run();
}
}, delay);
}
function start() {
if (typeof timeout !== 'undefined') return false;
if (swiper.autoplay.running) return false;
swiper.autoplay.running = true;
emit('autoplayStart');
run();
return true;
}
function stop() {
if (!swiper.autoplay.running) return false;
if (typeof timeout === 'undefined') return false;
if (timeout) {
clearTimeout(timeout);
timeout = undefined;
}
swiper.autoplay.running = false;
emit('autoplayStop');
return true;
}
function pause(speed) {
if (!swiper.autoplay.running) return;
if (swiper.autoplay.paused) return;
if (timeout) clearTimeout(timeout);
swiper.autoplay.paused = true;
if (speed === 0 || !swiper.params.autoplay.waitForTransition) {
swiper.autoplay.paused = false;
run();
} else {
['transitionEnd', 'webkitTransitionEnd'].forEach(event => {
swiper.on(event, onTransitionEnd);
});
}
}
function onVisibilityChange() {
// const document = getDocument();
// if (document.visibilityState === 'hidden' && swiper.autoplay.running) {
// pause();
// }
// if (document.visibilityState === 'visible' && swiper.autoplay.paused) {
// run();
// swiper.autoplay.paused = false;
// }
}
function onTransitionEnd(e) {
if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return;
// if (e.target !== swiper.$wrapperEl[0]) return;
['transitionEnd', 'webkitTransitionEnd'].forEach(event => {
swiper.off(event, onTransitionEnd);
});
swiper.autoplay.paused = false;
if (!swiper.autoplay.running) {
stop();
} else {
run();
}
}
function onMouseEnter() {
if (swiper.params.autoplay.disableOnInteraction) {
stop();
} else {
pause();
}
// ['transitionend', 'webkitTransitionEnd'].forEach(event => {
// swiper.$wrapperEl[0].removeEventListener(event, onTransitionEnd);
// });
}
function onMouseLeave() {
if (swiper.params.autoplay.disableOnInteraction) {
return;
}
swiper.autoplay.paused = false;
run();
}
function attachMouseEvents() {
if (swiper.params.autoplay.pauseOnMouseEnter) {}
}
function detachMouseEvents() {}
on('init update', () => {
if (swiper.params.autoplay.enabled) {
start();
attachMouseEvents();
}
});
on('beforeTransitionStart', (_s, speed, internal) => {
if (swiper.autoplay.running) {
if (internal || !swiper.params.autoplay.disableOnInteraction) {
swiper.autoplay.pause(speed);
} else {
if (!swiper.params.loop) {
stop();
}
}
}
});
on('sliderFirstMove', () => {
if (swiper.autoplay.running) {
if (swiper.params.autoplay.disableOnInteraction) {
stop();
} else {
pause();
}
}
});
on('touch-end', () => {
if (swiper.params.cssMode && swiper.autoplay.paused && !swiper.params.autoplay.disableOnInteraction) {
run();
}
});
on('destroy', () => {
detachMouseEvents();
if (swiper.autoplay.running) {
stop();
}
});
Object.assign(swiper.autoplay, {
pause,
run,
start,
stop
});
}

View File

@@ -0,0 +1,189 @@
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', () => {
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;
}
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,
});
}

View File

@@ -0,0 +1,130 @@
import effectInit from '../../shared/effect-init.js';
import effectTarget from '../../shared/effect-target.js';
import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
export default function EffectCards({
swiper,
extendParams,
on
}) {
extendParams({
cardsEffect: {
slideShadows: true,
transformEl: null,
rotate: true,
perSlideRotate: 2,
perSlideOffset: 8,
},
});
const setTranslate = () => {
const {
slides,
activeIndex
} = swiper;
const params = swiper.params.cardsEffect;
const {
startTranslate,
isTouched
} = swiper.touchEventsData;
const currentTranslate = swiper.translate;
for (let i = 0; i < slides.length; i += 1) {
const $slideEl = slides[i];
const slideProgress = $slideEl.progress;
const progress = Math.min(Math.max(slideProgress, -4), 4);
let offset = $slideEl.swiperSlideOffset;
if (swiper.params.centeredSlides && !swiper.params.cssMode) {
swiper.$wrapperEl.transform(`translateX(${swiper.minTranslate()}px)`);
}
if (swiper.params.centeredSlides && swiper.params.cssMode) {
offset -= slides.swiperSlideOffset;
}
let tX = swiper.params.cssMode ? -offset - swiper.translate : -offset;
let tY = 0;
const tZ = -100 * Math.abs(progress);
let scale = 1;
let rotate = -params.perSlideRotate * progress;
let tXAdd = params.perSlideOffset - Math.abs(progress) * 0.75;
const isSwipeToNext =
(i === activeIndex || i === activeIndex - 1) &&
progress > 0 &&
progress < 1 &&
(isTouched || swiper.params.cssMode) &&
currentTranslate < startTranslate;
const isSwipeToPrev =
(i === activeIndex || i === activeIndex + 1) &&
progress < 0 &&
progress > -1 &&
(isTouched || swiper.params.cssMode) &&
currentTranslate > startTranslate;
if (isSwipeToNext || isSwipeToPrev) {
const subProgress = (1 - Math.abs((Math.abs(progress) - 0.5) / 0.5)) ** 0.5;
rotate += -28 * progress * subProgress;
scale += -0.5 * subProgress;
tXAdd += 96 * subProgress;
tY = `${-25 * subProgress * Math.abs(progress)}%`;
}
if (progress < 0) {
// next
tX = `calc(${tX}px + (${tXAdd * Math.abs(progress)}%))`;
} else if (progress > 0) {
// prev
tX = `calc(${tX}px + (-${tXAdd * Math.abs(progress)}%))`;
} else {
tX = `${tX}px`;
}
if (!swiper.isHorizontal()) {
const prevY = tY;
tY = tX;
tX = prevY;
}
const scaleString =
progress < 0 ? `${1 + (1 - scale) * progress}` : `${1 - (1 - scale) * progress}`;
const transform =
`translate3d(${tX}, ${tY}, ${tZ}px) rotateZ(${params.rotate ? rotate : 0}deg) scale(${scaleString})`;
$slideEl.css({
zIndex: -Math.abs(Math.round(slideProgress)) + slides.length
})
const $targetEl = effectTarget(params, $slideEl);
$targetEl.transform(transform);
if (swiper.params.willChange) {
$targetEl.willChange("transform");
}
slides[i].addClass('swiper-slide-cards')
}
};
const setTransition = (duration) => {
const {
transformEl
} = swiper.params.cardsEffect;
const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
for (let i = 0; i < $transitionElements.length; i += 1) {
$transitionElements[i].transition(duration);
}
effectVirtualTransitionEnd({
swiper,
duration,
transformEl
});
};
effectInit({
effect: 'cards',
swiper,
on,
setTranslate,
setTransition,
perspective: () => true,
overwriteParams: () => ({
watchSlidesProgress: true,
virtualTranslate: !swiper.params.cssMode,
}),
});
}

View File

@@ -0,0 +1,8 @@
.swiper-cards {
overflow: visible;
}
.swiper-slide-cards {
transform-origin: center bottom;
backface-visibility: hidden;
}

View File

@@ -0,0 +1,66 @@
import effectInit from '../../shared/effect-init.js';
import effectTarget from '../../shared/effect-target.js';
export default function EffectCarousel({
swiper,
extendParams,
on
}) {
extendParams({
carouselEffect: {}
});
const setTranslate = () => {
const scaleStep = 0.2;
const zIndexMax = swiper.slides.length;
for (let i = 0; i < swiper.slides.length; i += 1) {
const slideEl = swiper.slides[i];
const slideProgress = swiper.slides[i].progress;
const absProgress = Math.abs(slideProgress);
let modify = 1;
if (absProgress > 1) {
modify = (absProgress - 1) * 0.3 + 1;
}
const translate = `${slideProgress * modify * 50}%`;
const scale = 1 - absProgress * scaleStep;
const zIndex = zIndexMax - Math.abs(Math.round(slideProgress));
const slideTransform = `translateX(${translate}) scale(${scale})`;
slideEl.transform(slideTransform);
slideEl.css({
zIndex: zIndex
})
if (absProgress > 3) {
slideEl.css({
opacity: 0
})
} else {
slideEl.css({
opacity: 1
})
}
}
};
const setTransition = duration => {
const {
transformEl
} = swiper.params.coverflowEffect;
const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
for (var i = 0; i < $transitionElements.length; i++) {
$transitionElements[i].transition(duration);
}
};
effectInit({
effect: 'carousel',
swiper,
on,
setTranslate,
setTransition,
perspective: () => true,
overwriteParams: () => ({
watchSlidesProgress: true,
slidesPerView: 'auto',
centeredSlides: true,
})
});
}

View File

@@ -0,0 +1,6 @@
.swiper-slide-carousel {
backface-visibility: hidden;
overflow: hidden;
transition-property: transform, opacity, height;
transform-style: preserve-3d;
}

View File

@@ -0,0 +1,110 @@
import effectInit from '../../shared/effect-init.js';
import effectTarget from '../../shared/effect-target.js';
export default function EffectCoverflow({
swiper,
extendParams,
on
}) {
extendParams({
coverflowEffect: {
rotate: 50,
stretch: 0,
depth: 100,
scale: 1,
modifier: 1,
slideShadows: true,
transformEl: null
}
});
const setTranslate = () => {
const {
width: swiperWidth,
height: swiperHeight,
slides,
slidesSizesGrid
} = swiper;
const params = swiper.params.coverflowEffect;
const isHorizontal = swiper.isHorizontal();
const transform = swiper.translate;
const center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2;
const rotate = isHorizontal ? params.rotate : -params.rotate;
const translate = params.depth; // Each slide offset from center
for (let i = 0, length = slides.length; i < length; i += 1) {
const $slideEl = slides[i];
const slideSize = slidesSizesGrid[i];
const slideOffset = $slideEl.swiperSlideOffset;
const offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * params.modifier;
let rotateY = isHorizontal ? rotate * offsetMultiplier : 0;
let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier; // var rotateZ = 0
let translateZ = -translate * Math.abs(offsetMultiplier);
let stretch = params.stretch; // Allow percentage to make a relative stretch for responsive sliders
if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) {
stretch = parseFloat(params.stretch) / 100 * slideSize;
}
let translateY = isHorizontal ? 0 : stretch * offsetMultiplier;
let translateX = isHorizontal ? stretch * offsetMultiplier : 0;
let scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier); // Fix for ultra small values
if (Math.abs(translateX) < 0.001) translateX = 0;
if (Math.abs(translateY) < 0.001) translateY = 0;
if (Math.abs(translateZ) < 0.001) translateZ = 0;
if (Math.abs(rotateY) < 0.001) rotateY = 0;
if (Math.abs(rotateX) < 0.001) rotateX = 0;
if (Math.abs(scale) < 0.001) scale = 0;
const slideTransform =
`translate3d(${translateX}px,${translateY}px,${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(${scale})`;
const $targetEl = effectTarget(params, $slideEl);
$targetEl.transform(slideTransform);
$slideEl.css({
zIndex: -Math.abs(Math.round(offsetMultiplier)) + 1
})
if (swiper.params.willChange) {
$targetEl.willChange("transform");
}
$slideEl.addClass('swiper-slide-coverflow')
// if (params.slideShadows) {
// // Set shadows
// let $shadowBeforeEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');
// let $shadowAfterEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');
// if ($shadowBeforeEl.length === 0) {
// $shadowBeforeEl = createShadow(params, $slideEl, isHorizontal ? 'left' : 'top');
// }
// if ($shadowAfterEl.length === 0) {
// $shadowAfterEl = createShadow(params, $slideEl, isHorizontal ? 'right' : 'bottom');
// }
// if ($shadowBeforeEl.length) $shadowBeforeEl[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
// if ($shadowAfterEl.length) $shadowAfterEl[0].style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;
// }
}
};
const setTransition = duration => {
const {
transformEl
} = swiper.params.coverflowEffect;
const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
for (var i = 0; i < $transitionElements.length; i++) {
$transitionElements[i].transition(duration);
}
};
effectInit({
effect: 'coverflow',
swiper,
on,
setTranslate,
setTransition,
perspective: () => true,
overwriteParams: () => ({
watchSlidesProgress: true
})
});
}

View File

@@ -0,0 +1,3 @@
.swiper-slide-coverflow{
transform-style: preserve-3d;
}

View File

@@ -0,0 +1,178 @@
import effectInit from '../../shared/effect-init.js';
import effectTarget from '../../shared/effect-target.js';
import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
export default function EffectCreative({
swiper,
extendParams,
on
}) {
extendParams({
creativeEffect: {
transformEl: null,
limitProgress: 1,
shadowPerProgress: false,
progressMultiplier: 1,
perspective: true,
prev: {
translate: [0, 0, 0],
rotate: [0, 0, 0],
opacity: 1,
scale: 1,
},
next: {
translate: [0, 0, 0],
rotate: [0, 0, 0],
opacity: 1,
scale: 1,
},
},
});
const getTranslateValue = (value) => {
if (typeof value === 'string') return value;
return `${value}px`;
};
const setTranslate = () => {
const {
slides,
$wrapperEl,
slidesSizesGrid
} = swiper;
const params = swiper.params.creativeEffect;
const {
progressMultiplier: multiplier
} = params;
const isCenteredSlides = swiper.params.centeredSlides;
if (isCenteredSlides) {
const margin = slidesSizesGrid[0] / 2 - swiper.params.slidesOffsetBefore || 0;
$wrapperEl.transform(`translateX(calc(50% - ${margin}px))`);
}
for (let i = 0; i < slides.length; i += 1) {
const $slideEl = slides[i];
const slideProgress = $slideEl.progress;
const progress = Math.min(
Math.max($slideEl.progress, -params.limitProgress),
params.limitProgress,
);
let originalProgress = progress;
if (!isCenteredSlides) {
originalProgress = Math.min(
Math.max($slideEl.originalProgress, -params.limitProgress),
params.limitProgress,
);
}
const offset = $slideEl.swiperSlideOffset;
const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0];
const r = [0, 0, 0];
let custom = false;
if (!swiper.isHorizontal()) {
t[1] = t[0];
t[0] = 0;
}
let data = {
translate: [0, 0, 0],
rotate: [0, 0, 0],
scale: 1,
opacity: 1,
};
if (progress < 0) {
data = params.next;
custom = true;
} else if (progress > 0) {
data = params.prev;
custom = true;
}
// set translate
t.forEach((value, index) => {
t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(
progress * multiplier,
)}))`;
});
// set rotates
r.forEach((value, index) => {
r[index] = data.rotate[index] * Math.abs(progress * multiplier);
});
// $slideEl[0].style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
$slideEl.css({
zIndex: -Math.abs(Math.round(slideProgress)) + slides.length
})
const translateString = t.join(', ');
const rotateString = `rotateX(${r[0]}deg) rotateY(${r[1]}deg) rotateZ(${r[2]}deg)`;
const scaleString =
originalProgress < 0 ?
`scale(${1 + (1 - data.scale) * originalProgress * multiplier})` :
`scale(${1 - (1 - data.scale) * originalProgress * multiplier})`;
const opacityString =
originalProgress < 0 ?
1 + (1 - data.opacity) * originalProgress * multiplier :
1 - (1 - data.opacity) * originalProgress * multiplier;
const transform = `translate3d(${translateString}) ${rotateString} ${scaleString}`;
// Set shadows
// if ((custom && data.shadow) || !custom) {
// let $shadowEl = $slideEl.children('.swiper-slide-shadow');
// if ($shadowEl.length === 0 && data.shadow) {
// $shadowEl = createShadow(params, $slideEl);
// }
// if ($shadowEl.length) {
// const shadowOpacity = params.shadowPerProgress
// ? progress * (1 / params.limitProgress)
// : progress;
// $shadowEl[0].style.opacity = Math.min(Math.max(Math.abs(shadowOpacity), 0), 1);
// }
// }
const $targetEl = effectTarget(params, $slideEl);
$targetEl.transform(transform);
$targetEl.css({
opacity: opacityString
});
if (data.origin) {
$targetEl.css({
'transform-origin': data.origin
});
}
if (swiper.params.willChange) {
slides[i].willChange("transform,opacity");
}
slides[i].addClass('swiper-slide-creative')
}
};
const setTransition = (duration) => {
const {
transformEl
} = swiper.params.creativeEffect;
const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
for (let i = 0; i < $transitionElements.length; i += 1) {
$transitionElements[i].transition(duration);
}
effectVirtualTransitionEnd({
swiper,
duration,
transformEl,
allSlides: true
});
};
effectInit({
effect: 'creative',
swiper,
on,
setTranslate,
setTransition,
perspective: () => swiper.params.creativeEffect.perspective,
overwriteParams: () => ({
watchSlidesProgress: true,
virtualTranslate: !swiper.params.cssMode,
}),
});
}

View File

@@ -0,0 +1,9 @@
.swiper-creative {
}
.swiper-slide-creative {
backface-visibility: hidden;
overflow: hidden;
transition-property: transform, opacity, height;
transform-style: preserve-3d;
}

View File

@@ -0,0 +1,191 @@
import effectInit from '../../shared/effect-init.js';
export default function EffectCube({
swiper,
extendParams,
on
}) {
extendParams({
cubeEffect: {
slideShadows: true,
shadow: true,
shadowOffset: 20,
shadowScale: 0.94,
},
});
const setTranslate = () => {
const {
$el,
$wrapperEl,
slides,
width: swiperWidth,
height: swiperHeight,
rtlTranslate: rtl,
size: swiperSize,
browser,
} = swiper;
const params = swiper.params.cubeEffect;
const isHorizontal = swiper.isHorizontal();
const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
let wrapperRotate = 0;
let $cubeShadowEl;
if (params.shadow) {
if (isHorizontal) {
// $cubeShadowEl = $wrapperEl.find('.swiper-cube-shadow');
if (!swiper.native.cubeShadowShowWrapper) {
swiper.$wrapperEl.updateData({
cubeShadowShowWrapper: true
})
}
swiper.$wrapperEl.cubeShadowCss({
height: `${swiperWidth}px`
});
} else {
if (!swiper.native.cubeShadowShowRoot) {
swiper.$wrapperEl.updateData({
cubeShadowShowRoot: true
})
}
}
}
for (let i = 0; i < slides.length; i += 1) {
const $slideEl = slides[i];
let slideIndex = i;
if (isVirtual) {
slideIndex = parseInt(swiper.activeIndex, 10);
}
let slideAngle = slideIndex * 90;
let round = Math.floor(slideAngle / 360);
if (rtl) {
slideAngle = -slideAngle;
round = Math.floor(-slideAngle / 360);
}
const progress = Math.max(Math.min($slideEl.progress, 1), -1);
let tx = 0;
let ty = 0;
let tz = 0;
if (slideIndex % 4 === 0) {
tx = -round * 4 * swiperSize;
tz = 0;
} else if ((slideIndex - 1) % 4 === 0) {
tx = 0;
tz = -round * 4 * swiperSize;
} else if ((slideIndex - 2) % 4 === 0) {
tx = swiperSize + round * 4 * swiperSize;
tz = swiperSize;
} else if ((slideIndex - 3) % 4 === 0) {
tx = -swiperSize;
tz = 3 * swiperSize + swiperSize * 4 * round;
}
if (rtl) {
tx = -tx;
}
if (!isHorizontal) {
ty = tx;
tx = 0;
}
const transform = `rotateX(${isHorizontal ? 0 : -slideAngle}deg) rotateY(${
isHorizontal ? slideAngle : 0
}deg) translate3d(${tx}px, ${ty}px, ${tz}px)`;
if (progress <= 1 && progress > -1) {
wrapperRotate = slideIndex * 90 + progress * 90;
if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90;
}
$slideEl.transform(transform);
// if (params.slideShadows) {
// // Set shadows
// let shadowBefore = isHorizontal ?
// $slideEl.find('.swiper-slide-shadow-left') :
// $slideEl.find('.swiper-slide-shadow-top');
// let shadowAfter = isHorizontal ?
// $slideEl.find('.swiper-slide-shadow-right') :
// $slideEl.find('.swiper-slide-shadow-bottom');
// if (shadowBefore.length === 0) {
// shadowBefore = $(
// `<div class="swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}"></div>`,
// );
// $slideEl.append(shadowBefore);
// }
// if (shadowAfter.length === 0) {
// shadowAfter = $(
// `<div class="swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}"></div>`,
// );
// $slideEl.append(shadowAfter);
// }
// if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
// if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
// }
$slideEl.addClass('swiper-slide-cube')
}
$wrapperEl.css({
'-webkit-transform-origin': `50% 50% -${swiperSize / 2}px`,
'transform-origin': `50% 50% -${swiperSize / 2}px`,
});
if (params.shadow) {
if (isHorizontal) {
swiper.$wrapperEl.cubeShadowTransform(
`translate3d(0px, ${swiperWidth / 2 + params.shadowOffset}px, ${
-swiperWidth / 2
}px) rotateX(90deg) rotateZ(0deg) scale(${params.shadowScale})`,
);
} else {
const shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
const multiplier =
1.5 -
(Math.sin((shadowAngle * 2 * Math.PI) / 360) / 2 +
Math.cos((shadowAngle * 2 * Math.PI) / 360) / 2);
const scale1 = params.shadowScale;
const scale2 = params.shadowScale / multiplier;
const offset = params.shadowOffset;
swiper.$wrapperEl.cubeShadowTransform(
`scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${swiperHeight / 2 + offset}px, ${
-swiperHeight / 2 / scale2
}px) rotateX(-90deg)`,
);
}
}
const zFactor = browser.isSafari || browser.isWebView ? -swiperSize / 2 : 0;
$wrapperEl.transform(
`translate3d(0px,0,${zFactor}px) rotateX(${
swiper.isHorizontal() ? 0 : wrapperRotate
}deg) rotateY(${swiper.isHorizontal() ? -wrapperRotate : 0}deg)`,
);
};
const setTransition = (duration) => {
const {
$el,
slides
} = swiper;
for (var i = 0; i < slides.length; i++) {
slides[i].transition(duration)
}
if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {
swiper.$wrapperEl.cubeShadowTransition(duration);
}
};
effectInit({
effect: 'cube',
swiper,
on,
setTranslate,
setTransition,
perspective: () => true,
overwriteParams: () => ({
slidesPerView: 1,
slidesPerGroup: 1,
watchSlidesProgress: true,
resistanceRatio: 0,
spaceBetween: 0,
centeredSlides: false,
virtualTranslate: true,
}),
});
}

View File

@@ -0,0 +1,49 @@
.swiper-cube {
overflow: visible;
&.swiper-rtl .swiper-slide {
transform-origin: 100% 0;
}
.swiper-cube-shadow {
position: absolute;
left: 0;
bottom: 0px;
width: 100%;
height: 100%;
opacity: 0.6;
z-index: 0;
&:before {
content: '';
background: #000;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
-webkit-filter: blur(50px);
filter: blur(50px);
}
}
}
.swiper-slide-cube {
pointer-events: none;
backface-visibility: hidden;
z-index: 1;
visibility: hidden;
transform-origin: 0 0;
width: 100%;
height: 100%;
transform-style: preserve-3d;
.swiper-slide {
pointer-events: none;
}
}
.swiper-slide-cube.swiper-slide-active,
.swiper-slide-cube.swiper-slide-next,
.swiper-slide-cube.swiper-slide-prev,
.swiper-slide-cube.swiper-slide-next + .swiper-slide {
pointer-events: auto;
visibility: visible;
}

View File

@@ -0,0 +1,78 @@
import effectInit from '../../shared/effect-init.js';
import effectTarget from '../../shared/effect-target.js';
import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
export default function EffectFade({
swiper,
extendParams,
on
}) {
extendParams({
fadeEffect: {
crossFade: false,
transformEl: null
}
});
const setTranslate = () => {
const {
slides
} = swiper;
const params = swiper.params.fadeEffect;
for (let i = 0; i < slides.length; i += 1) {
const $slideEl = swiper.slides[i];
const offset = $slideEl.swiperSlideOffset;
let tx = -offset;
if (!swiper.params.virtualTranslate) tx -= swiper.translate;
let ty = 0;
if (!swiper.isHorizontal()) {
ty = tx;
tx = 0;
}
const slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs($slideEl.progress), 0) :
1 + Math.min(Math.max($slideEl.progress, -1), 0);
const $targetEl = effectTarget(params, $slideEl);
$targetEl.css({
opacity: slideOpacity
})
$targetEl.transform(`translate3d(${tx}px, ${ty}px, 0px)`);
if (swiper.params.willChange) {
$targetEl.willChange("opacity");
}
slides[i].addClass('swiper-slide-fade')
}
};
const setTransition = duration => {
const {
transformEl
} = swiper.params.fadeEffect;
const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
for (let i = 0; i < $transitionElements.length; i += 1) {
$transitionElements[i].transition(duration);
}
effectVirtualTransitionEnd({
swiper,
duration,
transformEl,
allSlides: true
});
};
effectInit({
effect: 'fade',
swiper,
on,
setTranslate,
setTransition,
overwriteParams: () => ({
slidesPerView: 1,
slidesPerGroup: 1,
watchSlidesProgress: true,
spaceBetween: 0,
virtualTranslate: !swiper.params.cssMode
})
});
}

View File

@@ -0,0 +1,11 @@
.swiper-slide-fade {
pointer-events: none;
transition-property: opacity;
.swiper-slide {
pointer-events: none;
}
}
.swiper-slide-fade.swiper-slide-active {
pointer-events: auto;
}

View File

@@ -0,0 +1,104 @@
import effectInit from '../../shared/effect-init.js';
import effectTarget from '../../shared/effect-target.js';
import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
export default function EffectFlip({
swiper,
extendParams,
on
}) {
extendParams({
flipEffect: {
slideShadows: true,
limitRotation: true,
transformEl: null,
},
});
const setTranslate = () => {
const {
slides,
rtlTranslate: rtl
} = swiper;
const params = swiper.params.flipEffect;
for (let i = 0; i < slides.length; i += 1) {
const $slideEl = slides[i];
let progress = $slideEl.progress;
if (swiper.params.flipEffect.limitRotation) {
progress = Math.max(Math.min($slideEl.progress, 1), -1);
}
const offset = $slideEl.swiperSlideOffset;
const rotate = -180 * progress;
let rotateY = rotate;
let rotateX = 0;
let tx = swiper.params.cssMode ? -offset - swiper.translate : -offset;
let ty = 0;
if (!swiper.isHorizontal()) {
ty = tx;
tx = 0;
rotateX = -rotateY;
rotateY = 0;
} else if (rtl) {
rotateY = -rotateY;
}
$slideEl.css({
zIndex: -Math.abs(Math.round(progress)) + slides.length
})
// if (params.slideShadows) {
// // Set shadows
// let shadowBefore = swiper.isHorizontal()
// ? $slideEl.find('.swiper-slide-shadow-left')
// : $slideEl.find('.swiper-slide-shadow-top');
// let shadowAfter = swiper.isHorizontal()
// ? $slideEl.find('.swiper-slide-shadow-right')
// : $slideEl.find('.swiper-slide-shadow-bottom');
// if (shadowBefore.length === 0) {
// shadowBefore = createShadow(params, $slideEl, swiper.isHorizontal() ? 'left' : 'top');
// }
// if (shadowAfter.length === 0) {
// shadowAfter = createShadow(params, $slideEl, swiper.isHorizontal() ? 'right' : 'bottom');
// }
// if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
// if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
// }
const transform = `translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
const $targetEl = effectTarget(params, $slideEl);
$targetEl.transform(transform);
if (swiper.params.willChange) {
$targetEl.willChange("transform");
}
slides[i].addClass('swiper-slide-flip')
}
};
const setTransition = (duration) => {
const {
transformEl
} = swiper.params.flipEffect;
const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
for (let i = 0; i < $transitionElements.length; i += 1) {
$transitionElements[i].transition(duration);
}
effectVirtualTransitionEnd({
swiper,
duration,
transformEl
});
};
effectInit({
effect: 'flip',
swiper,
on,
setTranslate,
setTransition,
perspective: () => true,
overwriteParams: () => ({
slidesPerView: 1,
slidesPerGroup: 1,
watchSlidesProgress: true,
spaceBetween: 0,
virtualTranslate: !swiper.params.cssMode,
}),
});
}

View File

@@ -0,0 +1,20 @@
.swiper-flip {
overflow: visible;
.swiper-slide-shadow-top,
.swiper-slide-shadow-bottom,
.swiper-slide-shadow-left,
.swiper-slide-shadow-right {
z-index: 0;
backface-visibility: hidden;
}
}
.swiper-slide-flip {
pointer-events: none;
backface-visibility: hidden;
z-index: 1;
transform-style: preserve-3d;
.swiper-slide {
pointer-events: none;
}
}

View File

@@ -0,0 +1,63 @@
export default function Panorama({
swiper,
extendParams,
on
}) {
extendParams({
panorama: {
depth: 200,
rotate: 30,
stretch: 1
},
});
on('beforeInit', () => {
if (swiper.params.effect !== 'panorama') return;
swiper.classNames.push(`${swiper.params.containerModifierClass}panorama`);
swiper.classNames.push(`${swiper.params.containerModifierClass}3d`);
const overwriteParams = {
watchSlidesProgress: true,
};
Object.assign(swiper.params, overwriteParams);
Object.assign(swiper.originalParams, overwriteParams);
});
on('progress', () => {
if (swiper.params.effect !== 'panorama') return;
const sizesGrid = swiper.slidesSizesGrid;
const {
depth = 200, rotate = 30, stretch = 1
} = swiper.params.panorama;
const angleRad = (rotate * Math.PI) / 180;
const halfAngleRad = angleRad / 2;
const angleModifier = 1 / (180 / rotate);
for (let i = 0; i < swiper.slides.length; i += 1) {
const slideEl = swiper.slides[i];
const slideProgress = slideEl.progress;
const slideSize = sizesGrid[i];
const progressModifier = swiper.params.centeredSlides ?
0 :
(swiper.params.slidesPerView - 1) * 0.5;
const modifiedProgress = slideProgress + progressModifier;
const angleCos = 1 - Math.cos(modifiedProgress * angleModifier * Math.PI);
const translateX = `${modifiedProgress * (stretch * slideSize / 3) * angleCos}px`;
const rotateY = modifiedProgress * rotate;
const radius = (slideSize * 0.5) / Math.sin(halfAngleRad);
const translateZ = `${radius * angleCos - depth}px`;
slideEl.transform(
`translateX(${translateX}) translateZ(${translateZ}) rotateY(${rotateY}deg)`);
if (swiper.params.willChange) {
slideEl.willChange("transform");
}
slideEl.addClass('swiper-slide-panorama')
}
});
on('setTransition', (s, duration) => {
if (swiper.params.effect !== 'panorama') return;
swiper.slides.forEach((slideEl) => {
slideEl.transition(duration);
});
});
}

View File

@@ -0,0 +1,3 @@
.swiper-panorama {
overflow: visible;
}

View File

@@ -0,0 +1,241 @@
import {
now
} from '../../shared/utils.js';
export default function freeMode({
swiper,
extendParams,
emit,
once
}) {
extendParams({
freeMode: {
enabled: false,
momentum: true,
momentumRatio: 1,
momentumBounce: true,
momentumBounceRatio: 1,
momentumVelocityRatio: 1,
sticky: false,
minimumVelocity: 0.02
}
});
function onTouchMove() {
const {
touchEventsData: data,
touches
} = swiper; // Velocity
if (data.velocities.length === 0) {
data.velocities.push({
position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],
time: data.touchStartTime
});
}
data.velocities.push({
position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],
time: now()
});
}
function onTouchEnd({
currentPos
}) {
const {
params,
$wrapperEl,
rtlTranslate: rtl,
snapGrid,
touchEventsData: data
} = swiper; // Time diff
const touchEndTime = now();
const timeDiff = touchEndTime - data.touchStartTime;
if (currentPos < -swiper.minTranslate()) {
swiper.slideTo(swiper.activeIndex);
return;
}
if (currentPos > -swiper.maxTranslate()) {
if (swiper.slides.length < snapGrid.length) {
swiper.slideTo(snapGrid.length - 1);
} else {
swiper.slideTo(swiper.slides.length - 1);
}
return;
}
if (params.freeMode.momentum) {
if (data.velocities.length > 1) {
const lastMoveEvent = data.velocities.pop();
const velocityEvent = data.velocities.pop();
const distance = lastMoveEvent.position - velocityEvent.position;
const time = lastMoveEvent.time - velocityEvent.time;
swiper.velocity = distance / time;
swiper.velocity /= 2;
if (Math.abs(swiper.velocity) < params.freeMode.minimumVelocity) {
swiper.velocity = 0;
} // this implies that the user stopped moving a finger then released.
// There would be no events with distance zero, so the last event is stale.
if (time > 150 || now() - lastMoveEvent.time > 300) {
swiper.velocity = 0;
}
} else {
swiper.velocity = 0;
}
swiper.velocity *= params.freeMode.momentumVelocityRatio;
data.velocities.length = 0;
let momentumDuration = 1000 * params.freeMode.momentumRatio;
const momentumDistance = swiper.velocity * momentumDuration;
let newPosition = swiper.translate + momentumDistance;
if (rtl) newPosition = -newPosition;
let doBounce = false;
let afterBouncePosition;
const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeMode.momentumBounceRatio;
let needsLoopFix;
if (newPosition < swiper.maxTranslate()) {
if (params.freeMode.momentumBounce) {
if (newPosition + swiper.maxTranslate() < -bounceAmount) {
newPosition = swiper.maxTranslate() - bounceAmount;
}
afterBouncePosition = swiper.maxTranslate();
doBounce = true;
data.allowMomentumBounce = true;
} else {
newPosition = swiper.maxTranslate();
}
if (params.loop && params.centeredSlides) needsLoopFix = true;
} else if (newPosition > swiper.minTranslate()) {
if (params.freeMode.momentumBounce) {
if (newPosition - swiper.minTranslate() > bounceAmount) {
newPosition = swiper.minTranslate() + bounceAmount;
}
afterBouncePosition = swiper.minTranslate();
doBounce = true;
data.allowMomentumBounce = true;
} else {
newPosition = swiper.minTranslate();
}
if (params.loop && params.centeredSlides) needsLoopFix = true;
} else if (params.freeMode.sticky) {
let nextSlide;
for (let j = 0; j < snapGrid.length; j += 1) {
if (snapGrid[j] > -newPosition) {
nextSlide = j;
break;
}
}
if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) ||
swiper.swipeDirection === 'next') {
newPosition = snapGrid[nextSlide];
} else {
newPosition = snapGrid[nextSlide - 1];
}
newPosition = -newPosition;
}
if (needsLoopFix) {
once('transitionEnd', () => {
swiper.loopFix();
});
} // Fix duration
if (swiper.velocity !== 0) {
if (rtl) {
momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);
} else {
momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);
}
if (params.freeMode.sticky) {
const moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate);
const currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex];
if (moveDistance < currentSlideSize) {
momentumDuration = params.speed;
} else if (moveDistance < 2 * currentSlideSize) {
momentumDuration = params.speed * 1.5;
} else {
momentumDuration = params.speed * 2.5;
}
}
} else if (params.freeMode.sticky) {
swiper.slideToClosest();
return;
}
if (params.freeMode.momentumBounce && doBounce) {
swiper.updateProgress(afterBouncePosition);
swiper.setTransition(momentumDuration);
swiper.setTranslate(newPosition);
swiper.transitionStart(true, swiper.swipeDirection);
swiper.animating = true;
$wrapperEl.transitionEnd(() => {
if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return;
emit('momentumBounce');
swiper.setTransition(params.speed);
setTimeout(() => {
swiper.setTranslate(afterBouncePosition);
$wrapperEl.transitionEnd(() => {
if (!swiper || swiper.destroyed) return;
swiper.transitionEnd();
}, momentumDuration);
}, 0);
}, momentumDuration);
} else if (swiper.velocity) {
emit('_freeModeNoMomentumRelease');
swiper.updateProgress(newPosition);
swiper.setTransition(momentumDuration);
swiper.setTranslate(newPosition);
swiper.transitionStart(true, swiper.swipeDirection);
if (!swiper.animating) {
swiper.animating = true;
$wrapperEl.transitionEnd(() => {
if (!swiper || swiper.destroyed) return;
swiper.transitionEnd();
}, momentumDuration);
}
} else {
swiper.updateProgress(newPosition);
}
swiper.updateActiveIndex();
swiper.updateSlidesClasses();
} else if (params.freeMode.sticky) {
swiper.slideToClosest();
return;
} else if (params.freeMode) {
emit('_freeModeNoMomentumRelease');
}
if (!params.freeMode.momentum || timeDiff >= params.longSwipesMs) {
swiper.updateProgress();
swiper.updateActiveIndex();
swiper.updateSlidesClasses();
}
}
Object.assign(swiper, {
freeMode: {
onTouchMove,
onTouchEnd
}
});
}

View File

@@ -0,0 +1,188 @@
export default function Navigation({
swiper,
extendParams,
on,
emit
}) {
extendParams({
navigation: {
nextEl: null,
prevEl: null,
hideOnClick: false,
disabledClass: 'swiper-button-disabled',
hiddenClass: 'swiper-button-hidden',
lockClass: 'swiper-button-lock',
},
});
swiper.navigation = {
nextEl: null,
$nextEl: null,
prevEl: null,
$prevEl: null,
};
function toggleEl($el, disabled) {
if (!swiper.$wrapperEl) return
// debugger
const params = swiper.params.navigation;
if ($el) {
swiper.$wrapperEl[disabled ? `add${$el}` : `remove${$el}`](params.disabledClass);
if (swiper.params.watchOverflow && swiper.enabled) {
swiper.$wrapperEl[swiper.isLocked ? `add${$el}` : `remove${$el}`](params.lockClass);
}
}
}
function update() {
// Update Navigation Buttons
if (swiper.params.loop) return;
const {
$nextEl,
$prevEl
} = swiper.navigation;
toggleEl('PrevElClass', swiper.isBeginning && !swiper.params.rewind);
toggleEl('NextElClass', swiper.isEnd && !swiper.params.rewind);
}
function onPrevClick(e) {
// e.preventDefault();
if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return;
swiper.slidePrev();
}
function onNextClick() {
// e.preventDefault();
if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return;
swiper.slideNext();
}
function init() {
const params = swiper.params.navigation;
if (params.slot || params.custom) {
params.nextEl = true;
params.prevEl = true;
}
if (!(params.nextEl || params.prevEl) && !params.slot && !params.custom) return;
if (params.slot) {
swiper.native.updateData({
showPrevButtonSlot: true,
showNextButtonSlot: true
})
} else if (params.custom) {} else {
swiper.native.updateData({
showPrevButton: true,
showNextButton: true
})
}
const $nextEl = params.nextEl;
const $prevEl = params.prevEl;
if ($nextEl) {
swiper.on('nextClick', onNextClick);
}
if ($prevEl) {
swiper.on('prevClick', onPrevClick);
}
Object.assign(swiper.navigation, {
$nextEl,
nextEl: $nextEl,
$prevEl,
prevEl: $prevEl,
});
if (!swiper.enabled) {
if ($nextEl) swiper.$wrapperEl.addNextElClass(params.lockClass);
if ($prevEl) swiper.$wrapperEl.addPrevElClass(params.lockClass);
}
}
function destroy() {
const {
$nextEl,
$prevEl
} = swiper.navigation;
if ($nextEl) {
swiper.off('nextClick', onNextClick);
swiper.$wrapperEl.removeNextElClass(swiper.params.navigation.disabledClass);
}
if ($prevEl) {
swiper.off('prevClick', onPrevClick);
swiper.$wrapperEl.removePrevElClass(swiper.params.navigation.disabledClass);
}
}
on('init', () => {
init();
update();
});
on('toEdge fromEdge lock unlock', () => {
update();
});
on('destroy', () => {
destroy();
});
on('enable disable', () => {
const {
$nextEl,
$prevEl
} = swiper.navigation;
if ($nextEl) {
swiper.$wrapperEl[swiper.enabled ? 'removeNextElClass' : 'addNextElClass'](swiper.params.navigation
.lockClass);
// $nextEl[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.navigation.lockClass);
}
if ($prevEl) {
swiper.$wrapperEl[swiper.enabled ? 'removePrevElClass' : 'addPrevElClass'](swiper.params.navigation
.lockClass);
// $prevEl[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.navigation.lockClass);
}
});
// on('click', (_s, e) => {
// const {
// $nextEl,
// $prevEl
// } = swiper.navigation;
// const targetEl = e.target;
// if (
// swiper.params.navigation.hideOnClick &&
// !$(targetEl).is($prevEl) &&
// !$(targetEl).is($nextEl)
// ) {
// if (
// swiper.pagination &&
// swiper.params.pagination &&
// swiper.params.pagination.clickable &&
// (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))
// )
// return;
// let isHidden;
// if ($nextEl) {
// isHidden = $nextEl.hasClass(swiper.params.navigation.hiddenClass);
// } else if ($prevEl) {
// isHidden = $prevEl.hasClass(swiper.params.navigation.hiddenClass);
// }
// if (isHidden === true) {
// emit('navigationShow');
// } else {
// emit('navigationHide');
// }
// if ($nextEl) {
// $nextEl.toggleClass(swiper.params.navigation.hiddenClass);
// }
// if ($prevEl) {
// $prevEl.toggleClass(swiper.params.navigation.hiddenClass);
// }
// }
// });
Object.assign(swiper.navigation, {
update,
init,
destroy,
});
}

View File

@@ -0,0 +1,49 @@
.swiper-button-prev,
.swiper-button-next {
position: absolute;
top: 50%;
// width: calc(80rpx / 44 * 27);
height: 80rpx;
margin-top: calc(0rpx - (80rpx / 2));
z-index: 10;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: #007aff;
font-size: 50rpx;
&.swiper-button-disabled {
opacity: 0.35;
cursor: auto;
pointer-events: none;
}
&:after {
font-family: swiper-icons;
font-size: 80rpx;
text-transform: none !important;
letter-spacing: 0;
text-transform: none;
font-variant: initial;
line-height: 1;
}
}
.swiper-button-prev,
.swiper-rtl .swiper-button-next {
// &:after {
// content: 'prev';
// }
left: 10px;
right: auto;
}
.swiper-button-next,
.swiper-rtl .swiper-button-prev {
// &:after {
// content: 'next';
// }
right: 10px;
left: auto;
}
.swiper-button-lock {
display: none;
}

View File

@@ -0,0 +1,510 @@
import classesToSelector from '../../shared/classes-to-selector.js';
export default function Pagination({
swiper,
extendParams,
on,
emit
}) {
const pfx = 'swiper-pagination';
extendParams({
pagination: {
el: null,
bulletElement: 'span',
clickable: false,
hideOnClick: false,
renderBullet: null,
renderProgressbar: null,
renderFraction: null,
renderCustom: null,
progressbarOpposite: false,
type: 'bullets', // 'bullets' or 'progressbar' or 'fraction' or 'custom'
dynamicBullets: false,
dynamicMainBullets: 1,
formatFractionCurrent: (number) => number,
formatFractionTotal: (number) => number,
bulletClass: `${pfx}-bullet`,
bulletActiveClass: `${pfx}-bullet-active`,
modifierClass: `${pfx}-`,
currentClass: `${pfx}-current`,
totalClass: `${pfx}-total`,
hiddenClass: `${pfx}-hidden`,
progressbarFillClass: `${pfx}-progressbar-fill`,
progressbarOppositeClass: `${pfx}-progressbar-opposite`,
clickableClass: `${pfx}-clickable`,
lockClass: `${pfx}-lock`,
horizontalClass: `${pfx}-horizontal`,
verticalClass: `${pfx}-vertical`,
},
});
swiper.pagination = {
el: null,
$el: null,
bullets: [],
};
let bulletSize;
let dynamicBulletIndex = 0;
function isPaginationDisabled() {
return (
!swiper.params.pagination.el ||
!swiper.pagination.el ||
!swiper.pagination.$el
);
}
function setSideBullets($bulletEl, position) {
const {
bulletActiveClass
} = swiper.params.pagination;
const bullets = swiper.pagination.bullets;
if (bullets[$bulletEl.index + position]) {
bullets[$bulletEl.index + position].addPaginationItemClass(
`${bulletActiveClass}-${position>0?'next':'prev'}`);
}
if (bullets[$bulletEl.index + (position > 0 ? position + 1 : position -
1)]) {
bullets[$bulletEl.index + (position > 0 ? position + 1 : position - 1)].addPaginationItemClass(
`${bulletActiveClass}-${position>0?'next':'prev'}-${position>0?'next':'prev'}`);
}
}
function update() {
// Render || Update Pagination bullets/items
const rtl = swiper.rtl;
const params = swiper.params.pagination;
if (isPaginationDisabled()) return;
const slidesLength =
swiper.virtual && swiper.params.virtual.enabled ?
swiper.virtual.slides.length :
swiper.slides.length;
const $el = swiper.pagination.$el;
// Current/Total
let current;
const total = swiper.params.loop ?
Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) :
swiper.snapGrid.length;
if (swiper.params.loop) {
current = Math.ceil(
(swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup,
);
if (current > slidesLength - 1 - swiper.loopedSlides * 2) {
current -= slidesLength - swiper.loopedSlides * 2;
}
if (current > total - 1) current -= total;
if (current < 0 && swiper.params.paginationType !== 'bullets') current = total + current;
} else if (typeof swiper.snapIndex !== 'undefined') {
current = swiper.snapIndex;
} else {
current = swiper.activeIndex || 0;
}
// Types
if (
params.type === 'bullets' &&
swiper.pagination.bullets &&
swiper.pagination.bullets.length > 0
) {
const bullets = swiper.pagination.bullets;
let firstIndex;
let lastIndex;
let midIndex;
if (params.dynamicBullets) {
bulletSize = bullets[0][swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'];
swiper.$wrapperEl.paginationCss({
[swiper.isHorizontal() ? 'width' :
'height'
]: `${bulletSize * (params.dynamicMainBullets + 4)}px`
});
if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) {
dynamicBulletIndex += current - (swiper.previousIndex - swiper.loopedSlides || 0);
if (dynamicBulletIndex > params.dynamicMainBullets - 1) {
dynamicBulletIndex = params.dynamicMainBullets - 1;
} else if (dynamicBulletIndex < 0) {
dynamicBulletIndex = 0;
}
}
firstIndex = Math.max(current - dynamicBulletIndex, 0);
lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);
midIndex = (lastIndex + firstIndex) / 2;
}
bullets.forEach((item) => {
item.removePaginationItemClass(
['', '-next', '-next-next', '-prev', '-prev-prev', '-main']
.map((suffix) => `${params.bulletActiveClass}${suffix}`)
.join(' '),
);
})
if ($el.length > 1) {
bullets.each((bullet) => {
const $bullet = $(bullet);
const bulletIndex = $bullet.index();
if (bulletIndex === current) {
$bullet.addClass(params.bulletActiveClass);
}
if (params.dynamicBullets) {
if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {
$bullet.addClass(`${params.bulletActiveClass}-main`);
}
if (bulletIndex === firstIndex) {
setSideBullets($bullet, 'prev');
}
if (bulletIndex === lastIndex) {
setSideBullets($bullet, 'next');
}
}
});
} else {
const $bullet = bullets[current];
const bulletIndex = $bullet.index;
$bullet.addPaginationItemClass(params.bulletActiveClass);
if (params.dynamicBullets) {
const $firstDisplayedBullet = bullets[firstIndex];
const $lastDisplayedBullet = bullets[lastIndex];
for (let i = firstIndex; i <= lastIndex; i += 1) {
bullets[i].addPaginationItemClass(`${params.bulletActiveClass}-main`);
}
if (swiper.params.loop) {
if (bulletIndex >= bullets.length) {
for (let i = params.dynamicMainBullets; i >= 0; i -= 1) {
bullets[bullets.length - i].addPaginationItemClass(`${params.bulletActiveClass}-main`);
}
bullets
[bullets.length - params.dynamicMainBullets - 1]
.addPaginationItemClass(`${params.bulletActiveClass}-prev`);
} else {
setSideBullets($firstDisplayedBullet, -1);
setSideBullets($lastDisplayedBullet, 1);
}
} else {
setSideBullets($firstDisplayedBullet, -1);
setSideBullets($lastDisplayedBullet, 1);
}
}
}
if (params.dynamicBullets) {
const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);
const bulletsOffset =
(bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize;
const offsetProp = rtl ? 'right' : 'left';
bullets.forEach((item) => {
item.setCss({
[swiper.isHorizontal() ? offsetProp : 'top']: `${bulletsOffset}px`
})
})
// bullets.css(swiper.isHorizontal() ? offsetProp : 'top', `${bulletsOffset}px`);
}
}
if (params.type === 'fraction') {
// $el
// .find(classesToSelector(params.currentClass))
// .text(params.formatFractionCurrent(current + 1));
swiper.native.paginationContent.text = params.formatFractionCurrent(current + 1);
swiper.native.paginationContent.total = params.formatFractionTotal(total);
swiper.native.updateData({
paginationContent: swiper.native.paginationContent,
})
// $el.find(classesToSelector(params.totalClass)).text(params.formatFractionTotal(total));
}
if (params.type === 'progressbar') {
let progressbarDirection;
if (params.progressbarOpposite) {
progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';
} else {
progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';
}
const scale = (current + 1) / total;
let scaleX = 1;
let scaleY = 1;
if (progressbarDirection === 'horizontal') {
scaleX = scale;
} else {
scaleY = scale;
}
// $el
// .find(classesToSelector(params.progressbarFillClass))
swiper.native.paginationContent.transform(`translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`);
swiper.native.paginationContent.transition(swiper.params.speed);
swiper.native.updateData({
paginationContent: swiper.native.paginationContent,
})
}
if (params.type === 'custom' && params.renderCustom) {
$el.html(params.renderCustom(swiper, current + 1, total));
emit('paginationRender', $el[0]);
} else {
emit('paginationUpdate', $el[0]);
}
if (swiper.params.watchOverflow && swiper.enabled) {
swiper.$wrapperEl[swiper.isLocked ? 'addPaginationClass' : 'removePaginationClass'](params.lockClass);
}
}
function render() {
// Render Container
const params = swiper.params.pagination;
if (isPaginationDisabled()) return;
const slidesLength =
swiper.virtual && swiper.params.virtual.enabled ?
swiper.virtual.slides.length :
swiper.slides.length;
const $el = swiper.pagination.$el;
let paginationHTML = 0;
if (params.type === 'bullets') {
let numberOfBullets = swiper.params.loop ?
Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) :
swiper.snapGrid.length;
if (
swiper.params.freeMode &&
swiper.params.freeMode.enabled &&
!swiper.params.loop &&
numberOfBullets > slidesLength
) {
numberOfBullets = slidesLength;
}
for (let i = 0; i < numberOfBullets; i += 1) {
if (params.renderBullet) {
paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);
}
// else {
// paginationHTML +=
// `<${params.bulletElement} class="${params.bulletClass}"></${params.bulletElement}>`;
// }
// paginationHTML += 1;
else {
swiper.native.paginationType = "bullets";
swiper.native.paginationContent.push({
index: i,
outerWidth: 16,
outerHeight: 16,
classContent: [params.bulletClass],
styleContent: {},
addPaginationItemClass: function(value) {
this.classContent = Array.from(new Set([...this.classContent,
...value.split(" ")
]));
},
removePaginationItemClass: function(value) {
this.classContent = this.classContent.filter(item => !value.split(
" ").includes(item));
},
setCss: function(value) {
// vueNative['itemStyle'] = {
// ...vueNative['itemStyle'],
// ...value
// };Object.keys(value).forEach((item) => {
Object.keys(value).forEach((item) => {
// this.$set(this.itemStyle, item, value[item])
this.styleContent[item] = value[item];
})
// this.$set(this.itemStyle, item, value[item])
}
});
swiper.native.updateData({
paginationType: swiper.native.paginationType,
paginationContent: swiper.native.paginationContent,
})
}
}
// $el.html(paginationHTML);
// swiper.$wrapperEl.addPaginationItemClass(params.bulletClass)
// swiper.pagination.bullets = $el.find(classesToSelector(params.bulletClass));
swiper.pagination.bullets = swiper.native.paginationContent;
}
if (params.type === 'fraction') {
if (params.renderFraction) {
paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);
} else {
swiper.native.paginationType = "fraction";
// paginationHTML =
// `<span class="${params.currentClass}"></span>` +
// ' / ' +
// `<span class="${params.totalClass}"></span>`;
swiper.native.paginationContent = {
currentClass: params.currentClass,
totalClass: params.totalClass
}
swiper.native.updateData({
paginationType: swiper.native.paginationType,
paginationContent: swiper.native.paginationContent,
})
}
}
if (params.type === 'progressbar') {
if (params.renderProgressbar) {
paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);
} else {
swiper.native.paginationType = "progressbar";
// paginationHTML = `<span class="${params.progressbarFillClass}"></span>`;
swiper.native.paginationContent = {
progressbarFillClass: params.progressbarFillClass,
styleContent: {
transform: '',
transitionDuration: ''
},
transition: function(value) {
this.styleContent.transitionDuration = `${value}ms`;
},
transform: function(value) {
this.styleContent.transform = value;
},
}
swiper.native.updateData({
paginationType: swiper.native.paginationType,
paginationContent: swiper.native.paginationContent,
})
}
// $el.html(paginationHTML);
}
if (params.type !== 'custom') {
emit('paginationRender', swiper.pagination.$el[0]);
}
}
function init() {
const params = swiper.params.pagination;
if (!params.el) return;
// swiper.native.showIndicators = true;
swiper.native.updateData({
showIndicators: true
})
let $el = params.el;
if (params.type === 'bullets' && params.clickable) {
swiper.$wrapperEl.addPaginationClass(params.clickableClass);
}
swiper.$wrapperEl.addPaginationClass(params.modifierClass + params.type);
swiper.$wrapperEl.addPaginationClass(params.modifierClass + swiper.params.direction);
if (params.type === 'bullets' && params.dynamicBullets) {
swiper.$wrapperEl.addPaginationClass(`${params.modifierClass}${params.type}-dynamic`);
dynamicBulletIndex = 0;
if (params.dynamicMainBullets < 1) {
params.dynamicMainBullets = 1;
}
}
if (params.type === 'progressbar' && params.progressbarOpposite) {
swiper.$wrapperEl.addPaginationClass(params.progressbarOppositeClass);
}
if (params.clickable) {
swiper.on('paginationItemClick', function onClick(_s, itemIndex) {
let index = itemIndex * swiper.params.slidesPerGroup;
if (swiper.params.loop) index += swiper.loopedSlides;
swiper.slideTo(index);
});
}
Object.assign(swiper.pagination, {
$el,
el: $el,
});
if (!swiper.enabled) {
swiper.$wrapperEl.addPaginationClass(params.lockClass);
}
}
function destroy() {
const params = swiper.params.pagination;
if (isPaginationDisabled()) return;
const $el = swiper.pagination.$el;
if (params.clickable) {
swiper.off('paginationItemClick', classesToSelector(params.bulletClass));
}
}
on('init update', () => {
if (swiper.native.paginationContent) {
swiper.native.updateData({
paginationContent: []
})
}
// swiper.native.paginationContent = [];
init();
render();
update();
});
on('activeIndexChange', () => {
if (swiper.params.loop) {
update();
} else if (typeof swiper.snapIndex === 'undefined') {
update();
}
});
on('snapIndexChange', () => {
if (!swiper.params.loop) {
update();
}
});
on('slidesLengthChange', () => {
if (swiper.params.loop) {
render();
update();
}
});
on('snapGridLengthChange', () => {
if (!swiper.params.loop) {
render();
update();
}
});
on('destroy', () => {
destroy();
});
on('enable disable', () => {
const {
$el
} = swiper.pagination;
if ($el) {
swiper.$wrapperEl[swiper.enabled ? 'removePaginationClass' : 'addPaginationClass'](swiper.params
.pagination.lockClass);
}
});
on('lock unlock', () => {
update();
});
on('click', (_s, e) => {
const targetEl = e.target;
const {
$el
} = swiper.pagination;
if (
swiper.params.pagination.el &&
swiper.params.pagination.hideOnClick &&
$el.length > 0 &&
!$(targetEl).hasClass(swiper.params.pagination.bulletClass)
) {
if (
swiper.navigation &&
((swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl) ||
(swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl))
)
return;
const isHidden = $el.hasClass(swiper.params.pagination.hiddenClass);
if (isHidden === true) {
emit('paginationShow');
} else {
emit('paginationHide');
}
$el.toggleClass(swiper.params.pagination.hiddenClass);
}
});
Object.assign(swiper.pagination, {
render,
update,
init,
destroy,
});
}

View File

@@ -0,0 +1,149 @@
.swiper-pagination {
position: absolute;
text-align: center;
transition: 300ms opacity;
transform: translate3d(0, 0, 0);
z-index: 10;
font-size: 24rpx;
&.swiper-pagination-hidden {
opacity: 0;
}
}
/* Common Styles */
.swiper-pagination-fraction,
.swiper-pagination-custom,
.swiper-horizontal > .swiper-pagination-bullets,
.swiper-pagination-bullets.swiper-pagination-horizontal {
bottom: 10px;
left: 0;
width: 100%;
}
/* Bullets */
.swiper-pagination-bullets-dynamic {
overflow: hidden;
font-size: 0;
.swiper-pagination-bullet {
transform: scale(0.33);
position: relative;
}
.swiper-pagination-bullet-active {
transform: scale(1);
}
.swiper-pagination-bullet-active-main {
transform: scale(1);
}
.swiper-pagination-bullet-active-prev {
transform: scale(0.66);
}
.swiper-pagination-bullet-active-prev-prev {
transform: scale(0.33);
}
.swiper-pagination-bullet-active-next {
transform: scale(0.66);
}
.swiper-pagination-bullet-active-next-next {
transform: scale(0.33);
}
}
.swiper-pagination-bullet {
width: var(--swiper-pagination-bullet-width, var(--swiper-pagination-bullet-size, 8px));
height: var(--swiper-pagination-bullet-height, var(--swiper-pagination-bullet-size, 8px));
display: inline-block;
border-radius: 50%;
background: var(--swiper-pagination-bullet-inactive-color, #000);
opacity: var(--swiper-pagination-bullet-inactive-opacity, 0.2);
// @at-root button#{&} {
// border: none;
// margin: 0;
// padding: 0;
// box-shadow: none;
// appearance: none;
// }
.swiper-pagination-clickable & {
cursor: pointer;
}
&:only-child {
display: none !important;
}
}
.swiper-pagination-bullet-active {
opacity: var(--swiper-pagination-bullet-opacity, 1);
background: var(--swiper-pagination-color, #007aff);
}
.swiper-vertical > .swiper-pagination-bullets,
.swiper-pagination-vertical.swiper-pagination-bullets {
right: 10px;
top: 50%;
transform: translate3d(0px, -50%, 0);
.swiper-pagination-bullet {
margin: var(--swiper-pagination-bullet-vertical-gap, 6px) 0;
display: block;
}
&.swiper-pagination-bullets-dynamic {
top: 50%;
transform: translateY(-50%);
width: 8px;
.swiper-pagination-bullet {
display: inline-block;
transition: 200ms transform, 200ms top;
}
}
}
.swiper-horizontal > .swiper-pagination-bullets,
.swiper-pagination-horizontal.swiper-pagination-bullets {
.swiper-pagination-bullet {
margin: 0 var(--swiper-pagination-bullet-horizontal-gap, 4px);
}
&.swiper-pagination-bullets-dynamic {
left: 50%;
transform: translateX(-50%);
white-space: nowrap;
.swiper-pagination-bullet {
transition: 200ms transform, 200ms left;
}
}
}
.swiper-horizontal.swiper-rtl > .swiper-pagination-bullets-dynamic .swiper-pagination-bullet {
transition: 200ms transform, 200ms right;
}
/* Progress */
.swiper-pagination-progressbar {
background: rgba(0, 0, 0, 0.25);
position: absolute;
.swiper-pagination-progressbar-fill {
background: var(--swiper-pagination-color, #007aff);
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
transform: scale(0);
transform-origin: left top;
}
.swiper-rtl & .swiper-pagination-progressbar-fill {
transform-origin: right top;
}
.swiper-horizontal > &,
&.swiper-pagination-horizontal,
.swiper-vertical > &.swiper-pagination-progressbar-opposite,
&.swiper-pagination-vertical.swiper-pagination-progressbar-opposite {
width: 100%;
height: 4px;
left: 0;
top: 0;
}
.swiper-vertical > &,
&.swiper-pagination-vertical,
.swiper-horizontal > &.swiper-pagination-progressbar-opposite,
&.swiper-pagination-horizontal.swiper-pagination-progressbar-opposite {
width: 4px;
height: 100%;
left: 0;
top: 0;
}
}
.swiper-pagination-lock {
display: none;
}

View File

@@ -0,0 +1,390 @@
import {
nextTick
} from '../../shared/utils.js';
export default function Scrollbar({
swiper,
extendParams,
on,
emit
}) {
let isTouched = false;
let timeout = null;
let dragTimeout = null;
let dragStartPos;
let dragSize;
let trackSize;
let divider;
extendParams({
scrollbar: {
el: null,
dragSize: 'auto',
hide: false,
draggable: false,
snapOnRelease: true,
lockClass: 'swiper-scrollbar-lock',
dragClass: 'swiper-scrollbar-drag',
},
});
swiper.scrollbar = {
el: null,
dragEl: null,
$el: null,
$dragEl: null,
};
function setTranslate() {
if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
const {
scrollbar,
rtlTranslate: rtl,
progress
} = swiper;
const params = swiper.params.scrollbar;
let newSize = dragSize;
let newPos = (trackSize - dragSize) * progress;
if (rtl) {
newPos = -newPos;
if (newPos > 0) {
newSize = dragSize - newPos;
newPos = 0;
} else if (-newPos + dragSize > trackSize) {
newSize = trackSize + newPos;
}
} else if (newPos < 0) {
newSize = dragSize + newPos;
newPos = 0;
} else if (newPos + dragSize > trackSize) {
newSize = trackSize - newPos;
}
if (swiper.isHorizontal()) {
swiper.$wrapperEl.scrollbarItemTransform(`translate3d(${newPos}px, 0, 0)`);
swiper.$wrapperEl.scrollbarItemCss({
width: `${newSize}px`
})
} else {
swiper.$wrapperEl.scrollbarItemTransform(`translate3d(0px, ${newPos}px, 0)`);
swiper.$wrapperEl.scrollbarItemCss({
height: `${newSize}px`
})
}
if (params.hide) {
clearTimeout(timeout);
swiper.$wrapperEl.scrollbarCss({
opacity: 1
})
timeout = setTimeout(() => {
swiper.$wrapperEl.scrollbarCss({
opacity: 0
})
swiper.$wrapperEl.scrollbarTransition(400)
}, 1000);
}
}
function setTransition(duration) {
if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
swiper.$wrapperEl.scrollbarItemTransition(duration);
}
async function updateSize() {
if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
const {
scrollbar
} = swiper;
const {
$el,
methods
} = scrollbar;
swiper.$wrapperEl.scrollbarItemCss({
width: '',
height: ''
})
let rectInfo = await swiper.native.getRectScrollbar();
methods.offset = function() {
return rectInfo;
}
trackSize = swiper.isHorizontal() ? rectInfo.width : rectInfo.height;
divider =
swiper.size /
(swiper.virtualSize +
swiper.params.slidesOffsetBefore -
(swiper.params.centeredSlides ? swiper.snapGrid[0] : 0));
if (swiper.params.scrollbar.dragSize === 'auto') {
dragSize = trackSize * divider;
} else {
dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);
}
if (swiper.isHorizontal()) {
swiper.$wrapperEl.scrollbarItemCss({
width: `${dragSize}px`
})
} else {
swiper.$wrapperEl.scrollbarItemCss({
height: `${dragSize}px`
})
}
if (divider >= 1) {
swiper.$wrapperEl.scrollbarCss({
display: 'none'
})
} else {
swiper.$wrapperEl.scrollbarCss({
display: ''
})
}
if (swiper.params.scrollbar.hide) {
swiper.$wrapperEl.scrollbarCss({
opacity: 0
})
}
if (swiper.params.watchOverflow && swiper.enabled) {
swiper.$wrapperEl[swiper.isLocked ? 'addScrollbarClass' : 'removeScrollbarClass'](
swiper.params.scrollbar.lockClass,
);
}
}
function getPointerPosition(e) {
if (swiper.isHorizontal()) {
return e.type === 'touchstart' || e.type === 'touchmove' || 'touchStart' || e.type === 'touchMove' ?
e.touches[0].clientX :
e.clientX;
}
return e.type === 'touchstart' || e.type === 'touchmove' ?
e.touches[0].clientY :
e.clientY;
}
function setDragPosition(e) {
const {
scrollbar,
rtlTranslate: rtl
} = swiper;
const {
$el,
methods
} = scrollbar;
let positionRatio;
positionRatio =
(getPointerPosition(e) -
methods.offset()[swiper.isHorizontal() ? 'left' : 'top'] -
(dragStartPos !== null ? dragStartPos : dragSize / 2)) /
(trackSize - dragSize);
positionRatio = Math.max(Math.min(positionRatio, 1), 0);
if (rtl) {
positionRatio = 1 - positionRatio;
}
const position =
swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio;
swiper.updateProgress(position);
swiper.setTranslate(position);
swiper.updateActiveIndex();
swiper.updateSlidesClasses();
}
function onDragStart(_s, e) {
const params = swiper.params.scrollbar;
const {
scrollbar,
$wrapperEl
} = swiper;
isTouched = true;
dragStartPos =
// e.target ===
// $dragEl[0] || e.target === $dragEl ?
// getPointerPosition(e) -
// e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] :
null;
// e.preventDefault();
// e.stopPropagation();
$wrapperEl.transition(100);
swiper.$wrapperEl.scrollbarItemTransition(100)
// $dragEl.transition(100);
setDragPosition(e);
clearTimeout(dragTimeout);
swiper.$wrapperEl.scrollbarTransition(0)
if (params.hide) {
swiper.$wrapperEl.scrollbarCss({
opacity: 1
})
}
if (swiper.params.cssMode) {
swiper.$wrapperEl.css({
'scroll-snap-type': 'none'
});
}
emit('scrollbarDragStart', e);
}
function onDragMove(_s, e) {
const {
scrollbar,
$wrapperEl
} = swiper;
if (!isTouched) return;
setDragPosition(e);
$wrapperEl.transition(0);
swiper.$wrapperEl.scrollbarTransition(0)
swiper.$wrapperEl.scrollbarItemTransition(0)
emit('scrollbarDragMove', e);
}
function onDragEnd(_s, e) {
const params = swiper.params.scrollbar;
const {
scrollbar,
$wrapperEl
} = swiper;
const {
$el
} = scrollbar;
if (!isTouched) return;
isTouched = false;
if (swiper.params.cssMode) {
swiper.$wrapperEl.css({
'scroll-snap-type': ''
});
$wrapperEl.transition('');
}
if (params.hide) {
clearTimeout(dragTimeout);
dragTimeout = nextTick(() => {
swiper.$wrapperEl.scrollbarCss({
opacity: 0
})
swiper.$wrapperEl.scrollbarTransition(400)
}, 1000);
}
emit('scrollbarDragEnd', e);
if (params.snapOnRelease) {
swiper.slideToClosest();
}
}
function events(method) {
const {
scrollbar,
touchEventsTouch,
touchEventsDesktop,
params,
support
} = swiper;
const $el = scrollbar.$el;
const target = $el;
const activeListener =
support.passiveListener && params.passiveListeners ? {
passive: false,
capture: false
} :
false;
const passiveListener =
support.passiveListener && params.passiveListeners ? {
passive: true,
capture: false
} :
false;
if (!target) return;
const eventMethod = method === 'on' ? 'on' : 'off';
if (!support.touch) {
swiper[eventMethod]('touchStartScrollbar', onDragStart, activeListener);
swiper[eventMethod]('touchMoveScrollbar', onDragMove, activeListener);
swiper[eventMethod]('touchEndScrollbar', onDragEnd, passiveListener);
} else {
swiper[eventMethod]('touchStartScrollbar', onDragStart, activeListener);
swiper[eventMethod]('touchMoveScrollbar', onDragMove, activeListener);
swiper[eventMethod]('touchEndScrollbar', onDragEnd, passiveListener);
}
}
function enableDraggable() {
if (!swiper.params.scrollbar.el) return;
events('on');
}
function disableDraggable() {
if (!swiper.params.scrollbar.el) return;
events('off');
}
function init() {
const {
scrollbar,
} = swiper;
const params = swiper.params.scrollbar;
if (!params.el) return;
// swiper.native.updateData({
// scrollbarShow: true
// })
let $el = params.el;
Object.assign(scrollbar, {
$el,
el: $el,
methods: {}
});
if (params.draggable) {
enableDraggable();
}
swiper.$wrapperEl[swiper.enabled ? 'removeScrollbarClass' : 'addScrollbarClass'](swiper.params.scrollbar
.lockClass);
return true;
}
function destroy() {
disableDraggable();
}
on('init', async () => {
await init();
updateSize();
setTranslate();
});
on('update resize observerUpdate lock unlock', () => {
updateSize();
});
on('setTranslate', () => {
setTranslate();
});
on('setTransition', (_s, duration) => {
setTransition(duration);
});
on('enable disable', () => {
const {
$el
} = swiper.scrollbar;
if ($el) {
$el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.scrollbar.lockClass);
}
});
on('destroy', () => {
destroy();
});
Object.assign(swiper.scrollbar, {
updateSize,
setTranslate,
init,
destroy,
});
}

View File

@@ -0,0 +1,38 @@
/* Scrollbar */
.swiper-scrollbar {
border-radius: 10px;
position: relative;
-ms-touch-action: none;
background: rgba(0, 0, 0, 0.1);
.swiper-horizontal > & {
position: absolute;
left: 1%;
bottom: 3px;
z-index: 50;
height: 5px;
width: 98%;
}
.swiper-vertical > & {
position: absolute;
right: 3px;
top: 1%;
z-index: 50;
width: 5px;
height: 98%;
}
}
.swiper-scrollbar-drag {
height: 100%;
width: 100%;
position: relative;
background: rgba(0, 0, 0, 0.5);
border-radius: 10px;
left: 0;
top: 0;
}
.swiper-scrollbar-cursor-drag {
cursor: move;
}
.swiper-scrollbar-lock {
display: none;
}

View File

@@ -0,0 +1,240 @@
import {
isObject
} from '../../shared/utils.js';
// import $ from '../../shared/dom.js';
export default function Thumb({
swiper,
extendParams,
on
}) {
extendParams({
thumbs: {
swiper: null,
multipleActiveThumbs: true,
autoScrollOffset: 0,
slideThumbActiveClass: 'swiper-slide-thumb-active',
thumbsContainerClass: 'swiper-thumbs',
},
});
let initialized = false;
let swiperCreated = false;
swiper.thumbs = {
swiper: null,
};
function onThumbClick() {
const thumbsSwiper = swiper.thumbs.swiper;
if (!thumbsSwiper) return;
const clickedIndex = thumbsSwiper.clickedIndex;
const clickedSlide = thumbsSwiper.clickedSlide;
if (clickedSlide && clickedSlide.hasClass(swiper.params.thumbs.slideThumbActiveClass))
return;
if (typeof clickedIndex === 'undefined' || clickedIndex === null) return;
let slideToIndex;
if (thumbsSwiper.params.loop) {
slideToIndex = parseInt($(thumbsSwiper.clickedSlide).attr('data-swiper-slide-index'), 10);
} else {
slideToIndex = clickedIndex;
}
if (swiper.params.loop) {
let currentIndex = swiper.activeIndex;
if (swiper.slides.eq(currentIndex).hasClass(swiper.params.slideDuplicateClass)) {
swiper.loopFix();
// eslint-disable-next-line
swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
currentIndex = swiper.activeIndex;
}
const prevIndex = swiper.slides
.eq(currentIndex)
.prevAll(`[data-swiper-slide-index="${slideToIndex}"]`)
.eq(0)
.index();
const nextIndex = swiper.slides
.eq(currentIndex)
.nextAll(`[data-swiper-slide-index="${slideToIndex}"]`)
.eq(0)
.index();
if (typeof prevIndex === 'undefined') slideToIndex = nextIndex;
else if (typeof nextIndex === 'undefined') slideToIndex = prevIndex;
else if (nextIndex - currentIndex < currentIndex - prevIndex) slideToIndex = nextIndex;
else slideToIndex = prevIndex;
}
swiper.slideTo(slideToIndex);
}
function init() {
const {
thumbs: thumbsParams
} = swiper.params;
if (initialized) return false;
initialized = true;
const SwiperClass = swiper.constructor;
if (thumbsParams.swiper instanceof SwiperClass) {
swiper.thumbs.swiper = thumbsParams.swiper;
Object.assign(swiper.thumbs.swiper.originalParams, {
watchSlidesProgress: true,
slideToClickedSlide: false,
});
Object.assign(swiper.thumbs.swiper.params, {
watchSlidesProgress: true,
slideToClickedSlide: false,
});
} else if (isObject(thumbsParams.swiper)) {
const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper);
Object.assign(thumbsSwiperParams, {
watchSlidesProgress: true,
slideToClickedSlide: false,
});
swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams);
swiperCreated = true;
}
swiper.thumbs.swiper.$el && swiper.thumbs.swiper.$el.addClass(swiper.params.thumbs.thumbsContainerClass);
swiper.thumbs.swiper.on('slideClick', onThumbClick);
return true;
}
function update(initial) {
const thumbsSwiper = swiper.thumbs.swiper;
if (!thumbsSwiper) return;
const slidesPerView =
thumbsSwiper.params.slidesPerView === 'auto' ?
thumbsSwiper.slidesPerViewDynamic() :
thumbsSwiper.params.slidesPerView;
const autoScrollOffset = swiper.params.thumbs.autoScrollOffset;
const useOffset = autoScrollOffset && !thumbsSwiper.params.loop;
if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {
let currentThumbsIndex = thumbsSwiper.activeIndex;
let newThumbsIndex;
let direction;
if (thumbsSwiper.params.loop) {
if (
thumbsSwiper.slides
.eq(currentThumbsIndex)
.hasClass(thumbsSwiper.params.slideDuplicateClass)
) {
thumbsSwiper.loopFix();
// eslint-disable-next-line
thumbsSwiper._clientLeft = thumbsSwiper.$wrapperEl[0].clientLeft;
currentThumbsIndex = thumbsSwiper.activeIndex;
}
// Find actual thumbs index to slide to
const prevThumbsIndex = thumbsSwiper.slides
.eq(currentThumbsIndex)
.prevAll(`[data-swiper-slide-index="${swiper.realIndex}"]`)
.eq(0)
.index();
const nextThumbsIndex = thumbsSwiper.slides
.eq(currentThumbsIndex)
.nextAll(`[data-swiper-slide-index="${swiper.realIndex}"]`)
.eq(0)
.index();
if (typeof prevThumbsIndex === 'undefined') {
newThumbsIndex = nextThumbsIndex;
} else if (typeof nextThumbsIndex === 'undefined') {
newThumbsIndex = prevThumbsIndex;
} else if (nextThumbsIndex - currentThumbsIndex === currentThumbsIndex - prevThumbsIndex) {
newThumbsIndex =
thumbsSwiper.params.slidesPerGroup > 1 ? nextThumbsIndex : currentThumbsIndex;
} else if (nextThumbsIndex - currentThumbsIndex < currentThumbsIndex - prevThumbsIndex) {
newThumbsIndex = nextThumbsIndex;
} else {
newThumbsIndex = prevThumbsIndex;
}
direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';
} else {
newThumbsIndex = swiper.realIndex;
direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';
}
if (useOffset) {
newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;
}
if (
thumbsSwiper.visibleSlidesIndexes &&
thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0
) {
if (thumbsSwiper.params.centeredSlides) {
if (newThumbsIndex > currentThumbsIndex) {
newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;
} else {
newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;
}
} else if (
newThumbsIndex > currentThumbsIndex &&
thumbsSwiper.params.slidesPerGroup === 1
) {
// newThumbsIndex = newThumbsIndex - slidesPerView + 1;
}
thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);
}
}
// Activate thumbs
let thumbsToActivate = 1;
const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;
if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {
thumbsToActivate = swiper.params.slidesPerView;
}
if (!swiper.params.thumbs.multipleActiveThumbs) {
thumbsToActivate = 1;
}
thumbsToActivate = Math.floor(thumbsToActivate);
// thumbsSwiper.slides.removeClass(thumbActiveClass);
thumbsSwiper.slides.forEach((item) => {
item.addClass(swiper.params.slideThumbsClass);
item.removeClass(thumbActiveClass);
})
if (
thumbsSwiper.params.loop ||
(thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled)
) {
for (let i = 0; i < thumbsToActivate; i += 1) {
thumbsSwiper.$wrapperEl
.children(`[data-swiper-slide-index="${swiper.realIndex + i}"]`)
.addClass(thumbActiveClass);
}
} else {
for (let i = 0; i < thumbsToActivate; i += 1) {
thumbsSwiper.slides[swiper.realIndex + i].addClass(thumbActiveClass);
}
}
}
on('beforeInit', () => {
const {
thumbs
} = swiper.params;
if (!thumbs || !thumbs.swiper) return;
init();
update(true);
});
on('slideChange update resize observerUpdate', () => {
if (!swiper.thumbs.swiper) return;
update();
});
on('setTransition', (_s, duration) => {
const thumbsSwiper = swiper.thumbs.swiper;
if (!thumbsSwiper) return;
thumbsSwiper.setTransition(duration);
});
on('beforeDestroy', () => {
const thumbsSwiper = swiper.thumbs.swiper;
if (!thumbsSwiper) return;
if (swiperCreated && thumbsSwiper) {
thumbsSwiper.destroy();
}
});
Object.assign(swiper.thumbs, {
init,
update,
});
}

View File

@@ -0,0 +1,10 @@
.swiper-thumbs {
}
.swiper-slide-thumb {
opacity: 0.4;
}
.swiper-slide-thumb-active {
// Styles for active thumb slide
opacity: 1;
}

View File

@@ -0,0 +1,318 @@
export default function Virtual({
swiper,
extendParams,
on
}) {
extendParams({
virtual: {
enabled: false,
slides: [],
cache: true,
renderSlide: null,
renderExternal: null,
renderExternalUpdate: true,
addSlidesBefore: 0,
addSlidesAfter: 0,
},
});
let cssModeTimeout;
swiper.virtual = {
cache: {},
from: undefined,
to: undefined,
slides: [],
offset: 0,
slidesGrid: [],
};
function renderSlide(slide, index) {
const params = swiper.params.virtual;
if (params.cache && swiper.virtual.cache[index]) {
return swiper.virtual.cache[index];
}
// const $slideEl = params.renderSlide ?
// $(params.renderSlide.call(swiper, slide, index)) :
// $(
// `<div class="${swiper.params.slideClass}" data-swiper-slide-index="${index}">${slide}</div>`,
// );
// if (!$slideEl.attr('data-swiper-slide-index')) $slideEl.attr('data-swiper-slide-index', index);
// if (params.cache) swiper.virtual.cache[index] = $slideEl;
// return $slideEl;
}
function onRendered() {
swiper.updateSlides();
swiper.updateProgress();
swiper.updateSlidesClasses();
if (swiper.lazy && swiper.params.lazy.enabled) {
swiper.lazy.load();
}
}
async function update(force) {
const {
slidesPerView,
slidesPerGroup,
centeredSlides
} = swiper.params;
const {
addSlidesBefore,
addSlidesAfter
} = swiper.params.virtual;
const {
from: previousFrom,
to: previousTo,
slides,
slidesGrid: previousSlidesGrid,
offset: previousOffset,
} = swiper.virtual;
if (!swiper.params.cssMode) {
swiper.updateActiveIndex();
}
const activeIndex = swiper.activeIndex || 0;
let offsetProp;
if (swiper.rtlTranslate) offsetProp = 'right';
else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
let slidesAfter;
let slidesBefore;
if (centeredSlides) {
slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter;
slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore;
} else {
slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter;
slidesBefore = slidesPerGroup + addSlidesBefore;
}
const from = Math.max((activeIndex || 0) - slidesBefore, 0);
const to = Math.min((activeIndex || 0) + slidesAfter, slides.length - 1);
const offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);
Object.assign(swiper.virtual, {
from,
to,
offset,
slidesGrid: swiper.slidesGrid,
});
function onRendered() {
swiper.updateSlides();
swiper.updateProgress();
swiper.updateSlidesClasses();
if (swiper.lazy && swiper.params.lazy.enabled) {
swiper.lazy.load();
}
}
if (previousFrom === from && previousTo === to && !force) {
if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {
swiper.slides.css(offsetProp, `${offset}px`);
}
swiper.updateProgress();
return;
}
if (swiper.params.virtual.renderExternal) {
swiper.params.virtual.renderExternal.call(swiper, {
offset,
from,
to,
slides: (function getSlides() {
const slidesToRender = [];
if (swiper.params.virtual.type == 'keep') {
for (let i = 0; i < from; i += 1) {
slidesToRender.push("");
}
}
for (let i = from; i <= to; i += 1) {
slidesToRender.push(slides[i]);
}
return slidesToRender;
})(),
});
if (swiper.params.virtual.renderExternalUpdate) {
onRendered();
}
return;
}
const prependIndexes = [];
const appendIndexes = [];
if (force) {
swiper.$wrapperEl.find(`.${swiper.params.slideClass}`).remove();
} else {
for (let i = previousFrom; i <= previousTo; i += 1) {
if (i < from || i > to) {
swiper.virtualList.splice(swiper.virtualList.findIndex((item) => {
return item == slides[i]
}), 1)
swiper.virtualIndexList.splice(swiper.virtualIndexList.findIndex((item) => {
return item == i
}), 1)
// swiper.slides[i].virtualShow = false;
}
}
}
for (let i = 0; i < slides.length; i += 1) {
if (i >= from && i <= to) {
if (typeof previousTo === 'undefined' || force) {
appendIndexes.push(i);
} else {
if (i > previousTo) appendIndexes.push(i);
if (i < previousFrom) prependIndexes.push(i);
}
}
}
// let list = [];
appendIndexes.forEach((index) => {
// if (swiper.slides[index]) {
// swiper.slides[index].virtualShow = true;
// } else {
swiper.virtualList.push(slides[index]);
swiper.virtualIndexList.push(index)
// }
// renderSlide(slides[index], index)
// renderSlide(slides[index], index)
// swiper.$wrapperEl.append(renderSlide(slides[index], index));
});
prependIndexes
.sort((a, b) => b - a)
.forEach((index) => {
// swiper.slides[index].virtualShow = true;
swiper.virtualList.unshift(slides[index]);
swiper.virtualIndexList.unshift(index)
// swiper.$wrapperEl.prepend(renderSlide(slides[index], index));
});
swiper.native.emit("input", [swiper.virtualList])
onRendered();
}
function appendSlide(slides) {
if (typeof slides === 'object' && 'length' in slides) {
for (let i = 0; i < slides.length; i += 1) {
if (slides[i]) swiper.virtual.slides.push(slides[i]);
}
} else {
swiper.virtual.slides.push(slides);
}
update(true);
}
function prependSlide(slides) {
const activeIndex = swiper.activeIndex;
let newActiveIndex = activeIndex + 1;
let numberOfNewSlides = 1;
if (Array.isArray(slides)) {
for (let i = 0; i < slides.length; i += 1) {
if (slides[i]) swiper.virtual.slides.unshift(slides[i]);
}
newActiveIndex = activeIndex + slides.length;
numberOfNewSlides = slides.length;
} else {
swiper.virtual.slides.unshift(slides);
}
if (swiper.params.virtual.cache) {
const cache = swiper.virtual.cache;
const newCache = {};
Object.keys(cache).forEach((cachedIndex) => {
const $cachedEl = cache[cachedIndex];
const cachedElIndex = $cachedEl.attr('data-swiper-slide-index');
if (cachedElIndex) {
$cachedEl.attr(
'data-swiper-slide-index',
parseInt(cachedElIndex, 10) + numberOfNewSlides,
);
}
newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = $cachedEl;
});
swiper.virtual.cache = newCache;
}
update(true);
swiper.slideTo(newActiveIndex, 0);
}
function removeSlide(slidesIndexes) {
if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;
let activeIndex = swiper.activeIndex;
if (Array.isArray(slidesIndexes)) {
for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) {
swiper.virtual.slides.splice(slidesIndexes[i], 1);
if (swiper.params.virtual.cache) {
delete swiper.virtual.cache[slidesIndexes[i]];
}
if (slidesIndexes[i] < activeIndex) activeIndex -= 1;
activeIndex = Math.max(activeIndex, 0);
}
} else {
swiper.virtual.slides.splice(slidesIndexes, 1);
if (swiper.params.virtual.cache) {
delete swiper.virtual.cache[slidesIndexes];
}
if (slidesIndexes < activeIndex) activeIndex -= 1;
activeIndex = Math.max(activeIndex, 0);
}
update(true);
swiper.slideTo(activeIndex, 0);
}
function removeAllSlides() {
swiper.virtual.slides = [];
if (swiper.params.virtual.cache) {
swiper.virtual.cache = {};
}
update(true);
swiper.slideTo(0, 0);
}
on('beforeInit', () => {
if (!swiper.params.virtual.enabled) return;
swiper.virtual.slides = swiper.params.virtual.slides;
swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);
swiper.params.watchSlidesProgress = true;
swiper.originalParams.watchSlidesProgress = true;
if (!swiper.params.initialSlide) {
update();
}
});
// on('beforeUpdate', () => {
// if (!swiper.params.virtual.enabled) return;
// let offsetProp;
// if (swiper.rtlTranslate) offsetProp = 'right';
// else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
// swiper.slides.forEach((item, index) => {
// item.dataSwiperSlideIndex = swiper.virtualIndexList[index];
// item.css({
// [offsetProp]: `${swiper.virtual.offset}px`
// })
// })
// })
on('setTranslate', async () => {
if (!swiper.params.virtual.enabled) return;
if (swiper.params.cssMode && !swiper._immediateVirtual) {
clearTimeout(cssModeTimeout);
cssModeTimeout = setTimeout(() => {
update();
}, 100);
} else {
clearTimeout(cssModeTimeout);
cssModeTimeout = setTimeout(() => {
update();
}, 100);
// update();
}
});
Object.assign(swiper.virtual, {
appendSlide,
prependSlide,
removeSlide,
removeAllSlides,
update,
});
}

View File

@@ -0,0 +1,17 @@
.swiper-virtual.swiper-css-mode {
.swiper-wrapper::after {
content: '';
position: absolute;
left: 0;
top: 0;
pointer-events: none;
}
&.swiper-horizontal .swiper-wrapper::after {
height: 1px;
width: var(--swiper-virtual-size);
}
&.swiper-vertical .swiper-wrapper::after {
width: 1px;
height: var(--swiper-virtual-size);
}
}

View File

@@ -0,0 +1,20 @@
export default function WillChange({
swiper,
extendParams,
on
}) {
on('setTransition', (s, duration) => {
if (!swiper.params.willChange) return;
if (swiper.params.effect == "slide" || swiper.params.effect == "cube" || swiper.params.effect ==
"coverflow" || swiper.params.effect == "panorama") {
swiper.$wrapperEl.willChange("transform");
}
});
on('transitionEnd', (s, duration) => {
if (!swiper.params.willChange) return;
swiper.$wrapperEl.willChange("auto");
swiper.slides.forEach((item) => {
item.$itemEl.willChange("auto");
})
});
}