I am using Vue.js in my project. I have a background of images which are animated, they are moving from up to down. Everything connected to the random image, position and etc is inside created()
:
const vue = require("@/assets/images/vue.png");
const bootstrap = require("@/assets/images/bootstrap.png");
const bulma = require("@/assets/images/bulma.png");
export default {
name: "randImg",
data() {
return {
images: [
vue,
bootstrap,
bulma
],
addedImage: [],
imgTop: -100,
imgLeft: -100,
imgHeight: 64,
imgWidth: 64,
changeInterval: 250
}
},
created() {
const randomImg = func => setInterval(func, this.changeInterval);
randomImg(this.randomImage);
randomImg(this.addImage);
randomImg(this.randomPosition);
},
mounted: function () {
if (this.addedImage[i] = {
style: {display: `none`}
}) {
this.addedImage.remove(this.addedImage[i]);
}
},
methods: {
randomImage() {
const idx = Math.floor(Math.random() * this.images.length);
this.selectedImage = this.images[idx];
},
randomPosition() {
const randomPos = twoSizes => Math.round(Math.random() * twoSizes);
this.imgTop = randomPos(screen.height / 10 - this.imgHeight);
this.imgLeft = randomPos(screen.width - this.imgWidth);
},
addImage() {
if (this.addedImage.length > 500) {
this.addedImage.splice(0, 300);
} else {
this.addedImage.push({
style: {
top: `${this.imgTop}px`,
left: `${this.imgLeft}px`,
height: `${this.imgHeight}px`,
width: `${this.imgWidth}px`
},
src: this.selectedImage
});
}
}
}
}
css
.image {
position: fixed;
z-index: -1;
opacity: 0;
animation-name: animationDrop;
animation-duration: 5s;
animation-timing-function: linear;
animation-iteration-count: 1;
filter: blur(3px);
will-change: transform;
}
@keyframes animationDrop {
15% {
opacity: 0.2;
}
50% {
opacity: 0.4;
}
80% {
opacity: 0.3;
}
100% {
top: 100%;
display: none;
}
}
and html
<div class="randImg">
<img class="image" :style="image.style"
:src="image.src"
v-for="image in addedImage">
</div>
My site is lagging because images are adding to the DOM infinitely. The idea of my animation is that when my image is on keyframe 100% it will have display none. So I decide to simply create an if statement inside mounted()
but it doesn't work; I get the error message "ReferenceError: i is not defined".
How can I delete the images when their display become none?
Using v-if to remove images which style is
display: none
. And i think you can delete all code inmounted()
.You want each image to persist for five seconds (based on your animation-duration), and you're adding one image every 250ms (based on your changeInterval variable). This means that your image array needs to contain a maximum of twenty images, rather than the 500 you're currently limiting it to.
You could control this by modifying your addImage function to drop the oldest image before adding the newest one. (You're already doing this, except that you're waiting until five hundred of them have built up and then splicing off three hundred at once; better to do it one at a time:)
There's no need to read the display value from the DOM, you can just depend on the timing to ensure that the images aren't removed before they're supposed to; modifying the array is all that's necessary to remove the elements from the DOM. (You could harmlessly leave a few extra in the array length, just in case, but there's no need to go all the way to 500.)
mounted()
wouldn't be useful for this case because that function only runs once, when the component is first drawn onto the page, before there's anything in the addedImages array.