Appleの商品ページに使用されているスクロールに合わせて動画を再生するエフェクトを実装するスクリプト -Scrolleo

Appleの商品ページに使用されているスクロールに合わせて動画を再生するエフェクトを実装するスクリプト -Scrolleo

https://ift.tt/2XleygX

/* Scrolleo – make your video scroll with inertia

* MIT License – by Mark Teater

*/

(function(window, document, undefined) {

  “use strict”;

 

  var _Scrolleo = function(opts) {

    // Defaults

    this.acceleration = 0.08; //1 is fastest, 0 is slowest, 0.08 is default

    this.secondsPerScreen = null; //Set this to the length of the video. “1” is 1 second.

    this.additionalOffset = 0; //Add or subtract pixels to when the video will start. “10” means that the video will start 10px earlier.

    this.wrapperEl = null;

 

    // Override defaults

    if (opts) {

      for (var opt in opts) {

        this[opt] = opts[opt];

      }

    }

  };

 

  var targetScrollPos;

 

  _Scrolleo.prototype = {

    init: function() {

      var self = this;

      this.wrapper = document.querySelectorAll(this.wrapperEl);

 

      // get the location of the top of the page

      targetScrollPos = window.pageYOffset;

      Array.prototype.forEach.call(this.wrapper, function(wr) {

        // Set the pixelsPerSecond to the full duration of the video if nothing was set in the options

        if (self.secondsPerScreen === null) {

          self.wrapper[0].addEventListener(“loadedmetadata”, function() {

            self.secondsPerScreen = self.wrapper[0].duration;

            //recalculate values on video with new pixelsPerSecond

            self.distanceToTop = getElemDistanceToTop(elem);

            self.offsetFromTop = getOffsetFromTop(self.distanceToTop);

            self.pixelsPerSecond = getPixelsPerSecond();

          });

        }

 

        self.pixelsPerSecond = null;

        self.scrollPos = null;

        self.currentTime = null;

        self.offsetFromTop = null;

        self.distanceToTop = null;

 

        // https://ift.tt/q1Lb2u

        // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel

        (function() {

          var lastTime = 0;

          var vendors = [“ms”, “moz”, “webkit”, “o”];

          for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {

            window.requestAnimationFrame = window[vendors[x] + “RequestAnimationFrame”];

            window.cancelAnimationFrame = window[vendors[x] + “CancelAnimationFrame”] || window[vendors[x] + “CancelRequestAnimationFrame”];

          }

          if (!window.requestAnimationFrame)

            window.requestAnimationFrame = function(callback, element) {

              var currTime = new Date().getTime();

              var timeToCall = Math.max(0, 16 (currTime lastTime));

              var id = window.setTimeout(function() {

                callback(currTime + timeToCall);

              }, timeToCall);

              lastTime = currTime + timeToCall;

              return id;

            };

          if (!window.cancelAnimationFrame)

            window.cancelAnimationFrame = function(id) {

              clearTimeout(id);

            };

        })();

 

        // requestAnim shim layer by Paul Irish

        window.requestAnimFrame = (function() {

          return (

            window.requestAnimationFrame ||

            window.webkitRequestAnimationFrame ||

            window.mozRequestAnimationFrame ||

            window.oRequestAnimationFrame ||

            window.msRequestAnimationFrame ||

            function(/* function */ callback, /* DOMElement */ element) {

              window.setTimeout(callback, 1000 / 60);

            }

          );

        })();

 

        // Define functions to be used by Scrolleo

        var getElemDistanceToTop = function(elem) {

            //https://ift.tt/375PCP5

            var location = 0;

            if (elem.offsetParent) {

              do {

                location += elem.offsetTop;

                elem = elem.offsetParent;

              } while (elem);

            }

            return location >= 0 ? location : 0;

          },

          getOffsetFromTop = function(distanceToTop) {

            var offset = distanceToTop window.innerHeight + self.additionalOffset;

            return offset >= 0 ? offset : 0;

          },

          getPixelsPerSecond = function() {

            var pixelsPerSecond = (window.innerHeight + self.wrapper[0].clientHeight) / self.secondsPerScreen;

            return pixelsPerSecond >= 0 ? pixelsPerSecond : 0;

          },

          scrollHandler = function() {

            targetScrollPos = window.pageYOffset;

          },

          resizeHandler = function() {

            //recalculate values on resize

            self.distanceToTop = getElemDistanceToTop(elem);

            self.offsetFromTop = getOffsetFromTop(self.distanceToTop);

            self.pixelsPerSecond = getPixelsPerSecond();

          },

          scrollControl = function() {

            //what to do when scrolling

            self.scrollPos += (targetScrollPos self.offsetFromTop self.scrollPos) * self.acceleration;

            self.currentTime = self.scrollPos / self.pixelsPerSecond; //convert scrollPos from pixels to seconds to set self.currentTime

            self.wrapper[0].currentTime = self.currentTime;

            self.wrapper[0].pause();

          };

 

        // Get an element’s distance from the top of the page

        var elem = self.wrapper[0];

 

        // Calulate the initial size, distance, and offset of each scrolleo video

        self.distanceToTop = getElemDistanceToTop(elem);

        self.offsetFromTop = getOffsetFromTop(self.distanceToTop);

        self.pixelsPerSecond = getPixelsPerSecond();

 

        self.scrollPos = targetScrollPos self.offsetFromTop;

 

        wr.pause();

 

        // Use requestAnimationFrame to ensure the video is updating when the browser is ready

        window.requestAnimFrame(function render() {

          window.requestAnimFrame(render);

          // Only kickoff scrollControl if the scrollPos of element hasn’t reached targetScrollPos

          if (Math.round(self.scrollPos + self.offsetFromTop) != targetScrollPos) {

            scrollControl();

          }

        });

 

        window.addEventListener(“scroll”, scrollHandler, false);

        window.addEventListener(“resize”, resizeHandler, false);

      });

    }

  };

  window.Scrolleo = _Scrolleo;

})(window, document);

 

// Setup video 1

var scrolleo1 = new Scrolleo({

  acceleration: 0.08, // 1 = instant, 0 = never

  secondsPerScreen: 6, // Defaults to video duration

  additionalOffset: 100, // Positive starts the video later, negative starts earlier. default starts when top of video hits bottom of the screen

  wrapperEl: “#scrolleo-1” // id of the video you want to control

});

scrolleo1.init();

 

// Setup Video 2

var scrolleo2 = new Scrolleo({

  wrapperEl: “#scrolleo-2”

});

scrolleo2.init();

@memo

webデザイン

https://ift.tt/32SZmbW
via コリス https://coliss.com

November 15, 2019 at 09:26AM https://ift.tt/32SZmbW