Русские документы
Ежедневные компьютерные новости RSS rusdoc.ru  Найти :
• Новости
• Последние поступления
• Книжный магазин
  Hardware:
• Видеоустройства
• Системные платы
• Процессоры
• Мобильные устройства
• Аудиосистема
• Охлаждение системы
• Накопители информации
• КПК и ноутбуки
• Телефоны и связь
• Периферия
• Система
• Сети
• Разные устройства
 
  Programming:
• Web-разработка
• Языки программирования
• Технологии и теория
• Разработка игр
• Программная инженерия
 
  Software:
• Операционные системы
• Windows 7
• Базы данных
• Обзоры программ
• Графика и дизайн
   
  Life:
• Компьютерная жизнь
• Разные материалы
   
• Партнеры
• Публикация
• Правовая информация
• Реклама на сайте
• Обратная связь
• Экспорт в RSS Экспорт в RSS2.0
    Читать в Яндекс.Ленте



«LibCanvas» — фреймворк для работы с Javascript Canvas

Раздел: Programming / JavaScript @ 08.04.2010 | Ключевые слова: libcanvas фреймворк javascript javascript framework версия для печати

Автор: TheShock
Источник: habrahabr

Думаю, люди, которые следят за моим творчеством, заметили, что я очень увлекся рисованием на Canvas в Javascript. Возможно это немного излишне, но ничего не могу с собой поделать, уж очень нравится эта технология. Так нравится, что я аж буду выступать на конференции с докладом о ней (Пономаренко Павел).

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



Инструментарий


Я безумно люблю JQuery, Я считаю его идеальным фреймворком для работы с DOM и сейчас, когда я от него отказался в этом фреймворке — я еще раз убедился в этом. Но вне DOM, имхо, JQuery становится слишком громоздким и его философия только раздражает. Потому изначально я решил написать сообственный фреймворк. расширяя прототипы втроенных объектов и создавая базовые функции для работы с DOM. В определенный момент гугля в поисках интересных решений с наследованием в Javascript я осознал одну истину: я пишу MooTools. Потому мною было принято решение, этот фреймворк был за пару часов изучен в достаточной для работы степени и я переписал весь, практически готовый проект (заодно отрефакторив) на новом фреймворке, о чем не жалею(Тем не менее для работы с DOM мне все равно намного приятнее JQuery). Кое-чего в MooTools мне таки не хватило, потому пришлось дорасширить втроенные объекты, добавив в их прототипы парочку методов)

Сообственно сам фреймворк


Все классы фреймворка находятся в пространстве имен LibCanvas.*. Я старался сделать его максимально изящным, исправив те недостатки, которые я смог заметить. Описание может показаться несколько сумбурным (в силу целой ночи программинга и того, что щас 7 часов утра, но с живым примером в конце станет яснее)

Оболочка


Я предлагаю работать с канвасом через некую универсальную оболочку, в которую уже встроен ImagePreloader, ProgressBar, fps-метер и другие фенечки.
new LibCanvas.Canvas2D($(`canvas`))
    .
setFps(50) // количество фпс, которое браузер постарается рендерить
    
.fpsMeter(20) // включаем измеритель фпс. он будет брать последних N каждов, получать среднее значение и выводить количество fps
    
.setConfig({
        
background  : `#EFEBE7`, // этим фоном заливаемся весь холст
        
images      : App.imagesList, // пока эти картинки не загрузятся - канвас работу не начнет 
        
progressBar : App.progressBarStyle // но чтобы пользователь не впал в ступор - покажем прогрессбар
    
})
    .
addElement(new App.MyFirstElement()) // Добавляем пару элементов в канвас
    
.addElement(new App.SecondElement()) // кажыдй кадр будет вызывать их метод .draw()
    
.start(); // сюда можно также передать ф-цию, в которой сделать дополнительные действия


Изменение Контекста


Мне всегда не нравилось во встроенном контексте две вещи: то, что функции возвращают undefined вместо this из-за чего нельзя делать цепочки вызовов и иногда функции с огромным количеством одинаковых аргументов, например:
ctx.drawImage(image, 15, 16, 12, 34, 56, 12, 32, 45);

Я создал свой контекст с бле с возвращаемым this, именованными параметрами и еще некоторыми плюшками. Замечу, что он обратно-совместим с обычным контекстом, хотя его использовать и не рекомендуется. Получить его очень просто:
$(`canvas`).getContext(`2d-libcanvas`)

Замечу, что отныне очень просто создавать свои контексты (если они вам нужны), для примера смотрите ./js/Libs/LibCanvas/Core/Context2D.js:
LibCanvas.addCanvasContext(`2d-libcanvas`, LibCanvas.Context2D);

На случай, если вы переопределили один из втроенных контекстов — всегда можно вызвать оригинальный:
$(`canvas`).getOriginalContext(`2d`);

Но контекст перетерпел кое-какие изменения и теперь стал удобнее. Например, теперь когда вы рисуете картинку — нет потребности догадываться, где какой параметр что значит (можно использовать любую пару from-to, from-size, to-size):
ctx.drawImage({
    
image : images[`ufo`],
    
crop  : {
        
from : [40, 80], 
        
to   : [120, 160]
    },
    
draw  : {
        
from : [80, 80]
        
size : [160, 160]
    }
})


И еще несколько косметических изменений:
ctx.fillAll(`green`) // Все полотно залили зеленым
    
.set(`strokeStyle`, `red`)
    .
stroke(new CanvasLib.Shapes.Polygon([
        [
231,  67],
        [
281,  67],
        [
317, 103],
        [
317, 153],
        [
281, 189],
        [
231, 189],
        [
195, 153],
        [
195, 103]
    ])) 
// обвели восьмиугольник
    
.arc({
        
circle : [100, 60, 40], // круг с центром в 100:60, радиусом 40 пикселей
        
angle  : [(5).degree(), (35).degree()] // c 5 по 35 градус
    
})

Замечу, что Number.degree() возвращает то вменяемое число градусов, которое было в Number, но в радианах, которые больше любит техника.

Фигуры


На базе CanvasLib.Shapes.* строится практически половина возможностей фреймворка. На данный момент там есть только три фигуры — Polygon, Circle, Rectangle, но со временем количество будет увеличиватся, например добавится RoundedRectangle, может еще что-то. Естественно можно создавать свои фигуры. Но важным при этом является реализация правильного алгоритма определения, находится ли определенная точка в пределах этой фигуры или нет. Поиск CanvasLib.Shapes.* в текущей версии находит 26 упоминаний.

Мышь и события


Самое интересное. В фреймворке реализованы события внутри элемента канвас а-ля тех, что мы используем в html. Изначально никак не задать обработку, например, mouseover на определенный объект внутри Канвас, это событие срабатывает только на сам html-элемент. Фреймворк позволяет работать с событиями очень легко и расширяемо. Достаточно подписаться на рассылку сообщений о событиях:
this.canvas.mouse.subscribe(this);

И при каждом событии будет вызывать метод event c именем события. На данный момент реализованы следующие: [click, mouseover, mousemove, mouseout, mouseup, mousedown], а также [away:mouseover, away:mousemove, away:mouseout, away:mouseup, away:mousedown] в случае, если событие произошло вне элемента. Для того, чтобы событие обработалось необходимо, чтобы элемент возвращал фигуру(getShape) у которой есть метод hasDot. То есть, например, если у нас есть круглая кнопка метод должен вернуть фигуру Circle "покарывающую" эту кнопку.
Иногда вместо того, чтобы обрабатывать евенты достаточно унаследоваться от LibCanvas.InterfaceElement, что позволит создавать объект, рендерящийся одним и з трех методов, зависимо от состояния:
elem.drawStandart(); // обычный метод
elem.drawHover();    // при наведенной мышке
elem.drawActive();   // когда объект нажат
, а также можно bind`ить и unbind`ить функции на события (как в том же ДжиКвери при работе с дом), что идеально для создания игр и GUI.

Пример


Заметьте, что само приложение - это только ./js/App/* и ./js/Start.js. Все остальное - фреймворк. Представте, насколько пришлось бы писать тяжелую логику, чтобы это обработать без фреймворка!
Желтая круглая фигня в правом нижнем углу - это EventsTester. Он подписан на события и выводит в правую панель состояние события. Если событие уже было хоть раз вызвано - меняются только координаты. Вы можете посмотреть, как для него выглядят все события, что происходят на хлсте.
Три фигни сверху - это LibCanvas.InterfaceElement, о котором я писал чуть выше. На них повешена через elem.bind(`click`, fn);
функция, которая показывает соответствующую картинку. Таким образом можна сделать, например, табы, как в JQueryUI. Или интерфейс какой-то игрушки)

Основные недоработки


1. Несколько функций в контексте остались со старым интерфейсом (например , setTransform). Я их не очень заю и на знаю, как их сделать удобнее для пользователя
2. Возможно недостаточно тестировалось
3. Осел не поддерживается. Опера, Хром и Фокс - работает

Благодарности


Спасибо за помощь моему другу greedykid, а также прекрасной девушке nutochka, (которая, между прочим, участвует в Miss IT) и помогала мне делать эту либу. Без вас я бы не справился.
Пользуясь случаем передаю привет маме и папе

Ссылки и лицензия


Лицензия - LGPL, скачать можно, как всегда на гуглокоде: code.google.com/p/libcanvas/

Это интересно:








версия для печатиРаспечатать статью


Вернуться в раздел: Programming / JavaScript


Реклама:
Читать наc на:

Add to Google
Читать в Яндекс.Ленте






Rambler's Top100
© Copyright 1998-2012 Александр Томов. All rights reserved.