1

I'm new to VueJS. I spent the last two hours trying to animate a slider, and finally I found a solution, but I don't understand why I need to set my image in position absolute to have the slide effect using the transform: translate property. Can someone explain me why? Here's the working code:

SCSS:

#slider {

        margin-top: 20px;
        width: 450px;
        height: 187.5px;
        position: relative;
        overflow: hidden;

        .layover {

            @extend %layover;
        }

        .wrapper-image-slider {

            width: 450px;
            height: 187.5px;
            position: relative;
            overflow: hidden;

            .slide-image {

                width: 100%;
                position: absolute; /* important */
                top: 0;
                left: 0;
                bottom: 0;
                right:0;
            }

            .thumb-text {

                position: absolute;
                top: 0;
                left: 0;
            }
            
        }

        .left-slide-enter-active, .left-slide-leave-active {

            transition: 1s;
        }

        .left-slide-enter {

            transform: translate(100%, 0);
        }

        .left-slide-leave-to {

            transform: translate(-100%, 0);
        }
    }

HTML:

                         <div id="slider">
                            <div class="layover"></div>
                            <transition-group name="left-slide" tag="div" class="wrapper-image-slider">
                                <div v-for="(post, index) in slider" :key="post.id" v-if="(activeImageSlider == index)">
                                    <img class="slide-image" :src="post.img">
                                    <div class="thumb-text">
                                        <div class="label">
                                            {{ slider[activeImageSlider].label }}
                                        </div>
                                        <h2>
                                            {{ slider[activeImageSlider].title }}
                                        </h2>
                                        <div class="descr">
                                            {{slider[activeImageSlider].descr }}
                                        </div>
                                    </div>
                                </div>
                            </transition-group>
                        </div>
Geeogee
  • 41
  • 5
  • Because both elements exist at the same time when transitioning so it needs absolute positioning so the layout doesn't glitch. You may want to look at the 'out-in' mode. https://vuejs.org/v2/guide/transitions.html#Transition-Modes – dantheman Jun 09 '21 at 18:03
  • It's clear, but I didn't think about that! I gave a look at the inspector and yes, there are two elements that transition together. So using position: absolute let the two divs stay side by side, right? – Geeogee Jun 10 '21 at 09:29
  • I also gave a look at the VueJS guide about list transitions, but it says that transition modes are not available, because we are no longer alternating between mutually exclusive elements. Looks like I can't use 'out-in' and 'in-out' mode – Geeogee Jun 10 '21 at 09:31

1 Answers1

0

I don't think you need to use a list transition for this. If you create a computed property that just returns the active slide then you can use a normal transition with the mode 'out-in'.

https://jsfiddle.net/9oj1h8r3/1/

new Vue({
  el: "#app",
  data: {
    activeSlideIndex: 0,
    slides: [
      { img: "https://picsum.photos/200/300?random=1" },
      { img: "https://picsum.photos/200/300?random=2" },
      { img: "https://picsum.photos/200/300?random=3" },
      { img: "https://picsum.photos/200/300?random=4" }
    ]
  },
  computed: {
    activeSlide() {
      return this.slides[this.activeSlideIndex]
    }
  }
})
dantheman
  • 3,189
  • 2
  • 10
  • 18
  • Sick animation, but that's not what I'm looking for. I'd like to have the next image and the image that is sliding left side by side during the transition. I achieved that, it works in my page, but not in this JSFiddle: [link](https://jsfiddle.net/dw2eup3b/124/) – Geeogee Jun 12 '21 at 09:51