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

所属分类: 软件编程 / C#教程 阅读数: 139
收藏 0 赞 0 分享

本文实例为大家分享了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;
  }
}

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

c#开发word批量转pdf源码分享

已经安装有Office环境,借助一些简单的代码即可实现批量Word转PDF,看下面的实例源码吧
收藏 0 赞 0 分享

c# xml API操作的小例子

这篇文章主要介绍了c# xml API操作的小例子,有需要的朋友可以参考一下
收藏 0 赞 0 分享

c#唯一值渲染实例代码

这篇文章主要介绍了c#唯一值渲染实例代码,有需要的朋友可以参考一下
收藏 0 赞 0 分享

淘宝IP地址库采集器c#代码

这篇文章主要介绍了淘宝IP地址库采集器c#代码,有需要的朋友可以参考一下
收藏 0 赞 0 分享

C#在后台运行操作(BackgroundWorker用法)示例分享

BackgroundWorker类允许在单独的专用线程上运行操作。如果需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用BackgroundWorker类方便地解决问题,下面看示例
收藏 0 赞 0 分享

c#文本加密程序代码示例

这是一个加密软件,但只限于文本加密,加了窗口控件的滑动效果,详细看下面的代码
收藏 0 赞 0 分享

c#生成站点地图(SiteMapPath)文件示例程序

这篇文章主要介绍了c#生成站点地图(SiteMapPath)文件的示例,大家参考使用
收藏 0 赞 0 分享

C# 键盘Enter键取代Tab键实现代码

这篇文章主要介绍了C# 键盘Enter键取代Tab键实现代码,有需要的朋友可以参考一下
收藏 0 赞 0 分享

C# WinForm导出Excel方法介绍

在.NET应用中,导出Excel是很常见的需求,导出Excel报表大致有以下三种方式:Office PIA,文件流和NPOI开源库,本文只介绍前两种方式
收藏 0 赞 0 分享

C#串口通信程序实例详解

在.NET平台下创建C#串口通信程序,.NET 2.0提供了串口通信的功能,其命名空间是System.IO.Ports,创建C#串口通信程序的具体实现是如何的呢?让我们开始吧
收藏 0 赞 0 分享
查看更多