Sáng Chủ nhật hôm nay rồi mày mò về WPF, làm một vài thứ linh tinh, và mình nhận ra một điều thú vị trong WPF về Animation.
Vấn đề mình gặp phải là làm sao để cho 1 UIElement chuyển động dọc theo một Path mình có sẵn???
Sử dụng Blend? Nhưng trong Blend mình làm thì nó lại chỉ di chuyển theo đường thẳng!!!
Sau một hồi tìm hiểu thì thật thú vị, trong namespace StoryBoard, chúng ta có một class là DoubleAnimationUsingPath. Cũng tương tự như class DoubleAnimation, nhưng DoubleAnimationUsingPath sử dụng một PathGeometry để nội suy (interpolate) hai hoặc nhiều giá trị. Chính điều này sẽ giúp cho chúng ta thể hiện tốt hơn các animation của UIElement trên màn hình.
Ý tưởng ở đây dựa trên môn Vật lý: mỗi vật khi di chuyển trong không gian (trong trường hợp của chúng ta ở đây là không gian 2 chiều) thì chúng ta có thể biểu diễn chuyển động của nó theo 2 phương là X và Y.
Từ ý tưởng đó, chúng ta sẽ tạo một StoryBoard cho UIElement của chúng ta, trong đó sẽ bao gồm 2 chuyển động là chuyển động theo phương X và chuyển động theo phương Y.
Để hiện thực tốt ý tưởng này, chúng ta cần chú ý một vài điểm như sau:
- sử dụng layout Canvas để sử dụng tốt với tọa độ X,Y
- 2 animation của chúng ta sẽ tác động đến các tọa độ X, Y trong đối tượng RenderTransform.TranslateTransform của UIElement.
Đầu tiên, tạo một PathGeometry trong Window.Resources, điều này rất tiện lợi cho chúng ta, bởi chúng ta không cần phải khai báo lại đối tượng khi sử dụng, chỉ cần gọi đến và sử dụng.
<!--
Tạo một PathGeometry cho moving
-->
<PathGeometry
x:Key="path"
Figures="M 0.5,213 C 75,-113 70,-24 146,213"/>
Tiếp theo, khai báo một Image cho animation
<Image Name="ball" Source="Basketball.png" Width="36" Height="36" Stretch="Fill">
<!--
Tạo đối tượng RenderTransform.TranslateTransform có tên xác định
để StoryBoard của chúng ta có thể tác động đến các properties.
-->
<Image.RenderTransform>
<TranslateTransform x:Name="movingTransform" X="0" Y="190"/>
</Image.RenderTransform>
</Image>
Như đã nói ở trên, bởi Animation của chúng sẽ tác động đến các properties trong đối tượng RenderTransform.TranslateTransform của đối tượng, nên chúng ta cần gán thuộc tính Name cho TranslateTransform của chúng ta để StoryBoard có thể thao tác đến.
Như vậy là đã chuẩn bị xong các đối tượng cần thiết, tiếp theo, tạo StoryBoard
<Storyboard x:Key="MovingBoard">
<!--
Tạo chuyển động theo phương X
tác động đến property X trong đối tượng RenderTransform.TranslateTransform
của UIElement
-->
<DoubleAnimationUsingPath
Storyboard.TargetName="movingTransform"
Storyboard.TargetProperty="X"
Source="X"
Duration="0:0:5"
RepeatBehavior="Forever" AutoReverse="True"
PathGeometry="{StaticResource path}"
/>
<!--
Tạo chuyển động theo phương Y
tác động đến property Y trong đối tượng RenderTransform.TranslateTransform
của UIElement
-->
<DoubleAnimationUsingPath
Storyboard.TargetName="movingTransform"
Storyboard.TargetProperty="Y"
Source="Y"
Duration="0:0:5"
RepeatBehavior="Forever" AutoReverse="True"
PathGeometry="{StaticResource path}"
/>
</Storyboard>
Done! Mọi cái đã xong. Các bạn có thể download full source code tại đây.