42savage Posted August 22, 2021 Share Posted August 22, 2021 Hello guys, Im trying to build a simple carousel slider in vue 2. First problem is that my timeline is initially paused (i heard that is a good practice) and if i click next or prev button my animation doesn't play. I found solution, but I don't know if it is right one. I mean, it works but when using prevSlide function animation back to first initial slide. (probably thats another not related problem) So my question is how to handle timelines in vue. Should I put timeline in mounted, and prevSlide and nextSlide functions should only play or reverse the timeline? temporary solution: nextSlide() { this.tl.to(gsap.utils.toArray(this.$refs.slider.children), { xPercent: "-=" + 100, onComplete: this.tl.pause() }); this.tl.play() } the main code: <template> <div id="app"> <div class="slider" ref="slider"> <div class="slide"></div> <div class="slide"></div> <div class="slide"></div> </div> <button @click="prevSlide">prev</button> <button @click="nextSlide">next</button> </div> </template> <script> import gsap from "gsap"; export default { name: "App", data() { return { currSlide: 1, tl: gsap.timeline({ paused: true }), }; }, methods: { nextSlide() { this.tl.to(gsap.utils.toArray(this.$refs.slider.children), { xPercent: "-=" + 100, }); }, prevSlide() { this.tl.to(gsap.utils.toArray(this.$refs.slider.children), { xPercent: "-=" - 100, }); }, }, mounted() {}, }; </script> <style> #app { font-family: "Avenir", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } .slider { width: 600px; height: 350px; display: flex; flex-direction: row; overflow: hidden; } .slide { width: 100%; height: 100%; flex-shrink: 0; } .slide:nth-child(1) { background: crimson; } .slide:nth-child(2) { background: green; } .slide:nth-child(3) { background: darkcyan; } </style> Code playground down below https://codesandbox.io/s/gracious-fog-y4b8d?file=/src/App.vue Link to comment Share on other sites More sharing options...
OSUblake Posted August 22, 2021 Share Posted August 22, 2021 Welcome to the forums @42savage That's really not going to work. All you're doing is adding a new tween to a timeline on every click. You're timeline just gets longer and longer, and it's not going to handle interruptions, like if you keep clicking one of the buttons. Here's a helper function that you should be able to use to create a slider. https://greensock.com/docs/v3/HelperFunctions#loop As for Vue. Put your timeline where it makes the most sense. You don't need to put in the data. In fact, it's kind of pointless to put it there because it's not a reactive property. If you need a timeline to be available for the life of the component, then mounted is fine. mounted() { this.timeline = gsap.timeline() ... }, beforeDestroy() { this.timeline.kill(); } Or even calling some method to create it for you. mounted() { this.init() }, beforeDestroy() { this.timeline.kill(); } methods() { init() { this.timeline = gsap.timeline() ... } } 2 1 Link to comment Share on other sites More sharing options...
Cassie Posted August 23, 2021 Share Posted August 23, 2021 15 hours ago, 42savage said: simple carousel slider This is definitely an oxymoron. 😅 4 Link to comment Share on other sites More sharing options...
42savage Posted August 23, 2021 Author Share Posted August 23, 2021 Thanks for answer @OSUblake. 23 hours ago, OSUblake said: That's really not going to work. All you're doing is adding a new tween to a timeline on every click. You're timeline just gets longer and longer, and it's not going to handle interruptions, like if you keep clicking one of the buttons. Yeah it makes sense, I'll try to understand the code in helper function that you linked. 23 hours ago, OSUblake said: As for Vue. Put your timeline where it makes the most sense. You don't need to put in the data. In fact, it's kind of pointless to put it there because it's not a reactive property. I didn't put timeline in data() becuase of reactivity, but I put it there because of easy acces from methods (and that is the only way I know). For example I can simply play timeline by this.tl.play(). 23 hours ago, OSUblake said: beforeDestroy() { this.timeline.kill(); } Is killing timeline necesarry? Link to comment Share on other sites More sharing options...
OSUblake Posted August 23, 2021 Share Posted August 23, 2021 1 hour ago, 42savage said: Is killing timeline necesarry? It's a good idea to clean up after yourself. Not killing animations can result in memory leaks if you're not careful. 1 hour ago, 42savage said: I didn't put timeline in data() becuase of reactivity, but I put it there because of easy acces from methods (and that is the only way I know). For example I can simply play timeline by this.tl.play(). Exactly, you don't need to put stuff on the data object to access it via this.this is available everywhere. mounted() { // available in all methods, no deed to put on data this.timeline = gsap.timeline(); }, methods: { foo() { // works this.timeline.play(); }, bar() { // works this.timeline.reverse(); } } 2 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now