diff --git a/flare_dart/CHANGELOG.md b/flare_dart/CHANGELOG.md index 267d3b6..1dcbe83 100644 --- a/flare_dart/CHANGELOG.md +++ b/flare_dart/CHANGELOG.md @@ -1,3 +1,7 @@ +## [2.2.4] - 2019-11-07 12:14:49 + +- Adding support for ActorImage.isDynamic which allows Flare to pacakge source UV coordinates for the image such that it can be swapped at runtime. This requires re-exporting files from Flare after marking the image as dynamic in the Flare UI. + ## [2.2.3] - 2019-10-29 12:44:02 - Copy transformAffectsStroke from the source shape when instancing. diff --git a/flare_dart/lib/actor_image.dart b/flare_dart/lib/actor_image.dart index 9a96446..611337f 100644 --- a/flare_dart/lib/actor_image.dart +++ b/flare_dart/lib/actor_image.dart @@ -28,6 +28,8 @@ class ActorImage extends ActorDrawable with ActorSkinnable { int _textureIndex = -1; Float32List _vertices; + Float32List _dynamicUV; + Float32List get dynamicUV => _dynamicUV; Uint16List _triangles; int _vertexCount = 0; int _triangleCount = 0; @@ -141,6 +143,15 @@ class ActorImage extends ActorDrawable with ActorSkinnable { node._vertices = reader.readFloat32Array(numVertices * node.vertexStride, "vertices"); + // In version 24 we started packing the original UV coordinates if the + // image was marked for dynamic runtime swapping. + if (artboard.actor.version >= 24) { + bool isDynamic = reader.readBool("isDynamic"); + if (isDynamic) { + node._dynamicUV = reader.readFloat32Array(numVertices * 2, "uv"); + } + } + int numTris = reader.readUint32("numTriangles"); node._triangles = Uint16List(numTris * 3); node._triangleCount = numTris; @@ -217,6 +228,7 @@ class ActorImage extends ActorDrawable with ActorSkinnable { _triangleCount = node._triangleCount; _vertices = node._vertices; _triangles = node._triangles; + _dynamicUV = node._dynamicUV; if (node._animationDeformedVertices != null) { _animationDeformedVertices = Float32List.fromList(node._animationDeformedVertices); diff --git a/flare_dart/pubspec.yaml b/flare_dart/pubspec.yaml index 905179d..77e590b 100644 --- a/flare_dart/pubspec.yaml +++ b/flare_dart/pubspec.yaml @@ -1,6 +1,6 @@ name: flare_dart description: Vector design and runtime animation. -version: 2.2.3 +version: 2.2.4 author: "2Dimensions Team " homepage: https://github.com/2d-inc/Flare-Flutter environment: diff --git a/flare_flutter/CHANGELOG.md b/flare_flutter/CHANGELOG.md index f518ac0..08f6de5 100644 --- a/flare_flutter/CHANGELOG.md +++ b/flare_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## [1.7.0] - 2019-11-07 12:16:35 + +- Adding support for runtime image swapping. + ## [1.6.5] - 2019-11-06 17:29:43 - Fixed an issue with FlareCacheBuilder calling setState when the widget is no longer mounted. diff --git a/flare_flutter/lib/flare.dart b/flare_flutter/lib/flare.dart index b27ca43..a629c0b 100644 --- a/flare_flutter/lib/flare.dart +++ b/flare_flutter/lib/flare.dart @@ -1067,6 +1067,67 @@ class FlutterActorImage extends ActorImage with FlutterActorDrawable { } } + /// Swap the image used to draw the mesh for this image node. + /// Returns true when successful. + bool changeImage(ui.Image image) { + if (triangles == null || dynamicUV == null) { + return false; + } + _uvBuffer = makeVertexUVBuffer(); + int count = vertexCount; + + // SKIA requires texture coordinates in full image space, not traditional + // normalized uv coordinates. + int idx = 0; + for (int i = 0; i < count; i++) { + _uvBuffer[idx] = dynamicUV[idx] * image.width; + _uvBuffer[idx + 1] = dynamicUV[idx + 1] * image.height; + idx += 2; + } + + _paint.shader = image != null + ? ui.ImageShader( + image, ui.TileMode.clamp, ui.TileMode.clamp, _identityMatrix) + : null; + + _canvasVertices = ui.Vertices.raw(ui.VertexMode.triangles, _vertexBuffer, + indices: _indices, textureCoordinates: _uvBuffer); + + onPaintUpdated(_paint); + + return true; + } + + /// Change the image for this node via a network url. + /// Returns true when successful. + Future changeImageFromNetwork(String url) async { + var networkImage = NetworkImage(url); + var val = await networkImage.obtainKey(const ImageConfiguration()); + var load = networkImage.load(val, (Uint8List bytes, + {int cacheWidth, int cacheHeight}) { + return PaintingBinding.instance.instantiateImageCodec(bytes, + cacheWidth: cacheWidth, cacheHeight: cacheHeight); + }); + + final completer = Completer(); + load.addListener(ImageStreamListener((ImageInfo info, bool syncCall) { + changeImage(info.image); + completer.complete(true); + })); + return completer.future; + } + + /// Change the image for this node with one in an asset bundle. + /// Returns true when successful. + Future changeImageFromBundle( + AssetBundle bundle, String filename) async { + ByteData data = await bundle.load(filename); + ui.Codec codec = + await ui.instantiateImageCodec(Uint8List.view(data.buffer)); + ui.FrameInfo frame = await codec.getNextFrame(); + return changeImage(frame.image); + } + @override void initializeGraphics() { super.initializeGraphics(); @@ -1139,7 +1200,6 @@ class FlutterActorImage extends ActorImage with FlutterActorDrawable { canvas.save(); clip(canvas); - _paint.color = _paint.color.withOpacity(renderOpacity.clamp(0.0, 1.0).toDouble()); diff --git a/flare_flutter/pubspec.yaml b/flare_flutter/pubspec.yaml index cd3b0b9..4e50caf 100644 --- a/flare_flutter/pubspec.yaml +++ b/flare_flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: flare_flutter description: Vector design and runtime animation for Flutter. -version: 1.6.5 +version: 1.7.0 author: "2Dimensions Team " homepage: https://github.com/2d-inc/Flare-Flutter environment: