Permalink
Browse files

New option to view folding control from a 3D side perspective

  • Loading branch information...
1 parent 99e3293 commit 5547840311ec8be3952775111d8c7516988f821c Mark Pospesel committed Aug 10, 2012
View
3 EnterTheMatrix/Enumerations.h
@@ -33,7 +33,8 @@ typedef enum {
SkewModeNone,
SkewModeLow,
SkewModeNormal,
- SkewModeHigh
+ SkewModeHigh,
+ SkewModeSide // Not a real skew mode, but a change in view point
} SkewMode;
typedef enum {
View
1 EnterTheMatrix/FlipViewController.m
@@ -191,6 +191,7 @@ - (CGFloat)skewMultiplier
return -4.666667;
case SkewModeNone:
+ case SkewModeSide:
return 0;
case SkewModeLow:
View
79 EnterTheMatrix/FoldViewController.m
@@ -129,17 +129,35 @@ - (void)viewDidUnload
[self setTopBar:nil];
[self setCenterBar:nil];
[self setBottomBar:nil];
- [self setSkewSegment:nil];
- [self setControlFrame:nil];
- [super viewDidUnload];
- // Release any retained subviews of the main view.
+ [self setSkewSegment:nil];
+ [self setControlFrame:nil];
+ [super viewDidUnload];
+ // Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
+- (void)viewWillAppear:(BOOL)animated
+{
+ [super viewWillAppear:animated];
+
+ // needed to keep view auto-sizing behavior from behaving badly with the optional side transform on contentView
+ UIView *superview = [self.contentView superview];
+ self.contentView.center = CGPointMake(roundf(CGRectGetMidX(superview.bounds)), roundf(CGRectGetMidY(superview.bounds)));
+ self.contentView.bounds = CGRectMake(0, 0, 500, 380);
+}
+
+- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
+{
+ UIView *superview = [self.contentView superview];
+ // needed to keep view auto-sizing behavior from behaving badly with the optional side transform on contentView
+ self.contentView.center = CGPointMake(roundf(CGRectGetMidX(superview.bounds)), roundf(CGRectGetMidY(superview.bounds)));
+ self.contentView.bounds = CGRectMake(0, 0, 500, 380);
+}
+
#pragma mark - Properties
- (SkewMode)skewMode
@@ -155,6 +173,7 @@ - (CGFloat)skew
return 1 / ((FOLD_HEIGHT / 2) * 4.666666667);
case SkewModeNone:
+ case SkewModeSide:
return 0;
case SkewModeLow:
@@ -242,9 +261,35 @@ - (void)handlePinch:(UIPinchGestureRecognizer *)gestureRecognizer {
}
- (IBAction)skewValueChanged:(UISegmentedControl *)sender {
- CATransform3D transform = CATransform3DIdentity;
- transform.m34 = [self skew];
- [[self perspectiveLayer] setSublayerTransform:transform];
+ BOOL wasSideView = !CATransform3DIsIdentity(self.contentView.layer.transform);
+ BOOL isSideView = self.skewMode == SkewModeSide;
+
+ CATransform3D perspectiveTransform = CATransform3DIdentity;
+ CATransform3D contentTransform = CATransform3DIdentity;
+
+ if (isSideView)
+ {
+ // Special transform so that we can view the fold from the side
+ perspectiveTransform.m34 = -0.0010;
+ perspectiveTransform = CATransform3DTranslate(perspectiveTransform, 30, -35, 0);
+ perspectiveTransform = CATransform3DRotate(perspectiveTransform, radians(60), .75, 1, -0.5);
+ contentTransform = perspectiveTransform;
+ }
+ else
+ perspectiveTransform.m34 = [self skew];
+
+ if (isSideView != wasSideView)
+ {
+ // animate the change in view point
+ CGFloat duration = DEFAULT_DURATION * [self durationMultiplier];
+ [UIView animateWithDuration:duration animations:^{
+ self.contentView.layer.transform = contentTransform;
+ }];
+ }
+ else
+ self.contentView.layer.transform = contentTransform;
+
+ [[self perspectiveLayer] setSublayerTransform:perspectiveTransform];
}
- (IBAction)durationValueChanged:(UISegmentedControl *)sender {
@@ -510,6 +555,10 @@ - (void)buildLayers
// we inset the folding panels 1 point on each side with a transparent margin to antialiase the edges
UIEdgeInsets foldInsets = vertical? UIEdgeInsetsMake(0, 1, 0, 1) : UIEdgeInsetsMake(1, 0, 1, 0);
+ // insets on top/bottom are only needed if we're transforming the entire view (in which case these edges need
+ // anti-aliasing as well)
+ UIEdgeInsets topInsets = vertical? UIEdgeInsetsMake(2,2,0,2) : UIEdgeInsetsMake(2, 2, 2, 0);
+ UIEdgeInsets bottomInsets = vertical? UIEdgeInsetsMake(0, 2, 2, 2) : UIEdgeInsetsMake(2, 0, 2, 2);
CGRect upperRect = bounds;
if (vertical)
@@ -526,14 +575,14 @@ - (void)buildLayers
[self.centerBar setHidden:NO];
UIImage * foldUpper = [MPAnimation renderImageFromView:self.centerBar withRect:upperRect transparentInsets:foldInsets];
UIImage * foldLower = [MPAnimation renderImageFromView:self.centerBar withRect:lowerRect transparentInsets:foldInsets];
- UIImage *slideUpper = [MPAnimation renderImageFromView:self.topBar];
- UIImage *slideLower = [MPAnimation renderImageFromView:self.bottomBar];
+ UIImage *slideUpper = [MPAnimation renderImageFromView:self.topBar withRect:self.topBar.bounds transparentInsets:topInsets];
+ UIImage *slideLower = [MPAnimation renderImageFromView:self.bottomBar withRect:self.bottomBar.bounds transparentInsets:bottomInsets];
UIView *actingSource = self.contentView;
UIView *containerView = [actingSource superview];
[actingSource setHidden:YES];
- CATransform3D transform = CATransform3DIdentity;
+ CATransform3D transform = self.contentView.layer.transform;
CALayer *upperFold;
CALayer *lowerFold;
@@ -543,7 +592,9 @@ - (void)buildLayers
CGFloat lowerHeight = (height * 2) - upperHeight;
// view to hold all our sublayers
+ self.contentView.layer.transform = CATransform3DIdentity; // need to temporarily remove transform before calling convertRect
CGRect mainRect = [containerView convertRect:self.centerBar.frame fromView:actingSource];
+ self.contentView.layer.transform = transform; // put the transform back
self.animationView = [[UIView alloc] initWithFrame:mainRect];
self.animationView.backgroundColor = [UIColor clearColor];
[containerView addSubview:self.animationView];
@@ -629,9 +680,8 @@ - (void)buildLayers
[self setDropShadowForLayer:self.bottomSleeve];
// reduce shadow on topSleeve slightly so it won't shade the upperFold panel so much
- CGRect topBounds = self.topSleeve.bounds;
- topBounds.size.height -= 3; // make it shorter by 3
- [self.topSleeve setShadowPath:[[UIBezierPath bezierPathWithRect:topBounds] CGPath]];
+ CGRect topBounds = CGRectMake(topInsets.left, topInsets.top, self.topSleeve.bounds.size.width - topInsets.left - topInsets.right, self.topSleeve.bounds.size.height - topInsets.top - topInsets.bottom - 3); // make it shorter by 3
+ [self.topSleeve setShadowPath:[[UIBezierPath bezierPathWithRect:topBounds] CGPath]];
CGRect upperFoldBounds = CGRectInset([upperFold bounds], foldInsets.left, foldInsets.top);
upperFoldBounds.size.height -= 1;
@@ -641,7 +691,8 @@ - (void)buildLayers
lowerFoldBounds.size.height -= 1;
[lowerFold setShadowPath:[[UIBezierPath bezierPathWithRect:lowerFoldBounds] CGPath]];
- [self.bottomSleeve setShadowPath:[[UIBezierPath bezierPathWithRect:[self.bottomSleeve bounds]] CGPath]];
+ CGRect bottomBounds = CGRectMake(bottomInsets.left, bottomInsets.top, self.bottomSleeve.bounds.size.width - bottomInsets.left - bottomInsets.right, self.bottomSleeve.bounds.size.height - bottomInsets.top - bottomInsets.bottom);
+ [self.bottomSleeve setShadowPath:[[UIBezierPath bezierPathWithRect:bottomBounds] CGPath]];
// Perspective is best proportional to the height of the pieces being folded away, rather than a fixed value
// the larger the piece being folded, the more perspective distance (zDistance) is needed.
View
140 EnterTheMatrix/en.lproj/MainStoryboard_iPad.storyboard
@@ -874,18 +874,19 @@ www.glyphish.com</string>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" id="UOG-po-r2B">
- <rect key="frame" x="20" y="20" width="425" height="120"/>
+ <rect key="frame" x="20" y="20" width="485" height="120"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="3" id="X9S-IX-LvT">
- <rect key="frame" x="105" y="70" width="300" height="30"/>
+ <rect key="frame" x="105" y="70" width="360" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<segments>
<segment title="Inverse"/>
<segment title="None"/>
<segment title="Low"/>
<segment title="Normal"/>
<segment title="High"/>
+ <segment title="Side"/>
</segments>
<connections>
<action selector="skewValueChanged:" destination="ueP-0g-58F" eventType="valueChanged" id="vI2-oj-OyF"/>
@@ -906,7 +907,7 @@ www.glyphish.com</string>
<nil key="highlightedColor"/>
</label>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="0" id="m9g-JV-hdk">
- <rect key="frame" x="105" y="20" width="300" height="30"/>
+ <rect key="frame" x="105" y="20" width="360" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<segments>
<segment title="1x"/>
@@ -1675,6 +1676,139 @@ www.glyphish.com</string>
<image name="matrix_01.png" width="480" height="360"/>
<image name="matrix_02.png" width="480" height="360"/>
</resources>
+ <classes>
+ <class className="AnchorPointTable" superclassName="UITableViewController">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/AnchorPointTable.h"/>
+ </class>
+ <class className="Arc" superclassName="UIView">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/Arc.h"/>
+ </class>
+ <class className="BasicAnimationViewController" superclassName="UIViewController">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/BasicAnimationViewController.h"/>
+ <relationships>
+ <relationship kind="action" name="animationChanged:"/>
+ <relationship kind="action" name="goPressed:"/>
+ <relationship kind="outlet" name="bar" candidateClass="UIView"/>
+ <relationship kind="outlet" name="controlFrame" candidateClass="UIView"/>
+ <relationship kind="outlet" name="modeSegment" candidateClass="UISegmentedControl"/>
+ <relationship kind="outlet" name="rotateLabel" candidateClass="UILabel"/>
+ <relationship kind="outlet" name="rotateSwitch" candidateClass="UISwitch"/>
+ <relationship kind="outlet" name="scaleLabel" candidateClass="UILabel"/>
+ <relationship kind="outlet" name="scaleSwitch" candidateClass="UISwitch"/>
+ <relationship kind="outlet" name="speedSwitch" candidateClass="UISwitch"/>
+ <relationship kind="outlet" name="translateLabel" candidateClass="UILabel"/>
+ <relationship kind="outlet" name="translateSwitch" candidateClass="UISwitch"/>
+ </relationships>
+ </class>
+ <class className="CATransformController" superclassName="TransformController">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/CATransformController.h"/>
+ <relationships>
+ <relationship kind="outlet" name="backgroundView" candidateClass="UIView"/>
+ </relationships>
+ </class>
+ <class className="CGAffineController" superclassName="TransformController">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/CGAffineController.h"/>
+ </class>
+ <class className="FlipViewController" superclassName="UIViewController">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/FlipViewController.h"/>
+ <relationships>
+ <relationship kind="action" name="antiAliaseValueChanged:"/>
+ <relationship kind="action" name="durationValueChanged:"/>
+ <relationship kind="action" name="shadowPathValueChanged:"/>
+ <relationship kind="action" name="skewValueChanged:"/>
+ <relationship kind="outlet" name="contentView" candidateClass="UIView"/>
+ <relationship kind="outlet" name="controlFrame" candidateClass="UIView"/>
+ <relationship kind="outlet" name="imageView" candidateClass="UIImageView"/>
+ <relationship kind="outlet" name="skewLabel" candidateClass="UILabel"/>
+ <relationship kind="outlet" name="skewSlider" candidateClass="UISlider"/>
+ </relationships>
+ </class>
+ <class className="FoldViewController" superclassName="UIViewController">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/FoldViewController.h"/>
+ <relationships>
+ <relationship kind="action" name="durationValueChanged:" candidateClass="UISegmentedControl"/>
+ <relationship kind="action" name="skewValueChanged:" candidateClass="UISegmentedControl"/>
+ <relationship kind="outlet" name="bottomBar" candidateClass="UIView"/>
+ <relationship kind="outlet" name="centerBar" candidateClass="UIView"/>
+ <relationship kind="outlet" name="contentView" candidateClass="UIView"/>
+ <relationship kind="outlet" name="controlFrame" candidateClass="UIView"/>
+ <relationship kind="outlet" name="skewSegment" candidateClass="UISegmentedControl"/>
+ <relationship kind="outlet" name="topBar" candidateClass="UIView"/>
+ </relationships>
+ </class>
+ <class className="GridView" superclassName="UIView">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/GridView.h"/>
+ </class>
+ <class className="GridViewController" superclassName="UIViewController">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/GridViewController.h"/>
+ <relationships>
+ <relationship kind="action" name="lockPressed:"/>
+ <relationship kind="action" name="resetPressed:"/>
+ <relationship kind="action" name="rotateHorzChanged:"/>
+ <relationship kind="action" name="rotateVertChanged:"/>
+ <relationship kind="action" name="scaleHorzChanged:"/>
+ <relationship kind="action" name="scaleVertChanged:"/>
+ <relationship kind="action" name="translateHorzChanged:"/>
+ <relationship kind="action" name="translateVertChanged:"/>
+ <relationship kind="outlet" name="grid" candidateClass="GridView"/>
+ <relationship kind="outlet" name="horizontalPanel" candidateClass="UIView"/>
+ <relationship kind="outlet" name="lockButton" candidateClass="UIButton"/>
+ <relationship kind="outlet" name="resetButton" candidateClass="UIButton"/>
+ <relationship kind="outlet" name="verticalPanel" candidateClass="UIView"/>
+ </relationships>
+ </class>
+ <class className="InfoView" superclassName="UIViewController">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/InfoView.h"/>
+ <relationships>
+ <relationship kind="outlet" name="label" candidateClass="UITextView"/>
+ </relationships>
+ </class>
+ <class className="KeyframeViewController" superclassName="UIViewController">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/KeyframeViewController.h"/>
+ <relationships>
+ <relationship kind="action" name="arcPositionValueChanged:"/>
+ <relationship kind="outlet" name="arc" candidateClass="Arc"/>
+ <relationship kind="outlet" name="arcPositionSegment" candidateClass="UISegmentedControl"/>
+ <relationship kind="outlet" name="bottomLabel" candidateClass="UILabel"/>
+ <relationship kind="outlet" name="controlFrame" candidateClass="UIView"/>
+ <relationship kind="outlet" name="modeSegment" candidateClass="UISegmentedControl"/>
+ <relationship kind="outlet" name="speedSwitch" candidateClass="UISwitch"/>
+ <relationship kind="outlet" name="topLabel" candidateClass="UILabel"/>
+ </relationships>
+ </class>
+ <class className="TransformController" superclassName="UIViewController">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/TransformController.h"/>
+ <relationships>
+ <relationship kind="action" name="anchorPressed:"/>
+ <relationship kind="action" name="infoPressed:"/>
+ <relationship kind="action" name="resetPressed:"/>
+ <relationship kind="action" name="transformPressed:"/>
+ <relationship kind="outlet" name="contentView" candidateClass="UIView"/>
+ <relationship kind="outlet" name="toolbar" candidateClass="UIToolbar"/>
+ </relationships>
+ </class>
+ <class className="TransformTable" superclassName="UITableViewController">
+ <source key="sourceIdentifier" type="project" relativePath="./Classes/TransformTable.h"/>
+ <relationships>
+ <relationship kind="action" name="resetRotationPressed:"/>
+ <relationship kind="action" name="resetScalePressed:"/>
+ <relationship kind="action" name="resetSkewPressed:"/>
+ <relationship kind="action" name="resetTranslatePressed:"/>
+ <relationship kind="action" name="rotateXChanged:"/>
+ <relationship kind="action" name="rotateYChanged:"/>
+ <relationship kind="action" name="rotateZChanged:"/>
+ <relationship kind="action" name="rotationAngleChanged:"/>
+ <relationship kind="action" name="scaleLockPressed:"/>
+ <relationship kind="action" name="scaleXChanged:"/>
+ <relationship kind="action" name="scaleYChanged:"/>
+ <relationship kind="action" name="scaleZChanged:"/>
+ <relationship kind="action" name="skewChanged:"/>
+ <relationship kind="action" name="translateXChanged:"/>
+ <relationship kind="action" name="translateYChanged:"/>
+ <relationship kind="action" name="translateZChanged:"/>
+ </relationships>
+ </class>
+ </classes>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar" statusBarStyle="blackTranslucent"/>
<simulatedOrientationMetrics key="orientation"/>

0 comments on commit 5547840

Please sign in to comment.