Skip to content

Ramin/animate_to_current_tick #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ captures/
.idea/modules.xml
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
.idea/navEditor.xml
.idea/codeStyles

# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
Expand Down
45 changes: 37 additions & 8 deletions lib/src/chart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,16 @@ class _ChartState extends State<Chart> with TickerProviderStateMixin {
AnimationController _loadingAnimationController;
AnimationController _topBoundQuoteAnimationController;
AnimationController _bottomBoundQuoteAnimationController;
AnimationController _rightEpochAnimationController;
Animation _currentTickAnimation;
Animation _currentTickBlinkAnimation;

bool get _shouldAutoPan => rightBoundEpoch > nowEpoch;

bool get _arrowButtonBeVisible =>
!_shouldAutoPan &&
!(_rightEpochAnimationController?.isAnimating ?? false);

double get _topBoundQuote => _topBoundQuoteAnimationController.value;

double get _bottomBoundQuote => _bottomBoundQuoteAnimationController.value;
Expand Down Expand Up @@ -129,19 +134,20 @@ class _ChartState extends State<Chart> with TickerProviderStateMixin {

if (oldGranularity != newGranularity) {
msPerPx = _getDefaultScale(newGranularity);
_scrollToNow();
rightBoundEpoch = nowEpoch + _pxToMs(maxCurrentTickOffset);
} else {
_onNewTick();
}
}

@override
void dispose() {
_currentTickAnimationController.dispose();
_currentTickBlinkingController.dispose();
_loadingAnimationController.dispose();
_topBoundQuoteAnimationController.dispose();
_bottomBoundQuoteAnimationController.dispose();
_rightEpochAnimationController?.dispose();
_currentTickAnimationController?.dispose();
_currentTickBlinkingController?.dispose();
_loadingAnimationController?.dispose();
_topBoundQuoteAnimationController?.dispose();
_bottomBoundQuoteAnimationController?.dispose();
super.dispose();
}

Expand Down Expand Up @@ -170,6 +176,16 @@ class _ChartState extends State<Chart> with TickerProviderStateMixin {
_setupCurrentTickAnimation();
_setupBlinkingAnimation();
_setupBoundsAnimation();
_setupRightEpochAnimation();
}

void _setupRightEpochAnimation() {
_rightEpochAnimationController = AnimationController.unbounded(
vsync: this,
value: rightBoundEpoch.toDouble(),
)..addListener(() {
rightBoundEpoch = _rightEpochAnimationController.value.toInt();
});
}

void _setupCurrentTickAnimation() {
Expand Down Expand Up @@ -333,7 +349,7 @@ class _ChartState extends State<Chart> with TickerProviderStateMixin {
);
}),
),
if (!_shouldAutoPan)
if (_arrowButtonBeVisible)
Positioned(
bottom: 30 + timeLabelsAreaHeight,
right: 30 + quoteLabelsAreaWidth,
Expand Down Expand Up @@ -447,7 +463,20 @@ class _ChartState extends State<Chart> with TickerProviderStateMixin {
}

void _scrollToNow() {
rightBoundEpoch = nowEpoch + _pxToMs(maxCurrentTickOffset);
final animationMsDuration = 600;
final lowerBound = rightBoundEpoch.toDouble();
final upperBound = nowEpoch +
_pxToMs(maxCurrentTickOffset).toDouble() +
animationMsDuration;

if (upperBound > lowerBound) {
_rightEpochAnimationController.value = lowerBound;
_rightEpochAnimationController.animateTo(
upperBound,
curve: Curves.easeOut,
duration: Duration(milliseconds: animationMsDuration),
);
}
}

void _onScaleAndPanEnd(ScaleEndDetails details) {
Expand Down