1

我正在尝试绘制自定义旋转动画。这是我的代码的输出。

在此处输入图像描述

基本上每个圈子都有小的子圈。唯一的问题是,有时动画会跳过一些帧,动画看起来会损坏。我的猜测是因为这个计算很耗时,所以会丢失一些帧。

我的问题是改善这一点并保持动画流畅的最佳方法是什么。是否可以只计算第一帧并旋转画布以便我们可以减少计算?

@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();
}
4

1 回答 1

2

您可以预先计算小圆圈的中心坐标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 计算排除在循环之外。

于 2020-07-26T05:31:53.207 回答