feat(eraser): configurable size + stroke-eraser mode
Some checks failed
CI / Windows build (push) Has been cancelled

"优化橡皮擦工具,你优化在哪" — the eraser already did segment erase, but
the radius was a hardcoded const with no size control and no whole-stroke
mode. Add both, OneNote/Notability-style:

- PenConfig: eraserRadius (0.005-0.1, default 0.02) + eraserWholeStroke
  bool, with copyWith / JSON / setters.
- PenCanvas: uses widget.eraserRadius for the live hit area AND the cursor
  preview (they stay in sync); eraserWholeStroke=true removes the whole
  stroke on contact, false keeps the segment-split behavior.
- pen_editor threads both from PenConfig.
- pen-settings: new Eraser section — size slider + "Stroke Eraser" switch.

Tests: pen_eraser_mode_widget proves point-eraser keeps the untouched ends
while stroke-eraser deletes the whole stroke from the same pass.

flutter analyze: 0 issues.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-23 09:47:58 +08:00
parent 299b9546a8
commit 4fb431727e
5 changed files with 192 additions and 12 deletions

View File

@@ -161,6 +161,31 @@ class _PenSettingsSheet extends StatelessWidget {
formatValue: (v) => v.toStringAsFixed(4),
onChanged: controller.setHighlighterWidth,
),
// ── Eraser ────────────────────────────────────────────────
_SectionHeader(
title: 'Eraser',
icon: Icons.cleaning_services_outlined,
colorScheme: colorScheme,
),
_SliderTile(
label: 'Eraser Size',
value: config.eraserRadius,
min: 0.005,
max: 0.1,
divisions: 19,
formatValue: (v) => v.toStringAsFixed(3),
onChanged: controller.setEraserRadius,
),
SwitchListTile(
title: const Text('Stroke Eraser'),
subtitle: const Text(
'Erase a whole stroke on contact (off: erase by segment)',
),
value: config.eraserWholeStroke,
onChanged: controller.setEraserWholeStroke,
contentPadding: EdgeInsets.zero,
),
],
);
},