PageSourceSearch

https://expert-park.su/local/templates/ro_expertpark/assets/js-standalone/helpers/swiper-helpers.js

js expert-park.su collected 2026-10-07 18:03:16 UTC 5,917 bytes, 261 lines download raw bytes

1const MIN_SLIDES_TARGET = 7
2
3const hasManySlides = (slider) => slider.getElementsByClassName('swiper-slide').length >= 2
4
5const slidesCount = (slider) => slider.getElementsByClassName('swiper-slide').length
6
7const getCreativeLoopCopies = (
8  baseSlides,
9  _limitProgress,
10  minSlidesTarget = MIN_SLIDES_TARGET
11) => {
12  if (baseSlides >= minSlidesTarget) {
13    return 0
14  }
15
16  const slidesToAdd = minSlidesTarget - baseSlides
17
18  return slidesToAdd
19}
20
21const addExtraClasses = (swiper) => {
22  const activeIndex = swiper.activeIndex
23
24  swiper.slides.forEach((slide, index) => {
25    slide.classList.remove('swiper-slide-pre-next', 'swiper-slide-pre-prev')
26    if (index === activeIndex + 2) slide.classList.add('swiper-slide-pre-next')
27    if (index === activeIndex - 2) slide.classList.add('swiper-slide-pre-prev')
28  })
29}
30
31const cloneSlidesForLoop = (swiperEl, limitProgress, minSlidesTarget = MIN_SLIDES_TARGET) => {
32  if (swiperEl.dataset.prepared === 'true') {
33    const baseSlides = Number(swiperEl.dataset.preparedSlides)
34    const copies = Number(swiperEl.dataset.preparedCopies)
35
36    return {
37      baseSlides,
38      copies
39    }
40  }
41
42  const wrapper = swiperEl.querySelector('.swiper-wrapper')
43
44  if (!wrapper) {
45    return { baseSlides: 0, copies: 1, initialSlide: 0 }
46  }
47
48  const originalSlides = Array.from(wrapper.querySelectorAll('.swiper-slide'))
49  const baseSlides = originalSlides.length
50
51  if (baseSlides === 0) {
52    return { baseSlides: 0, copies: 1, initialSlide: 0 }
53  }
54
55  const copies = getCreativeLoopCopies(baseSlides, limitProgress, minSlidesTarget)
56
57  if (copies > 0) {
58    const fragment = document.createDocumentFragment()
59
60    for (let i = 0; i < copies; i++) {
61      const slideIndex = i % baseSlides
62      fragment.appendChild(originalSlides[slideIndex].cloneNode(true))
63    }
64
65    wrapper.appendChild(fragment)
66  }
67
68  swiperEl.dataset.prepared = 'true'
69  swiperEl.dataset.preparedSlides = String(baseSlides)
70  swiperEl.dataset.preparedCopies = String(copies)
71
72  return {
73    baseSlides,
74    copies
75  }
76}
77
78const createCreativeLoopReflow = (limitProgress) => {
79  let isRepositioning = false
80
81  return (swiper) => {
82    if (isRepositioning || !swiper.params.loop) return
83
84    const slidesBefore = swiper.activeIndex
85    const slidesAfter = swiper.slides.length - slidesBefore - 1
86
87    if (slidesBefore >= limitProgress && slidesAfter >= limitProgress) return
88
89    isRepositioning = true
90    swiper.slideToLoop(swiper.realIndex, 0, false)
91    window.requestAnimationFrame(() => {
92      isRepositioning = false
93    })
94  }
95}
96
97const effectDiplomParams = {
98  fullhd: {
99    progressMultiplier: 0.8,
100    prev: {
101      translate: ['-65px', 0, -1],
102      scale: 0.96
103    },
104    next: {
105      translate: ['65px', 0, -1],
106      scale: 0.96
107    }
108  },
109  tablet: {
110    progressMultiplier: 0.8,
111    prev: {
112      translate: ['-65px', 0, -1],
113      scale: 0.96
114    },
115    next: {
116      translate: ['65px', 0, -1],
117      scale: 0.96
118    }
119  },
120  mobile: {
121    progressMultiplier: 0.8,
122    prev: {
123      translate: ['-48px', 0, -1],
124      scale: 0.96
125    },
126    next: {
127      translate: ['48px', 0, -1],
128      scale: 0.96
129    }
130  }
131}
132
133const effectCertParams = {
134  fullhd: {
135    progressMultiplier: 0.8,
136    prev: {
137      translate: ['-100px', 0, -1],
138      scale: 0.91
139    },
140    next: {
141      translate: ['100px', 0, -1],
142      scale: 0.91
143    }
144  },
145  tablet: {
146    progressMultiplier: 0.8,
147    prev: {
148      translate: ['-85px', 0, -1],
149      scale: 0.92
150    },
151    next: {
152      translate: ['85px', 0, -1],
153      scale: 0.92
154    }
155  },
156  mobile: {
157    progressMultiplier: 0.3,
158    prev: {
159      translate: ['-145px', 0, -1],
160      scale: 0.75
161    },
162    next: {
163      translate: ['145px', 0, -1],
164      scale: 0.75
165    }
166  }
167}
168
169const getEffectParam = (type) => {
170  const viewport = window.innerWidth
171  const paramObj = type === 'cert' ? effectCertParams : effectDiplomParams
172  let paramsEffect = null
173
174  switch (true) {
175    case viewport <= MEDIA.tablet[1] - 1:
176      paramsEffect = paramObj.mobile
177      break
178    case viewport <= MEDIA.desktop[1]:
179      paramsEffect = paramObj.tablet
180      break
181    default:
182      paramsEffect = paramObj.fullhd
183  }
184
185  return paramsEffect
186}
187
188const applyEffectParam = (swiper, type) => {
189  const effectVariant = getEffectParam(type)
190
191  const targets = [swiper.params.creativeEffect, swiper.originalParams.creativeEffect]
192
193  targets.forEach((effect) => {
194    if (!effect) return
195
196    effect.progressMultiplier = effectVariant.progressMultiplier
197
198    if (effect.prev) {
199      effect.prev.translate = [...effectVariant.prev.translate]
200      effect.prev.scale = effectVariant.prev.scale
201    }
202
203    if (effect.next) {
204      effect.next.translate = [...effectVariant.next.translate]
205      effect.next.scale = effectVariant.next.scale
206    }
207  })
208}
209
210const ensurePartnersLoopSlides = (carousel) => {
211  const wrapper = carousel.querySelector('.swiper-wrapper')
212
213  if (!wrapper) {
214    return
215  }
216
217  const slides = Array.from(wrapper.querySelectorAll(':scope > .swiper-slide'))
218
219  if (slides.length === 0) {
220    return
221  }
222
223  const carouselWidth = carousel.clientWidth || carousel.getBoundingClientRect().width || 0
224  const slideWidth = slides[0].getBoundingClientRect().width || 0
225
226  if (!carouselWidth || !slideWidth) {
227    return
228  }
229
230  const requiredSlides = Math.ceil(carouselWidth / slideWidth) + 4
231  const currentSlides = slides.length
232
233  if (currentSlides >= requiredSlides) {
234    return
235  }
236
237  let missingSlides = requiredSlides - currentSlides
238
239  while (missingSlides > 0) {
240    slides.forEach((slide) => {
241      if (missingSlides <= 0) {
242        return
243      }
244
245      wrapper.appendChild(slide.cloneNode(true))
246      missingSlides -= 1
247    })
248  }
249}
250
251window.swiperHelpers = {
252  hasManySlides,
253  slidesCount,
254  getCreativeLoopCopies,
255  addExtraClasses,
256  cloneSlidesForLoop,
257  createCreativeLoopReflow,
258  getEffectParam,
259  applyEffectParam,
260  ensurePartnersLoopSlides
261}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.