На Android как сделать области отсечения странной формы? - PullRequest
18 голосов
/ 15 февраля 2012

Вот как создать область отсечения в форме круга:

Path path = new Path();
path.addCircle(200,200,100,Direction.CW);
c.clipPath(path); // c is a Canvas

Теперь на холсте есть область отсечения, которая не позволяет рисовать что-либо за пределами этого круга. Но что, если я хочу, чтобы область отсечения была в форме пончика (или чего-то еще)?

Я попытался поиграть с созданием второго Path и использованием toggleInverseFillType для него, а затем добавить его к исходному пути, но это, похоже, не работает.

В качестве альтернативы, вместо использования Path, возможно ли просто создать растровое изображение для использования в качестве маски и как-то установить его в качестве обтравочной маски на холсте?

РЕДАКТИРОВАТЬ: Ответ именно то, что мне нужно, с одним небольшим дополнением. При выполнении нескольких операций на холсте всегда используйте Op.REPLACE при первом вызове clipPath. Это заменит любой существующий clipPath на этом Canvas.

Для справки, вот что я обнаружил, что означают 6 различных значений Region.Op. Представьте диаграмму Венна с 2 кружками. «B» - это часть, где 2 круга перекрываются. «А» - это непересекающийся левый круг. «C» - это непересекающийся правый круг.

c.clipPath(a,Region.Op.REPLACE);
c.clipPath(b,???);

Region.Op.DIFFERENCE         -> A..            
Region.Op.INTERSECT          -> .B.            
Region.Op.REPLACE            -> .BC            
Region.Op.REVERSE_DIFFERENCE -> ..C            
Region.Op.UNION              -> ABC
Region.Op.XOR                -> A.C

"." указывает на часть, которая не нарисована. Извините, если это не совсем понятно. Трудно хорошо описать без графики.

1 Ответ

18 голосов
/ 15 февраля 2012

Из Canvas javadoc :

Canvas#clipPath(Path path, Region.Op op) - Изменить текущий клип с указанным путем.

Итак, для вашего примера пончик:

  1. Создание 2 путей.Один для большего круга, один для меньшего круга.
  2. Canvas#clipPath( Path ) с большим кругом Path.
  3. Вызовите метод Canvas#clipPath( Path, Region.Op ) на холсте с меньшим кругомPath для первого аргумента и соответствующее Region.Op значение перечисления для второго аргумента.

    Path largePath = new Path();
    largePath.addCircle(200,200,100,Direction.CW);
    Path smallPath = new Path();
    smallPath.addCircle(200,200,40,Direction.CW);
    c.clipPath(largePath); // c is a Canvas
    c.clipPath(smallPath, Region.Op.DIFFERENCE);
    

Снова измените значение перечисления Region.Opчтобы получить разные эффекты ...

...