Как мне дополнительно анимировать изображение, которое находится на пути Безье

Может быть, кто-то может указать мне в правильном направлении. Я попробовал Google, но действительно не знаю, как определить мой вопрос в поисковых терминах.

Я анимирую изображение вдоль UIBezierPath следующим образом:

UIBezierPath *trackPath = [UIBezierPath bezierPath];
[trackPath moveToPoint:P(8, 250)];
[trackPath addCurveToPoint:P(318, 250)
             controlPoint1:P(156, 86)
             controlPoint2:P(166, 412)];
[trackPath addCurveToPoint:P(652, 254)
             controlPoint1:P(488, 86)
             controlPoint2:P(512, 412)];
[trackPath addCurveToPoint:P(992, 254)
             controlPoint1:P(818, 96)
             controlPoint2:P(872, 412)];


CALayer *bee = [CALayer layer];
bee.bounds = CGRectMake(0, 0, 69, 71);
bee.position = P(160, 25);
bee.contents = (id)([UIImage imageNamed:@"bee3.png"].CGImage);
[self.view.layer addSublayer:bee];

Что я хочу сделать, так это анимировать само изображение, когда оно движется по пути. Я могу анимировать изображение, когда оно само b, следующим образом:

    NSArray *blueArray = [NSArray array];
    blueArray = [[NSArray alloc] initWithObjects:
                 [UIImage imageNamed:@"blue1.png"],
                 [UIImage imageNamed:@"blue2.png"], nil];

    blueFly.animationImages = blueArray;
    blueFly.animationDuration = 0.20;
    blueFly.animationRepeatCount = -1;
    [blueFly startAnimating];

Как я могу совместить эти два, так сказать?

Кроме того, я знаю, как нарисовать сам путь на экране следующим образом:

CAShapeLayer *beeline = [CAShapeLayer layer];
beeline.path = trackPath.CGPath;
beeline.strokeColor = [UIColor whiteColor].CGColor;
beeline.fillColor = [UIColor clearColor].CGColor;
beeline.lineWidth = 2.0;
beeline.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:6],   [NSNumber numberWithInt:2], nil];
[self.view.layer addSublayer:beeline];

Но как я могу нарисовать линию только за изображением, поскольку оно анимируется по пути?


person Wesley Smith    schedule 04.09.2012    source источник


Ответы (2)


Вы можете использовать CAShapeLayer для отображения пути. Слой формы предоставляет два свойства strokeStart и strokeEnd, которые имеют значения между 0 и 1 и определяют видимую часть пути. Анимируя strokeEnd, вы можете создать впечатление, что путь «нарисован» на экране. См. http://oleb.net/blog/2010/12/animating-drawing-of-cgpath-with-cashapelayer для примера анимации пера, рисующего линию.

Чтобы изменить изображение пчелы, вы можете просто добавить анимацию, которая изменит содержимое вашего слоя с пчелой. Например, чтобы изменить изображение пера в проекте CAShapeLayer выше, мы можем добавить следующий код в метод startAnimation.

CAKeyframeAnimation *imageAnimation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
imageAnimation.duration = 1.0;
imageAnimation.repeatCount = HUGE_VALF;
imageAnimation.calculationMode = kCAAnimationDiscrete;
imageAnimation.values = [NSArray arrayWithObjects:
  (id)[UIImage imageNamed:@"noun_project_347_1.png"].CGImage,
  (id)[UIImage imageNamed:@"noun_project_347_2.png"].CGImage,
  nil];
[self.penLayer addAnimation:imageAnimation forKey:@"contents"];

Это просто добавляет ключевую анимацию к свойству contents слоя, отображающего перо. Обратите внимание, что изображение "noun_project_347_1.png" не является частью проекта, поэтому вам придется добавить изображение, чтобы увидеть эффект. Я просто перевернул изображение, которое идет с проектом, по горизонтали. При установке calculationMode на kCAAnimationDiscrete анимация не интерполируется между двумя изображениями, а заменяет одно другим.

person Jan Christiansen    schedule 04.09.2012
comment
Спасибо, Ян, я собираюсь погрузиться в этот пример, звучит идеально! Еще одна вещь, с которой я столкнулся, это то, как я могу отключить все анимации, когда я закончу с ними? У меня установлен таймер для вызова метода с именем masterReset через 7 секунд, что дает время для воспроизведения анимации, но я не знаю, как удалить созданные мной слои. - person Wesley Smith; 04.09.2012
comment
Я не уверен, что понимаю, что вам нужно, но вы можете удалить все анимации из слоя, вызвав removeAllAnimations. Кроме того, вы можете использовать removeAnimationForKey: для удаления определенной анимации. Если вам нужно согласовать несколько анимаций, например приостановить анимацию до завершения другой, посмотрите wangling.me/2011/06/time-warp-in-animation. Это было очень полезно для меня. - person Jan Christiansen; 04.09.2012
comment
Еще раз спасибо за ваше время. Я установил RepeatCount на 0 в CAKeyframAnimation, что теперь заставляет саму пчелу исчезать после того, как она достигает конечной точки, но я хочу одновременно удалить * beeline. я пробовал [self.view.layer removeAllAnimations]; но это не работает. Я предполагаю, что я действительно пытаюсь отклонить/удалить CAShapeLayer *beeline. - person Wesley Smith; 04.09.2012
comment
Вы можете просто удалить CAShapeLayer из его родительского слоя или установить strokeEnd на 0, если хотите использовать слой для другой анимации. - person Jan Christiansen; 04.09.2012
comment
Да, это то, что я читаю, но я не знаю, как это сделать. Проблема в том, что я хочу сделать это из другого метода, а именно из моего метода masterReset. но когда я пытаюсь сделать [beeline removeFromSuperlayer]; от этого способа билайн не опознается. Что мне нужно сделать, чтобы иметь возможность вызывать извне метод, создавший слой? - person Wesley Smith; 04.09.2012
comment
Если оба метода являются методами одного и того же объекта, вы, например, можете добавить переменную экземпляра к объекту, который хранит ссылку на слой. Извините, но мне кажется, что вам следует ознакомиться с некоторыми базовыми учебниками по объектно-ориентированному программированию. - person Jan Christiansen; 04.09.2012
comment
Не жалей, ты прав. Я только начинаю заниматься программированием. У меня есть небольшой опыт работы с HTML и CSS, но на этом все. Я просмотрел все видео на Lynda.com о Objective C и многому научился, но мои знания очень базовые, и я не совсем понимаю, как взаимодействуют все различные компоненты. Я только что делал кучу очень маленьких приложений, фокусирующихся на одной вещи за раз. Я наткнулся на пример анимации BezierPath и просто хотел посмотреть, как все анимации работают. - person Wesley Smith; 04.09.2012
comment
Было весело играть с ним, и я кое-чему научился, но это все еще немного не в моей лиге. Спасибо за ваше время, это ценится. - person Wesley Smith; 04.09.2012
comment
Немного поспав, я понял, что усложняю последнюю часть, и адаптировал свой код для создания второго вида, добавления слоев в этот вид, а затем просто удалял этот вид, когда анимация заканчивается. :) - person Wesley Smith; 05.09.2012
comment
давайте продолжим это обсуждение в чате - person Wesley Smith; 05.09.2012
comment
@JanChristiansen: Круто. Я не знал, что вы можете использовать массив изображений в качестве контента в анимации по ключевым кадрам. Спасибо за этот самородок. - person Duncan C; 07.09.2012

Пока вы можете получить точный путь, по которому вы хотите анимировать выравнивание изображения, вы можете сделать это с помощью Core Animation и CAKeyframeAnimation.

Обратитесь к инструкции -анимировать-одно-изображение-по-необычному-кривому-пути-в-моем-приложении-ipad).

person Paresh Navadiya    schedule 04.09.2012
comment
Спасибо, принц, на самом деле это одна из ссылок, которые я смог найти перед публикацией, но какая часть этого примера анимирует само изображение? У меня есть 2 изображения пчелы, одно с поднятыми крыльями, а другое с опущенными крыльями, и я хочу переключаться между двумя изображениями, поскольку они анимируются вдоль пути, поэтому кажется, что крылья хлопают. - person Wesley Smith; 04.09.2012