[Flutter] 튕기는 줄

Noah·2024년 3월 13일
0

Flutter

목록 보기
2/11
post-thumbnail

튕기는 줄
https://bouncing-string.web.app/

프로젝트 목표

  • 사용자의 제스처에 따라 움직이는 줄 만들기
  • 탄성이 있는 줄 표현

기능 소개

  • 점과 점 사이의 거리 구하기
  • 점을 잇는 곡선 만들기
  • 설정한 범위를 벗어났을 때 줄을 놓치는 효과
  • 줄의 탄성 표현

문제 사항

1. 점을 잇는 곡선을 어떻게 만들까?

  • path.quadraticBezierTo()를 이용해 점과 점 사이를 잇는다.
	Path path = Path();
    Paint paint = Paint()
      ..color = $style.colors.primary
      ..style = PaintingStyle.stroke
      ..strokeWidth = 4;

    double preX = string.start.x;
    double preY = string.start.y;

    path.moveTo(preX, preY);

    for (int i = 1; i < BouncingString.length; i++) {
      final cx = (preX + string.getPoint(i).x) / 2;
      final cy = (preY + string.getPoint(i).y) / 2;

      path.quadraticBezierTo(preX, preY, cx, cy);

      preX = string.getPoint(i).x;
      preY = string.getPoint(i).y;
    }

    path.lineTo(preX, preY);

    canvas.drawPath(path, paint);

2. 제스처로 일정 범위를 벗어나는 걸 어떻게 감지할까?

  • 두 점(px, py), (cx, cy)을 이용하여 거리를 구하고, 그 거리와 범위(r)를 비교하여 교차되는지 확인
  // 피타고라스의 정리를 이용하여 두 점 사이의 직선 거리를 계산
  static double distance(double x1, double y1, double x2, double y2) {
    final double x = x2 - x1;
    final double y = y2 - y1;

    return math.sqrt(x * x + y * y);
  }

  // 두 점(px, py), (cx, cy)을 이용하여 거리를 구하고, 그 거리와 범위(r)를 비교하여 교차되는지 확인
  static bool lineCircle(double x1, double y1, double x2, double y2, double cx, double cy, double r) {
    final double lineLength = distance(x1, y1, x2, y2);
    final double p = (((cx - x1) * (x2 - x1)) + ((cy - y1) * (y2 - y1))) / math.pow(lineLength, 2);

    final px = x1 + (p * (x2 - x1));
    final py = y1 + (p * (y2 - y1));

    return distance(px, py, cx, cy) < r;
  }

3. 줄의 탄성을 어떻게 표현할까?

  • 교차 결과를 검사하고 그 결과에 따라 이동속도를 조절하여 애니메이션을 표현
	if (GlobalFunction.lineCircle(
      string.start.x,
      string.start.y,
      string.end.x,
      string.end.y,
      moveX,
      moveY,
      string.detect,
    )) {
      string.detect = 300;
      final double tx = (string.middle.ox + moveX) / 2;
      final double ty = moveY;
      string.middle.vx = tx - string.middle.x;
      string.middle.vy = ty - string.middle.y;
    } else {
      string.detect = 10;
      final double tx = string.middle.ox;
      final double ty = string.middle.oy;
      string.middle.vx += tx - string.middle.x;
      string.middle.vx *= bounce;
      string.middle.vy += ty - string.middle.y;
      string.middle.vy *= bounce;
    }

    string.middle.x += string.middle.vx;
    string.middle.y += string.middle.vy;

성과

  • CustomPainter에서 path를 쓸 수 있다는 걸 확인
  • 피타고라스의 정의를 이용해 점과 점 사이의 거리를 재는 방법
  • 특정 범위를 벗어나는지 확인하는 방법
  • 탄성을 속도를 이용해 표현하는 방법론 습득

소스 코드
https://github.com/jsk9106/bouncing_string

해당 프로젝트는 Interactive Developer님의 영상을 참고했습니다.
https://www.youtube.com/watch?v=dXhAQbE8iBg&t=149s

profile
Flutter Specialist

0개의 댓글