Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <script>
- /* ============================================
- OV Parallax Reveal — Divi JS
- ============================================ */
- (function () {
- window.addEventListener('DOMContentLoaded', function () {
- // Secciones de Divi con clase ov-prl-section
- const sections = Array.from(document.querySelectorAll('.ov-prl-section'));
- const total = sections.length;
- if (total === 0) return;
- const DURATION = 900; // duración scroll normal (ms)
- const DURATION_SEQ = 600; // duración navegación secuencial — dots y anclas (ms)
- const PARALLAX = 0.35;
- let current = 0;
- let animating = false;
- // Mostrar primera sección
- sections[0].classList.add('ov-prl-visible');
- // --- Inyectar dots ---
- const dotsWrap = document.createElement('div');
- dotsWrap.id = 'ov-prl-dots';
- sections.forEach((_, i) => {
- const d = document.createElement('div');
- d.className = 'ov-prl-dot' + (i === 0 ? ' ov-prl-active' : '');
- d.dataset.goto = i;
- dotsWrap.appendChild(d);
- });
- document.body.appendChild(dotsWrap);
- const dots = Array.from(dotsWrap.querySelectorAll('.ov-prl-dot'));
- // --- Helpers ---
- function easeInOut(t) {
- return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
- }
- function reset(sec) {
- sec.style.transform = 'translateY(0)';
- const bg = sec.querySelector('.ov-prl-bg');
- if (bg) bg.style.transform = 'translateY(0)';
- }
- function updateDots() {
- dots.forEach((d, i) => d.classList.toggle('ov-prl-active', i === current));
- }
- // --- Animación principal (un paso) ---
- function goTo(next, duration = DURATION) {
- if (animating || next === current || next < 0 || next >= total) return;
- animating = true;
- const prev = current;
- const forward = next > prev;
- const leaving = sections[prev];
- const entering = sections[next];
- const leaveBg = leaving.querySelector('.ov-prl-bg');
- const enterBg = entering.querySelector('.ov-prl-bg');
- sections.forEach(s => s.classList.remove('ov-prl-visible'));
- leaving.classList.add('ov-prl-visible');
- entering.classList.add('ov-prl-visible');
- if (forward) {
- leaving.style.zIndex = 2;
- entering.style.zIndex = 1;
- leaving.style.transform = 'translateY(0)';
- if (leaveBg) leaveBg.style.transform = 'translateY(0)';
- entering.style.transform = 'translateY(0)';
- if (enterBg) enterBg.style.transform = `translateY(${PARALLAX * 60}%)`;
- const start = performance.now();
- (function tick(now) {
- const t = Math.min((now - start) / duration, 1);
- const ease = easeInOut(t);
- leaving.style.transform = `translateY(${-ease * 100}%)`;
- if (leaveBg) leaveBg.style.transform = `translateY(${ease * 100 * PARALLAX}%)`;
- if (enterBg) enterBg.style.transform = `translateY(${PARALLAX * 60 * (1 - ease)}%)`;
- if (t < 1) { requestAnimationFrame(tick); return; }
- leaving.classList.remove('ov-prl-visible');
- reset(leaving);
- reset(entering);
- current = next;
- animating = false;
- wheelAccum = 0; // resetear acumulador al terminar animación
- updateDots();
- })(performance.now());
- } else {
- entering.style.zIndex = 2;
- leaving.style.zIndex = 1;
- entering.style.transform = 'translateY(-100%)';
- if (enterBg) enterBg.style.transform = 'translateY(0%)';
- leaving.style.transform = 'translateY(0)';
- if (leaveBg) leaveBg.style.transform = 'translateY(0)';
- const start = performance.now();
- (function tick(now) {
- const t = Math.min((now - start) / duration, 1);
- const ease = easeInOut(t);
- entering.style.transform = `translateY(${-(1 - ease) * 100}%)`;
- if (leaveBg) leaveBg.style.transform = `translateY(${ease * 100 * PARALLAX}%)`;
- if (t < 1) { requestAnimationFrame(tick); return; }
- leaving.classList.remove('ov-prl-visible');
- reset(leaving);
- reset(entering);
- current = next;
- animating = false;
- wheelAccum = 0; // resetear acumulador al terminar animación
- updateDots();
- })(performance.now());
- }
- }
- // --- Navegación secuencial (pasa por cada slide intermedio) ---
- function goToSequential(target) {
- if (target === current) return;
- const step = target > current ? 1 : -1;
- function next() {
- const nextIndex = current + step;
- goTo(nextIndex, DURATION_SEQ);
- if (nextIndex === target) return;
- const wait = setInterval(() => {
- if (!animating) {
- clearInterval(wait);
- next();
- }
- }, 50);
- }
- next();
- }
- // --- Evento wheel con acumulador para trackpad ---
- let wheelAccum = 0;
- window.addEventListener('wheel', (e) => {
- if (animating) return;
- wheelAccum += e.deltaY;
- if (Math.abs(wheelAccum) < 50) return; // umbral mínimo
- const next = wheelAccum > 0 ? current + 1 : current - 1;
- wheelAccum = 0;
- if (next < 0 || next >= total) return;
- goTo(next);
- }, { passive: true });
- // --- Touch ---
- let ty = 0;
- window.addEventListener('touchstart', (e) => {
- ty = e.touches[0].clientY;
- }, { passive: true });
- window.addEventListener('touchend', (e) => {
- const diff = ty - e.changedTouches[0].clientY;
- if (Math.abs(diff) > 50) goTo(diff > 0 ? current + 1 : current - 1);
- }, { passive: true });
- // --- Teclado ---
- window.addEventListener('keydown', (e) => {
- if (e.key === 'ArrowDown' || e.key === 'PageDown') goTo(current + 1);
- if (e.key === 'ArrowUp' || e.key === 'PageUp') goTo(current - 1);
- });
- // --- Dots (secuencial) ---
- dots.forEach(d => d.addEventListener('click', () => goToSequential(+d.dataset.goto)));
- // --- Anclas del menú (secuencial) ---
- document.querySelectorAll('a[href^="#"]').forEach(link => {
- link.addEventListener('click', (e) => {
- const id = link.getAttribute('href').slice(1);
- const target = document.getElementById(id);
- if (!target) return;
- const index = sections.indexOf(target);
- if (index === -1) return;
- e.preventDefault();
- goToSequential(index);
- });
- });
- });
- })();
- </script>
Advertisement
Add Comment
Please, Sign In to add comment