個人開発者が勉強がてらまとめているだけのサイトです

署名パッド(手書き) Signature Pad

枠の中を指でなぞると、その通りに線が描ける。受け取りのサインや手書きメモに使う。

別名
手書きサイン署名欄手書き入力お絵かき手書きメモサインパッドSignatureDrawing CanvasFree Drawing
動き
なぞると線が描ける消すで真っ白に戻る
作り方
自作 標準ウィジェットの組み合わせで自分で作ります

本物の Flutter ウィジェットが動きます(初回は数秒かかります)

別タブで大きく開く ↗

どんなもの?

GestureDetector の onPanStart で新しい線を始め、onPanUpdate で点を足していき、CustomPaint で線を描きます。

点をそのまま直線でつなぐとカクカクするので、Path の quadraticBezierTo で点と点の中間を通る曲線にすると滑らかになります。

StrokeCap.round と StrokeJoin.round を付けると、線の端と折れ目が丸くなって手書きらしくなります。

「消す」「1つ戻す」と、何も描いていないときに「確定」を押せなくする処理をセットにします。

画像として保存するには、RepaintBoundary で包んで toImage() で書き出します。

こんなときに

  • 受け取りや同意のサイン、手書きのメモ・図

避けたい場面

  • 文字として使いたい入力(手書き文字は読み取りが難しいので、キーボード入力にする)

最小コード

GestureDetector(
  onPanStart: (d) => setState(() => strokes.add([d.localPosition])),
  onPanUpdate: (d) => setState(() => strokes.last.add(d.localPosition)),
  child: CustomPaint(
    painter: _SignaturePainter(strokes),
    size: Size.infinite,
  ),
)

// _SignaturePainter.paint の中
final paint = Paint()
  ..strokeWidth = 3
  ..style = PaintingStyle.stroke
  ..strokeCap = StrokeCap.round
  ..strokeJoin = StrokeJoin.round;
for (final s in strokes) {
  final path = Path()..moveTo(s.first.dx, s.first.dy);
  for (var i = 1; i < s.length - 1; i++) {
    final mid = (s[i] + s[i + 1]) / 2; // 中間点を通る曲線で滑らかに
    path.quadraticBezierTo(s[i].dx, s[i].dy, mid.dx, mid.dy);
  }
  canvas.drawPath(path, paint);
}

使うウィジェット

GestureDetector(onPanStart/onPanUpdate)CustomPaintPath

似ているもの・一緒に見たいもの

触ってみる ↗
ジェスチャー なぞって範囲選択Drag to Select

写真を長押しして、そのまま指をなぞると、なぞった範囲の写真がまとめて選ばれる。

長押しで選択開始
触ってみる ↗
ジェスチャー フリック入力Flick Input

キーを押すと上下左右に候補が十字に出て、払った向きの文字が入る。日本のスマホの文字入力。

押すと十字に候補