0

I have created animations that trigger when elements enter in viewport. Problem is that I have to repeat same code for every element. I'm using anime.js and scrollMonitor.js for animations, and it's kinda hard to make working for-loop.

Here is my code:

        $(window).on("load", function() {
            'use strict';

            var elementWatcher1 = scrollMonitor.create('#about', -200);
            elementWatcher1.enterViewport(function() {
                var startAnimation = anime.timeline();
                startAnimation
                    .add({
                        targets: '#about .toAnimate',
                        translateY: [50, 0],
                        opacity: 1,
                        duration: 600,
                        delay: function(el, index) {
                            return index * 80;
                        },
                        easing: 'easeOutQuad'
                    });
                this.destroy();
            });
            var elementWatcher2 = scrollMonitor.create('#portfolio', -200);
            elementWatcher2.enterViewport(function() {
                var startAnimation = anime.timeline();
                startAnimation
                    .add({
                        targets: '#portfolio .toAnimate',
                        translateY: [50, 0],
                        opacity: 1,
                        duration: 600,
                        delay: function(el, index) {
                            return index * 80;
                        },
                        easing: 'easeOutQuad'
                    });
                this.destroy();
            });
            var elementWatcher3 = scrollMonitor.create('#gallery', -200);
            elementWatcher3.enterViewport(function() {
                var startAnimation = anime.timeline();
                startAnimation
                    .add({
                        targets: '#gallery .toAnimate',
                        translateY: [50, 0],
                        opacity: 1,
                        duration: 600,
                        delay: function(el, index) {
                            return index * 80;
                        },
                        easing: 'easeOutQuad'
                    })
                    .add({
                        targets: '#gallery .toAnimateToo',
                        opacity: 1,
                        duration: 600,
                        delay: function(el, index) {
                            return index * 80;
                        },
                        easing: 'easeOutQuad',
                        offset: 0
                    });
                this.destroy();
            });
        });

Does anyone have idea how can I put this in for-loop?

RobiZzT
  • 231
  • 3
  • 17

1 Answers1

1

In ES5 just use a forEach loop on an array of those selectors:

$(window).on("load", function() {
    'use strict';

    ["#about", "#portfolio", "#gallery"].forEach(function(selector) {
        var elementWatcher = scrollMonitor.create(selector, -200);
        elementWatcher.enterViewport(function() {
            var startAnimation = anime.timeline();
            startAnimation
                .add({
                    targets: selector + ' .toAnimate',
                    translateY: [50, 0],
                    opacity: 1,
                    duration: 600,
                    delay: function(el, index) {
                        return index * 80;
                    },
                    easing: 'easeOutQuad'
                });
            this.destroy();
        });
    });
});

In ES2015+, you could use for-of instead (with const for elementWatcher) instead.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • *(If you see `'#about' + ' .toAnimate'` above, hit refresh. Editing error.)* – T.J. Crowder Nov 10 '17 at 15:49
  • I used .each() function, but ThemeForest recommends using for-loop instead, cause it's slightly faster. But I can't figure it out. For-loop only animates last element for "number-of-elements" times. – RobiZzT Nov 10 '17 at 15:53
  • @RobiZzT: You don't need to worry about performance in a single `forEach` call on a three-element array done once on the window `load` event. :-) (In fact, except in very rare extremely-performance-intensive code, you [don't have to worry about it at all](http://blog.niftysnippets.org/2012/02/foreach-and-runtime-cost.html).) As for why `for` didn't work, it's because of the [closures-in-loops issue](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example). – T.J. Crowder Nov 10 '17 at 16:01