はじめに
この記事はElixirアドベントカレンダー2025のシリーズ2、11日目の記事です
今回はBabylon.jsのチュートリアルの2章をLiveView+Babylon.jsでやっていく記事になります
12日目の続きから進めていきます
雛形作成
新しくページを作るので雛形を作ります
lib/babylon_web/live/ch210_live.ex
defmodule BabylonWeb.Ch210Live do
use BabylonWeb, :live_view
def render(assigns) do
~H"""
<div class="p-4">
<.header>
Chapter 2-10
<:actions><.button navigate={~p"/"}>Back</.button></:actions>
</.header>
</div>
"""
end
def mount(_params, _session, socket) do
{:ok, socket}
end
end
defmodule BabylonWeb.HomeLive do
use BabylonWeb, :live_view
def render(assigns) do
~H"""
<Layouts.app flash={@flash}>
<div class="flex flex-col w-1/2 gap-4">
<.button navigate={~p"/ch101"}>Chapter1-01</.button>
<.button navigate={~p"/ch103"}>Chapter1-03</.button>
<.button navigate={~p"/ch201"}>Chapter2-01</.button>
<.button navigate={~p"/ch203"}>Chapter2-03</.button>
+ <.button navigate={~p"/ch210"}>Chapter2-10</.button>
</div>
</Layouts.app>
"""
end
end
lib/babylon_web/router.ex
scope "/", BabylonWeb do
pipe_through :browser
live "/", HomeLive
live "/ch101", Ch101Live
live "/ch103", Ch103Live
live "/ch201", Ch201Live
live "/ch203", Ch203Live
live "/ch210", Ch210Live
end
2-10: Viewer (Changing the Viewer's Camera)
viewerライブラリを読み込みます
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="csrf-token" content={get_csrf_token()} />
<.live_title default="Babylon" suffix=" · Phoenix Framework">
{assigns[:page_title]}
</.live_title>
<link phx-track-static rel="stylesheet" href={~p"/assets/css/app.css"} />
<script src="https://preview.babylonjs.com/babylon.js" defer>
</script>
+ <script src="https://cdn.babylonjs.com/viewer/babylon.viewer.js" defer></script>
<script defer phx-track-static type="text/javascript" src={~p"/assets/js/app.js"}>
</script>
...
<head>
viewerをWebViewで動かす場合は block属性をつけて高さ、幅を指定しないと表示されませんでした
liveviewが更新しないようにidをつけてphx-update="ignore"をつけます
<babylon
id="babylon"
class="block w-screen h-[88vh]"
phx-update="ignore"
model="https://assets.babylonjs.com/meshes/village.glb"
>
</babylon>
床がデフォルトと読み込んだやつと衝突してるので修正
<babylon
id="babylon"
class="block w-screen h-[88vh]"
phx-update="ignore"
extends="minimal"
model="https://assets.babylonjs.com/meshes/village.glb"
>
</babylon>
カメラの初期位置がよくないので、Hookで調整し、最終的にこうなります
~H"""
<script :type={Phoenix.LiveView.ColocatedHook} name=".Viewer">
BabylonViewer.viewerManager.getViewerPromiseById('babylon').then((viewer) => {
viewer.onSceneInitObservable.add(() => {
viewer.sceneManager.camera.radius = 15; // カメラの半径をセット
viewer.sceneManager.camera.beta = Math.PI / 2.2; // 伏角
});
viewer.onEngineInitObservable.add((scene) => {
viewer.loadModel({
url: "https://assets.babylonjs.com/meshes/village.glb"
});
});
});
</script>
<div class="p-4">
<.header>
Chapter 2-10
<:actions><.button navigate={~p"/"}>Back</.button></:actions>
</.header>
</div>
<babylon
id="babylon"
class="block w-screen h-[88vh]"
phx-update="ignore"
phx-hook=".Viewer"
extends="minimal"
>
</babylon>
"""
end
最後に
Viewerを使えば作成したglbファイルをpriv/staticにおいてステージ毎の読み込みとかができそうですね
また通常のWebviewだとviewerで読み込みができるんですが、iOSアプリ内のWebviewだと動かない状態なので、動くようになったらまた紹介したいと思います
チュートリアル2章と本記事は以上になりますありがとうございました
ここまでのコード


