Использование 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);

Ссылка на Android: как использовать clipRect в API15

Ваш рисунок выглядит так без использования 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 для вырезания прямоугольника):

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

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

Другие вопросы по тегам