翼度科技»论坛 编程开发 .net 查看内容

WPF自定义控件之ItemsControl鱼眼效果

10

主题

10

帖子

30

积分

新手上路

Rank: 1

积分
30
原理

先获取鼠标在控件中的坐标,在获取其每一项相对于ItemsControl的坐标,然后计算每一项离当前鼠标的距离,在根据这个距离,对其每一项进行适当的缩放
实现

创建一个类,命名为FishEyeItemsControl
 public class FishEyeItemsControl : ItemsControl 
添加应用鱼眼效果方法(控制其控件的缩放)
  1. private void ApplyFishEyeEffect(UIElement element, double strength, double additionalScale = 0.0)
  2. {
  3.     // 将鱼眼效果应用于控件的正中心位置
  4.     // 获取控件的宽度和高度
  5.     double width = element.RenderSize.Width;
  6.     double height = element.RenderSize.Height;
  7.     // 计算控件的正中心位置
  8.     double centerX = width / 2.0;
  9.     double centerY = height / 2.0;
  10.     // 创建 ScaleTransform 对象并设置缩放中心为控件的正中心
  11.     ScaleTransform scaleTransform = new ScaleTransform();
  12.     scaleTransform.CenterX = centerX;
  13.     scaleTransform.CenterY = centerY;
  14.     // 根据强度调整缩放比例
  15.     scaleTransform.ScaleX = strength + additionalScale;
  16.     scaleTransform.ScaleY = strength + additionalScale;
  17.     // 将 ScaleTransform 应用于控件的 RenderTransform
  18.     element.RenderTransform = scaleTransform;
  19. }
复制代码
当鼠标移入到ItemsControl区域内时,计算其项距离鼠标距离,实现鱼眼效果
CalculateStrength方法可根据实际需求进行更改
  1. protected override void OnMouseMove(MouseEventArgs e)
  2. {
  3.     base.OnMouseMove(e);
  4.     Point mousePosition = e.GetPosition(this);
  5.     hoveredIndex = -1;
  6.     for (int i = 0; i < Items.Count; i++)
  7.     {
  8.         UIElement element = ItemContainerGenerator.ContainerFromIndex(i) as UIElement;
  9.         if (element != null)
  10.         {
  11.             Point itemPosition = element.TranslatePoint(new Point(element.RenderSize.Width / 2, element.RenderSize.Height / 2), this);
  12.             double distance = CalculateDistance(mousePosition, itemPosition);
  13.             double strength = CalculateStrength(distance);
  14.             ApplyFishEyeEffect(element, strength, Scale);
  15.             if (distance < element.RenderSize.Width)
  16.             {
  17.                 hoveredIndex = i;
  18.             }
  19.         }
  20.     }
  21. }
  22. private double CalculateDistance(Point p1, Point p2)
  23. {
  24.     double dx = p1.X - p2.X;
  25.     double dy = p1.Y - p2.Y;
  26.     return Math.Sqrt(dx * dx + dy * dy);
  27. }
  28. private double CalculateStrength(double distance)
  29. {
  30.     // 根据距离计算变换的强度
  31.     var strength = 1.0;
  32.     strength = Math.Exp(-distance / 100);
  33.     return strength;
  34. }
复制代码
当鼠标离开ItemsControl时,进行效果还原
  1. protected override void OnMouseLeave(MouseEventArgs e)
  2. {
  3.     base.OnMouseLeave(e);
  4.     for (int i = 0; i < Items.Count; i++)
  5.     {
  6.         UIElement element = ItemContainerGenerator.ContainerFromIndex(i) as UIElement;
  7.         if (element != null)
  8.         {
  9.             ApplyFishEyeEffect(element, 1.0);
  10.         }
  11.     }
  12.     hoveredIndex = -1;
  13. }
复制代码
添加背景色,如果未设置,当鼠标处于两个项之间的空间会触发OnMouseLeave
 
  1. public FishEyeItemsControl()
  2. {
  3.     this.Background = Brushes.Transparent;
  4. }
复制代码
属性
依赖属性Scale是为了在Xaml中动态修改其效果
  1. private int hoveredIndex = -1;
  2. #region DependencyProperty
  3. public double Scale
  4. {
  5.     get { return (double)GetValue(ScaleProperty); }
  6.     set { SetValue(ScaleProperty, value); }
  7. }
  8. // Using a DependencyProperty as the backing store for Scale.  This enables animation, styling, binding, etc...
  9. public static readonly DependencyProperty ScaleProperty =
  10.     DependencyProperty.Register("Scale", typeof(double), typeof(FishEyeItemsControl), new FrameworkPropertyMetadata(1.0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
  11. #endregion
复制代码
Xaml
  1.   <zWorkUi:FishEyeItemsControl
  2.       Width="800"
  3.       Height="600"
  4.       ItemsSource="{Binding TestList}">
  5.       <zWorkUi:FishEyeItemsControl.ItemsPanel>
  6.           <ItemsPanelTemplate>
  7.               <WrapPanel />
  8.           </ItemsPanelTemplate>
  9.       </zWorkUi:FishEyeItemsControl.ItemsPanel>
  10.       <zWorkUi:FishEyeItemsControl.ItemTemplate>
  11.           <DataTemplate>
  12.               <Border
  13.                   Width="50"
  14.                   Height="50"
  15.                   Margin="20,20"
  16.                   Background="Red" />
  17.           </DataTemplate>
  18.       </zWorkUi:FishEyeItemsControl.ItemTemplate>
  19.   </zWorkUi:FishEyeItemsControl>
复制代码
 
效果

鼠标未进入区域时

效果1

效果2

 鼠标进入区域,移到某一项上时

效果1

效果2


来源:https://www.cnblogs.com/fengxinyuan/archive/2023/12/29/17934002.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具