ミッドランドブログ

長めのお知らせ、紹介記事を掲載します

GeminiとChatGPTに同じ指示文でコードを生成させてみた

※これは2024年6月に書いています

Flutterで下の図のようなオブジェクトをアニメーションをさせたかったのですが、Animationが今一つ理解できなかったので、AIにサンプルを生成させてみることにしました。
※Geminiはadvanceではない方。ChatGPTは無料のもの。

 

 

指示文

二つのウィジットA、Bがあり、A、Bを格納するウィジットCがあります
これらはすべて同時にアニメーションします
Cは前後運動と同時に回転運動をします
Aは三つの画像X、Y、Zを順番に表示します
Bは回転運動をします
Flutterのコードで生成してください

 

結果

こんな微妙な指示文で出力してくれるのにまず驚きました。
Geminiは三案ほど出力してくれたのですが、3案とも意図したものと少し違うようでした。
無料版ではChatGPTの方が使えそうな雰囲気です。

すごい時代になりました。

 

Geminiの出力(A案のみ記載)


import 'package:flutter/material.dart';

class AnimatedContainerExample extends StatefulWidget {
  @override
  _AnimatedContainerExampleState createState() =>
      _AnimatedContainerExampleState();
}

class _AnimatedContainerExampleState extends State
    with SingleTickerProviderStateMixin {
  AnimationController _controller;
  Animation _animationFrontToBack;
  Animation _animationBackToFront;
  Animation _rotationAnimation;
  Animation _imageIndexAnimation;

  @override
  void initState() {
    super.initState();

    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 4),
    )..repeat();

    _animationFrontToBack = Tween(begin: 0.0, end: 1.0)
        .animate(_controller);

    _animationBackToFront = Tween(begin: 1.0, end: 0.0)
        .animate(_controller);

    _rotationAnimation = Tween(begin: 0.0, end: 360.0)
        .animate(_controller);

    _imageIndexAnimation = Tween(begin: 0, end: 2)
        .animate(_controller.repeatDuration);

    _controller.addListener(() {
      setState(() {});
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          AnimatedContainer(
            duration: const Duration(seconds: 2),
            curve: Curves.easeInOut,
            transform: Matrix4.identity()
              ..translate(
                  0.0,
                  _animationFrontToBack.value * 100 -
                      _animationBackToFront.value * 100),
            child: AnimatedRotation(
              turns: _rotationAnimation.value / 360,
              duration: const Duration(seconds: 2),
              curve: Curves.easeInOut,
              child: Container(
                width: 200,
                height: 200,
                child: AnimatedSwitcher(
                  duration: const Duration(milliseconds: 500),
                  transition: ScaleTransition(scale: 2),
                  child: IndexedStack(
                    index: _imageIndexAnimation.value,
                    children: [
                      Image.asset('assets/image_x.png'),
                      Image.asset('assets/image_y.png'),
                      Image.asset('assets/image_z.png'),
                    ],
                  ),
                ),
              ),
            ),
          ),
          const SizedBox(height: 20),
          Text('Widget C'),
        ],
      ),
    );
  }
}

 

 

 

ChatGPTの出力


import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: WidgetC(),
        ),
      ),
    );
  }
}

class WidgetC extends StatefulWidget {
  @override
  _WidgetCState createState() => _WidgetCState();
}

class _WidgetCState extends State with TickerProviderStateMixin {
  late AnimationController _controller;
  late Animation _slideAnimation;
  late Animation _rotationAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(seconds: 3),
      vsync: this,
    )..repeat(reverse: true);

    _slideAnimation = Tween(
      begin: Offset(-0.1, 0),
      end: Offset(0.1, 0),
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.easeInOut,
    ));

    _rotationAnimation = Tween(
      begin: 0,
      end: 2 * 3.141592653589793,
    ).animate(_controller);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SlideTransition(
      position: _slideAnimation,
      child: RotationTransition(
        turns: _rotationAnimation,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            WidgetA(),
            SizedBox(height: 20),
            WidgetB(),
          ],
        ),
      ),
    );
  }
}

class WidgetA extends StatefulWidget {
  @override
  _WidgetAState createState() => _WidgetAState();
}

class _WidgetAState extends State with TickerProviderStateMixin {
  late AnimationController _controller;
  late List images;
  int currentIndex = 0;

  @override
  void initState() {
    super.initState();
    images = ['assets/image_x.png', 'assets/image_y.png', 'assets/image_z.png'];
    _controller = AnimationController(
      duration: Duration(seconds: 1),
      vsync: this,
    )..repeat();

    _controller.addListener(() {
      setState(() {
        currentIndex = (_controller.value * images.length).floor() % images.length;
      });
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Image.asset(images[currentIndex]);
  }
}

class WidgetB extends StatefulWidget {
  @override
  _WidgetBState createState() => _WidgetBState();
}

class _WidgetBState extends State with TickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(seconds: 3),
      vsync: this,
    )..repeat();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return RotationTransition(
      turns: _controller,
      child: Container(
        width: 100,
        height: 100,
        color: Colors.blue,
      ),
    );
  }
}