добавить эффект перехода в vue на backgroundImage - PullRequest
0 голосов
/ 22 апреля 2020

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

Вот фрагмент кода, который я тестировал на:

new Vue({
  el: "#main",
  data: {
    images: [
      "https://images.freeimages.com/images/large-previews/bfd/clouds-1371838.jpg",
      "https://images.freeimages.com/images/large-previews/ffa/water-lilly-1368676.jpg",
      "https://images.freeimages.com/images/large-previews/efb/lotus-flower-1382251.jpg"
    ],
    current: 0,
    show: false
  },
  methods: {
    changeBG: function () {
      if (this.current < this.images.length - 1) {
        this.current = this.current + 1;
      } else {
        this.current = 0;
      }
    }
  }
});
.main {
  height: 800px;
  width: 100%;
  margin-left: auto;
  margin-right: auto;
  z-index: 0;
  background-repeat: no-repeat;
  background-size: cover;	
  background-position: center 0px; 
} 
button {
  width: 200px;
  height: 25px;
  margin: 10px; 
}
p.hello{
  color: white;
  margin: 10px;
  font-size: 50px;
}

.fade-enter-active,
.fade-leave-active {
  transition: all 2s linear;
}

.fade-enter-to,
.fade-leave {
  opacity: 0;
}

.fade-enter,
.fade-leave-to {
  opacity: 1;
}

/* hello example transition */
.slide-fade-enter-active {
  transition: all 1s ease;
}
.slide-fade-leave-active {
  transition: all 1s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter,
.slide-fade-leave-to {
  transform: translateX(10px);
  opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<transition name="fade">
  <div v-if="changeBG" class="main" id="main" :style="{ backgroundImage: 'url(\'' + images[current] + '\')' }">
    <button v-on:click="changeBG">
      changeBG
    </button>
    <div id="testFromGuide">
      <button @click="show = !show">
        toggleHello
      </button>
      <transition name="slide-fade">
        <p class="hello" v-if="show">all your base are belong to us</p>
      </transition>
    </div>
  </div>
</transition>

Мой первый вопрос, возможно ли это просто? Причина, по которой я использую backgroundImage, заключается в том, что веб-сайт, на котором я использую это, имеет фон, с которым легче всего реагировать быстро (всегда закрывая, не повторяя и сохраняя его в центре). И мой интересный вопрос, если нет, есть ли возможность заставить его работать с заданным фоном, как описано здесь ?

В коде ручки я добавил пример vue руководство , чтобы убедиться, что оно работает, и ничего больше не так. И пример работает отлично. Не могу найти ответ для моего примера, но я начинаю подозревать, что это просто невозможно, или я не могу понять, почему vue не обнаруживает, что что-то меняется.

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Для Vue Переходы на работу, вам нужно изменить элементы DOM. Таким образом, этот способ будет работать, если вы меняете реальные изображения. В вашем примере вы меняете только значение атрибута. DOM не запускает переход, так как это один и тот же элемент.

Однако вы можете использовать атрибут :key, чтобы убедить VUE заменить элемент, тем самым предоставляя вам переход между двумя элементами.

Вы также можете установить изображение со строчкой CSS, как вы делаете в примере. Вам все равно придется создать переход в вашем CSS.

. Вот пример использования Vue Transition

new Vue({
  el: "#main",
  data: {
		currentID: 0,
    images: [
'https://images.freeimages.com/images/large-previews/efb/lotus-flower-1382251.jpg',
'https://images.freeimages.com/images/large-previews/ffa/water-lilly-1368676.jpg',
'https://images.freeimages.com/images/large-previews/bfd/clouds-1371838.jpg'
		]
  },
  methods: {
    toggleImage: function(){
       if(this.currentID < this.images.length-1){
				 this.currentID +=1
			 } else {
				 this.currentID = 0
			 } 	   
    }
  }
});
body {
  overflow: hidden;
}

.main {
  position: relative;
}

img {
  width: 100%;
  height: auto;
  display: block;
  position: absolute;
  -webkit-transition: all 3s ease;
  transition: all 3s ease;
}

button {
  z-index: 100;
  position: relative;
  width: 200px;
  height: 25px;
  margin: 20px;
}

/* prefix with transition name */
.slide-fade-enter-active {
  opacity: 1;
  z-index: 10;
}

.slide-fade-leave-active {
  opacity: 1;
}

.slide-fade-enter,
.slide-fade-leave-to {
  opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div class="main" id="main">
    <transition name="slide-fade">
<!-- 			SRC comes from the array of images the :key is important for vue to believe its a 'new' DOM element and do the transition -->
      <img v-bind:src="images[currentID]" v-bind:key="currentID" />
    </transition>
	<button @click="toggleImage">
      Toggle Image
    </button>
</div>

Однако вы не можете контролировать это, поскольку он использует теги изображений. Вместо этого может быть лучше использовать фоновое изображение, как это:

new Vue({
  el: "#main",
  data: {
		currentID: 0,
    images: [
'https://images.freeimages.com/images/large-previews/efb/lotus-flower-1382251.jpg',
'https://images.freeimages.com/images/large-previews/ffa/water-lilly-1368676.jpg',
'https://images.freeimages.com/images/large-previews/bfd/clouds-1371838.jpg'
		]
  },
  methods: {
    toggleImage: function(){
       if(this.currentID < this.images.length-1){
				 this.currentID +=1
			 } else {
				 this.currentID = 0
			 } 	   
    }
  }
});
.main {
  /* make this the size of the window */
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

.theImage {
  width: 100%;
  height: 100%;
  position: absolute;
  background-color: #333;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center center;
  -webkit-transition: all 3s ease;
  transition: all 3s ease;
}

button {
  z-index: 100;
  position: relative;
  width: 200px;
  height: 25px;
  margin: 20px;
}

/* prefix with transition name */
.slide-fade-enter-active {
  opacity: 1;
  z-index: 10;
}

.slide-fade-leave-active {
  opacity: 1;
}

.slide-fade-enter,
.slide-fade-leave-to {
  opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div class="main" id="main">
    <transition name="slide-fade">
<!-- 			SRC comes from the array of images the :key is important for vue to believe its a 'new' DOM element and do the transition -->
			<div class="theImage" v-bind:style="{'background-image': 'url(' + images[currentID] + ')'}" v-bind:key="currentID"></div>
    </transition>
	<button @click="toggleImage">
      Toggle Image
    </button>
</div>
0 голосов
/ 22 апреля 2020

Ответ действительно заключался в том, чтобы забыть о vue переходах и позволить css сделать работу. Рабочий пример можно найти здесь:

new Vue({
  el: "#main",
  data: {
    show: false,
    BG1: true,
    BG2: false,
    BG3: false
  },
  methods: {
    changeBG: function(){
    	if (this.BG1 == true){
				this.BG1 = false;
				this.BG2 = true;
        this.BG3 = false;
			} else if (this.BG2 == true) {
				this.BG1 = false;
				this.BG2 = false;
        this.BG3 = true;
			} else if (this.BG3 == true) {
				this.BG1 = true;
				this.BG2 = false;
        this.BG3 = false;
			}       
    },
    showBG1: function(){
			if (this.BG1 == true){
				return "";
			} else {
				return "transparent";
			}
    },
    showBG2: function(){
			if (this.BG2 == true){
				return "";
			} else {
				return "transparent";
			}
    },
    showBG3: function(){
			if (this.BG3 == true){
				return "";
			} else {
				return "transparent";
			}
    }    
  }
});
.main {
} 

#bgs img.transparent {
  opacity:0;
  transform: translateY(-0.0px);
}

#bgs img{
  /* Set rules to fill background */
  min-height: 100%;
  min-width: 1024px;
	
  /* Set up proportionate scaling */
  width: 100%;
  height: auto;
	
  /* Set up positioning */
  position: fixed;
  top: 0;
  left: 0;
  
  z-index: -1;
  -webkit-transition: all 0.5s ease-in-out;
  -moz-transition: all 0.5s ease-in-out;
  -o-transition: all 0.5s ease-in-out;
  transition: all 0.5s ease-in-out;    
}

@media screen and (max-width: 1024px) { /* Specific to this particular image */
  #bgs img{
    left: 50%;
    margin-left: -512px;   /* 50% */
  }
}

button {
  z-index: 100;
  position: relative;
  width: 200px;
  height: 25px;
  margin: 20px; 
}
p.hello{
  color: white;
  margin: 40px;
  font-size: 50px;
}

.fade-enter-active {
  transition: all 1s ease;
}
.fade-leave-active {
  transition: all 1s ease;
}
.fade-enter, .fade-leave-to{
  transform: translateY(-5px);
  opacity: 0;
}

/* hello example transition */
.slide-fade-enter-active {
  transition: all 1s ease;
}
.slide-fade-leave-active {
  transition: all 1s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter,
.slide-fade-leave-to {
  transform: translateY(-5px);
  opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div class="main" id="main">
  <div id="bgs">
    <img :class="showBG1()" src="https://images.freeimages.com/images/large-previews/efb/lotus-flower-1382251.jpg">
    <img :class="showBG2()" src="https://images.freeimages.com/images/large-previews/ffa/water-lilly-1368676.jpg">
   <img :class="showBG3()" src="https://images.freeimages.com/images/large-previews/bfd/clouds-1371838.jpg">
  </div>
  <button @click="changeBG">
    changeBG
  </button>
  <div id="testFromGuide">
    <button @click="show = !show">
      toggleHello
    </button>
    <transition name="slide-fade">
      <p class="hello" v-if="show">all your base are belong to us</p>
    </transition>
  </div>
</div>

Это еще не идеально, так как для каждого дополнительного фона мне нужно добавить функцию и добавить дополнительный , если еще l oop к функции changeBG. Было бы более элегантно, если бы это можно было сделать с помощью переменной списка, но я не нашел способа заставить это работать с методом: class. Я надеюсь рассмотреть это позже.

...