I am doing a calligraphy application and would like to modify my code below so when a user ends a brush stroke, the line tapers and thins out like it would with a real calligraphy pen (a flick effect). I understand that touchesEnded may be a better way to do this, however I was just wondering what would be the best way to programmatically make this flick at the end of a stroke using CGRect or GraphicsContext in UIKit in Xcode for Objective C.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
currentPoint = [touch locationInView:self.view];
UIGraphicsBeginImageContext(CGSizeMake(320, 568));
[drawImage.image drawInRect:CGRectMake(0, 0, 320, 568)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0, 0, 0, 1);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
[drawImage setFrame:CGRectMake(0, 0, 320, 568)];
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
//what code do I put here to get the flick effect - what CGGetContext Parameter
//may be applicable or what programming technique may help with this.
}
This may be over simplifying, but it should lead you in something of the right direction. I'm going to just make a triangle, but you could eventually add bezier curves to make the effect more realistic.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
//what code do I put here to get the flick effect - what CGGetContext Parameter
//may be applicable or what programming technique may help with this.
UIGraphicsBeginImageContext(CGSizeMake(320, 568));
[drawImage.image drawInRect:CGRectMake(0, 0, 320, 568)];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 5.0);
CGContextSetRGBFillColor(context, 0, 0, 0, 1);
CGContextBeginPath(context);
CGContextBeginPath(context);
CGContextMoveToPoint(context, lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(context, currentPoint.x, currentPoint.y);
CGContextClosePath(context);
CGContextStrokePath(context);
//Normalized directionality
float lineLength = sqrt((currentPoint.x - lastPoint.x)*(currentPoint.x - lastPoint.x) + (currentPoint.y - lastPoint.y)*(currentPoint.y - lastPoint.y));
float dx = (currentPoint.x - lastPoint.x)/lineLength;
float dy = (currentPoint.y - lastPoint.y)/lineLength;
//Now make a triangle
CGContextBeginPath(context);
//2.5 is from 1/2 of your line width (5)
CGContextMoveToPoint(context, currentPoint.x + 2.5*dy, currentPoint.y - 2.5*dx);
//This 10 is completely arbitrary, the length your taper is going to be.
//Ideally this will be proportional to your last line segment length, longer if their finger is moving faster...
CGContextAddLineToPoint(context, currentPoint.x + 10*dx, currentPoint.y + 10*dy);
//Now the last tip of the triangle
CGContextMoveToPoint(context, currentPoint.x - 2.5*dy, currentPoint.y + 2.5*dx);
CGContextClosePath(context);
CGContextFillPath(context);
[drawImage setFrame:CGRectMake(0, 0, 320, 568)];
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
Now to make this cooler you could add in calculation of the curve the person was drawing and create your "triangle" taper with bezier curves in the direction that they were curving. That could actually be really fun to calculate.