Вы замечали множество приложений, написанных на Canvas. Почти все они используют тяжеловесные библиотеки для реализации событий. Дело в том, что обычный HTML5 Canvas не умеет использовать события, но я научу вас их внедрять в Canvas, а если точнее — реализовывать их работу.
В теории
Мы как-бы разделяем процесс рисования и процесс выявления событий. В зависимости от ситуации, можно использовать один или два Canvas элемента (в моем случае — один). Мы находим самую верхнюю фигуру (используя алгоритмы) по координате мыши (при этом оставляя предыдущую для события mouseout) и задействуем определенные события.
Сегодня я дам упрощенный туториал по реализации событий. В дальнейшем дам тот же самый туториал, но уже с применением различных классов, объектов и т.п.
Реализация
Для реализации нам потребуется:
— Несколько фигур
— Алгоритм выделения фигуры
— События на Canvas элементе
Для начала начнем с простого кода — инициализация фигур.
var shapes = [];
function circle(ctx){
ctx.beginPath();
ctx.arc(0,0,40,0,Math.PI*2,true);
ctx.closePath();
}
function rect(ctx){
ctx.beginPath();
ctx.rect(-50,-50,100,100);
ctx.closePath();
}
shapes.push(rect,circle);
function useShape(ctx,func){
func(ctx);
}
Здесь мы видим две фигуры: круг и квадрат, и функция для их задействования. Для рисования будет использовать следующий код:
function draw(ctx){
clear(ctx);
for(var i=0;i<shapes.length;i++){
useShape(shapes[i]);
ctx.fill();
}
}
Для поиска фигуры будем использовать другой код:
function findShape(ctx,x,y){
for(var i = shapes.length - 1; i >= 0; i--){
var shape = shapes[i];
useShape(ctx,shape);
var a = ctx.isPointInPath(x,y); //Простейший алгоритм, также могу предложить использовать отдельный Canvas элемент для рисования изображения и определения уровня альфа-канала
if(a) return shape;
}
}
Теперь интересный момент
Мы реализовали базовые функции. Теперь мы должны привязать некоторые события к самому Canvas элементу.
window.onload = function(){
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.translate(64,64);
draw(ctx);
var mouseover, mouseout;
canvas.addEventListener("mousemove",function(e){
var x = e.clientX - this.getClientBoundingRect().left;
var y = e.clientY - this.getClientBoundingRect().top;
mouseout = mouseover;
mouseover = findShape(x,y);
if(mouseover != mouseout){
if(mouseout){
//Событие mouseout у фигуры mouseout
}
if(mouseover){
//Событие mouseover у фигуры mouseover
}
} else if(mouseover){
//Событие mousemove у фигуры mousemove
}
});
canvas.addEventListener("click",function(){
if(mouseover){
//Событие click у текущей фигуры
}
});
}
HTML содержимое
Для нас подойдет практически любое HTML содержание. Главное, чтобы содержал Canvas элемент с id=«canvas».
Вот самый простой пример:
<!DOCTYPE html>
<html>
<head>
<title>Canvas Events</title>
<script src="demo.js"></script>
</head>
<body>
<canvas id="canvas" width="320" height="240"></canvas>
</body>
</html>
Недостающий фрагмент
Вы наверное заметили незатронутую функцию clear? Вот сама функция:
function clear(ctx){
ctx.save();
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.restore();
}
В итоге
У нас должен получится черный квадрат с кругом внутри (который мы вряд ли увидим). Однако его события должны срабатывать при наведении на него. Я дал простой туториал по событиям в Canvas элементе.
Вы можете написать свой код, с уже более сложным содержанием (использовать классы, объекты, привязка событий к фигуре). Я лишь даю совет, как реализовать работу событий.
Прошу работу сильно не критиковать, я старался сделать свой как можно проще, передать основную мысль. Если что-то не понятно, могу дать пояснений.
Автор: Alexei03a
Здравствуйте, у Вас тут ошибка, нужно исправить.
function draw(ctx){
clear(ctx);
for(var i=0;i<shapes.length;i++){
useShape(ctx, shapes[i]);
ctx.fill();
}
}
Александр, спасибо !