Как исправить стиль v-align для imgs разных размеров в переходной группе Vue.js?

Я подготовил пример слайдера изображений, что мне нужно. Я сталкиваюсь с проблемой стиля при использовании изображений с различными размерами. Когда элемент покидает массив, его местоположение задается как абсолютное значение, что необходимо для плавного перехода, но изображение также перемещается вверх.

Я хотел бы иметь хорошее вертикальное выравнивание по середине, даже выйти или войти в массив, но никак не мог попасть.

Еще одна проблема, которую я хотел бы решить, это когда я покинул окно, а затем вернулся через некоторое время. Анимация запускает все циклы одновременно, чтобы достичь текущего состояния, вместо этого просто остановите анимацию и запустите ее. Может быть, это моя ответственность, но браузеры не предлагают хорошее событие, чтобы поймать окно размытия, или я ошибаюсь? Согласно этой дискуссии

Спасибо за любые идеи.

let numbers = [{key:1},{key:2},{key:3},{key:4},{key:5},{key:6},{key:7}]
 
 let images = [
  { key:1,
    src:"http://lorempixel.com/50/100/sports/"},
  { key:2,
    src:"http://lorempixel.com/50/50/sports/"},
  { key:3,
    src:"http://lorempixel.com/100/50/sports/"},
  { key:4,
    src:"http://lorempixel.com/20/30/sports/"},
  { key:5,
    src:"http://lorempixel.com/80/20/sports/"},
  { key:6,
    src:"http://lorempixel.com/20/80/sports/"},
  { key:7,
    src:"http://lorempixel.com/100/100/sports/"}
 ]
 
 new Vue({
  el: '#rotator',
  data: {
    items: images,
    lastKey: 7,
    direction: false
  },
  mounted () {
    setInterval(() => {
      if (this.direction) { this.prevr() } else { this.nextr() }
    }, 1000)
  },
  methods: {
    nextr () {
     let it = this.items.shift()
      it.key = ++this.lastKey
      this.items.push(it)
    },
    prevr () {
     let it = this.items.pop()
      it.key = ++this.lastKey
      this.items.unshift(it)
    }
  }
})
.litem {
  transition: all 1s;
  display: inline-block;
  margin-right: 10px;
  border: 1px solid green;
  background-color: lightgreen;
  padding: 10px 10px 10px 10px;
  height: 100px;
}
.innerDiv {
  border: 1px solid red;
}
.container {
  overflow: hidden;
  white-space: nowrap;
  height: 250px;
  border: 1px solid blue;
  background-color: lightblue;
}
.list-enter {
  opacity: 0;
  transform: translateX(40px);
}
.list-leave-to {
  opacity: 0;
  transform: translateX(-40px);
}
.list-leave-active {
  position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.js"></script>

<div id="rotator">
  
  <button @click="direction = !direction">
      change direction
  </button>
  
  <transition-group 
    name="list" 
    tag="div" 
    class="container">
    
      <div 
        v-for="item in items"            
        :key="item.key" class="litem">
        <!-- 
          <div 
            class='innerDiv'>
              {{ item.key }}
          </div> 
        -->
        <div class='innerDiv'>
          <img :src='item.src'>
        </div>
    </div>
  </transition-group>
</div>

1 ответ

Решение

Это занимает некоторое время, но в конце я думаю, что у меня получился лучший результат для скользящей анимации с функцией изменения направления.

Одна досадная мысль - когда я переключаю направление скольжения, чтобы анимация в течение "микросекунды" переходила в следующее состояние, а затем возвращалась в правильное состояние, после чего анимация продолжалась, как и ожидалось. Это происходит только в одном направлении, и я не знаю, как это исправить. И последний бокс ведет себя по-разному тоже только один раз. Понятия не имею вообще.

Так что просто 98% решение:-)

let images = [
  {key:1, domKey:1, src:"http://lorempixel.com/50/100/sports/"  },
  {key:2, domKey:2, src:"http://lorempixel.com/50/50/sports/"   },
  {key:3, domKey:3, src:"http://lorempixel.com/100/50/sports/"  },
  {key:4, domKey:4, src:"http://lorempixel.com/20/30/sports/"   },
  {key:5, domKey:5, src:"http://lorempixel.com/80/20/sports/"   },
  {key:6, domKey:6, src:"http://lorempixel.com/20/80/sports/"   },
  {key:7, domKey:7, src:"http://lorempixel.com/100/100/sports/" }
]

let setPositionRelative = el => el.style.position = "relative"

new Vue({
  el: '#rotator',
  data: {
    items: images,
    lastKey: 7,
    direction: true,
    changeDirectionRequest: false
  },
  mounted () {
   Array.from(this.$el.querySelectorAll("div[data-key]")).map(setPositionRelative)
    setInterval(() => {
      if(this.changeDirectionRequest) {
        this.changeDirectionRequest = false
        this.direction = !this.direction
        if (this.direction) 
         Array.from(this.$el.querySelectorAll("div[data-key]")).map(setPositionRelative)
        else 
         Array.from(this.$el.querySelectorAll("div[data-key]")).map(el => el.style.position = "")
      } 
      if (this.direction) this.prevr() 
      else this.nextr()
    }, 1000)
  },
  methods: {
    nextr () {
      let it = this.items.shift()
      it.key = ++this.lastKey
      this.items.push(it)
    },
    prevr () {
     let it = this.items.pop()
      it.key = ++this.lastKey
      this.items.unshift(it)
      setPositionRelative(this.$el.querySelector("div[data-domkey='"+it.domKey+"']"))
    }
 }
})
.container {
  overflow: hidden;
  white-space: nowrap;
  height: 200px;
  border: 1px solid blue;
  background-color: lightblue;
  display: flex;
  align-items: center;
}
.innerDiv {
  border: 1px solid red;
  width: auto; 
  height: auto; 

  display:-moz-box; 
  -moz-box-pack:center; 
  -moz-box-align:center; 

  display:-webkit-box; 
  -webkit-box-pack:center; 
  -webkit-box-align:center; 

  display:box; 
  box-pack:center; 
  box-align:center;
}
.litem {
  transition: all 1s;
  margin-right: 10px;
  border: 1px solid green;
  background-color: lightgreen;
  padding: 10px 10px 10px 10px;
}
.list2-enter, .list-enter {
  opacity: 0;
  transform: translateX(40px);
}
.list2-leave-to, .list-leave-to {
  opacity: 0;
  transform: translateX(-40px);
}
.list-leave-active {
  position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.js"></script>

<div id="rotator">
  <button @click="changeDirectionRequest = true">change direction</button>
  <transition-group name="list" tag="div" class="container">
    <div   v-for="item in items" 
          :key="item.key" 
          :data-domkey="item.domKey" 
          class="litem">
          
       <div class='innerDiv'>
          <img :src='item.src'>
        </div>
    </div>
  </transition-group>
</div>

Другие вопросы по тегам