MyIconButton.xaml.vb 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. Imports System.Windows.Shapes
  2. Public Class MyIconButton
  3. '自定义事件
  4. Public Event Click(sender As Object, e As EventArgs)
  5. '自定义属性
  6. Public Uuid As Integer = GetUuid()
  7. Public Property Logo As String
  8. Get
  9. Return Path.Data.ToString
  10. End Get
  11. Set(value As String)
  12. Path.Data = (New GeometryConverter).ConvertFromString(value)
  13. End Set
  14. End Property
  15. Private _LogoScale As Double = 1
  16. Public Property LogoScale() As Double
  17. Get
  18. Return _LogoScale
  19. End Get
  20. Set(value As Double)
  21. _LogoScale = value
  22. If Not IsNothing(Path) Then Path.RenderTransform = New ScaleTransform With {.ScaleX = LogoScale, .ScaleY = LogoScale}
  23. End Set
  24. End Property
  25. Public Enum Themes
  26. Color
  27. White
  28. Black
  29. Red
  30. Custom
  31. End Enum
  32. Public Property Theme As Themes = Themes.Color
  33. Private _Foreground As New SolidColorBrush(Color.FromRgb(128, 128, 128))
  34. Public Property Foreground As SolidColorBrush
  35. Get
  36. Return _Foreground
  37. End Get
  38. Set(value As SolidColorBrush)
  39. _Foreground = value
  40. AniControlEnabled += 1
  41. RefreshAnim()
  42. AniControlEnabled -= 1
  43. End Set
  44. End Property
  45. '鼠标点击判定(务必放在点击事件之后,以使得 Button_MouseUp 先于 Button_MouseLeave 执行)
  46. Private IsMouseDown As Boolean = False
  47. Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonUp
  48. If Not IsMouseDown Then Return
  49. Logger.Info($"按下图标按钮{If(String.IsNullOrEmpty(Name), "", ":" & Name)}")
  50. RaiseEvent Click(sender, e)
  51. e.Handled = True
  52. Button_MouseUp()
  53. RaiseCustomEvent() '自定义事件
  54. End Sub
  55. Private Sub Button_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
  56. IsMouseDown = True
  57. Focus()
  58. '指向
  59. AniStart(AaScaleTransform(PanBack, 0.8 - CType(PanBack.RenderTransform, ScaleTransform).ScaleX, 400,, New AniEaseOutFluent(AniEasePower.Strong)), "MyIconButton Scale " & Uuid)
  60. End Sub
  61. Private Sub Button_MouseUp() Handles Me.MouseLeftButtonUp
  62. If IsMouseDown Then
  63. IsMouseDown = False
  64. AniStart({
  65. AaScaleTransform(PanBack, 1.05 - CType(PanBack.RenderTransform, ScaleTransform).ScaleX, 250,, New AniEaseOutBack(AniEasePower.Weak)),
  66. AaScaleTransform(PanBack, -0.05, 250,, New AniEaseOutFluent(AniEasePower.Strong))
  67. }, "MyIconButton Scale " & Uuid)
  68. End If
  69. RefreshAnim() '直接刷新颜色以判断是否已触发 MouseLeave
  70. End Sub
  71. Private Sub Button_MouseLeave() Handles Me.MouseLeave
  72. IsMouseDown = False
  73. AniStart({
  74. AaScaleTransform(PanBack, 1 - CType(PanBack.RenderTransform, ScaleTransform).ScaleX, 250,, New AniEaseOutFluent)
  75. }, "MyIconButton Scale " & Uuid)
  76. RefreshAnim() '直接刷新颜色以判断是否已触发 MouseLeave
  77. End Sub
  78. '务必放在 IsMouseDown 更新之后
  79. Private Const AnimationColorIn As Integer = 120
  80. Private Const AnimationColorOut As Integer = 150
  81. Public Sub RefreshAnim() Handles Me.MouseEnter, Me.MouseLeave, Me.Loaded
  82. Try
  83. If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
  84. If PanBack.Background Is Nothing Then PanBack.Background = New MyColor(0, 255, 255, 255)
  85. If Path.Fill Is Nothing Then
  86. Select Case Theme
  87. Case Themes.Red
  88. Path.Fill = New MyColor(160, 255, 76, 76)
  89. Case Themes.Black
  90. Path.Fill = New MyColor(160, 0, 0, 0)
  91. Case Themes.Custom
  92. Path.Fill = New MyColor(160, Foreground)
  93. End Select
  94. End If
  95. If IsMouseOver Then
  96. '指向
  97. Dim AnimList As New List(Of AniData)
  98. Select Case Theme
  99. Case Themes.Color
  100. AnimList.Add(AaColor(Path, Shape.FillProperty, "ColorBrush2", AnimationColorIn))
  101. Case Themes.White
  102. AnimList.Add(AaColor(PanBack, BackgroundProperty, New MyColor(50, 255, 255, 255) - PanBack.Background, AnimationColorIn))
  103. Case Themes.Red
  104. AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(255, 76, 76) - Path.Fill, AnimationColorIn))
  105. Case Themes.Black
  106. AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(230, 0, 0, 0) - Path.Fill, AnimationColorIn))
  107. Case Themes.Custom
  108. AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(255, Foreground) - Path.Fill, AnimationColorIn))
  109. End Select
  110. AniStart(AnimList, "MyIconButton Color " & Uuid)
  111. Else
  112. '普通
  113. Dim AnimList As New List(Of AniData)
  114. Select Case Theme
  115. Case Themes.Color
  116. AnimList.Add(AaColor(Path, Shape.FillProperty, "ColorBrush4", AnimationColorOut))
  117. PanBack.Background = New MyColor(0, 255, 255, 255)
  118. Case Themes.White
  119. AnimList.Add(AaColor(Path, Shape.FillProperty, "ColorBrush8", AnimationColorOut))
  120. AnimList.Add(AaColor(PanBack, BackgroundProperty, New MyColor(0, 255, 255, 255) - PanBack.Background, AnimationColorOut))
  121. Case Themes.Red
  122. AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(160, 255, 76, 76) - Path.Fill, AnimationColorOut))
  123. PanBack.Background = New MyColor(0, 255, 255, 255)
  124. Case Themes.Black
  125. AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(160, 0, 0, 0) - Path.Fill, AnimationColorOut))
  126. PanBack.Background = New MyColor(0, 255, 255, 255)
  127. Case Themes.Custom
  128. AnimList.Add(AaColor(Path, Shape.FillProperty, New MyColor(160, Foreground) - Path.Fill, AnimationColorOut))
  129. PanBack.Background = New MyColor(0, 255, 255, 255)
  130. End Select
  131. AniStart(AnimList, "MyIconButton Color " & Uuid)
  132. End If
  133. Else
  134. AniStop("MyIconButton Color " & Uuid)
  135. Select Case Theme
  136. Case Themes.Color
  137. Path.SetResourceReference(Shape.FillProperty, "ColorBrush5")
  138. Case Themes.White
  139. Path.SetResourceReference(Shape.FillProperty, "ColorBrush8")
  140. Case Themes.Red
  141. Path.Fill = New MyColor(160, 255, 76, 76)
  142. Case Themes.Black
  143. Path.Fill = New MyColor(160, 0, 0, 0)
  144. Case Themes.Custom
  145. Path.Fill = New MyColor(160, Foreground)
  146. End Select
  147. PanBack.Background = New MyColor(0, 255, 255, 255)
  148. End If
  149. Catch ex As Exception
  150. Logger.Warn(ex, "刷新图标按钮动画状态出错")
  151. End Try
  152. End Sub
  153. End Class
  154. Partial Public Module ModAnimation
  155. Public Sub AniDispose(Control As MyIconButton, RemoveFromChildren As Boolean, Optional CallBack As ParameterizedThreadStart = Nothing)
  156. If Not Control.IsHitTestVisible Then Return
  157. Control.IsHitTestVisible = False
  158. AniStart({
  159. AaScaleTransform(Control, -1.5, 200,, New AniEaseInFluent),
  160. AaCode(Sub()
  161. If RemoveFromChildren Then
  162. CType(Control.Parent, Object).Children.Remove(Control)
  163. Else
  164. Control.Visibility = Visibility.Collapsed
  165. End If
  166. If CallBack IsNot Nothing Then CallBack(Control)
  167. End Sub,, True)
  168. }, "MyIconButton Dispose " & Control.Uuid)
  169. End Sub
  170. End Module