Разработка → Кубик Рубика на canvas

lany 30 июля 2010 в 13:41 4,9k
Недавние посты об алгоритме сборки кубика 5×5 сподвигли меня написать эмулятор кубика на канвас. Автором статей про сборку предлагался свой кубик на OpenGL, но он мне многим не понравился. Надеюсь, с моим кому-нибудь удастся освоить алгоритм быстрее. Некоторые особенности и преимущества:
  • Кроссплатформенность, кроссбраузерность (IE за браузер не считаем), ненужность инсталлятора и прочие преимущества веб-приложения.
  • Поддержка кубиков от 2×2 и до бесконечности (пока грани не станут сильно маленькими и рендеринг не начнёт жестоко тормозить). В интерфейс вынесено до 11×11, но в библиотеке ограничений нет.
  • Псевдообъёмные грани для красоты.
  • Бесконечный undo-буфер.
  • Возможность замеса кубика (shuffle).
  • Слои вращаются легко и интуитивно, быстро привыкаешь. Крутить весь кубик (мышкой с зажатым шифтом или правой кнопкой) не так легко, но тоже можно привыкнуть.
  • Вся библиотека компактная, размещается в одном js-файле и не имеет никаких внешних зависимостей.
  • Лицензия MIT, а также открытые и не очень страшные исходники позволяют вставить кубик на ваш сайт и доработать по вкусу.
Не знаю, стоит ли рассказывать про особенности разработки. Было много сложностей, но все достаточно мелкие. Я почему-то поленился использовать однородные координаты, из-за чего, в частности, проекция ортогональная, а не перспективная. Модель рендеринга тоже немного странная. В общем виде кубик представляется в виде 6, 12 или 18 граней, а каждая грань содержит до size^2 элементов, каждый элемент — это квадратик. На внутренних срезах, которые видно при вращении, элемент всего один площадью на всю грань. Здесь подписаны 9 видимых граней, остальные 9 расположены симметрично им:

Потребовалось также сортировать грани в правильном порядке, чтобы корректно удалялись невидимые части. Здесь правильный порядок — вдоль оси вращения (если вращения нет, порядок неважен).

Объёмность граней ненаучная: это просто круговой градиент канвас, центр которого отклоняется в направлении нормали. Честно считать освещённость по BRDF показалось для этой задачи неоправданно.

Что хотелось ещё сделать, но лень:
  • Управление с клавиатуры.
  • Перед вращением слоёв мышкой подсвечивать вращаемый слой, чтобы уменьшить число ошибок. Сейчас вращение начинается, если с зажатой кнопкой провести мышкой на 50 пикселей в направлении вращения. Подсветку можно включать на меньшем расстоянии, тогда пользователь вовремя остановится. Может, это и не нужно, у меня ошибки случались редко.
  • Починить кубик 2×2, почему-то он не работает. исправлено — спасибо fllln
  • Сделать перспективную проекцию.
  • Сохранение/загрузку (можно в cookies).
  • Поддержка IE6-8 (вероятно, радиальный градиент в excanvas не заработает).
Если кто-нибудь хочет заняться, то пожалуйста. Если есть вопросы по коду, задавайте, с радостью отвечу.
Проголосовать:
+92
Сохранить: