-
-
Save tonyxiao/7861726 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// VideoView.m | |
// MacVideoWall | |
// | |
// Created by David Rönnqvist on 9/28/13. | |
// This is the source code behind the Mac Video Wall that I was trying to port to iOS in [this Stack Overflow question](http://stackoverflow.com/questions/19065816/ios-alternative-to-qtmovielayer-that-has-non-nil-contents) | |
// | |
#import "VideoView.h" | |
#import <QuartzCore/QuartzCore.h> | |
#import <QTKit/QTKit.h> | |
@interface VideoView () | |
@property (strong) CALayer *sourceLayer; | |
@end | |
@implementation VideoView | |
- (void)awakeFromNib { | |
// Initialization code here. | |
// The view needs layers | |
[self setWantsLayer:YES]; | |
self.layer.backgroundColor = [NSColor colorWithCalibratedWhite:0.15 alpha:1.0].CGColor; | |
// Give the view's layer a perspective transform for it's children | |
CATransform3D perspective = CATransform3DIdentity; | |
perspective.m34 = 1./800.; | |
self.layer.sublayerTransform = perspective; | |
// Load the movie | |
NSError *error = nil; | |
NSURL *videoURL = [[NSBundle mainBundle] URLForResource:@"video" withExtension:@"m4v"]; | |
NSLog(@"can %@ play this", [QTMovie canInitWithURL:videoURL]?@"absolutely":@"not"); | |
QTMovie *movie = [QTMovie movieWithURL:videoURL error:&error]; | |
if (error) { | |
NSLog(@"ERROR! %@", [error localizedDescription]); | |
} | |
// Create a movie layer | |
QTMovieLayer *movieLayer = [QTMovieLayer layerWithMovie:movie]; | |
self.sourceLayer = movieLayer; | |
movieLayer.frame = CGRectInset(self.bounds, 50, 50); | |
[self.layer addSublayer:movieLayer]; | |
// Start playing the movie | |
[movie play]; | |
// Layout more layers inside this layer | |
CGRect layerRects = CGRectInset(self.bounds, 15, 15); | |
NSInteger num = 10; | |
CGFloat margin = 0.; | |
// Width & height of the layers | |
CGFloat width = CGRectGetWidth(layerRects)/num-margin; | |
CGFloat height = CGRectGetHeight(layerRects)/num-margin; | |
CGFloat floatNum = num; | |
self.sourceLayer.frame = (CGRect){layerRects.origin, CGSizeMake(width, height)}; | |
self.sourceLayer.contentsRect = CGRectMake(0, 0, 1/floatNum, 1/floatNum); | |
// These are just the animations that tilt the all the layers | |
CABasicAnimation *flipY = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"]; | |
flipY.fromValue = @(-M_PI/5.); | |
flipY.toValue = @(+M_PI/5.); | |
flipY.duration = 2.0; | |
flipY.autoreverses = YES; | |
flipY.repeatCount = INFINITY; | |
CABasicAnimation *flipX = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"]; | |
flipX.fromValue = @(-M_PI/3.); | |
flipX.toValue = @(+M_PI/3.); | |
flipX.duration = 3.5; | |
flipX.autoreverses = YES; | |
flipX.repeatCount = INFINITY; | |
// Tilt the source layer | |
[self.sourceLayer addAnimation:flipY forKey:nil]; | |
[self.sourceLayer addAnimation:flipX forKey:nil]; | |
// Loop over the rows and coumns to create a grid of layers | |
for (NSInteger col=0; col<num; col++) { | |
for (NSInteger row=0; row<num; row++) { | |
if (row+col == 0) continue; | |
// Create a new layer | |
CALayer *copiedLayer = [CALayer layer]; | |
// Give it the same contents as the movie layer | |
copiedLayer.contents = self.sourceLayer.contents; | |
copiedLayer.frame = CGRectMake(CGRectGetMinX(layerRects)+row*width +row*margin, | |
CGRectGetMinY(layerRects)+col*height +col*margin, | |
width, height); | |
// Display only part of that conent in this layer | |
copiedLayer.contentsRect = CGRectMake(row/floatNum, col/floatNum, 1/floatNum, 1/floatNum); | |
[self.layer addSublayer:copiedLayer]; | |
// Add the tilting animation | |
[copiedLayer addAnimation:flipY forKey:nil]; | |
[copiedLayer addAnimation:flipX forKey:nil]; | |
} | |
} | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment