Search code examples
imageflutterdartalignment

Is there a way in Flutter/Dart to display part of an image


Working on a card game in Flutter. Have one large graphic with full card deck in a 5 x 12 grid. 5th row are jokers and card backs. It would be more efficient on resources than have 60 individual files.

I would like to display just a card at a time. I want to specify x y for where to start on the image and then height/width for how much to show.

Tried this thinking the inscribe would move the alignment from .topLeft based on the size and rect.

https://api.flutter.dev/flutter/painting/Alignment/inscribe.html

  body: Center(
          child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                ClipRect(
                  child: Align(
                    alignment: Alignment.topLeft.inscribe(
                        Size(100, 100), Rect.fromLTWH(0, 0, 100, 100)),
                    heightFactor: 0.5,
                    child: Image.asset(
                      'images/Deck1.png',
                    ),
                  ),
                ),
                RaisedButton(

But am getting a compile error on this line

Compiler message:
lib/screens/home/home.dart:34:50: Error: The argument type 'Rect' can't be assigned to the parameter type 'AlignmentGeometry'.
 - 'Rect' is from 'dart:ui'.
 - 'AlignmentGeometry' is from 'package:flutter/src/painting/alignment.dart' ('../../Developer/flutter/packages/flutter/lib/src/painting/alignment.dart').
                    alignment: Alignment.topLeft.inscribe(

Solution

  • You can copy paste run full code below
    You can use package https://pub.dev/packages/flame to work with Sprite
    For this example to work, you need to put png https://raw.githubusercontent.com/flame-engine/flame/master/doc/examples/animation_widget/assets/images/minotaur.png in assets/images folder

    This png has 1 row and 19 column
    After load SpriteSheet , You can display with SpriteWidget and define picture position you want to display

    SpriteWidget(sprite: _animationSpriteSheet.getSprite(0, 5))
    

    code snippet

     final _animationSpriteSheet = SpriteSheet(
          imageName: 'minotaur.png',
          columns: 19,
          rows: 1,
          textureWidth: 96,
          textureHeight: 96,
        );
      ...
      Container(
        width: 200,
        height: 200,
        child: SpriteWidget(sprite: _animationSpriteSheet.getSprite(0, 0)),
      ),
      Container(
        width: 200,
        height: 200,
        child: SpriteWidget(sprite: _animationSpriteSheet.getSprite(0, 5)),
      ),
    

    you can reference detail in document source https://medium.com/flutter-community/sprite-sheet-animations-in-flutter-1b693630bfb3
    working demo

    enter image description here

    full code

    import 'dart:async';
    
    import 'package:flame/anchor.dart';
    import 'package:flame/flame.dart';
    import 'package:flame/animation.dart' as animation;
    import 'package:flame/sprite.dart';
    import 'package:flame/spritesheet.dart';
    import 'package:flame/position.dart';
    import 'package:flame/widgets/animation_widget.dart';
    import 'package:flame/widgets/sprite_widget.dart';
    import 'package:flutter/material.dart';
    
    Sprite _sprite;
    Sprite _sprite1;
    animation.Animation _animation;
    final _animationSpriteSheet = SpriteSheet(
      imageName: 'minotaur.png',
      columns: 19,
      rows: 1,
      textureWidth: 96,
      textureHeight: 96,
    );
    
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      _sprite = await Sprite.loadSprite('minotaur.png', width: 96, height: 96);
    
    
      await Flame.images.load('minotaur.png');
    
      _animation = _animationSpriteSheet.createAnimation(
        0,
        stepTime: 0.2,
        to: 19,
      );
    
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Animation as a Widget Demo',
          theme: ThemeData(primarySwatch: Colors.blue),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      Position _position = Position(256.0, 256.0);
    
      @override
      void initState() {
        super.initState();
        changePosition();
      }
    
      void changePosition() async {
        await Future.delayed(const Duration(seconds: 1));
        setState(() {
          _position = Position(10 + _position.x, 10 + _position.y);
          print(_position.toString());
        });
      }
    
      void _clickFab(GlobalKey<ScaffoldState> key) {
        key.currentState.showSnackBar(
          const SnackBar(
            content: const Text('You clicked the FAB!'),
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        final key = GlobalKey<ScaffoldState>();
        return Scaffold(
          key: key,
          appBar: AppBar(
            title: const Text('Animation as a Widget Demo'),
          ),
          body: Center(
            child: SingleChildScrollView(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  const Text('Hi there! This is a regular Flutter app,'),
                  const Text('with a complex widget tree and also'),
                  const Text('some pretty sprite sheet animations :)'),
                  Container(
                    width: 200,
                    height: 200,
                    child: AnimationWidget(animation: _animation),
                  ),
                  const Text('Neat, hum?'),
                  const Text(
                      'By the way, you can also use static sprites as widgets:'),
                  Container(
                    width: 200,
                    height: 200,
                    child: SpriteWidget(sprite: _sprite),
                  ),
                  Container(
                    width: 200,
                    height: 200,
                    child: SpriteWidget(sprite: _animationSpriteSheet.getSprite(0, 0)),
                  ),
                  Container(
                    width: 200,
                    height: 200,
                    child: SpriteWidget(sprite: _animationSpriteSheet.getSprite(0, 5)),
                  ),
                  const Text('Sprites from Elthen\'s amazing work on itch.io:'),
                  const Text('https://elthen.itch.io/2d-pixel-art-minotaur-sprites'),
                ],
              ),
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () => _clickFab(key),
            child: const Icon(Icons.add),
          ),
        );
      }
    }