Flutter에서 AnimatedRotation을 사용한 나침반 방향

지도 애플리케이션에서 사용자를 위한 부드러운 각도 전환 생성



그래서 저는 지도와 관련된 프로젝트를 진행하고 있습니다. 요구 사항 중 하나는 위치뿐만 아니라 사용자가 가리키는 항목도 업데이트하는 것이었습니다.

이를 위해 다음 플러그인을 앱에 통합했습니다.

  • flutter_compass - Flutter 나침반입니다. 방향은 0에서 360까지 다양하며 0은 북쪽입니다.

  • flutter_map - leaflet.js를 기반으로 하는 Flutter용 다목적 매핑 패키지로, 간단하고 배우기 쉬우면서도 완벽하게 사용자 정의 및 구성할 수 있습니다.

  • flutter_compass 플러그인에 대한 전체 문서는 the example pagepub.dev을 참조하세요.

    이제 사용자 머리글의 지속적인 변경 사항을 얻으려면 flutter_compass 플러그인에서 제공하는 API를 구독해야 합니다.

    double? userHeading;
    
    FlutterCompass.events?.listen((CompassEvent event) {
      userHeading = event.heading;
    }
    


    방향이 null인 경우 이는 클라이언트의 기기에 나침반 센서가 없다는 것을 의미하며 이 시나리오는 앱 실행 시 예외가 발생하지 않도록 처리되어야 합니다.

    이 방향 값을 노출하려면 다음과 같은 몇 가지 접근 방식을 사용할 수 있습니다.
  • 스트림빌더
  • 제공자
  • ValueNotifier
  • 기타

  • 하지만 이것은 메인 주제가 아니므로 선호하는 주제를 사용하십시오 ;)

    위젯의 경우 플러그인의 예에서는 다음과 같이 Transform.rotate를 사용하도록 제안합니다.

    Transform.rotate(
      angle: (direction * (math.pi / 180) * -1),
      child: Image.asset('assets/compass.jpg'),
    )
    


    작동하더라도 각도를 부드럽게 변경하는 다른 방법을 찾았습니다.

    어떤 다른 옵션이 있습니까???



    AnimatedRotation
    지정된 회전이 변경될 때마다 지정된 기간 동안 자식 회전을 자동으로 전환하는 Transform.rotate의 애니메이션 버전입니다.

    하지만 이 위젯은 이전 값과 비교하여 확인한 다음 왼쪽에서 오른쪽으로(값이 증가하는 경우) 또는 오른쪽에서 왼쪽으로(값이 감소하는 경우) 회전 전환을 애니메이션화하기 위해 회전 값이 필요합니다.

    각도를 회전으로 변환



    좋아요, 이거 쉽죠? 단순히 방향/360을 나누면 사용자가 가리키는 위치에 따라 값을 얻을 수 있습니다.

    그러나 이제 첫 번째 큰 문제에 직면하게 됩니다.
    나침반은 두 가지 시나리오에서 오작동합니다.
  • 사용자의 회전은 1도에서 360도까지입니다.
  • 사용자가 회전하면 360도에서 1도가 됩니다.

  • 이것은 까다로운 부분입니다



    각도의 변화를 구한 다음 예상되는 동작을 얻기 위해 약간의 수학을 수행해야 하기 때문입니다.

    다음과 같이 리스너 기능을 업그레이드할 수 있습니다.

    double turns = 0;
    double prevValue = 0;
    
    FlutterCompass.events?.listen((CompassEvent event) {
      double? direction = event.heading;
    
      direction = direction < 0 ? (360 + direction): direction;
      double diff = direction - prevValue;
      if(diff.abs() > 180) {
        if(prevValue > direction) {
          diff = 360 - (direction-prevValue).abs();
        } else {
          diff = 360 - (prevValue-direction).abs();
          diff = diff * -1;
        }
      }
      turns += (diff / 360);
      prevValue = direction;
    }
    


    이제 우리는 마지막 각도와 새 각도 사이의 변경 사항인 원하는 값을 차례대로 갖게 되었습니다.

    위젯은 다음과 같아야 합니다.

    AnimatedRotation(
      turns: turns,
      duration: const Duration(milliseconds: 250),
      child: const Icon(Icons.arrow_upward_outlined),
    )
    


    이것이 도움이 되고 시간을 절약할 수 있기를 바랍니다. ;)

    좋은 웹페이지 즐겨찾기