javascript - How to adjust a Greensock.js tween based on browser scroll y position rather than by the time? - Stack Overflow

admin2025-04-18  0

How would I go about adjusting the time manually based on the scroll position? What might that look like? To basically 'scroll' the tween? So that the tween reacts to the scrolling mouse's Y position rather than just trigger and execute based on a preset time?

How would I go about adjusting the time manually based on the scroll position? What might that look like? To basically 'scroll' the tween? So that the tween reacts to the scrolling mouse's Y position rather than just trigger and execute based on a preset time?

Share asked May 19, 2015 at 1:38 Agent ZebraAgent Zebra 4,5506 gold badges37 silver badges70 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

IMHO, here is what you'll need to do:

  1. You will need TimelineMax for sequencing your animations. Place your animations in TimelineMax as you like them to be.
  2. You'll need to figure out the maximum scroll position your window can scroll up to, beforehand. (This can also be re-calculated on browser resize as well but I haven't taken this into account in my example below). You can figure out with the help of this answer. Also read the ments on that answer.
  3. Upon scroll, you'll need to convert the current scroll position of your window object into percentage that is: var currentScrollProgress=window.scrollY/maxScroll; such that your currentScrollProgress should always be between 0 and 1.
  4. TimelineMax has a progress() method which takes values ranging from 0 and 1 where 0 being the initial state of the animations and 1 being the final state. Feed this currentScrollProgress into it and you're done.
  5. OR, you can tween the timeline itself that is: TweenMax.to(timeline,scrollTweenDuration,{progress:currentScrollProgress,ease:ease});.

Code used in my example is as follows:

HTML:

<div>&nbsp;</div>
<div>&nbsp;</div>
...

CSS:

html, body { margin: 0; padding: 0; }
div { width: 100%; height: 60px; margin: 2px 0; }
div:nth-child(odd) { background: #cc0; }
div:nth-child(even) { background: #0cc; }

JavaScript:

/*global TweenMax, TimelineMax,Power2*/
var myDIVs=document.querySelectorAll('div'),numDIVs=myDIVs.length;
var timeline=new TimelineMax({paused:true}),duration=.4,ease=Power2.easeOut,staggerFactor=.1,scrollTweenDuration=.4;
var scrollTimeout=null,scrollTimeoutDelay=20,currentScrollProgress=0;
var maxScroll=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight)-window.innerHeight; //see [https://stackoverflow./a/17698713/3344111]
function init(){
    initTimeline();
    listenToScrollEvent();
    onScroll();
}
function initTimeline(){
    for(var i=0; i<numDIVs; i+=1){ timeline.fromTo(myDIVs[i],duration,{opacity:0},{opacity:1,ease:ease},i*staggerFactor); }
}
function listenToScrollEvent(){
    (window.addEventListener)?window.addEventListener('scroll',debounceScroll,false):window.attachEvent('onscroll',debounceScroll);
}
function debounceScroll(){
    clearTimeout(scrollTimeout);
    scrollTimeout=setTimeout(onScroll,scrollTimeoutDelay);
}
function onScroll(){
    currentScrollProgress=roundDecimal(window.scrollY/maxScroll,4);
    //timeline.progress(currentScrollProgress); // either directly set the [progress] of the timeline which may produce a rather jumpy result
    TweenMax.to(timeline,scrollTweenDuration,{progress:currentScrollProgress,ease:ease}); // or tween the [timeline] itself to produce a transition from one state to another i.e. it looks smooth
}
function roundDecimal(value,place){ return Math.round(value*Math.pow(10,place))/Math.pow(10,place); }
//
init();

Here is the resulting jsFiddle. Hope it helps.

T

While Tahir's answer is correct and sufficient, there's a lot of unnecessary code to show the example.

A more concise snippet is:

var max_scroll = document.body.offsetHeight - window.innerHeight;

win.addEventListener('scroll', function(){
    var scroll_perc = parseFloat(Math.min(window.pageYOffset / max_scroll, 1).toFixed(2));

    TweenMax.to(tl, 0, {
        progress: scroll_perc
    });
});

var tl = new TimelineMax({paused: true});
// the rest of your timeline....
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1744932117a275220.html

最新回复(0)