Blog

Havazás effekt HTML5 Canvas-szal

Többé-kevésbé már tél van, nyakunkon a december, ezzel egyetemben a Karácsony is. Ilyenkor sokan feldobják a weboldalukat egy-egy fenyőfával, hóemberrel, díszekkel, és van aki hóesés effektet is alkalmaz a téli hangulat megteremtésére. Az alábbi bejegyzésben egy modern eljárással készült hóesést animációt szeretnék bemutatni, amely alkalmas lehet háttérebe, vagy Kellemes ünnepeket kívánó bejegyzésbe, de az alkalmazás mikéntjének igazából csak a képzeletünk szabhat határt!


Az effektet előállításához a HTML5 egyik új elemét, a Canvast fogjuk használni. Ez csupán egy problémát rejt magában, hogy csak az újabb verziójú böngészőkkel fog megjelenni az hóesés. Ez a probléma igazából csak az Internet Explorereket érinti, ahol minimum a 9-es verzióra lesz szükség a Canvas rendereléséhez. A többi elterjedt böngésző (Chrome, Safari, Firefox, Opera) gond nélkül fog vele boldogulni, ezek már régóta támogatják ezt a szolgáltatást.

Lássunk is neki. Íme a HTML kód:

<!Doctype html>
<html lang="en">
<head>
	<title>Canvas havazas</title>
	<style>
		#csnow {
			background:url('bg_winter.jpg') no-repeat;
		}
	</style>
	<script type="text/javascript" src="snowfall.js"></script>
</head>
<body onload="letSnow();">
	<canvas id="csnow" width="600" height="450"></canvas>
</body>
</html>

Nos, ezen nincs is sok magyarázni való. A szokásos HTML elemeken kívül a <canvas> elem az egyetlen amire szükségünk van. Méretének megadásával definiáljuk a rajzfelületet és adunk neki egy ID-t, amivel majd hivatkozhatunk rá.
CSS-el adhatunk neki valami jópofa hátteret, vagy alkalmazhatunk rá egyéb stílus jellemzőket, mint például egy hagyományos DIV elemnél.

És az egész lelke, a JavaScript kód:

var maxFlakes = 300;	// Hopelyhek szama
var FlakesAlpha = 6;	// Hopelyhek attetszosege
var snowCtx;
var snowflakes;

function Snowflake() {
	this.cavasWidth = csnow.width;
	this.canvasHeight = csnow.height;
	this.x = Math.round(Math.random() * this.cavasWidth);
	this.y = Math.round(Math.random() * this.canvasHeight);
	this.scale = (Math.random()*3) + 3;
	this.angle = Math.random()*6;
	this.rotationRate = (Math.random()*0.1) - 0.05;
	this.rotation = 0;
	this.alpha = this.scale/FlakesAlpha;
	this.swing = 0;
}

Snowflake.prototype.calc = function() {
	this.angle += Math.PI/180*3;
	this.swing = Math.sin(this.angle)/3;
	this.x += this.swing;
	this.y += this.scale * 0.4;
	if (this.y > this.canvasHeight + 6) {
		this.y = -6;
	}
	this.rotation += this.rotationRate;
}

Snowflake.prototype.draw = function(ctx) {
	ctx.save();
	ctx.translate(this.x-20, this.y);
	ctx.rotate(this.rotation);

	var r = this.scale;
	var ir = 0.282 * r;
	ctx.fillStyle = "rgba(255, 255, 255, "+this.alpha+")";

	ctx.beginPath();
	ctx.moveTo(0, -r);
	for (var i = 1; i <= 10; i++) {
		var rad = (i % 2) ? ir : r;
		var a = -Math.PI / 2 + i * Math.PI / 5;
		ctx.lineTo(Math.cos(a) * rad, Math.sin(a) * rad);
	}
	ctx.fill();
	ctx.restore();
}

function letSnow() {
	var snowCvs = document.getElementById('csnow');
	if (snowCvs.getContext){
		snowCtx = snowCvs.getContext('2d');
	}
	snowflakes = new Array();
	for (i=0; i<maxFlakes; i++) {
		snowflakes[i] = new Snowflake();
	}
	setInterval(render, 33);
}

function render() {
	snowCtx.clearRect(0, 0, csnow.width, csnow.height);
	for (i=0; i<snowflakes.length; i++) {
		snowflakes[i].calc()
		snowflakes[i].draw(snowCtx);
	}
}

Mint látható, ez már jóval összetettebb kód. Nem is fogom részletezni, mivel nagyrészt néhány matematikai függvény és randomizáció segítségével történik a hópehely előállítás. A scriptet beágyazhatjuk a fejlécbe, vagy elhelyezhetjük külön js fájlba is (utóbbi a javasolt a jobb átláthatóság és szerkeszthetőség érdekében).

A maxFlakes váltózóval az egyidejűleg megjelenítendő hópelyhek számát definiáljuk. A FlakesAlpha változóval pedig azok áttetszőségén változtathatunk.

Az elkészült produktum ezen az oldalon működés közben is megtekinthető. Természetesen bárki szabadon felhasználhatja, módosíthatja igénye szerint.

Letöltés: Canvas hóesés effekt (59.24 kB)

Hozzászólások

  • Barcsai Dominik szerint:

    Köszönöm a kódod, nagyon tetszik! :)
    Viszont lenne egy kérdésem: Hogy lehet pixelszám nélkül, százalékosan, egész képernyőre kirakni?
    Választ előre is köszönöm.
    Üdv.:
    Barcsai Dominik

    • blintux szerint:

      Szia!
      A canvas méretét százalékosan is meg lehet adni, tehát:
      <canvas id=”csnow” width=”100%” height=”100%”></canvas>
      Ahhoz, hogy magasságra is kitöltse az oldalt, minden szülő elemet is 100% magasságúra kell állítani. Tehát ha a canvas közvetlenül a body-ban van, akkor, a CSS:
      html, body { height: 100% }

Szóljon hozzá!

Új generációs játékok