Android

关注公众号 jb51net

关闭
首页 > 软件编程 > Android > Android Flutter立体旋转

Android利用Flutter实现立体旋转效果

作者:岛上码农

本文主要介绍了Flutter绘图如何使用ImageShader填充图形,并且利用 Matrix4的三维变换加上动画实现了立体旋转的动画效果,感兴趣的可以尝试一下

前言

之前我们提到了 CustomPaint erPaint 可以使用渐变(GradientShader)来填充绘制的图形,本篇我们来介绍使用图片填充,并且配合动画实现“立体”旋转效果,之所以给“立体”加上引号,是因为实际是通过填充图片自身的光影效果旋转后看起来像是立体效果一样。下面是实现的效果图。

ImageShader 简介

ImageShader 的定义如下,我们来看看各个参数的用途。

ImageShader(
  Image image, 
  TileMode tmx, 
  TileMode tmy, 
  Float64List matrix4, 
  {
    FilterQuality? filterQuality,
  }
)

tmxtmyTileMode 枚举,有以下几种取值:

clamp:图片不能完整填充图形时,使用最接近图形边缘的颜色进行填充,其实就是边缘的延伸。比如同时这是 tmx 和 tmy 都为 TileMode.clamp 的时候的效果图如下。

repeated:这个好理解,就是在各自方向重复。

decal:就是这个方向不做任何处理,使用透明填充,比如我们将上面的 tmy 改成 decal,就只会在 x 轴重复了。

mirror:顾名思义,就是镜像填充,下面是 tmxmirrortmyrepeated的效果图。

构建 ui.Image对象

要使用 ImageShader,我们首先要从图片资源中构建ui.Image 对象。这需要将图片文件按ByteData 二进制方式读取,在将二进制文件解码成为 ui.Image 对象。这个操作是异步的,因此在操作没完成前不能使用图像资源,我们设置了一个isImageLoaded布尔值标识图像是否加载完成。

final ByteData data = await rootBundle.load('images/beauty.jpg');
fillImage = await loadImage(Uint8List.view(data.buffer));

Future<ui.Image> loadImage(Uint8List img) async {
  final Completer<ui.Image> completer = Completer();
  ui.decodeImageFromList(img, (ui.Image img) {
    setState(() {
      isImageLoaded = true;
    });
    return completer.complete(img);
  });
  return completer.future;
}

使用 ImageShader 填充形状

使用 ImageShader 填充和 GradientShader 类似,按我们上面说的参数构建一个 ImageShader 对象就可以了,代码如下。注意,Paint 对象的填充方式必须是 fill,如果是空心的话是看不到效果的。

@override
void paint(Canvas canvas, Size size) {
  var paint = Paint();
  paint.style = PaintingStyle.fill;

  paint.shader = ImageShader(
    image,
    TileMode.mirror,
    TileMode.repeated,
    Matrix4.identity().storage,
    filterQuality: FilterQuality.high,
  );
  canvas.drawRect(Rect.fromLTRB(0, 0, size.width, size.height), paint);
}

立体旋转效果实现

立体效果需要利用填充图像的光影效果,因此我们需要找一张图片,比如明暗不同,或色彩不同的,这样旋转起来就会感觉是立体的。旋转的话使用 Matrix4的旋转变换就行。同时,为了让旋转过程展示的图像不固定,我们旋转的时候可以通过Matrix4的平移显示不同图形的区域。下面是我们用于测试的两张图片。

实现的代码如下所示,其中animationValue是动画过程中 Animation 对象的值,我们的动画时长设置为10秒。这里我们绘制的其实是一个圆形,只是因为填充图像在不停的旋转,且展示的图像不同就看起来有了立体效果。

void paint(Canvas canvas, Size size) {
    var paint = Paint();
    paint.style = PaintingStyle.fill;
    paint.shader = ImageShader(
      image,
      TileMode.mirror,
      TileMode.mirror,
      (Matrix4.identity()
            ..translate(5 * animationValue, 5 * animationValue)
            ..scaled(0.5)
            ..rotateZ(2 * pi * animationValue))
          .storage,
      filterQuality: FilterQuality.high,
    );
    Offset center = Offset(size.width / 2, size.height / 2);
    canvas.drawCircle(center, 200, paint);
}

下图是换了星球图片的运行效果,大家也可以调整 ImageShader 的参数看看其他参数的效果。

总结

源码已经提交至:绘图相关源码,文件名为:image_shader_demo.dart。本篇介绍了 Flutter 绘图使用 ImageShader 填充图形,并且利用 Matrix4的三维变换加上动画实现了立体旋转的动画效果。随着对 Flutter 绘图的深入,我们会发现绘图覆盖的面非常广,也能够实现更多有趣的效果。

以上就是Android利用Flutter实现立体旋转效果的详细内容,更多关于Android Flutter立体旋转的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文