Код: https://github.com/lucamug/elm-playground-3d
Демо: https://elm-playground-3d.netlify.com/
Пример: https: //elmjapan.org/

Вяз-площадка-3д - экспериментальная библиотека, построенная на базе Вяза-детской площадки. Итак, позвольте мне сначала представить вам эту библиотеку ...

вяз-детская площадка

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

Он является оболочкой The Elm Architecture, предоставляя простые директивы для рисования объектов на экране (квадрат, круг, треугольник и т. Д.) И их преобразования (перемещения, поворота, масштабирования).

Она имеет

  • Три уровня сложности, которым вы можете следовать в процессе обучения: картинка, анимация, игра.
  • Информация об экране, мыши и клавиатуре для создания интерактивного приложения
  • Крючки для перемещения объекта, такие как вращение, волна, зигзаг

Библиотека поддерживает двухмерные формы, но мне нужно было создать простую трехмерную композицию, и я хочу сохранить все функции, которые предоставляет elm-Playground, сохраняя тот же уровень простоты.

Поехали в 3D!

Итак, я построил простой трехмерный слой над детской площадкой из вяза. Это сравнение использования 2D и 3D версий:

2D

main =
    picture
        [ square purple 500
            |> fade 0.8
            |> move 200 0
        ]

3D

main =
    picture
        [ cube darkPurple purple lightPurple 500
            |> fade3d 0.8
            |> move3d 200 0 0
            |> shape3dto2d camera1
        ]

Как видите, эти два процесса следуют одной и той же логике. Тонкие различия заключаются в следующем:

  • По возможности функции в 2D имеют аналоги в 3D с суффиксом «3d» в названии. Суффикс позволяет импортировать все из 3D-библиотеки, не создавая конфликтов с функциями из 2D-библиотеки.
  • Для функций в 3D могут потребоваться дополнительные аргументы, такие как move3d, для которых требуется дополнительная координата Z.
  • Трехмерные формы необходимо преобразовать в двухмерные с помощью shape3dto2d перед их обработкой с помощью функций 2D (например, picture).

Волшебство творится функцией shape3dto2d. То, что он делает, называется 3D-проекцией. Я использовал перспективную проекцию с помощью ianmackenzie / elm-3d-camera. Для преобразований в трехмерном пространстве я использовал ianmackenzie / elm-geometry.

Это расширенная библиотека для 3D-преобразований, и вам обязательно стоит взглянуть на них, если вы хотите заняться чем-то серьезным с 3D-рендерингом. Для этой библиотеки я их упростил, заменив несколько аргументов значениями по умолчанию.

Ниже приведены три примера, отсортированные по сложности (picture, animation, game).

Пример 1 - Изображение

Демо: https://elm-playground-3d.netlify.com/example1-picture.html

В этом примере собраны вместе двухмерные и трехмерные элементы.

main =
    picture
        [ group3d
            [ cube darkPurple purple lightPurple 600
                |> fade3d 0.5
            , words3d darkPurple "3D"
                |> scale3d 5
            ]
            |> shape3dto2d camera1
            |> moveLeft 180
        , group
            [ square darkPurple 300
                |> fade 0.5
            , words darkPurple "2D"
                |> scale 5
            ]
            |> moveRight 180
        ]

Пример 2 - Анимация

Демо: https://elm-playground-3d.netlify.com/example2-animation.html

Здесь мы добавляем действие

main =
    animation view

view time =
    [ group3d
        [ cube lightPurple purple darkPurple 600
            |> fade3d 0.5
        , words3d darkPurple "3D"
            |> scale3d 5
            |> move3d 300 300 0
        ]
        |> rotate3d 0 0 (spin 3 time)
        |> shape3dto2d camera1
        |> rotate (spin 3 time)
        |> moveLeft 180
    , group
        [ square darkPurple 300
            |> fade 0.5
        , words darkPurple "2D"
            |> scale 5
        ]
        |> rotate (spin 3 time)
        |> moveRight 180
    ]

Пример 3 - Игра

Демо: https://elm-playground-3d.netlify.com/example3-game.html

Этот другой пример добавляет взаимодействия:

  • Горизонтальные движения мыши вращают все объекты на экране. Это получается добавлением координаты мыши к преобразованию rotate3d:
rotate3d 0 0 (computer.mouse.x / 3)
  • Маленький кубик управляется по горизонтали с помощью клавиш со стрелками и по вертикали с помощью мыши, это достигается с помощью
move3d (500 - x * 30) (500 - y * 30) (500 + computer.mouse.y * 2)

Откуда приходят x и y

update : Computer -> Memory -> Memory
update computer ( x, y ) =
    let
        ( dx, dy ) =
            toXY computer.keyboard
    in
    ( x + dx, y + dy )

как объяснено в документации на вязаную площадку

  • Дополнительные модификации, основанные на нажатой кнопке. Чтобы определить, нажата ли кнопка:
if Set.member "s" computer.keyboard.keys then
    ...

Толкаем конверт

Из этих простых блоков можно построить довольно сложную композицию, например плавучий город на https://elmjapan.org/:

В этом случае мы не только анимируем объект, но и постоянно анимируем камеру, создавая эффект плавания.

Со временем я опубликую исходный код этого веб-сайта, следите за обновлениями!

Выводы

Эта библиотека все еще находится на ранней стадии, и в ней отсутствуют многие функции, которые должна поддерживать «серьезная» 3D-библиотека.

Как новичок в области 3D-рендеринга, это было очень весело, а также оказалось проще, чем я ожидал.

Для более серьезных 3D-вещей в Elm, взгляните на