前言

之前在知乎闲逛看有意思的项目的时候,发现一个前辈曾做过一个在鼠标周围随机生成爱心的小程序,闲来无聊实现了一版随机生成彩色小球的(因为没有女朋友,只是练练手)。最近疫情在网上撩了一个小妹妹,她知道这个程序之后,让我给她做一个“格桑花”版的。我想着应该差不多,就改了改代码。好感度+1(不一定有),但是妹汁送我一杯奶茶,嘻嘻。话不多说,下面介绍一下。


实现

总的思路很简单,就是获取鼠标的位置,然后再鼠标周围随机进行动画。实现主要分为这几个函数。

            InitProperty();    //初始化动画配置,放到多大,透明度多少,持续时间
            InitGraph();      //初始化需要放大的样式,只要继承FrameworkElement类就可以了
            MaxmizeAndTransparenceWindow();       //窗口设置,设置全屏,还有一个坑(放大比)
            StartMarvellousMouse();       //核心代码,随机生成小球

1.初始化属性

这里动画主要是样式放大的一些设置:长宽,透明度。是WPF比较基础的类FrameworkElement的属性。

           private void InitProperty()
        {
            MyStoryBoard = new Storyboard();
            //MyStoryBoard.RepeatBehavior = RepeatBehavior.Forever;
            DAWidth = new DoubleAnimation();
            DAWidth.From = 0;
            DAWidth.To = 2 * Radius;
            DAWidth.Duration = new Duration(TimeSpan.FromMilliseconds(DurationTime));
            DAHeight = new DoubleAnimation();
            DAHeight.From = 0;
            DAHeight.To = 2 * Radius;
            DAHeight.Duration = new Duration(TimeSpan.FromMilliseconds(DurationTime));
            DAOpacity = new DoubleAnimation();
            DAOpacity.From = 0;
            DAOpacity.To = 0.7;
            DAOpacity.Duration = new Duration(TimeSpan.FromMilliseconds(DurationTime));
            MyStoryBoard.Children.Add(DAWidth);
            MyStoryBoard.Children.Add(DAHeight);
            MyStoryBoard.Children.Add(DAOpacity);
        }

2.初始化样式

这里一开始是使用WPF的自定义控件比如ellipse,等。后来给妹汁做格桑花的时候,突然想到:图片不就是天然的FrameworkElement嘛,所以理论上啥样式都已放进图片并显示。顺带说一句,图片资源获取网上搜一下,然后在Google活bing的识图里面找类似的。
很难找到背景透明的图(比如带白底),可以用ps工具,或者网上的去底色工具或网址(我直接百度搜了个网址就可以用)。反正图片放大的也不大,略微丢失一点边边角角无伤大雅。

        private void InitGraph()
        {
            var elements =ElementProvider.GetElements<MyImage>();
            if (elements != null)
            {
                foreach (var item in elements)
                {
                    this.canvas.Children.Add(item);
                }
            }
            NumofGrap = this.canvas.Children.Count;
        }


3.屏幕最大化及一些设置

这里的一个坑就是,不是所有的屏幕都是100%放大,在一些笔记本上可能分辨率调的超级高,然偶后放大到200%,所以鼠标位置会有问题。这里计算了下放大比,然后鼠标的XY乘以系数。

        private void MaxmizeAndTransparenceWindow()
        {
            this.Width = SystemParameters.PrimaryScreenWidth;
            this.Height = SystemParameters.PrimaryScreenHeight;
            var hdc = GetDC(GetDesktopWindow());
            int ResolutionHeight = GetDeviceCaps(hdc, 10);        //高
            int ResolutionWidth = GetDeviceCaps(hdc, 8);       //宽
            ScaleX = (double)(ResolutionWidth / Width);
            ScaleY = (double)(ResolutionHeight / Height);
            this.Top = 0;
            this.Left = 0;
            this.WindowStyle = WindowStyle.None;
            this.ResizeMode = ResizeMode.NoResize;
            this.Topmost = true;
        }

4.核心显示

就是不停地获取鼠标位置,然后随机再鼠标周围生成图案。这里因为是死循环疯狂更新,所以内存会爆炸。所以设置线程需要休息一会会再发送(及时1ms也足够了)。

        private void StartMarvellousMouse()
        {
            POINT lpPoint;
            var widthProperty = new PropertyPath("Width");
            var heightProperty = new PropertyPath("Height");
            var opacityProperty = new PropertyPath("Opacity");
            new Thread(() =>
            {
                while (true)
                {
                    for (int i = 0; i < NumofGrap; i++)
                    {
                        GetCursorPos(out lpPoint);
                        Dispatcher.BeginInvoke(new Action(() =>
                        {
                            if (i == NumofGrap) return;           //防止循环i=NumofGrap的时候,ui线程正好访问
                            var item = (FrameworkElement)this.canvas.Children[i];
                            Canvas.SetLeft(item, (lpPoint.X - Radius + RandomDistance) / ScaleX);
                            Canvas.SetTop(item, (lpPoint.Y - Radius + RandomDistance) / ScaleY);
                            //item.Fill = RandomColor;
                            Storyboard.SetTarget(DAWidth, item);
                            Storyboard.SetTargetProperty(DAWidth, widthProperty);
                            Storyboard.SetTarget(DAHeight, item);
                            Storyboard.SetTargetProperty(DAHeight, heightProperty);
                            Storyboard.SetTarget(DAOpacity, item);
                            Storyboard.SetTargetProperty(DAOpacity, opacityProperty);
                            MyStoryBoard.Begin();
                        }));
                        Thread.Sleep((int)DurationTime / NumofGrap);
                    }
                }

            }).Start();
        }

最后预祝我能追到妹汁吧,感谢。

代码开源:git@github.com:liuchuomidi/MarvellousMouse.git

内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/chendasxian/p/16063479.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!