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, }), }); }