janpaepke / ScrollMagic

The javascript library for magical scroll interactions.
http://ScrollMagic.io
Other
14.88k stars 2.17k forks source link

autorefresh scenes on resize AND turn off for mobile #698

Closed zucoa closed 7 years ago

zucoa commented 7 years ago

Hello - fantastic plugin! I've been combing through the issues that would address the following:

  1. turn off scroll magic on mobile AND
  2. refresh my scenes on resize without having to hit the browser reload button

I'm developing my app within a bootstrap framework and came across these issues where I implemented code from 15 (#15 and #38) though the latter isn't something I'm completely grasping for my app.

The first scene is applied to 20 or sections throughout my app and everything works fine with regard to number 1 above, with the problem that I have to reload the page on browser resize. Any thoughts on getting both of the above to work together?

`

    var tooSmall = false;
    var controller = null;
    var maxWidth = 768; // sizes above maxWidth will turn on scroll magic

    if( $(window).width() < maxWidth ) {
        tooSmall = true;
    }
    var controller = new ScrollMagic.Controller();
    function initScrollMagic() {
        $('body').scrollTop( 0 );
        controller = new ScrollMagic.Controller();
        // add your ScrollMagic scene goodness here

        // loop through all elements with a class of fadein-trigger  https://www.youtube.com/watch?v=c85GjM7vy5A
        $('.fadein-trigger').each(function(){
            // Tween
            var fadein_tween = TweenMax.from($(this), 1.5,{ autoAlpha: 0, ease:Power1.easeIn});
            // Scene
            var fadein_scene = new ScrollMagic.Scene({
              triggerElement: this, // this refers to the .fadein-trigger class
              triggerHook: 1, // or use a value between 0 and 1; 0 = top, .5 = middle, 1 = bottom
              reverse: false // when false the animation will only play once
            })
            .setTween(fadein_tween) // trigger TweenMax tween
            .addTo(controller);
        });

        var download_scene = new ScrollMagic.Scene({
            triggerElement: '.summary_scrollmagic',
            triggerHook: 0,
            duration: 500
        })
        .setClassToggle("#scrollmagic-class", "active")
        //.addIndicators()  for debugging
        .addTo(controller);
    }

    if( !tooSmall ) {
        initScrollMagic();
    }

    // part of the problem is that window resizes can trigger multiple times as the events fire rapidly
    // this solution prevents the controller from being initialized/destroyed more than once
    // https://github.com/janpaepke/ScrollMagic/issues/15
    $(window).resize( function() {
        var wWidth = $(window).width();
        if( wWidth < maxWidth ) {
            if( controller !== null && controller !== undefined ) {
                // completely destroy the controller
                controller = controller.destroy( true );
                // if needed, use jQuery to manually remove styles added to DOM elements by GSAP etc. here
            }
        } else if( wWidth >= maxWidth ) {
            if( controller === null || controller === undefined ) {
                // reinitialize ScrollMagic only if it is not already initialized
                initScrollMagic();
            }
        }
    });
`
zucoa commented 7 years ago

Ended up using isMobile.js simplifying the code quite a bit.

     jQuery( document ).ready( function($) {
        if (isMobile.any) return;

        var controller = new ScrollMagic.Controller();

        // loop through all elements with a class of fadein-trigger  https://www.youtube.com/watch?v=c85GjM7vy5A
        $('.fadein-trigger').each(function(){
            // Tween
            var fadein_tween = TweenMax.from($(this), 1.5,{ autoAlpha: 0, ease:Power1.easeIn});
            // Scene
            var fadein_scene = new ScrollMagic.Scene({
              triggerElement: this, // this refers to the .fadein-trigger class
              triggerHook: 1, // or use a value between 0 and 1; 0 = top, .5 = middle, 1 = bottom
              reverse: false // when false the animation will only play once
            })
            .setTween(fadein_tween) // trigger TweenMax tween
            .addTo(controller);
        });

        var download_scene = new ScrollMagic.Scene({
            triggerElement: '.summary_scrollmagic',
            triggerHook: 0,
            duration: 500
        })
        .setClassToggle("#scrollmagic-class", "active")
        //.addIndicators()  for debugging
        .addTo(controller);

    });
woodybepierced commented 6 years ago

@zucoa Do you have a live example, or Fiddle, of this working?

I have yet to use isMobile. Does "if (isMobile.any) return;" stop JS from running any further at that point?

As well, in your trimmed down code, I don't see the .resize function. How did you finalize this working?

shikkaba commented 4 years ago

@zucoa You could reset the page programmatically to achieve the point reset. I realize you'd said without hitting the reset button, but the user wouldn't have to physically hit the button, and the majority of the time they wouldn't be able to tell other than some elements changing position. Ideal? Probably not.

zucoa commented 4 years ago

@woodybepierced and @shikkaba - so sorry for not responding! Our scrollmagic usage has gone through several revisions since first reported. Lines 70 - 270 here show the current implementation: https://github.com/USEPA/Air-Trends-Report/blob/d7133683a24c8760e78f678f4bce58618e61c229/etrends_2019/src/js/etrends_structure.js#L70

shikkaba commented 4 years ago

@zucoa Thank you for showing this. Looking at how you wrote your code, and looking at other people's implementations really helped. I managed to get one going WITHOUT just refreshing the scene, which is awesome because then that reset can be used if a scene height is changed via ajax as well.

If anyone is wondering, this was my solution: https://codepen.io/shikkaba/pen/bGGPwWj Any advice on cleaning up the code is greatly appreciated.