xaml
<Window ouseMove="DockBarWindow_OnMouseMove">
<Grid>
<StackPanel
x:Name="DockBarStackPanel"
Margin="12" HorizontalAlignment="Center" VerticalAlignment="Bottom"
Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="Ellipse">
<Setter Property="Width" Value="40" />
<Setter Property="Height" Value="{Binding RelativeSource={RelativeSource Self}, Path=Width}" />
<Setter Property="Fill" Value="CornflowerBlue" />
<Setter Property="Margin" Value="4,0" />
<Setter Property="VerticalAlignment" Value="Bottom" />
<Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
<Setter Property="LayoutTransform">
<!-- 这里要用 LayoutTransform , 因为每个点会相互影响 -->
<Setter.Value>
<ScaleTransform ScaleX="1" ScaleY="{Binding RelativeSource={RelativeSource Self}, Path=ScaleX}" />
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<Ellipse />
<Ellipse />
<Ellipse />
<Ellipse />
<Ellipse />
<Ellipse />
</StackPanel>
</Grid>
</Window>
cs
private void DockBarWindow_OnMouseMove(object sender, MouseEventArgs e)
{
var panel = this.DockBarStackPanel;
var ellipses = panel.Children.OfType<Ellipse>().ToArray();
// 根据宽度计算一个尺寸,作为影响缩放的基础距离
var baseLen = panel.RenderSize.Width / ellipses.Length;
foreach (var ellipse in ellipses)
{
// 向量计算鼠标与圆心的距离
var mousePoint = e.GetPosition(ellipse);
var center = new Point(ellipse.RenderSize.Width / 2, ellipse.RenderSize.Height / 2); // RenderSize 包括了变形处理
var distance = Point.Subtract(mousePoint, center);
if (ellipse.LayoutTransform is not ScaleTransform transform)
{
continue;
}
if (distance.Length >= baseLen)
{
// 距离太远,缩放比较为1
transform.ScaleX = 1;
}
else
{
// 根据距离计算缩放比,最小为 1
transform.ScaleX = 1 + 1.5d * (baseLen - distance.Length) / (2d * baseLen);
}
}
}