draw_your_image 0.4.2 copy "draw_your_image: ^0.4.2" to clipboard
draw_your_image: ^0.4.2 copied to clipboard

A Flutter package which enables users to draw with fingers in your designed UI.

example/lib/main.dart

import 'dart:ui';
import 'package:draw_your_image/draw_your_image.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'onStrokeStarted Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        useMaterial3: true,
      ),
      home: MyHomePage(),
    );
  }
}

/// Drawing mode definition
enum DrawingMode {
  stylusOnly,
  stylusPrior,
  stylusDrawFingerErase,
  differentColors,
  differentWidths,
}

extension DrawingModeExtension on DrawingMode {
  String get displayName {
    switch (this) {
      case DrawingMode.stylusOnly:
        return 'Stylus Only';
      case DrawingMode.stylusPrior:
        return 'Stylus Priority';
      case DrawingMode.stylusDrawFingerErase:
        return 'Stylus Draw / Finger Erase';
      case DrawingMode.differentColors:
        return 'Different Colors';
      case DrawingMode.differentWidths:
        return 'Different Widths';
    }
  }

  String get description {
    switch (this) {
      case DrawingMode.stylusOnly:
        return 'Only accepts stylus input. Finger input is ignored.';
      case DrawingMode.stylusPrior:
        return 'Prioritizes stylus. Finger input is ignored while drawing with stylus.';
      case DrawingMode.stylusDrawFingerErase:
        return 'Draw with stylus and erase with finger.';
      case DrawingMode.differentColors:
        return 'Stylus draws in black, finger draws in red.';
      case DrawingMode.differentWidths:
        return 'Stylus draws thin lines, finger draws thick lines.';
    }
  }
}

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

class _MyHomePageState extends State<MyHomePage> {
  var _strokes = <Stroke>[];
  var _currentMode = DrawingMode.stylusOnly;

  void _clear() {
    setState(() {
      _strokes = [];
    });
  }

  /// Returns the stroke handler for the current mode
  Stroke? Function(Stroke, Stroke?)? _getStrokeHandler() {
    switch (_currentMode) {
      case DrawingMode.stylusOnly:
        return stylusOnlyHandler;
      case DrawingMode.stylusPrior:
        return stylusPriorHandler;
      case DrawingMode.stylusDrawFingerErase:
        return _stylusDrawFingerEraseHandler;
      case DrawingMode.differentColors:
        return _differentColorsHandler;
      case DrawingMode.differentWidths:
        return _differentWidthsHandler;
    }
  }

  /// Handler for stylus drawing and finger erasing
  Stroke? _stylusDrawFingerEraseHandler(
      Stroke newStroke, Stroke? currentStroke) {
    // Continue current stroke if already drawing
    if (currentStroke != null) {
      return currentStroke;
    }

    // Stylus for normal drawing
    if (_isStylus(newStroke.deviceKind)) {
      return newStroke.copyWith(
        color: Colors.black,
        width: 4.0,
        isErasing: false,
      );
    }

    // Finger for erasing
    return newStroke.copyWith(
      isErasing: true,
      width: 20.0,
    );
  }

  /// Handler for different colors by device
  Stroke? _differentColorsHandler(Stroke newStroke, Stroke? currentStroke) {
    // Continue current stroke if already drawing
    if (currentStroke != null) {
      return currentStroke;
    }

    // Stylus: black, Finger: red
    final color = _isStylus(newStroke.deviceKind) ? Colors.black : Colors.red;
    return newStroke.copyWith(
      color: color,
      width: 4.0,
    );
  }

  /// Handler for different widths by device
  Stroke? _differentWidthsHandler(Stroke newStroke, Stroke? currentStroke) {
    // Continue current stroke if already drawing
    if (currentStroke != null) {
      return currentStroke;
    }

    // Stylus: thin line, Finger: thick line
    final width = _isStylus(newStroke.deviceKind) ? 2.0 : 8.0;
    return newStroke.copyWith(
      color: Colors.black,
      width: width,
    );
  }

  /// Check if the device kind is stylus
  bool _isStylus(PointerDeviceKind kind) {
    return kind == PointerDeviceKind.stylus ||
        kind == PointerDeviceKind.invertedStylus;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('onStrokeStarted Demo'),
        actions: [
          IconButton(
            icon: Icon(Icons.clear),
            onPressed: _strokes.isEmpty ? null : _clear,
            tooltip: 'Clear',
          ),
        ],
      ),
      body: Column(
        children: [
          // Mode selection area
          Container(
            width: double.infinity,
            padding: EdgeInsets.all(16),
            color: Colors.grey[100],
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  'Mode Selection',
                  style: TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                SizedBox(height: 8),
                DropdownButton<DrawingMode>(
                  value: _currentMode,
                  isExpanded: true,
                  items: DrawingMode.values.map((mode) {
                    return DropdownMenuItem(
                      value: mode,
                      child: Text(mode.displayName),
                    );
                  }).toList(),
                  onChanged: (mode) {
                    if (mode != null) {
                      setState(() {
                        _currentMode = mode;
                        _strokes = []; // Clear on mode change
                      });
                    }
                  },
                ),
                SizedBox(height: 8),
                Text(
                  _currentMode.description,
                  style: TextStyle(
                    fontSize: 14,
                    color: Colors.grey[700],
                  ),
                ),
              ],
            ),
          ),
          // Drawing area
          Expanded(
            child: Container(
              margin: EdgeInsets.all(16),
              decoration: BoxDecoration(
                border: Border.all(color: Colors.grey[300]!),
                borderRadius: BorderRadius.circular(8),
              ),
              child: ClipRRect(
                borderRadius: BorderRadius.circular(8),
                child: Draw(
                  strokes: _strokes,
                  strokeColor: Colors.black,
                  strokeWidth: 4.0,
                  backgroundColor: Colors.white,
                  smoothingFunc: SmoothingMode.catmullRom.converter,
                  onStrokeDrawn: (stroke) {
                    setState(() => _strokes = [..._strokes, stroke]);
                  },
                  onStrokeStarted: _getStrokeHandler(),
                ),
              ),
            ),
          ),
          // Instructions area
          Container(
            width: double.infinity,
            padding: EdgeInsets.all(16),
            color: Colors.blue[50],
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '💡 How to Use',
                  style: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.bold,
                    color: Colors.blue[900],
                  ),
                ),
                SizedBox(height: 8),
                Text(
                  'Select a mode and try drawing with both stylus and finger.\n'
                  'You can see how the behavior differs depending on the mode.',
                  style: TextStyle(
                    fontSize: 14,
                    color: Colors.blue[800],
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
45
likes
0
points
475
downloads

Publisher

verified publishertsuyoshichujo.com

Weekly Downloads

A Flutter package which enables users to draw with fingers in your designed UI.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter

More

Packages that depend on draw_your_image