想要实现一个图片的粒子效果,非常简单
效果图:
思路:
- 遍历图片的宽高,通过Bitmap.getPixel(row,cloum)这个方法,返回值我们可以拿到当前像素点的颜色值,我们也能拿到当前的坐标点,然后封装成一个一个的小球对象,保存在集合里面。
- 在onDraw里面遍历集合根据这些小球的坐标点和颜色值绘制圆圈。如果我们取的像素足够密,绘制出来的原点可以组成这个图片。
- 动画效果,通过属性动画,在onAnimationUpdate方法中根据一定的算法不断更新小球对象的x,y坐标点。这个算法可以自己定,比如通过自有落体的公式,或者随机数等。
- 在onTouchEvent方法中监听ACTION_DOWN事件开启动画
- 如果直接取图片的所有像素,如果图片很大的话,会非常卡,如果不取全部的,那绘制出来效果没原图清晰,我们可以通过一个标志位,开始绘制原图,点击之后在绘制小圆球。
创建一个Ball对象,用来保存将要绘制的每个点的坐标和当坐标更新时的变化速度。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class Ball {
public int color;
//x坐标
public float x;
//y坐标
public float y;
//半径
public float r;
//水平速度
public float vX;
//垂直速度
public float vY;
//水平加速度
public float aX;
//垂直加速度
public float aY;
}
创建一个bitmap,遍历它的宽高,获取像素值,和坐标值,封装成一个一个的小球并保存起来。为了提高效率这里的遍历每次+2,可根据实际情况更改。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19mBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.shader);
for (int i = 0; i < mBitmap.getWidth()/d; i+=2) {
for (int j = 0; j < mBitmap.getHeight()/d; j+=2) {
Ball ball = new Ball();
ball.color = mBitmap.getPixel(i,j);
ball.x = i*d+d/2;
ball.y = j*d+d/2;
ball.r = d/2;
//速度(-20,20)
ball.vX = (float) (Math.pow(-1, Math.ceil(Math.random() * 100)) * 20 * Math.random());
ball.vY = rangInt(-15, 35);
//加速度
ball.aX = 0;
ball.aY = 0.98f;
mBalls.add(ball);
}
}
开始绘制,判断是绘制原图还是绘制小圆圈。1
2
3
4
5
6
7
8
9
10
11
12protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(getWidth()/2-mBitmap.getWidth()/2,getHeight()/2-mBitmap.getHeight()/2);
if(isShowBitmap){
canvas.drawBitmap(mBitmap,0,0,null);
}else {
for (Ball ball : mBalls) {
mPaint.setColor(ball.color);
canvas.drawCircle(ball.x,ball.y,ball.r,mPaint);
}
}
}
使用属性动画,动态的更新每个小球的坐标值然后重新绘制。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20splitAnimator = ValueAnimator.ofFloat(0,1);
splitAnimator.setRepeatCount(-1);
splitAnimator.setDuration(2000);
splitAnimator.setInterpolator(new LinearInterpolator());
splitAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
updateBall();
invalidate();
}
});
private void updateBall() {
for (Ball ball : mBalls) {
ball.x += ball.vX;
ball.y += ball.vY;
ball.vX += ball.aX;
ball.vY += ball.aY;
}
}
OK完成,源码地址点击这里