Flutter 진급 의 애니메이션 효과 구현(5)

이 글 이 시작 되 기 전에 우리 가 어떤 일 을 했 는 지 살 펴 보 자.4제1 편에서 우 리 는 애니메이션 값 이 변 경 될 때 double lerp Double(num a,num b,double t)을 호출 하여 줄 모양 을 다시 그립 니 다.4제2 편에서 우 리 는 먼저 Tween 류 로 애니메이션 값 을 관리 하고 줄 모양 을 다시 그 린 다음 에 줄 모양 애니메이션 과 관련 된 종 류 를 bar.dart 파일 로 추출 합 니 다.제3 편에서 우 리 는 먼저 Bar 류 에 색상 의 필드 를 추가 하고 color 를 새로 만 듭 니 다.팔레트.dart 파일 은 색상 값 을 가 져 오 는 데 사용 되 며,공장 구조 함수 인 Bar.empty 와 Bar.random 으로 각각 공백 Bar 인 스 턴 스 와 무 작위 Bar 인 스 턴 스 를 만 듭 니 다.제4 편에서 저 희 는 BarChart 류 를 추 가 했 습 니 다.지정 한 수량의 Bar 인 스 턴 스 목록 을 만 들 고 선형 을 그 리 는 코드 를 선형 그림 으로 변경 합 니 다.
그 다음 에 우 리 는 Bar 류 에 x 좌표 와 너비 속성 을 추가 한 다음 에 BarChart 로 하여 금 서로 다른 열 수 를 가 진 도 표를 지원 하 게 합 니 다.우리 의 새로운 도 표 는 데이터 세트 에 적 용 될 것 입 니 다.그 중에서 bar i 는 일부 시리즈 의 i 번 째 값 을 대표 합 니 다.예 를 들 어 제품 발표 후 i 일 째 매출 액 입 니 다.이러한 도 표 는 0.n 개의 선형 과 관련 되 지만 하나의 도표 의 선형 수량 n 은 다음 도표 와 다 를 수 있다.
예 를 들 어 두 개의 도표 가 있 는데 각각 5 개 와 7 개의 선형 이 있다.5 개의 선형 표 는 이전 방법 에 따라 애니메이션 화 할 수 있다.bars 의 색인 5 와 6 은 다른 애니메이션 종점 에서 상대방 이 없 지만 이 제 는 모든 선형 에 게 자신의 위치 와 너 비 를 자 유 롭 게 줄 수 있 습 니 다.우 리 는 보이 지 않 는 두 개의 선형 을 도입 하여 이 역할 을 할 수 있 습 니 다.시각 적 효 과 는 애니메이션 의 진행 에 따라 bars 의 색인 5 와 6 이 최종 외관 으로 성장 하 는 것 이다.반대 방향의 애니메이션 이 라면 bars 의 색인 5 와 6 은 스텔스 로 약화 되 거나 옅 어 집 니 다.
복합 값 간 의 선형 플러그 인(lerp)은 해당 구성 요 소 를 통 해 연 결 됩 니 다.한 구성 요소 가 종점 에서 잃 어 버 리 면 그 위치 에서 보이 지 않 는 구성 요 소 를 사용 합 니 다.일반적으로 보이 지 않 는 구성 요 소 를 선택 하 는 몇 가지 방법 이 있 습 니 다.만약 에 저희 제품 매니저 가 0 너비,0 높이 의 선형 을 사용 하기 로 결정 했다 고 가정 하면 x 좌표 와 색 채 는 보 이 는 대상 에서 계승 되 고 저 희 는 Bar 에 주어진 인 스 턴 스 의 collapsed 버 전 을 만 들 것 입 니 다.

import 'package:flutter/material.dart';
import 'package:flutter/animation.dart';
import 'dart:ui' show lerpDouble;
import 'dart:math';
import 'color_palette.dart';

class BarChart {
 final List<Bar> bars;

 BarChart(this.bars);

 factory BarChart.empty(Size size) {
 return new BarChart(<Bar>[]);
 }

 factory BarChart.random(Size size, Random random) {
 const barWidthFraction = 0.75;
 const minBarDistance = 20.0;
 // floor():           
 final barCount = random.nextInt((size.width/minBarDistance).floor()) + 1;
 final barDistance = size.width / (1+barCount);
 final barWidth = barDistance * barWidthFraction;
 final startX = barDistance - barWidth/2;
 final color = ColorPalette.primary.random(random);
 final bars = new List.generate(
  barCount,
  (i)=> new Bar(
  startX + i * barDistance,
  barWidth,
  random.nextDouble() * size.height,
  color,
  ),
 );
 return new BarChart(bars);
 }

 static BarChart lerp(BarChart begin, BarChart end, double t) {
 // max:            
 final barCount = max(begin.bars.length, end.bars.length);
 final bars = new List.generate(
  barCount,
  (i) => Bar.lerp(
  // ??:          
  begin._barOrNull(i) ?? end.bars[i].collapsed,
  end._barOrNull(i) ?? begin.bars[i].collapsed,
  t,
  )
 );
 return new BarChart(bars);
 }

 Bar _barOrNull(int index) => (index<bars.length ? bars[index] : null);
}

class BarChartTween extends Tween<BarChart> {
 BarChartTween(BarChart begin, BarChart end) : super(begin: begin, end: end);

 @override
 BarChart lerp(double t) => BarChart.lerp(begin, end, t);
}

class Bar {
 Bar(this.x, this.width, this.height, this.color);
 final double x;
 final double width;
 final double height;
 final Color color;

 Bar get collapsed => new Bar(x, 0.0, 0.0, color);

 static Bar lerp(Bar begin, Bar end, double t) {
 return new Bar(
  lerpDouble(begin.x, end.x, t),
  lerpDouble(begin.width, end.width, t),
  lerpDouble(begin.height, end.height, t),
  Color.lerp(begin.color, end.color, t)
 );
 }
}

class BarTween extends Tween<Bar> {
 BarTween(Bar begin, Bar end) : super(begin: begin, end: end);

 @override
 Bar lerp(double t) => Bar.lerp(begin, end, t);
}

class BarChartPainter extends CustomPainter {
 BarChartPainter(Animation<BarChart> animation)
  : animation = animation,
  super(repaint: animation);

 final Animation<BarChart> animation;

 @override
 void paint(Canvas canvas, Size size) {
 final paint = new Paint()..style = PaintingStyle.fill;
 final chart = animation.value;
 for(final bar in chart.bars) {
  paint.color = bar.color;
  canvas.drawRect(
  new Rect.fromLTWH(
   bar.x,
   size.height - bar.height,
   bar.width,
   bar.height
  ),
  paint
  );
 }
 }

 @override
 bool shouldRepaint(BarChartPainter old) => false;
}
이 설정 을 위해 BarChart.random 과 BarChart.empty 를 다시 정의 하 는 것 을 포함 하여 상기 코드 를 응용 프로그램 에 통합 합 니 다.이 제 는 빈 도표 0 줄 형 을 합 리 적 으로 포함 할 수 있 으 며,무 작위 막대 그래프 는 같은 무 작위 색상 의 무 작위 수량의 막대 형 을 포함 할 수 있 으 며,각각 무 작위 로 선택 한 높이 를 가지 고 있다.그러나 위치 와 너비 가 현재 Bar 정의 의 일부분 이기 때문에 BarChart.random 에서 이 속성 을 지정 해 야 합 니 다.BarChart.random 에 도표 Size 인 자 를 제공 하 는 것 은 합 리 적 이 며 BarChart Painter.paint 의 대부분 계산 을 완화 시 킬 수 있 습 니 다.
마지막 으로 프로그램 이 다시 표시 할 수 있 도록 main.dart 파일 을 업데이트 해 야 합 니 다.

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
 static const size = const Size(200.0, 100.0);
 // ...
 @override
 void initState() {
 // ...
 tween = new BarChartTween(
  new BarChart.empty(size),
  new BarChart.random(size, random));
 animation.forward();
 }
 // ...
 void changeData() {
 setState(() {
  tween = new BarChartTween(
  tween.evaluate(animation),
  new BarChart.random(size, random),
  );
  animation.forward(from: 0.0);
 });
 }
 // ...
 }
}

이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기