Lecaw

Учимся создавать Web-сайты

Огненное меню на HTML5 Canvas

June 1, 2012 490hits

Вы нибудь задумались о создании интерактивного навигационного меню на HTML5? Да, это - странная идея, но возможно, что такую идею используете и вы в своем проекте. Поэтому, я решил создать  наше первое, чистое html5 меню (в основном – это - некоторый набор кнопок). Мы создадим эти кнопки с аффектом огня.

ДЕМО

 

Шаг 1. HTML разметка

Наша основная HTML разметка очень проста:

<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="utf-8" />
<title>HTML5 Canvas Navigation menu with Fire | Script Tutorials</title>
<link rel="stylesheet" href="/css/main.css" type="text/css" />
<script src="/js/vector2d.js"></script>
<script src="/js/fire_menu.js"></script>
</head>
<body>
<canvas id="panel" width="1000px" height="100px">HTML5 compliant browser required</canvas>
<img id="image" src="/images/bg.jpg" />
</body>
</html>

Есть только единственный элемент canvas. Плюс – одно изображение непосредственно после этого элемента.

Шаг 2. JS

Теперь, мы должны создать новый файл "js/fire_menu.js'' и вставить в него  следующий код:

// Button object
function Button(x, y, w, h, state, image, text) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.state = state;
    this.imageShift = 0;
    this.image = image;
    this.text = text;
}
// Draw Button function
function drawButton(ctx, button) {
    // draw button image
    ctx.drawImage(button.image, 0, button.imageShift, button.w, button.h, button.x, button.y, button.w, button.h);
    // and text
    ctx.fillText(button.text, button.x + button.w / 2, 5 + button.y + button.h / 2);
}
// Get mouse position function
function getMousePosition(e){
    if (!e){
        var e = window.event;
    }
    if (e.pageX || e.pageY){
        return new vector2d(e.pageX, e.pageY);
    } else if (e.clientX || e.clientY){
        return new vector2d(e.clientX, e.clientY);
    }
}
// Inner variables
var canvas, ctx;
var data_width;
var data_height;
var colors = [];
var out_data = [];
var buttons = [];
// Fill new array with certain value
function fill_new_array(len, val) {
    var rv = new Array(len);
    while (--len >= 0) {
        rv[len] = val;
    }
    return rv;
}
// Prepare palette function
function prepare_palette() {
    for (var i = 0; i < 64; ++i) {
        colors[i + 0] = {r: 0, g: 0, b: i << 1, a: i};
        colors[i + 64] = {r: i << 3, g: 0, b: 128 - (i << 2), a: i+64};
        colors[i + 128] = {r: 255, g: i << 1, b: 0, a: i+128};
        colors[i + 192] = {r: 255, g: 255, b: i << 2, a: i+192};
    }
}
// Draw Main scene
function drawScene() {
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // clear canvas
    // Draw fire
    var data_cnt = data_width * (data_height - 1);
    for (var i = 0; i < data_width; i++) {
        out_data[data_cnt + i] = (0.6 > Math.random()) ? 255 : 20;
    }
    for (var y = 0; y < 100; y++){
        for (var x = 10; x < data_width - 10; x++){
            var s = data_cnt + x;
            var temp_data = out_data[s] + out_data[s + 1] + out_data[s - 1] + out_data[s - data_width];
            temp_data >>= 2;
            if (temp_data > 1){
                temp_data -= 1;
            }
            temp_data < buttons[i].x && mouse.x < buttons[i].x+buttons[i].w && mouse.y > buttons[i].y && mouse.y < buttons[i].y+buttons[i].h) {
                    buttons[i].state = 'hover';
                    buttons[i].imageShift = 136;
                }
            }
        }
    }
    // Onmousedown event handler
    canvas.onmousedown = function(e) {
        var mouse = getMousePosition(e).sub(new vector2d(canvas.offsetLeft, canvas.offsetTop));
        for (var i = 0; i < buttons.length; i++) { // Apply 'pressed' state for buttons
            if (mouse.x > buttons[i].x && mouse.x < buttons[i].x+buttons[i].w && mouse.y > buttons[i].y && mouse.y < buttons[i].y+buttons[i].h) {
                buttons[i].state = 'pressed';
                buttons[i].imageShift = 68;
            }
        }
    }
    // Onmouseup event handler
    canvas.onmouseup = function(e) {
        var mouse = getMousePosition(e).sub(new vector2d(canvas.offsetLeft, canvas.offsetTop));
        for (var i = 0; i < buttons.length; i++) { // Reset states for buttons
            if (mouse.x > buttons[i].x && mouse.x < buttons[i].x+buttons[i].w && mouse.y > buttons[i].y && mouse.y < buttons[i].y+buttons[i].h) {
                alert(buttons[i].text + ' is pushed');
            }
            buttons[i].state = 'normal';
            buttons[i].imageShift = 0;
        }
    }
}

Основная идея нашего меню – помещаем несколько кнопок в элемент canvas, а затем – добавляем обработчики событий. Поэтому наша дополнительная функция – добавила анимации к огню на фоне. Я уверен, что наше демо вдохновит вас на новые идеи для ваших проектов.

Шаг 3. Дополнительные файлы

Наверно, вы заметили, что я использую дополнительные файлы в нашем проекте: main.css, Ds-digib.ttf, bg.jpg, button.png и vector2d.js. Все эти файлы доступны для загрузки.

ДЕМО

 

Дополнительная информация

Влерий Аликин - веб-разработчик & дизайнер. Соучредитель и член команды Lecaw.

Эл. почта
RATTING:
(0 голосов)

Оставить комментарий