📜 ⬆️ ⬇️

Animation of falling snow on Canvas is more effective than animation on DOM several times.

. In comparison with native JS on DOM elements, the implementation of animation algorithms on Canvas is usually more productive many times. This is a well-known fact (but with features for a small number of particles, as it will turn out later), and it can find a realization that hinders the traditional way under NG but is driven by rational users of “falling snow”. So that the load was small, in recent years it is considered good form to “launch” snow on the site barely noticeable, with a minimum amount of snowflakes (5-15). Here and the effect is, and the load on the processor is almost no.

Therefore, while the NG still has a few more days in winter, I propose to arrange a hackathon to implement the best algorithms on the canvas and their analogues on the DOM, taking as a basis mainly the ancient native algorithms that were wrapped in jQuery as a maximum to make it convenient to connect. Most of these algorithms do not match the load on the processor or are inefficient, so even with a small number of snowflakes, the processor is loaded at 100%. Here is an example of a review article , where more than 10 implementations are considered, not all that occur in nature. In addition, we will consider a few chosen ones in order to get the groundwork for the development of the algorithm and its implementation with good efficiency (we will get another 5-6 options). On this basis, you can build a revision. Github with 12 demos (links are repeated below) and several algorithms.

As usual, the life of an article on Habré does not last more than 1.5 days, so you can’t count an effective stock. But after the New Year, various miracles happen: the flow of visitors is falling, and random lunatics get a chance not to forget one article for 5 whole days. They bet on.

It is better if it is tied to a lengthy process, for example, to the club of anonymous Santa Clauses, by going to which you can always get a link to the discussion and development of the options of "snow fall" and at the same time it is not tied rigidly to the holiday. The result at present is here: geekadm.ru/#/2015 , and there are, of course, intermediate experiments of the type 46.101.141.171/snow.html?v=4 - snow for HabraAdm with additional effects.
')
A preliminary "hackathon" was arranged by a couple of participants and (or) club visitors - (1) , (2) . As a result, it turned out up to 10 options on the engine with Canvas. Their number can be much larger, but free time is needed for everything, so the action turned into an open one. For example, you can “screw” a model of snowflakes falling by the author Peter Gehrig, already written in 2003, to the engine. The revision in 2005-2006 shows on modern browsers that 20-30 snowflakes slightly load the processor (10-20%, depends on the power and the video card; hereinafter we will talk about loading one processor core , since JS is single-threaded), and according to the testimony of the old forums, it was the same on older browsers like Opera 9 and IE6, but somewhat worse. On the Canvas with the same algorithm, it would be possible to run 5 times more objects.


demo


Let's look at the history and look at its course.


Let's start from the beginning, from 2002-2005 approximately. Javascript showed the ability to animate the falling snowflakes. True, it turned out, and it was natural, the animation on the script is either unproductive, or it loads the processor heavily. Therefore, in those old days, it was necessary either to save resources very much, or to load the processor to the maximum, 100% in the browser stream (on 1 core), which slowed down the other tabs (in those browsers like Opera 9, where they were) and windows, and this caused poorly concealed indignation of visitors to such pages.

After 8 years there was a solution to this problem at the browser level. The main browsers, starting with Chrome, began to suspend the execution of scripts on invisible tabs. This helped not to interfere with viewing other windows and programs (but does not pause when switching to another window, it only reduces the load if the window is not drawn on the screen or partially visible). True, in connection with the mobile era, the opening of the pages with the loading animation is still not perceived positively.

But over the years, a more advanced animation mechanism has emerged - Canvas. Immediately, it should be noted that another innovative mechanism - animations in CSS - does not help save the load, and they spend exactly as much processor power as animation on Javascript + DOM. That is, if you look for the best solution, you have to do it in Canvas.

Canvas, as will be seen in the examples, allows you to run a hundred snowflakes with a load of 30-40% for an average desktop computer or laptop. This is about 5 times more efficient than the best optimized algorithms on JS + DOM.

As a tribute to history, we will consider the “classical” algorithms, which are waiting in the wings for optimization and transfer to Canvas.

A lot of algorithms are easy to find by searching in Github according to the words “snowfall js”, “snow flakes js”. They will complement a good selection of 12 scripts with demo links mentioned above (or an extended copy ).

Overview of algorithms with examples


(When browsing the pages with examples, be prepared to sometimes 100% CPU load. When showing a link in the article about the level of loading is warned.)

Many algorithms, besides being inefficient, are not yet similar in behavior to the actual behavior of snowflakes. Probably, many people remember the striking discrepancy between reality and the movement of snowflakes along a sinusoid. Once seen (or newer ), it is remembered for a long time as a negative example. Therefore, the task of the algorithm is to be not only effective, but also reflecting reality. (In terms of efficiency, the calculation of harmonic functions should also lose.)

Of the previously revised algorithms, two are the closest to reality - with random movements (you need to vary the speed, not the coordinates) and the mentioned algorithm Peter Gehrig (2003), in which the movement is controlled by 4 variables, and one of them is harmonically changing, which creates periodic effects of "turbulence". However, one can argue about this and add new implementations to the piggy bank.

From the found implementations of the P.Gehrig algorithm, a page with an example was found: www.softtime.ru/javascript/snow-falling.html . It is clear what it is about. A small amount of snowflakes (15-20) still does not load much processors (10-20% for not weak laptops), works in Chrome and Firefox, although Opera 9, IE5 and 6 and some early Firefox are read in the support list. Of course, the Canvas did not know then.

We will reduce what we saw in the table, where we show:
*) number of particles;
*) animation type;
*) availability of a sandbox for experiments;
*) CPU usage (MacBook, Firefox 43) (Chrome is usually% 10 more efficient);
*) comments about features.

(The real data of the processor load will differ from those indicated for different computers, for computers with different video cards and for mobile devices over a wide range. Given for orientation is for a medium-power notebook with integrated graphics.)

Let's look faster at scripts using Canvas.
Not pure jsDemo: 400x400, Snowman with Falling Snow
Particles on demo: 100
Type: Canvas
Sandbox - YES
Download: 70%
Code lines: 106 + ProcessingJS (800K)
Drawn in 800K uncompressed code ProcessingNS environment that creates a “Rapier” type language. The snowman is drawn with the same code. An example is a special one. Shows that you can do anything with shells (to solve simple problems in complex ways), and even in this case, Canvas does not catastrophically lose out to solutions on the DOM.
Article (en) , 2012Code: GithubDemo: full screen
Particles on demo: 500
Type: Canvas
Sandbox? Not
Download: 100%
Code lines: 50 + 100 in * .html + ThreeCanvasJS (72K)
72K compressed unpacked code of the ThreeCanvas.js library. 3D scene with the rotation of its mouse movement. Here, for the sake of smooth movement, a small bitrate is set, so everything is beautiful, but as a background action it is not very appropriate.
Year: 2010Code: JSDemo and description: full screen
Particles on the demo: 60 , spinning in the plane of the picture
Type: Canvas
Sandbox? Not
Download: 100%
Code Lines: 160
Very frequent animation does not allow to appreciate the advantages of Canvas here too. There is a rotation of drawing snowflakes around its axis, a slow drop with wanderings. But some of them “walk” along sinusoids, torsion in one plane does not at all give realism, which, on the contrary, rejects from the perception of the effect, creates, rather, the effect of intrusiveness. The code, on the contrary, shows its power and compactness. In sum, the excellent efforts are aimed at achieving a little bit of the effects that, for the consumer, are no better than energy-consuming engines on the DOM.

Let's look at examples of scripts working with DOM (layers), without the Canvas.

Year: 2009Demo: jSnow - jQuery Snow Effect , full screenCode: JS (uncompressed old version)
Particles on demo: 25
Type: DOM
Sandbox? Not
Download: 70%
Code Lines: 160 + jQuery
Options in Fiddle sandboxes (character snowflakes are used everywhere):
  • Packaged (obfuscated) original code in a sandbox with adaptation to jQuery 2.
  • Unpacked, but poorly moving (small sinusoids) mod1 mod code in the sandbox with adaptation to jQuery 2.
  • Rebuilt with refactoring of names, style, the most similar and working code (Fiddle) of this script in the sandbox. Stops / starts by the stop button. In compressed form - 1.5K.
  • Extended to the ability to run multiple objects in blocks or in the whole window. Run by collection. In compressed form - 1.8 K, less than the original, which is 2.2-2.4 for different mods.
This script has a characteristic style of movement of particles (strongly to the sides). If you look closely, these are just very large sine waves perceived as one big whirlwind in the middle of the window. He is very restrained in waste of resources. Source code version 1.2 - lost or always obfustsirovan packer; Unpacked versions 1.1.mod2 (modified by other authors) are in the Codepen sandbox, but do not work with the new jQuery, because they refer to the canceled $ .browser. And they show signs of unpacking. Looks great in low headlines ( example ), when sinusoids do not have time to look through. Of the dozens of examples, if you should look at a couple of them (by execution and code), then this example is one of them. Therefore, we will take the jSnow version thoroughly by running it in a sandbox.
Interestingly, the packaged version of the author, 1.1 or 1.2 works much faster - with the same external settings it loads the processor by 40% , and 1.1.mod2 - by 55% . (Fiddle also does not work faster in multi-window mode.) Most likely, this is the effect of unnecessary checks in the snowflake drawing cycle (features have been added to the mods). The code itself is not extremely optimized - it writes inline styles that can be defined by rules.

Further, it became more interesting - in the code with the tested settings, a number of bugs showed up (and this does not mean that all were found). Some changes in the code will have to be done (to remove incompatibility with jQ 2+, to calculate the initial position of the snowflake, not to let them go beyond the left edge of the window - in poppies this leads to a “flashing” scroll bar, and it is useful to do the same for the lower border ), so use better modified modern versions.

Versions-mods (2009-2010) added a couple of pressing “features” - setting the smooth disappearance of snowflakes below (fadeAway: 1) and the ability to scroll with the snowflakes field not moving (followScroll: 1). The names are left original, which they called the developers.

The goal of debugging old code is to transfer the algorithm to Canvas and compare the speeds. (The cripple to win is not enough honor.) In the settings I repeat the same mistakes that I criticized others over. For the developer, it does not matter that the multi-colored snow falling in 2D does not happen - the main thing is to have a technical opportunity to paint. And yet, not snowflakes are flying, but clumps in reality. But 3/4 of the population of the Earth does not know this, so we are waiting for success ... In the set of snowflakes, most of the Unicode characters that are similar to snowflakes are used - they already accumulated 8. You can find as many more.

So, we have a readable code, 20 lines shorter (90 lines) and 30% less packed in packed form (1.5K) than the best mod samples, without losing the functions and adding a stop-start button. This intermediate option is compact, but it works, as before, with a window and can absolutely set the height (height: number) in the parameters. This is not very convenient, especially since the plugin does not use the context collection at all, so it feels fine with a strange-looking $ (). JSnow (...) call, i.e. without context. It turned out pretty simple, we limit ourselves here to a link to the demo .

And let's complicate the task - start working with contextual jQuery collections. Save this behavior when there is no context - we choose to work with the window, as in the context of window and $ ('body')) and add work with the container block (for example, run on $ ('. ContSnow'). JSnow (.. .)). The container will have to be prepared, it needs position: relative, so that the inserted block with absolute feels good. The block that covers the whole window will also start behaving differently, will cover the window, so all the page content will need to be lifted if there is such a block. (It is possible and otherwise, in the old way, but why complicate things? Rather, they will use either the first script or the second one.) It will turn out like this:

demo, (code in repo) . This is DOM, load 30% per stream (15% total) with a bit rate of 12.
Somewhat influenced by the fact that the pictures - large and transparent.

In fact, why work with only one container if jQuery can provide a collection? It turns out something like this , a load of 30-50% for a sum of 70-120 particles. Stop-start can also be divided by buttons or make common.

When trying to apply what is written, the impracticality of running the script on the collection is immediately apparent. Run - yes, you can, even dozens of instances of scripts, handing out a bit of snowflakes to each. But all the blocks of the collection are given the same parameters, and this is impractical, because more often you want to do another task - run a few windows (virtual, on divs), but with different parameters, and for this you have to report them to one element. It turns out, most often, that how many elements, so many starts .jSnow are needed, that it turns out long, although clearly.

Here there is an analogy with writing rules for CSS. The rules are the same parameter declarations that we do when launching plug-ins, even selectors for plug-ins are in place. But now there are no mechanisms to gradually accumulate descriptions of the rules (just as in one — font-size, in the other — position). The second launch of the plug-in on the same element adds another instance of the plug-in (long-playing function with closure and the ability to turn off), but does not add properties to the already running one. In this case, it would be more convenient to list selectors (just strings with classes), rather than JSON settings. But not a single plugin will be remembered, where such a method of constructing settings would be needed and worked. At the most advanced version of the demo, we will write the launch in 4 areas as the plugin can now:


demo, (cat in repo) , load 50% with 75 particles and 12 FPS.

Improvements to the plugin have added about 300 bytes of compressed code, but now it can be called a plugin with more reason. True, without a single method.

Other scripts for working with DOM


Such attention is paid to one script, not the most advanced, because if you look ahead, it turns out to be a small competitor to the Canvas scripts, not the one above, but well, economically written. Inefficiently written will not become competitors, so the code can not allow anything extra, so that there is something to compare with.

For example, there is a very popular DOM script called Snowstorm , with compressed code of 20K, a very large number of settings, disabling in mobile devices - there is something to learn for small scripts. But to study what is there too much and whether it leads to losses is too difficult a task. It's easier to write small and expand settings. The significance of each is found out on tests and practice.

Quickly go through another small script that is not found among the well-designed demos and sandboxes, but has interesting behavior (mentioned above, by P.Gehrig). There are no big difficulties in placing it in the sandbox - no bugs are required for modifications, jQuery does not use, but it took a lot of training for the modern doctype. Also, it used to be bad with special Unicode characters in system fonts, now it is better, therefore, the falling letters are replaced with falling textual (highlighted) snowflakes.
Year: 2005, falling-snow with settings , code , jsFiddle
Particles on demo: 25
Type: DOM
Sandbox? YES
Load: 10% (due to 8 FPS)
Code Lines: 90
Such a small system load in the original script settings is caused by a low FPS exposure. This, of course, is noticeable in the movements as a frequent slideshow. It was necessary for old browsers and is warned in old comments to the script. At 30 FPS - load 35%, about the same as the previous script will have with the same settings.

This script has a modification with the addition of the Brownian motion and with the fall as if from a distance from the screen, increasing and melting (increasing transparency) near or below.
Year: 2006, falling-snow with a "distant" fall with settings , jsFiddle
Particles on demo: 25
(watch in full screen)
Type: DOM
Sandbox? YES
Download to jsFiddle: 60% (16 FPS)
Code Lines: 100
Here, the size settings are quite “capricious” - with a small change in the growth rate, you can get huge snowflakes or not growing, so other behavioral scenarios need to be selected, and the effectiveness will ultimately depend on the window size and behavior (it does not adjust itself).A noticeable increase in load is associated with drawing large transparent characters (images). (The source code is written tightly, the actual amount of the code after thinning would be 2 times more.)

Let's write all the variants of the code with snow on Gitkhab. We take into account the shortcomings of predecessors who did not write demo pages, and therefore far fewer people looked at their code. Github allows you to extremely easily run the demo, if you work in the gh-pages branch. Now all versions of versions are easily recorded in the change history and the differences look. Github: github.com/spmbt/snowfalls .

What's up with CSS animations?


We look at examples written by others, further, in search of efficient algorithms and spectacular results.

1. An example (almost the only one with CSS animations ) of heavily loading animation on CSS3 with rotating DOM snowflakes is www.jqueryscript.net/animation/jQuery-Plugin-For-Snowfall-Effect-with-Rotating-Snowflakes.html . (This site has everything - description, code and demo for each script, but without sandboxes.)

2. Animation on 3 picture layers in CSS (Codepen).

We try to watch more animations on the canvas in order to find a script that does not heavily load the system.

Canvas, , , — 200-300, 50-100 — www.jqueryscript.net/animation/Yet-Another-Falling-Snow-Animation-with-jQuery-Canvas-GlauserChristmas.html .

Canvas , : www.jqueryscript.net/animation/Nice-Snow-Falling-Effect-with-jQuery-Canvas-Nice-Snowing.html .

, Canvas, - , 100% (, , JS). . (, .)

-


Among the scripts with snow, there are very few load-saving processors, although they are for both the DOM and Canvas. We show that the same effect of a full load can be achieved not for 100, but for a couple of thousand snowflakes, and it is better to consider normal load of a kernel by 10-20% for 200-400 pieces.

Choosing an effective Canvas


However, there was one economical script on a clean Canvas. We will do our examples approximately in his style.
Year: 2015Demo: Snow Effect using HTML5 Canvas and Javascript , full screenCopy on jsFiddle
Particles on demo: 25
Type: Canvas
Sandbox - YES
Download: 45%
Code Lines: 90
, , , , . 200 ( ) 45% ( 2 3 — Chrome Chrome helper) 60% 2000. Firefox — , 10% ( ) .
But Canvas is problematic at low loads. The load with 2 particles is often 40-60% and the same for 25, and 0 for the non-started setInterval (). Any drawing of it loads the processor (at 30 FPS - 30 percent), and the volume of drawing does not matter much. Obviously, with a worse video card, the results will be worse, and somewhere we will stop seeing improvements, it will always start to slow down if there is a Canvas, and it will only be possible to fix it by decreasing the FPS.

In more detail, the results are as follows. We take jsFiddle as less affecting the results, copy the example with the addition . , , ( , ). Activity Monitor (MacBook Intel HD Graphics 5000). Windows, , 4- , 25%. 100% , .. 25% 4. - , , , .

-10% ().
0 — 30%;
2 — 35%;
25 — 40%;
200 — 50%;
1000 — 55%;
2000 — 65%.
, .

, Canvas . , , « », , , 20%. 5 . , IE8, Canvas, 0.5 .


. , . , . — , , .

.
: 2015: , ,
: 100
: Canvas
—
: 35%
: 50
, , , , . «» , . *.999 «». , . , .

— . , , , ( , ).
2 : ,
: 1000
: Canvas
—
: 40-50% (30 FPS)
: 50
, : , . «» .

, . , . .

, , . . , ( , 30% , 120 ).


Kafeman


kafeman .
— . , . , ( 1 , 2 , 3 ) . , , . .

And we must somehow grow the snow cover: jsfiddle.net/162e4jte/3 , but not so that it swallows the entire planet with an astronaut on it. At first, he, too, lay down in bumps and melted: jsfiddle.net/162e4jte/1 . This behavior was found in the scripts of other authors.

Well, for the future, the idea of ​​combining engine generators into one also deserves execution. According to the results, in addition to the mass of third-party scripts, we have 3-4 particle motion algorithms and 2 methods of implementation, the common parts of which are well enough represented by the sandboxes and repos that are tracked.

Some statistics. Javascript , — , Canvas Javascript — . , .

Conclusion


2 — DOM- Canvas — . 50 DOM, , , . . 50 ( — 200) — — Canvas. — 30% . — , , . «» 5 , , 200 DOM 5000 Canvas.

All the excess of the algorithm for a typical commercial application (the user's attention in the area of ​​holidays) must be removed, tested algorithms on different devices and make decisions about the niche of user coverage. There may be more advantageous low-rate illumination on the Canvas or short-term fireworks on it. It does not hurt to tell which button to turn off the animation and to remember in the settings of the user that the action has worked. Since the snow is not as cash as the Yandex browser, there is no reason to "break" this button consciously. After another couple of years, one can hope that the situation with the canvas will improve, and he will slowly select for himself an area of ​​a small number of particles and an increased bitrate.

The expressive possibilities of snow scripts are mostly exhausted at this stage (nothing qualitatively new has appeared in recent years in this group). Sufficiently completed scripts have a number of properties that are recognized as necessary, and some properties that are impossible to perform in terms of performance (rotating snowflakes in 3D format) are not performed, but this does not bother anyone. But because of the productive rendering on the canvas, you can expect such scripts to appear (with a load of 30%).

Perspectives of coding - you can write constructors that would give an object for the DOM or Canvas according to the settings. Designers could write different authors. With this approach, a project was organized in HabraADM (Githab): github.com/clubadm/snowmachine . Run the current code from this repo via jsFiddle .

Source: https://habr.com/ru/post/274535/


All Articles