LoginSignup
1
0

More than 5 years have passed since last update.

GrimoireJSのシーンをスクリプトで操作したい

Last updated at Posted at 2016-12-09

(この記事はGrimoireJSアドベントカレンダー2016の9日目です。)

前回はGrimoireJSの基本的な構造についてという記事でGomlNodeとComponentについて簡単に紹介しました。
ページにgomlを埋め込むことでそれがツリーとしてパースされ、そのままのシーンがレンダリングされます。
でも、せっかくhtmlページに埋め込むなら、ほかのhtml要素と同じように動的に操作したくなりませんか?

ということで今回は、gomlから構築されたGomlNodeツリーをスクリプトからどのように操作するのかを紹介していきたいとおもいます。

3種のインタフェース

GrimoireJSは、gomlから作られたシーン中のGomlNodeを簡単に操作するためのインタフェースを提供しています。
このインタフェースは

  • GrimoireInterface
  • GomlInterface
  • NodeInterface

の3段階に分かれていて、それぞれ操作する対象が違います。

Interface 対象 コード
GrimoireInterface 環境全体 gr
GomlInterface htmlに埋め込まれた各goml gr("selector")
NodeInterface GomlNodeツリー中の各ノード gr("selector")("")

まずは、公式のチュートリアルから引っ張ってきた以下のコードを見てみましょう。

index.js
gr(function() {
    setTimeout(function(){
      gr("#main")("#green-mesh").setAttribute("position", "3,0,0");
    },1000);
});

GrimoireInterface

grは、GrimoireJSを読み込むとグローバルに定義されるGrimoireInterfaceです。
よく見ると1行目と3行目で違う使い方をされていますが、まずは3行目の方を見てみましょう。
各インタフェースに共通しているのは、関数としてセレクタを渡して対象を検索できることです。
alt

それを踏まえて先程のサンプルコードを思い出してみると、

gr("#main")("#green-mesh").setAttribute("position", "3,0,0");

gr"#main"というセレクタが渡され、idが"main"であるスクリプトタグに対応するgomlを検索して、GomlInterfaceが返されます。
そのGomlInterfaceに対して"#green-mesh"を渡すことで、このgoml中のidが"green-mesh"であるノードが検索され、NodeInterfaceが返されてます。

また、NodeInterfaceに対しての操作は、対象となるすべてのノードに対して実行されるので、setAttribute()すると複数ノードに同時に属性を設定できます。
ここではid指定なので対象ノードは一つだけですが、例えば、gr("#main")("mesh")とすればすべてのmeshタグを一度に操作することができます。

基本的にこれらの機能を使うことが多いですが、それぞれのインタフェースには他にもいくつか機能があるので、その辺りも紹介します。

GrimoireInterface

まず先程のサンプルの1行目で使われていた機能。

functionを渡して関数として呼び出す

functionを渡すと、Gomツリーがロードされた直後に渡した関数がコールバックされます
Gomツリー上の要素をいじるときは当然ツリーのロードが完了していないといけないので、基本的にこの中で操作を行うことになります。

gr.registerComponent()

gr.registerComponent("ComponentName", {
  attribute:{},
  $awake:function(){}
  })

新しいコンポーネントを作るときに使います。コンポーネント名はCamelCase推奨です。

gr.registerNode()

gr.registerNode("node-name",["ComponentName"],{attr:"default Value"});

こちらは新しいノードの定義です。ノード名は、snake-case推奨です。
上のregisterComponentにも言えることですが、registerはロード完了前にやる必要があるので、gr(function(){})の中で呼んではダメです。

GomlInterface

実はこいつにはほとんど機能がないのですが、強いて挙げるなら。

gr("selector").getNodeById("id")

gr("selector")("#id")とするのとほぼ等価ですが、こちらのほうが高速です。
パフォーマンスが必要な場合に使ってください。
ちなみに返り値はNodeInterfaceではなく、GomlNodeの配列です。

NodeInterface

一番多機能です。よく使う順で紹介。

setAttribute

gr("slctr")("slctr").setAttribute("attrName","value")

そのまんま属性の設定です。よく使います。

getAttribute

gr("slctr")("slctr").getAttribute("attrName")

属性の取得です。
これもよく使いますが、対象ノードが存在しないと例外を投げます。
また、対象が複数存在するとき、最初のノードの属性を返します。

forEach

gr("slctr")("slctr").forEach(function(node,gomlIndex,nodeIndex){
  // for all node.
  console.log(node);
})

対象ノードに反復処理ができます。ノード本体は第一引数で、そのノードの属するgomlのインデックスとnodeのインデックスも渡されます。
汎用性高いのでよく使います。

addComponent

gr("slctr")("slctr").addComponent("ComponentName",{attr:"value"})

コンポーネントをノードに追加します。
動的にコンポーネントを制御するのに使います。

delete

gr("slctr")("slctr").delete()

ノードを削除します。

count

var count = gr("slctr")("slctr").count()

対象ノードの個数です。

first

var node = gr("slctr")("slctr").first()

最初のノードを返します。一つも存在しないとnullを返します。

single

var node = gr("slctr")("slctr").single()

firstとほぼ同じですが、対象が存在しなかったり、複数存在するときには例外を投げます。
対象がひとつしかないことを期待するならこっちを使ったほうが安全です。

まとめ

大抵、gr()()で取得するノードインタフェースを通して操作する。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0