0

我正在尝试在 iPhone 上使用 Core Animation。

到目前为止我所做的详细信息:我正在使用图层和 CAKeyFrameAnimation 使用路径。我创建了一个图层,其内容设置为我想在螺旋路径上制作动画的苍蝇的位图文件。螺旋路径的中心点位于 CGPoint (150,150)。螺旋路径的终点是半径 100.0f。

我想要实现的目标:我还想将半径增加到一个值,以便螺旋可以超出视图框架的边界,但是当它到达边界时,我希望苍蝇回溯路径。

编辑:(添加代码):

-(IBAction) clickToAnimate:(id) sender 
{ 
    //create a path to animate the fly 
    CGFloat minRadius = 5.0f; 
    CGFloat maxRadius = 100.0f; 
    CGFloat radiusOffset = 5.0f; 
    float i; 
    int count =1; 
    int remainder; 
    curvePath = CGPathCreateMutable(); 
    //this looping mimics the "spiral path" 
    for (i = minRadius; i <= maxRadius; i = i + 5.0f) 
    { 
        remainder = count % 2; 
        if (remainder == 0) 
        { 
            CGPathAddArc(curvePath, NULL, currentPoint.x, currentPoint.y, i, M_PI / 2, 1.5 * M_PI, NO);  
        } 
        else 
        {
        CGPathAddArc(curvePath, NULL, currentPoint.x, currentPoint.y + radiusOffset, i, 1.5 * M_PI , M_PI / 2, NO);     
    }

            count = count +1; 
   }
    //add timer
    timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(checkCoordinatesOnTimer) userInfo:self repeats:YES];

        CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 
        animation.calculationMode = kCAAnimationPaced; 
        animation.path = curvePath; 
        animation.duration = 25.0f; 
        animation.autoreverses = YES; 
        animation.fillMode = kCAFillModeFrozen; 
        CGPathRelease(curvePath); 
        [animationLayer addAnimation:animation forKey:@"position"]; 

}
4

1 回答 1

0

采取的方法:我设置了一个计时器,它会每半秒检查一次动画层的坐标。将对照边界 x 和 y 坐标检查坐标。如果发现坐标越界,我们将禁用计时器并开始反向动画过程。反向动画过程将首先检查动画越过边界时与水平方向的角度。使用从中心点的角度和半径,创建反向动画的路径。详细信息可以在下面的代码中找到。

- (void) checkCoordinatesOnTimer
  {

     if (!presentLayer) 
     {
         presentLayer =[[CALayer alloc] init];
     }
     presentLayer = [animationLayer presentationLayer];

     CGPoint curPt;
     curPt.x = presentLayer.position.x;
     curPt.y = presentLayer.position.y;

     currRadius = sqrt(pow(fabsf(curPt.x - centerPoint.x), 2) + pow(fabsf(curPt.y -     centerPoint.y), 2));
     if ((curPt.x >= CGRectGetMaxX(self.view.frame)) || (curPt.y >= CGRectGetMaxY(self.view.frame))) 
     {
         [timer invalidate];
         [self reverseAnimation:curPt];
     }


 }

-(void) reverseAnimation:(CGPoint)curPoint 
{
    CGFloat angle = (CGFloat)[self calculateAngleInRadians:curPoint];

    maxRadius = currRadius;
    float i;
    int count =1;
    int remainder;
    BOOL firstLap = YES;

    CGPathRelease(curvePath);
    curvePath =  CGPathCreateMutable();
    for (i = maxRadius; i >= minRadius; i = i - 5.0f) 
    {
        remainder = count % 2 ;
        if (firstLap) 
        {
            if ((angle >= (M_PI/2)) && (angle <= 1.5 *M_PI)) 
                     //2nd and third quard, 
             //angle to change from final angle to 90
            {
                 CGPathAddArc(curvePath, NULL, centerPoint.x, centerPoint.y, i, angle, 1.5 * M_PI, FALSE);
            }
            else 
            { 
                CGPathAddArc(curvePath, NULL, centerPoint.x, centerPoint.y, i, angle,  M_PI / 2 , FALSE);       
            }
            firstLap = NO;
            continue;
      }
      else 
      {
            if (remainder == 0)
            {
                CGPathAddArc(curvePath, NULL, centerPoint.x, centerPoint.y, i, 1.5* M_PI,  M_PI / 2, FALSE);    
            }
            else 
            {

                CGPathAddArc(curvePath, NULL, centerPoint.x, centerPoint.y + radiusOffset, i, M_PI / 2 ,1.5* M_PI, FALSE);      
            }
       }
       count = count +1;
    }

    animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation.calculationMode =kCAAnimationPaced; // for even pacing of animation in segments.
    animation.path = curvePath;
    animation.duration = 40.0f;
    animation.fillMode = kCAFillModeForwards;
    CGPathRelease(curvePath);
    [animationLayer addAnimation:animation forKey:@"position"];
}
-(CGFloat) calculateAngleInRadians:(CGPoint) pt
{

CGFloat xLen = fabsf(centerPoint.x - pt.x);
CGFloat yLen = fabsf(centerPoint.y - pt.y);
double value = yLen/xLen;

double angle = atan(value);
double angleInDeg = ( 180 * angle/ M_PI);
double finalAngle;
if ((pt.x > centerPoint.x) || (pt.y > centerPoint.y)) {
    finalAngle = angle;
}
else if ((centerPoint.x > pt.x) || (pt.y > centerPoint.y))
{
    finalAngle = M_PI/2 + angle;
}
else if ((centerPoint.x > pt.x) || (centerPoint.y > pt.y))
{
    finalAngle = M_PI + angle;
}
else {
    finalAngle = (1.5 * M_PI) + angle;
}
return finalAngle;
}
于 2013-11-14T05:54:17.787 回答