WPF beads effect button group implementation tutorial

Time:2020-7-13

design sketch

Related knowledge

This part is basically nonsense. You can find it on the Internet. I just sorted out the following. I suggest not to read it. You can come back and have a look when you use it

Bezier curve

Let’s take a look at two sets of graphs to help you understand what a Bezier curve is

Quadratic Bezier curve:

P0 is the starting point, P2 is the end point and P1 is the control point

Cubic Bezier curve:

P0 is the starting point, P2 is the end point, P1 is the control point 1 and P2 is the control point 2

Connect all points in turn to form a line segment

T is the scale, between 0 and 1, that is, the length of each line segment is 1

Bessel curve is the path of the innermost line segment at t position

Cubic Bessel curve formula: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) represents any point on the curve, P0, 1, 2 and 3 represent the four points determining the curve respectively, and T represents any value of curve length of 1

Other knowledge

If you don’t know Bezier curve, you may have to take some time to sort out, and other knowledge will be relatively simple

Right triangle, opposite side a of angle a, edge B, hypotenuse C

Trigonometric function:

sinA=a/c

cosA=b/c

Pythagorean theorem:

c^2=a^2+b^2

General introduction

This effect is difficult in two parts: one is the connection of water ball separation and fusion, and the other is the shaking of the main body circle

However, there are solutions on the Internet

The first part is to add a path composed of Bezier curve between two circles, using the same color, which is actually a blind eye. See reference link 4

In the second part, the path composed of four cubic Bezier curves is used instead of ellipse, because the ellipse can’t shake, so the points of Bezier curve can be controlled to make the circle jitter. See reference link 3

The great circle of the subject

Path drawing

The big circle of the main body is a togglebutton, and the background is a circle composed of Bezier curves

The starting point and end point of each Bezier curve are not mentioned, very simple, here we mainly talk about control points

Calculate the point in the middle of 1 / 4 arc, where t = 0.5, triangle side length H = sin45 * r

Let the control points P1 and P2 be on the tangent lines of the starting point and the end point respectively, and the distance between P1 and X axis is equal to the distance L between P2 and Y axis

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

Therefore, two control points (R, l) and (L, R) can be determined

The two points obtained are mathematical coordinates. If you want to convert them into the coordinates of the program, they correspond to four quadrants. They are nothing more than the radius of addition and subtraction, and the addition and subtraction of L, I will not elaborate

Complete path, take radius is 50, see code


<Path>
 <Path.Data>
 <PathGeometry>
  <PathFigure StartPoint="50,0">
  <BezierSegment Point1="77.614237491541,0" Point2="100,22.385762508459" Point3="100,50"></BezierSegment>
  <BezierSegment Point1="100,77.614237491541" Point2="77.614237491541,100" Point3="50,100"></BezierSegment>
  <BezierSegment Point1="22.385762508459,100" Point2="0,77.614237491541" Point3="0,50"></BezierSegment>
  <BezierSegment Point1="0,22.385762508459" Point2="22.385762508459,0" Point3="50,0"></BezierSegment>
  </PathFigure>
 </PathGeometry>
 </Path.Data>
</Path>

Jiggle animation

Because the circle is controlled by 12 points, let the circle shake, that is to do some animation on the 12 points

You can use keyframe animation, so the control is more detailed. It should be noted that the connection should be smooth. What I did here is relatively simple. I found a transformed graph and repeated it 5 times. If you are interested, you can do more. The more you do, the more expressive the animation looks

I didn’t study any algorithm here, but I simply found some points in blend

See code:


<EventTrigger RoutedEvent="Click">
 <BeginStoryboard>
 <Storyboard>
  <PointAnimationUsingKeyFrames Storyboard.TargetName="pf_main" Storyboard.TargetProperty="StartPoint" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
  <EasingPointKeyFrame Value="40,0" KeyTime="0:0:0.2"></EasingPointKeyFrame>
  </PointAnimationUsingKeyFrames>
  <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main0" Storyboard.TargetProperty="Point1" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
  <EasingPointKeyFrame Value="68,-10" KeyTime="0:0:0.2"></EasingPointKeyFrame>
  </PointAnimationUsingKeyFrames>
  <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main0" Storyboard.TargetProperty="Point2" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
  <EasingPointKeyFrame Value="115,14" KeyTime="0:0:0.2"></EasingPointKeyFrame>
  </PointAnimationUsingKeyFrames>
  <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main0" Storyboard.TargetProperty="Point3" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
  <EasingPointKeyFrame Value="100,66" KeyTime="0:0:0.2"></EasingPointKeyFrame>
  </PointAnimationUsingKeyFrames>
  <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main1" Storyboard.TargetProperty="Point1" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
  <EasingPointKeyFrame Value="100,67" KeyTime="0:0:0.2"></EasingPointKeyFrame>
  </PointAnimationUsingKeyFrames>
  <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main1" Storyboard.TargetProperty="Point2" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
  <EasingPointKeyFrame Value="85,111" KeyTime="0:0:0.2"></EasingPointKeyFrame>
  </PointAnimationUsingKeyFrames>
  <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main1" Storyboard.TargetProperty="Point3" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
  <EasingPointKeyFrame Value="33,103" KeyTime="0:0:0.2"></EasingPointKeyFrame>
  </PointAnimationUsingKeyFrames>
  <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main2" Storyboard.TargetProperty="Point1" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
  <EasingPointKeyFrame Value="22,103" KeyTime="0:0:0.2"></EasingPointKeyFrame>
  </PointAnimationUsingKeyFrames>
  <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main2" Storyboard.TargetProperty="Point2" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
  <EasingPointKeyFrame Value="-15,85" KeyTime="0:0:0.2"></EasingPointKeyFrame>
  </PointAnimationUsingKeyFrames>
  <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main2" Storyboard.TargetProperty="Point3" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
  <EasingPointKeyFrame Value="-6,50" KeyTime="0:0:0.2"></EasingPointKeyFrame>
  </PointAnimationUsingKeyFrames>
  <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main3" Storyboard.TargetProperty="Point1" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
  <EasingPointKeyFrame Value="4,9" KeyTime="0:0:0.2"></EasingPointKeyFrame>
  </PointAnimationUsingKeyFrames>
  <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main3" Storyboard.TargetProperty="Point2" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
  <EasingPointKeyFrame Value="41,-1" KeyTime="0:0:0.2"></EasingPointKeyFrame>
  </PointAnimationUsingKeyFrames>
  <PointAnimationUsingKeyFrames Storyboard.TargetName="bs_main3" Storyboard.TargetProperty="Point3" BeginTime="0:0:0.7" AutoReverse="True" RepeatBehavior="5x" FillBehavior="Stop">
  <EasingPointKeyFrame Value="42,0" KeyTime="0:0:0.2"></EasingPointKeyFrame>
  </PointAnimationUsingKeyFrames>
 </Storyboard>
 </BeginStoryboard>
</EventTrigger>

item

Position of the button

Whether it’s odd or even, we want it to be symmetric on the y-axis

First of all, divide the circle into eight equal parts, each of which is 45 degrees, which means that only eight items can be put down at most,

As can be seen from the above figure, it is actually an odd number of lines, and an even number between two lines

A simple method is to arrange the vertices clockwise first, with an interval of 45 degrees for each item, and then rotate it anticlockwise. For each additional item, turn an additional 45 / 2 degrees (the two split lines are 45 degrees, and the middle is 45 / 2 degrees), as shown in the following figure:

The figure above shows the location of the end of the item, and the location of the starting point is at the center of the circle

Double animation is used to control the displacement of the item button from the center of the circle to the calculated position

Code for calculating location:

//The function is in radians and 2pi is 360 degrees
 1 a = c * Math.Sin(2 * Math.PI / 8 * i - (itemsSource.Count - 1) * 2 * Math.PI / 8 / 2);
 2 b = c * Math.Cos(2 * Math.PI / 8 * i - (itemsSource.Count - 1) * 2 * Math.PI / 8 / 2);

Part of the water ball connection

The connecting part is to make a path with two quadratic BESSELS and a straight line

At the beginning, the height of the two Bezier curves is 0, and the control point is on the edge of the rectangle where the path is located. Then, the points and control points on the above Bezier curve are animated, moving upward and inward respectively, and finally forming the figure on the right of the figure above. Then, combining this animation with the animation of moving the item button outward, the effect of water ball separation is disguised

The red rectangle in the figure above is the path of the connecting part. The animation process is that when the diameter of the item button intersects with the big circle, the animation starts with the item button, and finally moves to the position where the diameter of the item button is located. The whole distance is the radius of the item + the distance from the item to the main body + the blue D, and the blue D can be calculated by the formula

At the beginning, the path of the connecting part is placed at the center of the circle. The positioning method is exactly the same as that of the item button. Here, we will not repeat it. Just say that the distance between the center of the big circle and the small circle – half of the height of the connecting path

Source code download: waterdropsbuttongroup (jb51. Net). Zip

The above WPF bead effect button group implementation tutorial is the small editor to share all the content, I hope to give you a reference, also hope you can support developeppaer.