I'm using a library called ParticlesJS for part of the background of my website - this library dynamically generates a canvas element sized according to its parent, and fills it with animated particle effects, creating a neat effect. With that said, I have run into some practical issues when trying to use it as the background:
If the canvas element is the same size as the content, the visuals become pixelated and distorted if the height changes, such as with the addition of new content. Reloading the library is not a solution to this as it creates a visually distracting effect.
If the canvas element is an arbitrary extreme height and not sized according to the content (with the overflow simply hidden), the performance of the website suffers, as the library consumes excessive CPU power.
If the canvas element is simply given a fixed position in CSS, performance is good and it sticks, but it looks out of place as everything behind it moves during scrolling.
After some consideration, it seems like the best way to make it work is to give it a modest size (like 200% page height), and then make it repeat infinitely during scrolling - performance would be acceptable, and there wouldn't be any distortion. However, I can't find any way to do this - I'm aware that there's a background-repeat property in CSS, but that seems to only work for images.
Is there any way to do what I'm trying to accomplish? Both CSS and JS based answers are welcome.
After some trial and error, it looks like the only means of accomplishing what I'm trying to do is as follows:
Create 3 or so background divs, each the size of the view port, and stack them vertically
Record user scrolling activity, and set a trigger for when a user has scrolled a height equal to the height of the view port
when the trigger is hit, place the div that just left the view port at the end of the list, and insert an empty spacer div where it used to be
If done correctly, this creates an effect where the user is apparently scrolling through an infinite background, when it's really just the same 3 or so divs being shuffled over and over. Going in reverse is the same principle.
Not sure how to make this work with in a system that also has scroll position restoration, but it could probably be done by waiting for page loads and then dynamically inserting enough spacers to move the background divs to the appropriate position in the view port.
The downside to using animated effects that rely on viewport dimensions is that the user may resize the browser and wreck your animation so you have no choice but to catch any viewport resizing in which case you may have to reload everything or recalculate!
You can't have the cake and the cherry on top unfortunately, so you'll either have to abandon the idea of "impressive effects" because they are impractical or take action...
document.body.onresize=function(){Adjustments();};
function Adjustments(){
var W=Container.offsetWidth, H=Container.offsetHeight;
// You've now got the new resolution so go for your life!
}
Related
I'm making a simple website, that doesn't have to be super fast and performant, I'm only focused on some nice design elements. One of those design elements is blur that is applied to statically positioned background "under" some containers, that move when scrolling. This example should be self-explanatory. (I hope it's OK to share the website itself. It's just a personal website, no advertisement intended.)
This could be done with CSS filters and some moving background-position on the containers. However, the background is not an image but a canvas element. (For now, it's just an image redrawn into the canvas, but it will be generated algorithmically.) So my approach is: The blurred containers contain a canvas as their background and the content of the background canvas is redrawn with a filter applied on every scroll and resize event. As I said, this doesn't have to be fast and probably no other complex computations will be performed on the client-side, but a smooth user experience is important.
(If needed, I will provide relevant parts of the code.)
My question is: I noticed, that when scrolling with a scrollbar, it renders very smoothly, but when scrolling with a mouse wheel it probably just can't redraw the background fast enough and it looks as if the blurred background falls a bit behind. When swiping on a touch screen, it gets even worse and the blurred background is always behind the actual background. The fact that it's able to keep up when scrolling with a scrollbar makes me think that the problem is not with the canvas redrawing approach but with handling the events. Is there any way to handle the scroll event in such a way, that the performance will always be as good as when scrolling with a scrollbar? Maybe it's not even about performance, but rather that mouse wheel and swipe scrolling don't trigger the event as frequently, which causes these "gaps" when the canvas isn't being redrawn? If so, I should probably implement the redrawing in such a way, that it accounts for the delta of the scroll event and just draws the blurred background several times in between the events.
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.
Need your help.
I created a static semi-opaque banner which stays at the top of a website. When a user scrolls the website the entire container objects goes underneath the banner. I want all the objects (images, text..etc) getting blury effect as it goes underneath the banner.
Thanks
The only way you're going to be able to do this is by getting fancy with some CSS and javascript. CSS doesn't support blur directly, but you can emulate it with text-shadow. Images can also be blurred with a little jquery/css/javascript magic, but will be problematic because you can't partially blur an image (what happens when only part of the image is under the banner?). It could probably be done by layering your images and keeping track of their position on screen, but all of this seems like a lot of work for a very small return.
So, assuming you've decided to give all of this a shot, you're going to have to use javascript to determine which parts of the page have passed under the banner and apply the style to those parts. The difficulty of this task will scale with the complexity of your page layout. In a best case scenario, your banner and content container are both 100% the width of the html body. At this point, it would be fairly trivial to write some kind of scanner that traverses the dom every time you page scroll to find elements that the blur should be applied to. However, best-case-scenario is rarely the case at hand, at which point I'd recommend abandoning the effort to pursue something with a greater ROI.
This isn't possible with CSS nor jQuery. You might be able to do something with IE's filters, however that's IE only (of course), and will invalidate your CSS.
Currently, there is no way to do this, although something might come along in CSS 4 or something.
The Chrome nightly builds support some filters, however there isn't an alpha blur filter (yet, at least).
I am building an Webpage that uses SVG, Canvas and, of course, HTML. The idea of this page is to animate the redrawing of some of svg-paths on the canvas. The paths I like to redraw are annotated with an namespace Attribute, all other paths are just displayed as they are. That is all working fine! The performance leak appeared the last two hours while I was adding some content to the page.
But at first a little illustration of the page setup:
The SVG and the Canvas are both 4000 * 4000 px wide and lie directly over each other in one container div. Going from one "page" to another means to tween the upper left edge of this container. This was also working fine since the discussion of inserting text turned in the direction of using html div container, instead of the svg itself.
So i inserted a third container div in which all the texts are stored and after svg is loaded they are positioned absolutly.
With every div I added the "pan-tween" and even the drawing performance decreased to a Point that is just too low.
I am searching for way to bring the performance back to a level that is acceptable for the user. One of my ideas is to set text divs to display : none, or visibility : hidden, as long as they are not displayed actually. Another option is to tween only svg and canvas, after this is finished placing the text-div-container in one step. But I am currently not sure which solution is better, or if there isn't something much better. So if anybody has an Idea, please let me know.
Thanks for reading!
Greetings Philipp
Try to pan the outer "text div" in intervals(say 10ms or 50ms). I this with a lot with rendering, in HTML usually I use greater values like 100ms or 150ms(I use to do this with canvas).
Didn't understand if you pan the outer div or all the "text divs".
I would like to be able to set a background on our homepage which can expand and contract with the window size whilst keeping the original images aspect ratio.... I'm guessing this will need some clever Javascript or similar.
The effect has been implemented here whereby then the window exceeds around 1500 pixels in width the background will dynamically expand.
http://www.pixelcrayons.com/
First the bad news: CSS doesn't (currently) allow a background image to be stretched or scaled, so it isn't as easy as it should be.
However, there are a number of ways around it. The best solution (IMHO) is to have a normal <img> tag sized to 100%, positioned absolute (or even static depending on the effect you want) and layered behind everything else using z-index.
The best thing about this option is that there's no Javascript involved.
But if you want to find out about the other solutions (that do involve Javascript), then try this link: http://css-tricks.com/how-to-resizeable-background-image/
(but note that his preferred solution in the end is the same as mine)
Hope that helps.
There is a really great jQuery plugin available: SuperSized
Not only does it do background resize, but has lots of other options. Hope it helps!