Flutter 진급 의 애니메이션 효과 구현(7)
애니메이션 효 과 는 매우 예 쁘 게 만 들 수 있 지만 사용 자 를 곤 혹 스 럽 게 할 수 있다.왜?의 미 를 보존 하지 않 기 때문이다.이 는 제품 유형 B 를 나타 내 는 도형 요 소 를 유형 C 를 대표 하 는 도형 요소 로 바 꾸 고 C 의 도형 요 소 를 다른 곳 으로 바 꿉 니 다.바로 2016 B 가 마침 2017 C 이후 에 나타 난 같은 위치 이기 때문에 전자 가 후자 가 되 어야 한 다 는 것 을 의미 하지 않 는 다.반면 2016 년 에는 B 가 없어 져 야 하고 2016 년 에는 C 가 2017 년 까지 왼쪽으로 이동 해 야 하 며 2017 년 에는 D 가 오른쪽 에 나타 나 야 한다.우 리 는 전통 적 인 통합 정렬 목록 을 사용 하여 이러한 혼합 을 실현 할 수 있다.
우 리 는 각 선형 에 서로 다른 색깔 을 주 고 색깔 로 판매 하 는 제품 을 구분 할 수 있다.한 가지 색깔 은 한 제품 을 대표 한다.한 가지 색깔 이 사라 지면 이 제품 이 이미 내 려 갔다 는 것 을 설명 하고,반대로 신제품 이 이미 출시 되 었 다 는 것 을 설명 한다.
의미 에 대응 하 는 구성 요 소 를 통 해 복합 값 간 의 선형 플러그 인(lerp)을 진행 합 니 다.구성 요소 가 정렬 목록 을 만 들 때 병합 알고리즘 은 이 구성 요 소 를 측면 에 두 고 보이 지 않 는 구성 요 소 를 사용 하여 단면 합병 을 처리 할 수 있 습 니 다.우리 가 필요 로 하 는 것 은 Bar 실례 를 선형 순서 로 서로 비교 하 는 것 이다.그리고 우 리 는 그것들 을 합병 할 수 있다.
// ...
class BarChart {
// ...
factory BarChart.random(Size size, Random random) {
const barWidthFraction = 0.75;
final ranks = selectRanks(random, ColorPalette.primary.length);
final barCount = ranks.length;
final barDistance = size.width / (1+barCount);
final barWidth = barDistance * barWidthFraction;
final startX = barDistance - barWidth/2;
final bars = new List.generate(
barCount,
(i)=> new Bar(
ranks[i],
startX + i * barDistance,
barWidth,
random.nextDouble() * size.height,
ColorPalette.primary[ranks[i]],
),
);
return new BarChart(bars);
}
static List<int> selectRanks(Random random, int cap) {
final ranks = <int>[];
var rank = 0;
while(true) {
//
if(random.nextDouble() < 0.2) rank++;
if(cap <= rank) break;
ranks.add(rank);
rank++;
}
return ranks;
}
static BarChart lerp(BarChart begin, BarChart end, double t) {
final bars = <Bar>[];
final bMax = begin.bars.length;
final eMax = end.bars.length;
var b = 0;
var e = 0;
while (b + e < bMax + eMax) {
/*
b < bMax && e == eMax:
b < bMax && begin.bars[b] < end.bars[e]:
, ,
*/
if(b < bMax && (e == eMax || begin.bars[b] < end.bars[e])) {
bars.add(Bar.lerp(begin.bars[b], begin.bars[b].collapsed, t));
b++;
/*
e < eMax && b == bMax:
e < eMax && end.bars[e] < begin.bars[b]:
, ,
*/
} else if(e < eMax && (b == bMax || end.bars[e] < begin.bars[b])) {
bars.add(Bar.lerp(end.bars[e].collapsed, end.bars[e], t));
e++;
// ,
} else {
bars.add(Bar.lerp(begin.bars[b], end.bars[e], t));
b++;
e++;
}
}
return new BarChart(bars);
}
}
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.rank, this.x, this.width, this.height, this.color);
final int rank;
final double x;
final double width;
final double height;
final Color color;
Bar get collapsed => new Bar(rank, x, 0.0, 0.0, color);
/*
bool operator <(
Duration other
)
Duration other , true
bool operator <(Duration other) => this._duration < other._duration;
*/
bool operator <(Bar other) => rank < other.rank;
static Bar lerp(Bar begin, Bar end, double t) {
assert(begin.rank == end.rank);
return new Bar(
begin.rank,
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) {
assert(begin.rank == end.rank);
}
@override
Bar lerp(double t) => Bar.lerp(begin, end, t);
}
// ...
구체 적 으로 말 하면,우 리 는 정수 rank 속성의 형식 으로 각 선형 에 정렬 키 를 분배 할 것 이다.그 다음 에 rank 을 편리 하 게 사용 하여 팔레트 에서 모든 스 트 라 이 프 의 색 을 분배 하여 애니메이션 프레젠테이션 에서 각 스 트 라 이 프 의 이동 을 추적 할 수 있 습 니 다.무 작위 막대 그래프 는 현재 무 작위 로 선택 한 행렬 을 기반 으로 합 니 다.
그러나 이것 은 가장 효과 적 인 해결 방안 이 아 닙 니 다.저 희 는 BarChart.lerp 에서 합병 알고리즘 을 반복 적 으로 실행 하고 있 습 니 다.t 의 모든 값 에 대해 한 번 씩 실행 합 니 다.이 문 제 를 해결 하기 위해 서 는 BarChart Tween 에 재 활용 가능 한 정 보 를 저장 할 수 있 도록 앞의 글 에서 언급 한 아 이 디 어 를 실현 할 것 입 니 다.
// ...
class BarChartTween extends Tween<BarChart> {
final _tweens = <BarTween>[];
BarChartTween(BarChart begin, BarChart end) : super(begin: begin, end: end) {
final bMax = begin.bars.length;
final eMax = end.bars.length;
var b = 0;
var e = 0;
while (b + e < bMax + eMax) {
if(b < bMax && (e == eMax || begin.bars[b] < end.bars[e])) {
_tweens.add(new BarTween(begin.bars[b], begin.bars[b].collapsed));
b++;
} else if(e < eMax && (b == bMax || end.bars[e] < begin.bars[b])) {
_tweens.add(new BarTween(end.bars[e].collapsed, end.bars[e]));
e++;
} else {
_tweens.add(new BarTween(begin.bars[b], end.bars[e]));
b++;
e++;
}
}
}
@override
BarChart lerp(double t) => new BarChart(
new List.generate(
_tweens.length,
(i) => _tweens[i].lerp(t))
);
}
// ...
그리고 우 리 는 정적 인 BarChart.lerp 방법 을 삭제 할 수 있 습 니 다.이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Flutter】DateTime 전월의 일수를 취득한다달의 일수를 취득할 필요가 있어, 의외로 수요 있을까라고 생각했으므로 비망록 정도에 남겨 둡니다. DateTime 날짜에 0을 입력하면 전월 DateTime이 됩니다. 2021년 3월 0일 = 2021년 2월 28일...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.