// // CAScrollDeltaLayer.m // GooPad // // Created by Joachim Bengtsson on 2007-08-03. // Copyright 2007 Joachim Bengtsson. All rights reserved. // #import "CAScrollDeltaLayer.h" #import "CALayerAdditions.h" TCVector TCVectorMake(CGFloat x, CGFloat y, CGFloat z) { TCVector vec; vec.x = x; vec.y = y; vec.z = z; return vec; } @implementation CAScrollDeltaLayer -(id)init; { if(![super init]) return nil; currentScroll = CGRectMake(0, 0, 0, 0); currentZoom = 1.0; return self; } - (void)scrollDelta:(CGPoint)deltaScroll; { currentScroll.origin.x -= deltaScroll.x*(1.0/currentZoom); currentScroll.origin.y += deltaScroll.y*(1.0/currentZoom); [super scrollToPoint:currentScroll.origin]; } - (void)zoomDelta:(CGFloat)deltaZoom; { deltaZoom *= currentZoom; currentZoom += deltaZoom; currentZoom = fabsf(currentZoom); [self applyTransforms]; } -(CGFloat)zoom; { return currentZoom; } - (void)rotateDelta:(TCVector)rotations; { currentRotation.x += rotations.x; currentRotation.y += rotations.y; currentRotation.z += rotations.z; [self applyTransforms]; } - (void)scrollToPoint:(CGPoint)thePoint { currentScroll.origin = thePoint; [super scrollToPoint:thePoint]; } - (void)scrollToRect:(CGRect)r { currentScroll = r; [super scrollToRect:r]; } - (CGPoint)compensatePoint:(CGPoint)p; { NSAffineTransform *ts = [NSAffineTransform transform]; [ts translateXBy:currentScroll.origin.x yBy:currentScroll.origin.y]; [ts translateXBy:self.anchorPoint.x*self.frame.size.width yBy:self.anchorPoint.y*self.frame.size.height]; [ts scaleBy:1.0/currentZoom]; [ts translateXBy:-self.anchorPoint.x*self.frame.size.width yBy:-self.anchorPoint.y*self.frame.size.height]; p = NSPointToCGPoint([ts transformPoint:NSPointFromCGPoint(p)]); return p; } - (NSPoint)compensateNSPoint:(NSPoint)p; { return NSPointFromCGPoint([self compensatePoint:NSPointToCGPoint(p)]); } -(CGPoint) unscrollPoint:(CGPoint)p; { return CGPointMake(currentScroll.origin.x + p.x, currentScroll.origin.y + p.y); } -(void)applyTransforms; { CATransform3D sublay = CATransform3DMakeScale(currentZoom, currentZoom, currentZoom); sublay = CATransform3DRotate(sublay, currentRotation.x, 1, 0, 0); sublay = CATransform3DRotate(sublay, currentRotation.y, 0, 1, 0); sublay = CATransform3DRotate(sublay, currentRotation.z, 0, 0, 1); float zDistance = 420.; sublay.m34 = 1. / -zDistance; self.sublayerTransform = sublay; } @end