Skip to content

Instantly share code, notes, and snippets.

@dgkanatsios
Created July 25, 2014 18:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dgkanatsios/5991f60daa1b30f03280 to your computer and use it in GitHub Desktop.
Save dgkanatsios/5991f60daa1b30f03280 to your computer and use it in GitHub Desktop.
A XAML Behavior for a small tap animation for Windows Phone, allows for an event to run after the Storyboard is completed
public class TapAction : Behavior<FrameworkElement>
{
public string EventAfterStoryboard
{
get { return (string)GetValue(EventAfterStoryboardProperty); }
set { SetValue(EventAfterStoryboardProperty, value); }
}
// Using a DependencyProperty as the backing store for EventAfterStoryboard. This enables animation, styling, binding, etc...
public static readonly DependencyProperty EventAfterStoryboardProperty =
DependencyProperty.Register("EventAfterStoryboard", typeof(string), typeof(TapAction), new PropertyMetadata(null));
public object Tag
{
get { return (object)GetValue(TagProperty); }
set { SetValue(TagProperty, value); }
}
// Using a DependencyProperty as the backing store for Tag. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TagProperty =
DependencyProperty.Register("Tag", typeof(object), typeof(TapAction), new PropertyMetadata(null));
public int AnimationDuration
{
get { return (int)GetValue(AnimationDurationProperty); }
set { SetValue(AnimationDurationProperty, value); }
}
// Using a DependencyProperty as the backing store for AnimationDuration. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AnimationDurationProperty =
DependencyProperty.Register("AnimationDuration", typeof(int), typeof(TapAction), new PropertyMetadata(300));
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Tap += AssociatedObject_Tap;
}
Storyboard sb;
void AssociatedObject_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
if (sb != null)
{
sb.Stop();
sb = null;
}
sb = CreateTapFeedbackStoryboard(AssociatedObject, true, AnimationDuration);
if (EventAfterStoryboard != null)
sb.Completed += (se, ev) =>
{
FrameworkElement dob = AssociatedObject.Parent as FrameworkElement;
while (!(dob is PhoneApplicationPage))
{
dob = dob.Parent as FrameworkElement;
}
if(Tag == null)
dob.GetType().GetMethod(EventAfterStoryboard, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Invoke(dob, null);
else
dob.GetType().GetMethod(EventAfterStoryboard, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Invoke(dob, new object[]{Tag});
};
sb.Begin();
}
protected override void OnDetaching()
{
base.OnDetaching();
if (sb != null)
{
sb.Stop();
sb = null;
}
AssociatedObject.Tap -= AssociatedObject_Tap;
}
//this animates scale, feel free to change it to whatever you like
public static Storyboard CreateTapFeedbackStoryboard(FrameworkElement AssociatedObject, bool ignorePreviousScale=false, int duration=300)
{
Storyboard sb = new Storyboard();
double originalScaleX = 1;
double originalScaleY = 1;
if (AssociatedObject.RenderTransform is MatrixTransform)
AssociatedObject.RenderTransform = new CompositeTransform();
else if (AssociatedObject.RenderTransform is CompositeTransform && !ignorePreviousScale)
{
originalScaleX = (AssociatedObject.RenderTransform as CompositeTransform).ScaleX;
originalScaleY = (AssociatedObject.RenderTransform as CompositeTransform).ScaleY;
}
AssociatedObject.RenderTransformOrigin = new Point(0.5, 0.5);
DoubleAnimationUsingKeyFrames scaleAnimation = new DoubleAnimationUsingKeyFrames();
DoubleKeyFrame keyframe1 = new EasingDoubleKeyFrame();
keyframe1.KeyTime = TimeSpan.FromMilliseconds((int)(duration/2));
keyframe1.Value = originalScaleX + 0.2;
DoubleKeyFrame keyframe2 = new EasingDoubleKeyFrame();
keyframe2.KeyTime = TimeSpan.FromMilliseconds(duration);
keyframe2.Value = originalScaleX;
scaleAnimation.KeyFrames.Add(keyframe1); scaleAnimation.KeyFrames.Add(keyframe2);
DoubleAnimationUsingKeyFrames scaleAnimation2 = new DoubleAnimationUsingKeyFrames();
DoubleKeyFrame keyframe11 = new EasingDoubleKeyFrame();
keyframe11.KeyTime = TimeSpan.FromMilliseconds((int)(duration/2));
keyframe11.Value = originalScaleY + 0.2;
DoubleKeyFrame keyframe21 = new EasingDoubleKeyFrame();
keyframe21.KeyTime = TimeSpan.FromMilliseconds(duration);
keyframe21.Value = originalScaleY;
scaleAnimation2.KeyFrames.Add(keyframe11); scaleAnimation2.KeyFrames.Add(keyframe21);
Storyboard.SetTarget(scaleAnimation, AssociatedObject);
Storyboard.SetTarget(scaleAnimation2, AssociatedObject);
Storyboard.SetTargetProperty(scaleAnimation, new PropertyPath("(FrameworkElement.RenderTransform).(CompositeTransform.ScaleX)"));
Storyboard.SetTargetProperty(scaleAnimation2, new PropertyPath("(FrameworkElement.RenderTransform).(CompositeTransform.ScaleY)"));
sb.Children.Add(scaleAnimation);
sb.Children.Add(scaleAnimation2);
return sb;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment