android 谷歌地图的图标翻页旋转效果

最近在看扔物线的 hencoder 自定义 view 系列,有个图标翻页旋转效果很炫酷。自己思考加上看了位大神的思路,总算做出来了。(GIF 录制的有点卡,真实效果可以自己运行查看)


效果

思路

整体由三个属性动画构成。首先把整个图标平均分成两部分,一部分先向上翻折(最开始的动画)称为 a 半边;另一部分最后向上翻折(最后一个动画)称为 b 半边

第一个动画:使用 camera 3d 动画,将 a 半边沿着 Y 轴反方向旋转 45 度;
第二个动画:使用 canvas 2d 动画旋转,将“a 半边的 3d 效果”逆时针旋转 270 度(就是我们看到的平面旋转效果);
第三个动画:b 半边沿着 Y 轴旋转 45 度。

光是描述有点难形容,若是没搞懂思路,只能通过代码一步一步走,慢慢推倒理解了。核心代码如下:

    /**
     * a半边的动画旋转角度(第一个动画 3d)
     */
    private int degreeY;
    /**
     * b半边的动画旋转角度(第三个动画 3d)
     */
    private int degreeNextY;
    /**
     * 画布的动画旋转角度(第二个动画 2d)
     */
    private int degreeZ;
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int centerX = getWidth() / 2;
        int centerY = getHeight() / 2;
        int x = centerX - bitmap.getWidth() / 2;
        int y = centerY - bitmap.getHeight() / 2;

        // a半边的处理
        canvas.save();

        camera.save();
        canvas.translate(centerX, centerY);
        // 第一个动画的3d旋转
        camera.rotateY(degreeY);
        // 旋转画布
        canvas.rotate(degreeZ);
        // 此时图标的正中心跟坐标原点位置相同
        canvas.clipRect(0, -centerY, centerX, centerY);
        camera.applyToCanvas(canvas);
        // 记住画布要旋转回来
        canvas.rotate(-degreeZ);
        canvas.translate(-centerX, -centerY);
        camera.restore();

        canvas.drawBitmap(bitmap, x, y, paint);
        canvas.restore();
        
        // b半边的处理
        canvas.save();

        camera.save();
        canvas.translate(centerX, centerY);
        // b半边也要跟着旋转(保持另外半边不动)
        canvas.rotate(degreeZ);
        // 第三个动画的 3d 旋转
        camera.rotateY(degreeNextY);
        // 此时图标的正中心跟坐标原点位置相同
        canvas.clipRect(-centerX, -centerY, 0, centerY);
        camera.applyToCanvas(canvas);
        // 记住画布要旋转回来
        canvas.rotate(-degreeZ);
        canvas.translate(-centerX, -centerY);
        camera.restore();

        canvas.drawBitmap(bitmap, x, y, paint);
        canvas.restore();
    }

详细代码在我的 GitHub上,欢迎大家 star。

你可能感兴趣的:(android 谷歌地图的图标翻页旋转效果)