Canvas 加动画,实现火柴人跳绳效果,2021Android 开发面试解答
*/public void quadTo(float x1, float
y1, float x2, float y2) ;
/**
和 quadTo 相同,只不过这里是使用的是相对坐标。*/public void rQuadTo(float dx1, float dy1, float dx2, float dy2)
bitmap 绘制
1、获取图片的 bitmap
private val jumpBitmap1 = BitmapFactory.decodeResource(context.resources, R.drawable.jump_1)
2、将 bitmap 绘制在画布上
/**
@param bitmap The bitmap to be drawn
@param src May be null. The subset of the bitmap to be drawn
@param dst The rectangle that the bitmap will be scaled/translated to fit into
@param paint May be null. The paint used to draw the bitmap*/public void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst,@Nullable Paint paint) {super.drawBitmap(bitmap, src, dst, paint);}
其中 Rect src 是图片的子域,通过设置 src 的大小可以截取图片的部分区域,dst 指图片在画布上面的位置,一般情况下不裁剪图片的话,设置 src 为 null 就可以了。
实现
1、跳绳实现
如上图,path 的起点和中点在屏幕的中点两边,中点的点是控制贝塞尔曲线的点,这个点上下动就可以控制绘制出一条跳绳。要注意ValueAnimator.ofInt(0, b.bottom / 2, b.bottom, b.bottom / 2, 0)
的值是从 0 到.bottom / 2,再到 bottom,在到 bottom / 2,最后回到 0 的,如果不是这样直接从(0-》bottom)的话,贝塞尔曲线的运动轨迹就不是连续的。
2、跳动的火柴人
跳动的火柴人由两种状态,由动画的值确定,根据动画的值来改变火柴人的位置,火柴人初始位置是在画布的正中间,根据动画的值,改变上下位置,同时更改 bitmap。
代码
定义 PathDrawable 继承 Drawable 并且实现 AnimatorUpdateListener 接口
internal class PathDrawable(context: Context) : Drawable(),AnimatorUpdateListener
定义动画,
mAnimator = ValueAnimator.ofInt(0, b.bottom / 2, b.bottom, b.bottom / 2, 0)
更新贝塞尔曲线和火柴人
override fun onAnimationUpdate(animator: ValueAnimator) {Log.d(TAG, "onAnimationUpdate animator${animator.animatedValue}")mPath.reset()val b: Rect = boundsmPath.moveTo(b.left.toFloat(), b.bottom.toFloat() / 2)mPath.quadTo(((b.right - b.left) / 2).toFloat(),(animator.animatedValue as Int).toFloat(), b.right.toFloat(), b.bottom.toFloat() / 2)++countif (count % 24 == 0) {
currentBitmap = if (animator.animatedValue as Int > b.bottom / 2) {jumpBitmap1} else {jumpBitmap3}count = 0}destinationRect.set(b.left + (halfW(b) - imageW() / 2).toInt(),b.top + (halfH(b) - imageH() / 2).toInt() + (animator.animatedValue as Int)/8,
评论