oscarviedma

Código Funcionalidad OVPC JavaScript WooCommerce - OV DIVI

Oct 17th, 2025
522
0
Never
6
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 14.06 KB | None | 0 0
  1. <!-- Ionicons -->
  2. <script type="module" src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.esm.js"></script>
  3. <script nomodule src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.js"></script>
  4.  
  5. <!-- GSAP -->
  6. <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
  7.  
  8. <script>
  9.   // Products data - Se carga dinámicamente desde WooCommerce
  10.   let products = [];
  11.  
  12.   // Función para cargar productos de WooCommerce vía AJAX
  13.   async function loadWooProducts() {
  14.       try {
  15.           const response = await fetch('/wp-admin/admin-ajax.php?action=ovdivi_get_woo_products');
  16.           const data = await response.json();
  17.          
  18.           if (data.success && data.data && data.data.length > 0) {
  19.              products = data.data;
  20.               console.log('✅ Productos WooCommerce cargados:', products.length);
  21.               initializeSlider();
  22.           } else {
  23.               console.error('❌ No hay productos disponibles en WooCommerce');
  24.               ovPsProductNameText.textContent = 'No hay productos disponibles';
  25.           }
  26.       } catch (error) {
  27.           console.error('❌ Error cargando productos WooCommerce:', error);
  28.           ovPsProductNameText.textContent = 'Error al cargar productos';
  29.       }
  30.   }
  31.  
  32.   // Main slider logic
  33.   const ovPsGallery = document.querySelector(".ov-ps-ovPsGallery");
  34.   const ovPsProductsContainer = document.querySelector(".ov-ps-products");
  35.   const ovPsProductName = document.querySelector(".ov-ps-product-name");
  36.   const ovPsProductNameText = document.querySelector(".ov-ps-product-name p");
  37.   const ovPsProductPreview = document.querySelector(".ov-ps-product-preview");
  38.   const ovPsPreviewOverlay = document.querySelector(".ov-ps-preview-overlay");
  39.   const ovPsPreviewName = document.querySelector(".ov-ps-product-preview-name p");
  40.   const ovPsPreviewImg = document.querySelector(".ov-ps-product-preview-img img");
  41.   const ovPsPreviewTag = document.querySelector(".ov-ps-product-preview-tag p");
  42.   const ovPsPreviewUrl = document.querySelector(".ov-ps-product-url .ov-ps-btn a");
  43.   const ovPsProductBanner = document.querySelector(".ov-ps-product-banner");
  44.   const ovPsBannerImg = document.querySelector(".ov-ps-product-banner img");
  45.   const ovPsViewBtn = document.querySelector(".ov-ps-view-btn");
  46.   const ovPsViewBtnIcon = ovPsViewBtn.querySelector("ion-icon");
  47.   const ovPsPrevBtn = document.querySelector(".ov-ps-nav-btn.ov-ps-prev");
  48.   const ovPsNextBtn = document.querySelector(".ov-ps-nav-btn.ov-ps-next");
  49.   const ovPsDragIndicator = document.querySelector(".ov-ps-drag-indicator");
  50.  
  51.   let currentProductIndex = 0;
  52.   let slideItems = [];
  53.   let isPreviewAnimating = false;
  54.   let isPreviewOpen = false;
  55.   let isDragging = false;
  56.   let dragStartX = 0;
  57.   let dragThreshold = 50;
  58.  
  59.   const BUFFER_SIZE = 5;
  60.   const spacing = 0.375;
  61.   const slideWidth = spacing * 1000;
  62.  
  63.   function addSlideItem(relativeIndex) {
  64.       const productIndex =
  65.           (((currentProductIndex + relativeIndex) % products.length) +
  66.               products.length) %
  67.           products.length;
  68.       const product = products[productIndex];
  69.  
  70.       const li = document.createElement("li");
  71.       li.innerHTML = `<img src="${product.img}" alt="${product.name}" />`;
  72.       li.dataset.relativeIndex = relativeIndex;
  73.  
  74.       li.addEventListener("click", function(e) {
  75.           if (!isDragging && relativeIndex === 0) {
  76.              togglePreview();
  77.           }
  78.       });
  79.  
  80.       gsap.set(li, {
  81.           x: relativeIndex * slideWidth,
  82.           scale: relativeIndex === 0 ? 1.25 : 0.75,
  83.           zIndex: relativeIndex === 0 ? 100 : 1,
  84.           opacity: isPreviewOpen ? 0 : 1,
  85.       });
  86.  
  87.       ovPsProductsContainer.appendChild(li);
  88.       slideItems.push({ element: li, relativeIndex: relativeIndex });
  89.   }
  90.  
  91.   function removeSlideItem(relativeIndex) {
  92.       const itemIndex = slideItems.findIndex(
  93.           (item) => item.relativeIndex === relativeIndex
  94.       );
  95.       if (itemIndex !== -1) {
  96.           const item = slideItems[itemIndex];
  97.           item.element.remove();
  98.           slideItems.splice(itemIndex, 1);
  99.       }
  100.   }
  101.  
  102.   function updateSliderPosition() {
  103.       slideItems.forEach((item) => {
  104.           const isActive = item.relativeIndex === 0;
  105.           gsap.to(item.element, {
  106.               x: item.relativeIndex * slideWidth,
  107.               scale: isActive ? 1.25 : 0.75,
  108.               zIndex: isActive ? 100 : 1,
  109.               duration: 0.75,
  110.               ease: "power3.out",
  111.           });
  112.       });
  113.   }
  114.  
  115.   function updateProductName() {
  116.       const actualIndex =
  117.           ((currentProductIndex % products.length) + products.length) %
  118.           products.length;
  119.       ovPsProductNameText.textContent = products[actualIndex].name;
  120.   }
  121.  
  122.   function updatePreviewContent(animate = true) {
  123.       const actualIndex =
  124.           ((currentProductIndex % products.length) + products.length) %
  125.           products.length;
  126.       const currentProduct = products[actualIndex];
  127.      
  128.       const currencySymbol = currentProduct.currency || '$';
  129.       const currencyCode = currentProduct.currency_code || 'USD';
  130.      
  131.       if (!animate) {
  132.           // Solo actualizar contenido sin animar (para inicialización)
  133.           ovPsPreviewName.textContent = currentProduct.name;
  134.           ovPsPreviewImg.src = currentProduct.img;
  135.           ovPsPreviewImg.alt = currentProduct.name;
  136.           ovPsPreviewTag.textContent = currentProduct.tag;
  137.           ovPsPreviewUrl.href = currentProduct.url;
  138.           ovPsPreviewUrl.target = "_blank";
  139.           ovPsPreviewUrl.rel = "noopener noreferrer";
  140.           ovPsPreviewUrl.textContent = `Ver Detalles - ${currencySymbol}${parseFloat(currentProduct.price).toFixed(2)} ${currencyCode}`;
  141.           ovPsBannerImg.src = currentProduct.img;
  142.           ovPsBannerImg.alt = currentProduct.name;
  143.           return;
  144.       }
  145.      
  146.       // Animar el preview hacia abajo primero
  147.       gsap.to(ovPsProductPreview, {
  148.           y: "0%",
  149.           opacity: 0,
  150.           duration: 0.3,
  151.           ease: "power2.in",
  152.           onComplete: () => {
  153.               // Update content
  154.               ovPsPreviewName.textContent = currentProduct.name;
  155.               ovPsPreviewImg.src = currentProduct.img;
  156.               ovPsPreviewImg.alt = currentProduct.name;
  157.               ovPsPreviewTag.textContent = currentProduct.tag;
  158.               ovPsPreviewUrl.href = currentProduct.url;
  159.               ovPsPreviewUrl.target = "_blank";
  160.               ovPsPreviewUrl.rel = "noopener noreferrer";
  161.               ovPsPreviewUrl.textContent = `Ver Detalles - ${currencySymbol}${parseFloat(currentProduct.price).toFixed(2)} ${currencyCode}`;
  162.               ovPsBannerImg.src = currentProduct.img;
  163.               ovPsBannerImg.alt = currentProduct.name;
  164.              
  165.               // Animar el preview desde abajo hacia arriba
  166.               gsap.fromTo(ovPsProductPreview,
  167.                   {
  168.                       y: "20%",
  169.                       opacity: 0
  170.                   },
  171.                   {
  172.                       y: "-50%",
  173.                       opacity: 1,
  174.                       duration: 0.5,
  175.                       ease: "power2.out"
  176.                   }
  177.               );
  178.              
  179.               // Fade banner image
  180.               gsap.to(ovPsBannerImg, {
  181.                   opacity: 1,
  182.                   duration: 0.3
  183.               });
  184.           }
  185.       });
  186.   }
  187.  
  188.   function moveNext() {
  189.       if (isPreviewAnimating) return;
  190.  
  191.       currentProductIndex++;
  192.       removeSlideItem(-BUFFER_SIZE);
  193.       slideItems.forEach((item) => {
  194.           item.relativeIndex--;
  195.           item.element.dataset.relativeIndex = item.relativeIndex;
  196.          
  197.           item.element.onclick = function() {
  198.               if (!isDragging && item.relativeIndex === 0) {
  199.                  togglePreview();
  200.               }
  201.           };
  202.       });
  203.       addSlideItem(BUFFER_SIZE);
  204.       updateSliderPosition();
  205.       updateProductName();
  206.      
  207.       if (isPreviewOpen) {
  208.           updatePreviewContent();
  209.       }
  210.   }
  211.  
  212.   function movePrev() {
  213.       if (isPreviewAnimating) return;
  214.  
  215.       currentProductIndex--;
  216.       removeSlideItem(BUFFER_SIZE);
  217.       slideItems.forEach((item) => {
  218.           item.relativeIndex++;
  219.           item.element.dataset.relativeIndex = item.relativeIndex;
  220.          
  221.           item.element.onclick = function() {
  222.               if (!isDragging && item.relativeIndex === 0) {
  223.                  togglePreview();
  224.               }
  225.           };
  226.       });
  227.       addSlideItem(-BUFFER_SIZE);
  228.       updateSliderPosition();
  229.       updateProductName();
  230.      
  231.       if (isPreviewOpen) {
  232.           updatePreviewContent();
  233.       }
  234.   }
  235.  
  236.   function updateButtonStates() {
  237.       if (isPreviewAnimating) {
  238.           ovPsPrevBtn.classList.add("ov-ps-disabled");
  239.           ovPsNextBtn.classList.add("ov-ps-disabled");
  240.       } else {
  241.           ovPsPrevBtn.classList.remove("ov-ps-disabled");
  242.           ovPsNextBtn.classList.remove("ov-ps-disabled");
  243.       }
  244.   }
  245.  
  246.   function getActiveSlide() {
  247.       return slideItems.find((item) => item.relativeIndex === 0);
  248.   }
  249.  
  250.   function animateSideItems(hide = false) {
  251.       const activeSlide = getActiveSlide();
  252.  
  253.       slideItems.forEach((item) => {
  254.           gsap.to(item.element, {
  255.               x: hide
  256.                   ? item.relativeIndex * slideWidth * 1.5
  257.                   : item.relativeIndex * slideWidth,
  258.               opacity: hide ? 0 : 1,
  259.               duration: 0.75,
  260.               ease: "power3.inOut",
  261.           });
  262.       });
  263.  
  264.       if (activeSlide) {
  265.           gsap.to(activeSlide.element, {
  266.               scale: hide ? 0.75 : 1.25,
  267.               duration: 0.75,
  268.               ease: "power3.inOut",
  269.           });
  270.       }
  271.   }
  272.  
  273.   function togglePreview() {
  274.       if (isPreviewAnimating) return;
  275.  
  276.       isPreviewAnimating = true;
  277.       updateButtonStates();
  278.  
  279.       if (!isPreviewOpen) {
  280.           updatePreviewContent();
  281.           ovPsViewBtn.classList.add("ov-ps-active");
  282.           ovPsViewBtnIcon.name = "close-outline";
  283.           ovPsPreviewOverlay.classList.add("active");
  284.          
  285.           ovPsProductBanner.style.zIndex = "0";
  286.           ovPsProductName.style.opacity = "0";
  287.       } else {
  288.           ovPsViewBtn.classList.remove("ov-ps-active");
  289.           ovPsViewBtnIcon.name = "eye-outline";
  290.           ovPsPreviewOverlay.classList.remove("active");
  291.          
  292.           ovPsProductBanner.style.zIndex = "-1";
  293.           ovPsProductName.style.opacity = "1";
  294.       }
  295.  
  296.       gsap.to(ovPsProductPreview, {
  297.           y: isPreviewOpen ? "100%" : "-50%",
  298.           duration: 0.75,
  299.           ease: "power3.inOut",
  300.       });
  301.      
  302.       gsap.to(ovPsProductBanner, {
  303.           opacity: isPreviewOpen ? 0 : 1,
  304.           duration: 0.4,
  305.           delay: isPreviewOpen ? 0 : 0.25,
  306.           ease: "power3.inOut",
  307.       });
  308.  
  309.       animateSideItems(!isPreviewOpen);
  310.  
  311.       setTimeout(() => {
  312.           isPreviewAnimating = false;
  313.           isPreviewOpen = !isPreviewOpen;
  314.           updateButtonStates();
  315.       }, 600);
  316.   }
  317.  
  318.   function closePreview() {
  319.       if (isPreviewOpen && !isPreviewAnimating) {
  320.          togglePreview();
  321.       }
  322.   }
  323.  
  324.   function handleDragStart(e) {
  325.       if (isPreviewAnimating) return;
  326.      
  327.       isDragging = false;
  328.       dragStartX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
  329.       ovPsGallery.classList.add('dragging');
  330.   }
  331.  
  332.   function handleDragMove(e) {
  333.       if (isPreviewAnimating) return;
  334.       if (!dragStartX) return;
  335.  
  336.       const currentX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
  337.       const diff = currentX - dragStartX;
  338.  
  339.       if (Math.abs(diff) > 5) {
  340.           isDragging = true;
  341.           e.preventDefault();
  342.       }
  343.  
  344.       slideItems.forEach((item) => {
  345.           gsap.to(item.element, {
  346.               x: item.relativeIndex * slideWidth + diff * 0.5,
  347.               duration: 0.1,
  348.           });
  349.       });
  350.   }
  351.  
  352.   function handleDragEnd(e) {
  353.       if (isPreviewAnimating) return;
  354.       if (!dragStartX) return;
  355.  
  356.       const currentX = e.type.includes('mouse') ? e.clientX : e.changedTouches[0].clientX;
  357.       const diff = currentX - dragStartX;
  358.  
  359.       ovPsGallery.classList.remove('dragging');
  360.  
  361.       if (Math.abs(diff) > dragThreshold) {
  362.           if (diff > 0) {
  363.               movePrev();
  364.           } else {
  365.               moveNext();
  366.           }
  367.       } else {
  368.           updateSliderPosition();
  369.       }
  370.  
  371.       dragStartX = 0;
  372.      
  373.       setTimeout(() => {
  374.           isDragging = false;
  375.       }, 100);
  376.   }
  377.  
  378.   ovPsGallery.addEventListener('mousedown', handleDragStart);
  379.   ovPsGallery.addEventListener('mousemove', handleDragMove);
  380.   ovPsGallery.addEventListener('mouseup', handleDragEnd);
  381.   ovPsGallery.addEventListener('mouseleave', handleDragEnd);
  382.  
  383.   ovPsGallery.addEventListener('touchstart', handleDragStart, { passive: false });
  384.   ovPsGallery.addEventListener('touchmove', handleDragMove, { passive: false });
  385.   ovPsGallery.addEventListener('touchend', handleDragEnd);
  386.  
  387.   document.addEventListener('keydown', (e) => {
  388.       if (e.key === 'Escape') {
  389.           closePreview();
  390.       }
  391.   });
  392.  
  393.   ovPsPreviewOverlay.addEventListener('click', closePreview);
  394.  
  395.   ovPsGallery.addEventListener('mousedown', () => {
  396.       setTimeout(() => {
  397.           ovPsDragIndicator.style.display = 'none';
  398.       }, 1000);
  399.   }, { once: true });
  400.  
  401.   ovPsGallery.addEventListener('touchstart', () => {
  402.       setTimeout(() => {
  403.           ovPsDragIndicator.style.display = 'none';
  404.       }, 1000);
  405.   }, { once: true });
  406.  
  407.   function initializeSlider() {
  408.       if (products.length === 0) {
  409.           ovPsProductNameText.textContent = 'No hay productos disponibles';
  410.           return;
  411.       }
  412.      
  413.       for (let i = -BUFFER_SIZE; i <= BUFFER_SIZE; i++) {
  414.          addSlideItem(i);
  415.      }
  416.      updateSliderPosition();
  417.      updateProductName();
  418.      updatePreviewContent(false);
  419.      updateButtonStates();
  420.  }
  421.  
  422.  ovPsPrevBtn.addEventListener("click", movePrev);
  423.  ovPsNextBtn.addEventListener("click", moveNext);
  424.  ovPsViewBtn.addEventListener("click", togglePreview);
  425.  
  426.  loadWooProducts();
  427. </script>
Advertisement
Comments
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
Add Comment
Please, Sign In to add comment