美文网首页
Flutter 仿QQ消息拖拽(贝塞尔曲线实现)

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

作者: Boyko | 来源:发表于2019-05-07 19:22 被阅读0次

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


    拖拽.gif
    细节.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消息拖拽(贝塞尔曲线实现)

          本文链接:https://www.haomeiwen.com/subject/gibyoqtx.html