Android高级UI开发(四十五)Canvas Path

举报
yd_57386892 发表于 2020/12/28 23:02:54 2020/12/28
【摘要】 1. Path概念 用Path定义一个图形,然后用canvas.drawPath(...)函数来绘制这个图形。例如绘制一个圆。Path可以绘制各种图形,如二次,三次贝塞尔曲线,圆形、多边形,三角形,五角星等几何形状。 public class PathOpView extends View { private Paint mPaint; public PathOpVi...

1. Path概念

用Path定义一个图形,然后用canvas.drawPath(...)函数来绘制这个图形。例如绘制一个圆。Path可以绘制各种图形,如二次,三次贝塞尔曲线,圆形、多边形,三角形,五角星等几何形状。


  
  1. public class PathOpView extends View {
  2. private Paint mPaint;
  3. public PathOpView(Context context) {
  4. super(context);
  5. mPaint = new Paint();
  6. mPaint.setColor(Color.RED);
  7. mPaint.setStrokeWidth(8);
  8. mPaint.setStyle(Paint.Style.STROKE);
  9. mPaint.setAntiAlias(true);
  10. }
  11. @Override
  12. protected void onDraw(Canvas canvas) {
  13. super.onDraw(canvas);
  14. drawCircle(canvas)
  15. }
  16. private void drawCircle(Canvas canvas) {
  17. Path path = new Path();
  18. path.addCircle(150, 150, 100, Path.Direction.CW);
  19. canvas.drawPath(path,mPaint);
  20. }
  21. }

在上述代码中的drawCircle函数里,new一个Path,调用Path.addCircle定义一个圆形路径区域,最后调用canvas.drawPath绘制出这个圆形区域。

 

2.  两个path之间的合并

现在有以下几种合并方式:

 Path.Op.DIFFERENCE Path1调用合并函数:减去Path2后Path1区域剩下的部分
 
 Path.Op.INTERSECT 保留Path2 和 Path1 共同的部分
 
 Path.Op.UNION 保留Path1 和 Path 2
 
 Path.Op.XOR 保留Path1 和 Path2 + 共同的部分
 
 Path.Op.REVERSE_DIFFERENCE  与 Path.Op.DIFFERENCE相反,减去Path1后Path2区域剩下的部分
 

2.1  Path.Op.DIFFERENCE

绘制两个圆,使用Path.Op.DIFFERENCE模式,最终的结果是 Path1圆减去path2圆后剩下的部分

最终效果图如下:其灰色表示最初的2个圆path,红色表示经过Path.Op.DIFFERENCE模式合并后,剩下的path1部分。

 

源码如下:


  
  1. package com.xiaowei.path_basic;
  2. import android.content.Context;
  3. import android.graphics.Canvas;
  4. import android.graphics.Color;
  5. import android.graphics.Paint;
  6. import android.graphics.Path;
  7. import android.view.View;
  8. /**
  9. * Created by Xiaowei
  10. */
  11. public class PathOpView extends View {
  12. private Paint mPaint;
  13. public PathOpView(Context context) {
  14. super(context);
  15. mPaint = new Paint();
  16. mPaint.setColor(Color.RED);
  17. mPaint.setStrokeWidth(8);
  18. mPaint.setStyle(Paint.Style.STROKE);
  19. mPaint.setAntiAlias(true);
  20. }
  21. @Override
  22. protected void onDraw(Canvas canvas) {
  23. super.onDraw(canvas);
  24. // DIFFERENCE -- 减去Path2后Path1区域剩下的部分
  25. drawDifferenceOp(canvas);
  26. }
  27. private void drawDifferenceOp(Canvas canvas) {
  28. Path path1 = new Path();
  29. path1.addCircle(150, 150, 100, Path.Direction.CW);
  30. Path path2 = new Path();
  31. path2.addCircle(200, 200, 100, Path.Direction.CW);
  32. path1.op(path2, Path.Op.DIFFERENCE);
  33. canvas.drawPath(path1, mPaint);
  34. mPaint.setColor(Color.DKGRAY);
  35. mPaint.setStrokeWidth(2);
  36. canvas.drawCircle(150, 150, 100,mPaint);
  37. canvas.drawCircle(200, 200, 100,mPaint);
  38. }
  39. }

其中drawDifferenceOp函数里,定义了2个路径path1与path2两个圆形路径,         path1.op(path2, Path.Op.DIFFERENCE); 将2个路径合并,合并方法为:path1减去path2后,剩下的部分。后面的2个canvas.drawCircle(......)是绘制出没有合并的2个圆,用于对比合并后的图形。

2.2 Path.Op.INTERSECT 模式

保留两个圆相交的区域

效果图如下:

核心代码如下:


  
  1. private void drawIntersectOp(Canvas canvas) {
  2. Path path1 = new Path();
  3. path1.addCircle(150, 150, 100, Path.Direction.CW);
  4. Path path2 = new Path();
  5. path2.addCircle(200, 200, 100, Path.Direction.CW);
  6. path1.op(path2, Path.Op.INTERSECT);
  7. canvas.drawPath(path1, mPaint);
  8. mPaint.setColor(Color.DKGRAY);
  9. mPaint.setStrokeWidth(2);
  10. canvas.drawCircle(150, 150, 100,mPaint);
  11. canvas.drawCircle(200, 200, 100,mPaint);
  12. }

上述drawIntersectOp函数也是在onDraw里调用,下文中的核心函数也是同样。

2.3 Path.Op.UNION

合并path1和path2

效果图:

核心代码:


  
  1. private void drawUnionOp(Canvas canvas) {
  2. Path path1 = new Path();
  3. path1.addCircle(150, 150, 100, Path.Direction.CW);
  4. Path path2 = new Path();
  5. path2.addCircle(200, 200, 100, Path.Direction.CW);
  6. path1.op(path2, Path.Op.UNION);
  7. canvas.drawPath(path1, mPaint);
  8. mPaint.setColor(Color.DKGRAY);
  9. mPaint.setStrokeWidth(2);
  10. canvas.drawCircle(150, 150, 100,mPaint);
  11. canvas.drawCircle(200, 200, 100,mPaint);
  12. }

2.4 Path.Op.XOR

path1+path2+两者的共同部分

效果图如下:

核心代码:


  
  1. private void drawXorOp(Canvas canvas) {
  2. Path path1 = new Path();
  3. path1.addCircle(150, 150, 100, Path.Direction.CW);
  4. Path path2 = new Path();
  5. path2.addCircle(200, 200, 100, Path.Direction.CW);
  6. path1.op(path2, Path.Op.XOR);
  7. canvas.drawPath(path1, mPaint);
  8. mPaint.setColor(Color.DKGRAY);
  9. mPaint.setStrokeWidth(2);
  10. canvas.drawCircle(150, 150, 100,mPaint);
  11. canvas.drawCircle(200, 200, 100,mPaint);
  12. }

2.5  Path.Op.REVERSE_DIFFERENCE

  与DIFFERENCE相反,保留的是path2 - path1后剩下的 path2部分

效果图如下:

核心代码:


  
  1. private void drawReverseDifferenceOp(Canvas canvas) {
  2. Path path1 = new Path();
  3. path1.addCircle(150, 150, 100, Path.Direction.CW);
  4. Path path2 = new Path();
  5. path2.addCircle(200, 200, 100, Path.Direction.CW);
  6. path1.op(path2, Path.Op.REVERSE_DIFFERENCE);
  7. canvas.drawPath(path1, mPaint);
  8. mPaint.setColor(Color.DKGRAY);
  9. mPaint.setStrokeWidth(2);
  10. canvas.drawCircle(150, 150, 100,mPaint);
  11. canvas.drawCircle(200, 200, 100,mPaint);
  12. }

demo源码:https://download.csdn.net/download/gaoxiaoweiandy/12435514

文章来源: blog.csdn.net,作者:冉航--小虾米,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/gaoxiaoweiandy/article/details/106194583

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200