📅  最后修改于: 2022-03-11 15:01:46.980000             🧑  作者: Mango
// detect if browser firefox as it appears to be the only
// browser that return deltaModes different than DOM_DELTA_PIXEL
// Ref: https://stackoverflow.com/a/37474225/4146962
var FF = !(window.mozInnerScreenX == null);
// Function grabbed from the reference above
// It tries to read current line-height of document (for 'lines' deltaMode)
function getScrollLineHeight() {
var r;
var iframe = document.createElement('iframe');
iframe.src = '#';
document.body.appendChild(iframe);
var iwin = iframe.contentWindow;
var idoc = iwin.document;
idoc.open();
idoc.write('a');
idoc.close();
var span = idoc.body.firstElementChild;
r = span.offsetHeight;
document.body.removeChild(iframe);
return r;
}
// html5 elements
var vid = document.getElementById("v"); // HTML5 video element
var canvas = document.getElementById("c"); // HTML5 canvas element
var context = canvas.getContext('2d'); // Canvas context
var momentum = document.getElementById('m'); // Current momentum display
var delta = document.getElementById('d'); // Current deltaMode display
var lineheight = document.getElementById('l'); // Current deltaMode display
// global variables
var ch = 120; // canvas with (could be window.innerHeight)
var cw = Math.round(ch * (16 / 9)); // 16/9 proportion width
var targetOffset = 0; // Video offset target position when scrolling
// deltaY to FPS coefficients (for fine tuning)
// Possible mouse scroll wheel 'event.deltaMode'
// modes are: 0:'pixels', 1:'lines', 2:'page'
var pc = 1000; // 'pixels' deltaY coefficient
var lh = "disabled"; //getScrollLineHeight(); // get line-height of deltaMode 'lines'
lineheight.value = lh; // display current document line height
coefficient = 30;
var deltaModes = ['pixels', 'lines', 'page']; // For deltaMode display
// Sets canvas dimensions
canvas.width = cw;
canvas.height = ch;
// Pauses video (this also starts to load the video)
vid.pause();
// Listens video changes time position
vid.addEventListener('seeked', function() {
// Updates canvas with current video frame
context.drawImage(vid, 0, 0, cw, ch);
});
// Listens mouse scroll wheel
window.addEventListener('wheel', function(e) {
// Don't do what scroll wheel normally does
e.preventDefault();
// You don't need an amount, just positive or negative value: -1, 1
var deltabs = 1;
if (e.deltaY<0) deltabs = -1;
// Disable page scrolling, modes[e.deltaMode]=='page'
if (e.deltaMode>1) return false;
delta.value = deltaModes[e.deltaMode];
// Normally scrolling this should be a subtraction
// not a sum but "I like it like this!"
// targetOffset = targetOffset + (e.deltaY / coefficient); // e.deltaY is the thing!!
targetOffset = targetOffset + (deltabs/coefficient);
// Shows current momentum
momentum.value = targetOffset;
return false;
});
// Updates canvas on a loop (both for play or pause state)
var renderLoop = function() {
requestAnimationFrame(function() {
// This parts updates canvas when video is paused
// Needs 'seeked' listener above
if (vid.paused || vid.ended) {
// Reduce target offset gradually
targetOffset = targetOffset * 0.9;
// Show current momentum
momentum.value = Math.round(targetOffset * 100) / 100;
// this part joins start and end of video when scrolling
// forward & backwards
var vct = vid.currentTime - targetOffset;
if (vct < 0) {
vct = vid.duration + vct;
} else if (vct > vid.duration) {
vct = vct - vid.duration;
}
vid.currentTime = vct;
// This parts updates canvas when video is playing
} else {
// update canvas with current video frame
context.drawImage(vid, 0, 0, cw, ch);
}
renderLoop(); // Recursive call to loop
});
};
renderLoop(); // Initial call to loop