janpaepke / ScrollMagic

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

How to create a smoother, more robust animation? #786

Open ghost opened 6 years ago

ghost commented 6 years ago

I've used ScrollMagic on my portfolio site to animate the positions of various images. But the animations are somewhat clunky.

Here's the relevant js. How can I make the animations smoother and less resource-intensive?

var controller = new ScrollMagic.Controller();
$(function() {
    var xTo = 1.15*window.innerWidth;
    var yTo = 0.5*window.innerHeight;

var rocketTween = new TimelineMax().add([
    TweenMax.from("#parallaxContainer #bg", 1, {backgroundPosition:"0 100%", ease: Linear.easeNone}),
    TweenMax.from("#parallaxContainer #starsSmall", 1, {backgroundPosition:"0 12%", ease: Linear.easeNone}),
    TweenMax.from("#parallaxContainer #starsLarge", 1, {backgroundPosition:"0 6%", ease: Linear.easeNone}),
    TweenMax.to("#parallaxContainer #rocket", 1, {y:0, ease: Linear.easeNone}),
    TweenMax.to("#parallaxContainer #cloudsFront", 1, {y:0, ease: Linear.easeNone}),
    TweenMax.to("#parallaxContainer #cloudsBack", 1, {y:0, ease: Linear.easeNone}),
    TweenMax.to("#parallaxContainer #comet", 0.5, {x:-xTo, y:yTo, delay:0.5, ease: Linear.easeNone}),
    TweenMax.to("#parallaxContainer #logo", 0.8, {opacity:0, ease: Linear.easeNone}),
    TweenMax.to("#parallaxContainer #arrow", 0.07, {opacity:0})
]);

var scene = new ScrollMagic.Scene({
    triggerElement: "#parallaxContainer",
    triggerHook: 0,
    duration: "110%"})

    .setTween(rocketTween)
    .setPin("#parallaxContainer")
    .addTo(controller);
});

$(function() { 
    var controller = new ScrollMagic.Controller();
    var featuresTL = new TimelineMax();
        featuresTL.from("#standardsCon", 2, {x:-750, ease: Power2.easeInOut});
        featuresTL.from("#responsiveCon", 2, {x:750, ease: Power2.easeInOut}, '0');
        featuresTL.to("#featuresConImg", 1.5, {opacity:0}, '0.4');
    var scene1 = new ScrollMagic.Scene({
        triggerElement: '#featuresCon',
        triggerHook: 1,
        offset: 1,
        duration: 550
    });
        scene1.setTween(featuresTL);
        scene1.addTo(controller);

    var jordanFade = TweenMax.from($('#aboutMeImgCon'), 0.7, {autoAlpha:0, ease: Power2.easeIn});
    var scene2 = new ScrollMagic.Scene({
        triggerElement: '#aboutMeImgCon',
        triggerHook: 1,
        offset: 100,
        reverse: false
    });
    scene2.setTween(jordanFade);
    scene2.addTo(controller);
});

var controller2 = new ScrollMagic.Controller();

$('.portfolioSpacer div').each(function(){

var detailsFade = TweenMax.from($(this), 0.7, {autoAlpha:0, ease: Power2.easeIn});
var scene3 = new ScrollMagic.Scene({
    triggerElement: this,
    triggerHook: 1,
    offset: 80,
    reverse: false
});
    scene3.setTween(detailsFade);
    scene3.addTo(controller2);
});
BadgersNadgers commented 6 years ago

IM not sure if scroll-magic is being maintained anymore??? On another note, many people talk about reducing resource intense etc but and this maybe controversial but machines are getting faster and can process things in hardly anytime so why bother making code super slick?

Ok, yes it needs to be to an extent but not as much as it was in the past and many coders strive for days, weeks etc trying to make sublime code when in reality, the processing speed of even a basic mobile can handle a lot nowadays

ghost commented 6 years ago

@jwmcgavin You're animating some expensive properties like background-position or padding, try only animating with opacities and transforms instead and cache all relevant layers with will-change: transform.

@BadgersNadgers It's not controversial, it's naive.

petebarr commented 6 years ago

@mystrdat I was chatting with Jack from Greensock the other day and he was saying to not use will-change just now as it's a minefield and could cause more issues than it solves.

petebarr commented 6 years ago

@mystrdat https://greensock.com/will-change

ghost commented 6 years ago

@petebarr I've had success using it for transforms that do not scale or caching position fixed layers without transformations, to a large degree it seems to work like transform: translate3d(0). Despite the implementation complexity, they still recommend using it for transforms past Chrome 53:

Make sure to set will-change: transform if you're animating transforms and want to opt-in to performance optimizations and avoid jittery background-image scaling. But be careful about how it might affect stacking contexts, and keep checking when other browsers decide to implement will-change, as it could change how your content looks.

The stacking context problem is something Webkit broke back in the day when positions and transforms started always establishing contexts, it makes sense that the property creates its own too. I feel like the problem shows itself properly only if you start scaling elements above 1.

BadgersNadgers commented 6 years ago

@mystrdat hardly naive, most mobiles can handle plenty nowadays, working out the load you need to use is key, order of events. Have used load distribution etc for many years, no problems so not naive, tried and tests hundreds of times. Plan the project well so you can animate background images, use padding animation as-well no need to avoid them if you've planned properly, its naive not to.

ghost commented 6 years ago

@BadgersNadgers I'm afraid you're making sweeping statements about a complex system where one mechanism can perform really fast and the other not so much. That is the case with padding in HTML rendering, which modifies the element box model and triggers a recalculate for every update of the property.

Especially in more than simple demo cases, the performance will be far away from using transforms, which is instead a cached texture processed by the GPU. This is a complex topic overall, I suggest you do some research on animatable style properties, perhaps in comparison to canvas and WebGL animation. It is hard to make a HTML UI fly, even more so on mobile and Cordova-wrapped apps.

Complexity of performance in a HTML UI is the reason Facebook failed to deliver a good HTML5 experience back in the day: https://news.ycombinator.com/item?id=4507879

petebarr commented 6 years ago

I'm afraid I have to agree with @BadgersNadgers, try animating a border thickness and you can see how poor the animation experience is. Check this out as a frame of reference: https://css-tricks.com/animating-border/ . You can achieve so much with transforms, scale and opacity that I rarely go near anything else for UI animation, sometimes a height here or there but I try to avoid it if at all possible.

ghost commented 6 years ago

@petebarr Either you swapped the nicknames or I'm lost in the debate :suspect:

petebarr commented 6 years ago

I meant you @mystrdat lol! Sorry, brain is firing on 50% with the late nights of a deadline.