CoocaSliedsのコードを読む。いくつかクラスがあるが、トランジション処理は SlideshowViewクラス に記述されている。
SlideshowViewはNSViewのサブクラスでメンバ変数には、表示中のイメージやトランジションのスタイル、マスク画像などが保持されている。
@interface SlideshowView : NSView
{
NSImageView *currentImageView; // an NSImageView that displays the current image, as a subview of the SlideshowView
int transitionStyle; // the style of transition to use; one of the SlideshowViewTransitionStyle values enumerated above
BOOL autoCyclesTransitionStyle; // set if we should automatically cycle our transitionStyle
CIImage *inputShadingImage; // an environment-map image that the transition filter may use in generating the transition effect
CIImage *inputMaskImage; // a mask image that the transition filter may use in generating the transition effect
}
まず awakeFromNib。ここではマスク画像など共通に使われる CIImageインスタンスを準備している。
- (void)awakeFromNib {
:
inputShadingImage = [[CIImage alloc] initWithBitmapImageRep:shadingBitmap];
:
inputMaskImage = [[CIImage alloc] initWithBitmapImageRep:maskBitmap];
}
続いて updateSubviewsTransition。ここはトランジションの切り替えで呼ばれる。
- (void)updateSubviewsTransition {
NSRect rect = [self bounds];
NSString *transitionType = nil;
CIFilter *transitionFilter = nil;
CIFilter *maskScalingFilter = nil;
CGRect maskExtent;
switch (transitionStyle) {
case SlideshowViewFadeTransitionStyle:
transitionType = kCATransitionFade;
break;
:
case SlideshowViewRippleTransitionStyle:
default:
transitionFilter = [[CIFilter filterWithName:@"CIRippleTransition"] retain];
[transitionFilter setDefaults];
[transitionFilter setValue:[CIVector vectorWithX:NSMidX(rect) Y:NSMidY(rect)] forKey:@"inputCenter"];
[transitionFilter setValue:[CIVector vectorWithX:rect.origin.x Y:rect.origin.y Z:rect.size.width W:rect.size.height] forKey:@"inputExtent"];
[transitionFilter setValue:inputShadingImage forKey:@"inputShadingImage"];
break;
CIRippleTransitionの設定が一通り行われる。続いて Core Annimation 設定。
// Construct a new CATransition that describes the transition effect we want.
CATransition *transition = [CATransition animation];
if (transitionFilter) {
// We want to build a CIFilter-based CATransition. When an CATransition's "filter" property is set, the CATransition's "type" and "subtype" properties are ignored, so we don't need to bother setting them.
[transition setFilter:transitionFilter];
} else {
// We want to specify one of Core Animation's built-in transitions.
[transition setType:transitionType];
[transition setSubtype:kCATransitionFromLeft];
}
// Specify an explicit duration for the transition.
[transition setDuration:1.0];
// Associate the CATransition we've just built with the "subviews" key for this SlideshowView instance, so that when we swap ImageView instances in our -transitionToImage: method below (via -replaceSubview:with:).
[self setAnimations:[NSDictionary dictionaryWithObject:transition forKey:@"subviews"]];
この @"subviews"がよくわからない。
そして transitionToImage: 。このメソッドは SlidshowWindowController から呼出される。画像が次々と変わる時に transitionToImage: が呼出される。
- (void)transitionToImage:(NSImage *)newImage {
:
:
// Create a new NSImageView and swap it into the view in place of our previous NSImageView. This will trigger the transition animation we've wired up in -updateSubviewsTransition, which fires on changes in the "subviews" property.
NSImageView *newImageView = nil;
if (newImage) {
newImageView = [[NSImageView alloc] initWithFrame:[self bounds]];
[newImageView setImage:newImage];
[newImageView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
}
if (currentImageView && newImageView) {
[[self animator] replaceSubview:currentImageView with:newImageView];
} else {
if (currentImageView) [[currentImageView animator] removeFromSuperview];
if (newImageView) [[self animator] addSubview:newImageView];
}
[currentImageView release];
currentImageView = newImageView;
}
渡された画像(NSImage)を表示する NSImageViewを作成し、トランジションをかける。っと見えるのだがイマイチ理解できない。
[[self animator] replaceSubview:currentImageView with:newImageView];
この辺りがトランジションのアニメーション処理の肝だろうか。