I am using JVectorMap to create a map Page on my Website. However I found that the scrolling zoom speed is much to slow. How do I adjust the scroll speed? There is no documentation for this issue. I found this:
zoomStep: 1.6,
This is however to specify the zoom step for the buttons, not the scrolling.
Another issue that I have found is that I cannot set the height of the Map Container to:
window.innerHeight;
But i can however set the width to:
window.innerWidth;
How can I specify to Height of the Map container to be in relation to the Window size? I've also tried using a % value.
Thank you
this might be quite late answer, even might have been already answered somewhere.
But i got the same problem with mouse scroll speed and found the solution.
It can be fixed in js file in line 2382
zoomStep = Math.pow(1.003, event.deltaY);
You can easily change speed by changing that "1.003" value. More you make it - faster the scroll is.
I didnt fully understand the second problem of yours. But if it is about container height, I just use % values for the height. Make sure your parent has some height value as well.
Re. the scroll speed I agree that it is far too slow in 2.0.1.
I had a look into the js file and found some comments on line 234 - " If this is an older event and the delta is divisable by 120, then we are assuming that the browser is treating this as an older mouse wheel event and that we should divide the deltas by 40 to try and get a more usable deltaFactor. Side note, this actually impacts the reported scroll distance in older browsers and can cause scrolling to be slower than native. Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
On line 113 you will find the adjustOldDeltas set as true. I have set it as false but no change in the scroll speed.
Hopefully this works for you or gives you enough to explore the issue further.
W.
Related
I have a page where I'm applying a parallax effect. This is accomplished using translate3d. Now, while this works well, I'm wondering how I can override the default "steps" when scrolling with the mouse wheel?
If I scroll with the scrollbars, everything is fine. But with the mouse wheel, it's all jumpy.
I'm doing this in a pretty straight forward way:
var prefix = Modernizr.prefixed('transform');
$window.on('scroll', function(){
var scroll_top = $window.scrollTop();
if(scroll_top < forside_infographics_offset){
$_('#slider').css(prefix , "translate3d(0,"+(scroll_top/3)+"px,0)");
}
});
Now, I've seen this site where the scrolling is super smooth, also with a mouse wheel with steps on it. I've tried to look at the code, and he's using requestAnimationFrame is seems, but how he accomplish this excact scrolling effect, I'm not sure.
http://cirkateater.no/
Any ideas?
After doing a lot of research, I found a pretty easy solution :)
http://bassta.bg/demos/smooth-page-scroll/
Interestingly enough, I didn't have to alter my existing code at all. This overrides the default scroll behaviour, while leaving the event open for me to use like I would normally do.
EDIT: This is a really bad idea. Never ever hijack and override expected behavior. I guess I was overly fascinated with animations back then and overdid everything. Thankfully we all learn and expand our perceptions of good UX principles :)
Scrolling using the mouse wheel requires special handling. Reason being each mouse wheel scroll doesn't scroll the content by a certain amount of pixels. Each scroll causes your page to jump and then each jump results in the "jumpy" jittery animation as the background image is trying to position itself at these jumps.
Using a library will solve the problem most of the time, but it is also worth understanding what problems it is trying to solve under the hood.
Just for reference sakes, the mouse events are mousewheel and DOMMouseScroll
This plugin for Chrome provides the functionality necessary for this. Someone created a gist with a minified version of it. It's from a pretty old version, but I think that's fine because, as I've checked, the latest version of the plugin adds too much stuff.
A couple things with that gist though:
It checks if the browser is Chrome before initiating.
It initiates automatically.
It uses jQuery.
So I let myself create a version that addresses those points. Just add the script and call SmoothScroll.init() to start.
Edit: While testing I figured out this has a significant bug. While my version behaves (in my opinion) tremendously better than the original code, it unfortunately does not account for scrolling by other means (scroll bar/middle click and drag). Scrolling by one of these methods and then scrolling with the mouse wheel causes it to revert to wherever scroll location you were at when you last scrolled the mousewheel. I'll update when I develop a solution to this.
Kenny's referenced solution was a fine approach, but it's functionality drove me crazy. If you scroll the wheel quickly it wouldn't scroll much faster.
I improved it such that you scroll a given distance per click regardless of mouse wheel spin speed.
The reason his answer did not is because if you scroll the wheel a second time before the first animation is complete the new scroll to height is only the current scroll height plus however much it scrolls per wheel click. (So if scroll time is .5 seconds and you scroll a second time after .25 seconds then it will scroll 1.5 times the wheel scroll distance instead of 2 times that distance)
It's late at night, I hope that makes sense.
Regradless here's my code:
Required libraries
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/latest/plugins/ScrollToPlugin.min.js"></script>
Scroll code
<script>
$(function(){
var $window = $(window)
var $scoll = $('#page-container')
var scrollTime = 0.5
var scrollDistance = 120
var scrollTop = $scoll.scrollTop()
$window.on("mousewheel DOMMouseScroll", function(event){
event.preventDefault()
var delta = event.originalEvent.wheelDelta/120 || -event.originalEvent.detail/3
scrollTop = scrollTop - parseInt(delta*scrollDistance)
scrollTop = Math.max(0, Math.min($scoll[0].scrollHeight, scrollTop))
TweenMax.to($scoll, scrollTime, {
scrollTo : { y: scrollTop, autoKill:true },
ease: Power1.easeOut,
overwrite: 5
})
})
})
</script>
Great question.
The library I use is this one:
https://github.com/cferdinandi/smooth-scroll
Simply include the smoothscroll.js file, and job done.
The mouse-wheel will now smoothly easy down the page, rather than jumping down in chunks of pixels.
It really improves the look of parallax webpages.
Btw, for parallax images, I use this library:
https://github.com/pederan/Parallax-ImageScroll
It's really easy to add to a webpage, just remember to include and initialise this library at the bottom of your webpage, after your images and HTML.
(I didn't realise that this would make a difference, but it absolutely does !)
I know I'm late to the game but I was researching the topic of smooth scrolling today after I stumbled on I Love me Wellness' site.
Analyzing the sites JavaScript I found that they are using a vanillaJS script called Luxy.js which is showcased at Luxy.js on GitHub. I find the effect rather pleasing. I don't think it's a very bad idea if implemented well. And it's very easy to implement.
I'm having a hard time googling this issue because most of the things I can find are about animations that are supposed to be fast but are acting slow. My question is regarding an animation that I want to have a long duration but still be smooth.
I've created this jsfiddle to demonstrate the issue: http://jsfiddle.net/93Bqx/
I'm trying to make an element slowly move to another position over time. But the animation is very choppy.
Basically, it boils down to something like this:
$elem.animate({
left: x,
top: y
}, someLargeNumber);
I'm wondering if the problem is that the animation is so slow that each step is less than a pixel and so it is rounding them to either 0 or 1 making it appear to drop frames and then move all at once. But I don't know how I would check or fix this.
Is there a better way to be doing slow animations so they're smooth? I had a similar one created with CSS3 and translate(x,y) that was smooth but unfortunately I need more flexibility than I think I can get with CSS.
I guess it's the inevitable bargain with doing animation programmatically.
Maybe try a framework specialized in animation like:
http://www.greensock.com/gsap-js/
but adapting the animation to CSS would be best.
It's not much smoother even using a CSS transition.
I added the Transit jQuery plugin to test a CSS transition instead, and it looks almost the same.
Your code with minor fixes: http://jsfiddle.net/thirtydot/93Bqx/5/
Same code but with Transit added: http://jsfiddle.net/thirtydot/93Bqx/6/.
I think this is a limitation of the fact that (most?) browsers don't do subpixel rendering. As you mentioned, the x and y of the element is rounded after every step of the animation, and it's this rounding that causes the unsightly "jiggling" effect.
The CSS transition version does look noticeably better for less pathological test cases. Read this for more information: http://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/
I think it has something to do with how often you move an element. For example, if you move the object once every second, it will seem choppy. Try decreasing the amount of time between each move as well as decreasing the distance between each move. See http://jsfiddle.net/2K9xP/ for an example.
So we have...
var duration = Math.round(10 * distance);
instead of...
var duration = Math.round(1000 * distance);
I've been working on a slideshow script that uses CSS3 transitions, or jQuery's animate when they are unavailable. I've created a custom function to do the slide animations, which does so appropriately. Everything seemed to be working fine, but I've hit a major snag during testing.
For one reason or another, there is an large delay applying the jQuery CSS before and after the transition on large slideshows. For example, the slideshow in the link below is around 9900 pixels wide (container width, most of which is hidden). The container is maneuvered to display the appropriate slide, using CSS3 transition and transform properties. The delay occurs applying the CSS between lines 75 - 82 in the paste below. In particular, applying the 'transition' CSS causes the problem. Add the 'transition' CSS to the stylesheet (rather than applying it with JS), and delay disappears. This isn't really a solution however, because we only want to use CSS3 transitions on specific properties, that can vary (using 'all' in the stylesheet would transition some CSS that we don't want to animate, but change regularly).
Animation function:
http://pastebin.com/9wumQvrP
Slideshow Demo:
http://www.matthewruddy.com/demo/?p=2431
The real problem is with iOS, in which the slideshow (and even the browser sometimes) becomes completely un-usable. I can't pinpoint any errors, and have really exhausted my knowledge of debugging JS. I'm sure it is related to this section of the function after playing around a bit, and disabling CSS3 support within the plugin altogether removes the problem completely.
I'm completely stuck, and really appreciate any help anyone can give.
--- Edit ---
I've tried applying the CSS with native Javascript rather than jQuery's .css function. Same results, no better performance. Also worth noting that this isn't happening at all in Firefox, and seems to only be a problem with Webkit browsers.
Anyone with a solution, would happy to make a donation towards a few beers! I really cannot figure this out!
--- Second Edit ---
Ok, so been debugging and I can see that the slowdown is caused by the browser repaint cycle that is taking a very long time. Is there a better way to handle this that the way it is already doing? Positioning the element absolutely is a known way to reduce repaints, but that isn't really working because the slideshow is responsive. Absolutely positioning the slide images or the slides themselves causes it to collapse.
--- Third Edit ---
A day later, and I've made some progress. Adding 'transition: all 0s ease' to the elements stylesheet CSS has gotten rid of the repaint caused by adding the inline CSS transition property via the custom animation function mentioned in the original post. This causes a significant performance gain, especially when removing the inline CSS transition property when the transition itself has finished.
Good stuff! However, now there is still a slowdown when the inline CSS translate is being removed (that was used to create the hardware accelerated transition effect itself) after the transition, and the left positioning is being applied. When the two happen together, there is a slowdown.
Breaking them up into two separate tasks (the translate removed, then the left position added in a setTimeout with no time specified), again gets rid of the repaints = performance gain, and looks likes problem solved. But sometimes, the CSS transition property isn't get negated fast enough, and the translate removal gets animated. No good, and don't know where to look next to work around it.
I think the problem is you're loading HUGE images :)
They are too big for the container you have them in, so you scale them down, which is even more resource intensive.
Try resizing them.
First of all congrats for your debugging!
I have been working on the exact same stuff lately and found out that ios devices don't support a large number of images positionned in the same page. It causes crashes and the only solution I found was removing elements instead of just hiding them. The downside is that removing and appending elements causes lags so you have to do it cleverly, when your transitions are done. I thought the best way to go was keep 3 or 5 images in the DOM and replacing the rest with thumbnails of the images, resized to fit the original. When transitions are done, I'd just put the large images back into place...
Hope this helps you a bit on the ios problem at least...
After spending some time analysing your code TimeLine with Chrome Dev Tools, I believe there's some optimization you could do.
As far as I can tell, every single one of your 16 images gets fully repainted every time an animation is requested. This seems quite obvious to me, as there are 16 images in your example, and the Chrome Dev Tools reports 16 long "Paint" executions every time in hit "Next".
In my humble opinion, you should figure out a solution that considers only translating two images: the one you want to hide and the one you want to show. So, consider please, not moving the rest of the images and, instead, leaving them all side-by-side to the shown image.
One more thing, using scaled down images is probably making the paint cycles quite longer. Avoid them whenever you can.
Well, think I've managed to figure it out! Just so you know, original post links don't reflect the changes as I've done them on my localhost environment.
Absolutely positioning the slides container has fixed the problem that was occurring with repaint speeds after the transition had taken place (whilst applying CSS properties). Obviously taking them out of the DOM has done the trick, allowing painting to take place much more efficiently.
I originally didn't try this too much because I knew this would add a lot of work to the resizing functionality. I had originally intended to not resize at all in JS, and rely on percentages to do the dirty work. Absolutely positioning the container would cause the slideshow viewport to collapse, rendering the native resizing useless.
However, I was already having problems with sub-pixel rendering in other browsers anyway, so I guess it was time to bite the bullet and rely on fixed pixel values. I then used JS to handle the resizing, using the window resize event. All seems good, however the slideshow was still collapsed due to the positioning. Assigning height values wasn't working correctly, so was at a bit of a loss.
Thankfully, I came across a neat little trick of setting the 'padding-top' of the slideshow viewport to a percentage value, dynamically calculated (desired slideshow height, set in the settings panel for this script, divided by desired width). As padding-top percentages are relative to the width of the element, this did a great job of providing responsive height and correcting the viewport again (no longer looking collapsed).
Here is some info on using padding-top for responsive elements that maintain aspect ratio. Great little trick: http://f6design.com/projects/responsive-aspect-ratio/
All is good now, and things are working well in iOS and webkit browsers. Everything is extremely quick and working as it should. Four days later, and it is finally figured out. Not happy about having to resort to JS for resizing, but I guess it was always going to happen due to percentage inconsistencies between browsers. Lots of decimals = no good!
Thanks to all who tried to point me in the right direction. Definitely got me thinking, and learned a lot of debugging skills that I can use again to make sure transitions are performing well. Thanks again!
not sure if this helps or not but I noticed you use 3d translation - I would think a simple 2d translation would be enough especially since your third parameter is 0 and might accelerate the issue, also go with fewer images as Armel L. suggested, don't have an iphone to test though... alternatively, this is a solution I used before css3 but should still work move the element containing the images using javascript by modifying left (?and top - the demo only moves left and right though? without the transition effects) and this way you can fine-tune the refresh rate which I think might account for the slowdown... you can go as low as 18 fps without anyone noticing, might even be good enough with just 16fps
I had this when I was first designing a magazine carousel-style page device.
If you have a series of images within a long "tray", even if they are not within the viewport, they will still take up ram, and you can effectively have five or so before leaks and nastiness begin to happen.
What I found works is "hiding" them ... But make sure they take up the physical space necessary.
What I also found worked was that one could make the 'previous' current and 'next' image are visible and move the tray, 'unhiding' them as they reach those three positions.
In my own system, I skipped the 'tray' holding e images and only had them at -100% width, 100% width and the current one a 0.
I never had much luck with the typical long-tray carousel with large scale background images... Especially with css3 acceleration.
So a fellow StackOverflow-er wrote out some jQuery based Javascript for me a few days ago.
It works, but there's an annoying issue with it and I wondered if anyone could help out.
The JavaScript is calculating a margin for alignment purposes. The value it calculates is is not always an exact pixel, e.g sometimes its 14.4 etc. In Firefox the issue does not exist, but in other browsers such as in Safari or Chrome when the margin is being calculated (as the screen is re-sized) the far right hand side box 'jumps' and never quite stays against the edge of the container.
As I said above, in Firefox it does not 'jump', and this is the effect I was looking for.
Is there anything that could be done to stop this 'jumping' effect or is it completely related to the browsers rendering engine and out of my control? :(
This JSFiddle contains the code/demo : http://jsfiddle.net/m4rGp/1/
(Try resizing the browser width in Firefox then Safari/Chrome and you will notice the jump on the right)
Any reply's are really, really appreciated! Many thanks
This is because of the rendering engine only. There are no decimals in pixel. 1px is the smallest addressable screen element. So before changing the margin add a Math.round
$(".barModules li").css('margin-left', Math.round(dynMargin) + "px");
yet the bouncing will be there because the element is positioned in such a way that it is bound to its left (reference). When it sees the attribute margin-right:0, it tries to activate that one too ... but due to its margin-left being set and positioning based on left .... it is bouncing like that. like a debounced function call.
If your aim is to get a dynamic margin, then you have to adjust with this, else go for a fixed width page with centered elements and you don't have to worry about overflow problem
I want to detect if the browser is zoomed in or out (don't really care to know the value, but I assume it will need to be found anyway in the decision process). I have read a lot of other SO posts on the topic, but none of the solutions given work on FF (although there is an IE7/8 and chrome solution).
Oh, and I can't use flash, so the flash solution is out of the question.
Edit: And I must be able to detect this on the initial page load
With modern versions of FireFox, you can now do the following:
DPR = window.devicePixelRatio;
if ( DPR <= 0.999 || DPR >= 1.001 ){
// User has zoomed in or zoomed out
}
If by zoom you mean that the user pressed ctrl/cmd+[plus] and not css transformation you can detect computed font-size. Just checked in FF 4.0.1/Mac and it worked for me. To detect computed font-size I used code from this question: Get computed font size for DOM element in JS .
The value changed after zooming. You need to know what the font-size of a certain element should be (as set in css) and compare it with what it really is.
I suggest you look at this generic question. And possibly close your own as a duplicate (not voting to do this myself, since it's not "an exact dup".
Did you try to detect the resolution, which may help you to detect the zoom.
Maybe instead of detecting the zoom you could detect the error.
For example if your layout expects an elements' offset to be at 100,200 and a query shows it's at 300,450 you'll know it's in the wrong place and you can apply your fixup/workaround.
This has the added benefit that if the zoom issue is fixed in a future version of the browser you won't be applying your fix needlessly or incorrectly.