Today – New Year’s Eve Day. And we would like to congratulate all of our readers to this wonderful event. Thank you for being with us from the beginning, feel free to visit our website and in the New Year where you will find a great variety of new tutorials and articles. Today we have prepared an interesting html5 postcard for Christmas and New Year. This is animated Snowflakes at canvas.
Welcome to test our demonstration, and download the sources
Live Demo
Live Demo 2
download in package
Step 1. HTML Markup
As usual for html5 tutorials – our HTML markup is very easy:
01 | <!DOCTYPE html> |
02 | <html lang="en"> |
03 | <head> |
04 | <meta charset="utf-8" /> |
05 | <title>Happy New Year 2013 - HTML5 card | Script Tutorials</title> |
06 | <link rel="stylesheet" href="css/main.css" type="text/css" /> |
07 | <script src="js/script.js"></script> |
08 | </head> |
09 | <body> |
10 | <header> |
11 | <h2>Happy New Year 2013 - HTML5 card (<a href="http://www.script-tutorials.com/happy-new-year-2013/">Back to original tutorial</a>)</h2> |
12 | </header> |
13 | <canvas id="panel">HTML5 compliant browser required</canvas> |
14 | </body> |
15 | </html> |
There is only single canvas element. We are going to make full screen canvas with festive background image.
Step 2. JS
Now, we please create an empty file ‘js/script.js’ and put next code inside:
001 | // canvas and context objects |
002 | var canvas, ctx; |
003 |
004 | //Snowflakes object |
005 | Snowflakes = (function () { |
006 |
007 | // sprites information |
008 | var sprCnt = 15; |
009 | var sprWidth = 80; |
010 | var sprHeight = 68; |
011 |
012 | // arrays of snowflakes and sprites |
013 | var snowflakes = []; |
014 | var snowflakeSprites = []; |
015 |
016 | // other inner params |
017 | var minScale = 0.2; // min scale for flakes |
018 | var maxScale = 1.2; // max scale for flakes |
019 |
020 | var minVerticalVelocity = 2; // min vertical velocity |
021 | var maxVerticalVelocity = 5; // max vertical velocity |
022 | var minHorizontalVelocity = -2; // min horizontal velocity |
023 | var maxHorizontalVelocity = 3; // max horizontal velocity |
024 |
025 | var minOpacity = 0.1; // min opacity |
026 | var maxOpacity = 0.9; // max opacity |
027 | var maxOpacityIncrement = 60; // opacity increment |
028 |
029 | // every flake swings in the interim between next deltas: |
030 | var minHorizontalDelta = 1; |
031 | var maxHorizontalDelta = 4; |
032 |
033 | var speed = 2; // speed |
034 |
035 | // get random number between x1 and x2 |
036 | function getRandom(x1, x2) { |
037 | return Math.random() * (x2 - x1) + x1 |
038 | } |
039 |
040 | // initialize sprites |
041 | function initializeSprites() { |
042 | var img = new Image(); |
043 | img.onload = function () { |
044 |
045 | // fill snowflakeSprites with every sprite of sprite.png |
046 | for (var i = 0; i < sprCnt; i++) { |
047 | // create new canvas |
048 | var sprite = document.createElement('canvas'); |
049 | sprite.width = sprWidth; |
050 | sprite.height = sprHeight; |
051 | var context = sprite.getContext('2d'); |
052 |
053 | // and draw every sprite at this canvas |
054 | context.drawImage(img, i * sprWidth, 0, sprWidth, sprHeight, 0, 0, sprWidth, sprHeight); |
055 |
056 | // and fill array |
057 | snowflakeSprites.push(sprite); |
058 | } |
059 | } |
060 | img.src = './sprite.png'; |
061 | }; |
062 |
063 | // initialize snowflakes |
064 | function initialize(number) { |
065 | // initialize sprites |
066 | initializeSprites(); |
067 |
068 | // prepare a necessary amount of snowflakes |
069 | for (var i = 0; i < number; i++) { |
070 | snowflakes.push(initializeSnowflake()); |
071 | } |
072 | }; |
073 |
074 | // initialize snowflake |
075 | function initializeSnowflake() { |
076 | // get random scale |
077 | var scale = getRandom(minScale, maxScale); |
078 |
079 | return { |
080 | x: Math.random() * ctx.canvas.width, // x and |
081 | y: Math.random() * ctx.canvas.height, // y positions |
082 | vv: getRandom(minVerticalVelocity, maxVerticalVelocity), // vertical and |
083 | hv: getRandom(minHorizontalVelocity, maxHorizontalVelocity), // horizontal velocity |
084 | o: getRandom(minOpacity, maxOpacity), // opacity |
085 | oi: Math.random() / maxOpacityIncrement, // opacity increment |
086 | mhd: getRandom(minHorizontalDelta, maxHorizontalDelta), // maximum horizontal delta |
087 | hd: 0, // horizontal delta |
088 | hdi: Math.random() / (maxHorizontalVelocity * minHorizontalDelta), // horizontal delta increment |
089 | sw: scale * sprWidth, // scaled sprite width |
090 | sh: scale * sprHeight, // and height |
091 | si: Math.ceil(Math.random() * (sprCnt - 1)) // sprite index |
092 | } |
093 | }; |
094 |
095 | // move flakes |
096 | function moveFlakes() { |
097 | for (var i = 0; i < snowflakes.length; i++) { |
098 | var osf = snowflakes[i]; |
099 |
100 | // shift X and Y position |
101 | osf.x += (osf.hd + osf.hv) * speed; |
102 | osf.y += osf.vv * speed; |
103 |
104 | // swings |
105 | osf.hd += osf.hdi; |
106 | if (osf.hd < -osf.mhd || osf.hd > osf.mhd) { |
107 | osf.hdi = -osf.hdi; |
108 | }; |
109 |
110 | // collision with borders |
111 | if (osf.y > ctx.canvas.height + sprHeight / 2) { |
112 | osf.y = 0 |
113 | }; |
114 | if (osf.y < 0) { |
115 | osf.y = ctx.canvas.height |
116 | }; |
117 | if (osf.x > ctx.canvas.width + sprWidth / 2) { |
118 | osf.x = 0 |
119 | }; |
120 | if (osf.x < 0) { |
121 | osf.x = ctx.canvas.width |
122 | }; |
123 |
124 | // toggle opacity |
125 | osf.o += osf.oi; |
126 | if (osf.o > maxOpacity || osf.o < minOpacity) { |
127 | osf.oi = -osf.oi |
128 | }; |
129 | if (osf.o > maxOpacity) |
130 | osf.o = maxOpacity; |
131 | if (osf.o < minOpacity) |
132 | osf.o = minOpacity; |
133 | } |
134 | } |
135 |
136 | // render frame |
137 | function renderFrame() { |
138 |
139 | // move (shift) our flakes |
140 | moveFlakes(); |
141 |
142 | // clear content |
143 | ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); |
144 |
145 | // draw each flake |
146 | for (var i = 0; i < snowflakes.length; i++) { |
147 | var osf = snowflakes[i]; |
148 | ctx.globalAlpha = osf.o; |
149 | ctx.drawImage(snowflakeSprites[osf.si], 0, 0, sprWidth, sprHeight, osf.x, osf.y, osf.sw, osf.sh); |
150 | } |
151 | } |
152 |
153 | return { |
154 | 'initialize': initialize, |
155 | 'render': renderFrame, |
156 | } |
157 | })(); |
158 |
159 | // main initialization |
160 | function initialization() { |
161 |
162 | // create canvas and context objects |
163 | canvas = document.getElementById('panel'); |
164 | ctx = canvas.getContext('2d'); |
165 |
166 | // set canvas size - fullscreen |
167 | ctx.canvas.width = window.innerWidth; |
168 | ctx.canvas.height = window.innerHeight; |
169 |
170 | // loop main scene |
171 | setInterval(Snowflakes.render, 40); |
172 | Snowflakes.initialize(100); |
173 | } |
174 |
175 | // window onload event handler |
176 | if (window.attachEvent) { |
177 | window.attachEvent('onload', initialization); |
178 | } else { |
179 | if (window.onload) { |
180 | var curronload = window.onload; |
181 | var newonload = function() { |
182 | curronload(); |
183 | initialization(); |
184 | }; |
185 | window.onload = newonload; |
186 | } else { |
187 | window.onload = initialization; |
188 | } |
189 | } |
The main concept is: in the beginning we resize our canvas object (we have to make it fullscreen), then, we initialize our snowflakes (we have to initialize various sprite images and snowflake objects), once we are ready – we can start rendering frames. Render function cleans our canvas and draws every single flake. In addition, we have to move every snowflake (download it) from left to right and back again.
Step 3. CSS
We used a very simple technique to lock full-screen background image:
1 | body { |
2 | overflow:hidden; |
3 |
4 | background: url("../christmas_tree1.jpg") no-repeat center center fixed; |
5 | -webkit-background-size: cover; |
6 | -moz-background-size: cover; |
7 | -o-background-size: cover; |
8 | background-size: cover; |
9 | } |
Live Demo
Conclusion
Happy New Year. I hope that you like our articles and experiments. Welcome back.







