Now, let's move on to the animation itself. Like we did for the castle banners, we will use the TWEEN.js library:
- First, create a new startAnimation method that calculates a random animation duration and accepts a delay parameter:
methods: {
// ...
startAnimation (delay = 0) {
const vm = this
// Element width
const width = this.$el.clientWidth
// Random animation duration
const { min, max } = cloudAnimationDurations
const animationDuration = Math.random() * (max - min) + min
// Bing faster clouds forward
this.style.zIndex = Math.round(max - animationDuration)
// Animation will be there
},
}
The faster a cloud is, the lower its animation duration will be. Faster clouds will be displayed before slower clouds, thanks to the z-index CSS property.
- Inside the startAnimation method, calculate a random vertical position for the cloud and then create a Tween object. It will animate the horizontal position with a delay and set the position of the cloud each time it updates. When it completes, we will start another animation with a random delay:
// Random position
const top = Math.random() * (window.innerHeight * 0.3)
new TWEEN.Tween({ value: -width })
.to({ value: window.innerWidth }, animationDuration)
.delay(delay)
.onUpdate(function () {
vm.setPosition(this.value, top)
})
.onComplete(() => {
// With a random delay
this.startAnimation(Math.random() * 10000)
})
.start()
- In the mounted hook of the component, call the startAnimation method to begin the initial animation (with a random delay):
mounted () {
// We start the animation with a negative delay
// So it begins midway
this.startAnimation(-Math.random() *
cloudAnimationDurations.min)
},
Our cloud component is ready.
- Add some clouds to the main template in the world element:
<div class="clouds">
<cloud v-for="index in 10" :type="(index - 1) % 5 + 1" />
</div>
Be careful to pass a value to the type prop ranging from 1 to 5. Here, we use the % operator to return the division remainder for 5.
Here is what it should look like: