Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

401
Visualizações
CSS: cómo no restablecer la animación onhover en cada hover

Tengo una animación CSS simple al pasar el mouse que hace una transición de diapositivas entre las imágenes.

Cuando el usuario pasa el cursor sobre la SECCIÓN UNO y antes de que finalice la animación, haga el desplazamiento sobre la SECCIÓN dos, la animación se reinicia y hace un movimiento retrasado.

MI CÓDIGO:

 var $circle = $('#circle'); function moveCircle(e) { TweenLite.to($circle, 0.8, { css: { left: e.pageX, top: e.pageY } }); } $(window).on('mousemove', moveCircle);
 @import "compass/css3"; @keyframes in { from { transform: translateY(-100%); } to { transform: translateY(0); } } @keyframes out { from { transform: translateY(0); } to { transform: translateY(100%); } } html { background: #0E3741; } #circle { position: absolute; pointer-events : none; width: 400px; height: 200px; top: 50%; left: 50%; margin: -50px 0 0 -50px; } #circle .circle-wrapper { overflow: hidden; width: 400px; height: 200px; position: relative; } #circle img { position: absolute; top: 0; bottom: 0; left: 0; right: 0; width: 400px; height: 200px; object-fit: cover; overflow: hidden; } #wrapper { display: flex; flex-direction: column; } .special-element { width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; } #one { background: blue; } #two { background: red; } #one:hover ~ #circle .circle-wrapper #imgOne { animation: in 1s ease-in-out; z-index: 2; } #one:hover ~ #circle .circle-wrapper #imgTwo { animation: out 1s ease-in-out; } #two:hover ~ #circle .circle-wrapper #imgTwo { animation: in 1s ease-in-out; z-index: 2; } #two:hover ~ #circle .circle-wrapper #imgOne { animation: out 1s ease-in-out; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.4/TweenMax.min.js"></script> <section id="wrapper"> <section class="special-element" id="one"> section one </section> <section class="special-element" id="two"> section two </section> <div id="circle"> <div class="circle-wrapper"> <img id="imgOne" src="https://upload.wikimedia.org/wikipedia/commons/3/3b/Coca-cat.jpg"> <img id="imgTwo" src="https://staticcdn.sk/images/photoarchive/sized/700/2020/07/29/ohrozeny-vtak-krakla-belasa.jpg"> </div> </div> </section>

¿Hay alguna solución para evitar este problema de retraso?

¿Quizás hay alguna solución a cómo puedo resolverlo y hacer que esta animación sea fluida?

Estoy buscando algo como animación en este sitio web .

over 4 years ago · Santiago Trujillo
4 Respostas
Responde à pergunta

0

Creo que ese problema se debe a la "función de círculo en movimiento". Mover el elemento dom con izquierda y derecha no es bueno para el rendimiento. Debes mover el círculo con "transformar". Transforme las ejecuciones con la aceleración de GPU y funciona mejor y hace que el movimiento sea fluido.

Prueba este código.

 function moveCircle(e) { TweenLite.to($circle, 0.8, { css: { transform: `translate(${e.pageX}px, ${e.pageY}px)` } }); }
over 4 years ago · Santiago Trujillo Relatório

0

Versión actualizada

Puedes hacer una versión simplificada con gsap. Probablemente sea mejor no mezclar demasiado css simple con gsap, a menos que use css dentro de la biblioteca gsap. Porque gsap manipulará algunos de los accesorios. Por ejemplo, la transformación. Y es mejor usar transform que solo left/top porque está acelerado por hardware.

He hecho algunas mejoras en el código que he publicado antes. Se ve más suave ahora. Además, he agregado un pequeño efecto de zoom y desplazamiento horizontal, similar a la animación en el sitio web al que se hace referencia. Además, la animación ahora comienza desde abajo.

La animación está muy bien hecha en la página de referencia. Está hecho con WebGL. Esta no es su animación de todos los días y requiere bastante esfuerzo para que funcione, al menos para alguien que no es diseñador. Utiliza una matriz de transformación 3d y algunos otros efectos juntos.

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset-css@5.0.1/reset.min.css" /> <script type="application/javascript" defer src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script> <script type="application/javascript" defer src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/plugins/CSSPlugin.min.js"></script> <style type="text/css"> .section { display: block; width: 100%; height: 300px; border-bottom: 1px solid red; } .overlay { position: absolute; top: 0; left: 0; display: none; background: transparent; z-index: -1; } .stack { position: relative; min-width: 300px; min-height: 300px; width: 480px; height: 320px; max-width: 480px; max-height: 320px; overflow: hidden; z-index: 1; } .img { position: absolute; top: 0; left: 0; width: auto; height: auto; max-width: 100%; object-fit: contain; z-index: -1; } </style> </head> <body> <main class="main"> <section class="section section-1" data-img="img-1">section 1</section> <section class="section section-2" data-img="img-2">section 2</section> <div class="overlay"> <div class="stack"> <img id="img-1" class="img" src="https://upload.wikimedia.org/wikipedia/commons/3/3b/Coca-cat.jpg"> <img id="img-2" class="img" src="https://staticcdn.sk/images/photoarchive/sized/700/2020/07/29/ohrozeny-vtak-krakla-belasa.jpg"> </div> </div> </main> <script type="application/javascript"> window.onload = () => { const overlay = document.querySelector(".overlay"); const stack = document.querySelector(".stack"); const s1 = document.querySelector(".section-1"); const s2 = document.querySelector(".section-2"); const main = document.querySelector(".main"); const overlaySize = { width: 480, height: 320 }; const easeFunc = "sine.inOut"; const easeDuration = 0.5; let animation; let activeSection; let currentTarget; function createAnimation() { //console.log('create animation'); t1 = gsap.timeline({ paused: true }); t1.to(currentTarget, { zIndex: 2, display: "block" }, 0); t1.fromTo(currentTarget, { y: "100%" }, { y: 0, duration: easeDuration, ease: easeFunc }, 0); t1.to(currentTarget, { scale: 1.25, transformOrigin: "center", duration: easeDuration, ease: easeFunc }, 0); stack.querySelectorAll(".img").forEach((it) => { if (it !== currentTarget) { t1.to(it, { zIndex: -1 }, 0); t1.to(it, { scale: 1, transformOrigin: "center" }, 0); t1.to(it, { display: "none" }, easeDuration); } }); return t1; } function onMouseLeave(e) { const target = e.target; //console.log("leave", e.target); if (target === activeSection) { gsap.set(overlay, { display: "none" }); currentTarget = null; } } function onMouseEnter(e) { currentTarget = stack.querySelector(`#${e.target.dataset.img}`); gsap.set(overlay, { display: "block" }); if (!animation) { //console.log("undefined animation") animation = createAnimation(); animation.play(); } else if (animation.isActive()) { //console.log("still active"); animation.timeScale(10); // fast forward the rest of the animation animation = createAnimation(); animation.timeScale(1).play(); } else { //console.log("no longer active"); animation = createAnimation(); animation.play(); } } function onMouseMove(e) { const hoveredEl = document.elementFromPoint(e.pageX, e.pageY); if (hoveredEl.classList.contains("section")) { if (activeSection !== hoveredEl) { activeSection = hoveredEl; } } else if (hoveredEl.classList.contains("overlay") || hoveredEl.classList.contains("stack") || hoveredEl.classList.contains("pointer")) { // do nothing } else { if (activeSection) { activeSection = null; } } if (currentTarget) { // update overlay gsap.set(overlay, { x: e.pageX - overlaySize.width / 2, y: e.pageY - overlaySize.height / 2 }); // add a little horizontal-shift effect const dx = window.innerWidth / 2 - e.pageX; const offsetX = dx / window.innerWidth / 2 * 100; gsap.to(currentTarget, { x: offsetX * 2, duration: 2 }, 0); } } gsap.set(overlay, { x: 0, y: 0 }); stack.querySelectorAll('.img').forEach((it) => gsap.set(it, { x: 0, y: "100%" })); window.addEventListener("mousemove", onMouseMove); s1.addEventListener("mouseleave", onMouseLeave); s2.addEventListener("mouseleave", onMouseLeave); s1.addEventListener("mouseenter", onMouseEnter); s2.addEventListener("mouseenter", onMouseEnter); } </script> </body> </html>

respuesta antigua

 I have been playing around a little bit with the gsap library today. I've honestly never done anything with or like it. Tried to do it with the x and y params that you may pass to gsap. It will take care of the transformations - also the TimeLine stuff is quite handy. The result is not that great, also the animations look like it could be done better, but maybe it might still help you out. You could also improve some of the logic and animation probably. At least it runs quite stable - performance wise. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset-css@5.0.1/reset.min.css" /> <script type="application/javascript" defer src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script> <script type="application/javascript" defer src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/plugins/CSSPlugin.min.js"></script> <style type="text/css"> .section { display: block; width: 100%; height: 200px; border-bottom: 1px solid red; } .overlay { position: absolute; top: 0; left: 0; display: none; border: none; // 1px dashed black; background: transparent; // lavender; overflow: hidden; } .stack { position: relative; left: 0; right: 0; top: 0; bottom: 0; min-width: 300px; min-height: 300px; width: 480px; height: 320px; z-index: 0; } .anim-img { position: absolute; top: 0; left: 0; width: auto; height: auto; max-width: 100%; object-fit: contain; z-index: 1; } </style> </head> <body> <main class="main"> <section class="section section-1">section 1</section> <section class="section section-2">section 2</section> <div class="overlay"> <div class="stack"> <img id="img-1" class="anim-img" src="https://upload.wikimedia.org/wikipedia/commons/3/3b/Coca-cat.jpg"> <img id="img-2" class="anim-img" src="https://staticcdn.sk/images/photoarchive/sized/700/2020/07/29/ohrozeny-vtak-krakla-belasa.jpg"> </div> </div> </main> <script type="application/javascript"> window.onload = () => { const overlay = document.querySelector(".overlay"); const img1 = document.getElementById("img-1"); const img2 = document.getElementById("img-2"); const s1 = document.querySelector(".section-1"); const s2 = document.querySelector(".section-2"); const main = document.querySelector(".main"); let anim; let isS1active = false; let isS2active = false; let showEl; let hideEl; let leaveTimeout; function reverseFadeInOut(showEl, hideEl) { console.log("create reverse timeline anim -> ", { showEl, hideEl }); const tl = gsap.timeline({ paused: true }); tl .to(showEl, { zIndex: 1 }, 0) .to(hideEl, { zIndex: 10 }, 0) .to(hideEl, { y: "-100%", duration: 0.375 }, 0) .to(hideEl, { display: "none" }, 0.375) .to(hideEl, { zIndex: 1 }, 0.375) .to(showEl, { display: "block", zIndex: 10 }, 0.375) .fromTo(showEl, { y: "-100%" }, { y: 0, duration: .375 }, 0.375) .to(hideEl, { display: "none" }); return tl; } function fadeInOut(showEl, hideEl) { console.log("create timeline anim -> ", { showEl, hideEl }); const tl = gsap.timeline({ paused: true }); tl .to(hideEl, { zIndex: 1 }, 0) .to(showEl, { display: "block", zIndex: 10 }, 0) .fromTo(showEl, { y: "-100%" }, { y: 0, duration: .75 }, 0) .fromTo(hideEl, { y: 0 }, { y: "-100%", duration: .75 }, 0) .to(hideEl, { display: "none" }, 0.75); return tl; } function animateImage() { if (isS1active || isS2active) { if (isS1active) { showEl = img1; hideEl = img2; } else if (isS2active) { showEl = img2; hideEl = img1; } if (!anim) { console.log("create new animation"); anim = fadeInOut(showEl, hideEl); anim.play(); } else { console.log("anim active:", anim.isActive()); if (anim.isActive()) { console.log("reverse"); anim.kill(); anim = reverseFadeInOut(showEl, hideEl); anim.play(); } else { anim = fadeInOut(showEl, hideEl); anim.play(); } } } } function moveOverlay(e) { e.preventDefault(); e.stopPropagation(); gsap.set(overlay, { x: e.pageX + 15, y: e.pageY + 15, display: isS1active || isS2active ? "block" : "none" }); } function mouseOver(e, el, isEntering) { e.preventDefault(); e.stopPropagation(); el.classList.toggle("active"); isS1active = s1.classList.contains("active"); isS2active = s2.classList.contains("active"); if (isEntering) { clearTimeout(leaveTimeout); animateImage(); } else { leaveTimeout = setTimeout(() => { if (anim) { console.log("kill anim"); anim.kill(); anim = null; } gsap.timeline({ onComplete: () => { console.log("clear props"); gsap.set(".anim-img", { clearProps: true }); } }); }, 500); } } gsap.set(overlay, { x: "0", y: "0" }); gsap.set(img1, { x: "0", y: "-100%" }); gsap.set(img2, { x: "0", y: "-100%" }); window.addEventListener("mousemove", moveOverlay); s1.addEventListener("mouseenter", (e) => { mouseOver(e, s1, true); }); s1.addEventListener("mouseleave", (e) => { mouseOver(e, s1, false); }); s2.addEventListener("mouseenter", (e) => { mouseOver(e, s2, true); }); s2.addEventListener("mouseleave", (e) => { mouseOver(e, s2, false); }); } </script> </body> </html>

over 4 years ago · Santiago Trujillo Relatório

0

Sí, lo hay, modificando el valor del segundo parámetro de TweenLite.to , porque esa es la duration , vea más aquí: http://www.tud.ttu.ee/im/Jaak.Henno/FlashDevelop/greensock-as3 /greensock-as3/docs/com/greensock/TweenLite.html#to()

ingrese la descripción de la imagen aquí

 var $circle = $('#circle'); function moveCircle(e) { TweenLite.to($circle, 0.1, { css: { left: e.pageX, top: e.pageY } }); } $(window).on('mousemove', moveCircle);
 @import "compass/css3"; @keyframes in { from { transform: translateY(-100%); } to { transform: translateY(0); } } @keyframes out { from { transform: translateY(0); } to { transform: translateY(100%); } } html { background: #0E3741; } #circle { position: absolute; pointer-events : none; width: 400px; height: 200px; top: 50%; left: 50%; margin: -50px 0 0 -50px; } #circle .circle-wrapper { overflow: hidden; width: 400px; height: 200px; position: relative; } #circle img { position: absolute; top: 0; bottom: 0; left: 0; right: 0; width: 400px; height: 200px; object-fit: cover; overflow: hidden; } #wrapper { display: flex; flex-direction: column; } .special-element { width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; } #one { background: blue; } #two { background: red; } #one:hover ~ #circle .circle-wrapper #imgOne { animation: in 1s ease-in-out; z-index: 2; } #one:hover ~ #circle .circle-wrapper #imgTwo { animation: out 1s ease-in-out; } #two:hover ~ #circle .circle-wrapper #imgTwo { animation: in 1s ease-in-out; z-index: 2; } #two:hover ~ #circle .circle-wrapper #imgOne { animation: out 1s ease-in-out; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.4/TweenMax.min.js"></script> <section id="wrapper"> <section class="special-element" id="one"> section one </section> <section class="special-element" id="two"> section two </section> <div id="circle"> <div class="circle-wrapper"> <img id="imgOne" src="https://upload.wikimedia.org/wikipedia/commons/3/3b/Coca-cat.jpg"> <img id="imgTwo" src="https://staticcdn.sk/images/photoarchive/sized/700/2020/07/29/ohrozeny-vtak-krakla-belasa.jpg"> </div> </div> </section>

over 4 years ago · Santiago Trujillo Relatório

0

El sitio web está usando lienzo para la presentación de diapositivas en movimiento y han usado webgl para el tipo suave de efectos de revelación.

 <div class="site-footer"> <div class="js-scroll-height"></div> <canvas width="780" height="624" class="js-webgl" style="width: 1041px;height: 833px;opacity: 1;border: 1px solid brown;"></canvas> </div>


Podemos crear un efecto de revelación similar usando animación simple y manipulación del índice z:

 var $cursor = $('#cursor'); function movecursor(e) { TweenLite.to($cursor, 0.8, { css: { left: e.pageX, top: e.pageY } }); } $(window).on('mousemove', movecursor); let topImg = null; $('.special-element').mouseenter((e) => { //make all images at same level $('.img-wrapper').css({ zIndex: '1' }); //make last focused image at second highest level if (topImg) topImg.css({ zIndex: '2' }); //make current image as topImage let atr = $(e.target).attr('data-img'); topImg = $('.img-wrapper[data-img="' + atr + '"]'); //make it topmost topImg.css({ zIndex: '3' }); });
 :root { --cursor-img-height: 30vh; --cursor-img-width: 30vw; } html, body { background: #0E3741; } #wrapper { display: flex; flex-direction: column; } .special-element { width: 100%; height: 33vh; display: flex; justify-content: center; align-items: center; font-size: 2rem; } .special-element:nth-child(1) { background: lightblue; } .special-element:nth-child(2) { background: lightcoral; } .special-element:nth-child(3) { background: lightgreen; } #cursor { position: absolute; pointer-events: none; margin: 0; margin-top: calc(var(--cursor-img-height) * -0.5); margin-left: calc(var(--cursor-img-width) * -0.5); overflow: hidden; width: var(--cursor-img-width); height: var(--cursor-img-height); } .img-wrapper { position: absolute; bottom: 0; left: 0; width: var(--cursor-img-width); height: var(--cursor-img-height); overflow: hidden; } .img-wrapper>img { position: absolute; bottom: 0; left: 0; width: var(--cursor-img-width); height: var(--cursor-img-height); object-fit: fill; z-index: 1; } .special-element[data-img="one"]:hover~#cursor [data-img="one"], .special-element[data-img="two"]:hover~#cursor [data-img="two"], .special-element[data-img="three"]:hover~#cursor [data-img="three"] { animation: slide .8s ease-in-out; } @keyframes slide { from { height: 0px; transform: scale(1.2); } to { height: (--cursor-img-height); transform: scale(1); } }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.4/TweenMax.min.js"></script> <section id="wrapper"> <section class="special-element" data-img="one">food</section> <section class="special-element" data-img="two">animal</section> <section class="special-element" data-img="three">night</section> <div id="cursor"> <div class="img-wrapper" data-img='one'> <img src="https://picsum.photos/id/674/400/200"> </div> <div class="img-wrapper" data-img='two'> <img src="https://picsum.photos/id/433/400/200"> </div> <div class="img-wrapper" data-img='three'> <img src="https://picsum.photos/id/901/400/200"> </div> </div> </section>


Ver en modo página completa.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda