А редактор на printio.ru это не серьёзно? :) Пока что работает вроде нормально, используя Fabric.js, конечно, которую я именно для редактора и написал — printio.ru/tees/new
Заняло где-то 2 часа. По размеру получается приблизительно также как и LibCanvas. Хотя сама Fabric весит меньше :P
Было бы хорошо подробно написать о том как реализовал всё это, но нет времени. В двух словах:
— В принципе всё было более менее очевидно
— В Fabric нет hover событий (не хотел добавлять из-за производительности), поэтому пришлось сделать небольшой «monkey-patching» одного из методов, чтобы это событие симулировать (~20 линий)
— В Fabric нет ничего для работы со спрайтами (так как мы на игры, например, сильно не ориентируемся), поэтому тоже пришлось вручную. Рендерил спрайт прямо на маленький канвас в памяти, с отступом, потом читая через data-url создавал картинки (~15 линий)
— Архитектурой не занимался. Можно было бы создать специальный класс для планеты с подсветкой, но я сделал всё тупо и линейно. Подсветка вокруг планеты — просто круг который показываем в нужном месте или прячем за холстом. Ну и всё остальное тоже как отдельные простые объекты — планеты как картинки (fabric.Image), орбиты как круги (fabric.Circle), текст как текст (fabric.Text). Всё создаём, добавляем на холст, запускаем анимацию вокруг центра, и следим за hover событиями. Вот и всё.
Недостаток по сравнению с LibCanvas в том что рендерим всё на одном слое, поэтому производительность скорее всего хуже. И ещё иногда вижу какой-то глюк с разпознанием планет. Иногде не подсвечиваются кажется; не уверен в чём проблема, буду разбираться как будет время.
Да, интерeсный подход. В принципе всегда можно проверить если вызов супер метода присутствует в теле функции. Если да — заворачиваем, нет — нет. Я в Fabric именно так и делаю.
Для этого используем так называемое function decompilation (function(){...} + '') и просто смотрим если присутствует наш keyword ($super, callSuper, и т.д.).
Это де факто стандарт, и присутстует практически во всех существующих движках. В идеале можно перестраховаться и добавить feature test проверяющий что действительно работает. Если нет, то заворачиваем все функции подряд (что на практике не должно произойти вообще).
все трансформации проходят только относительно центра объекта?
я бы хотел трансформации по выбранной точке делать — есть возможность?
ну вот скажем я беру кубик с левой стороны и тяну вбок — чтобы правая сторона оставалась на месте, а левая двигалась только… вытягивать в нужную сторону как бы…
Да, это был один из самых популярных запросов :) Начиная с 1.0 версии, теперь именно так всё и работает. Вот посмотрите fabricjs.com/kitchensink/
еще интересно что манипулятор трансформации именно скейлит объект, в итоге обводка объекта тоже скейлится и вытягивая квадратик получаешь по бокам другую толщину контура.
есть ли возможность при таскании за манипулятор менять не скейл объекта, а его размер? то есть width и height??
Пока нет. Но изменение габаритов углов и краёв — это не хорошо, будем исправлять.
и есть ли кривые безье? а то квадратики да кругляки как то уже не радуют, хочется гладких кривых управляемых…
Конечно! Я же даже в конце статьи упомянул.
и все сказанное можно еще к группам применительно спросить — выделяем 3 объекта и тягяем их сбоку — чтобы все не скейлились, а изменяли свои размерности и все трансформации шли по некому пайвоту. лучше всего чтобы именно как вытягивание работало все — то есть двигаем левую границу, все остальные на места остаются…
Встроенной поддержки для таких вещей как прокрутка всего канваса, увеличение или поворот — пока нет. Но в форуме можно найти несколько решений — groups.google.com/forum/#!forum/fabricjs
На самом деле стоило смотреть на новую версию, которую я разрабатываю и как раз перелил в основной бранч. Там и коммиты регулярные и вес побольше.
Отлично, подправил.
Насчёт тестов — да, в unit tests проверяю только логику. Функциональные есть, но не настолько хорошие и достаточные насколько хотелось бы. Вот например когда-то пытался использовать оффициальный SVG test suite — fabricjs.com/test/functional/ Также есть базовая проверка для Node и SVG экспорта. Будем всё это дополнять в будущем. Тестирование прорисовки через unit tests — это вообще отдельная (интересная, но не без проблем) тема.
Это фича. Я специально отказался от IE<9, т.к. там нереально реализовать всё необходимое для обратной совместимости с Canvas.
Это понятно. Но для моих целей не подходит. Даже просто показать картинку человеку и позволить её двигать и вращать по канвасу — уже хорошо. Не обязательно поддерживать полный функционал. Получается что-то вроде «progressive enhancement».
В новой версии я сделал это опциональным. Всё так же, при желании можно расширить прототипы, но теперь библиотека не требует этого
Это хорошо :)
На счёт nodeJS скажу, что лично я не юзал, но ребята на сервере его юзают)
Мы на printio.ru запускаем Fabric прямо на сервере, на Node. Всё просто летает (когда-то давно мучались с Jaxer'ом, если слышали о таком). Канвас сериализуется на клиенте, посылаем JSON на сервер, загружаем через Node и получаем картинку в любом разрешении (обычно здоровенном) через секунду.
Кстати, я нашёл отличную альтернативу этому)
Ну там в принципе и искать не надо :) Все альтернативы уже известны. Можно конечно сократить буквально до `$super()`. Но у всего как плюсы так и минусы.
Ну вот к примеру Various: Static Canvas. Что я вижу? 3 статичных объекта и 1 движущийся. Двигается один, а перерисовывается все 4 из-за того, что вызывается canvas.renderAll(). В LibCanvas мы при изменении дёргаем element.redraw(), а уже фреймворк считает, что надо перерисовать, смотрит, не затрём ли мы что-то другое и так далее. В итоге, на поле может быть сотни объектов, а проц чувствует себя спокойно.
Да, есть такое дело. Хочу заметить что в Fabric `renderAll` тоже проходит по всем объектам и говорит каждому отрисовать себя. Однако оптимизацию типа «dirty rectangles» пока не делали (вот открытый тикет кстати — github.com/kangax/fabric.js/issues/318).
Важно понимать что Fabric не позиционирует себя как framework для создания игр — у нас нет абстракций для работы со спрайтами, звуком, collision detection, и т.д. Поэтому, например, не было особого приоритета оптимизировать тысячи объектов на канвасе. Однако для удобной работы с коллажами Fabric по-моему идеален. Именно для этого я и создал его; и если посмотрите на наш редактор дизайнов — printio.ru/tees/new — я например редко вижу что-то более удобное чем у нас (даже у гигантских западных аналогов — www.zazzle.com/cr/design/pt-zazzle_shirt?style=value_tshirt)
Хитрая работа со слоями и подобная перерисовка вообще позволяют держать десятки тысяч объектов на карте и проц будет чувствовать себя прохладно)
Да конечно. Kinetic.js этим постоянно хвастается :) Возможно добавим поддержку слоёв в будущем. Пока только два статичныx — для всех объектов и для прямоугольника выбора объектов. Добавить поддержку не сложно, но надо продумать как иметь дело с групами.
Ну и мне всегда было непонятно, почему во всех либах круто раскрыта всякая банальщина вроде работы с вектором, но никаких интересностей типа графических редакторов и игр)
Опять же, зависит от назначения. Для нас SVG парсер просто необходим. Для игр он скорей всего нафиг не нужен (хотя… кто его знает) :)
Да, зависит от браузера. SVG в последнее время становится всё быстрее и быстрее. Но у меня в Chrome 25, например, 1000 кружков работают с одинаковой скоростью как на канвасе так и в SVG. Только с 5000 канвас начинает подтармаживать.
Заметьте что в изначальной (статичной) отрисовке канвас обычно всегда выигрывает у SVG.
Ну во-первых, внутри тега source другие теги не работают, поправьте пожалуйста.
Ага, не заметил. Исправлю.
Насчёт уникальности — я в принципе на неё не претендую :) Хотя не забывайте что начинал я это всё почти 4 года назад, когда ни Easel.js, ни Kinetic.js, и тем более ни Paper.js ещё не было даже в задумке.
Помню в то время был Cake.js (https://code.google.com/p/cakejs/source/detail?r=1), который сейчас уже умер.
Но это не важно. Важно качество. Именно на этом у нас фокус. А также, такие вещи как поддержка большого количества сред (cross-browser), тесты, высокая производительность, чистый код, и следование стандартам (как разработчик Prototype.js я с этим хорошо знаком). К сожелению всё ещё до сих пор сложно найти библиотеку сочетающие в себе _все_ эти качества. То одно, то другое, да и пропущено.
JCScript выглядит интересно. Видно влияние jQuery. Документация хорошая, но тесты полностью отсутствуют. Не модулярный, хотя с 58КБ (minified) это не страшно. SVG парсера нет, и интерактивный слой самый базовый (таскать можно а вращать/масштабировать нет). Перетаскивание у меня в Chrome кстати как-то медленно. В коде вижу что методы присваеваются напрямую объектам во время создания (Зачем? Это же абсолютно не эффективно. Возможно из за этого?).
LibCanvas выглядит действительно впечатляюще. Ну и размер впечатляющий (106KB плюс AtomJS как dependency). Много функционала, похоже что в основном ориентировано на игры. Опять же, тестов нет. Документация минимальная. Модулярность вроде как отсутствует. И к тому же ещё использует ES5 аксессоры, что полностью исключает IE<9 и другие пожилые браузеры. Смотря на код, вижу ещё и навешивание методов на хост-объекты. Проблемы с этим мы уже проходили в Prototype.js — я даже пост на эту тему когда-то писал :) perfectionkills.com/whats-wrong-with-extending-the-dom/ Зато в LibCanvas интерактив хороший; действительно почти как в Fabric.
Если дадите всё информацию, могу прямо сейчас добавить.
Заняло где-то 2 часа. По размеру получается приблизительно также как и LibCanvas. Хотя сама Fabric весит меньше :P
Было бы хорошо подробно написать о том как реализовал всё это, но нет времени. В двух словах:
— В принципе всё было более менее очевидно
— В Fabric нет hover событий (не хотел добавлять из-за производительности), поэтому пришлось сделать небольшой «monkey-patching» одного из методов, чтобы это событие симулировать (~20 линий)
— В Fabric нет ничего для работы со спрайтами (так как мы на игры, например, сильно не ориентируемся), поэтому тоже пришлось вручную. Рендерил спрайт прямо на маленький канвас в памяти, с отступом, потом читая через data-url создавал картинки (~15 линий)
— Архитектурой не занимался. Можно было бы создать специальный класс для планеты с подсветкой, но я сделал всё тупо и линейно. Подсветка вокруг планеты — просто круг который показываем в нужном месте или прячем за холстом. Ну и всё остальное тоже как отдельные простые объекты — планеты как картинки (fabric.Image), орбиты как круги (fabric.Circle), текст как текст (fabric.Text). Всё создаём, добавляем на холст, запускаем анимацию вокруг центра, и следим за hover событиями. Вот и всё.
Недостаток по сравнению с LibCanvas в том что рендерим всё на одном слое, поэтому производительность скорее всего хуже. И ещё иногда вижу какой-то глюк с разпознанием планет. Иногде не подсвечиваются кажется; не уверен в чём проблема, буду разбираться как будет время.
Ну а так в общем всё вроде более менее работает.
Да, интерeсный подход. В принципе всегда можно проверить если вызов супер метода присутствует в теле функции. Если да — заворачиваем, нет — нет. Я в Fabric именно так и делаю.
Для этого используем так называемое function decompilation (function(){...} + '') и просто смотрим если присутствует наш keyword ($super, callSuper, и т.д.).
Это де факто стандарт, и присутстует практически во всех существующих движках. В идеале можно перестраховаться и добавить feature test проверяющий что действительно работает. Если нет, то заворачиваем все функции подряд (что на практике не должно произойти вообще).
Да, это был один из самых популярных запросов :) Начиная с 1.0 версии, теперь именно так всё и работает. Вот посмотрите fabricjs.com/kitchensink/
Пока нет. Но изменение габаритов углов и краёв — это не хорошо, будем исправлять.
Конечно! Я же даже в конце статьи упомянул.
Ну да. Посмотрите, именно так сейчас и работает.
Отлично, подправил.
Насчёт тестов — да, в unit tests проверяю только логику. Функциональные есть, но не настолько хорошие и достаточные насколько хотелось бы. Вот например когда-то пытался использовать оффициальный SVG test suite — fabricjs.com/test/functional/ Также есть базовая проверка для Node и SVG экспорта. Будем всё это дополнять в будущем. Тестирование прорисовки через unit tests — это вообще отдельная (интересная, но не без проблем) тема.
Это понятно. Но для моих целей не подходит. Даже просто показать картинку человеку и позволить её двигать и вращать по канвасу — уже хорошо. Не обязательно поддерживать полный функционал. Получается что-то вроде «progressive enhancement».
Это хорошо :)
Мы на printio.ru запускаем Fabric прямо на сервере, на Node. Всё просто летает (когда-то давно мучались с Jaxer'ом, если слышали о таком). Канвас сериализуется на клиенте, посылаем JSON на сервер, загружаем через Node и получаем картинку в любом разрешении (обычно здоровенном) через секунду.
Ну там в принципе и искать не надо :) Все альтернативы уже известны. Можно конечно сократить буквально до `$super()`. Но у всего как плюсы так и минусы.
Да, есть такое дело. Хочу заметить что в Fabric `renderAll` тоже проходит по всем объектам и говорит каждому отрисовать себя. Однако оптимизацию типа «dirty rectangles» пока не делали (вот открытый тикет кстати — github.com/kangax/fabric.js/issues/318).
Важно понимать что Fabric не позиционирует себя как framework для создания игр — у нас нет абстракций для работы со спрайтами, звуком, collision detection, и т.д. Поэтому, например, не было особого приоритета оптимизировать тысячи объектов на канвасе. Однако для удобной работы с коллажами Fabric по-моему идеален. Именно для этого я и создал его; и если посмотрите на наш редактор дизайнов — printio.ru/tees/new — я например редко вижу что-то более удобное чем у нас (даже у гигантских западных аналогов — www.zazzle.com/cr/design/pt-zazzle_shirt?style=value_tshirt)
Да конечно. Kinetic.js этим постоянно хвастается :) Возможно добавим поддержку слоёв в будущем. Пока только два статичныx — для всех объектов и для прямоугольника выбора объектов. Добавить поддержку не сложно, но надо продумать как иметь дело с групами.
Опять же, зависит от назначения. Для нас SVG парсер просто необходим. Для игр он скорей всего нафиг не нужен (хотя… кто его знает) :)
Вот кстати есть такой документик о том когда стоит использовать Fabric, а когда нет — github.com/kangax/fabric.js/wiki/When-to-use-Fabric
Заметьте что в изначальной (статичной) отрисовке канвас обычно всегда выигрывает у SVG.
Ага, не заметил. Исправлю.
Насчёт уникальности — я в принципе на неё не претендую :) Хотя не забывайте что начинал я это всё почти 4 года назад, когда ни Easel.js, ни Kinetic.js, и тем более ни Paper.js ещё не было даже в задумке.
Помню в то время был Cake.js (https://code.google.com/p/cakejs/source/detail?r=1), который сейчас уже умер.
Но это не важно. Важно качество. Именно на этом у нас фокус. А также, такие вещи как поддержка большого количества сред (cross-browser), тесты, высокая производительность, чистый код, и следование стандартам (как разработчик Prototype.js я с этим хорошо знаком). К сожелению всё ещё до сих пор сложно найти библиотеку сочетающие в себе _все_ эти качества. То одно, то другое, да и пропущено.
Даже взять, к примеру, упомянытые вами LibCanvas и JCScript (о которых я до этого не слышал). Посмотрел, ради интереса. Добавил в таблицу сравнения — docs.google.com/spreadsheet/ccc?key=0Aqj_mVmuz3Y8dHNhUVFDYlRaaXlyX0xYSTVnalV5ZlE#gid=0
JCScript выглядит интересно. Видно влияние jQuery. Документация хорошая, но тесты полностью отсутствуют. Не модулярный, хотя с 58КБ (minified) это не страшно. SVG парсера нет, и интерактивный слой самый базовый (таскать можно а вращать/масштабировать нет). Перетаскивание у меня в Chrome кстати как-то медленно. В коде вижу что методы присваеваются напрямую объектам во время создания (Зачем? Это же абсолютно не эффективно. Возможно из за этого?).
LibCanvas выглядит действительно впечатляюще. Ну и размер впечатляющий (106KB плюс AtomJS как dependency). Много функционала, похоже что в основном ориентировано на игры. Опять же, тестов нет. Документация минимальная. Модулярность вроде как отсутствует. И к тому же ещё использует ES5 аксессоры, что полностью исключает IE<9 и другие пожилые браузеры. Смотря на код, вижу ещё и навешивание методов на хост-объекты. Проблемы с этим мы уже проходили в Prototype.js — я даже пост на эту тему когда-то писал :) perfectionkills.com/whats-wrong-with-extending-the-dom/ Зато в LibCanvas интерактив хороший; действительно почти как в Fabric.
Ну если сравнивать с попиксельным рисованием, то может быть и шучу :)
На самом деле, очень много повторяющихся конструкций и абстракция действительно помогает.
Из игр, я видел только тетрис — end3r.com/games/fabrictetris/
fabricjs.com/per-pixel-drag-drop/