Praveen
Praveen

Reputation: 49

Animate thumb of UWP Slider

I am using the Slider XAML control in my UWP app. Whenever we tap on the slider and change its value, I want the slider thumb to simply show a translation animation while moving from the old position to the new position. How can this be achieved?

Upvotes: 0

Views: 350

Answers (1)

lindexi
lindexi

Reputation: 4327

You can use a property to get the last value and play an animation to set the value from the last vale to current value.

Adding a Slider in xaml

    <Slider x:Name="Slider" Value="{x:Bind Value,Mode=TwoWay}"/>

Adding a DependencyProperty in MainPage.

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
        "Value", typeof(double), typeof(MainPage), new PropertyMetadata(default(double), (s
            , e) =>
        {
            ((MainPage) s)._lastValue = (double) e.OldValue;
        }));

    public double Value
    {
        get => (double) GetValue(ValueProperty);
        set => SetValue(ValueProperty, value);
    }

    private double _lastValue;

The Value can set the _lastValue that can begin the Storyboard

Adding PointerPressedEvent and PointerReleasedEvent in MainPage code for the Slider will handle it.

    public MainPage()
    {
        InitializeComponent();
        Slider.AddHandler(PointerPressedEvent, new PointerEventHandler(Slider_OnPointerPressed), true);
        Slider.AddHandler(PointerReleasedEvent, new PointerEventHandler(Slider_OnPointerReleased), true);
    }

I save the ClickPoint in Slider_OnPointerPressed and I compare the current point in Slider_OnPointerReleased. The user may click the Slider that should begin the animation and the user drag the thumb that should not begin the animation.

    private void Slider_OnPointerPressed(object sender, PointerRoutedEventArgs e)
    {
        var slider = (Slider) sender;

        ClickPoint = e.GetCurrentPoint(slider).Position;
    }

    private Point ClickPoint { set; get; }

    private void Slider_OnPointerReleased(object sender, PointerRoutedEventArgs e)
    {
        var slider = (Slider) sender;

        var point = e.GetCurrentPoint(slider).Position;

        var x = point.X - ClickPoint.X;
        var y = point.Y - ClickPoint.Y;
        var length = x * x + y * y;
        if (length < 10)
        {
            AnimationValue();
        }
    }

The AnimationValue will begin the animation.

    private void AnimationValue()
    {
        var storyboard = new Storyboard();

        var animation = new DoubleAnimation
        {
            From = _lastValue,
            To = Value,
            Duration = TimeSpan.FromSeconds(2),
            EasingFunction = new CubicEase(),
            EnableDependentAnimation = true
        };

        Storyboard.SetTarget(animation, Slider);
        Storyboard.SetTargetProperty(animation, "Value");

        storyboard.BeginTime = TimeSpan.Zero;
        storyboard.Children.Add(animation);

        storyboard.Begin();

        _storyboard = storyboard;
    }

You can custom the Duration and EasingFunction to change the time.

All code in github

If you can read Chinese, please read my blog because my English is very poor, I am worried that I can’t tell you exactly what I mean.

Upvotes: 2

Related Questions