Давно уж хотел написать нечто подобное, потому как штатных средств для анимации и отлова событий у элемента HTML5 Canvas не предусмотрено.
Сразу предупреждаю - проект очень сырой, написан за два вечера на коленке.
Итак представляю вашему вниманию фреймворк (как звучит-то
) ExtCanvas, от словосочетания Extended Canvas.
Что он умеет:
- работать с фигурами как с объектами;
- анимировать любые числовые параметры фигур, такие как координаты, размеры и т. п. (анимация CSS-цветов в разработке);
- изменять параметры фигур без анимации;
- обрабатывать события мыши для каждой фигуры в отдельности.
Что он не умеет:
- обработчик событий не работает если фигура была нарисована не способом "beginPath - рисуем - closePath" (надеюсь в будущих выпусках спецификации это исправят).
Фреймворк работает полностью автономно, то есть не нужно никаких дополнительных библиотек, что в сумме с очень маленьким размером (14 кб в несжатом виде) делает его загрузку моментальной.
Инициализируется вот так:
var canvas = document.getElementById('canvasId');
var extcanvas = new ExtCanvas(canvas);
В качестве аргумента конструктору можно передавать элемент, контекст или просто ID элемента (хотя в идеале я хочу сделать выбор по CSS селектору как в jQuery), инициализация нативная.
Рисуются фигуры вот так:
var circle = extcanvas.addShape(function(x, y, radius) {
// Эта функция выполняется в контексте CanvasRenderingContext2D, поэтому можно использовать this для рисования
this.beginPath();
this.arc(x, y, radius, 0, Math.PI * 2, false);
this.closePath();
this.fillStyle = '#F00';
this.fill();
}, {
// Эти параметры будут переданы как аргументы в предыдущую функцию
// Если параметр не задекларирован здесь, то он не сможет принимать участие в анимации
x: 100,
y: 100,
radius: 50
});
Для того чтобы изменить один или несколько параметров нужно написать:
circle.set({
x: 150,
y: 150
});
После этого окружность поменяет свои координаты. Те параметры, которые не были указаны, останутся без изменений.
Для того чтобы создать анимацию, например, плавного увеличения окружности в течение 500 мс, пишем вот так:
circle.animate({
radius: 75
}, 500, function() {
// Здесь можно написать функцию обратного вызова
});
Устанавливать обработчики событий можно двумя способами - аля jQuery и в стиле стандартного addEventListener:
circle.hover(function() {
alert('Навели мышку.');
}, function() {
alert('Отвели мышку.');
});
circle.addEventListener('mouseclick', function(event) {
// Переменная event содержит в себе текущие координаты курсора, на каком объекте он расположен и т. п.
alert('Клацнули мышкой');
});
Обработчики суммируются, то есть будут выполняться в порядке их установления (нужно будет, кстати, сделать возможность удаления обработчиков).
Сейчас фреймворк обрабатывает такие события:
- mousemove
- mouseover
- mouseout
- mousedown
- mouseup
- mouseclick
Посмотреть исходник с простенькой демонстрашкой можно
тут. С красотами не заморачивался, нарисовал пару примитивов чтоб что-то мельтешило, фигурки можно таскать мышкой.
Программированием занимаюсь менее года, поэтому сильно не пинать. А вообще рад буду выслушать конструктивную критику и рекомендации.