My question concerns the possibility of tracking the coordinates of the strokeEnd point of a CAShapeLayer.
I have an UISlider, which generates a variable between 0 and 1. I Create an UIBezierPath from a CGMutablePathRef and I assign it as the path property of an CAShapeLayer.
Here is my header file:
@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UISlider *progressSlider;
@property (strong,nonatomic) CAShapeLayer *raceTrack;
- (IBAction)progressChanged:(id)sender;
@end
In the implementation file, I wrote the following code:
CGMutablePathRef truePath = CGPathCreateMutable();
CGPathMoveToPoint(truePath, NULL, 100.0f, 468.0f-20.0f);
CGPathAddQuadCurveToPoint(truePath, NULL, 70.0f, 268.0f, 100.0f, 68.0f+20.0f);
UIBezierPath *trackPath = [UIBezierPath bezierPathWithCGPath:truePath];
self.raceTrack = [CAShapeLayer layer];
self.raceTrack.path = trackPath.CGPath;
self.raceTrack.strokeEnd = 0.0;
self.raceTrack.strokeColor = [UIColor yellowColor].CGColor;
self.raceTrack.fillColor = [UIColor clearColor].CGColor;
self.raceTrack.lineWidth = 7.0;
[self.view.layer addSublayer:self.raceTrack];
And each time the slider is changed the following function is called:
- (IBAction)progressChanged:(id)sender{
self.raceTrack.strokeEnd = self.progressSlider.value;}
This works perfectly ! But now I want to add a kind of circle at the end of line drawn on the screen. I cannot post image, but if you want to understand we may assume that the circle is a comet and behind it, the stroked path is the tail of the comet.
And I don't know how to achieve this. I thought maybe the best way was to track the coordinates of the stroke end point and add a circle with addSublayer and set the position property of this circle equals to the coordinates of the strokeEnd point. I don't know if a such strokeEnd point exists or maybe there is a simple solution one of you used for this kind of problem.
This why I am asking for your help for the first time.
As far as I know, you have to calculate the point from the formula for the quadratic bezier curve. This code, will do that,
- (IBAction)progressChanged:(UISlider *)sender{
self.raceTrack.strokeEnd = sender.value;
CGPoint strokeEnd = [self pointAtStrokeEnd:sender.value];
}
-(CGPoint)pointAtStrokeEnd:(CGFloat) fraction {
CGFloat x = (1 - fraction) * (1 - fraction) * self.startPoint.x + 2 * (1 - fraction) * fraction * self.controlPoint.x + fraction * fraction * self.endPoint.x;
CGFloat y = (1 - fraction) * (1 - fraction) * self.startPoint.y + 2 * (1 - fraction) * fraction * self.controlPoint.y + fraction * fraction * self.endPoint.y;
return CGPointMake(x, y);
}
You'll need to create properties or ivars for the starting, ending, and control point of your curve so you can pass them to the pointAtStrokeEnd: method.