canvas 理解 輔助坐標(biāo)系闭树,輔助繪制
1
//剪切canvas,canvas本身位置不變,剩下的是截切內(nèi)的區(qū)域,Rect是相對與整個屏幕的,而canvas是他剩余的不分并且位置不變(不回到左上角0點位置)
canvas.clipRect(new Rect(300, 300, 600, 600));
//canvas平移
canvas.translate(-400,-400);
//剪切canvas娇斑,在canvas上面剪切的剩余不分和Rect取交集
canvas.clipRect(new Rect(0, 0, 700, 700));
2
canvas.save();//將當(dāng)前的畫布狀態(tài)壓入棧,會面可以取出這個棧來canvas
canvas.restore();//彈出一個畫布棧返回上一個棧的canvas狀態(tài),來canvas
canvas的兩種操作
1,canvas位置(大小材部、位置)毫缆、matrix操作(translate scale rotate skew) 剪切操作clipX
2,canvas繪制 drawX
canvas.save()乐导、canvas.saveLayer()苦丁,可以設(shè)置matrix操作(MATRIX_SAVE_FLAG )或者剪切操作(CLIP_SAVE_FLAG) 的狀態(tài)來確定canvas.restore()恢復(fù)的是那種canvas.
MATRIX_SAVE_FLAG 操作translate scale rotate skew
測試代碼
public static class SampleView extends View {
private Paint mPaint;
private Path mPath = new Path();
private float mPreX,mPreY;
private int mItemWaveLength = 800;
private int dx;
public SampleView(Context context) {
super(context);
init();
}
public SampleView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public SampleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public SampleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
public void init(){
setFocusable(true);
mPaint = new Paint();
mPaint.setAntiAlias(true);
startAnim();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//普通手勢
// switch (event.getAction()){
// case MotionEvent.ACTION_DOWN: {
// mPath.moveTo(event.getX(), event.getY());
// return true;
// }
// case MotionEvent.ACTION_MOVE:
// mPath.lineTo(event.getX(), event.getY());
// postInvalidate();
// break;
// default:
// break;
// }
//貝塞爾手勢
// switch (event.getAction()){
// case MotionEvent.ACTION_DOWN:{
// mPath.moveTo(event.getX(),event.getY());
// mPreX = event.getX();
// mPreY = event.getY();
// return true;
// }
// case MotionEvent.ACTION_MOVE:{
// float endX = (mPreX+event.getX())/2;
// float endY = (mPreY+event.getY())/2;
// mPath.quadTo(mPreX,mPreY,endX,endY);
// mPreX = event.getX();
// mPreY =event.getY();
// invalidate();
// }
// break;
// default:
// break;
// }
return super.onTouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
wave(canvas);
// bsrDraw(canvas);
// bsrTest(canvas);
// test2(canvas);
// test1(canvas);
// canvas.drawColor(Color.WHITE);
// canvas.translate(10, 10);
// mPaint.setColor(Color.RED);
// canvas.drawCircle(75, 75, 75, mPaint);
// canvas.saveLayerAlpha(0, 0, 200, 200, 0x88, LAYER_FLAGS);
// mPaint.setColor(Color.BLUE);
// canvas.drawCircle(125, 125, 75, mPaint);
// canvas.restore();
}
public void startAnim(){
ValueAnimator animator = ValueAnimator.ofInt(0,mItemWaveLength);
animator.setDuration(2000);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setInterpolator(new LinearInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
dx = (int)animation.getAnimatedValue();
postInvalidate();
}
});
animator.start();
}
private void wave(Canvas canvas) {
mPath.reset();
int originY = 300;
int halfWaveLen = mItemWaveLength/2;
mPath.moveTo(-mItemWaveLength+dx,originY);
for (int i = -mItemWaveLength;i<=getWidth()+mItemWaveLength;i+=mItemWaveLength){
mPath.rQuadTo(halfWaveLen/2,-100,halfWaveLen,0);
mPath.rQuadTo(halfWaveLen/2,100,halfWaveLen,0);
}
mPath.lineTo(getWidth(),getHeight());
mPath.lineTo(0,getHeight());
mPath.close();
canvas.drawPath(mPath,mPaint);
}
private void bsrDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(mPath,paint);
}
private void bsrTest(Canvas canvas) {
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GREEN);
Path path = new Path();
path.moveTo(100,300);
path.quadTo(200,200,300,300);
path.quadTo(400,400,500,300);
canvas.drawPath(path,paint);
}
private void test2(Canvas canvas) {
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
canvas.drawColor(Color.BLACK);
Paint paint = new Paint();
paint.setColor((Color.RED));
canvas.drawRect(new Rect( paddingLeft, paddingTop, getWidth() - paddingLeft, getHeight() - paddingTop),paint);
//保存的畫布大小為全屏幕大小
canvas.save();
canvas.clipRect(new Rect(100 + paddingLeft, 100 +paddingTop, 800, 800));
canvas.drawColor(Color.GREEN);
//保存畫布大小為Rect(100, 100, 800, 800)
canvas.save();
canvas.clipRect(new Rect(200 + paddingLeft, 200 +paddingTop, 700, 700));
canvas.drawColor(Color.BLUE);
//保存畫布大小為Rect(200, 200, 700, 700)
canvas.save();
//剪切canvas,canvas本身位置不變,剩下的是截切內(nèi)的區(qū)域物臂,Rect是相對與整個屏幕的旺拉,而canvas是他剩余的不分并且位置不變(不回到左上角0點位置)
canvas.clipRect(new Rect(300 + paddingLeft, 300 +paddingTop, 600, 600));
//canvas平移
canvas.translate(-400,-400);
//剪切canvas产上,在canvas上面剪切的剩余不分和Rect取交集
// canvas.clipRect(new Rect(0 + paddingLeft, 0 +paddingTop, 700, 700));
// canvas.drawColor(Color.BLACK);
//保存畫布大小為Rect(300, 300, 600, 600)
// canvas.save();//將當(dāng)前的畫布狀態(tài)壓入棧,會面可以取出這個棧來canvas
// canvas.restore();//彈出一個畫布棧返回上一個棧來canvas translate scale rotate skew clipXXX drawXXXXX
// canvas.clipRect(new Rect(400, 400, 500, 500));
// canvas.drawColor(Color.WHITE);
//
// //將棧頂?shù)漠嫴紶顟B(tài)取出來,作為當(dāng)前畫布蛾狗,并畫成黃色背景
// canvas.restore();
// canvas.drawColor(Color.YELLOW);
}
private void test1(Canvas canvas) {
canvas.translate(100, 100);
canvas.drawColor(Color.RED);//可以看到蒂秘,整個屏幕依然填充為紅色
Paint paint = new Paint();
paint.setColor(Color.GREEN);
canvas.drawRect(new Rect(-100, -100, 0, 0),paint);
canvas.scale(0.5f, 0.5f);
paint.setColor(Color.BLUE);
canvas.drawRect(new Rect(0, 0, 100, 100), paint);//縮放了
canvas.translate(200, 0);
canvas.rotate(30);
paint.setColor(Color.YELLOW);
canvas.drawRect(new Rect(0, 0, 100, 100), paint);//旋轉(zhuǎn)了
canvas.translate(200, 0);
canvas.skew(.5f, .5f);//扭曲了
paint.setColor(Color.BLACK);
canvas.drawRect(new Rect(0, 0, 100, 100), paint);
// canvas.setMatrix(matrix);//Matrix的使用在后面在是。
}
}