blob: 7b47d2ba532dfa713c85bd4b43d198ae2e94122e [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:typed_data';
import 'package:fidl/fidl.dart' show InterfaceHandle;
import 'package:fidl_fuchsia_mem/fidl.dart' show Buffer;
import 'package:fidl_fuchsia_skia_skottie/fidl.dart' as skottie;
import 'package:fidl_fuchsia_sys/fidl.dart';
import 'package:fidl_fuchsia_ui_app/fidl.dart' show ViewProviderProxy;
import 'package:fidl_fuchsia_ui_views/fidl_async.dart'
show ViewToken, ViewHolderToken;
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:fuchsia_scenic_flutter/child_view.dart' show ChildView;
import 'package:fuchsia_scenic_flutter/child_view_connection.dart'
show ChildViewConnection;
import '';
import 'package:meta/meta.dart';
import 'package:zircon/zircon.dart';
typedef LoadCallback = void Function(
skottie.Status status, skottie.Player player);
/// A [Widget] that displays lottie animation in a scenic view.
class LottiePlayer extends StatefulWidget {
/// The JSON data of the animation as a string.
final String json;
/// The background color.
final Color backgroundColor;
/// Called after animation is loaded.
final LoadCallback onLoad;
/// Loops the animation. Default [true].
final bool loop;
/// Starts playing the animation after loading. Default [true].
final bool autoplay;
/// Constructor.
const LottiePlayer({
@required this.json,
this.backgroundColor =,
this.loop = true,
this.autoplay = true,
Key key,
}) : super(key: key);
_LottiePlayerState createState() => new _LottiePlayerState();
class _LottiePlayerState extends State<LottiePlayer> {
final ComponentControllerProxy _controller = ComponentControllerProxy();
final skottie.LoaderProxy _loader = skottie.LoaderProxy();
ChildViewConnection _connection;
void initState() {
void didUpdateWidget(LottiePlayer old) {
if (old.json == widget.json &&
old.backgroundColor == widget.backgroundColor &&
old.loop == widget.loop &&
old.autoplay == widget.autoplay) {
void dispose() {
_connection = null;
Widget build(BuildContext context) => ChildView(
connection: _connection,
hitTestable: false,
focusable: false,
void _launchViewer() {
final startupContext = StartupContext.fromStartupInfo();
final incomingServices = Services();
final launcher = LauncherProxy();
connectToService(startupContext.environmentServices, launcher.ctrl);
url: 'skottie_viewer',
directoryRequest: incomingServices.request(),
final viewTokens = EventPairPair();
assert(viewTokens.status == ZX.OK);
final viewHolderToken = ViewHolderToken(value: viewTokens.first);
final viewToken = ViewToken(value: viewTokens.second);
final viewProvider = ViewProviderProxy();
viewProvider.createView(viewToken.value, null, null);
_connection = ChildViewConnection(viewHolderToken);
void _loadViewer() {
final SizedVmo vmo =
final options = skottie.Options(
backgroundColor: widget.backgroundColor.value,
loop: widget.loop,
autoplay: widget.autoplay,
_loader.load(Buffer(vmo: vmo, size: vmo.size), options,
(skottie.Status status, InterfaceHandle<skottie.Player> player) {
widget.onLoad(status, skottie.PlayerProxy()..ctrl.bind(player));