public void pull(float overscroll, float extent, float crossAxisOffset, float crossExtent) { _pullRecedeTimer?.cancel(); _pullDistance += overscroll / 200.0f; // This factor is magic. Not clear why we need it to match Android. _glowOpacityTween.begin = _glowOpacity.value; _glowOpacityTween.end = Mathf.Min(_glowOpacity.value + overscroll / extent * _pullOpacityGlowFactor, _maxOpacity); float height = Mathf.Min(extent, crossExtent * _widthToHeightFactor); _glowSizeTween.begin = _glowSize.value; _glowSizeTween.end = Mathf.Max(1.0f - 1.0f / (0.7f * Mathf.Sqrt(_pullDistance * height)), _glowSize.value); _displacementTarget = crossAxisOffset / crossExtent; if (_displacementTarget != _displacement) { if (!_displacementTicker.isTicking) { D.assert(_displacementTickerLastElapsed == null); _displacementTicker.start(); } } else { _displacementTicker.stop(); _displacementTickerLastElapsed = null; } _glowController.duration = _pullTime; if (_state != _GlowState.pull) { _glowController.forward(from: 0.0f); _state = _GlowState.pull; } else { if (!_glowController.isAnimating) { D.assert(_glowController.value == 1.0f); notifyListeners(); } } _pullRecedeTimer = Timer.create(_pullHoldTime, () => { _recede(_pullDecayTime); return(null); }); }
public void absorbImpact(float velocity) { D.assert(velocity >= 0.0f); _pullRecedeTimer?.cancel(); _pullRecedeTimer = null; velocity = velocity.clamp(_minVelocity, _maxVelocity); _glowOpacityTween.begin = _state == _GlowState.idle ? 0.3f : _glowOpacity.value; _glowOpacityTween.end = (velocity * _velocityGlowFactor).clamp(_glowOpacityTween.begin, _maxOpacity); _glowSizeTween.begin = _glowSize.value; _glowSizeTween.end = Mathf.Min(0.025f + 7.5e-7f * velocity * velocity, 1.0f); _glowController.duration = new TimeSpan(0, 0, 0, 0, (0.15f + velocity * 0.02f).round()); _glowController.forward(from: 0.0f); _displacement = 0.5f; _state = _GlowState.absorb; }
void _recede(TimeSpan duration) { if (_state == _GlowState.recede || _state == _GlowState.idle) { return; } _pullRecedeTimer?.cancel(); _pullRecedeTimer = null; _glowOpacityTween.begin = _glowOpacity.value; _glowOpacityTween.end = 0.0f; _glowSizeTween.begin = _glowSize.value; _glowSizeTween.end = 0.0f; _glowController.duration = duration; _glowController.forward(from: 0.0f); _state = _GlowState.recede; }
void _changePhase(AnimationStatus status) { if (status != AnimationStatus.completed) { return; } switch (_state) { case _GlowState.absorb: _recede(_recedeTime); break; case _GlowState.recede: _state = _GlowState.idle; _pullDistance = 0.0f; break; case _GlowState.pull: case _GlowState.idle: break; } }