Не все слои CoreAnimation движутся с одинаковой скоростью: что мне не хватает? - PullRequest
0 голосов
/ 11 октября 2011

У меня есть приложение с CALayers, которое перемещается с одной стороны экрана на другую.Я пытаюсь подобрать правильное время, чтобы все они заняли одно и то же время, чтобы перейти от первой стороны к произвольному разделителю, который я выбрал (рядом с другой стороной), а затем продолжить свой пробег, чтобы исчезнуть с экрана.

Вот пример того, что я имею в виду:

visual description of my problem

Оба блока должны двигаться с одинаковой скоростью (анимация имеет линейное время), поэтому, когда маленький блок попадает вразделитель, небольшой разрыв между ними должен быть одинаковым.

Однако я скорее вижу это:

visual description of what happens

Выражение словами, кажется, что мой большойкоробка движется быстрее, чем маленькая коробка.

Вот соответствующая часть моего кода.Я определяю скорость в пикселях в секунду, затем устанавливаю продолжительность анимации, учитывая количество пикселей, которые должны перемещаться.

const CGRect viewBounds = CGRectMake(0,0, 500, 400);
const CGFloat distanceToCross = viewBounds.size.width - delimiterX;
const CFTimeInterval timeToCross = 5;
const CGFloat pixelsPerSecond = distanceToCross / timeToCross;

const CGFloat y = /* y coordinate of the box */;
CALayer* box = [CALayer layer];
// the layer should lie outside the viewport at first
box.frame = CGRectMake(viewBounds.size.width, y, /* size here */);
box.anchorPoint = CGPointMake(0, 0.5);
// snip

[CATransaction begin];
CATransaction.animationTimingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
CATransaction.animationDuration = (viewBounds.size.width + box.frame.size.width) / pixelsPerSecond;
// and the layer should cross the viewport to outside of it, too
box.position = CGPointMake(-box.frame.size.width, y);
[CATransaction commit];

Это не показано в моем графическом примере, но блоки такого же размеравсе идут с одинаковой скоростью, поэтому, очевидно, я делаю что-то не так с моим расчетом времени.Чего мне не хватает?

1 Ответ

1 голос
/ 11 октября 2011

CALayer.position по умолчанию указывает центральную точку поля. Таким образом, ваш конечный кадр для каждого блока фактически превышает желаемую точку, а сумма, которую он превышает, зависит от размера блока. Это отбросит ваш расчет, поскольку ваша продолжительность основана на неправильном расстоянии. Я удивлен, что вы не заметили, что ваши боксы слегка смещаются вниз при движении, поскольку координата y используется и для frame.origin.y, и для position.y.

Простое исправление - взять середину кадра. Вы можете сделать это, сделав что-то вроде

CGFrame newFrame = (CGRect){{-box.frame.size.width, y}, box.frame.size};
box.position = CGPointMake(CGRectGetMidX(newFrame), CGRectGetMidY(newFrame));

Или, чтобы сделать его устойчивым перед лицом anchorPoint изменений, вы можете использовать что-то вроде

box.position = CGPointMake(-box.frame.size.width + box.frame.size.width*box.anchorPoint.x, y + box.frame.size.height*box.anchorPoint.y);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...