Drag mouse events jittery - onmousemove - javascript

Working on a scrub bar for a chromeless player through youtube. I have the functionality working pretty much as Id like BUT when I click to drag the blue "seeker" button and drag it, it jumps back to its original position until I release the mouse click. Once I release, it starts the video at the appropriate position and draws the progress bar at the appropriate position too. code is here: http://jsfiddle.net/VysBU/1/
I also logged the position of the mouse and width of the progress bar (which is the part that jumps around) and the width values move consistently upward or downward on drag which doesn't make sense because visually, it jumps back and forth. Odd.
Any help is appreciated...if you need me to clarify something, let me know.
NOTE: just remembered...it tends to jump on vertical mouse movements only. ie, if i move the mouse horizontally without changing its vertical position at all, it 'animates' fine. if the vertical position does move, the 'animations' are erratic.

Check this out http://jsfiddle.net/sz4FF/
you need to stop the interval of
setInterval(animateProgress, 100);
when you begin seeking, and continue it when the seeking stops. The reason why it makes that jump is simply because animateProgress is called and sets the width of the playedBar and seeker.
I hastily added it to a global function (window.TEST_INTERVAL) just to check if it would work, and it does.
(how to initialize and clear the interval)
clearInterval(TEST_INTERVAL);
TEST_INTERVAL = setInterval(animateProgress, 100);
within seeking
function seeking(e){
clearInterval(TEST_INTERVAL);
within doneSeeking
function doneSeeking(e){
TEST_INTERVAL = setInterval(animateBuffer, 250);
UPDATE: IE8 and below problem
mousePos = e==undefined ? event.clientX : e.pageX;
//get the position of the mouse
//mousePos = e.pageX;
the event returned by onmousemove is "undefined" in ie7 and 8, that way we are checking for window.event.clientX, which shows the mouse position relative to the window. It seems to work fine but I believe that in a normal environment some minor tweaks might be needed

Related

Using ScrollY on iOS gives strange values after bounce on bottom

I am using the window.scrollY event listener to get the scroll amount on my page and I set an animatino fram accordingly:
scroll = window.scrollY //inside the event listener
...
function animationLoop() {
...
scrollRatio = scroll/window.innerHeight
animMixer.setTime(scrollRatio) // every page is a "second"
...
}
This works wonderfully on the desktop, and also on iOS on the first scroll forward through the page. But as soon as the page bounces at the end, the scroll value seems to jump around unnecessarily, ie there is a mismatch between the position in the webpage and the animation frame. The timing is off until I scroll back to the very top of the page. After that the downward scrolling works fine again.
What happens to the scrollY value after bounce? I can't figure out where the problem is. I've tried things like pageYOffset but the problem remains. Also the value of the scrollRatio is clamped.
I know that there are some issues with the bouncy behavior of webpages on iOS, but these are negative values at the top of the page.
Thanks for any pointers.

How to increase speed of mousemove/clientX/Y and applying a transform?

I have built a WordPress theme. I came across a website that created a div to follow the user's cursor. The div was enlarged smoothly when the user hovers over a button or a link.
I want to add this nice functionality as an optional feature.
I added a div to the web page, #ambition_cursor and added some basic styling. The div now shows like a blue circle. The circle has position fixed to the top left corner of the site. The position can be changed by adding a CSS translate property.
I managed to make it work with the following code:
var ambition_cursor = document.getElementById("ambition_cursor");
function ambition_mouse(e) {
var ambition_cursor_x = e.clientX; // Get the horizontal coordinate
var ambition_cursor_y = e.clientY; // Get the vertical coordinate
var ambition_cursor_pos = `translate(${ambition_cursor_x}px, ${ambition_cursor_y}px)`;
ambition_cursor.style.transform = ambition_cursor_pos;
}
window.addEventListener('mousemove', ambition_mouse);
The big downside here is the lag (?). There's quite a big delay, especially when moving the mouse around very fast. You can try it out on this site. I also put the situation in a JSFiddle; although the delay doesn't really happen there.
I didn't apply yet much styling (the default cursor is visible, so you can get a better idea of the real position). I first want this to work better, before I spent much time on that.
How can I increase the speed of this, so that the div position follows the mouse more accurately? I'm a beginner, so I don't really know which JavaScript optimisations I should make.
Current code is JavaScript, but jQuery is also an option.
Many thanks in advance!
Update: example how it looks on my computer.
All elements on the page have a transition applied. Remove/override this style and the delay goes away (tested).
As an alternative to the great answer of Joseph Atkinson:
var ambition_cursor = document.getElementById("ambition_cursor");
function ambition_mouse(e) {
ambition_cursor.style.left = e.clientX + 'px'; // Get the horizontal coordinate
ambition_cursor.style.top = e.clientY + 'px' ; // Get the vertical coordinate
}
window.addEventListener('mousemove', ambition_mouse);
See: https://levelup.gitconnected.com/use-javascript-to-make-an-element-follow-the-cursor-3872307778b4
I visited the site example, cracked open the dev console, and found throttled(20, ambition_mouse) It is not a performance issue, and the solution is to not throttle the events. It was too smooth to be a performance issue, which gave me the first clue it had to be an accidental/deliberate effect.

javascript addEventListener "wheel" for element still scrolls window

I have the following javascript code, which triggers when a user wants to view a large image:
var divOverlay = document.getElementById ("overlay");
divOverlay.style.visibility = "visible";
divOverlay.addEventListener ("wheel", zoom); // respond to mouse wheel
The function zoom() is working fine. It handles events from the mouse wheel and zooms in or out for the image, contained in "overlay".
The problem is that the mouse wheel events are also causing scrolling of the whole browser window. I want the mouse wheel events to go only to "overlay".
I have tried adding this:
origOnWheel = window.onwheel;
window.onwheel = function() { return false; }
followed, later, with restoring window.onWheel when the user is done. That partially works: it prevents the window from scrolling then the user is zooming "overlay". However, when the user finishes (and window.onWheel is restored), the main browser window no longer scrolls with the mouse wheel.
It will be a bit hard to give a complete (working) example without a working jsfiddle, but here are the guidelines:
Inside the zoom function - when you want to prevent the regular scroll of the page - you should use event.preventDefault()
You will need to decide if you want to disable the default scroll - basically this will be based on the height of the image vs. the height of the window (window.innerHeight). In case the height of the image is larger - you should not use the event.preventDefault() or do the prevent default and set the window.scrollTo(x, y) where the y should be the height of image - the height of the window (this will scroll to the bottom of the image).

Vertical scroll on mobile - hammer.js element in page

There are a million similar questions but I can't find an answer that works for me.
Here is the situation:
I have an HTML page, and within that page is an element that I am using hammer.js on.
Need to be able to scroll like this:
--->
While also being able to pinch-to-zoom (and subsequently pan on that zoomed element) on the seating chart element above.
The element itself works perfectly. I'm using doubletap, pinch, pinchend, pan, and panend on it.
Now, in the event that the element is totally zoomed out (I'm keeping track of the scale for this reason), I would like the entire page to scroll when using it on a mobile browser (aka the finger will be dragging the page up).
I have tried almost everything under the sun at this point. I can't seem to get it to manually scroll to a specific position (I have tried setting window.scrollTop and using window.scrollTo() with no results).
If someone could point me in the right direction, I'll worship you and your family for the next...say....13 days. Heck, maybe even 14.
TL;DR
- Have we pinch zoomed on the element? If so, handle panning around that element with glee!
- Are we fully zoomed out / pinched out on the element? If so, mobile users should be able to scroll the page like normal!
Thanks
Chris
You may try window.scrollTo to "simulate" normal scroll. Like so:
var currentScroll = 0;
var currentScale = 1; //"fully zoomed out" state
hammer.on("panstart", function (ev) {
currentScroll = window.scrollY;
});
hammer.on("pan", function(ev) {
if (currentScale == 1) {
//abort pan and scroll window instead
window.scrollTo(0, currentScroll + ev.deltaY * -1);
return;
}
//do stuff with pan here...
});

jQuery's $(selector).position().left Sometimes Fails in Firefox, Chrome Browsers

I have a content slideshow:
slide container
|--> wrapper
|------> slide1, slide2, etc.
that works as simple as calculating wrapper's position X and slide's position X to determine where to slide the wrapper for the next/previous slide to show up within container's viewport. It's pretty straight forward.
For Firefox and Chrome I am using CSS3 transform and transition-duration to animate the slides. Everything works perfect. Almost.
The problem is only when I click next button very fast. I am using jQuery's
$(selector).position().left
to read the slide's position X (left) and position becomes 0 (instead of expected, say, 300px). I do have a flag isAnimating to prevent users from going too fast but that does not help either. It does prevent from scrolling content too fast but position left may still be 0 as if something else is causing it to fail to determine.
I did a brief search and discovered that if it was image being loaded, some browsers would fail to determine its position until loading is over. However, each slide has an image but inside of it. The slide's CSS seems to have all widths and margins set fine.
The question is why may this be happening based on the scenario I described and possibly what can be improved to determine position X at all times for Firefox, Chrome browsers?
I've decided that if offsetLeft is not reliable for me at all times, I could use width of an element and its index position within container to figure out position X
var newWrapperPos = undefined;
$(lotWrapper).children('div').each(function(index){
if($(this).attr("id") === "slot"+id){
var width = $(this).width();
newWrapperPos = index * width;
return false;
}
});
//now I can shift wrapper to position = newWrapperPos
Sorry I couldn't share the code - it is a bit time consuming to rip off all pieces of functionality involved. But if somebody has a better answer, let me know. For now this works fine for me.

Categories