0

我正在颤动的画布上绘制文本和其他对象。

我想检测鼠标何时悬停在画布上呈现的某些文本上。

TextSpan 类具有recognizer以及onEnter和的属性onExit

当在画布上绘制文本跨度时,它们似乎没有被调用。

我是否需要自己为 Canvas 上的文本编写命中测试逻辑?

4

1 回答 1

2

我找不到按照您的意愿执行此操作的方法,但是我已经能够使用不同的方法来执行此操作。在这个例子中,我CustomPaint用 a包装MouseRegion(因为我用颤振网络测试它,你可以用InkWellor为手机重新创建它GestureDetector),然后我检查鼠标的 localPosition 是否在TextPainter. 我正在创建TextPainter外部CustomPainter,因为我希望整个画布的大小是TextPainter' 的两倍。

class GestureText extends StatefulWidget {
  const GestureText(this.text, {required this.style, this.maxWidth, Key? key})
      : super(key: key);
  final String text;
  final TextStyle style;
  final double? maxWidth;

  @override
  _GestureTextState createState() => _GestureTextState();
}

class _GestureTextState extends State<GestureText> {

  Offset? mousePosition;

  @override
  Widget build(BuildContext context) {
    final TextPainter textPainter = TextPainter(
      text: TextSpan(
        text: widget.text,
        style: widget.style,
      ),
      textDirection: TextDirection.ltr,
    )..layout(maxWidth: widget.maxWidth ?? double.infinity);

    return Container(
      child: MouseRegion(
        onHover: (e){
          setState(() {
            mousePosition = e.localPosition;
          });
        },
        onExit: (e){
          setState(() {
            mousePosition = null;
          });
        },
        child: CustomPaint(
          size: Size(textPainter.size.width*2, textPainter.size.width*2),
          painter: GestureTextPainter(textPainter, mousePosition),
        ),
      ),
    );
  }
}

class GestureTextPainter extends CustomPainter {
  const GestureTextPainter(this.textPainter, this.mousePosition);

  final TextPainter textPainter;
  final Offset? mousePosition;

  @override
  void paint(Canvas canvas, Size size) {

    final textOffset = Offset(size.width/2  - textPainter.width/2, size.height/2 - textPainter.height/2); 
// So that the text is in the middle of the canvas

    final textRect = Rect.fromLTWH(textOffset.dx, textOffset.dy, textPainter.width, textPainter.height);


    if(mousePosition != null && textRect.contains(mousePosition!)){
      canvas.drawRect(textRect, Paint()..color=Colors.amber);
    }

    textPainter.paint(canvas, textOffset);

  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
于 2021-07-11T18:38:52.270 回答