#ios #animation #border
#iOS #Анимация #граница
Вопрос:
У меня есть UIImageView, отображающий изображение. Я хочу «выделить» часть изображения, нарисовав округлый контур прямоугольника. Я хотел бы, чтобы контур был нарисован толстой пунктирной линией, которая «анимируется», постоянно изменяя, где начинается «начало» строки.
Я думал о том, чтобы нарисовать круг, который имел бы желаемый вид, а затем просто анимировать его, но мне действительно нужно прямоугольное решение, так что это исключено.
Фон:
Я рисую округлую прямоугольную границу, вычисляя 8 точек и рисуя 4 прямые линии и 4 кривые. (Может быть, это может быть проще, но это не сломанная часть!)
Я думаю, что я буду использовать переменную «offset», которая начинается в верхнем левом углу закругленного прямоугольника, где верхняя левая кривая встречается с верхней прямой частью. Затем я буду увеличивать это «смещение» по верхней части закругленного прямоугольника, пока оно не достигнет кривой в правом верхнем углу, после чего я «сброшу» переменную «offset» до ее исходного значения.
Это работает почти так, как мне хотелось бы, пока не произойдет «сброс». На этом этапе анимация отрывистая (вроде ожидаемая), но, похоже, она также движется в обратном направлении в течение небольшой части времени, прежде чем возобновить движение «вперед». Наконец, в начале / конце моей пунктирной линии я получаю дополнительный длинный сегмент на пунктирной линии. Я знаю, что они не могут быть одинаковой длины (не так ли? как вычислить?), но как я могу сделать 2 более коротких сегмента, а не 1 более длинный сегмент?
У кого-нибудь есть представление о том, что я могу сделать, чтобы получить гладкий вид «марширующих муравьев»? Любые другие идеи о хорошем способе (с использованием анимации) привлечь внимание пользователя к определенной области экрана? (Он должен окружать определенную область, не скрывая ее.)
Текущий код:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);
// Rounded corner will be 10% of average side length (i.e., (w h) / 2)
float averageSide = ([self HighlightRect].size.width [self HighlightRect].size.height) / 2.0;
float roundSize = averageSide * 0.10;
// offset is a static, class variable
offset = roundSize / 4.0;
if ([WhereIAmView offset] < roundSize) {
offset = roundSize;
}
if ([WhereIAmView offset] > ([self HighlightRect].size.width - roundSize)) {
offset = roundSize;
}
// Set the "main" color of the rounded rectangle
UIColor *lineColor = [UIColor colorWithRed:027.0/255.0 green:050.0/255.0 blue:224.0/255.0 alpha:1.0];
CGContextSetStrokeColorWithColor(context, [lineColor CGColor]);
CGContextSetLineWidth(context, 16.0);
CGFloat pattern[] = {25.0, 5.0};
CGContextSetLineDash(context, offset, pattern, 2);
CGRect rRect = [self HighlightRect];
// The top left corner
CGPoint topLeft = CGPointMake(rRect.origin.x, rRect.origin.y);
// The top right corner
CGPoint topRight = CGPointMake(rRect.origin.x rRect.size.width, rRect.origin.y);
// The bottom right corner
CGPoint bottomRight = CGPointMake(rRect.origin.x rRect.size.width, rRect.origin.y rRect.size.height);
// The bottom left corner
CGPoint bottomLeft = CGPointMake(rRect.origin.x, rRect.origin.y rRect.size.height);
// The two points across the top of the rounded rectangle (left to right)
CGPoint point1 = CGPointMake(rRect.origin.x roundSize, rRect.origin.y);
CGPoint point2 = CGPointMake(rRect.origin.x rRect.size.width - roundSize, rRect.origin.y);
// The two points along the right of the rounded rectangle (top to bottom)
CGPoint point3 = CGPointMake(rRect.origin.x rRect.size.width, rRect.origin.y roundSize);
CGPoint point4 = CGPointMake(rRect.origin.x rRect.size.width, rRect.origin.y rRect.size.height - roundSize);
// The two points along the bottom of the rounded rectangle (right to left)
CGPoint point5 = CGPointMake(rRect.origin.x rRect.size.width - roundSize, rRect.origin.y rRect.size.height);
CGPoint point6 = CGPointMake(rRect.origin.x roundSize, rRect.origin.y rRect.size.height);
// The two points along the left of the rounded rectangle (bottom to top)
CGPoint point7 = CGPointMake(rRect.origin.x, rRect.origin.y rRect.size.height - roundSize);
CGPoint point8 = CGPointMake(rRect.origin.x, rRect.origin.y roundSize);
// Move to point 1
CGContextMoveToPoint(context, point1.x, point1.y);
// Add line to point 2 (this is the straight portion across the top)
CGContextAddLineToPoint(context, point2.x, point2.y);
// Add curve to point 3 (this is the rounded portion in top right)
CGContextAddArcToPoint(context, topRight.x, topRight.y, point3.x, point3.y, roundSize);
// Add line to point 4 (this is the straight portion across the right)
CGContextAddLineToPoint(context, point4.x, point4.y);
// Add curve to point 5 (this is the rounded portion in bottom right)
CGContextAddArcToPoint(context, bottomRight.x, bottomRight.y, point5.x, point5.y, roundSize);
// Add line to point 6 (this is the straight portion across the bottom)
CGContextAddLineToPoint(context, point6.x, point6.y);
// Add curve to point 7 (this is the rounded portion in bottom left)
CGContextAddArcToPoint(context, bottomLeft.x, bottomLeft.y, point7.x, point7.y, roundSize);
// Add line to point 8 (this is the straight portion across the left)
CGContextAddLineToPoint(context, point8.x, point8.y);
// Add curve to point 1 (this is the rounded portion in top left)
CGContextAddArcToPoint(context, topLeft.x, topLeft.y, point1.x, point1.y, roundSize);
// Stroke the path
CGContextStrokePath(context);
}
удар
, удар, удар
Комментарии:
1. вы хотите эффект «марширующих муравьев» для изображения с круглым углом ?.
Ответ №1:
Попробуйте использовать CAShapeLayer с CGPath вашей формы.
Путь к округлому прямоугольнику может быть построен с использованием удобного метода Uibezierpath.
Вы можете задать шаблон линий для слоя фигуры. Анимация свойства line слоя shape даст «эффект марширующих муравьев«.
shapeLayer = [CAShapeLayer layer];
CGRect shapeRect = CGRectMake(0.0f, 0.0f, 200.0f, 100.0f);
[shapeLayer setBounds:shapeRect];
[shapeLayer setPosition:CGPointMake(160.0f, 140.0f)];
[shapeLayer setFillColor:[[UIColor clearColor] CGColor]];
[shapeLayer setStrokeColor:[[UIColor blackColor] CGColor]];
[shapeLayer setLineWidth:1.0f];
[shapeLayer setLineJoin:kCALineJoinRound];
[shapeLayer setLineDashPattern:
[NSArray arrayWithObjects:[NSNumber numberWithInt:10],
[NSNumber numberWithInt:5],
nil]];
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:shapeRect cornerRadius:15.0];
[shapeLayer setPath:path.CGPath];
[[imageview layer] addSublayer:shapeLayer];
Функция анимации может быть,
- (void)toggleMarching
{
if ([shapeLayer animationForKey:@"linePhase"])
[shapeLayer removeAnimationForKey:@"linePhase"];
else {
CABasicAnimation *dashAnimation;
dashAnimation = [CABasicAnimation
animationWithKeyPath:@"lineDashPhase"];
[dashAnimation setFromValue:[NSNumber numberWithFloat:0.0f]];
[dashAnimation setToValue:[NSNumber numberWithFloat:15.0f]];
[dashAnimation setDuration:0.75f];
[dashAnimation setRepeatCount:10000];
[shapeLayer addAnimation:dashAnimation forKey:@"linePhase"];
}
}
Комментарии:
1. Мальчик! Этот код выглядит знакомо, cimgf.com/2009/10/20/marching-ants-with-core-animation . Атрибуция, конечно, была бы хороша.
2. @Matt На самом деле я намеревался указать атрибуцию, сказав «эффект марширующих муравьев» и ссылку на него. Но, увы, ссылка пропущена. Я отредактировал. Кстати, спасибо !.
3. Привет, Мэтт, я пытаюсь адаптировать код «эффект марширующих муравьев» для Mac, но безуспешно. Любой совет? Большое вам спасибо!