Created
July 21, 2018 15:09
-
-
Save arthurrump/43c2b18e638ff380da4c579f72d525ab to your computer and use it in GitHub Desktop.
Animated GridViewItem with Windows.UI.Composition https://www.arthurrump.com/2018/07/21/animating-gridviewitems-with-windows-ui-composition-aka-the-visual-layer/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ResourceDictionary | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> | |
<Style TargetType="GridViewItem" x:Key="BorderlessGridViewItem" BasedOn="{StaticResource GridViewItemExpanded}"> | |
<Setter Property="Template"> | |
<Setter.Value> | |
<ControlTemplate TargetType="GridViewItem"> | |
<Grid x:Name="ContentBorder" | |
Control.IsTemplateFocusTarget="True" | |
FocusVisualMargin="{TemplateBinding FocusVisualMargin}" | |
Background="{TemplateBinding Background}" | |
BorderBrush="{TemplateBinding BorderBrush}" | |
BorderThickness="{TemplateBinding BorderThickness}" | |
RenderTransformOrigin="0.5,0.5"> | |
<Grid.RenderTransform> | |
<ScaleTransform x:Name="ContentBorderScale" /> | |
</Grid.RenderTransform> | |
<VisualStateManager.VisualStateGroups> | |
<VisualStateGroup x:Name="FocusStates"> | |
<VisualState x:Name="Focused" /> | |
<VisualState x:Name="Unfocused" /> | |
</VisualStateGroup> | |
<VisualStateGroup x:Name="CommonStates"> | |
<VisualState x:Name="Normal"> | |
<Storyboard> | |
<PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="PointerOver"> | |
<Storyboard> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlForegroundBaseHighBrush}" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="FocusVisualSecondaryBrush"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListLowBrush}" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="FocusVisualSecondaryThickness"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="2" /> | |
</ObjectAnimationUsingKeyFrames> | |
<PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="Pressed"> | |
<Storyboard> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlForegroundBaseHighBrush}" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="FocusVisualSecondaryBrush"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListMediumBrush}" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="FocusVisualSecondaryThickness"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="2" /> | |
</ObjectAnimationUsingKeyFrames> | |
<PointerDownThemeAnimation TargetName="ContentPresenter" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="Selected"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="MultiSelectCheck" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="1" /> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlForegroundBaseHighBrush}" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="FocusVisualSecondaryBrush"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentBrush}" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="FocusVisualSecondaryThickness"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="2" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="Background"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentBrush}" /> | |
</ObjectAnimationUsingKeyFrames> | |
<PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="PointerOverSelected"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="MultiSelectCheck" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="1" /> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlForegroundBaseHighBrush}" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="FocusVisualSecondaryBrush"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListAccentMediumBrush}" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="FocusVisualSecondaryThickness"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="2" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="Background"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentBrush}" /> | |
</ObjectAnimationUsingKeyFrames> | |
<PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="PressedSelected"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="MultiSelectCheck" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="1" /> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlForegroundBaseHighBrush}" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="FocusVisualSecondaryBrush"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListAccentHighBrush}" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="FocusVisualSecondaryThickness"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="2" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="Background"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentBrush}" /> | |
</ObjectAnimationUsingKeyFrames> | |
<PointerDownThemeAnimation TargetName="ContentPresenter" /> | |
</Storyboard> | |
</VisualState> | |
</VisualStateGroup> | |
<VisualStateGroup x:Name="DisabledStates"> | |
<VisualState x:Name="Enabled" /> | |
<VisualState x:Name="Disabled"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="ContentBorder" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="{ThemeResource ListViewItemDisabledThemeOpacity}" /> | |
</Storyboard> | |
</VisualState> | |
</VisualStateGroup> | |
<VisualStateGroup x:Name="MultiSelectStates"> | |
<VisualState x:Name="MultiSelectDisabled"> | |
<Storyboard> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="Visibility"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> | |
<DiscreteObjectKeyFrame KeyTime="0:0:0.333" Value="Collapsed" /> | |
</ObjectAnimationUsingKeyFrames> | |
<FadeOutThemeAnimation TargetName="MultiSelectSquare" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="MultiSelectEnabled"> | |
<Storyboard> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="Visibility"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> | |
</ObjectAnimationUsingKeyFrames> | |
<FadeInThemeAnimation TargetName="MultiSelectSquare" /> | |
</Storyboard> | |
</VisualState> | |
</VisualStateGroup> | |
<VisualStateGroup x:Name="DataVirtualizationStates"> | |
<VisualState x:Name="DataAvailable" /> | |
<VisualState x:Name="DataPlaceholder"> | |
<Storyboard> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextBlock" Storyboard.TargetProperty="Visibility"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> | |
</ObjectAnimationUsingKeyFrames> | |
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderRect" Storyboard.TargetProperty="Visibility"> | |
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> | |
</ObjectAnimationUsingKeyFrames> | |
</Storyboard> | |
</VisualState> | |
</VisualStateGroup> | |
<VisualStateGroup x:Name="ReorderHintStates"> | |
<VisualState x:Name="NoReorderHint" /> | |
<VisualState x:Name="BottomReorderHint"> | |
<Storyboard> | |
<DragOverThemeAnimation TargetName="ContentBorder" ToOffset="{ThemeResource GridViewItemReorderHintThemeOffset}" Direction="Bottom" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="TopReorderHint"> | |
<Storyboard> | |
<DragOverThemeAnimation TargetName="ContentBorder" ToOffset="{ThemeResource GridViewItemReorderHintThemeOffset}" Direction="Top" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="RightReorderHint"> | |
<Storyboard> | |
<DragOverThemeAnimation TargetName="ContentBorder" ToOffset="{ThemeResource GridViewItemReorderHintThemeOffset}" Direction="Right" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="LeftReorderHint"> | |
<Storyboard> | |
<DragOverThemeAnimation TargetName="ContentBorder" ToOffset="{ThemeResource GridViewItemReorderHintThemeOffset}" Direction="Left" /> | |
</Storyboard> | |
</VisualState> | |
<VisualStateGroup.Transitions> | |
<VisualTransition To="NoReorderHint" GeneratedDuration="0:0:0.2" /> | |
</VisualStateGroup.Transitions> | |
</VisualStateGroup> | |
<VisualStateGroup x:Name="DragStates"> | |
<VisualState x:Name="NotDragging" /> | |
<VisualState x:Name="Dragging"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="ContentBorder" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="{ThemeResource ListViewItemDragThemeOpacity}" /> | |
<DragItemThemeAnimation TargetName="ContentBorder" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="DraggingTarget" /> | |
<VisualState x:Name="MultipleDraggingPrimary"> | |
<Storyboard> | |
<!-- These two Opacity animations are required - the FadeInThemeAnimations | |
on the same elements animate an internal Opacity. --> | |
<DoubleAnimation Storyboard.TargetName="MultiArrangeOverlayText" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="1" /> | |
<DoubleAnimation Storyboard.TargetName="MultiArrangeOverlayTextBorder" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="1" /> | |
<DoubleAnimation Storyboard.TargetName="MultiSelectSquare" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="0" /> | |
<DoubleAnimation Storyboard.TargetName="MultiSelectCheck" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="0" /> | |
<DoubleAnimation Storyboard.TargetName="ContentBorder" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="{ThemeResource ListViewItemDragThemeOpacity}" /> | |
<FadeInThemeAnimation TargetName="MultiArrangeOverlayText" /> | |
<FadeInThemeAnimation TargetName="MultiArrangeOverlayTextBorder" /> | |
<DragItemThemeAnimation TargetName="ContentBorder" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="MultipleDraggingSecondary" /> | |
<VisualState x:Name="DraggedPlaceholder" /> | |
<VisualState x:Name="Reordering"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="ContentBorder" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0:0:0.240" | |
To="{ThemeResource ListViewItemReorderThemeOpacity}" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="ReorderingTarget"> | |
<Storyboard> | |
<DoubleAnimation Storyboard.TargetName="ContentBorder" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0:0:0.240" | |
To="{ThemeResource ListViewItemReorderTargetThemeOpacity}" /> | |
<DoubleAnimation Storyboard.TargetName="ContentBorderScale" | |
Storyboard.TargetProperty="ScaleX" | |
Duration="0:0:0.240" | |
To="{ThemeResource ListViewItemReorderTargetThemeScale}" /> | |
<DoubleAnimation Storyboard.TargetName="ContentBorderScale" | |
Storyboard.TargetProperty="ScaleY" | |
Duration="0:0:0.240" | |
To="{ThemeResource ListViewItemReorderTargetThemeScale}" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="MultipleReorderingPrimary"> | |
<Storyboard> | |
<!-- These two Opacity animations are required - the FadeInThemeAnimations | |
on the same elements animate an internal Opacity. --> | |
<DoubleAnimation Storyboard.TargetName="MultiArrangeOverlayText" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="1" /> | |
<DoubleAnimation Storyboard.TargetName="MultiArrangeOverlayTextBorder" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="1" /> | |
<DoubleAnimation Storyboard.TargetName="MultiSelectSquare" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="0" /> | |
<DoubleAnimation Storyboard.TargetName="MultiSelectCheck" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0" | |
To="0" /> | |
<DoubleAnimation Storyboard.TargetName="ContentBorder" | |
Storyboard.TargetProperty="Opacity" | |
Duration="0:0:0.240" | |
To="{ThemeResource ListViewItemDragThemeOpacity}" /> | |
<FadeInThemeAnimation TargetName="MultiArrangeOverlayText" /> | |
<FadeInThemeAnimation TargetName="MultiArrangeOverlayTextBorder" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="ReorderedPlaceholder"> | |
<Storyboard> | |
<FadeOutThemeAnimation TargetName="ContentBorder" /> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="DragOver"> | |
<Storyboard> | |
<DropTargetItemThemeAnimation TargetName="ContentBorder" /> | |
</Storyboard> | |
</VisualState> | |
<VisualStateGroup.Transitions> | |
<VisualTransition To="NotDragging" GeneratedDuration="0:0:0.2" /> | |
</VisualStateGroup.Transitions> | |
</VisualStateGroup> | |
</VisualStateManager.VisualStateGroups> | |
<ContentPresenter x:Name="ContentPresenter" | |
ContentTransitions="{TemplateBinding ContentTransitions}" | |
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" | |
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" | |
Margin="{TemplateBinding Padding}" /> | |
<!-- The 'Xg' text simulates the amount of space one line of text will occupy. | |
In the DataPlaceholder state, the Content is not loaded yet so we | |
approximate the size of the item using placeholder text. --> | |
<TextBlock x:Name="PlaceholderTextBlock" | |
Visibility="Collapsed" | |
Text="Xg" | |
Foreground="{x:Null}" | |
Margin="{TemplateBinding Padding}" | |
IsHitTestVisible="False" | |
AutomationProperties.AccessibilityView="Raw" /> | |
<Rectangle x:Name="PlaceholderRect" Visibility="Collapsed" Fill="{ThemeResource ListViewItemPlaceholderBackground}" /> | |
<Border x:Name="MultiSelectSquare" | |
Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" | |
Width="20" | |
Height="20" | |
Margin="0,2,2,0" | |
VerticalAlignment="Top" | |
HorizontalAlignment="Right" | |
Visibility="Collapsed"> | |
<FontIcon x:Name="MultiSelectCheck" | |
FontFamily="{ThemeResource SymbolThemeFontFamily}" | |
Glyph="" | |
FontSize="16" | |
Foreground="{ThemeResource SystemControlForegroundBaseMediumHighBrush}" | |
Opacity="0" /> | |
</Border> | |
<Border x:Name="MultiArrangeOverlayTextBorder" | |
Opacity="0" | |
IsHitTestVisible="False" | |
MinWidth="20" | |
Height="20" | |
VerticalAlignment="Center" | |
HorizontalAlignment="Center" | |
Background="{ThemeResource SystemControlBackgroundAccentBrush}" | |
BorderThickness="2" | |
BorderBrush="{ThemeResource SystemControlBackgroundChromeWhiteBrush}"> | |
<TextBlock x:Name="MultiArrangeOverlayText" | |
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DragItemsCount}" | |
Style="{ThemeResource CaptionTextBlockStyle}" | |
IsHitTestVisible="False" | |
Opacity="0" | |
VerticalAlignment="Center" | |
HorizontalAlignment="Center" | |
AutomationProperties.AccessibilityView="Raw" /> | |
</Border> | |
</Grid> | |
</ControlTemplate> | |
</Setter.Value> | |
</Setter> | |
</Style> | |
</ResourceDictionary> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Page | |
x:Class="CompositionTrials.MainPage" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:local="using:CompositionTrials" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
mc:Ignorable="d" | |
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> | |
<Page.Resources> | |
<ResourceDictionary Source="BorderlessGridViewItem.xaml" /> | |
</Page.Resources> | |
<Grid> | |
<GridView SelectionMode="None" IsItemClickEnabled="True" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="16"> | |
<GridView.ItemContainerStyle> | |
<Style TargetType="GridViewItem" BasedOn="{StaticResource BorderlessGridViewItem}"> | |
<Setter Property="Margin" Value="6" /> | |
</Style> | |
</GridView.ItemContainerStyle> | |
<GridView.Items> | |
<SolidColorBrush Color="LightSkyBlue" /> | |
<SolidColorBrush Color="LightGreen" /> | |
<SolidColorBrush Color="LightSalmon" /> | |
</GridView.Items> | |
<GridView.ItemTemplate> | |
<DataTemplate> | |
<Grid Loaded="Item_Loaded"> | |
<Canvas x:Name="ShadowContainer" /> | |
<Rectangle Fill="{Binding}" Height="100" Width="100" /> | |
</Grid> | |
</DataTemplate> | |
</GridView.ItemTemplate> | |
</GridView> | |
</Grid> | |
</Page> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Numerics; | |
using Windows.UI; | |
using Windows.UI.Xaml; | |
using Windows.UI.Xaml.Controls; | |
using Windows.UI.Xaml.Hosting; | |
using Windows.UI.Xaml.Media; | |
namespace CompositionTrials | |
{ | |
public sealed partial class MainPage : Page | |
{ | |
public MainPage() | |
{ | |
InitializeComponent(); | |
} | |
private void InitializeAnimation(UIElement root, UIElement shadowHost) | |
{ | |
var rootVisual = ElementCompositionPreview.GetElementVisual(root); | |
var shadowHostVisual = ElementCompositionPreview.GetElementVisual(shadowHost); | |
var compositor = rootVisual.Compositor; | |
// Create shadow and add it to the Visual Tree | |
var shadow = compositor.CreateDropShadow(); | |
shadow.Color = Color.FromArgb(255, 75, 75, 80); | |
var shadowVisual = compositor.CreateSpriteVisual(); | |
shadowVisual.Shadow = shadow; | |
ElementCompositionPreview.SetElementChildVisual(shadowHost, shadowVisual); | |
// Make sure the shadow resizes as its host resizes | |
var bindSizeAnimation = compositor.CreateExpressionAnimation("hostVisual.Size"); | |
bindSizeAnimation.SetReferenceParameter("hostVisual", shadowHostVisual); | |
shadowVisual.StartAnimation("Size", bindSizeAnimation); | |
// Increase the blurradius as the rectangle is scaled up | |
var shadowAnimation = compositor.CreateExpressionAnimation("100 * (source.Scale.X - 1)"); | |
shadowAnimation.SetReferenceParameter("source", rootVisual); | |
shadow.StartAnimation("BlurRadius", shadowAnimation); | |
// Create animation to scale up the rectangle | |
var pointerEnteredAnimation = compositor.CreateVector3KeyFrameAnimation(); | |
pointerEnteredAnimation.InsertKeyFrame(1.0f, new Vector3(1.1f)); | |
// Create animation to scale the rectangle back down | |
var pointerExitedAnimation = compositor.CreateVector3KeyFrameAnimation(); | |
pointerExitedAnimation.InsertKeyFrame(1.0f, new Vector3(1.0f)); | |
// Play animations on pointer enter and exit | |
root.PointerEntered += (sender, args) => | |
{ | |
rootVisual.CenterPoint = new Vector3(rootVisual.Size / 2, 0); | |
rootVisual.StartAnimation("Scale", pointerEnteredAnimation); | |
}; | |
root.PointerExited += (sender, args) => rootVisual.StartAnimation("Scale", pointerExitedAnimation); | |
} | |
private void Item_Loaded(object sender, RoutedEventArgs e) | |
{ | |
var root = (UIElement)sender; | |
InitializeAnimation(root, FindVisualChild<Canvas>(root)); | |
} | |
private TChild FindVisualChild<TChild>(DependencyObject obj) where TChild : DependencyObject | |
{ | |
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) | |
{ | |
DependencyObject child = VisualTreeHelper.GetChild(obj, i); | |
if (child != null && child is TChild found) | |
return found; | |
else | |
{ | |
TChild childOfChild = FindVisualChild<TChild>(child); | |
if (childOfChild != null) | |
return childOfChild; | |
} | |
} | |
return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment