WPF实现背景灯光随鼠标闪动效果

作者:RunnerDNA 时间:2023-09-05 15:39:27 

本文实例为大家分享了WPF实现背景灯光随鼠标闪动的具体代码,供大家参考,具体内容如下

实现效果如下:

WPF实现背景灯光随鼠标闪动效果

思路:将容器分割成组合三角形Path,鼠标移动时更新每个三角形的填充颜色。

步骤:

1、窗体xaml

只需放置一个Canvas。


<Canvas x:Name="container" Width="400" Height="400"></Canvas>

2、交互逻辑


/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
 private Point lastMousePosition = new Point(0, 0);//鼠标位置
 private int triangleLength = 100;//三角形边长

public MainWindow()
 {
  InitializeComponent();
  this.Loaded += MainWindow_Loaded;
  CompositionTarget.Rendering += UpdateTriangle;
  this.container.PreviewMouseMove += UpdateLastMousePosition;
 }

private void MainWindow_Loaded(object sender, RoutedEventArgs e)
 {
  //将长方形容易划分成组合三角形
  int horizontalCount = (int)(this.container.ActualWidth / triangleLength);
  int verticalCount = (int)(this.container.ActualHeight / triangleLength);
  for (int i = 0; i < horizontalCount; i++)
  {
   for (int j = 0; j < verticalCount; j++)
   {
    Path trianglePath1 = new Path();
    var g1 = new StreamGeometry();
    using (StreamGeometryContext context = g1.Open())
    {
     context.BeginFigure(new Point(i * triangleLength, j * triangleLength), true, true);
     context.LineTo(new Point(i * triangleLength, (j + 1) * triangleLength), true, false);
     context.LineTo(new Point((i + 1) * triangleLength, (j + 1) * triangleLength), true, false);
    }
    trianglePath1.Data = g1;
    trianglePath1.Fill = new SolidColorBrush(Color.FromArgb(255, 247, 18, 65));
    this.container.Children.Add(trianglePath1);

Path trianglePath2 = new Path();
    var g2 = new StreamGeometry();
    using (StreamGeometryContext context = g2.Open())
    {
     context.BeginFigure(new Point(i * triangleLength, j * triangleLength), true, true);
     context.LineTo(new Point((i + 1) * triangleLength, j * triangleLength), true, false);
     context.LineTo(new Point((i + 1) * triangleLength, (j + 1) * triangleLength), true, false);
    }
    trianglePath2.Data = g2;
    trianglePath2.Fill = new SolidColorBrush(Color.FromArgb(255, 247, 18, 65));
    this.container.Children.Add(trianglePath2);
   }
  }
 }

private void UpdateTriangle(object sender, EventArgs e)
 {
  //获取子控件
  List<Path> childList = GetChildObjects<Path>(this.container);
  for (int i = 0; i < childList.Count; i++)
  {
   for (int j = 1; j < childList.Count; j++)
   {
    string si = childList[i].Data.ToString();
    string si1 = MidStrEx(si, "M", "L");
    string si2 = MidStrEx(si, "L", " ");
    string si3 = MidStrEx(si, " ", "z");
    string sj = childList[j].Data.ToString();
    string sj1 = MidStrEx(sj, "M", "L");
    string sj2 = MidStrEx(sj, "L", " ");
    string sj3 = MidStrEx(sj, " ", "z");
    //左右三角形判断
    if (si1 == sj1 && si3 == sj3)
    {
     double x = childList[i].Data.Bounds.X + (1 - Math.Pow(2, 0.5) / 2) * triangleLength - lastMousePosition.X;
     double y = childList[i].Data.Bounds.Y + (1 - Math.Pow(2, 0.5) / 2) * triangleLength - lastMousePosition.Y;
     double rRadio = 1 - Math.Pow(x * x + y * y, 0.5) / Math.Pow(this.container.ActualWidth * this.container.ActualWidth + this.container.ActualHeight * this.container.ActualHeight, 0.5);
     childList[j].Fill = new SolidColorBrush(Color.FromArgb((byte)(255 * rRadio), 247, 18, 65));
     x = childList[j].Data.Bounds.TopRight.X - (1 - Math.Pow(2, 0.5) / 2) * triangleLength - lastMousePosition.X;
     rRadio = 1 - Math.Pow(x * x + y * y, 0.5) / Math.Pow(this.container.ActualWidth * this.container.ActualWidth + this.container.ActualHeight * this.container.ActualHeight, 0.5);
     childList[i].Fill = new SolidColorBrush(Color.FromArgb((byte)(255 * rRadio), 247, 18, 65));
     break;
    }
   }
  }
 }

private void UpdateLastMousePosition(object sender, MouseEventArgs e)
 {
  lastMousePosition = e.GetPosition(this.container);
 }

/// <summary>
 /// 获得所有子控件
 /// </summary>
 private List<T> GetChildObjects<T>(System.Windows.DependencyObject obj) where T : System.Windows.FrameworkElement
 {
  System.Windows.DependencyObject child = null;
  List<T> childList = new List<T>();
  for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
  {
   child = VisualTreeHelper.GetChild(obj, i);
   if (child is T)
   {
    childList.Add((T)child);
   }
   childList.AddRange(GetChildObjects<T>(child));
  }
  return childList;
 }

/// <summary>
 /// 截取两个指定字符中间的字符串
 /// </summary>
 public static string MidStrEx(string sourse, string startstr, string endstr)
 {
  string result = string.Empty;
  int startindex, endindex;
  try
  {
   startindex = sourse.IndexOf(startstr);
   if (startindex == -1)
    return result;
   string tmpstr = sourse.Substring(startindex + startstr.Length);
   endindex = tmpstr.IndexOf(endstr);
   if (endindex == -1)
    return result;
   result = tmpstr.Remove(endindex);
  }
  catch (Exception ex)
  {
  }
  return result;
 }
}

说明:当组合三角形过多时,会有明显卡顿,需要优化色彩更新方法。

来源:https://blog.csdn.net/dnazhd/article/details/107967026

标签:WPF,灯光,鼠标闪动
0
投稿

猜你喜欢

  • 一文带你真正理解Java中的内部类

    2023-11-24 20:42:07
  • 详解C#如何实现读写ini文件

    2022-02-04 23:15:27
  • springboot使用JPA时间类型进行模糊查询的方法

    2023-10-26 21:59:02
  • C#中实现Json序列化与反序列化的几种方式

    2021-11-06 01:31:07
  • SpringBoot异步任务使用方法详解

    2021-08-07 07:57:02
  • Android自定义View实现分段选择按钮的实现代码

    2022-09-06 07:46:21
  • Android使用Gridview单行横向滚动显示

    2021-07-28 17:40:43
  • c#实现metro文件压缩解压示例

    2022-07-07 22:36:33
  • Java CAS原子操作详解

    2023-05-06 15:37:15
  • Android控件之SeekBar的用法总结

    2022-10-25 00:15:38
  • CCF考试试题之门禁系统java解题代码

    2022-10-05 02:39:27
  • 函数指针与指针函数的学习总结

    2023-07-07 13:13:50
  • C#实现对二维数组排序的方法

    2023-06-19 09:09:08
  • Java System类两个常用方法代码实例

    2023-02-01 13:52:15
  • Android中ListView用法实例分析

    2022-04-08 17:11:29
  • Java实现的断点续传功能的示例代码

    2023-05-25 12:17:22
  • C#多态的三种实现方式(小结)

    2022-12-29 18:10:57
  • 解决mybatis分页插件PageHelper导致自定义拦截器失效

    2023-10-13 07:24:29
  • MyBatisPlus+Lombok实现分页功能的方法详解

    2021-07-04 06:34:57
  • Android Studio使用小技巧:布局预览时填充数据

    2021-06-04 09:00:03
  • asp之家 软件编程 m.aspxhome.com