iOS / Core-Animation: 12 накладывающихся друг на друга карт по кругу - PullRequest
6 голосов
/ 30 августа 2011

Я пытаюсь расположить 12 объектов в круге так, чтобы каждый перекрывал своего соседа против часовой стрелки.

Примерно так:

enter image description here

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

Я пытался использовать

    {
        GlowButton* G = glowButton[ 0 ];

        float theta = 0.3;
        G.layer.transform = CATransform3DMakeRotation( theta, 0, 1, 0 );
    }

При попытке поворота вокруг вертикальной оси, таким образом заправляя одну сторону позади соседа, но это не работает.

Мне сказали, что это потому, что основная анимация не поддерживает глубинное тестирование.

Есть ли способ сделать это без взлома GL?

Ответы [ 2 ]

6 голосов
/ 30 августа 2011

Я могу придумать два способа избежать этой проблемы:

  1. Разделите каждый объект пополам. Сначала нарисуйте те половины, которые находятся за соседними объектами, затем нарисуйте эти половины поверх соседей.

  2. Используйте область отсечения и нарисуйте круг в два этапа. Первая область отсечения ограничивает рисунок левой половиной изображения. Вторая область отсечения ограничена правой половиной. Каждый раз вы рисуете все объекты. Но начинать нужно либо с нижнего, либо с верхнего элемента.

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

4 голосов
/ 31 августа 2011

У меня это отлично работает сейчас.Я очень рад, что мне не пришлось идти на GL.

enter image description here

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

Затем я рисую оставшиеся 11.

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

    for( int i = 0; i <= 12; i++ )
    {
        for ( int dullGlow = 0; dullGlow <= 1; dullGlow++ )
        {
            BOOL isDull = ( dullGlow == 0 ) ? YES : NO;

            CALayer* L = [CALayer layer];

            CGImageRef dullImage = [ButtonImages dullImage: i % 12];
            CGImageRef glowImage = [ButtonImages glowImage: i % 12];

            L.contents = (id) ( isDull ? dullImage : glowImage );

            L.bounds = CGRectMake( 0, 0, buttonSize, buttonSize ); 

            L.opacity = ( isDull ? 1.0 : 0.0 );

            if( i == 0  ||  i == 12 )
            {
                CGFloat halfSize = buttonSize / 2.0;

                CGRect keepLeftHalf = CGRectMake( 0, 0, 
                                                 halfSize, buttonSize );

                CGRect keepRightHalf = CGRectMake( halfSize,  0, 
                                                  halfSize, buttonSize );

                CALayer* maskLayer = [CALayer layer];
                maskLayer.frame = ( i == 0 ) ? keepRightHalf : keepLeftHalf;
                maskLayer.backgroundColor = [UIColor greenColor].CGColor;

                maskLayer.edgeAntialiasingMask = 0x0;

                [L setMask: maskLayer];
            }

            [self.layer addSublayer: L];

            layers[ dullGlow ] [ i ] = L;

        } // dullGlow

    } // i

Установка 4 младших значащих битов edgeAntialiasingMask на 0 условий сглаживания на всех 4 ребрах - без этой линии я получал шов.

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

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

Я предполагаю, что для каждого пикселя он умножает пиксель RGBA слоя на альфазначение на мспросить пикселей

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...