Menu w html5 canvas

W tutorialu pokażę jak stworzyć ciekawe menu wykorzystując html5 canvas (menu html5 canvas - demo). Na początek przygotujmy dokument html. W sekcji head załączamy bibliotekę jquery, skrypt menu_shape.js, w którym umieścimy kod skryptu odpowiedzialnego za działanie menu oraz trochę stylów css. W sekcji body umieszczamy element canvas oraz listę ul z odnośnikami do poszczególnych sekcji menu.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>Html5 canvas menu - demo</title>
	<link href="css/menu.css" rel="stylesheet" type="text/css" />
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
	<script type="text/javascript" src="js/menu_shape.js"></script>
	<style type="text/css">
		body {
			background:url("bg2.jpg") no-repeat top center;
		}
		div.container {
			position:relative;
			margin:50px auto 0 auto;
			width:800px;
		}
		#menu_shape {
			position:absolute;
			top:0;
			padding:0;
			margin:17px 0 0 20px;
			width:100%;
		}
		#menu_shape li {
			float:left;
			list-style:none;
			padding:0;
			margin:0;
			margin-right:10px;
		}
		#menu_shape li a {
			text-decoration:none;
			font:14px Verdana, Arial, Helvetica, sans-serif;
			color:white;
			font-weight:bold;
			width:180px;
			float:left;
			text-align:center;
		}
	</style>
</head>
<body>
	<div class="container">
	<canvas id="canvas" width="800px" height="100px"></canvas>
	<ul id="menu_shape">
		<li><a href="#">HOME</a></li>
		<li><a href="#">PORTFOLIO</a></li>
		<li><a href="#">CONTACT</a></li>
	</ul>
	</div>
</body>
</html>
Menu html5 canvas Teraz będziemy stopniowo uzupełniać plik javascript. Najpierw łapiemy element canvas oraz jego context. Ustalamy również startowe wartości pomocniczych zmiennych (kappa - poziom zaokręglenia elipsy, up - zmienna do sprawdzania, w którą stronę idzie animacja, all - zlicza liczę elementów li w menu).
$(document).ready(function() {
	var canvas = document.getElementById("canvas"), context = canvas.getContext("2d");
	var kappa = 0.75;
	var up = true, interval, all = $('#menu_shape li').length;
});
Dopiszmy funkcję rysującą elipsę i narysujmy trzy elipsy odpowiadające li w naszym menu.
function drawEllipse(context, x, y, w, h, number_ellipse,kappa) {
	ox = (w / 2) * kappa,
	oy = (h / 2) * kappa,
	x = x+((number_ellipse-1)*190),//odpowiednie przesuniecie elipsy aby pasowala do kolejnego li
	xe = x + w,
	ye = y + h,
	xm = x + w / 2,
	ym = y + h / 2;
	context.fillStyle = 'rgba(112,209,215,0.3)';
	context.strokeStyle = 'rgba(112,209,215,0.6)';
	context.beginPath();
	context.moveTo(x, ym);
	context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
	context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
	context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
	context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
	context.closePath();
	context.stroke();
	context.fill();
}
drawEllipse(context, 20, 5, 180, 40, 1, kappa);
drawEllipse(context, 20, 5, 180, 40, 2, kappa);
drawEllipse(context, 20, 5, 180, 40, 3, kappa);
Wprowadzimy teraz obsługę zdarzenia hover na elemencie menu. Po najechaniu wskaźnikiem myszy na li uruchomi się funkcja anim_menu, po zjechaniu stop_anim_menu.
$('#menu_shape li').hover(function() {
	anim_menu(this);
},
function() {
	stop_anim_menu(this);
});
Pozostała nam już tylko implementacja funkcji animujących.
function anim_menu(element)
{
	var ind = $(element).index();
	interval = window.setInterval(function() {
	if(kappa>=1.4)
	{
		up = false;
	}
	if(kappa<=0.7)
	{
		up = true;
	}
	if(up)
	{
		kappa+=0.1;
	}
	if(!up)
	{
		kappa-=0.1;
	}
	context.clearRect(0,0,canvas.width,canvas.height);
	//rysujemy przekształconą elipsę
	drawEllipse(context, 20, 5, 180, 40, ind+1, kappa);
	//poniższa petla ustawia pozostale elipsy w swoich pozycjach
	for(var i=1; i <= all;i++)
	{
		if(i != ind+1)
		{
			drawEllipse(context, 20, 5, 180, 40, i, 0.75);
		}
	}
	},
	100);
}
function stop_anim_menu(element)
{
	window.clearInterval(interval);
	context.clearRect(0,0,canvas.width,canvas.height);
	for(var i=1; i <= all;i++)
	{
		drawEllipse(context, 20, 5, 180, 40, i, 0.75);
	}
}
Animacja polega na przekształcaniu elipsy. Po zjechaniu wskaźnika myszy z li przerywamy animację (clearInterval) i ustawiamy nasze elipsy w wyjściowej pozycji.