I made a click and drag scrolling Image Viewer here.
It works like a charm in FF and Chrome, but IE is behaving weird. The diagonal movement is jagged, as if the scrolling is slow and every movement is seperately visible.
I'm scrolling the DIV like this (viewPort is a jQuery object).
viewPort[0].scrollTop = newy;
viewPort[0].scrollLeft = newx;
Is anybody able to create a smooth movement in IE9 and IE10?
Edit:
I'm using IE10 on Windows 7. I've seen it working on IE10 on Windows 8.
It is always a good practice, when dealing with mousemove/touchmove, to apply UI changes in a requestAnimationFrame callback. Consider this jsfiddle
I am not sure if this helps, but it is definitely some better approach.
There is event better solution with transforms. You apply for an image position:absolute styles and for the container overflow:hidden and position:relative. After that, you change not the scrollLeft/scrollTop of the container, but translate(Xpx,Ypx) for the image itself.
Related
If anybody could help me, I would greatly appreciate it. I am using requestAnimationFrame() to apply a vertical translate on an element with CSS, and I want the vertical translate distance to relate to the vertical scroll position. My issue is that it seems like some frames either do not call my function or do not repaint with the updated CSS when using the scroll wheel (testing with Chrome and Firefox, both up-to-date).
This is a trimmed down version (optimizations removed) to show the root of what I'm trying to do:
let sticky = document.getElementById('top');
function changePos() {
let position = window.scrollY;
sticky.style.transform = `translateY(${position}px)`;
window.requestAnimationFrame(changePos);
}
window.requestAnimationFrame(changePos);
You can see a full working demo on this upload. For some reason clicking and dragging the scrollbar doesn't miss any frames, but using the mouse wheel does. You may have to throttle CPU using dev tools to see the missed frames, or use an older computer or phone.
Thanks so much.
In the following fiddle, there is significant jitter while scrolling. The jitter is noticed only in Safari on Mac, while Chrome and Firefox scrolls the page smoothly.
https://jsfiddle.net/saptarshi17/akxuLL9x/
The jitter is a result of applying parallax effect on the first paragraph. The parallax is implemented by dynamically calculating the top css property triggered by scroll events. I am noticing this on Mac OSX El Capitan, not sure about Windows.
So far, I tried:
Added a mousewheel event-listener in addition to scroll as per this accepted answer on SO.
Tried wrapping the css("top", ...) function call within requestAnimationFrame()
Changed div from relative to absolute to avoid costly reflows.
Added preserve3d property to "hardware accelerate" position calculation as per some comments somewhere on SO.
Since 2 and 3 haven't helped, I assume the core issue has much to do with Safari's scroll implementation and less about frame-rate optimizations. There is a delay Safari's predictive rendering and the subsequent handler call which offsets the position. This results in 2 renders causing the jitter. While I understand Safari's intention behind the first render which works in most cases, this seems to be wrong in cases when the developer wants to override positioning. Maybe there is a way to tell Safari to disable the predictive rendering.
This issue seems to affect android only.
I'm working on a phonegap App for a client and I have a scrolling area using jQuery animate. However one of the nested divs doesn't move with it's parent div and stays fixed in position.
Again this issue only presents on android devices and works fine in desktop browsers and iOS.
Can anyone shed any light on what this may be?
Seems jQuery animate runs into issues with relatively positioned items, removed relative position and used margin and it seems to work now.
I've created a website with a parallax street scene. See here for an archived version.
It works just fine on all major desktop browsers, and Safari Mobile. It works fine in Mobile Firefox and Chrome for Android Beta also. However the default Android browser has issues with the scroll event. Let me be clear. Scrolling is not the issue. The div scrolls as required. The scroll event doesn't fire. This issue I experience on Honeycomb as well as ICS.
I'm not concerned about other mobile browsers because for mobile screen sizes one usually does not see the parallax scene; mediaqueries and conditional JavaScript loading take care of that. Responsive design and all that jazz.
Basically, I've written a parallise() jQuery plugin that positions each image based on its position and 'depth'. This function is bound to the scroll event.
On Android Browser, this event only fires at the start of the next touch, instead of continuously.
OK, so I thought that perhaps if I bound the function to touchstart, touchmove, and touchend events I would solve my issue. No cigar. Other touch events are also bugged. Applying the suggested workaround causes the events to fire, but as I have to e.preventDefault(), scrolling (the whole point of the exercise) is disabled.
What if I just poll the position of the stage div relative to the window div? Turns out that the position information is only updated at the start of the next touch.
I am at the end of my tether. Any help would be much appreciated.
Even if the touch events worked correctly on the bugged versions of Android, and you were then effectively able to track the native scroll position during a drag, this would be prone to error. For example, it wouldn't account for the momentum animation which happens after the touching has finished.
iOS and Android make sacrifices to improve the performance of scrolling. On both platforms, it's not possible to get the accurate scroll position until the scroll has completed. The scroll event (on the <body>) doesn't fire until the momentum animation is finished. So while your original question is about scroll events on an overflowing <div>, fixing this might not be totally helpful for you anyway.
If you want an animation to update in time with the scroll, then you need to perform the scroll programatically rather than using the browser's native scroll. The best library to do this is iScroll. You can achieve parallax effects very easily as seen in this demo.
If you need more complex effects (the walking character, in your example), you can opt for the "probe" version of iScroll which allows pixel-perfect polling of scroll position in return for reduced performance.
However, there are many downsides to using iScroll:
You may need to change your markup and styling
It is unnecessary overhead for desktop browsers, but due to markup changes may be difficult to use only as a fallback
The scrolling will not feel perfect - on iOS, with its usually excellent scrolling performance - the slight difference in momentum calculation can feel jarring. On Android, the scrolling can become more laggy than usual.
Swipe shim that doesn't need preventdefault on touchstart: https://github.com/TNT-RoX/android-swipe-shim
I have implemented scrolling of a div by using relative positioning and webkit animation for the iphone, it works beautifully on desktop safari but is choppy on the actual iphone (fine on the simulator).
The scrolling works by having a div nested and clipped (overflow:hidden) by its parent. I then set the top position and animate it with -webkit style declarations. The iphone seems to noticeably slow down when there are a lot of items in the inner div.
Any ideas how make the scrolling smoother?
This was a problem with iScroll code and my own hand coded stuff.
Using translate3d is much faster than straight up translate, as it utilizes hardware acceleration.