На Android, как я могу сделать странные области отсечения?
Вот как создать область обрезки по форме круга:
Path path = new Path();
path.addCircle(200,200,100,Direction.CW);
c.clipPath(path); // c is a Canvas
Теперь на холсте есть область отсечения, которая предотвращает рисование чего-либо за пределами этого круга. Но, если я хочу, чтобы область отсечения была сформирована как пончик (или что-то еще)?
Я попытался сыграть с созданием второго Пути и использовать toggleInverseFillType на нем, а затем добавить это к исходному пути, но это, похоже, не работает.
В качестве альтернативы вместо использования Path можно просто создать Bitmap для использования в качестве маски и как-то установить его как обтравочную маску на Canvas?
EDIT: Ответ - это то, что мне нужно с одним небольшим дополнением. При выполнении нескольких операций на холсте всегда используйте Op.REPLACE при первом вызове clipPath. Это заменит любой существующий клиппат на этом холсте.
Для справки, вот что я обнаружил, что означают 6 разных значений Region.Op. Представьте себе диаграмму Венна с двумя кругами. "B" - это та часть, где два круга перекрываются. "A" - это неперекрывающийся левый круг. "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
Из Canvas
javadoc:
Canvas#clipPath(Path path, Region.Op op)
- Изменить текущий клип с указанным путем.
Итак, для примера вашего пончика:
- Создайте 2 пути. Один для большего круга, один для меньшего круга.
-
Canvas#clipPath( Path )
с большим кругом Path
.
-
Вызовите метод Canvas#clipPath( Path, Region.Op )
на вашем холсте с меньшим кругом Path
для первого аргумента и соответствующим Region.Op
значение enum для второго аргумента.
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
enum, чтобы получить разные эффекты...