maxwellito / vivus

JavaScript library to make drawing animation on SVG
MIT License
15.25k stars 1.13k forks source link

Coordinating draw with scroll #230

Closed benklocek closed 4 years ago

benklocek commented 4 years ago

Vivus version: v.0.4.4

Browser: Chrome 86

JSFiddle link : https://jsfiddle.net/dfq1gn2r/

I'm wondering if there is a way to coordinate the drawing to end within the window. Basically, I want to ensure that the animation is done before it scrolls out of sight.

Perhaps I need to have a shorter line, or adjust progress in some way?

maxwellito commented 4 years ago

So here is what I made:

var vivus = new Vivus('Layer_1', {
  duration: 10000000,
  type: 'sync',
  start: 'manual'
});

window.addEventListener('wheel', scrolling);

var progress = 0;
var dh = jQuery(document).height(); // document height
var wh = jQuery(window).height(); // window height
var eh = jQuery('#Layer_1').height(); // element height

function scrolling(e) {
  var elementoffsettop = jQuery("#Layer_1").offset().top;
  var windowsscrollpostion = jQuery(window).scrollTop();

  // Define where the scroll starts and end
  var scrollStart = elementoffsettop - wh;
  var scrollEnd = elementoffsettop + eh - wh/2; // I made it stop while at half screen
  var scrollDistance = scrollEnd - scrollStart;

  // Calcultate the progress
  var animProgress = (windowsscrollpostion - scrollStart)/scrollDistance
  animProgress = Math.min(1, Math.max(0, animProgress));

  // Little hack to ask for a rendering at frame request. 
  // Otherwise you trigger a re-draw at every scroll event. 
  // It should make the scroll/animation smoother
  requestVivusUpdate(animProgress); 
}

// The logic of all this is to request an animation frame
// and wait for keep the value updated until the frame
// is executed.
var requestVivusUpdateRAF = null;
var requestVivusUpdateVal = 0;
function requestVivusUpdate (progress) {
    requestVivusUpdateVal = progress;
  if (requestVivusUpdateRAF) {
        return;
  }
  requestVivusUpdateRAF = window.requestAnimationFrame(() => {
    console.log(requestVivusUpdateVal);
    requestVivusUpdateRAF = null;
    vivus.setFrameProgress(requestVivusUpdateVal);
  });
}

// Ok there might be some useless calls with value 0 and 1 while outside of the desired scroll
// Feel free to fix this ;-)

I dunno if this helps

benklocek commented 4 years ago

Yes! This is brilliant! Much less of a hit on the page, and stops just where it needs to.

Hero!!

maxwellito commented 4 years ago

😉 you're welcome!

benklocek commented 4 years ago

Hi there,

I'm working on writing this so I can trigger different animations while scrolling.

I have it working when I only have one SVG, but when I add another, both don't show. I'm certain vivus supports multiples on a page or am I missing something?

http://jsfiddle.net/benklocek/7aog23cj/