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>

Dopiszmy funkcję rysującą elipsę i narysujmy trzy elipsy odpowiadające li w naszym 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;
- });
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.
- 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);
Pozostała nam już tylko implementacja funkcji animujących.
- $('#menu_shape li').hover(function() {
- anim_menu(this);
- },
- function() {
- stop_anim_menu(this);
- });
Animacja polega na przekształcaniu elipsy. Po zjechaniu wskaźnika myszy z li przerywamy animację (clearInterval) i ustawiamy nasze elipsy w wyjściowej pozycji.
- 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);
- }
- }