in src/Avalonia.Controls/PullToRefresh/RefreshVisualizer.cs [194:303]
private void UpdateContent()
{
if (_content != null && _root != null)
{
var root = _root;
var visual = _refreshInfoProvider?.Visual;
var contentVisual = ElementComposition.GetElementVisual(_content);
var visualizerVisual = ElementComposition.GetElementVisual(this);
if (visual != null && contentVisual != null && visualizerVisual != null)
{
contentVisual.CenterPoint = new Vector3D((_content.Bounds.Width / 2), (_content.Bounds.Height / 2), 0);
switch (RefreshVisualizerState)
{
case RefreshVisualizerState.Idle:
_played = false;
if(_rotateAnimation != null)
{
_rotateAnimation.IterationBehavior = AnimationIterationBehavior.Count;
_rotateAnimation = null;
}
contentVisual.Opacity = MinimumIndicatorOpacity;
contentVisual.RotationAngle = _startingRotationAngle;
visualizerVisual.Offset = IsPullDirectionVertical ?
new Vector3D(visualizerVisual.Offset.X, 0, 0) :
new Vector3D(0, visualizerVisual.Offset.Y, 0);
visual.Offset = visualizerVisual.Offset;
_content.InvalidateMeasure();
break;
case RefreshVisualizerState.Interacting:
_played = false;
contentVisual.Opacity = MinimumIndicatorOpacity;
contentVisual.RotationAngle = (float)(_startingRotationAngle + _interactionRatio * 2 * Math.PI);
Vector3D offset = default;
if (IsPullDirectionVertical)
{
offset = new Vector3D(0, (_interactionRatio * (IsPullDirectionFar ? -1 : 1) * root.Bounds.Height), 0);
}
else
{
offset = new Vector3D((_interactionRatio * (IsPullDirectionFar ? -1 : 1) * root.Bounds.Width), 0, 0);
}
visual.Offset = offset;
visualizerVisual.Offset = IsPullDirectionVertical ?
new Vector3D(visualizerVisual.Offset.X, offset.Y, 0) :
new Vector3D(offset.X, visualizerVisual.Offset.Y, 0);
break;
case RefreshVisualizerState.Pending:
contentVisual.Opacity = 1;
contentVisual.RotationAngle = _startingRotationAngle + (float)(2 * Math.PI);
if (IsPullDirectionVertical)
{
offset = new Vector3D(0, (_interactionRatio * (IsPullDirectionFar ? -1 : 1) * root.Bounds.Height), 0);
}
else
{
offset = new Vector3D((_interactionRatio * (IsPullDirectionFar ? -1 : 1) * root.Bounds.Width), 0, 0);
}
visual.Offset = offset;
visualizerVisual.Offset = IsPullDirectionVertical ?
new Vector3D(visualizerVisual.Offset.X, offset.Y, 0) :
new Vector3D(offset.X, visualizerVisual.Offset.Y, 0);
if (!_played)
{
_played = true;
var scaleAnimation = contentVisual.Compositor!.CreateVector3KeyFrameAnimation();
scaleAnimation.Target = "Scale";
scaleAnimation.InsertKeyFrame(0.5f, new Vector3(1.5f, 1.5f, 1));
scaleAnimation.InsertKeyFrame(1f, new Vector3(1f, 1f, 1));
scaleAnimation.Duration = TimeSpan.FromSeconds(0.3);
contentVisual.StartAnimation("Scale", scaleAnimation);
}
break;
case RefreshVisualizerState.Refreshing:
_rotateAnimation = contentVisual.Compositor!.CreateScalarKeyFrameAnimation();
_rotateAnimation.Target = "RotationAngle";
_rotateAnimation.InsertKeyFrame(0, _startingRotationAngle, new LinearEasing());
_rotateAnimation.InsertKeyFrame(1, _startingRotationAngle + (float)(2 * Math.PI), new LinearEasing());
_rotateAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
_rotateAnimation.StopBehavior = AnimationStopBehavior.LeaveCurrentValue;
_rotateAnimation.Duration = TimeSpan.FromSeconds(0.5);
contentVisual.StartAnimation("RotationAngle", _rotateAnimation);
contentVisual.Opacity = 1;
float translationRatio = (float)(_refreshInfoProvider != null ? (1.0f - _refreshInfoProvider.ExecutionRatio) * ParallaxPositionRatio : 1.0f)
* (IsPullDirectionFar ? -1f : 1f);
if (IsPullDirectionVertical)
{
offset = new Vector3D(0, (_executingRatio * (IsPullDirectionFar ? -1 : 1) * root.Bounds.Height), 0);
}
else
{
offset = new Vector3D((_executingRatio * (IsPullDirectionFar ? -1 : 1) * root.Bounds.Width), 0, 0);
}
visual.Offset = offset;
contentVisual.Offset += IsPullDirectionVertical ? new Vector3D(0, (translationRatio * root.Bounds.Height), 0) :
new Vector3D((translationRatio * root.Bounds.Width), 0, 0);
visualizerVisual.Offset = IsPullDirectionVertical ?
new Vector3D(visualizerVisual.Offset.X, offset.Y, 0) :
new Vector3D(offset.X, visualizerVisual.Offset.Y, 0);
break;
case RefreshVisualizerState.Peeking:
contentVisual.Opacity = 1;
contentVisual.RotationAngle = _startingRotationAngle;
break;
}
}
}
}