前言
提示:仿照手机qq未读红点拖拽粘连效果
贝塞尔曲线的应用非常广泛,本篇文章将使用Winform贝塞尔曲线来实现QQ未读红点拖拽粘连的效果
手机QQ粘连效果
最终实现的效果
分析效果
- 1.可以看出随着拖拽的距离变大,固定点的圆会逐渐变小
- 2.粘连效果是一个由两个小球边缘位置贝塞尔曲线构成,所以需要计算出两个小球边缘的点 A,B,C,D和两条贝塞尔曲线的控制点E,F
核心公式
计算按下的位置到中心点的距离
通过公式c^2 = a^2+b^2
带入到代码为
// 计算两点距离公式 c^2 = a^2+b^2
int y2 = mouse_point.Y - (this.Height / 2);
int x2 = mouse_point.X - (this.Width / 2);
distance = Math.Sqrt(y2 * y2 + x2 * x2);
计算出按下位置到中心点的角度
// 计算角度公式
degree = Math.Atan2(y2, x2) * 180 / Math.PI;
Console.WriteLine(degree);
边缘点的计算
边缘的点的可以用三角函数公式计算得到
// 小球一侧的点
var angle = (degree + 90) / 180 * Math.PI;
float x1 = Convert.ToSingle(radius * 0.5f * Math.Cos(angle) + (this.Width / 2));
float y1 = Convert.ToSingle(radius * 0.5f * Math.Sin(angle) + (this.Height / 2));
// 另一侧的点
var angle2 = (degree - 90) / 180 * Math.PI;
float x2 = Convert.ToSingle(radius * 0.5f * Math.Cos(angle2) + (this.Width / 2));
float y2 = Convert.ToSingle(radius * 0.5f * Math.Sin(angle2) + (this.Height / 2));
贝塞尔控制点的计算
两个控制点的位置刚刚在球心连线的1/4和3/4处
// 两个圆之间的1/4 和 3/4 点,就是三阶贝塞尔的两个控制点
var angle3 = degree / 180 * Math.PI;
float control_x1 = Convert.ToSingle(distance * 0.25f * Math.Cos(angle3) + (this.Width / 2));
float control_y1 = Convert.ToSingle(distance * 0.25f * Math.Sin(angle3) + (this.Height / 2));
float control_x2 = Convert.ToSingle(distance * 0.75 * Math.Cos(angle3) + (this.Width / 2));
float control_y3 = Convert.ToSingle(distance * 0.75 * Math.Sin(angle3) + (this.Height / 2));
完整代码
本效果有使用C#语言实现,其他语言道理相同
1.创建自定义控件 重写OnMouseDown
OnMouseUp
OnMouseMove
方法来获取当前鼠标响应的事件
2.重写控件的OnPaint
方法, 绘制出中心点和鼠标按下的点
3.使用GraphicsPath
添加贝塞尔曲线,并连接各点,填充实现
点这里下载完整源码