win10 UWP 蜘蛛网效果

简介: 原文:win10 UWP 蜘蛛网效果 我看见了知乎首页登录背景和普通的地球人写的博客,发现了个好看的效果。 那么我来告诉大家如何做这个效果。
原文: win10 UWP 蜘蛛网效果

我看见了知乎首页登录背景和普通的地球人写的博客,发现了个好看的效果。

那么我来告诉大家如何做这个效果。

第一步是在 Canvas 画点,第二步是让点移动,第三步是画线

在 Canvas 画一个点

我们画点可以使用 Ellipse 我们给他宽和高,Fill,就可以画出来。需要加在 Canvas ,可以使用canvas.Children.Add(ellipse)

Canvas 一开始的大小是 0 ,需要一开始给他一个足够大的值


<Canvas x:Name="P" Width="1000" Height="1000"/>

于是给他一个比较大的值,超过外面的Grid就不显示。

添加 一个 Ellipse 就会显示,可以没有指定在哪显示,也就是显示的 X 和 Y。

指定添加到 Canvas 的 Element 的位置

我们可以通过几个方法改变控件的位置,在我之前写的拖动控件博客有说到。

现在使用 Canvas,可以使用 Canvas 有的一个方法。

假如有一个 X 和 Y 要设置在控件,那么可以使用


                Canvas.SetLeft(control, X);
                Canvas.SetTop(control, Y);

注意,Canvas 是类。

这个方法可以移动控件。

我就是用他移动点。

随机移动点

我首先写一个类,Staf。包含显示的 Point 和他的 X,Y,两个方向移动速度。还有移动多久,超过了可以移动的时间,就随机给新移动速度。


    public class Staf
    {
        public UIElement Point { set; get; }

        public double X { set; get; }

        public double Y { set; get; }

        public double Vx { set; get; }

        public double Vy { set; get; }

        public void RandomStaf(Random ran)
        {
            var staf = this;
            _ran = ran;
            staf.Vx = (double)ran.Next(-1000, 1000) / 1000;
            staf.Vy = (double)ran.Next(-1000, 1000) / 1000;
            staf.Time = ran.Next(100);
        }
        private Random _ran;
        public int Time
        {
            set
            {
                _time = value;
                if (value == 0)
                {
                    RandomStaf(_ran);
                }
            }
            get
            {
                return _time;
            }
        }

        private int _time;
    }

画线

使用两重 foreach ,得到两个点之间距离,如果距离小于我给的一个值,那么就是可以连线

那么距离长的就把连线的宽度变短。

这个做法很简单,可以使用 StrokeThickness 设置线宽度。

line.StrokeThickness=最大宽度 * (最大距离-距离)/最大距离

线需要多少个点可以确定?这个我就不说啦,确定了两个点是可以连线,于是使用就可以设置线的点。需要知道,点的X和Y是左上角,需要加上画的图形的值才是连在点,不然看起来不是连在点。

自动移动

可以使用 DispatcherTimer ,过 0.1 s就移动点和画线。


        public MainPage()
        {
            this.InitializeComponent();
            _time = new DispatcherTimer();
            _time.Interval = TimeSpan.FromTicks(500);
            _time.Tick += Time_Tick;            
            _time.Start();
        }

private DispatcherTimer _time

Time_Tick就写移动点和线的代码

全部代码


<Page
    x:Class="Bsgame.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Bsgame"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Canvas x:Name="P" Width="1000" Height="1000">

        </Canvas>
        <Canvas x:Name="Pw" Width="1000" Height="1000"></Canvas>
    </Grid>
</Page>


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Shapes;

namespace Bsgame
{
    /// <summary>
    /// 可用于自身或导航至 Frame 内部的空白页。
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            _time = new DispatcherTimer();
            _time.Interval = TimeSpan.FromTicks(500);
            _time.Tick += Time_Tick;
            RandomStaf();
            _time.Start();
            _width = Window.Current.Bounds.Width;
            _height = Window.Current.Bounds.Height;//lindexi
        }

        private void RandomStaf()
        {
            const int count = 20;

            for (int i = 0; i < count; i++)
            {
                Staf staf = new Staf();
                staf.X = ran.Next((int)_width);
                staf.Y = ran.Next((int)_height);
                staf.Point = new Ellipse()
                {
                    Height = 10,
                    Width = 10,
                    Fill = new SolidColorBrush(Colors.Gray),
                };
                staf.RandomStaf(ran);
                // CSDN
                _staf.Add(staf);
            }

            foreach (var temp in _staf)
            {
                P.Children.Add(temp.Point);
                //lindexi
            }
        }

        private List<Staf> _staf = new List<Staf>();

        private double _width;
        private double _height;

        private void Time_Tick(object sender, object e)
        {
            foreach (var temp in _staf)
            {
                if (temp.X > _width || temp.Y > _height
                    || temp.X < 0 || temp.Y < 0)
                {
                    temp.X = ran.Next((int)_width);
                    temp.Y = ran.Next((int)_height);
                }//lindexi.oschina.io

                temp.X -= temp.Vx;
                temp.Y -= temp.Vy;

                Canvas.SetLeft(temp.Point, temp.X);
                Canvas.SetTop(temp.Point, temp.Y);

                temp.Time--;
            }
            const double distan = 200;
            Pw.Children.Clear();
            Line line = new Line();
            foreach (var temp in _staf)
            {
                foreach (var p in _staf)
                {
                    line.X1 = temp.X + 5;
                    line.Y1 = temp.Y + 5;
                    line.X2 = p.X + 5;
                    line.Y2 = p.Y + 5;
                    double sqrt = Math.Sqrt(Math.Pow((line.X1 - line.X2), 2) +
                      Math.Pow((line.Y1 - line.Y2), 2));
                    if (sqrt < distan)
                    {
                        line.Stroke = new SolidColorBrush(Colors.Gray);
                        line.StrokeThickness = 5* (distan- sqrt) /distan;
                        Pw.Children.Add(line);
                        line = new Line();
                    }
                }
            }
        }

        private Random ran = new Random();

        private DispatcherTimer _time;
    }

    public class Staf
    {
        public UIElement Point { set; get; }

        public double X { set; get; }

        public double Y { set; get; }

        public double Vx { set; get; }

        public double Vy { set; get; }

        public void RandomStaf(Random ran)
        {
            var staf = this;
            _ran = ran;
            staf.Vx = (double)ran.Next(-1000, 1000) / 1000;
            staf.Vy = (double)ran.Next(-1000, 1000) / 1000;
            staf.Time = ran.Next(100);
        }
        private Random _ran;
        public int Time
        {
            set
            {
                _time = value;
                if (value == 0)
                {
                    RandomStaf(_ran);
                }
            }
            get
            {
                return _time;
            }
        }

        private int _time;
    }
}

可以看到性能很差,于是把连线去掉,显示点不显示连接

        private void RandomStaf(object sender, object e)
        {
            Storyboard board = new Storyboard();
            board.Duration = new Duration(TimeSpan.FromSeconds(1));
            board.Completed += RandomStaf;
            DoubleAnimationUsingKeyFrames animation;
            foreach (var temp in _staf)
            {
                double f = temp.X;

                temp.X += temp.Vx * 10;
                if (temp.X > _width - 100)
                {
                    temp.X = _width - 100;
                }
                else if (temp.X < 0)
                {
                    temp.X = 0;
                }



                animation = EllPoile(f, temp.X);
                Storyboard.SetTarget(animation, temp.Point);
                Storyboard.SetTargetProperty(animation, "(Canvas.Left)");
                board.Children.Add(animation);

                f = temp.Y;
                temp.Y += temp.Vy * 10;

                if (temp.Y > _height - 100)
                {
                    temp.Y = _height - 100;
                }
                else if (temp.Y < 0)
                {
                    temp.Y = 0;
                }

                animation = EllPoile(f, temp.Y);
                Storyboard.SetTarget(animation, temp.Point);
                Storyboard.SetTargetProperty(animation, "(Canvas.Top)");

                if (temp.X >= _width - 100 || temp.Y >= _height - 100
                      || temp.X <= 0 || temp.Y <= 0)
                {
                    temp.X = ran.Next((int)_width);
                    temp.Y = ran.Next((int)_height);
                }
                board.Children.Add(animation);
                temp.Time -= 10;

                animation = EllPoile(10, 15);
                Storyboard.SetTarget(animation, temp.Point);
                Storyboard.SetTargetProperty(animation, "Height");
                board.Children.Add(animation);

                animation = EllPoile(10, 15);
                Storyboard.SetTarget(animation, temp.Point);
                Storyboard.SetTargetProperty(animation, "Width");
                board.Children.Add(animation);

                animation = new DoubleAnimationUsingKeyFrames();
                EasingDoubleKeyFrame frame = new EasingDoubleKeyFrame();
                frame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
                frame.Value = 0;
                animation.KeyFrames.Add(frame);

                frame = new EasingDoubleKeyFrame();
                frame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.5));
                frame.Value = 180;
                animation.KeyFrames.Add(frame);

                frame = new EasingDoubleKeyFrame();
                frame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
                frame.Value = 0;
                animation.KeyFrames.Add(frame);
                Storyboard.SetTarget(animation, temp.Point.RenderTransform);
                Storyboard.SetTargetProperty(animation, "(CompositeTransform.Rotation)");
                board.Children.Add(animation);

            }
            board.Begin();

        }

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

目录
相关文章
|
C# Windows API
Windows 下的高 DPI 应用开发(UWP / WPF / Windows Forms / Win32)
原文 Windows 下的高 DPI 应用开发(UWP / WPF / Windows Forms / Win32) 本文将介绍 Windows 系统中高 DPI 开发的基础知识。由于涉及到坐标转换,这种转换经常发生在计算的不知不觉中;所以无论你使用哪种 Windows 下的 UI 框架进行开发,你都需要了解这些内容,以免不断踩坑。
1870 0
|
C# Windows
WPF程序在Windows 7下应用Windows 8主题
原文:WPF程序在Windows 7下应用Windows 8主题 这篇博客介绍如何在Windows 7下应用Windows 8的主题。 首先我们先看一个很常见的场景,同样的WPF程序(样式未重写)在不同的操作系统上展示会有些不同。
1013 0
|
前端开发 UED
[UWP]不那么好用的ContentDialog
原文:[UWP]不那么好用的ContentDialog ContentDialog是UWP开发中最常用的组件之一,一个体验良好的UWP应用很难避免不去使用它。博客园里也有许多的文章介绍如何来利用ContentDialog实现各种自定义样式的弹窗界面。
1300 0
|
C# 程序员
[UWP]做个调皮的BusyIndicator
原文:[UWP]做个调皮的BusyIndicator 1. 前言 最近突然想要个BusyIndicator。做过WPF开发的程序员对BusyIndicator应该不陌生,Extended WPF Toolkit 提供了BusyIndicator的开源实现,Silverlight Toolkit也有一个,这次想要把这个控件移植到UWP中。
907 0
[UWP]了解IValueConverter
原文:[UWP]了解IValueConverter 1. 前言 IValueConverter是用于数据绑定的强大的武器,它用于Value在Binding Source和Binding Target之间的转换。
935 0
[UWP]使用Acrylic(亚克力)
原文:[UWP]使用Acrylic(亚克力) 1. 前言 在 如何使用Fluent Design System 这篇文章里已经简单介绍过Reveal的用法,这篇再详细介绍其它内容。 自Windows 8 放弃Aero后,群众对毛玻璃回归的呼声一致都很大。
1496 0
|
搜索推荐 API 开发者
简单说一下UWP中的JumpList
原文:简单说一下UWP中的JumpList   在Windows10的10856这个版本中,微软为桌面版提供了一组新的应用交互方式,磁贴和Toast通知的个性化都有了一定的改善。针对磁贴方面,微软为我们提供了一组新的API来扩充我们对应用的交互方式——JumpList。
789 0
|
数据安全/隐私保护 安全 API
win10 uwp ApplicationView
原文:win10 uwp ApplicationView 本文和大家介绍一个重要的类,他可以用来设置窗口,如设置启动大小,设置是否允许截图,是否进入全屏,所有和窗口有关的,都可以在他这里设置。
1176 0
win10 uwp 打包第三方字体到应用
原文:win10 uwp 打包第三方字体到应用 有时候我们会把一些特殊字体打包到软件,因为如果找不到我们的字体会变为默认,现在很多字体图标我们用得好,有时候我们的应用会用很漂亮的字体,需要我们自己打包,因为用户一般是没有字体。
1059 0
|
C# 数据格式 XML
[UWP]了解TypeConverter
原文:[UWP]了解TypeConverter 1. 前言 TypeConverter是XAML解释器的幕后功臣,它做了大量工作,从WPF诞生以来,几乎每一次XAML的运作都有它的参与。虽然UWP中TypeConverter已经彻彻底底退居幕后,连自定义TypeConverver都不可以,但了解TypeConverter的原理对理解XAML解析器的运作方式总是有帮助的。
1351 0