Zeitraffer-Animation mit Vue.js

Man nehme ein Set von Bildpfaden, mische dies mit Vue.js und erwecke dieses dann zum Leben.


Ich möchte euch in diesem Artikel zeigen, wie man in Handumdrehen eine Zeitraffer-Animation im Browser zaubern kann.

Vorbereitung

Zuerst benötigt ihr ein Set von Bildern. Achtet darauf, dass die Bilder nicht zu groß sind, da wir später im DOM binne weniger Millisekunden das src-Attribut eines <img>-Tags ändern.


In meinem Beispiel verwende ich Bilder von [placeholder.com](https://placeholder.com/)

Unser Markup

Ich setze auf die CDN-Version von Vue.js. Diese läuft out of the box und kann direkt im Browser benutzt werden. 😉

Im ersten Step legen wir eine index.html Datei an und füllen sie mit folgendem Inhalt:

<!DOCTYPE html>
    <html lang="de">
        <head>
            <meta charset="utf-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>Vue.js | Zeitraffer Tutorial von niklaskoehler.de</title>
            <style type="text/css">
                [v-cloak] {
                    display: none;
                }
            </style>
        </head>
    <body>
        <div id="timelapse-app" v-cloak>
            <div v-if="isLoadingImages">Bilder werden geladen…</div>

            <div v-else>
                <div v-if="images.length">
                    <img :src="images[currentImage]" alt="" />
                </div>

                <button @click="isPlaying = !isPlaying">{{ !isPlaying ? 'Start' : 'Stop' }}</button>
                <button @click="currentImage = 0">Reset</button>
            </div>
        </div>

        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
        <script src="timelapse.js"></script>
    </body>
</html>

Unsere App: Das Herzstück

Im nächsten Schritt legen wir eine timelapse.js Datei an.


Das Array `images: []` muss nun also nur noch mit euren Bildpfaden befüllt werden.

Ich habe zusätzlich noch beim mounted() unserer App einen Preloader eingebaut. So werden alle zu ladenden Bilder vorausgeladen. Wenn alle Bilder geladen sind, wird isLoadingImages auf false gesetzt und die App kann benutzt werden.

Die Magie des Ganzen liegt in der State-Variable currentImage. Diese ist letztendlich nur der Index unseres images-Array. In einer timeout()-Funktion wird der Index immer weiter hochgezählt, bis das Limit erreicht ist. Danach startet sich die Zeitraffer-Animation von selbst neu: Sprich, currentImage wird auf 0 gesetzt.

const timelapseApp = new Vue({
    el: '#timelapse-app',
    data: {
        isPlaying: false,
        isLoadingImages: true,
        currentImage: 0,
        images: [
            'https://via.placeholder.com/320x240.png?text=1',
            'https://via.placeholder.com/320x240.png?text=2',
            'https://via.placeholder.com/320x240.png?text=3',
            'https://via.placeholder.com/320x240.png?text=4',
            'https://via.placeholder.com/320x240.png?text=5',
            'https://via.placeholder.com/320x240.png?text=6',
            'https://via.placeholder.com/320x240.png?text=7',
            'https://via.placeholder.com/320x240.png?text=8',
            'https://via.placeholder.com/320x240.png?text=9',
            'https://via.placeholder.com/320x240.png?text=10',
        ],
    },
    mounted() {
        const promises = this.images.map((src) => {
            return new Promise((resolve, reject) => {
                const img = new Image();
                img.src = src;
                img.onload = resolve;
                img.onerror = reject;
            })
        });

        Promise.all(promises)
            .then(() => this.isLoadingImages = false)
            .catch(error => console.error(error));
    },
    methods: {
        play() {
            if (!this.isPlaying) return;

            if (this.currentImage < this.images.length - 1) {
                this.currentImage++;
            } else {
                this.currentImage = 0;
            }

            setTimeout(() => this.play(), 100);
        }
    },
    watch: {
        isPlaying(isPlaying) {
            if (!isPlaying) return;

            this.play();
        }
    }
});

Fertig

Und so schaut die Zeitraffer App dann aus:

Zeitraffer-Aufnahme der fertigen App

Viel Spaß beim "Zeitraffern" 🎞😉