原博客地址: 自定义控件其实很简单1/3
Matrix
乘
Scale
旋转
根据三角函数的关系我们可以得出p(x,y)的坐标:
同样根据三角函数的关系我们也可以得出p(x0,y0)的坐标:
上述两公式结合我们则可以得出简化后的p(x,y)的坐标:
这是什么公式呢?是不是就是上面矩阵的乘积呢?囧……
绕点p(a,b)顺时针转:
其实绕某个点旋转没有想象中的那么复杂,相对于绕中心点来说就多了两步:先将坐标原点移到我们的p(a,b)处然后执行旋转最后再把坐标圆点移回去:
实践
matrix.preScale(0.5f, 1);
matrix.setScale(1, 0.6f);
matrix.postScale(0.7f, 1);
matrix.preTranslate(15, 0);
- Matrix的计算过程:translate (15, 0) -> scale (1, 0.6f) -> scale (0.7f, 1)
matrix.preScale(0.5f, 1);
matrix.preTranslate(10, 0);
matrix.postScale(0.7f, 1);
matrix.postTranslate(15, 0);
- 计算过程: translate (10, 0) -> scale (0.5f, 1) -> scale (0.7f, 1) -> translate (15, 0)
Canvas Advance
原文章:[1] 自定义控件其实很简单5/12
[drawBitmapMesh](http://developer.android.com/reference/android/graphics/Canvas.html#drawBitmapMesh(android.graphics.Bitmap, int, int, float[], int, int[], int, android.graphics.Paint))(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint)
Sample-1
float multiple = mBitmap.getWidth();
for (int y = 0; y <= 19; y++) { //1. 把位图分为19顶点值
float fy = mBitmap.getHeight() * y / 19;
for (int x = 0; x <= W; x++) {
// fx方向的顶点值+偏移
float fx = mBitmap.getWidth() * x / 19 + ((19 - y) * 1.0F / 19 * multiple);
setXY(fx, fy, index);
index += 1;
}
}
canvas.drawBitmapMesh(mBitmap, 19, 19, verts, 0, null, 0, null);
Sample-2
int index = 0;
float multipleY = mBitmap.getHeight() / HEIGHT;
float multipleX = mBitmap.getWidth() / WIDTH;
for (int y = 0; y <= HEIGHT; y++) {
float fy = multipleY * y;
for (int x = 0; x <= WIDTH; x++) {
float fx = multipleX * x;
setXY(fx, fy, index);
if (5 == y) {
if (8 == x) {
setXY(fx - multipleX, fy - multipleY, index);
}
if (9 == x) {
setXY(fx + multipleX, fy - multipleY, index);
}
}
if (6 == y) {
if (8 == x) {
setXY(fx - multipleX, fy + multipleY, index);
}
if (9 == x) {
setXY(fx + multipleX, fy + multipleY, index);
}
}
index += 1;
}
}
- Canvas对象概略:
在framework中,Activty被创建时(更准确地说是在addView的时候)会同时创建一个叫做ViewRootImpl的对象,ViewRootImpl是个很碉堡的类,它负责很多GUI的东西,包括我们常见的窗口显示、用户的输入输出等等,同时,它也负责Window跟WMS通信(Window你可以想象是一个容器,里面包含着我们的一个Activity,而AMS呢全称为Activity Manager Service,顾名思义很好理解它的作用),当ViewRootImpl跟WMS建立通信注册了Window后就会发出第一次渲染View Hierachy的请求,涉及到的方法均在ViewRootImpl下:setView、requestLayout、scheduleTraversals等,大家有兴趣可以自己去搜罗看看,在performTraversals方法中ViewRootImpl就会去创建Surface,而此后的渲染则可以通过Surface的lockCanvas方法获取Surface的Canvas来进行,然后遍历View Hierachy把需要绘制的View通过Canvas(View.onDraw(Canvas canvas))绘制到Surface上,绘制完成后解锁(Surface.unlockCanvasAndPost)让SurfaceFlinger将Surface绘制到屏幕上。
- Canvas分类:
- 第一是以drawXXX为主的绘制方法,
- 第二是以clipXXX为主的裁剪方法,
- 第三是以scale、skew、translate和rotate组成的Canvas变换方法,
- 最后一类则是以saveXXX和restoreXXX构成的画布锁定和还原
Rect
- intersect
mRect = new Rect(0, 0, 500, 500);
mRect.intersect(250, 250, 750, 750);
canvas.clipRect(mRect);
- union