Tap to toggle visible flight paths
iPad landscape screenshots
Key Tech Features
Core Graphics Layers
Scalable Bezier Paths
Core Animation
CAShapeLayer * visibleFlightPath1; //ivars CAShapeLayer * visibleFlightPath2; -(void)setup { CALayer * b1 = getBumblebee(); CALayer * b2 = getBumblebee(); CGPathRef fp1 = getFlightPath(0, 1.0f, 1.0f); CGPathRef fp2 = getFlightPath(80, 3.0f, 0.8f); CAKeyframeAnimation * a1 = getAnimationWithPath(fp1, 3.3, 0); [b1 addAnimation:a1 forKey:nil]; [self.view.layer addSublayer:b1]; CAKeyframeAnimation * a2 = getAnimationWithPath(fp2, 3.9, 0); [b2 addAnimation:a2 forKey:nil]; [self.view.layer addSublayer:b2]; visibleFlightPath1 = getVisibleFlightPath(fp1); visibleFlightPath2 = getVisibleFlightPath(fp2); [self.view.layer addSublayer:visibleFlightPath1]; [self.view.layer addSublayer:visibleFlightPath2]; } CAGradientLayer * getBumblebee() { CAGradientLayer * b = [CAGradientLayer layer]; b.frame = CGRectMake(0, 0, 25, 25); b.borderColor = [UIColor darkGrayColor].CGColor; b.borderWidth = 0.5f; b.cornerRadius = 10.0f; b.masksToBounds = YES; CGColorRef black = [UIColor blackColor].CGColor; CGColorRef yellow = [UIColor yellowColor].CGColor; b.colors = @[ (__bridge id)black, (__bridge id)yellow, (__bridge id)black, (__bridge id)yellow ]; //vertical gradient b.startPoint = CGPointMake(0.0f, 0.5f); b.endPoint = CGPointMake(1.0f, 0.5f); b.locations = @[ [NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:0.33], [NSNumber numberWithFloat:0.5], [NSNumber numberWithFloat:0.9], [NSNumber numberWithFloat:1.0] ]; return b; } CGPathRef getFlightPath(const int yOffset, const CGFloat factor1, const CGFloat factor2) { const CGPoint startPoint = CGPointMake(20, (200 + (yOffset * factor1))); const CGFloat normalFlightPoints[] = { 220, 200, 420, 200, 620, 200, 820, 200 }; UIBezierPath * fp = [UIBezierPath bezierPath]; [fp moveToPoint:startPoint]; //add normal flight points const int count = sizeof(normalFlightPoints)/sizeof(CGFloat); const int cpOffset = 100; const CGFloat cpYOffsetFactor = (cpOffset * factor1); for (int i = 0, s = 0; i < count; i++, s++) { const CGFloat x = normalFlightPoints[i]; const CGFloat y = normalFlightPoints[i + 1] + (yOffset * factor1); const CGPoint p = CGPointMake(x, y); const CGFloat cpYHighLowOffset = ((s % 2) ? cpYOffsetFactor : -cpYOffsetFactor); const CGPoint cp = CGPointMake((p.x - cpOffset), (p.y + cpYHighLowOffset)); [fp addQuadCurveToPoint:p controlPoint:cp]; //connect flight points i += 1; } //add pseudo random flight points const CGFloat w = (yOffset * factor1) * factor2; [fp addQuadCurveToPoint:CGPointMake(700, 175 + w) controlPoint:CGPointMake(850, 150 + w)]; [fp addQuadCurveToPoint:CGPointMake(900, 200 + w) controlPoint:CGPointMake(550, 200 + w)]; const CGFloat randomYOffset = (arc4random_uniform(2) == 0 ? -cpOffset : cpOffset); [fp addCurveToPoint:CGPointMake(1200, fp.currentPoint.y + randomYOffset) controlPoint1:CGPointMake(1000, fp.currentPoint.y) controlPoint2:CGPointMake(1100, fp.currentPoint.y)]; return fp.CGPath; } CAKeyframeAnimation * getAnimationWithPath(CGPathRef aPath, CFTimeInterval aDuration, CFTimeInterval aTimeOffset) { CAKeyframeAnimation * a = [CAKeyframeAnimation animation]; a.keyPath = @"position"; a.path = aPath; a.duration = aDuration; a.timeOffset = aTimeOffset; a.repeatCount = HUGE_VALF; a.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; return a; } CAShapeLayer * getVisibleFlightPath(CGPathRef aPath) { CAShapeLayer * fp = [CAShapeLayer layer]; fp.path = aPath; fp.fillColor = [UIColor clearColor].CGColor; fp.strokeColor = [UIColor darkGrayColor].CGColor; fp.lineWidth = 1.0f; fp.zPosition = -1.0f; return fp; } //tap to toggle visible flight paths -(void)tap:(UIGestureRecognizer*)sender { visibleFlightPath1.hidden = !visibleFlightPath1.hidden; visibleFlightPath2.hidden = !visibleFlightPath2.hidden; } -(void)viewDidLoad { [super viewDidLoad]; UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)]; [self.view addGestureRecognizer:tap]; [self setup]; }
No comments:
Post a Comment