import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: customRotationTransition(),
    );
  }
}

class customRotationTransition extends StatefulWidget {
  const customRotationTransition({Key? key}) : super(key: key);

  @override
  _customRotationTransitionState createState() =>
      _customRotationTransitionState();
}

class _customRotationTransitionState extends State<customRotationTransition>
    with SingleTickerProviderStateMixin {
  double radian = 0.0;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    // 지속적으로 무언가를 실행할땐 timer
    Timer.periodic(Duration(milliseconds: 100), (timer) {
      setState(() {
        radian = radian + pi / 9;
      });
      // setState가 재실행되기 때문에 랜더링이 계속 됨
    });
    // Future.delayed(Duration(seconds: 3),()=>{});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            RaisedButton(
              onPressed: () {
                setState(() {
                  radian = radian + pi / 2;
                });
              },
              child: Text("버튼"),
            ),
            Transform.rotate(
              // angle 만큼 회전
              // 단위 pi -> radian 개념 (반지름의 길이와 같은 원의 둘레)
              // radian이 되는 각도는 57도, 180도일때의 반지름과 3레디안의 차이는 0.14임
              // 원의 둘레는 radian으로 표현 => 원 둘레 = 5.x * radian
              // pi = 3 radian - 0.14
              // 원의 둘레 = pi * 2
              angle: radian,
              child: Container(
                width: 100,
                height: 100,
                color: Colors.blue,
                child: Text("왼쪽모서리"),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

참고

Timer를 통해 setState를 계속 호출하는건 현재 페이지의 랜더링을 계속하기 때문에 비효율적
버튼을 통해 애니메이션이 필요할때 위의 방법이 유용

728x90

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: positionedTransition(),
    );
  }
}

class positionedTransition extends StatefulWidget {
  const positionedTransition({Key? key}) : super(key: key);

  @override
  _positionedTransitionState createState() => _positionedTransitionState();
}

class _positionedTransitionState extends State<positionedTransition>
    with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  @override
  void initState() {
    // TODO: implement initState
        // PositionedTransition의 컨트롤러를 컨트롤할 컨트롤러 
    _animationController =
        AnimationController(vsync: this, duration: Duration(seconds: 5));
    _animationController.repeat();
    super.initState();
    // 컨트롤러 초기화
    ;
  }

  @override
  Widget build(BuildContext context) {
        // 미디어쿼리로 디바이스 높이가져옴
    double height = MediaQuery.of(context).size.height;
        // PositionedTransition 컨트롤러 생성
    Animation<RelativeRect> _controller = RelativeRectTween(
            begin: RelativeRect.fromLTRB(0, height, 0, 0),
            end: RelativeRect.fromLTRB(0, 0, 0, 0))
        .animate(CurvedAnimation(
            parent: _animationController, curve: Curves.easeInOut));
    return Scaffold(
      body: Stack(
        children: [
                    // PositionedTransition은 스택에서만 작동
          PositionedTransition(
            rect: _controller,
            child: Container(color: Colors.blue),
          ),
        ],
      ),
    );
  }
}
728x90

+ Recent posts