Flutter 仿QQ消息拖拽(贝塞尔曲线实现)

Flutter 仿qq消息拖拽效果通过自定义view实现,效果如下


拖拽.gif

Flutter 仿QQ消息拖拽(贝塞尔曲线实现)_第1张图片
细节.png
  1. 如果要实现最终的效果,首先绘制拖拽连接处的线(很长矩形).
  2. 手指拖拽时,为了保证矩形宽度不变,计算矩形四个点的动态坐标,
  3. 通过Path连接,将上下两边用贝塞尔曲线替换.
  4. 最后两边绘制圆形,隐藏矩形尖角.
var angleA = atan((during.dx - end.dx) / (end.dy - during.dy));
var temp_dx = cos(angleA) * lineWidth;
var temp_dy = sin(angleA) * lineWidth;
var firstControlPoint = Offset(end.dx + (during.dx - end.dx) / 2, during.dy + (end.dy - during.dy) / 2);
var firstPoint = Offset(during.dx + temp_dx, during.dy + temp_dy);
var secondPoint = Offset(end.dx - temp_dx * ratio, end.dy - temp_dy * ratio);

/**
  p1                          p3
    |------------------------|
    |                        |
    |                        |
    |------------------------|
  p2                          p4
*/
// 原点 -> p1
path.moveTo(end.dx - temp_dx * ratio, end.dy - temp_dy * ratio);
// p1 -> p2
path.lineTo(end.dx + temp_dx * ratio, end.dy + temp_dy * ratio);
// p2 -> p4
path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy, firstPoint.dx, firstPoint.dy);
// p4 -> p3
path.lineTo(during.dx - temp_dx, during.dy - temp_dy);
// p3 -> p1
path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy, secondPoint.dx, secondPoint.dy);

canvas.drawPath(path, paint);
canvas.drawCircle(end, lineWidth * ratio, paint);
canvas.drawCircle(during, lineWidth, paint);

如有问题欢迎留言指正.

演示Demo下载

你可能感兴趣的:(Flutter 仿QQ消息拖拽(贝塞尔曲线实现))