FiveGUI — красивые кнопочки для canvas'a

    Всем привет. Я не выдержал и решил поделиться со всеми тем, чем сейчас более-менее активно занимаюсь.



    Примерно месяц назад я продолжил экспериментировать с Canvas'ом и зачем-то мне понадобилась кнопочка. Да, самая обычная кнопочка, которую можно было бы затолкать на страничку обычным тегом, но это ведь не путь истинного самурая. В итоге были обшарены все закрома github'a и gitorious'a, гугл затерт до дыр, а подходящего инстумента так и не нашлось. Разве что libCanvas хвастался подобными примерами… Но их я обнаружил уже после начала работы, так что решил не забрасывать.


    В общем и целом FiveGUI — это набор виджетов графического интерфейса, который позволяет отрисовывать на canvas'e красивые кнопочки, слайдеры, кусочки текста и прочие плюшки обычных интерфейсов, при этом совершенно не ломая логику работы того, что уже отрисовывается на нашей канве. Все, что нужно для начала работы — это создать на странице объект GUI, прибить его к существующей канве, добавить к нему элементов и вызвать метод .draw(). Примерно вот так:

    <html>
        <body>
            <canvas id="canvas" width="600" height="400"></canvas>
        </body>
        <script>
                G = new FiveGUI.GUI({
                    canvas: "canvas",
                    fontColor: "#fff"
                });
    
                Region = new FiveGUI.GUIRegion({
                    x: 50,
                    y: 50,
                    width: 400,
                    height: 325,
                });
    
                Button = new FiveGUI.GUIButton({
                    x: 10,
                    y: 30,
                    width: 108,
                    height: 22,
                    caption: "GUIButton",
                    value: null,
                    borderWidth: 2,
                    borderColor: "#aaa",
                    hoverBorderColor: "#ccc",
                    clickBorderColor: "#eee"
                });
    
                Region.addElement(Button);
                G.addElement(Region);
    
                G.drawGUI();
    
        </script>
    </html>
    


    В итоге получим блок с кнопочкой. На страничке библиотеки так же есть пример, как заставить кнопочку выполнять какие-то полезные действия.

    Прошу прощения за отсутствие внятной документации и толкового howto. В самое ближайшее время постараюсь все это закончить, но такак сами исходники сейчас в довольно сыром состоянии (так и не удалось добиться работы с Опере, IE даже не смотрел, т.к. не на чем) — адеюсь все это сделать как можно быстрее не в ущерб всему остальному.

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

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

    В общем, если она окажется для вас полезным и приятным дополнением во время экспериментов с canvas'ом — я буду очень рад.

    Работающие примеры можно посмотреть здесь:

    http://fivegui.elhsmart.net.ru

    Github:

    https://github.com/elhsmart/FiveGUI

    P.S. Как я отмечал выше — стабильно работает в последних версиях FF и Chrome. IE9 у меня нет (если кто может проверить — пожалуйста, расскажите мне, что там происходит), а Oper'у еще не довел до ума.

    P.S.S. Вся графика в примерах заимствована из игры Battle for Wesnoth. Надеюсь, ребята на меня не будут сильно обижаться, ибо дизайнер интерфейсов из меня никакущий и попытки нарисовать красивую кнопочку были бы долгими, болезненными и мучительными.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 58

      +4
      а почему у checkbox не работает <label>?
        –7
        Хм… Скорее всего потому что я изначально решил отделить мух от котлет и не привязывать к checkbox'у функционал, который ему, по большому счету, не нужен. Но если кому-то будет так уж необходимо это в обязательном порядке — попробую сделать, не проблема.
          +14
          Ну, вообще-то, label является чуть ли не основным элементом чекбокса ;)
            +2
            Возможно моя позиция действительно выглядит как банальное ламерство и незнание и я оговорился. Я знаю, что в стандартной реализации HTML у чекбокса есть label. И он там не зря, да. Просто я его решил сделать отдельным элементом GUILabel.
              +2
              Просто в случае с чекбоксами и радиокнопками label выполняет очень важную функцию с точки зрения юзабилити — расширяет поле, куда надо ткнуть, чтобы соответсвующий контрол сработал.
                0
                Хм… От этом я не подумал, спасибо. Обязательно добавлю.
                ЭТо еще раз говорит о том, что каждый элемент нужно очень подробно изучать.
                  +2
                  В целом, это — стандартное поведение label'ов — переводить фокус на связаный элемент. То есть даже если label у текстбокса, то щелчок по такому label'у должен фокусировать текстбокс. Просто в случае с чекбоксами и радиокнопками это наиболее заметно.
        +3
        И у радиобатона надо бы как-нибудь отличие от чекбокса — кружок вместо квадратика
          +1
          И еще — почему нельзя ткнуть в какое-либо положение на слайдере чтобы туда поставить сразу, без дёрганья крутилки?
        –10
        В IE8 не работает:

        Сведения об ошибке на веб-странице

        Сообщение: 'FiveGUI.GUILib' - есть null или не является объектом
        Строка: 38
        Символ: 1
        Код: 0
        URI-код: fivegui.elhsmart.net.ru/js/FiveGUI/src/GUILabel.js

        Сообщение: 'FiveGUI.GUILib' - есть null или не является объектом
        Строка: 37
        Символ: 1
        Код: 0
        URI-код: fivegui.elhsmart.net.ru/js/FiveGUI/src/GUICheckbox.js

        Сообщение: 'FiveGUI.GUILib' - есть null или не является объектом
        Строка: 37
        Символ: 1
        Код: 0
        URI-код: fivegui.elhsmart.net.ru/js/FiveGUI/src/GUIRadiobutton.js

        Сообщение: 'FiveGUI.GUILib' - есть null или не является объектом
        Строка: 41
        Символ: 1
        Код: 0
        URI-код: fivegui.elhsmart.net.ru/js/FiveGUI/src/GUITextfield.js

        Сообщение: 'FiveGUI.GUILib' - есть null или не является объектом
        Строка: 41
        Символ: 1
        Код: 0
        URI-код: fivegui.elhsmart.net.ru/js/FiveGUI/src/GUIDropdown.js

        Сообщение: 'FiveGUI.GUILib' - есть null или не является объектом
        Строка: 36
        Символ: 1
        Код: 0
        URI-код: fivegui.elhsmart.net.ru/js/FiveGUI/src/GUISelect.js

        Сообщение: 'FiveGUI.GUILib' - есть null или не является объектом
        Строка: 46
        Символ: 1
        Код: 0
        URI-код: fivegui.elhsmart.net.ru/js/FiveGUI/src/GUITextarea.js

        Сообщение: 'FiveGUI.GUILib' - есть null или не является объектом
        Строка: 6
        Символ: 1
        Код: 0
        URI-код: fivegui.elhsmart.net.ru/js/FiveGUI/src/GUIWindow.js

        Сообщение: 'FiveGUI.GUILib' - есть null или не является объектом
        Строка: 43
        Символ: 1
        Код: 0
        URI-код: fivegui.elhsmart.net.ru/js/FiveGUI/src/GUIOption.js

        Сообщение: 'FiveGUI.GUILib' - есть null или не является объектом
        Строка: 41
        Символ: 1
        Код: 0
        URI-код: fivegui.elhsmart.net.ru/js/FiveGUI/src/GUISlider.js

        Сообщение: 'FiveGUI.GUILib' - есть null или не является объектом
        Строка: 39
        Символ: 1
        Код: 0
        URI-код: fivegui.elhsmart.net.ru/js/FiveGUI/src/GUIProgressbar.js

        Сообщение: Предполагается наличие идентификатора, строки или числа
        Строка: 337
        Символ: 13
        Код: 0
        URI-код: fivegui.elhsmart.net.ru/skinned-dynamic.html
          +16
          а вас не смутило слово canvas в заголовке?
          +2
          Дропдаун не закрывается если ничего не выбирать и продолжать работу с интерфейсом.
            0
            Спасибо, на днях поправлю.
            0
            в IE9 не работает.
            пишет ошибку:

            SCRIPT438: Объект не поддерживает это свойство или метод
            GFX.js, строка 93 символ 5


              0
              Спасибо, обязательно поковыряюсь и исправлю, если найду IE9
              0
              В Опере обе версии со скинами не работают.
                0
                Я уже даже знаю, в чем причина. Спасибо, поправлю.
                0
                Не считайте это за придирку, просто как вектор развития — работает из рук вон плохо на iOS и Android.
                  0
                  Спасибо, я вообще удивлен, что работает на iOS и Android. Как только найду доступ к телефонам с этими операционками — постараюсь исправить.
                    –2
                    Ну для Андроида можно эмулятор скачать…
                    • UFO just landed and posted this here
                        –2
                        Да ладно, для тестов можно и попользовать
                          –1
                          Я не знаю. У меня не хватило терпения дождаться пока запуститься браузер. Пару раз уже пробовал.
                            0
                            Проще на тот же VirtualBox поставить android. Быстро, дёшево и сердито =)
                              0
                              А как же тач-интерфейс?
                  0
                  В опере хуже всего работают кнопки. Но вообще интересно.
                    +1
                    То, что radiobutton не круглый, а квадратный как checkbox — это убого и не правильно.
                      0
                      Посмотрите внимательно пример. Вид радиобаттона 1. Можно достаточно легко изменить. 2. нет никаких проблем изменить ctx.moveTo() на ctx.bezierCurveTo() или, в графическом варианте, еще легче — картинку checkbox'a на картинку radiobutton'a. Все это достаточно легко делается, у меня просто не было необходимой графики.
                      +4
                      я немного недоумеваю…

                      но разве нельзя поверх канваса разместить html контролы? а дальше уже давно отточенными средствами css настроить внешний вид… зато не придется реализовывать функционал работы с языками (ввод текста, лево/право сторонний, модификаторы и т.п.) устройствами ввода (скролл мыши, сенсорный экран планшетников,..) и многое другое.
                        0
                        www.quirksmode.org/html5/inputs.html
                        На quirksmode где-то была статья сравнения, где как и какие элементы рендерятся. Так что если мне, к примеру, нужна будет кнопка ровно 100х20 пикселей с текстом по центру — все может быть плохо. Да и не хотелось JS перемешивать с css/html.
                          0
                          Я долго думал как же отрисовывать UI в игре на канвасе, и пришел к выводу, что наиболее производительным будет использование HTML элементов поверх канваса.

                          Простой текст на канвасе, может жрать до 30% нагрузки и вашем примере это видно, если начать быстро печатать в текстфилде
                            0
                            На самом деле сейчас просто не оптимизированы события. Я думаю, нагрузку там можно значительно уменьшить.
                              0
                              да не в событиях дело, нативно рисовать текст на канвасе (как и использовать градиенты и тени) — очень напряжно и лучше этого избегать. просто попробуйте сравнить)

                              кроме того, UI статичен и HTML элементы будут органично смотреться (естественно если будут хорошо выполнены графически). А вот когда не годиться использовать HTML, так это когда элемент интерфейса внутри игры может закрываться границами (например контекстная подсказка/меню объекта)
                      • UFO just landed and posted this here
                          0
                          Почему же плохая? Любой GUI под DirectX/OpenGL изначально занимается плохой идеей и переписывает стандартные контролы (посмотрите тот же CeGUI или Guichan), Qt/GTK изначально тоже занимаются плохой идеей и переписывают стандартные контролы. Что уж там говорить, вид стандартных контролов в разных браузерах разный.

                          Я понимаю, что сейчас реализация очень далека от идеала, но все же, не нужно судить так критично. Спасибо за отзыв.
                            0
                            Qt переписывает? оО как раз у них контролы нативные (или выглядят нативными)
                              0
                              Раньше переписывали, судя по вики. Теперь же «Recent versions of Qt use the native style APIs of the different platforms to query the platform for the desired appearance of the Qt controls, and so do not suffer from such issues as much». Как я понимаю, и сейчас они используют не нативные контролы целевой платформы, но теперь их внешний вид запрашивается у системы. Надо исходники посмотреть.
                          0
                          Если со слайдера увести мышку вверх, то он продолжает работать, а если вниз то нет.
                            0
                            Спасибо, проверю и поправлю.
                              0
                              На самом деле независимо от направления — глючит когда курсор уходит с подложки интерфейса
                            0
                            Текстэрия работает странно. Бэкспейс и стрелки вставляют проценты и делают странные вещи. FF8.
                              0
                              В других браузерах не пробовали? Скорее всего нужно вставить проверну на onkeypress, во время того, как отрабатывает onkeydown.
                              0
                              На самом деле такие вещи надо делать на svg (ие способен показать через рафаель) либо вообще картинками. Сильная сторона канваса в динамике. Имхо
                                0
                                Такие вещи могут быть частью какого-то большего проекта на Canvas…
                                  0
                                  Как уже сказал товарищ выше, это может быть проблемой, если над элементом GUI нужно отрисовать часть логики проекта, или какой-то набор объектов.

                                  В общем, лучше иметь удобный GUI внутри canvas'a и использовать его как подобие 2D-слоя видеокарты, чем городить над канвасом стандартные элементы или сращивать canvas+svg.
                                  0
                                  Не без багов, но найс. Жаль, что не как плагин для LibCanvas, я бы использовал =)
                                    0
                                    Спасибо, ждал твоего комментария. Баги постараюсь в ближайшее время поисправлять, да, х таки очень много, нельзя было в таком состоянии показывать. А вот сделать порт под LibCanvas — это идея, да. И это не так уж сложно, попробую форкнуть и озадачиться портированием.
                                      0
                                      Та не. Кроме проблемы с Оперой (ох уж эта Опера) и Эксплорером (ох уж этот Эксплорер) остальные баги не так страшны даже для продакшна.
                                        0
                                        Кстати, основная проблема далеко не в том, чтобы «просто прикрутить его к приложению». Самое важное — это заставить его корректно работать с другими объектами на странице. Чтобы не проваливались события сквозь кнопки, чтобы их было легко показать и убрать. И так далее.
                                      –4
                                      Мне одному скрин напомнил кнопки из Lineage 2?)
                                        –3
                                        А ещё — ВарКрафт
                                        –1
                                        И всё-таки нативные контролы — лучшее решение.
                                          0
                                          О господи! Ну зачем?
                                          Таких ужасных велосипедов еще нужно поискать.
                                            0
                                            Можно поподробнее, чем он ужасен и чем велосипед?
                                            0
                                            В селекте множественный выбор не работает.
                                            MacOSX 10.7.2, FF 8.0.1

                                            Only users with full accounts can post comments. Log in, please.