Rubyでどう書く?:RubyCocoa+Core Animationでお手軽アニメーション
佐藤伸吾(KBMJ)
2008/08/14 08:00
今回はRubyCocoaとMac OS XのフレームワークであるCore Animationを使って、お手軽にアニメーションを作成してみましょう。
問題
RubyCocoaは、Mac OS XのCocoaオブジェクトをRubyスクリプトからRubyオブジェクトとして扱うための、Ruby用ライブラリとフレームワークです。RubyCocoaを用いれば、RubyでCocoaアプリケーションを記述することができるのです。
Core AnimationはMax OS Xのフレームワークで、その利点は手軽さにあります。普通にアニメーションプログラミングを行おうとすると、時間軸管理、非同期な描画スレッド、パフォーマンスの向上など、考慮すべき点があまりにも多すぎます。
しかし、Core Animationを用いれば、面倒な部分はOSに任せて、自分の実現したいことに集中できるのです。
今回はRubyCocoaとMac OS XのフレームワークであるCore Animationを使って、お手軽にアニメーションを作成してみましょう。
回答例
AppController.rbを作成し、以下のように記述します。
require 'osx/cocoa'
OSX.require_framework 'QuartzCore'
class AppController < OSX::NSObject
ib_outlet :window
ib_outlet :view
ib_action :pressPosition
ib_action :pressRotation
ib_action :pressSepia
ib_action :pressBloom
ib_action :pressHole
ib_action :pressZoom
ib_action :pressHalftone
def awakeFromNib
bitmapImage = OSX::NSBitmapImageRep.imageRepWithContentsOfFile_('/Users/ssato/Pictures/ruby.png')
image = bitmapImage.CGImage()
layer = OSX::CALayer.layer()
layer.contents = image
layer.frame = OSX::CGRectMake(0,0,995/4,996/4)
black=OSX::CGColorCreateGenericRGB(0,0, 0,1.0)
backgroundLayer=OSX::CALayer.layer()
backgroundLayer.backgroundColor=black
backgroundLayer.addSublayer_(layer)
@view.setLayer_(backgroundLayer)
@view.setWantsLayer_(true)
end
def pressPosition(sender)
animation = OSX::CABasicAnimation.animationWithKeyPath_('position')
animation.duration = 1.0
layer = @view.layer.sublayers.objectAtIndex_(0)
position = layer.position
animation.fromValue = OSX::NSValue.valueWithPoint_(OSX::NSPointFromCGPoint(position))
position.x += 256;
position.y += 160;
animation.toValue = OSX::NSValue.valueWithPoint_(OSX::NSPointFromCGPoint(position))
animation.autoreverses = true
animation.repeatCount = 4
layer.addAnimation_forKey_(animation, 'positionAnimation')
end
def pressRotation(sender)
animation = OSX::CABasicAnimation.animationWithKeyPath_('transform')
animation.duration = 0.5
animation.autoreverses = true
animation.repeatCount = 4
transform = OSX::CATransform3DIdentity
animation.fromValue = OSX::NSValue.valueWithCATransform3D(transform)
transform = OSX::CATransform3DMakeRotation(Math::PI, 0, 1.0, 0)
transform.m34 = 1.0 / -420.0
animation.toValue = OSX::NSValue.valueWithCATransform3D(transform)
layer = @view.layer.sublayers.objectAtIndex_(0)
layer.addAnimation_forKey_(animation, 'transformAnimation')
end
def pressSepia(sender)
filter = OSX::CIFilter.filterWithName_('CISepiaTone')
filter.setDefaults()
layer = @view.layer.sublayers.objectAtIndex_(0)
layer.name = 'sepiaFilter'
layer.setFilters_(OSX::NSArray.arrayWithObject_(filter))
end
def pressBloom(sender)
filter2 = OSX::CIFilter.filterWithName_('CIBloom')
filter2.setDefaults
filter2.setValue_forKey_(OSX::NSNumber.numberWithFloat_(0.0), 'inputIntensity')
filter2.setValue_forKey_(OSX::NSNumber.numberWithFloat_(5.0), 'inputRadius')
filter2.setName_('bloomFilter')
layer = @view.layer.sublayers.objectAtIndex_(0)
layer.setFilters_(OSX::NSArray.arrayWithObject_(filter2))
pluseAnimation = OSX::CABasicAnimation.animation
pluseAnimation.keyPath = 'filters.bloomFilter.inputIntensity'
pluseAnimation.fromValue = OSX::NSNumber.numberWithFloat_(0.0)
pluseAnimation.toValue = OSX::NSNumber.numberWithFloat_(1.5*2)
pluseAnimation.duration = 1.0
pluseAnimation.repeatCount = 4
pluseAnimation.autoreverses = true
layer.addAnimation_forKey_(pluseAnimation, 'bloom')
end
def pressHole(sender)
filter = OSX::CIFilter.filterWithName_('CIHoleDistortion')
filter.setDefaults()
layer = @view.layer.sublayers.objectAtIndex_(0)
layer.setFilters_(OSX::NSArray.arrayWithObject_(filter))
end
def pressZoom(sender)
filter = OSX::CIFilter.filterWithName_('CIZoomBlur')
filter.setDefaults()
layer = @view.layer.sublayers.objectAtIndex_(0)
layer.setFilters_(OSX::NSArray.arrayWithObject_(filter))
end
def pressHalftone(sender)
filter = OSX::CIFilter.filterWithName_('CICMYKHalftone')
filter.setDefaults()
layer = @view.layer.sublayers.objectAtIndex_(0)
layer.setFilters_(OSX::NSArray.arrayWithObject_(filter))
end
end
Interface Builderで画像1のようにコンポーネントを配置します。
画像1
NSObjectを追加して、ClassにAppcontrollerを指定します(画像2)。
画像2
OutletsとActionsのConnectionを画像3のように設定します。
画像3
実行結果
Positionボタンを押すと、画像が斜めに移動します(画像4)。
画像4
Rotationボタンを押すと画像が回転し、Sepiaをクリックすると画像がセピア色になります(画像5)。
画像5
同様に、Bloomは画像が光り輝き(画像6)、Holeは画像に穴が空きます(画像7)。Zoomボタンはズームエフェクト(画像8)で、Halftoneはハーフトーンフィルタです(画像9)。
画像6
画像7
画像8
画像9
解説
- 特集: Rubyでどう書く? (7件)
- 今日のトップ記事
- 昨日
- 5日前
- 6日前
- 7日前
- ホワイトペーパー
- 話題のタグ
Tips
開発環境
Opera
Microsoft
RIA
Ajax
Mac OS X
Apple
Firefox
iPod touch
Linux
Windows
リファレンス
アプリケーション
Windows XP
HTML
iPhone
ブラウザ
Chrome
インストール
Webサービス
UI
CSS
Webデザイン
WebKit
小技
Internet Explorer
セキュリティ
オープンソース
Flash
Safari
OS
データベース
Mozilla
Google
脆弱性
Windows Vista
Database
ソフトウェア開発
iPhone 3G
Windows 7
JavaScript
Off Topic
クラウド
Firefox 3
Java
モバイル
仮想化
マイクロソフト
プログラミング言語
話題のタグを見る »
「Google Chrome」の拡張機能、開発者からのアップロード受付を開始
IMAPでGmailを受信、最も手っ取り早いのは?Windows 7、Ubuntu 9.10、Snow Leopardのメーラー比較
Snow LeopardではNTFSをサポート--その源流を訪ねる(2)
MS運営のオープンソース開発プロジェクト支援サイト「CodePlex」を探検する(2)
Snow LeopardではNTFSをサポート--その源流を訪ねる(1)
フォトレポート:「Windows Server 2008 R2」--あまり知られていない有用な機能10選
100万円で実現!中小企業の情報漏えい対策
―エン・ジャパン厳選求人☆毎週更新―
企業ITシステムの企画、構築、運用のイロハ
大丈夫?あなたの会社のセキュリティ対策
【最終警告】パンデミック対策特集
高まるiSCSIストレージへの注目度
電力に"ふた"をする独自の省エネ機能とは!?