1class MainSlider{ 2 MIN_SHIFT = 0; 3 isPaused = false; 4 TRANSITION = 1200; 5 QUICK_TRANSITION = 100; 6 TIME_QUICK_TRANSITION = 200; 7 MIN_SHIFT_PHONE = 20; 8 TRANSITION_PHONE = 300; 9 SCREEN_SIZE_PHONE = 576; 10 FIRST_SLIDE = 0; 11 VISIBLE_SLIDE = 1; 12 PLAY_VIDEO = true; 13 DELAY_STATE_CHANGE = 10; 14 $storage; 15 $slides; 16 $slide; 17 prevIndex; 18 index; 19 nextIndex 20 slideIndex; 21 slideSize; 22 slidesOffsetLeftBegin; 23 shiftStartX; 24 shiftEndX; 25 shiftStartY; 26 shiftEndY; 27 slidesOffsetLeft; 28 $dot; 29 PlayerState; 30 YT; 31 timerId; 32 widthLineBetweenDots; 33 videoId; 34 shiftTime = 0; 35 storageTransition; 36 autoplayParam = "Y"; 37 speedParam = 15000; 38 39 constructor(storage, slides, dot, autoplay, speed){ 40 this.$storage = $(storage); 41 this.$slides = $(slides); 42 this.$dot = $(dot); 43 this.$dots = $(dot).parent(); 44 this.autoplayParam = autoplay; 45 this.speedParam = speed; 46 this.$document = $(document); 47 this.$window = $(window); 48 this.isFirstRender = true; 49 this.renderTimerId = null; 50 this.run(); 51 } 52 53 init(){ 54 this.index = this.FIRST_SLIDE; 55 this.checkIndex(); 56 this.render(this.prevIndex, this.index, this.nextIndex); 57 this.slideSize = this.$slides.find(".js-main-slide-item").width(); 58 this.slidesOffsetLeftBegin = this.$slides.offset().left; 59 } 60 syncSlidesHeight(){ 61 let height = 0; 62 this.$storage.each((_, oItem) => { 63 height = Math.max(height, $(oItem).outerHeight()); 64 }); 65 this.$slides.css("min-height", height).children().css("min-height", height); 66 } 67 autoplay(){ 68 if(this.autoplayParam !== "Y") return false; 69 this.timerId = setInterval(() => { 70 if(!this.isPaused){ 71 let index = ++this.index; 72 this.checkDirection("right", index); 73 } 74 }, this.speedParam); 75 } 76 slideProgressBar(){ 77 const progressBar = $(".main-slider__dots-controls-progress path"), 78 totalLength = progressBar[0].getTotalLength(), 79 animationDuration = this.speedParam, 80 startTime = performance.now(); 81 82 function updateProgressBar(timestamp) { 83 const elapsedTime = timestamp - startTime, 84 progress = elapsedTime / animationDuration, 85 offset = totalLength * (1 - progress); 86 progressBar.css("strokeDashoffset", offset); 87 88 if(elapsedTime < animationDuration){ 89 requestAnimationFrame(updateProgressBar); 90 } 91 } 92 requestAnimationFrame(updateProgressBar); 93 } 94 togglePause(){ 95 this.isPaused = !this.isPaused; 96 clearTimeout(this.timerId); 97 if(!this.isPaused){ 98 this.autoplay(); 99 $('.main-slider__dots-controls').html('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">\n' + 100 ' <path d="M3 2.85714C3 2.38376 3.38376 2 3.85714 2H5.14286C5.61624 2 6 2.38376 6 2.85714V13.1429C6 13.6162 5.61624 14 5.14286 14H3.85714C3.38376 14 3 13.6162 3 13.1429V2.85714Z" fill="white"/>\n' +
101 ' <path d="M10 2.85714C10 2.38376 10.3838 2 10.8571 2H12.1429C12.6162 2 13 2.38376 13 2.85714V13.1429C13 13.6162 12.6162 14 12.1429 14H10.8571C10.3838 14 10 13.6162 10 13.1429V2.85714Z" fill="white"/>\n' + 102 '</svg>'+ 103 '<svg class="main-slider__dots-controls-progress" viewBox="0 0 100 100" style="display: block; width: 100%;">' + 104 ' <path d="M 50,50 m 0,-46 a 46,46 0 1 1 0,92 a 46,46 0 1 1 0,-92" stroke="#fff" stroke-width="8" fill-opacity="0" style="stroke-dasharray: 289.067, 289.067; stroke-dashoffset: 289";>' + 105 ' </path>' + 106 '</svg>'); 107 this.slideProgressBar(); 108 }else{ 109 $('.main-slider__dots-controls').html('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">\n' + 110 '<path d="M14.0111 6.96962C14.7963 7.42757 14.7963 8.57243 14.0111 9.03038L5.76667 13.8388C4.98148 14.2968 4 13.7243 4 12.8084L4 3.19156C4 2.27566 4.98148 1.70323 5.76667 2.16118L14.0111 6.96962Z" fill="white"/>\n' + 111 '</svg>' + 112 '<svg class="main-slider__dots-controls-progress" viewBox="0 0 100 100" style="display: block; width: 100%;">' + 113 ' <path d="M 50,50 m 0,-46 a 46,46 0 1 1 0,92 a 46,46 0 1 1 0,-92" stroke="#fff" stroke-width="8" fill-opacity="0" style="stroke-dasharray: 289.067, 289.067; stroke-dashoffset: 289;">' + 114 ' </path>' + 115 '</svg>'); 116 } 117 } 118 resetAutoplay(){ 119 clearTimeout(this.timerId); 120 this.autoplay(); 121 } 122 123 checkDirection(direction, nextIndex = null, event = ""){ 124 this.finalizeTransition(); 125 $(".js-main-slider-item-player iframe").hide(); 126 if(typeof nextIndex === "number" && event === "click"){ 127 this.render(this.prevIndex, this.index, nextIndex); 128 this.index = nextIndex; 129 }else if(typeof nextIndex === "number"){ 130 this.index = nextIndex; 131 }else{ 132 this.index = direction === "right" ? this.index += 1 : this.index -= 1; 133 } 134 if(nextIndex === this.slideIndex) return false; 135 this.checkIndex(); 136 this.shiftAnimated(direction); 137 this.renderTimerId = setTimeout(() => { 138 this.renderTimerId = null; 139 this.render(this.prevIndex, this.index, this.nextIndex); 140 }, this.TRANSITION); 141 } 142 143 finalizeTransition(){ 144 if(!this.renderTimerId) return; 145 clearTimeout(this.renderTimerId); 146 this.renderTimerId = null; 147 this.render(this.prevIndex, this.index, this.nextIndex); 148 } 149 150 render(){ 151 this.$slides.html(""); 152 for (let index = 0; index < arguments.length; index++){ 153 const $slide = $(this.$storage[arguments[index]]).clone(); 154 // ÐÑли ÑÑо не пеÑвÑй ÑÐµÐ½Ð´ÐµÑ Ð¸ Ñлайд акÑивнÑй, оÑклÑÑаем lazyload Ð´Ð»Ñ Ð°ÐºÑивного Ñлайда 155 if(!this.isFirstRender && index === this.VISIBLE_SLIDE){ 156 $slide.find("img.lazy-load").each((_, img) => { 157 img.src = img.dataset.src; 158 img.classList.remove("lazy-load"); 159 }); 160 } 161 this.$slides.append($slide); 162 } 163 this.syncSlidesHeight(); 164 this.shift(); 165 this.$slide = $(this.$slides.find(".js-main-slide-item")[this.VISIBLE_SLIDE]); 166 this.videoId = this.$slide.data("video-id"); 167 this.$video = this.$slide.find(".main-slider__item--player") 168 this.videoType = this.$video.data("type") 169 this.slideIndex = this.$slide.data("index"); 170 if(this.$window.width() > this.SCREEN_SIZE_PHONE){ 171 this.setVideo(); 172 } 173 this.setDot(); 174 175 // ÐоÑле пеÑвого ÑендеÑа ÑÑÑанавливаем Ñлаг в false 176 if(this.isFirstRender){ 177 this.isFirstRender = false;
178 } 179 } 180 181 shift(shift = 0){ 182 this.$slides.css({ 183 "transform": `translateX(${shift}px)`, 184 "transition": "0ms" 185 }); 186 } 187 188 shiftAnimated(direction = "right"){ 189 if(!this.isPaused){ 190 this.slideProgressBar(); 191 } 192 this.$slides.css({ 193 "transform": `translateX(${direction === "right" ? -this.slideSize : this.slideSize}px)`, 194 "transition": `${this.TRANSITION}ms` 195 }); 196 } 197 198 setVideo(){ 199 if (this.videoType === 'youtube') { 200 this.$video.append(`<div id="player"></div>`); 201 if(this.PLAY_VIDEO === true && typeof this.videoId !== "undefined"){ 202 new YT.Player("player", { 203 videoId: this.videoId, 204 playerVars: { 205 playlist: this.videoId, 206 autoplay: 1, 207 controls: 0, 208 mute: 1, 209 loop: 1 210 }, 211 events: { 212 "onReady": this.onPlayerReady, 213 "onStateChange": this.onPlayerStateChange 214 } 215 }); 216 } 217 } 218 if (this.videoType === 'rutube') { 219 let oVideo = new InitVideoRUTUBE(this.videoId) 220 oVideo.init() 221 this.$video.html(oVideo.htmlFrame) 222 this.$video.find("iframe").on('load', function () { 223 $(this)[0].contentWindow.postMessage(JSON.stringify({type: 'player:play', data: {}}), '*') 224 $(this)[0].contentWindow.postMessage(JSON.stringify({type: 'player:mute', data: {}}), '*') 225 }) 226 this.onPlayerReady() 227 this.$video.find("iframe").fadeIn(800) 228 } 229 } 230 231 onPlayerReady = (e = null) => { 232 let slideWidth = this.$slide.width(), 233 slideHeight = this.$slide.height(), 234 slideHeightCalculated = slideWidth / 1.78; 235 if (this.videoType === 'youtube') { 236 let player = e.target 237 player.playVideo(); 238 player.setPlaybackQuality("highres"); 239 }
240 if(slideHeightCalculated > slideHeight){ 241 this.$video.find("iframe").css({ 242 "width": slideWidth, 243 "height": slideHeightCalculated, 244 "top": `-${slideHeightCalculated / 2 - slideHeight / 2}px`, 245 "left": '0' 246 }); 247 }else{ 248 let slideWidthCalculated = slideHeight * 1.78; 249 this.$video.find("iframe").css({ 250 "width": slideWidthCalculated, 251 "height": slideHeight, 252 "top": "0", 253 "left": `-${slideWidthCalculated / 2 - slideWidth / 2}px` 254 }); 255 } 256 } 257 258 onPlayerStateChange = () => { 259 this.$video.find("iframe").fadeIn(800); 260 } 261 262 setDot(){ 263 this.$dot.each((index, item) => { 264 const $item = $(item), 265 $svg = $item.find("svg"), 266 iDotsCount = this.$dot.length, 267 width = (this.$dots.width() - this.$dot.width() * iDotsCount) / (iDotsCount > 1 ? iDotsCount - 1 : 1); 268 if(width < 0) return false; 269 $svg.remove(); 270 if(index === this.slideIndex){ 271 $item.append(` 272 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none"> 273 <circle cx="10" cy="10" r="5" fill="#E86A4D"/> 274 <circle cx="10" cy="10" r="4.5" stroke="white" stroke-opacity="0.3"/> 275 <circle cx="10" cy="10" r="9.5" stroke="white"/> 276 </svg> 277 `); 278 }else{ 279 $item.append(` 280 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none"> 281 <circle opacity="0.7" cx="10" cy="10" r="5" fill="white"/> 282 <circle cx="10" cy="10" r="4.5" stroke="white"/> 283 </svg> 284 `); 285 } 286 }); 287 } 288 289 checkIndex(){ 290 if(this.index < 0){ 291 this.index = this.$storage.length - 1; 292 }else if(this.index > this.$storage.length - 1){ 293 this.index = this.FIRST_SLIDE; 294 } 295 if(this.index === 0){ 296 this.prevIndex = this.$storage.length - 1; 297 this.nextIndex = this.index + 1; 298 }else if(this.index === this.$storage.length - 1){ 299 this.prevIndex = this.index - 1; 300 this.nextIndex = this.FIRST_SLIDE; 301 }else{ 302 this.prevIndex = this.index - 1; 303 this.nextIndex = this.index + 1; 304 } 305 } 306 307 checkShiftTime(){ 308 if(this.shiftTime + this.TRANSITION > $.now()){ 309 this.storageTransition = this.TRANSITION; 310 this.TRANSITION = this.QUICK_TRANSITION; 311 this.shiftTime = $.now(); 312 setTimeout(() => { 313 this.TRANSITION = this.storageTransition; 314 }, this.TIME_QUICK_TRANSITION); 315 } 316 } 317 nextSlide(){ 318 if(this.isSliderVisible()){ 319 this.resetAutoplay(); 320 this.checkDirection("right"); 321 } 322 } 323 prevSlide(){ 324 if(this.isSliderVisible()) { 325 this.resetAutoplay(); 326 this.checkDirection("left"); 327 } 328 } 329 handleKeyPress(event){ 330 if(event.key === "ArrowRight"){ 331 this.nextSlide(); 332 }else if(event.key === "ArrowLeft"){ 333 this.prevSlide(); 334 } 335 } 336 isSliderVisible(){ 337 let sliderRect = this.$slides[0].getBoundingClientRect(), 338 isVisible = (sliderRect.top < window.innerHeight && sliderRect.bottom >= 0) && 339 (sliderRect.left < window.innerWidth && sliderRect.right >= 0); 340 return isVisible; 341 } 342 run(){ 343 if(this.$window.width() < this.SCREEN_SIZE_PHONE){ 344 this.TRANSITION = this.TRANSITION_PHONE; 345 this.MIN_SHIFT = this.MIN_SHIFT_PHONE; 346 } 347 $(document).keydown((event) => { 348 this.handleKeyPress(event); 349 }); 350 this.init(); 351 this.autoplay(); 352 if(!this.isPaused){ 353 this.slideProgressBar(); 354 } 355 this.$dot.on("click", (e) => { 356 e = e.originalEvent; 357 if(e) e.stopPropagation(); 358 this.resetAutoplay();
359 let index = $(e.target).closest(".js-main-dot").index() - 1, 360 direction = this.index > index ? "left" : "right"; 361 this.checkDirection(direction, index, "click"); 362 }); 363 this.$window.on("resize.mainSlider", () => { 364 this.syncSlidesHeight(); 365 this.slideSize = this.$slides.find(".js-main-slide-item").width(); 366 }); 367 this.$slides.on("mousedown touchstart", (e) => { 368 e = e.originalEvent; 369 if(e) e.stopPropagation(); 370 this.resetAutoplay(); 371 this.checkShiftTime(); 372 this.finalizeTransition(); 373 if(e.type === "touchstart"){ 374 this.shiftStartX = e.targetTouches[0].clientX; 375 this.shiftStartY = e.targetTouches[0].clientY; 376 }else{ 377 this.shiftStartX = e.clientX; 378 this.shiftStartY = e.clientY; 379 } 380 this.shiftEndX = this.shiftStartX; 381 this.shiftEndY = this.shiftStartY; 382 this.slidesOffsetLeft = this.$slides.offset().left; 383 this.$slides.on("mousemove touchmove", (e) => { 384 e = e.originalEvent; 385 if(e) e.stopPropagation(); 386 if(this.$window.width() <= this.SCREEN_SIZE_PHONE){ 387 if(Math.abs(this.shiftEndY - this.shiftStartY) > Math.abs(this.shiftEndX - this.shiftStartX)) this.$slides.off("mousemove touchmove"); 388 } 389 if(e.type === "touchmove"){ 390 this.shiftStartX = e.targetTouches[0].clientX; 391 this.shiftStartY = e.targetTouches[0].clientY; 392 }else{ 393 this.shiftStartX = e.clientX; 394 this.shiftStartY = e.clientY; 395 } 396 let shiftValue = this.slidesOffsetLeft - (this.shiftEndX - this.shiftStartX) - this.slidesOffsetLeftBegin; 397 shiftValue = Math.max(-this.slideSize, Math.min(this.slideSize, shiftValue)); 398 this.shift(shiftValue); 399 }); 400 }); 401 this.$slides.on("mouseup touchend", (e) => { 402 e = e.originalEvent; 403 if(e) e.stopPropagation(); 404 this.shiftTime = $.now(); 405 this.$slides.off("mousemove touchmove"); 406 let diff = this.shiftEndX - this.shiftStartX; 407 if(Math.abs(diff) < this.MIN_SHIFT){ 408 this.$slides.css({ 409 "transform": `translateX(${this.slidesOffsetLeft - this.slidesOffsetLeftBegin}px)`, 410 "transition": `${this.TRANSITION}ms` 411 }); 412 }else if(diff > 0){ 413 this.checkDirection("right"); 414 }else if(diff < 0){ 415 this.checkDirection("left"); 416 } 417 }); 418 $(".main-slider__dots-controls").on("click", () => { 419 this.togglePause(); 420 }); 421 window.onYouTubeIframeAPIReady = () => { 422 this.PLAY_VIDEO = true; 423 } 424 } 425}
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.