Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug report] Unintended Drawing Recorded During Pinch Gestures #66

Closed
enoiu opened this issue Mar 17, 2025 · 3 comments
Closed

[Bug report] Unintended Drawing Recorded During Pinch Gestures #66

enoiu opened this issue Mar 17, 2025 · 3 comments

Comments

@enoiu
Copy link

enoiu commented Mar 17, 2025

Version

0.9.5

Platforms

Android, iOS

Device Model

Pixel 8a (Android 15), iPhone 16 (iOS 18.2, iOS Simulator)

flutter info

[✓] Flutter (Channel stable, 3.27.3, on macOS 15.3.1 24D70 darwin-arm64, locale ja-JP)
    • Flutter version 3.27.3 on channel stable at /Users/enoiu/Developer/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision c519ee916e (8 weeks ago), 2025-01-21 10:32:23 -0800
    • Engine revision e672b006cb
    • Dart version 3.6.1
    • DevTools version 2.40.2

[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.1)
    • Android SDK at /Users/enoiu/Library/Android/sdk
    • Platform android-35, build-tools 35.0.1
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.11+0-17.0.11b1207.24-11852314)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 16.2)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 16C5032a
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2024.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.11+0-17.0.11b1207.24-11852314)

[✓] VS Code (version 1.98.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.106.0

[✓] Connected device (6 available)
    • Pixel 8a (mobile)               • 44031JEKB13569                       • android-arm64  • Android 15 (API 35)
    • iPhone 16 (mobile)              • 8B525797-D328-4ADE-B969-AE9322E2692D • ios            •
      com.apple.CoreSimulator.SimRuntime.iOS-18-2 (simulator)
    • iPad (10th generation) (mobile) • B6909FB2-8DA5-4457-8817-ED31BB154E74 • ios            •
      com.apple.CoreSimulator.SimRuntime.iOS-18-2 (simulator)
    • macOS (desktop)                 • macos                                • darwin-arm64   • macOS 15.3.1 24D70 darwin-arm64
    • Mac Designed for iPad (desktop) • mac-designed-for-ipad                • darwin         • macOS 15.3.1 24D70 darwin-arm64
    • Chrome (web)                    • chrome                               • web-javascript • Google Chrome 134.0.6998.89

[✓] Network resources
    • All expected network resources are available.

• No issues found!

How to reproduce?

Thank you for creating this wonderful package.

When performing pinch gestures (such as pinch-to-zoom) while using the flutter_drawing_board, unintended drawing is recorded.

I attempted to call _drawingBoardController.cancelDraw(); within onInteractionStart, onInteractionUpdate, and onInteractionEnd, but the issue persists.

The following log was recorded when running the example code and repeatedly performing pinch in/out gestures.
Although the pinch gesture does not always record drawing, it does so with a high probability.
As a result, even if nothing appears to be drawn, the undo button becomes enabled.

The same issue can be observed in the demo provided in the Readme.

I would appreciate any guidance on how to resolve this problem.

Logs

Restarted application in 784ms.
I/flutter (19910): onInteractionStart
I/flutter (19910): [Instance of 'SimpleLine']
I/flutter (19910): onInteractionStart
I/flutter (19910): [Instance of 'SimpleLine', Instance of 'SimpleLine']
I/flutter (19910): onInteractionStart
I/flutter (19910): [Instance of 'SimpleLine', Instance of 'SimpleLine', Instance of 'SimpleLine']
I/flutter (19910): onInteractionStart
I/flutter (19910): [Instance of 'SimpleLine', Instance of 'SimpleLine', Instance of 'SimpleLine', Instance of 'SimpleLine']
I/flutter (19910): onInteractionStart
I/flutter (19910): [Instance of 'SimpleLine', Instance of 'SimpleLine', Instance of 'SimpleLine', Instance of 'SimpleLine']

Example code (optional)

import 'package:flutter/material.dart';
import 'package:flutter_drawing_board/flutter_drawing_board.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Drawing Board Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final DrawingController _drawingController = DrawingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Drawing Board Example'),
      ),
      body: LayoutBuilder(
        builder: (context, constraints) {
          return DrawingBoard(
            controller: _drawingController,
            background: Container(
              width: constraints.maxWidth,
              height: constraints.maxHeight,
              color: Colors.white,
            ),
            showDefaultActions: true,
            showDefaultTools: true,
            onInteractionStart: (details) {
              print('onInteractionStart');
              print(_drawingController.getHistory);
              _drawingController.cancelDraw()
            },
          );
        },
      ),
    );
  }
}

Contact

No response

@enoiu
Copy link
Author

enoiu commented Mar 18, 2025

After trying various approaches, I confirmed that unintended drawing is recorded when only onPointerDown is called and onPointerMove or onPointerUp are not called.
Therefore, as a temporary solution, I added a process in the listener to delete this drawing in such cases, as shown in the code below.

This has resolved the issue, so there is no urgent need to address it immediately; however, I would appreciate it if you could fix this issue when you have time.

import 'package:flutter/material.dart';
import 'package:flutter_drawing_board/flutter_drawing_board.dart';
import 'package:flutter_drawing_board/paint_contents.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Drawing Board Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final DrawingController _drawingController = DrawingController();

  void _listener() {
    print('listener');

    if (_isPointerDown) {
      List<PaintContent> contents = List.of(_drawingController.getHistory);
      contents.removeLast();
      _drawingController.clear();
      _drawingController.addContents(contents);
      print('listener: history changed');
    }
    print(_drawingController.getHistory);
  }

  @override
  void initState() {
    super.initState();
    _drawingController.addListener(_listener);
  }

  bool _isPointerDown = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Drawing Board Example'),
      ),
      body: LayoutBuilder(
        builder: (context, constraints) {
          return DrawingBoard(
            controller: _drawingController,
            background: Container(
              width: constraints.maxWidth,
              height: constraints.maxHeight,
              color: Colors.white,
            ),
            showDefaultActions: true,
            showDefaultTools: true,
            onPointerDown: (details) {
              _isPointerDown = true;
              print('onPointerDown');
              print(_drawingController.getHistory);
            },
            onPointerMove: (details) {
              _isPointerDown = false;
              print('onPointerMove');
              print(_drawingController.getHistory);
            },
            onPointerUp: (details) {
              _isPointerDown = false;
              print('onPointerUp');
              print(_drawingController.getHistory);
            },
            onInteractionStart: (details) {
              print('onInteractionStart');
              print(_drawingController.getHistory);
            },
            onInteractionEnd: (details) {
              print('onInteractionEnd');
              print(_drawingController.getHistory);
            },
          );
        },
      ),
    );
  }
}

xSILENCEx added a commit that referenced this issue Mar 21, 2025
@xSILENCEx
Copy link
Collaborator

Fixed at 0.9.7

@enoiu
Copy link
Author

enoiu commented Mar 24, 2025

Thank you for your response and update.

After upgrading from version 0.9.5 to 0.9.8, the pinch gesture issue on the simulator has been resolved.

However, on a physical device (Pixel 8a), a dot appears at the start of the pinch gesture, as shown in the attached video. In version 0.9.5, this dot was not displayed.

screen-20250324-094756.mp4
import 'package:flutter/material.dart';
import 'package:flutter_drawing_board/flutter_drawing_board.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Drawing Board Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final DrawingController _drawingController = DrawingController();

  void _listener() {
    print('listener');

    print(_drawingController.getHistory);
  }

  @override
  void initState() {
    super.initState();
    _drawingController.addListener(_listener);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Drawing Board Example'),
      ),
      body: LayoutBuilder(
        builder: (context, constraints) {
          return DrawingBoard(
            controller: _drawingController,
            background: Container(
              width: constraints.maxWidth,
              height: constraints.maxHeight,
              color: Colors.white,
            ),
            showDefaultActions: true,
            showDefaultTools: true,
            onPointerDown: (details) {
              print('onPointerDown');
              print(_drawingController.getHistory);
            },
            onPointerMove: (details) {
              print('onPointerMove');
              print(_drawingController.getHistory);
            },
            onPointerUp: (details) {
              print('onPointerUp');
              print(_drawingController.getHistory);
            },
            onInteractionStart: (details) {
              print('onInteractionStart');
              print(_drawingController.getHistory);
            },
            onInteractionEnd: (details) {
              print('onInteractionEnd');
              print(_drawingController.getHistory);
            },
          );
        },
      ),
    );
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants