iPhoneで手軽に3D表示をしてみたと思ったこと一度はありますよね?
できます
そう、ElixirDesktopならね
実行画面
開発環境
- M4 Mac mini 16GB
- macOS Tahoe 26.1
- Elixir 1.19.3-otp-27
- Erlang 27.3.4
- Xcode 26.1.1 (17B100)
- iPhone 16e
- iOS 18.6.2
前提知識
ElixirDesktopでのビルド
こちらが参考になります
Elixirでの3D表示
では作業開始
まず、ベースとなる3Dのソースを取得します
こちらの環境構築の部分を試してください
まず実行結果が出ればOKです
ElixirDesktop関連のライブラリを組み込む
前提として一度
で動作確認をしてください
これが進まないとできません
上記コラムの動作チェックができたら
ライブラリーを追加
mix.exs
defmodule Three.MixProject do
use Mix.Project
# 省略 #
defp deps do
[
# 省略 #
- {:bandit, "~> 1.5"}
+ {:bandit, "~> 1.5"},
+ {:desktop_setup, github: "thehaigo/desktop_setup", only: :dev}
]
end
# 省略 #
end
$ mix deps.get
$ mix desktop.install
これでライブラリーの取得できました
ルータの書き換え
ルートを表示したいページに書き換え
defmodule ThreeWeb.Router do
use ThreeWeb, :router
# 省略 #
scope "/", ThreeWeb do
pipe_through :browser_s
- get "/", PageController, :home
+ live "/", CgLive.S1, :index
end
# 省略 #
end
3Dを表示する内容
好きに書き換えてください
これはサンプルです
lib/three_web/live/cg/s1.ex
defmodule ThreeWeb.CgLive.S1 do
use ThreeWeb, :live_view
import ThreeWeb.Cg.CgHelper
# 1列のパネル数
@plane_count 80
@plane_x -18
@plane_s 2
@impl true
def mount(_params, _session, socket) do
Process.send_after(self(), :update, 500)
socket =
socket
|> set_size()
|> assign(data: initialization_character_data())
|> add_planes()
|> add_plane("logo_plane", 0.71 / 2, 0.48 / 2, "#FFFFFF")
|> position("logo_plane", -4.3, 3.5, 0)
|> load_texture("logo", "/images/logo.png")
|> load_texture("t1", "/images/t1.jpg")
|> load_model("test", "/images/test.vrm")
|> add_text_plane("my_greeting", "Phoenix Framework", 15, "#CC5500")
|> position("my_greeting", 0.1, 3.5, 0)
{:ok, main(socket)}
end
@impl true
def handle_info(:update, socket) do
Process.send_after(self(), :update, 20)
{:noreply, main(socket)}
end
def handle_event("load_model", %{"name" => "test", "status" => "completion"}, socket) do
socket =
socket
|> position("test", -1, 0, 1)
|> rotation("test", -2, 0, -1.6)
{:noreply, socket}
end
def handle_event("load_texture", %{"name" => "logo", "status" => "completion"}, socket) do
socket =
socket
|> set_texture("logo_plane", "logo")
{:noreply, socket}
end
def handle_event("load_texture", %{"name" => "t1", "status" => "completion"}, socket) do
socket =
socket
|> set_textures()
{:noreply, socket}
end
defp initialization_character_data() do
0
end
defp main(socket) do
character_data = update(socket.assigns.data)
socket
|> positions(-character_data)
|> set_text_plane_text(
"my_greeting",
"Phoenix Framework #{DateTime.utc_now()}",
15,
"#CC5500"
)
|> assign(data: character_data)
end
defp update(character_data) do
if character_data >= 2, do: 0, else: character_data + 0.01
end
defp add_planes(socket) do
Enum.reduce(1..@plane_count, socket, fn x, acc ->
acc
|> add_plane("bg_#{x}", @plane_s, @plane_s, "#666666")
|> add_plane("bg_a#{x}", @plane_s, @plane_s, "#333333")
|> add_plane("bg_b#{x}", @plane_s, @plane_s, "#111111")
end)
end
defp set_textures(socket) do
Enum.reduce(1..@plane_count, socket, fn x, acc ->
set_texture(acc, "bg_#{x}", "t1")
|> set_texture("bg_a#{x}", "t1")
|> set_texture("bg_b#{x}", "t1")
end)
end
defp positions(socket, add_x) do
Enum.reduce(1..@plane_count, socket, fn x, acc ->
base = @plane_x + x * @plane_s
bg_x = base + add_x * 64
bg_ax = base + add_x * 16
bg_bx = base + add_x * 4
position(acc, "bg_#{x}", bg_x, -4, -2)
|> position("bg_a#{x}", bg_ax, -2, -2)
|> position("bg_b#{x}", bg_bx, 0, -2)
end)
|> rotation("test", add_x * 10, 0, -1.6)
|> rotation_bone("test", "J_Bip_R_UpperArm", add_x, add_x * 10, add_x)
|> rotation_bone("test", "J_Bip_L_UpperArm", add_x * 10, add_x * -10, add_x)
end
end
iOSアプリの準備
$ mix desktop.setup.ios
$ cd native/ios
$ carthage update --platform iOS --use-xcframeworks
$ ./run_mix
$ % open Three.xcodeproj
Xcodeが起動するのでスタートボタンを押して実行してください
実機でハマったこと
全てを一度にやって動きました
ソース

