Анимация изменения размера маски CALAYER

Вы можете использовать размеры продолжения A и B с np.newaxis/None , чтобы ввести broadcasting для векторизованного решения так же -

A[...,None]*B[:,None,:]

Объяснение: np.outer(np.transpose(A[i]), B[i]) в основном выполняет элементное умножение между столбчатой ​​ версией A[i] и B[i]. Вы повторяете это для всех строк в A для сопоставления строк в B. Обратите внимание, что np.transpose(), похоже, не оказывает никакого влияния, поскольку np.outer заботится о предполагаемых элементарных умножениях.

Я бы описал эти шаги в векторизованном языке и, таким образом, реализовать так:

  1. Расширить размеры A и B, чтобы сформировать фигуры 3D для обоих из них, чтобы мы сохранили axis=0 и сохранили как axis=0 в обеих этих расширенных версиях. Таким образом, нам остается решать две последние оси.
  2. Чтобы ввести элементарные умножения, нажмите axis=1 из A в своей исходной 2D-версии на axis=1 в своем 3D, тем самым создавая одномерное измерение в axis=2 для расширенной версии A.
  3. Это последнее одноэлементное измерение версии 3D A должно совпадать с элементами из axis=1 в оригинальной 2D версии B, чтобы broadcasting произошло. Таким образом, расширенная версия B имела бы элементы из axis=1 в своей 2D-версии, которые были бы нажаты на axis=2 в ее версии 3D, тем самым создавая одномерное измерение для axis=1.

Наконец, расширенные версии: A[...,None] & amp; B[:,None,:], умножив, кто даст нам желаемый результат.

28
задан Alex Repty 26 May 2010 в 07:08
поделиться

5 ответов

Я использую CAShapeLayer для маскировки UIView, устанавливая self.layer.mask для этого слоя формы.

Чтобы анимировать маску всякий раз, когда изменяется размер представления, я переписал -setBounds:, чтобы анимировать путь слоя маски, если границы изменяются во время анимации.

Вот как я это реализовал:

- (void)setBounds:(CGRect)bounds
{
    [super setBounds:bounds];
    CAPropertyAnimation *boundsAnimation = (CABasicAnimation *)[self.layer animationForKey:@"bounds"];

    // update the mask
    self.maskLayer.frame = self.layer.bounds;

    // if the bounds change happens within an animation, also animate the mask path
    if (!boundsAnimation) {
        self.maskLayer.path = [self createMaskPath];
    } else {
        // copying the original animation allows us to keep all animation settings
        CABasicAnimation *animation = [boundsAnimation copy];
        animation.keyPath = @"path";

        CGPathRef newPath = [self createMaskPath];
        animation.fromValue = (id)self.maskLayer.path;
        animation.toValue = (__bridge id)newPath;

        self.maskLayer.path = newPath;

        [self.maskLayer addAnimation:animation forKey:@"path"];
    }
}

(Для примера self.maskLayer установлено значение `self.layer.mask)

My -createMaskPath вычисляет CGPathRef, который я используйте, чтобы замаскировать вид. Я также обновляю путь маски в -layoutSubviews.

10
ответ дан stigi 28 November 2019 в 02:49
поделиться

Чтобы анимировать изменение границ слоя маски UIView: подкласс UIView, и анимировать маску с помощью транзакции CAT - аналогично ответу Kekodas, но более общего:

@implementation UIMaskView

- (void) layoutSubviews {
    [super layoutSubviews];

    CAAnimation* animation = [self.layer animationForKey:@"bounds"];
    if (animation) {
        [CATransaction begin];
        [CATransaction setAnimationDuration:animation.duration];
    }

    self.layer.mask.bounds = self.layer.bounds;
    if (animation) {
        [CATransaction commit];
    }
}

@end
5
ответ дан Nick H247 28 November 2019 в 02:49
поделиться

Я не смог найти никакого программного решения, поэтому я просто нарисовал изображение PNG с правильной формой и значениями альфа и использовал его вместо этого. Таким образом, мне не нужно использовать маску ...

0
ответ дан Ida 28 November 2019 в 02:49
поделиться

Быстрый 3+ ответ, основанный на решении Кекоа :

let duration = 0.15 //match this to the value of the UIView.animate(withDuration:) call

CATransaction.begin()
CATransaction.setValue(duration, forKey: kCATransactionAnimationDuration)

myView.layer.mask.position = CGPoint(x: [new X], y: [new Y]) //just an example

CATransaction.commit()
0
ответ дан Tamás Sengel 28 November 2019 в 02:49
поделиться

Свойство маски CALayer не может быть анимировано, что объясняет вашу неудачу в этом направлении.

Зависит ли рисунок вашей маски от рамки / границ маски? (Не могли бы вы предоставить код?) Установлено ли для маски свойство needsDisplayOnBoundsChange?

Ура, Корин

5
ответ дан 28 November 2019 в 02:49
поделиться