drawArc

샤워실의 바보·2024년 3월 13일
0

Flutter Animation

목록 보기
26/31
post-thumbnail
import 'dart:math';
import 'package:flutter/material.dart';

class AppleWatchScreen extends StatefulWidget {
  const AppleWatchScreen({super.key});

  
  State<AppleWatchScreen> createState() => _AppleWatchScreenState();
}

class _AppleWatchScreenState extends State<AppleWatchScreen> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      appBar: AppBar(
        backgroundColor: Colors.black,
        foregroundColor: Colors.white,
        title: const Text("Apple Watch"),
      ),
      body: Center(
        child: CustomPaint(
          painter: AppleWatchPainter(),
          size: const Size(400, 400),
        ),
      ),
    );
  }
}

class AppleWatchPainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    final center = Offset(
      size.width / 2,
      size.height / 2,
    );

    // 빨간색 원 그리기
    final redCirclePaint = Paint()
      ..color = Colors.red.shade400.withOpacity(0.3) // 색상과 투명도 설정
      ..style = PaintingStyle.stroke // 외곽선만 그리기 설정
      ..strokeWidth = 25; // 외곽선의 두께 설정
    final redCircleRadius = (size.width / 2) * 0.9;
    canvas.drawCircle(center, redCircleRadius, redCirclePaint);

    // 초록색 원 그리기
    final greenCircle = Paint()
      ..color = Colors.green.shade400.withOpacity(0.3)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 25;
    canvas.drawCircle(center, (size.width / 2) * 0.76, greenCircle);

    // 파란색 원 그리기
    final blueCircle = Paint()
      ..color = Colors.cyan.shade400.withOpacity(0.3)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 25;
    canvas.drawCircle(center, (size.width / 2) * 0.62, blueCircle);

    // 빨간색 아크 그리기
    final redArcRect = Rect.fromCircle(center: center, radius: redCircleRadius);
    final redArcPaint = Paint()
      ..color = Colors.red.shade400 // 아크의 색상 설정
      ..style = PaintingStyle.stroke // 외곽선만 그리기 설정
      ..strokeCap = StrokeCap.round // 아크 끝의 모양을 둥글게 처리
      ..strokeWidth = 25; // 아크의 두께 설정
    // 아크 그리기: 시작 각도는 -0.5 * pi, 각도의 길이는 1.5 * pi로 설정
    canvas.drawArc(redArcRect, -0.5 * pi, 1.5 * pi, false, redArcPaint);
  }

  
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // 위젯이 다시 그려질 필요가 없으므로 false 반환
    return false;
  }
}

이 코드에서 drawArc 메서드는 Canvas 객체에 아크(원의 일부분)를 그리는 데 사용됩니다. 아크를 그리기 위한 주요 파라미터로는 그릴 범위를 나타내는 Rect, 시작 각도, 각도의 길이, 그리고 그림을 그릴 Paint 객체가 있습니다. 아크는 -0.5 * pi에서 시작하여 1.5 * pi의 길이로 그려지며, 이는 원의 대략 3/4를 그리는 것과 같습니다. Paint 객체에서는 아크의 색상, 스타일, 끝점의 모양, 그리고 두께를 설정할 수 있습니다.

이 코드는 Flutter에서 커스텀 페인팅 기술을 이용해 특정 그래픽을 캔버스에 그리는 과정을 설명합니다. 구체적으로 Apple Watch 스크린을 상상하며 그린 그래픽으로, 세 개의 원과 하나의 아크를 중심으로 구성되어 있습니다. 여기서 각 단계는 다음과 같은 역할을 합니다:

중심점 계산

  • 이 그림의 모든 도형은 캔버스의 중앙에 위치합니다. 그 중심점(center)을 계산하기 위해, 캔버스의 너비(size.width)와 높이(size.height)를 각각 2로 나눈 값을 사용합니다. 이 위치는 원과 아크를 그릴 때 기준점으로 쓰입니다.

원 그리기

  • 먼저, 빨간색, 초록색, 파란색의 세 개의 원을 순차적으로 그립니다. 각 원은 서로 다른 반지름을 가지며, 색상은 .shade400으로 조금 진하게 하고 .withOpacity(0.3)을 적용하여 투명도를 조절해 겹치는 부분에서 색이 섞이는 효과를 줍니다.
  • PaintingStyle.stroke를 설정하여 원의 내부를 채우지 않고 외곽선만 그립니다. strokeWidth는 25로 설정하여 원의 외곽선 두께를 조절합니다.
  • 각 원의 반지름은 캔버스의 반지름(size.width / 2)에 비례한 값(0.9, 0.76, 0.62 배율)으로 설정해, 크기가 서로 다른 중첩된 원들을 만듭니다.

아크 그리기

  • 빨간색 아크를 그리기 위해, 빨간색 원과 동일한 반지름을 가진 원을 기반으로 한 Rect.fromCircle를 정의합니다. 이 사각형은 drawArc 메서드에서 아크를 그릴 범위를 정의하는 데 사용됩니다.
  • 아크는 -0.5 * pi에서 시작하여 1.5 * pi의 각도로 그려지며, 이는 원의 약 3/4에 해당하는 아크를 만듭니다. pi는 원주율 값으로, 각도를 라디안 단위로 표현하는 데 사용됩니다. -0.5 * pi는 수평선에서 위쪽으로 90도 회전한 시작점을 의미합니다.
  • strokeCap.round를 설정하여 아크의 양 끝을 둥글게 처리합니다. 이는 아크가 더 매끄럽고 완성도 있는 모습을 갖게 합니다.
  • strokeWidth는 25로 설정하여 아크의 두께를 일관되게 유지합니다.

이 과정을 통해, 복잡한 그래픽 요소를 단계별로 구성하고, Flutter 앱에 시각적으로 매력적인 요소를 추가할 수 있음을 보여줍니다. Flutter의 커스텀 페인팅 기능은 다양한 시각적 표현을 가능하게 하여, 앱의 사용자 인터페이스 디자인을 한층 풍부하게 합니다.

profile
공부하는 개발자

0개의 댓글