Jump to content
Search Community

[VUE 2] GSAP Carousel slider timeline

42savage test
Moderator Tag

Recommended Posts

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

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() ...
  }
}

 

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

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

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();
  }
}

 

 

  • Like 2
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...