RubyCocoaでアニメーション:レイヤーの階層構造を作る
Posted: 2008.02.12 (Tue) by うちゃ in プログラミング
昨日うまくいかなかった移動しながらの画像の押し出し効果だが、今日提供されたOSのアップデータをかけてもそのままであった(^^; しかたがないので、なんとかうまく表示できないか、考えてみることにする。動きをよく見ると、どうも移動途中のレイヤーの座標がうまくとれていなくて、押し出される側の画像を、レイヤーが最初にいた位置に表示してしまっているようである。
そこで、画像を表示してるレイヤーの親レイヤーを作って、移動のアニメーションはそちらで行なうようにする。そうすると、画像を切り替えている方のレイヤーは全く動いていないことになるので、表示する位置がずれるということはなくなるはずだ。図で表わすと、こんな感じになる。
では、コードを書いて行こう。まず、awakeFromNibで表示するレイヤーを背景レイヤーに入れている箇所
backgroundLayer.addSublayer_(layer)
を消して、以下のように書き換える。
transitionLayer =OSX::CALayer.layer()
transitionLayer.frame = layer.frame
transitionLayer.addSublayer_(layer)
transitionLayer.masksToBounds=true
backgroundLayer.addSublayer_(transitionLayer)
このコードでは、新しくtransitionLayerを作り、その中に、いままでのレイヤーをaddSublayerで加えている。そして背景レイヤーには新しく作ったtransitionLayerの方を入れているのだ。
続いて、画像切り替えのcangeContentsの方にも手を入れよう。contentsの中身を入れ替えるレイヤーは一つ階層が深くなっているのだから、最初にレイヤーを取得するコードを
layer = @view.layer.sublayers.objectAtIndex_(0)
から
transitionLayer = @view.layer.sublayers.objectAtIndex_(0)
layer=transitionLayer.sublayers.objectAtIndex_(0)
に変更する。
これで、アニメーションしながら押し出しの効果を実行しても、おかしな表示にはならないはずだ。
しかし、移動のアニメーションはちゃんと動作するものの、フィルターのアニメーションが動かなくなっている。アニメーションがtransitionLayerの方についているが、フィルターはもとのlayerの方についているため、フィルターのアニメーションが利かなくなっているのだ。
そこで、awakeFromNibでfilterをつけるレイヤーをtransitionLayerの方に変えてやる。
layer.setFilters_(filterArray)
を
transitionLayer.setFilters_(filterArray)
こうかえるわけだ。
これで、思った通りの動きをするようなっているはずだ。