import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) =>
      MaterialApp(theme: ThemeData(), home: MyHomePage());
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: ripplePointer, // 引数が同じだとこうやって短く書ける
      child: Scaffold(
        body: offset != null
            ? CustomPaint(painter: RipplePainter(offset: offset))
            : const SizedBox(),
      ),
    );
  }

  Offset offset;
  void ripplePointer(TapDownDetails details) {
    // 単純に offset を更新しているだけ
    setState(() {
      offset = details.globalPosition;
      print(details.globalPosition);
    });
  }
}

class RipplePainter extends CustomPainter {
  RipplePainter({@required this.offset});
  final Offset offset;
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..style = PaintingStyle.stroke // 図形をぬりつずつかどうか
      ..color = Colors.blue // 色の指定
      ..strokeWidth = 2; // 線の太さの指定
    canvas.drawCircle(offset, 100, paint); // 位置と輪っかの大きさを指定
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.