WPF水珠效果按钮组

二次贝塞尔曲线,二次贝塞尔曲线

效果图

澳门蒲京网址 1

 

效果图

澳门蒲京网址 2

 

连锁文化

那有的骨干就是废话,网上都能找到,作者只不过是收拾了以下.指出先不看,用到的时候可以回来看望

连锁文化

那有的骨干就是废话,网上都能找到,作者只不过是整治了以下.提出先不看,用到的时候可以回来看望

贝塞尔曲线

先来看两组图,有助于精晓什么是贝塞尔曲线澳门蒲京网址 3(图片取自维基百科,参考链接1)

2次贝塞尔曲线:

澳门蒲京网址 4澳门蒲京网址 5

P0是起源,P2是终点,P1是控制点

一遍贝塞尔曲线:

澳门蒲京网址 6澳门蒲京网址 7

 P0是起源,P3是终极,P1是控制点1,P2是控制点2

各样连接全数点,组成线段

t是比例,在0-1之间,就是每条线段的尺寸都以1

贝塞尔曲线就是最里层的线条在t地点的点所组成的路子

三遍贝塞尔曲线公式:B(t)=(1-t)^3*P0+3(1-t)^2*t*澳门蒲京网址,P1+3(1-t)*t^2*P2+t^3*P3,0<=t<=1

B(t)表示曲线上任意点,P0,1,2,3独家表示决定曲线的四个点,t代表曲线长度为1的任性取值

贝塞尔曲线

先来看两组图,有助于了然什么是贝塞尔曲线澳门蒲京网址 8(图片取自维基百科,参考链接1)

三次贝塞尔曲线:

澳门蒲京网址 9澳门蒲京网址 10

P0是源点,P2是极限,P1是控制点

三遍贝塞尔曲线:

澳门蒲京网址 11澳门蒲京网址 12

 P0是源点,P3是终端,P1是控制点1,P2是控制点2

逐条连接全部点,组成线段

t是比例,在0-1之间,就是每条线段的长短都以1

贝塞尔曲线就是最里层的线条在t地点的点所组成的路线

一次贝塞尔曲线公式:B(t)=(1-t)^3*P0+3(1-t)^2*t*P1+3(1-t)*t^2*P2+t^3*P3,0<=t<=1

B(t)代表曲线上任意点,P0,1,2,3分头表示决定曲线的陆个点,t代表曲线长度为1的肆意取值

别的文化

没接触过贝塞尔曲线的话,或然得花些时间整治下,其他的文化就相比简单了

澳门蒲京网址 13

直角三角形,角A的对边a,临边b,斜边c

三角形函数:

sinA=a/c

cosA=b/c

勾股定理:

c^2=a^2+b^2

任何文化

没接触过贝塞尔曲线的话,大概得花些时间整理下,其余的文化就相比简单了

澳门蒲京网址 14

直角三角形,角A的对边a,临边b,斜边c

三角形函数:

sinA=a/c

cosA=b/c

勾股定理:

c^2=a^2+b^2

回顾介绍

其一功用难点就两片段:一是水球分离和融合时候的一连,二是宗旨圆的震荡

唯独实际上网上都有缓解方案了

第二局部是在五个圆之间加个用贝塞尔曲线组成的path,用相同的颜色,其实是障眼法.见参考链接4

第叁片段是用4段一回贝塞尔曲线组成的path代替Ellipse,因为Ellipse是颠簸不起来的,那样就足以操纵贝塞尔曲线的点来让圆抖动.见参考链接3

归纳介绍

那几个职能难点就两局地:一是水球分离和融合时候的连日,二是主题圆的颠簸

然则事实上网上都有消除方案了

首先部分是在三个圆之间加个用贝塞尔曲线组成的path,用同一的水彩,其实是障眼法.见参考链接4

其次有个别是用4段一回贝塞尔曲线组成的path代替Ellipse,因为Ellipse是振动不起来的,那样就能够操纵贝塞尔曲线的点来让圆抖动.见参考链接3

中心的大圆

重点的大圆

Path画法

主体的大圆是个ToggleButton,替换模版,背景换到贝塞尔曲线组成的圆.

各种贝塞尔曲线的起源和终端就背着了,非凡简单,那里首要说说控制点.

澳门蒲京网址 15

测算出肆分之一圆弧的高中级地点的点,此时t=0.5, 三角型边长h=sin45*r

让决定点P1,P2分别在源点和终点的切线上,P1到X轴的相距等于P2到Y轴的距离L

B(0.5)=h=sin45*r=(1-0.5)^3*0+3*(1-0.5)^2*0.5*L+3*(1-0.5)*0.5^2*r+0.5^3*r

sin45*r=0+0.375*L+0.375*r+0.125*r

L=(sin45*r-0.5*r)/0.375

于是乎多少个控制点(r,L)和(L,r)可以规定

求出来的三个点是数学的坐标,要转换来程序的坐标,对应成5个象限,无非就是加减半径,加减L,不细说了

完全的path,取半径是50,见代码

澳门蒲京网址 16澳门蒲京网址 17

 1 <Path>
 2     <Path.Data>
 3         <PathGeometry>
 4             <PathFigure StartPoint="50,0">
 5                 <BezierSegment Point1="77.614237491541,0" Point2="100,22.385762508459" Point3="100,50"></BezierSegment>
 6                 <BezierSegment Point1="100,77.614237491541" Point2="77.614237491541,100" Point3="50,100"></BezierSegment>
 7                 <BezierSegment Point1="22.385762508459,100" Point2="0,77.614237491541" Point3="0,50"></BezierSegment>
 8                 <BezierSegment Point1="0,22.385762508459" Point2="22.385762508459,0" Point3="50,0"></BezierSegment>
 9             </PathFigure>
10         </PathGeometry>
11     </Path.Data>
12 </Path>

View Code

Path画法

主体的大圆是个ToggleButton,替换模版,背景换来贝塞尔曲线组成的圆.

各种贝塞尔曲线的起源和终点就背着了,十二分简单,那里根本说说控制点.

澳门蒲京网址 18

统计出肆分一半圆的高中级地方的点,此时t=0.5, 三角型边长h=sin45*r

让决定点P1,P2分别在源点和终极的切线上,P1到X轴的离开等于P2到Y轴的距离L

B(0.5)=h=sin45*r=(1-0.5)^3*0+3*(1-0.5)^2*0.5*L+3*(1-0.5)*0.5^2*r+0.5^3*r

sin45*r=0+0.375*L+0.375*r+0.125*r

L=(sin45*r-0.5*r)/0.375

于是乎多个控制点(r,L)和(L,r)能够规定

求出来的五个点是数学的坐标,要转换到程序的坐标,对应成六个象限,无非就是加减半径,加减L,不细说了

完全的path,取半径是50,见代码

澳门蒲京网址 19澳门蒲京网址 20

 1 <Path>
 2     <Path.Data>
 3         <PathGeometry>
 4             <PathFigure StartPoint="50,0">
 5                 <BezierSegment Point1="77.614237491541,0" Point2="100,22.385762508459" Point3="100,50"></BezierSegment>
 6                 <BezierSegment Point1="100,77.614237491541" Point2="77.614237491541,100" Point3="50,100"></BezierSegment>
 7                 <BezierSegment Point1="22.385762508459,100" Point2="0,77.614237491541" Point3="0,50"></BezierSegment>
 8                 <BezierSegment Point1="0,22.385762508459" Point2="22.385762508459,0" Point3="50,0"></BezierSegment>
 9             </PathFigure>
10         </PathGeometry>
11     </Path.Data>
12 </Path>

View Code

振动动画

是因为圆是被十三个点控制的,让圆抖动,约等于对十一个点做点动画

可以用关键帧动画,那样控制的相比较缜密,要留心的是,衔接的地点要平滑.我那里做的相比简陋,就找了多个变换后的图片,重复了六遍.倘使你有趣味,能够多做些,做的越来越多,动画看起来表现力越强

那边小编并从未去商讨怎么着算法,就是简单的在blend里,找了一部分点

见代码:

澳门蒲京网址 21澳门蒲京网址 22

 1 <EventTrigger RoutedEvent="Click">
 2     <BeginStoryboard>
 3         <Storyboard>
 4             <PointAnimationUsingKeyFrames Storyboard.TargetName="pf_main" Storyboard.TargetProperty="StartPoint" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
 5                 <EasingPointKeyFrame Value="40,0" KeyTime="0:0:0.2"></EasingPointKeyFrame>
 6             </PointAnimationUsingKeyFrames>
 7             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main0" Storyboard.TargetProperty="Point1" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
 8                 <EasingPointKeyFrame Value="68,-10" KeyTime="0:0:0.2"></EasingPointKeyFrame>
 9             </PointAnimationUsingKeyFrames>
10             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main0" Storyboard.TargetProperty="Point2" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
11                 <EasingPointKeyFrame Value="115,14" KeyTime="0:0:0.2"></EasingPointKeyFrame>
12             </PointAnimationUsingKeyFrames>
13             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main0" Storyboard.TargetProperty="Point3" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
14                 <EasingPointKeyFrame Value="100,66" KeyTime="0:0:0.2"></EasingPointKeyFrame>
15             </PointAnimationUsingKeyFrames>
16             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main1" Storyboard.TargetProperty="Point1" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
17                 <EasingPointKeyFrame Value="100,67" KeyTime="0:0:0.2"></EasingPointKeyFrame>
18             </PointAnimationUsingKeyFrames>
19             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main1" Storyboard.TargetProperty="Point2" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
20                 <EasingPointKeyFrame Value="85,111" KeyTime="0:0:0.2"></EasingPointKeyFrame>
21             </PointAnimationUsingKeyFrames>
22             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main1" Storyboard.TargetProperty="Point3" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
23                 <EasingPointKeyFrame Value="33,103" KeyTime="0:0:0.2"></EasingPointKeyFrame>
24             </PointAnimationUsingKeyFrames>
25             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main2" Storyboard.TargetProperty="Point1" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
26                 <EasingPointKeyFrame Value="22,103" KeyTime="0:0:0.2"></EasingPointKeyFrame>
27             </PointAnimationUsingKeyFrames>
28             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main2" Storyboard.TargetProperty="Point2" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
29                 <EasingPointKeyFrame Value="-15,85" KeyTime="0:0:0.2"></EasingPointKeyFrame>
30             </PointAnimationUsingKeyFrames>
31             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main2" Storyboard.TargetProperty="Point3" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
32                 <EasingPointKeyFrame Value="-6,50" KeyTime="0:0:0.2"></EasingPointKeyFrame>
33             </PointAnimationUsingKeyFrames>
34             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main3" Storyboard.TargetProperty="Point1" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
35                 <EasingPointKeyFrame Value="4,9" KeyTime="0:0:0.2"></EasingPointKeyFrame>
36             </PointAnimationUsingKeyFrames>
37             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main3" Storyboard.TargetProperty="Point2" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
38                 <EasingPointKeyFrame Value="41,-1" KeyTime="0:0:0.2"></EasingPointKeyFrame>
39             </PointAnimationUsingKeyFrames>
40             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main3" Storyboard.TargetProperty="Point3" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
41                 <EasingPointKeyFrame Value="42,0" KeyTime="0:0:0.2"></EasingPointKeyFrame>
42             </PointAnimationUsingKeyFrames>
43         </Storyboard>
44     </BeginStoryboard>
45 </EventTrigger>

View Code

振动动画

鉴于圆是被13个点控制的,让圆抖动,约等于对拾3个点做点动画

可以用关键帧动画,那样控制的相比较细致,要注意的是,衔接的地点要平滑.笔者那里做的相比较简陋,就找了一个转移后的图形,重复了7次.假使你有趣味,能够多做些,做的越多,动画看起来表现力越强

此间笔者并没有去探究怎么算法,就是不难的在blend里,找了部分点

见代码:

澳门蒲京网址 23澳门蒲京网址 24

 1 <EventTrigger RoutedEvent="Click">
 2     <BeginStoryboard>
 3         <Storyboard>
 4             <PointAnimationUsingKeyFrames Storyboard.TargetName="pf_main" Storyboard.TargetProperty="StartPoint" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
 5                 <EasingPointKeyFrame Value="40,0" KeyTime="0:0:0.2"></EasingPointKeyFrame>
 6             </PointAnimationUsingKeyFrames>
 7             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main0" Storyboard.TargetProperty="Point1" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
 8                 <EasingPointKeyFrame Value="68,-10" KeyTime="0:0:0.2"></EasingPointKeyFrame>
 9             </PointAnimationUsingKeyFrames>
10             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main0" Storyboard.TargetProperty="Point2" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
11                 <EasingPointKeyFrame Value="115,14" KeyTime="0:0:0.2"></EasingPointKeyFrame>
12             </PointAnimationUsingKeyFrames>
13             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main0" Storyboard.TargetProperty="Point3" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
14                 <EasingPointKeyFrame Value="100,66" KeyTime="0:0:0.2"></EasingPointKeyFrame>
15             </PointAnimationUsingKeyFrames>
16             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main1" Storyboard.TargetProperty="Point1" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
17                 <EasingPointKeyFrame Value="100,67" KeyTime="0:0:0.2"></EasingPointKeyFrame>
18             </PointAnimationUsingKeyFrames>
19             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main1" Storyboard.TargetProperty="Point2" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
20                 <EasingPointKeyFrame Value="85,111" KeyTime="0:0:0.2"></EasingPointKeyFrame>
21             </PointAnimationUsingKeyFrames>
22             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main1" Storyboard.TargetProperty="Point3" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
23                 <EasingPointKeyFrame Value="33,103" KeyTime="0:0:0.2"></EasingPointKeyFrame>
24             </PointAnimationUsingKeyFrames>
25             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main2" Storyboard.TargetProperty="Point1" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
26                 <EasingPointKeyFrame Value="22,103" KeyTime="0:0:0.2"></EasingPointKeyFrame>
27             </PointAnimationUsingKeyFrames>
28             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main2" Storyboard.TargetProperty="Point2" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
29                 <EasingPointKeyFrame Value="-15,85" KeyTime="0:0:0.2"></EasingPointKeyFrame>
30             </PointAnimationUsingKeyFrames>
31             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main2" Storyboard.TargetProperty="Point3" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
32                 <EasingPointKeyFrame Value="-6,50" KeyTime="0:0:0.2"></EasingPointKeyFrame>
33             </PointAnimationUsingKeyFrames>
34             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main3" Storyboard.TargetProperty="Point1" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
35                 <EasingPointKeyFrame Value="4,9" KeyTime="0:0:0.2"></EasingPointKeyFrame>
36             </PointAnimationUsingKeyFrames>
37             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main3" Storyboard.TargetProperty="Point2" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
38                 <EasingPointKeyFrame Value="41,-1" KeyTime="0:0:0.2"></EasingPointKeyFrame>
39             </PointAnimationUsingKeyFrames>
40             <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main3" Storyboard.TargetProperty="Point3" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
41                 <EasingPointKeyFrame Value="42,0" KeyTime="0:0:0.2"></EasingPointKeyFrame>
42             </PointAnimationUsingKeyFrames>
43         </Storyboard>
44     </BeginStoryboard>
45 </EventTrigger>

View Code

item

item

按钮的地方

不管是奇数个,依旧偶数个,大家都想让它以Y轴对称

先是把圆分成8等份,每一份都以45度,相当于最五只好放下七个item,

澳门蒲京网址 25

 

从上图可以看出来,其实就是奇数个在线上,偶数个在两线时期

有个简单的艺术,就是先在巅峰依次顺时针排列,各个item间隔45度,然后再逆时针转动,每多二个item就多转45/2度(两条分割线是45度,中间约等于45/2度),如下图:

澳门蒲京网址 26

 上图是item终点的职位,源点的位置是在圆心.

动画片用DoubleAnimation控制item按钮的位移,从圆心移动到总结后的地点

 统计地方的代码:

//函数是弧度制 2PI是360度
a = c * Math.Sin(2 * Math.PI / 8 * i – (itemsSource.Count – 1) * 2
* Math.PI / 8 / 2);
b = c * Math.Cos(2 * Math.PI / 8 * i – (itemsSource.Count – 1) * 2
* Math.PI / 8 / 2);

按钮的职位

任由是奇数个,依然偶数个,大家都想让它以Y轴对称

先是把圆分成8等份,每一份都是45度,也等于最四只能放下八个item,

澳门蒲京网址 27

 

从上图可以看出来,其实就是奇数个在线上,偶数个在两线时期

有个不难的主意,就是先在终极依次顺时针排列,每一个item间隔45度,然后再逆时针转动,每多1个item就多转45/2度(两条分割线是45度,中间相当于45/2度),如下图:

澳门蒲京网址 28

 上图是item终点的职位,源点的职位是在圆心.

卡通用DoubleAnimation控制item按钮的活动,从圆心移动到统计后的职位

 统计地点的代码:

//函数是弧度制 2PI是360度
a = c * Math.Sin(2 * Math.PI / 8 * i – (itemsSource.Count – 1) * 2
* Math.PI / 8 / 2);
b = c * Math.Cos(2 * Math.PI / 8 * i – (itemsSource.Count – 1) * 2
* Math.PI / 8 / 2);

水球连接的局地

总是的一部分是用八个二遍贝塞尔和一条直线做二个path

澳门蒲京网址 29

发轫的时候,两条贝塞尔曲线的万丈是0,控制点在path所在矩形的一侧,然后对而塞尔曲线上边的点和控制点做动画,分别进步和内移动,最后形成上图右侧的图形,然后把这几个动画和item按钮向外部移动的动画组成起来,就伪装成了水球分离的效果.

澳门蒲京网址 30

 上图草地绿矩形就是两次三番部分的path.动画的进度就是Item按钮的直径和大圆相交的时候初步和item按钮一起做动画,最终移动到Item按钮直径所在的地点,整个距离就是Item的半径+item到重点的偏离+粉红白的d,而浅灰褐的d可以经过公式求出

开班的时候也是让连接部分path在圆心的地方.定位方法和定位Item按钮的点子是全然一样的.那里就不在重复了.只说一下c边的偏离是:大圆和小圆圆心的相距-连接path中度的二分一

 

源码下载:WaterDropsButtonGroup.zip 

 

参照连接:

  1. https://en.wikipedia.org/wiki/B%C3%A9zier_curve
  2. https://baike.baidu.com/item/%E8%B4%9D%E5%A1%9E%E5%B0%94%E6%9B%B2%E7%BA%BF/1091769?fr=aladdin
  3. https://www.cnblogs.com/ArthurQQ/articles/1730214.html
  4. http://blog.csdn.net/chouglas/article/details/50967566
水球连接的一些

总是的有的是用七个3回贝塞尔和一条直线做2个path

澳门蒲京网址 31

起来的时候,两条贝塞尔曲线的中度是0,控制点在path所在矩形的两旁,然后对而塞尔曲线上边的点和控制点做动画,分别提升和内活动,最终形成上图左边的图纸,然后把那么些动画和item按钮向外部移动的卡通组成起来,就伪装成了水球分离的效果.

澳门蒲京网址 32

 上图杏黄矩形就是连接部分的path.动画的进度就是Item按钮的直径和大圆相交的时候早先和item按钮一起做动画,最终移动到Item按钮直径所在的职分,整个距离就是Item的半径+item到核心的距离+铅色的d,而浅灰的d可以透过公式求出

初叶的时候也是让连接部分path在圆心的地方.定位方法和固定Item按钮的措施是一心平等的.那里就不在重复了.只说一下c边的离开是:大圆和小圆圆心的偏离-连接path高度的5/10

 

源码下载:WaterDropsButtonGroup.zip 

 

参照连接:

  1. https://en.wikipedia.org/wiki/B%C3%A9zier_curve
  2. https://baike.baidu.com/item/%E8%B4%9D%E5%A1%9E%E5%B0%94%E6%9B%B2%E7%BA%BF/1091769?fr=aladdin
  3. https://www.cnblogs.com/ArthurQQ/articles/1730214.html
  4. http://blog.csdn.net/chouglas/article/details/50967566