canvas教程

android自定义组件(手机加速球+水面波动效果)(2)

字号+ 作者:H5之家 来源:H5之家 2017-04-26 12:03 我要评论( )

构造方法中实例化出了一个画笔对象,颜色为绿色,抗锯齿。在onDraw()方法中添加了两个画直线的方法,我们要对每个点都要绘制所以使用了循环。 哎呀,这不是咱们想看到的效果呀,这是因为坐标的原点依旧在View的左上

构造方法中实例化出了一个画笔对象,颜色为绿色,抗锯齿。在onDraw()方法中添加了两个画直线的方法,我们要对每个点都要绘制所以使用了循环。

这里写图片描述


哎呀,这不是咱们想看到的效果呀,这是因为坐标的原点依旧在View的左上角,振幅小,都往下方画直线就覆盖了整个View,接下来我们把坐标系往下放移动len/2的距离,再去绘制:

@Override protected void onDraw(Canvas canvas) { // y = Asin(wx+b)+h ,这个公式里:w影响周期,A影响振幅,h影响y位置,b为初相; // 将周期定为view总宽度 float mCycleFactorW = (float) (2 * Math.PI / len); // 得到第一条波的y值 for (int i = 0; i < len; i++) { firstWaterLine[i] = (float) (10 * Math .sin(mCycleFactorW * i)); } // 得到第二条波的y值 for (int i = 0; i < len; i++) { secondWaterLine[i] = (float) (15 * Math.sin(mCycleFactorW * i + 10)); } //保存原来的内容 canvas.save(); canvas.translate(0,len/2); //第一条波的所有直线 for (int i = 0; i < len; i++) { canvas.drawLine(i, firstWaterLine[i], i, len, waterPaint); } //第二条波的所有直线 for (int i = 0; i < len; i++) { canvas.drawLine(i, secondWaterLine[i], i, len, waterPaint); } //恢复到原来的状态(会自动结合绘制的内容) canvas.restore();; }

我们需要先保存画布的状态,再去移动坐标系,之后在恢复合并。

这里写图片描述


现在是我们想看到的样子了,但是还有一点,我们希望他是一个圆形的,这时候就需要另外一个功能,cavans的剪切功能

@Override protected void onDraw(Canvas canvas) { // y = Asin(wx+b)+h ,这个公式里:w影响周期,A影响振幅,h影响y位置,b为初相; // 将周期定为view总宽度 float mCycleFactorW = (float) (2 * Math.PI / len); // 得到第一条波的y值 for (int i = 0; i < len; i++) { firstWaterLine[i] = (float) (10 * Math .sin(mCycleFactorW * i)); } // 得到第二条波的y值 for (int i = 0; i < len; i++) { secondWaterLine[i] = (float) (15 * Math.sin(mCycleFactorW * i + 10)); } // 裁剪成圆形区域 Path path = new Path(); path.reset(); float clipRadius=len/2; //添加圆形路径 //Path.Direction.CCW逆时针 //Path.Direction.CW顺时针 path.addCircle(len / 2, len / 2, clipRadius, Path.Direction.CCW); // (剪裁路径)裁剪成圆形区域 //(REPLACE用当前要剪切的区域代替画布中的内容的区域) canvas.clipPath(path, android.graphics.Region.Op.REPLACE); canvas.save(); canvas.translate(0,len/2); //第一条波的所有直线 for (int i = 0; i < len; i++) { canvas.drawLine(i, firstWaterLine[i], i, len, waterPaint); } //第二条波的所有直线 for (int i = 0; i < len; i++) { canvas.drawLine(i, secondWaterLine[i], i, len, waterPaint); } canvas.restore();; }

在我们要移动画布之前,将View剪切成了圆形
点击了解
Region.Op

手机加速球


在布局中我去除了,控件的背景,效果如图所示,接下来就是去控制让他动起来了,水平方向移动也就是每次初相都不相同,开启时间任务,让它的初相值不断变化(从右往左移动就加上一个数)

@Override protected void onDraw(Canvas canvas) { // y = Asin(wx+b)+h ,这个公式里:w影响周期,A影响振幅,h影响y位置,b为初相; // 将周期定为view总宽度 float mCycleFactorW = (float) (2 * Math.PI / len); // 得到第一条波的y值 for (int i = 0; i < len; i++) { //添加一个可变的初相值 firstWaterLine[i] = (float) (10 * Math .sin(mCycleFactorW * i+move)); } // 得到第二条波的y值 for (int i = 0; i < len; i++) { //添加一个可变的初相值 secondWaterLine[i] = (float) (15 * Math.sin(mCycleFactorW * i + move+10)); } // 裁剪成圆形区域 Path path = new Path(); path.reset(); float clipRadius=len/2; //添加圆形路径 //Path.Direction.CCW逆时针 //Path.Direction.CW顺时针 path.addCircle(len / 2, len / 2, clipRadius, Path.Direction.CCW); // (剪裁路径)裁剪成圆形区域 //(REPLACE用当前要剪切的区域代替画布中的内容的区域) canvas.clipPath(path, android.graphics.Region.Op.REPLACE); canvas.save(); canvas.translate(0,len/2); //第一条波的所有直线 for (int i = 0; i < len; i++) { canvas.drawLine(i, firstWaterLine[i], i, len, waterPaint); } //第二条波的所有直线 for (int i = 0; i < len; i++) { canvas.drawLine(i, secondWaterLine[i], i, len, waterPaint); } canvas.restore();; }

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • HTML5 Canvas自定义圆角矩形与虚线(Rounded Rectangle and Dash

    HTML5 Canvas自定义圆角矩形与虚线(Rounded Rectangle and Dash

    2017-04-25 13:01

  • CircularSeekBar 自定义 圆形 seekbar

    CircularSeekBar 自定义 圆形 seekbar

    2017-04-25 12:01

  • Android多屏幕适配

    Android多屏幕适配

    2017-04-25 11:02

  • Android图形图像之自定义控件属性(demo:刮刮乐与打

    Android图形图像之自定义控件属性(demo:刮刮乐与打

    2017-04-24 13:01

网友点评
s