I've been working in a web project that uses mouse scroll wheel for different actions over a video. At some point I have to establish a coefficient for the relation between the deltaY
and the number of frames that deltaY
should roll. So different types of mouses return very different deltaY
, specially smooth scroll ones.
In the fiddle I provide bellow this is done in:
targetOffset = targetOffset + (e.deltaY/1000); // 16000 aprox for smooth scroll mice
And 1000
is the coefficient that works well for a Notched Scroll Wheel common mouse. But if I use that coefficient with a Smooth Scroll Touch "wheel", like those of mac computers (that don't have a wheel really) that coefficient is "just too much", like 16 times "too much".
Is there something that could be done to detect this or to callibrate the coefficient in some way?
var FF = !(window.mozInnerScreenX == null); // is firefox?
var vid = document.getElementById("v");
var canvas = document.getElementById("c");
var context = canvas.getContext('2d');
var targetFrame = document.getElementById('t');
var cw = 200;
var ch = Math.round(cw/1.7777);
canvas.width = cw;
canvas.height = ch;
var directionScroll = 0;
var targetOffset = 0;
var coefficient = 1000;
var modes = ['pixels', 'lines', 'page'];
vid.pause();
vid.addEventListener('seeked', function() {
context.drawImage(vid, 0, 0, cw, ch);
});
window.addEventListener('wheel', function(e) {
e.preventDefault();
// Normally scrolling this should be a substraction
// not a sum but "I like it like this!"
// Changed this with help of @Kaiido 's answer as partially solves the discrepancies between Firefox and Chrome
// alert(modes[e.deltaMode]);
if (modes[e.deltaMode]=='pixels') coefficient = 1000;
else if (modes[e.deltaMode]=='lines') coefficient = 30; // This should correspond to line-height??
else return false; // Disable page scrolling, modes[e.deltaMode]=='page'
targetOffset = targetOffset + (e.deltaY/coefficient); // e.deltaY is the thing!!
if (e.deltaY < 0) directionScroll = 1;
if (e.deltaY > 0) directionScroll = -1;
targetFrame.value = targetOffset;
return false;
});
var renderLoop = function(){
requestAnimationFrame( function(){
context.drawImage(vid,0,0,cw,ch);
if (vid.paused || vid.ended) {
targetOffset = targetOffset*0.9;
targetFrame.value=Math.round(targetOffset*100)/100;
var vct = vid.currentTime-targetOffset;
if (vct<0) {
vct = vid.duration + vct;
} else if (vct>vid.duration) {
vct = vct - vid.duration;
}
vid.currentTime = vct;
}
renderLoop();
});
};
renderLoop();
.column {
float: left;
width: 50%;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
#c {
border:1px solid black;
}
<h3>
scroll up is forward
</h3>
<div class="row">
<div class="column">
<div>
Video element:
</div>
<video controls height="120" id="v" tabindex="-1" autobuffer="auto" preload="auto">
<source type="video/webm" src="https://www.html5rocks.com/tutorials/video/basics/Chrome_ImF.webm"></source>
</video>
</div>
<div class="column">
<div>
Canvas element:
</div>
<canvas id="c"></canvas>
<div>
Momentum: <input type=text id="t">
</div>
</div>
</div>
Any help appreciated.
Edit 1:
I've updated the code so that a simple condition is applied to the coefficient, but that does not quite solve the issue as many variants are posible due to browser/plattform/mouse. Some way of callibrate the mouse could work?
Edit 2:
@Kaiido 's answer turned to resolve Firefox and Chrome differences. Firefox returns lines
as deltaMode
while Chrome returns pixels
. I've edited the snippet to consider this.
But the problem still stands with the 'smooth scroll' mouse. To puzzle me even more, that mouse needs a coefficient opposite to the one of lines
, it needs a coefficient larger instead of smaller.