Как я складываю изображения для моделирования глубины с помощью Базовой Анимации?

У меня есть серия UIImages, с которым я должен моделировать глубину. Я не могу использовать масштабирование, потому что я должен смочь повернуть родительское представление, и изображения должны быть похожими, они сложены явно друг перед другом, не на той же плоскости.

Я сделал новый находящийся в ViewController проект и поместил это в viewDidLoad (а также присоединил три 120x120 пиксельные изображения, названные 1.png, 2.png, и 3.png):

- (void)viewDidLoad {

    // display image 3
    UIImageView *three = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"3.png"]];
    three.center = CGPointMake(160 + 60, 240 - 60);
    [self.view addSubview:three];

    // rotate image 3 around the z axis
    // THIS IS INCORRECT
    CATransform3D theTransform = three.layer.transform;
    theTransform.m34 = 1.0 / -1000;
    three.layer.transform = theTransform;

    // display image 2
    UIImageView *two = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"2.png"]];
    two.center = CGPointMake(160, 240);
    [self.view addSubview:two];

    // display image 1
    UIImageView *one = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"1.png"]];
    one.center = CGPointMake(160 - 60, 240 + 60);
    [self.view addSubview:one];

    //  rotate image 3 around the z axis
    // THIS IS INCORRECT
    theTransform = one.layer.transform;
    theTransform.m34 = 1.0 / 1000;
    one.layer.transform = theTransform;

    // release the images
    [one release];
    [two release];
    [three release];

    // rotate the parent view around the y axis
    theTransform = self.view.layer.transform;
    theTransform.m14 = 1.0 / -500;
    self.view.layer.transform = theTransform;

    [super viewDidLoad];
}

У меня есть очень определенные причины, почему я не использую EAGLView и почему я не загружаю изображения как CALayers (т.е. почему я использую UIImageViews для каждого). Это - просто быстрая демонстрация, которую я могу использовать для разработки точно, в чем я нуждаюсь в своем родительском приложении.

Там некоторый матричный путь состоит в том, чтобы перевести эти 2-е изображения вдоль оси z, таким образом, они будут похожи на то, что я пытаюсь представить? Я прошел другие статьи StackOverflow, а также ссылки Википедии, и не нашел то, что я ищу - хотя я не мог бы обязательно использовать правильные термины для того, что я пытаюсь сделать.

6
задан Brad Larson 14 May 2010 в 17:30
поделиться

2 ответа

Я, наконец, решил эту проблему, используя CATransform3DMakeTranslation, который кажется единственным способом переместить слой вверх или вниз по оси z:

UIImageView *three = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"3.png"]];
three.layer.transform = CATransform3DMakeTranslation(0.0f, 0.0f, 20.0f);
three.center = CGPointMake(160 + 60, 240 - 60);
[self.view addSubview:three];

(я также переместил UIImageView на один -20.0f пикселей по оси Z. Это наконец дало эффект, который я искал.)

2
ответ дан 10 December 2019 в 02:43
поделиться

Для того чтобы сложить виды в стопку и применить к ним перспективу, вам нужно сначала разместить их в разных положениях по Z, а затем применить эффект перспективы к содержащему слою.

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

- (void)viewDidLoad {

    UIImageView *three = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"3.png"]];
    three.center = CGPointMake(160 + 60, 240 - 60);
    [self.view addSubview:three];

    three.layer.zPosition = -100;

    UIImageView *two = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"2.png"]];
    two.center = CGPointMake(160, 240);
    [self.view addSubview:two];

    two.layer.zPosition = 0;

    UIImageView *one = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"1.png"]];
    one.center = CGPointMake(160 - 60, 240 + 60);
    [self.view addSubview:one];

    one.layer.zPosition = 100;

    // release the images
    [one release];
    [two release];
    [three release];

    CATransform3D theTransform = self.view.layer.sublayerTransform;
    theTransform.m34 = 1.0 / -500;
    self.view.layer.sublayerTransform = theTransform;

    [super viewDidLoad];
}

В вашем коде вы только устанавливаете перспективную часть CATransform3D на каждом слое вида (это то, что делает компонент m34 матрицы CATransform3D). Вы не смещаете их в плоскости Z. Для этого можно использовать преобразование, но я считаю, что свойство zPosition ваших CALayers обеспечивает более чистый способ расположения слоев в трехмерном пространстве.

После того как вы расположили слои относительно друг друга (отрицательные значения уходят от точки зрения пользователя), необходимо применить эффект перспективы ко всем слоям, расположенным в основном виде. Для этого необходимо установить sublayerTransform слоя главного представления, чтобы перспектива была правильно применена ко всем размещенным слоям.

Если вы хотите повернуть серию изображений, используйте CATransform3DRotate() для sublayerTransform основного слоя хостингового представления.

Пример приложения, которое выполняет трехмерные манипуляции с CALayers с применением к ним перспективы, можно найти в проекте, на который я ссылаюсь во втором обновлении моей статьи здесь.

7
ответ дан 10 December 2019 в 02:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: