vvjs-1.0.1/js/slideshow-navigation.js

js/slideshow-navigation.js
/**
 * @file
 * Slideshow navigation controls.
 *
 * Handles navigation buttons, dots, arrows, and play/pause controls.
 */

((Drupal) => {
  'use strict';

  const playIcon = `
    <svg class="svg-play" xmlns="http://www.w3.org/2000/svg" viewBox="80 -880 800 800" fill="currentColor">
      <path d="m380-300 280-180-280-180v360ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"></path>
    </svg>`;

  const pauseIcon = `
    <svg class="svg-pause" xmlns="http://www.w3.org/2000/svg" viewBox="80 -880 800 800" fill="currentColor">
      <path d="M360-320h80v-320h-80v320Zm160 0h80v-320h-80v320ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"></path>
    </svg>`;

  /**
   * Navigation controls class.
   */
  class SlideshowNavigation {
    constructor(container, slideshowCore) {
      this.container = container;
      this.core = slideshowCore;

      // Navigation elements
      this.playPauseButton = container.querySelector('.play-pause-button');
      this.nextButton = container.querySelector('.next-arrow');
      this.prevButton = container.querySelector('.prev-arrow');
      this.dots = container.querySelectorAll('.dots-numbers-button');
      this.currentSlideElement = container.querySelector('.current-slide');

      this.init();
    }

    init() {
      this.bindEvents();
      this.updateControls();

      // Listen for slideshow state changes
      this.container.addEventListener('vvjs:slideChanged', (e) => {
        this.updateControls(e.detail);
      });

      this.container.addEventListener('vvjs:pauseToggled', (e) => {
        this.updatePlayPauseButton(e.detail.isPaused);
      });
    }

    /**
     * Bind event listeners to navigation elements.
     */
    bindEvents() {
      // Play/pause button
      this.playPauseButton?.addEventListener('click', () => {
        // IMMEDIATE: Stop progress before toggling core state
        const modules = this.container.vvjsModules;
        if (modules && modules.progress && !this.core.isPaused) {
          modules.progress.resetProgress();
        }

        this.core.togglePause();
      });

      // Navigation arrows
      this.nextButton?.addEventListener('click', () => {
        this.core.nextSlide();
        this.core.startAutoSlide();
      });

      this.prevButton?.addEventListener('click', () => {
        this.core.prevSlide();
        this.core.startAutoSlide();
      });

      // Dot navigation
      this.dots.forEach((dot, index) => {
        dot.addEventListener('click', () => {
          this.core.goToSlide(index + 1);
          this.core.startAutoSlide();
        });
      });
    }

    /**
     * Update navigation controls based on current state.
     */
    updateControls(slideInfo = null) {
      if (slideInfo) {
        this.updateDots(slideInfo.slideIndex);
        this.updateSlideCounter(slideInfo.slideIndex);
      }
    }

    /**
     * Update dot navigation indicators.
     */
    updateDots(currentSlide) {
      this.dots.forEach((dot, index) => {
        const isActive = index + 1 === currentSlide;
        dot.classList.toggle('active', isActive);
        dot.setAttribute('aria-selected', isActive);
      });
    }

    /**
     * Update slide counter display.
     */
    updateSlideCounter(currentSlide) {
      if (this.currentSlideElement) {
        this.currentSlideElement.textContent = currentSlide;
      }
    }

    /**
     * Update play/pause button appearance.
     */
    updatePlayPauseButton(isPaused) {
      if (this.playPauseButton) {
        this.playPauseButton.innerHTML = isPaused ? playIcon : pauseIcon;
        this.playPauseButton.setAttribute(
          'aria-label',
          isPaused ? 'Play slideshow' : 'Pause slideshow'
        );
      }
    }

    /**
     * Enable/disable navigation controls.
     */
    setEnabled(enabled) {
      const controls = [
        this.playPauseButton,
        this.nextButton,
        this.prevButton,
        ...this.dots
      ].filter(Boolean);

      controls.forEach(control => {
        control.disabled = !enabled;
        control.setAttribute('aria-disabled', !enabled);
      });
    }
  }

  // Export to global namespace
  Drupal.vvjs = Drupal.vvjs || {};
  Drupal.vvjs.SlideshowNavigation = SlideshowNavigation;

})(Drupal);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc