How to do a smooth-scroll? - javascript

I have the following working code to make a element of my scrollbox visible:
var next = elements.item(i+1);
var xpcomInterface = scroll.boxObject.QueryInterface(
Components.interfaces.nsIScrollBoxObject);
xpcomInterface.ensureElementIsVisible(elements);
But I would like to make a smooth-scroll (slow or not). Any idea how to do it?
update
By the way, it's for Mozilla environment.

The simplest way would be to just use a setTimeout function and just keep moving the top and left value on the element's div by a small number, until you get where you want to be.
You may want to experiment with how fast to make it move, as there is a trade-off with smooth, and the fact that it should reach the endpoint in some reasonable time.
Update:
I forgot, you will want to keep calling the setTimeout until you reach the final destination, otherwise it won't redraw the browser window.

I don't know exactly how to do it, but here's a Chrome Extension called "Smooth Scroll" where you can potentially pick through the code to see what they do and maybe get you in the right direction.
PS I love this extension.

jQuery .animate() with accelerated motion can be kind of smooth (see demo for animate with a relative move). And with a plug-in, there are other easing equations it can use.

Related

CSS Transition is not triggering after insertBefore

I am trying to create an horizontal carousel that loops.
You can check the code here: https://codepen.io/nobitta/pen/xNOyrj
At the moment I am stuck. I managed to make it work, however the CSS transition that mimics the movement to the right, is not triggering when you click "next".
I already did some research and some say this has to do with browsers optimization and that setting a timeout or calling offsetWidth or getBoundingRect() should do the trick, as it forces the browser to re-render. However, even with those tips, I was not able to make it work...
Am I doing something wrong or missing something here? What should I do?
Thanks in advance ~
I managed to fix it by playing around with the margin-left property.
My bet is that when I prepended the last slider's item, it naturally shifted right due to the new element's size and the space it occupies. Therefore I decided to shift it back to mask the insertion shift. I followed the same reasoning for the appended items.
You can check the codepen in the question for more detail.
I hope this helps someone.

Javascript workaround for slow scrolling with smooth scrolling in firefox

I am a developer for a web application. In this application there is a certain scenario where there are multiple position:fixed elements, and canvases and a overflow:scroll element. In this scenario, scrolling is super slow on firefox when smooth scrolling is enabled.
From the user's perspective the solution is simply to disable smooth scrolling. However, as a developer I can't ensure that the user has done this.
Is there anywhere that I can tell firefox to not to use smooth scrolling for my website from javascript (or html)? Or is there any other known workaround for this?
I do understand that your question basically is how to disable smooth scrolling. however I will answer you a little differently to get this working.
Why different?
Even if you can detect smooth scrolling of users, you cannot force the user to disable it. In other words, you are trying to cover the problem instead of solving it. so lets solve it!
Intro: pixels-to-screen pipeline
On each frame the browser does the following steps to render the page on screen.
JavaScript. Typically JavaScript is used to handle work that will result in visual changes, whether it’s jQuery’s animate function, sorting a data set, or adding DOM elements to the page. It doesn’t have to be JavaScript that triggers a visual change, though: CSS Animations, Transitions, and the Web Animations API are also commonly used.
Style calculations. This is the process of figuring out which CSS rules apply to which elements based on matching selectors, e.g. .headline or .nav > .nav__item. From there, once rules are known, they are applied and the final styles for each element are calculated.
Layout. Once the browser knows which rules apply to an element it can begin to calculate how much space it takes up and where it is on screen. The web’s layout model means that one element can affect others, e.g. the width of the element typically affects its children’s widths and so on all the way up and down the tree, so the process can be quite involved for the browser.
Paint. Painting is the process of filling in pixels. It involves drawing out text, colors, images, borders, and shadows, essentially every visual part of the elements. The drawing is typically done onto multiple surfaces, often called layers.
Compositing. Since the parts of the page were drawn into potentially multiple layers they need to be drawn to the screen in the correct order so that the page renders correctly. This is especially important for elements that overlap another, since a mistake could result in one element appearing over the top of another incorrectly.
details and source: https://developers.google.com/web/fundamentals/performance/rendering/?hl=en
Step 1:
First step is to remove render costly css properties. You might not be able to remove alot, however you can replace rgba(255,255,255,1); with #fff which removes the alpha layer.
check this for more details: https://csstriggers.com/
some properties do not need to do a layout or a paint and there are less heavy than others.
Step 2:
Check for forced synchronous layout triggers. These happen when you force the browser to do a layout while its in the javascript step, then return to javascript, instead of walking smoothly along the pipeline on each frame. to do this, avoid getting layout attributes and setting them directly afterwards in a loop for example.
here is a list of what causes sync layout: https://gist.github.com/paulirish/5d52fb081b3570c81e3a
read more: https://developers.google.com/web/tools/chrome-devtools/profile/rendering-tools/forced-synchronous-layouts?hl=en
Step 3:
Move components on the page that need to be repainted regularly into new layers.
The browser needs to repaint every time you scroll or an animation is playing. to avoid a full page repaint and only repaint the part that is changing, move that part (ex parallax, navigation, animation) to a new layer on the browser (think about it like photoshop layers)
to do so use the will-change css property to tell the browser to move it to a new layer, and use transform: translateZ(0); if you want to force the broswer to move it.
Have you tried adding
backface-visibility: hidden;
to you fixed position elements?
I would rather fix the source of the problem. Often there is one small detail that creates a giant bottleneck and that is easy to fix with the change of one line of code or something. Note that you most probably won't need to reduce the "good looks" of the app at all; it's just a matter of avoiding the small but devastating-for-performance details of the browser's layout engine.
I'll make a guess and say that something on you web app is causing very large repaints and/or frequent reflows. Check for things like usage of offsetTop and position: fixed. Also using requestAnimationFrame instead of updating for every scroll event is something worth looking at. Here's a good guide on both finding and fixing scrolling performance problems.
Use inspect element to try and get a handle on the specific cause.
Also, if you've not installed FireBug, install it and use it instead of the default inspect element. This will give you more code details and allow you to step through the script to find the problem.
There also plugins for FireBug for various frameworks, which can aid the diagnostics if your using one of those frameworks.
We can make assumptions about the cause or come up with shotgun solutions; but, only you can diagnose your code to find the specifics.

CSS Skill Bar Animation on Scroll

I'm looking to do something like this. I'm using code from this answer here but the answer is never made entirely clear. They are suggested to use this jquery plugin here but I haven't been able to get it to work. I would go with the first example's code, only, I'm using Foundation 4 and the progress bars are something that come with it and are simpler to create. Also, the animation code provided in the second example is a lot cleaner-- overall, the first example is kinda messy, code heavy, and redundant.
My code is live here. I'm working with the skill bars in the about section. Before the user gets to this point, the animation should be paused. Once the user scrolls to this part of the page, the animation should play.
EDIT: Also, if you have any suggestions to stop the bars from "breaking" out of their containers when you scale the page (this site is meant to be responsive), I would appreciate that as well.
EDIT2: I've noticed as I've been playing with this that overflow: hidden; on .progress fixes my "breaking" issue.. however, when you resize the window, the sizes stay at what they initialized at. I know realistically users visiting my site likely won't be resizing the window a whole lot, but for employers looking at it, it'll kinda be lame if it doesn't work properly. I'm having this same issue with the grumpy-cat button overlays where it initializes at the first size and doesn't resize the overlay after that. Suggestions to this would be really, really appreciated!
If you know where your skill bar is and you know where your screen is at, you only need javascript. (no plugins or weird stuff)
To get the vertical position of your screen it's simple:
window.pageYOffset
To get the vertical position of your div, you just need
div.offsetTop
In your case, I would give an id to the div that wraps all the skill bars and set a loop (window.requestAnimationFrame https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame ) to check if you're within reach of the div (say, if the difference between the window offset and the div is less than some amount).
If the answer is yes, trigger the animation.
The best way to do the animation is by a css transition. (if you need a good intro to css animations here's a video that i found helpful: http://www.youtube.com/watch?v=VoncDvOfUkk )
You can set css animations from javascript.
The idea is that you would set all your "meter" widths to 0. Then in javascript do something like:
div.style.transition = "width 1s";
div.style.width = someValue;
My recommendation for the value to include in the div is some constant fraction of the "progress" div, as in with % as opposed to em or px. This technique should work. (in case you still have issues, you have a window.requestAnimationFrame loop going on so you can recalculate the values at each timestep... although... beware performance).
The reason you were recommended jQuery is because when you're going to have to update all the divs in order to animate them, just writing $(this).find('.meter') and then addClass('.expand') is so much easier.
Hope this helps

Animate scroll to a div with an ID

I know this has probably been asked before but I couldn't find the right answer.
I'm trying to have a link, when you click it, scrolls the page to an element with an ID, with just javascript, and I get to control the speed.
I know about:
document.getElementById('youridhere').scrollIntoView();
and that didn't work. It just snapped into view. I also tried scrollBy but that didn't work since it works in increments. I can write it up to check the remaining distance to the element and if it's less than the increment, then only move what's left, but that seems way too bulky.
I tried scrollTo as well but that wasn't helping much either.
Is there a cleaner way of doing this?
This needs to be javascript only. Here is a jquery equivalent:
var top = target.offset().top;
$('html,body').animate({scrollTop: top}, 1000);
There is no built-in way to smooth scroll. I would use setInterval and scrollBy an increment on each iteration, then clearInterval when done.
You could also check the jQuery source to see how they do it.

What is the best way of scrolling the browser window for expanding elements?

What I want to do is scroll down the window when I expand elements in my page.
The effect I am trying to achieve is like the Stack Overflow comments. If it expands beyond the page, it scrolls down to fit all the comments in the window.
What is the best way of doing this?
Edit: I am using JQuery.
This jQuery plugin worked well for me:
http://demos.flesler.com/jquery/scrollTo/
If you have the advantage of using Prototype, you can use $(element).scrollTo().
Otherwise, the general idea is to calculate the cumulative offset of the element, then set window.scrollTop (and window.scrollLeft) accordingly.
You can do it nicely with Scriptaculous (built on top of Prototype):
new Effect.ScrollTo('someDiv',{...some parameters...})
It gives you finer control than Prototype alone (delay before start, duration and callback events (such as afterFinish) that allow you to trigger other effects or whatever you choose. You can make it scroll smoothly and nicely, so the page doesn't suddenly jump.
If you know what the next element in the source is you could actually just jump to that element (location.href="#..."). This would use the browser's native 'scrolling' and not use any libraries.
You could use this code wich is okay but not perfect.
Based on the suggestion by blonkm
function scrollTo( Selector ){
$(Selector).before("<a name='scroll' id='scroll'></a>");
document.location.hash = 'scroll';
$('scroll').remove();
}
This should work.
Requires jQuery but you already say your using that.

Categories