公開日 2019年6月25日
かわいい3Dエンジン「Zdog」の紹介
Hello world, I give you Zdog 🐶 https://t.co/yL9FsIN6C7
— Dave DeSandro (@desandro) 2019年5月28日
Round, flat, designer-friendly pseudo-3D engine for canvas & SVG pic.twitter.com/JXhYlCd8Sb
先日、CodePenを眺めていたところ、Zdogというものを見つけて、とてもよかったので一通りドキュメントをみていろいろ作ってみました。
いつもならそれで終わりなのですが、6 月 4 日にリリースされたばかり1で日が浅く、まだ日本語の情報が少なかったため、自分のための備忘録も兼ねて簡単にご紹介します。
Zdog とは
Round, flat, designer-friendly pseudo-3D engine for canvas & SVG
フラットで丸みを帯びたレンダリングがなされる擬似 3D エンジンです。
こんなのや、
こんなのが簡単に作れます。
ロゴがこうやってぐりぐり動かせるのとてもいいと思います。
Zdog v1 is a beta-release, of sorts.
まだベータ版ということで、V2 が現在開発中2のようです。
Zdog 入門
せっかくなので、公式ドキュメントの Getting started を参考にしながら、Zdog で 3D モデルを表示して、ドラッグで動かすまでをやっていこうと思います。
インストール
公式ドキュメントには 3 通りの導入方法が紹介されていました。詳しくは公式サイトをご覧ください。
今回は、CDN を使います。
0. 準備
下記のサンプルコードは CDN を利用する場合の例です。この記事ではこのサンプルコードを使って説明していきます。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Zdog Tutorial</title>
<script src="https://unpkg.com/zdog@1/dist/zdog.dist.min.js"></script>
</head>
<body>
<canvas width="240" height="240" class="zdog-canvas"></canvas>
<script>
// ここにコードを記述
</script>
</body>
</html>
1. Illustration
インスタンスを作成
まず初めに親となるIllustration
インスタンスを作成します。
// ここにコードを記述
const illo = new Zdog.Illustration({
element: ".zdog-canvas",
})
element: '.zdog-canvas'
とすることで表示する<canvas>
要素を指定しています。
<canvas>
要素と結び付けたIllustration
に、この後登場するEllipse
やShape
などの図形を追加していき、最後にIllustration
をレンダリングするという流れになります。
2. 図形を追加
今回は円を表示してみようと思います。
// ここにコードを記述
const illo = new Zdog.Illustration({
element: ".zdog-canvas",
})
// 円を追加
new Zdog.Ellipse({
addTo: illo,
diameter: 80, // 直径
stroke: 20, // 線の太さ
color: "#E62", // 図形の色
})
addTo: illo
とすることで先程作成したIllustration
に図形を追加しています。
ただ、まだ追加しただけでレンダリングを行っていないので図形は表示されません。
3. レンダリング
// ここにコードを記述
const illo = new Zdog.Illustration({
element: ".zdog-canvas",
})
// 円を追加
new Zdog.Ellipse({
addTo: illo,
diameter: 80, // 直径
stroke: 20, // 線の太さ
color: "#E62", // 図形の色
})
// 図形を描画
illo.updateRenderGraph()
Illustration
クラスのupdateRenderGraph
メソッドを呼び出すことで図形をレンダリングします。
たった 3 ステップでフラットな 3D 図形を表示することができました!
しかし、このままだと動かないので 3D っぽくありません。ということで、次は図形をアニメーションさせてみようと思います。
4. アニメーション
アニメーション用の関数を作成して、requestAnimationFrame()
に渡します。
// - 省略 -
const animate = () => {
illo.rotate.x += 0.03
illo.rotate.y += 0.03 // 図形を回転
illo.updateRenderGraph() // 回転後の図形を描画
requestAnimationFrame(animate) // 再度呼び出し
}
animate()
くるくる回ります!
5. ドラッグで回転
// ここにコードを記述
const illo = new Zdog.Illustration({
element: ".zdog-canvas",
dragRotate: true, // ←これを追加
})
dragRotate: true
と設定するだけです。簡単にぐりぐりできます!
完成
初心者の私でも特につまずくことなく 3D 図形を表示して、ドラッグでぐりぐりすることができました!
Zdog is friendly. Modeling is done with a straight-forward declarative API.
とあるようにとても直感的でわかりやすいですね。
最後に、完成したコードを改めて記しておきます。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Zdog Tutorial</title>
<script src="https://unpkg.com/zdog@1/dist/zdog.dist.min.js"></script>
</head>
<body>
<canvas width="240" height="240" class="zdog-canvas"></canvas>
<script>
// ここにコードを記述
const illo = new Zdog.Illustration({
element: ".zdog-canvas",
dragRotate: true,
})
new Zdog.Ellipse({
addTo: illo,
diameter: 80, // 直径
stroke: 20, // 線の太さ
color: "#E62", // 図形の色
})
const animate = () => {
illo.rotate.x -= 0.03
illo.rotate.y += 0.03 // 図形を回転
illo.updateRenderGraph() // 回転後の図形を描画
requestAnimationFrame(animate) // 再度呼び出し
}
animate()
</script>
</body>
</html>
番外編:ネコをつくる 😹
これだけだとドキュメントまんまなので、番外編としてネコをつくってみます。少し長いので隠してあります。
クリックして開く
頭をつくる
const head = new Zdog.Shape({
addTo: illo,
stroke: 200,
color: "#9ED",
})
頭を作ります。Shape
クラスはパスで様々な形状の図形を作ることができますが、何も指定しない場合、ただの点が作られます。今回はその点の太さを調整して、球をつくっています。
右耳を作る
ネコといえば耳なので耳を作ります。Polygon
クラスを使うと多角形を作ることができますが、今回は先ほど使ったShape
にパスを指定して三角形を作っています。
const ear_right = new Zdog.Shape({
addTo: illo,
stroke: 20,
fill: true,
path: [
{ x: 0, y: -10 },
{ x: 30, y: 30 },
{ x: -30, y: 30 },
],
translate: { x: -90, y: -80, z: 10 },
rotate: { z: -0.6 },
})
translate
とrotate
を指定することで、図形の位置を調整することができます。
まだネコではありません。
左耳を作る
目や耳など、同じものを何個も作るときには、copy()
メソッドを使うと便利です。
// ear_left
ear_right.copy({
addTo: illo,
translate: { x: 90, y: -80, z: 10 },
rotate: { z: 0.6 },
})
引数として、様々なオプションを渡すことで、位置や大きさなどを調整できます。
まだネコではありません(目がないので)
目を作る
Ellipse
で円を作る際にquarters
を指定することで半円が作れます。
const eye_right = new Zdog.Ellipse({
addTo: illo,
diameter: 40,
quarters: 2,
stroke: 10,
rotate: { z: -Zdog.TAU / 4 },
translate: { x: -40, z: 90 },
})
// eye_left
eye_right.copy({
translate: { x: 40, z: 90 },
})
図形を 1/4 や 1/2 などキリの良い単位で回転させたい場合はZdog.TAU
を使います。
これはネコです。(目があるので)
口があるとかわいいので
Shape
を使って線を引いていきます。頂点の x,y,z 軸を示すオブジェクトを渡すだけなのでとても簡単です。
const mouth = new Zdog.Shape({
addTo: illo,
stroke: 8,
path: [{ x: -14 }, { x: 14 }],
translate: { y: 20, z: 90 },
})
よりネコらしくなりました。でもまだ何か足りない気もします。
ひげも必要でした
口と同じ要領でpath
をひいて位置を調整します。
// ひげ
const hige_left = new Zdog.Group({
addTo: illo,
translate: { x: -90, y: 10, z: 60 },
})
// 1本目のひげ
const hige = new Zdog.Shape({
addTo: hige_left,
stroke: 9,
path: [{ x: 15 }, { x: -15 }],
rotate: { z: 0.4 },
})
// 2本目のひげ
hige.copy({
translate: { y: 40 },
rotate: { z: -0.2 },
})
// まとめて複製
hige_left.copyGraph({
rotate: { z: Zdog.TAU / 2 },
translate: { x: 90, y: 50, z: 60 },
})
ひげのように複数の図形をまとめるときに便利なのがGroup
です。addTo
に作成したGroup
を指定することでまとめることができます。
copy()
メソッドは、子孫のアイテムまでコピーしてくれないので、まとめた図形を複製する際はcopyGraph()
メソッドを使います。
完成
かわいいネコができました!一応、こちらにコードも載せておきます。
おわりに
簡単な説明ということで物足りない部分もあるかと思いますが、参考になれば幸いです。
また、この Zdog をいたるところに使って3作成したホームページがあります。よろしければぜひご覧ください。
参考
- Zdog · Round, flat, designer-friendly pseudo-3D engine for canvas and SVG
- metafizzy/zdog - GitHub
- オシャレなフラットデザインを擬似的に 3D 化できるブラウザ向け 3D エンジン「Zdog」 - GIGAZINE
-
v1.0.0 - Initial public release
↩ -
https://github.com/metafizzy/zdog#beta
↩ -
言うほど使っていません、、、
↩