简体   繁体   English

为什么 GSAP 中的动画没有反转?

[英]Why is the animation not reversed in GSAP?

I have question, I wanted reverse animation showMenuList (this is pink background), but this not working, where is the mistake?我有疑问,我想要反向动画showMenuList (这是粉红色背景),但这不起作用,错误在哪里? I tried paused, and so many method but this not working, please help我试过暂停,还有很多方法,但这不起作用,请帮忙

I know that this is mostly code but I don't know what else to write.我知道这主要是代码,但我不知道还要写什么。 Find my code below and here a Codepen link.在下面找到我的代码,并在此处找到 Codepen 链接。

 const menuToggler = document.querySelector(".toggler"); const menuTogglerHamburger = document.querySelector(".toggler .hamburger"); menuToggler.addEventListener("click", function () { //checking if there is a class animationToggler if (menuTogglerHamburger.classList.contains("animationToggler")) { //restart animation rotate menuTogglerHamburger.classList.remove("animationToggler"); void menuTogglerHamburger.offsetWidth; menuTogglerHamburger.classList.add("animationToggler"); } menuTogglerHamburger.classList.add("animationToggler"); menuToggler.classList.toggle("show"); menuToggler.classList.contains("show") ? showMenuList(true) : showMenuList(false); setTimeout(() => { //animation line on the cross menuTogglerHamburger.classList.toggle("active"); }, 200); }); //---------------------- Show menu list ----------------------// const showMenuList = (e) => { console.log(e); const showMenuTl = gsap.timeline({ pause: true }); e ? showMenuTl.play() : showMenuTl.reverse(); showMenuTl .to(".nav-menu", 0.8, { css: { top: "50%" } }) .to(".nav-menu", 0.4, { css: { width: "140vw", height: "140vw" } }); };
 body { overflow: hidden; } nav { display: flex; width: 100%; align-items: center; justify-content: space-around; padding-top: 1em; } .toggler { display: flex; align-items: center; cursor: pointer; } .animationToggler { animation: animationTogglerMenu .8s ease; } .toggler p { margin: 0; text-transform: uppercase; font-size: 1.65rem; margin: 0 0 0 10px; z-index: 3; } .hamburger { z-index: 3; } .hamburger .line { height: 4px; width: 2.5em; background: #000; margin: .45em 0; border-radius: 50px; transition: .3s; } .active .one { transform: rotate(45deg) translateY(15px); } .active .two { background-color: transparent; transition: none; } .active .three { transform: rotate(-45deg) translateY(-15px); } .nav-menu { position: absolute; top: -100%; left: 50%; transform: translate(-50%, -50%); width: 3em; height: 3em; background-color: rgb(255, 117, 117); border-radius: 50%; /* opacity: 0.4; */ z-index: 2; } .nav-menu ul { display: none; } @keyframes animationTogglerMenu { 100% { transform: rotate(360deg); } }
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="toggler"> <div class="hamburger"> <div class="line one"></div> <div class="line two"></div> <div class="line three"></div> </div> <p>Menu</p> </div> <div class="nav-menu"> <ul> <li><a href="#">Home</a></li> <li><a href="#">Projekty</a></li> <li><a href="#">O nas</a></li> <li><a href="#">Kontakt</a></li> </ul> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script> <script src="main.js"></script> </body> </html>

First, it should be { paused: true } , not { pause: true } , as @jessegavin said.首先,它应该是{ paused: true } ,而不是{ pause: true } ,正如@jessegavin 所说。 Second, at the point where the click happens, you should have already made up the animation, which means the timeline definition should be at the top, outside of showMenuList .其次,在点击发生时,您应该已经制作了动画,这意味着时间线定义应该在顶部,在showMenuList之外。 Third, you could simplify your code to this:第三,您可以将代码简化为:

See the JavaScript part, it's way more short, I slightly modified the CSS.查看 JavaScript 部分,它更短,我稍微修改了 CSS。

 const menuToggler = document.querySelector(".toggler"); const showMenuTl = gsap.timeline({ paused: true }); showMenuTl .to(".nav-menu", 0.8, { css: { top: "50%" } }) .to(".nav-menu", 0.4, { css: { width: "140vw", height: "140vw" } }); menuToggler.addEventListener("click", function () { if (menuToggler.classList.contains("active")) { menuToggler.classList.remove("active"); showMenuTl.reverse(); } else { menuToggler.classList.add("active"); showMenuTl.play(); } });
 body { overflow: hidden; } nav { display: flex; width: 100%; align-items: center; justify-content: space-around; padding-top: 1em; } .toggler { display: flex; align-items: center; cursor: pointer; } .toggler p { margin: 0; text-transform: uppercase; font-size: 1.65rem; margin: 0 0 0 10px; z-index: 3; } .hamburger { z-index: 3; } .hamburger .line { height: 4px; width: 2.5em; background: #000; margin: 0.45em 0; border-radius: 50px; transition: 0.3s; } .active .hamburger { animation: animationTogglerMenu 0.8s ease; } .active .one { transform: rotate(45deg) translateY(15px); } .active .two { background-color: transparent; transition: none; } .active .three { transform: rotate(-45deg) translateY(-15px); } .nav-menu { position: absolute; top: -100%; left: 50%; transform: translate(-50%, -50%); width: 3em; height: 3em; background-color: rgb(255, 117, 117); border-radius: 50%; /* opacity: 0.4; */ z-index: 2; } .nav-menu ul { display: none; } @keyframes animationTogglerMenu { 100% { transform: rotate(360deg); } }
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="toggler"> <div class="hamburger"> <div class="line one"></div> <div class="line two"></div> <div class="line three"></div> </div> <p>Menu</p> </div> <div class="nav-menu"> <ul> <li><a href="#">Home</a></li> <li><a href="#">Projekty</a></li> <li><a href="#">O nas</a></li> <li><a href="#">Kontakt</a></li> </ul> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script> <script src="main.js"></script> </body> </html>

One issue with your code is you need to pass paused: true instead of pause:true to the timeline function.您的代码的一个问题是您需要将paused: true而不是pause:true传递给时间线函数。

One way you could improve your code (in my opinion) is to move the creation of your timeline object to the top level of your code block.改进代码的一种方法(在我看来)是将时间线对象的创建移到代码块的顶层。 Like so...像这样...

const menuToggler = document.querySelector(".toggler");
const menuTogglerHamburger = document.querySelector(".toggler .hamburger");

// Add it here -----------------------
const showMenuTl = gsap.timeline({ paused: true });
showMenuTl
  .to(".nav-menu", 0.8, { css: { top: "50%" } })
  .to(".nav-menu", 0.4, { css: { width: "140vw", height: "140vw" } });

Then you can get rid of the showMenuList function and call play and reverse directly.然后就可以去掉showMenuList函数,直接调用playreverse

  menuToggler.classList.toggle("show");
  menuToggler.classList.contains("show")
    ? showMenuTl.play()
    : showMenuTl.reverse()

One way you could approach this is creating another timeline.您可以解决此问题的一种方法是创建另一个时间线。 Which would be annoying to deal with if you added more keyframes.如果您添加更多关键帧,这会很烦人。 Another way you could do this is by adding a starting keyframe and then everything should run smoothly as shown below.您可以这样做的另一种方法是添加一个起始关键帧,然后一切都应该顺利运行,如下所示。

showMenuTl
  .to(".nav-menu", 1, { css: { width: "3rem", height: "3rem", top: "-100%" } })
    .to(".nav-menu", 0.8, { css: { width: "3rem", height: "3rem", top: "50%" } })
    .to(".nav-menu", 0.4, { css: { width: "140vw", height: "140vw", top: "50%" } });

  e ? showMenuTl.play() : showMenuTl.reverse(0);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM