Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!-- Ionicons -->
- <script type="module" src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.esm.js"></script>
- <script nomodule src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.js"></script>
- <!-- GSAP -->
- <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
- <script>
- // Products data - Se carga dinámicamente desde WooCommerce
- let products = [];
- // Función para cargar productos de WooCommerce vía AJAX
- async function loadWooProducts() {
- try {
- const response = await fetch('/wp-admin/admin-ajax.php?action=ovdivi_get_woo_products');
- const data = await response.json();
- if (data.success && data.data && data.data.length > 0) {
- products = data.data;
- console.log('✅ Productos WooCommerce cargados:', products.length);
- initializeSlider();
- } else {
- console.error('❌ No hay productos disponibles en WooCommerce');
- ovPsProductNameText.textContent = 'No hay productos disponibles';
- }
- } catch (error) {
- console.error('❌ Error cargando productos WooCommerce:', error);
- ovPsProductNameText.textContent = 'Error al cargar productos';
- }
- }
- // Main slider logic
- const ovPsGallery = document.querySelector(".ov-ps-ovPsGallery");
- const ovPsProductsContainer = document.querySelector(".ov-ps-products");
- const ovPsProductName = document.querySelector(".ov-ps-product-name");
- const ovPsProductNameText = document.querySelector(".ov-ps-product-name p");
- const ovPsProductPreview = document.querySelector(".ov-ps-product-preview");
- const ovPsPreviewOverlay = document.querySelector(".ov-ps-preview-overlay");
- const ovPsPreviewName = document.querySelector(".ov-ps-product-preview-name p");
- const ovPsPreviewImg = document.querySelector(".ov-ps-product-preview-img img");
- const ovPsPreviewTag = document.querySelector(".ov-ps-product-preview-tag p");
- const ovPsPreviewUrl = document.querySelector(".ov-ps-product-url .ov-ps-btn a");
- const ovPsProductBanner = document.querySelector(".ov-ps-product-banner");
- const ovPsBannerImg = document.querySelector(".ov-ps-product-banner img");
- const ovPsViewBtn = document.querySelector(".ov-ps-view-btn");
- const ovPsViewBtnIcon = ovPsViewBtn.querySelector("ion-icon");
- const ovPsPrevBtn = document.querySelector(".ov-ps-nav-btn.ov-ps-prev");
- const ovPsNextBtn = document.querySelector(".ov-ps-nav-btn.ov-ps-next");
- const ovPsDragIndicator = document.querySelector(".ov-ps-drag-indicator");
- let currentProductIndex = 0;
- let slideItems = [];
- let isPreviewAnimating = false;
- let isPreviewOpen = false;
- let isDragging = false;
- let dragStartX = 0;
- let dragThreshold = 50;
- const BUFFER_SIZE = 5;
- const spacing = 0.375;
- const slideWidth = spacing * 1000;
- function addSlideItem(relativeIndex) {
- const productIndex =
- (((currentProductIndex + relativeIndex) % products.length) +
- products.length) %
- products.length;
- const product = products[productIndex];
- const li = document.createElement("li");
- li.innerHTML = `<img src="${product.img}" alt="${product.name}" />`;
- li.dataset.relativeIndex = relativeIndex;
- li.addEventListener("click", function(e) {
- if (!isDragging && relativeIndex === 0) {
- togglePreview();
- }
- });
- gsap.set(li, {
- x: relativeIndex * slideWidth,
- scale: relativeIndex === 0 ? 1.25 : 0.75,
- zIndex: relativeIndex === 0 ? 100 : 1,
- opacity: isPreviewOpen ? 0 : 1,
- });
- ovPsProductsContainer.appendChild(li);
- slideItems.push({ element: li, relativeIndex: relativeIndex });
- }
- function removeSlideItem(relativeIndex) {
- const itemIndex = slideItems.findIndex(
- (item) => item.relativeIndex === relativeIndex
- );
- if (itemIndex !== -1) {
- const item = slideItems[itemIndex];
- item.element.remove();
- slideItems.splice(itemIndex, 1);
- }
- }
- function updateSliderPosition() {
- slideItems.forEach((item) => {
- const isActive = item.relativeIndex === 0;
- gsap.to(item.element, {
- x: item.relativeIndex * slideWidth,
- scale: isActive ? 1.25 : 0.75,
- zIndex: isActive ? 100 : 1,
- duration: 0.75,
- ease: "power3.out",
- });
- });
- }
- function updateProductName() {
- const actualIndex =
- ((currentProductIndex % products.length) + products.length) %
- products.length;
- ovPsProductNameText.textContent = products[actualIndex].name;
- }
- function updatePreviewContent(animate = true) {
- const actualIndex =
- ((currentProductIndex % products.length) + products.length) %
- products.length;
- const currentProduct = products[actualIndex];
- const currencySymbol = currentProduct.currency || '$';
- const currencyCode = currentProduct.currency_code || 'USD';
- if (!animate) {
- // Solo actualizar contenido sin animar (para inicialización)
- ovPsPreviewName.textContent = currentProduct.name;
- ovPsPreviewImg.src = currentProduct.img;
- ovPsPreviewImg.alt = currentProduct.name;
- ovPsPreviewTag.textContent = currentProduct.tag;
- ovPsPreviewUrl.href = currentProduct.url;
- ovPsPreviewUrl.target = "_blank";
- ovPsPreviewUrl.rel = "noopener noreferrer";
- ovPsPreviewUrl.textContent = `Ver Detalles - ${currencySymbol}${parseFloat(currentProduct.price).toFixed(2)} ${currencyCode}`;
- ovPsBannerImg.src = currentProduct.img;
- ovPsBannerImg.alt = currentProduct.name;
- return;
- }
- // Animar el preview hacia abajo primero
- gsap.to(ovPsProductPreview, {
- y: "0%",
- opacity: 0,
- duration: 0.3,
- ease: "power2.in",
- onComplete: () => {
- // Update content
- ovPsPreviewName.textContent = currentProduct.name;
- ovPsPreviewImg.src = currentProduct.img;
- ovPsPreviewImg.alt = currentProduct.name;
- ovPsPreviewTag.textContent = currentProduct.tag;
- ovPsPreviewUrl.href = currentProduct.url;
- ovPsPreviewUrl.target = "_blank";
- ovPsPreviewUrl.rel = "noopener noreferrer";
- ovPsPreviewUrl.textContent = `Ver Detalles - ${currencySymbol}${parseFloat(currentProduct.price).toFixed(2)} ${currencyCode}`;
- ovPsBannerImg.src = currentProduct.img;
- ovPsBannerImg.alt = currentProduct.name;
- // Animar el preview desde abajo hacia arriba
- gsap.fromTo(ovPsProductPreview,
- {
- y: "20%",
- opacity: 0
- },
- {
- y: "-50%",
- opacity: 1,
- duration: 0.5,
- ease: "power2.out"
- }
- );
- // Fade banner image
- gsap.to(ovPsBannerImg, {
- opacity: 1,
- duration: 0.3
- });
- }
- });
- }
- function moveNext() {
- if (isPreviewAnimating) return;
- currentProductIndex++;
- removeSlideItem(-BUFFER_SIZE);
- slideItems.forEach((item) => {
- item.relativeIndex--;
- item.element.dataset.relativeIndex = item.relativeIndex;
- item.element.onclick = function() {
- if (!isDragging && item.relativeIndex === 0) {
- togglePreview();
- }
- };
- });
- addSlideItem(BUFFER_SIZE);
- updateSliderPosition();
- updateProductName();
- if (isPreviewOpen) {
- updatePreviewContent();
- }
- }
- function movePrev() {
- if (isPreviewAnimating) return;
- currentProductIndex--;
- removeSlideItem(BUFFER_SIZE);
- slideItems.forEach((item) => {
- item.relativeIndex++;
- item.element.dataset.relativeIndex = item.relativeIndex;
- item.element.onclick = function() {
- if (!isDragging && item.relativeIndex === 0) {
- togglePreview();
- }
- };
- });
- addSlideItem(-BUFFER_SIZE);
- updateSliderPosition();
- updateProductName();
- if (isPreviewOpen) {
- updatePreviewContent();
- }
- }
- function updateButtonStates() {
- if (isPreviewAnimating) {
- ovPsPrevBtn.classList.add("ov-ps-disabled");
- ovPsNextBtn.classList.add("ov-ps-disabled");
- } else {
- ovPsPrevBtn.classList.remove("ov-ps-disabled");
- ovPsNextBtn.classList.remove("ov-ps-disabled");
- }
- }
- function getActiveSlide() {
- return slideItems.find((item) => item.relativeIndex === 0);
- }
- function animateSideItems(hide = false) {
- const activeSlide = getActiveSlide();
- slideItems.forEach((item) => {
- gsap.to(item.element, {
- x: hide
- ? item.relativeIndex * slideWidth * 1.5
- : item.relativeIndex * slideWidth,
- opacity: hide ? 0 : 1,
- duration: 0.75,
- ease: "power3.inOut",
- });
- });
- if (activeSlide) {
- gsap.to(activeSlide.element, {
- scale: hide ? 0.75 : 1.25,
- duration: 0.75,
- ease: "power3.inOut",
- });
- }
- }
- function togglePreview() {
- if (isPreviewAnimating) return;
- isPreviewAnimating = true;
- updateButtonStates();
- if (!isPreviewOpen) {
- updatePreviewContent();
- ovPsViewBtn.classList.add("ov-ps-active");
- ovPsViewBtnIcon.name = "close-outline";
- ovPsPreviewOverlay.classList.add("active");
- ovPsProductBanner.style.zIndex = "0";
- ovPsProductName.style.opacity = "0";
- } else {
- ovPsViewBtn.classList.remove("ov-ps-active");
- ovPsViewBtnIcon.name = "eye-outline";
- ovPsPreviewOverlay.classList.remove("active");
- ovPsProductBanner.style.zIndex = "-1";
- ovPsProductName.style.opacity = "1";
- }
- gsap.to(ovPsProductPreview, {
- y: isPreviewOpen ? "100%" : "-50%",
- duration: 0.75,
- ease: "power3.inOut",
- });
- gsap.to(ovPsProductBanner, {
- opacity: isPreviewOpen ? 0 : 1,
- duration: 0.4,
- delay: isPreviewOpen ? 0 : 0.25,
- ease: "power3.inOut",
- });
- animateSideItems(!isPreviewOpen);
- setTimeout(() => {
- isPreviewAnimating = false;
- isPreviewOpen = !isPreviewOpen;
- updateButtonStates();
- }, 600);
- }
- function closePreview() {
- if (isPreviewOpen && !isPreviewAnimating) {
- togglePreview();
- }
- }
- function handleDragStart(e) {
- if (isPreviewAnimating) return;
- isDragging = false;
- dragStartX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
- ovPsGallery.classList.add('dragging');
- }
- function handleDragMove(e) {
- if (isPreviewAnimating) return;
- if (!dragStartX) return;
- const currentX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
- const diff = currentX - dragStartX;
- if (Math.abs(diff) > 5) {
- isDragging = true;
- e.preventDefault();
- }
- slideItems.forEach((item) => {
- gsap.to(item.element, {
- x: item.relativeIndex * slideWidth + diff * 0.5,
- duration: 0.1,
- });
- });
- }
- function handleDragEnd(e) {
- if (isPreviewAnimating) return;
- if (!dragStartX) return;
- const currentX = e.type.includes('mouse') ? e.clientX : e.changedTouches[0].clientX;
- const diff = currentX - dragStartX;
- ovPsGallery.classList.remove('dragging');
- if (Math.abs(diff) > dragThreshold) {
- if (diff > 0) {
- movePrev();
- } else {
- moveNext();
- }
- } else {
- updateSliderPosition();
- }
- dragStartX = 0;
- setTimeout(() => {
- isDragging = false;
- }, 100);
- }
- ovPsGallery.addEventListener('mousedown', handleDragStart);
- ovPsGallery.addEventListener('mousemove', handleDragMove);
- ovPsGallery.addEventListener('mouseup', handleDragEnd);
- ovPsGallery.addEventListener('mouseleave', handleDragEnd);
- ovPsGallery.addEventListener('touchstart', handleDragStart, { passive: false });
- ovPsGallery.addEventListener('touchmove', handleDragMove, { passive: false });
- ovPsGallery.addEventListener('touchend', handleDragEnd);
- document.addEventListener('keydown', (e) => {
- if (e.key === 'Escape') {
- closePreview();
- }
- });
- ovPsPreviewOverlay.addEventListener('click', closePreview);
- ovPsGallery.addEventListener('mousedown', () => {
- setTimeout(() => {
- ovPsDragIndicator.style.display = 'none';
- }, 1000);
- }, { once: true });
- ovPsGallery.addEventListener('touchstart', () => {
- setTimeout(() => {
- ovPsDragIndicator.style.display = 'none';
- }, 1000);
- }, { once: true });
- function initializeSlider() {
- if (products.length === 0) {
- ovPsProductNameText.textContent = 'No hay productos disponibles';
- return;
- }
- for (let i = -BUFFER_SIZE; i <= BUFFER_SIZE; i++) {
- addSlideItem(i);
- }
- updateSliderPosition();
- updateProductName();
- updatePreviewContent(false);
- updateButtonStates();
- }
- ovPsPrevBtn.addEventListener("click", movePrev);
- ovPsNextBtn.addEventListener("click", moveNext);
- ovPsViewBtn.addEventListener("click", togglePreview);
- loadWooProducts();
- </script>
Advertisement