如何使用具有3D效果的加速度计移动视图?

时间:2016-09-29 14:24:45

标签: android animation accelerometer

我尝试重现以下动画:

3d effect animation

1)实施加速度计没问题:

public class Accelerometer extends AppCompatActivity implements SensorEventListener {

    private SensorManager senSensorManager;
    private Sensor senAccelerometer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //...

        // Get a reference to a SensorManager
        senSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    }

    // This method will update the UI on new sensor events
    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        Sensor sensor = sensorEvent.sensor;

        if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            float x = sensorEvent.values[0];
            float y = sensorEvent.values[1];
        }
    }

    @Override
    public void onAccuracyChanged(Sensor arg0, int arg1) {
    }

    @Override
    protected void onResume() {
        super.onResume();
        senSensorManager.registerListener(this, senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onStop() {
        senSensorManager.unregisterListener(this);
        super.onStop();
    }
}

2)我的问题是根据位置X和Y重现 3D效果。它不应与paralax效果相混淆。

我找到了Rotate3dAnimation

的解决方案

如果您看到该类,则动画就在camera.rotateY(degrees);上,因此我创建了一个自定义的Rotate3dAnimation:

public class CustomRotate3dAnimation extends Animation {
    private static final float DEPTHZ = 20.0f;

    private final float mFromXDegrees;
    private final float mFromYDegrees;
    private final float mToDegrees;
    private final float mCenterX;
    private final float mCenterY;
    private final boolean mRotateCameraX;
    private Camera mCamera;

    public CustomRotate3dAnimation(float fromXDegrees, float fromYDegrees, float toDegrees,
                                   float centerX, float centerY, boolean rotateCameraX) {
        mFromXDegrees = fromXDegrees;
        mFromYDegrees = fromYDegrees;
        mToDegrees = toDegrees;
        mCenterX = centerX;
        mCenterY = centerY;
        mRotateCameraX = rotateCameraX;
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        mCamera = new Camera();
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final float fromDegrees = mRotateCameraX ? mFromXDegrees : mFromYDegrees;
        float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);

        final float centerX = mCenterX;
        final float centerY = mCenterY;
        final Camera camera = mCamera;

        final Matrix matrix = t.getMatrix();

        camera.save();
        camera.translate(0.0f, 0.0f, DEPTHZ * interpolatedTime);

        if(mRotateCameraX) {
            camera.rotateY(degrees);
            camera.rotateX(mFromYDegrees);
        } else {
            camera.rotateY(mFromXDegrees);
            camera.rotateX(degrees);
        }
        camera.getMatrix(matrix);
        camera.restore();

        matrix.preTranslate(-centerX, -centerY);
        matrix.postTranslate(centerX, centerY);
    }
}

这是我在onSensorChanged上的实现:

@Override
public void onSensorChanged(SensorEvent sensorEvent) {
    Sensor sensor = sensorEvent.sensor;

    if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        int x = (int) sensorEvent.values[0];
        int y = (int) sensorEvent.values[1];

        if (x != currentXAngle / 10 && Math.abs(x) < 2) {
            Log.e(TAG, "X: " + x);

            int end = x * 10;

            final float centerX = viewCard.getWidth() / 2.0f;
            final float centerY = viewCard.getHeight() / 2.0f;

            final CustomRotate3dAnimation rotation = new CustomRotate3dAnimation(currentXAngle, currentYAngle, end, centerX, centerY, true);
            rotation.setDuration(200);
            rotation.setFillAfter(true);
            viewCard.startAnimation(rotation);

            currentXAngle = end;
        }

        if (y != currentYAngle / 10 && Math.abs(y) < 2) {
            Log.e(TAG, "Y: " + y);

            int end = y * 10;

            final float centerX = viewCard.getWidth() / 2.0f;
            final float centerY = viewCard.getHeight() / 2.0f;

            final CustomRotate3dAnimation rotation = new CustomRotate3dAnimation(currentXAngle, currentYAngle, end, centerX, centerY, false);
            rotation.setDuration(200);
            rotation.setFillAfter(true);
            viewCard.startAnimation(rotation);

            currentYAngle = end;
        }
    }
}

图片结果:

Result work in progress

但结果很糟糕,不顺利。

  

有人知道图书馆或文章可以帮助我吗?

0 个答案:

没有答案