Использование clipRect - объяснение
public class POCII extends Activity {
myView mv = new myView(this);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(mv);
}
}
class myView extends View {
public myView(Context context) {
super(context);
}
@Override
public void onDraw(Canvas canvas) {
Paint paint = new Paint();
canvas.drawRect(0,0,100,100, paint);
canvas.clipRect(0,0,50,50);
}
}
У меня вопрос: не должен ли вышеприведенный код нарисовать прямоугольник, а затем обрезать верхнюю левую часть? Прямоугольник не обрезается.
Пожалуйста, объясните, что делает clipRect. Что это на самом деле отсечения? Это обрезает в форме прямоугольника, учитывая координаты? Если так, то почему вышеприведенный код не работает?
3 ответа
Canvas.clipRect(left, top, right, bottom)
уменьшает область экрана, в которую могут писать будущие операции рисования. Он устанавливает clipBounds как пространственное пересечение текущего прямоугольника отсечения и указанного прямоугольника. Существует множество вариантов метода clipRect, которые принимают разные формы для регионов и разрешают разные операции с прямоугольником отсечения. Если вы хотите явно установить область отсечения, попробуйте:
canvas.clipRect(left, top, right, bottom, Region.Op.REPLACE);
Пятый аргумент означает заменить прямоугольник отсечения, а не создавать пересечение с предыдущей версией.
Попробуйте переместить оператор clipRect перед оператором drawRect. Или попробуйте добавить:
paint.setColor(Color.YELLOW);
drawRect(0,0,75,75);
после вашего существующего оператора clipRect. Он должен нарисовать 50x50 желтый квадрат поверх того, что вы имели раньше.
Еще одно замечание: (после долгого разочарования по поводу явно недокументированного кода View/ViewGroup/ Drawing) я обнаружил, что canvas.translate(x,y) также настраивает clipRect. Взаимодействие clipRect и матрицы рисования очень запутанно. Полезно распечатать:
canvas.getMatrix()
а также
canvas.getClipBounds()
до и после модификаций на холсте и до рисования вещей.
Чтобы обрезать верхнюю левую часть, выполните:
canvas.clipRect(0,0,50,50, Region.Op.DIFFERENCE);
// secondly...
canvas.drawRect(0,0,100,100, paint);
ICS и выше...
Режимы клипа XOR, Difference и ReverseDifference игнорируются ICS, если включено аппаратное ускорение.
Просто отключите 2D аппаратное ускорение на ваш взгляд:
myView.setLayerType (View.LAYER_TYPE_SOFTWARE, null);
Ваш рисунок выглядит так без использования cliprect:
теперь, если мы используем cliprect, мы накладываем прямоугольник поверх того, что у нас уже есть. своего рода невидимый. допустим, мы вызвали следующее:
override fun onDraw(canvas: Canvas) {
val paint = Paint();
paint.color = Color.RED
canvas.clipRect(0f,0f,500f,500f, Region.Op.DIFFERENCE);
// secondly...
canvas.drawRect(0f,0f,1000f,1000f, paint);
}
поскольку мы используем параметр РАЗНИЦА и знаем, что прямоугольник отсечения теперь НАХОДИТСЯ НАД красным прямоугольником холста, мы можем сказать мне особые вещи. выше сказано, что мы должны СОХРАНИТЬ РАЗНИЦУ между прямоугольником отсечения и оригиналом. так это будет выглядеть так (так как я использовал половину 1000 для вырезания прямоугольника):
и наоборот, если бы мы использовали пересечение, это выглядело бы так:
Я бы хотел посмотреть, сможет ли кто-нибудь сделать его закругленными углами.