wpf DockBar

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);
            }
        }
    }
上一篇
下一篇