android 旋转动画减少计算量,让动画更流畅
android rotate animation reduce calculations and make animation smooth
我正在尝试绘制自定义旋转动画。这是我的代码的输出。
基本上每个圈子都有小的子圈子。唯一的问题是,有时动画会跳过一些帧并且动画看起来很破损。我的猜测是因为这个计算很耗时,一些帧丢失了。
我的问题是改善这一点并保持动画流畅的最佳方法是什么。
是否可以只计算第一帧并旋转 canvas 以便我们减少计算量?
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int startRadius = 20;
int endRadius = 400;
int circleCount = 20;
int circleDistance = (int) (((endRadius - startRadius) / (float) circleCount));
for (int i = 0; i < circleCount; i++) {
int radius = startRadius + i * circleDistance;
canvas.drawCircle(center.x, center.y, radius, mPaint);
int subCircles=i+1;
double angleSegment = Math.PI * 2 / subCircles;
for (int segment = 0; segment < subCircles; segment++) {
double angle = angleSegment * segment + shiftAngle;
double x = Math.cos(angle) * radius;
double y = Math.sin(angle) * radius;
canvas.drawCircle((float) (x + center.x), (float) (y + center.y), 6, pointPaint);
}
}
}
动画师
public void startAnim() {
rotateAnim = ValueAnimator.ofInt(0, 100);
rotateAnim.setDuration(1000);
rotateAnim.setInterpolator(new LinearInterpolator());
rotateAnim.addUpdateListener(animation -> {
shiftAngle += Math.PI / 180;
View.this.invalidate();
});
rotateAnim.setRepeatCount(ValueAnimator.INFINITE);
rotateAnim.start();
}
你可以预先计算出shiftAngle = 0
处小圆的圆心坐标,并存储在数组中。您可以先绘制它们,然后使用以下公式将它们旋转Math.PI / 180
。
newX = Math.cos(Math.PI / 180) * x - Math.sin(Math.PI / 180) * y;
newY = Math.sin(Math.PI / 180) * x + Math.cos(Math.PI / 180) * y;
因为 Math.sin(Math.PI / 180)
和 Math.cos(Math.PI / 180)
是常量。可以提前在循环外计算出来。
您可以通过这样做将 sin 和 cos 计算推出循环。
我正在尝试绘制自定义旋转动画。这是我的代码的输出。
基本上每个圈子都有小的子圈子。唯一的问题是,有时动画会跳过一些帧并且动画看起来很破损。我的猜测是因为这个计算很耗时,一些帧丢失了。
我的问题是改善这一点并保持动画流畅的最佳方法是什么。 是否可以只计算第一帧并旋转 canvas 以便我们减少计算量?
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int startRadius = 20;
int endRadius = 400;
int circleCount = 20;
int circleDistance = (int) (((endRadius - startRadius) / (float) circleCount));
for (int i = 0; i < circleCount; i++) {
int radius = startRadius + i * circleDistance;
canvas.drawCircle(center.x, center.y, radius, mPaint);
int subCircles=i+1;
double angleSegment = Math.PI * 2 / subCircles;
for (int segment = 0; segment < subCircles; segment++) {
double angle = angleSegment * segment + shiftAngle;
double x = Math.cos(angle) * radius;
double y = Math.sin(angle) * radius;
canvas.drawCircle((float) (x + center.x), (float) (y + center.y), 6, pointPaint);
}
}
}
动画师
public void startAnim() {
rotateAnim = ValueAnimator.ofInt(0, 100);
rotateAnim.setDuration(1000);
rotateAnim.setInterpolator(new LinearInterpolator());
rotateAnim.addUpdateListener(animation -> {
shiftAngle += Math.PI / 180;
View.this.invalidate();
});
rotateAnim.setRepeatCount(ValueAnimator.INFINITE);
rotateAnim.start();
}
你可以预先计算出shiftAngle = 0
处小圆的圆心坐标,并存储在数组中。您可以先绘制它们,然后使用以下公式将它们旋转Math.PI / 180
。
newX = Math.cos(Math.PI / 180) * x - Math.sin(Math.PI / 180) * y;
newY = Math.sin(Math.PI / 180) * x + Math.cos(Math.PI / 180) * y;
因为 Math.sin(Math.PI / 180)
和 Math.cos(Math.PI / 180)
是常量。可以提前在循环外计算出来。
您可以通过这样做将 sin 和 cos 计算推出循环。