Giter VIP home page Giter VIP logo

scribble's People

Contributors

dampfwalze avatar dependabot[bot] avatar github-actions[bot] avatar johannschramm avatar mattrussell-sonocent avatar timcreatedit avatar wxxedu avatar yujinlin0224 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

scribble's Issues

It doesn't work on mobile browser

Hello,
thanks for the great library, the web version works very well on Desktop browser but unfortunately it has a lot of issues on mobile browser (I've tested it on iOS and Android, phones and tablets).

Thanks,
Dem

Problem when using part of the screen

Hi,
I have implemented the Scribble on part of the screen (inside a container)
Although it does not allow to start paining when out of the bounds of the container, If, while drawing I go out of the boundries of the container, it continues drawing.
ScribbleProblem01

Sketch is cut off on different screen sizes

I realized after I took the screenshots that I forgot a word so ignore that please lol.

When a sketch is drawn on a full screen iPad and then the view is in split screen the sketch is cut off.

IMG_0288
IMG_0290
IMG_0289

I am using just the basic scribble widget

 Scribble(
  notifier: _notifier,
  drawPen: true,
),

Sketches could be drawn outside of the scribble widget

image
The cyan outlined box at right top of the image is the constraint of the scribble widget. But the drawings could be drawn on other widgets when I draw the lines from the box to out of the box. This happens UNEXPECTEDly. It seems that the position of drawing layers gets differ when the size of the widget changes.

So that I tried to delete every dots with listener, but it invokes setState unlimitedly when I try to remove the dots outside of the box via setSketch().

a Pen in Ipad

i use a pen on the iPad for testing, but it's not good, sometimes, Scribble doesn't show the line. Please recheck it.

iOS Scribble (handwriting text input feature) conflicts with stylus stroke recognition

Thanks for the ace library!

When using an Apple Pencil on iOS with Scribble input enabled, there's a delay of maybe 1 second before the library begins to recognise the stylus stroke. Before then, a temporary grey stroke is shown, which I suspect is the OS attempting handwriting recognition briefly. If I disable Settings -> Apple Pencil -> Scribble, then the library recognises the stroke immediately.

iOS: 15.4.1
scribble: 0.4.0
Flutter: 2.10.5

RPReplay_Final1652872299.MP4

Export to SVG

Description

Exporting vector SVG file

Requirements

  • Checklist of requirements to be fulfilled

Additional Context

Since it can store JSON, seems viable to store SVG line info

perfect_freehand integration

Would you be open to using perfect_freehand to handle the stroke painting? I had a quick play today plugging perfect_freehand into ScribblePainter as part of an internal company hackathon, and the results were pretty good (much smoother lines). I'd be happy to put together a PoC PR if that was a direction you'd be interested in?

Create Scribble Viewer (View not edit)

So I had a use case where I needed to just view a scribble sketch. As I started working on this solution I realized that there was a lot of extra space in my sketch (ie. you draw a smiley face in the center of the canvas). So I came up with some helper functions that helped me create a scribble viewer that crops the sketch where it removes the whitespace above and below the main sketch.

These are the extensions I needed to help create the Sketch viewer.

extension SketchExt on Sketch {
  Sketch croppedSketch() {
    var newLines = List<SketchLine>.empty(growable: true);
    double minY = double.maxFinite;
    for (var line in lines) {
      var temp = line.points
          .reduce((value, element) => value.y < element.y ? value : element);
      if (temp.y < minY) {
        minY = temp.y;
      }
    }

    newLines = lines.map((e) {
      var newE = e;
      List<Point> points = List<Point>.empty(growable: true);
      for (var p in e.points) {
        var newP = p.copyWith(y: p.y - minY);
        points.add(newP);
      }
      newE = newE.copyWith(points: points);
      return newE;
    }).toList();
    return copyWith(lines: newLines);
  }

  double getTotalHeight() {
    double minY = double.maxFinite;
    double maxY = -double.maxFinite;
    for (var line in lines) {
      var minTemp = line.points
          .reduce((value, element) => value.y < element.y ? value : element);
      var maxTemp = line.points
          .reduce((value, element) => value.y > element.y ? value : element);
      if (minTemp.y < minY) {
        minY = minTemp.y;
      }
      if (maxTemp.y > maxY) {
        maxY = maxTemp.y;
      }
    }
    return maxY - minY;
  }
}

Here is the sketch viewer in motion

Widget sketchViewer(Sketch sketch){
    return SizedBox(
        height: sketch
            .getTotalHeight(),
        child: Scribble(
          notifier: ScribbleNotifier(
              allowedPointersMode: ScribblePointerMode.mouseOnly,
              sketch: sketch
                  .croppedSketch()),
          drawPen: true,
        ),
      );
}

I figured this could help somebody. I don't know if it is worth creating a pr for this or not.

Playback Scribble

Is it possible to "play" the scribble from JSON? Like as if it is being drawn from scratch?
Thanks

Change Previous Color on Background Color Change

Hi,

I've been trying to solve a problem but can't find the best way to do so. If I was drawing in black and then changed the background color to black, what would be the best way to change the previous lines that were black to white? The only thing I could think of was iterate through the JSON, find all of the instances that have the black color assignment and change it manually to a white color.

Even this process, I am having trouble iterating through the JSON. Unfortunately, I am a newbie to Dart.

Entering Text on Canvas

Great package! Is there a way that we can add text to the drawing canvas like OneNote or Evernote? An ability to put text (non-written) next to what we draw would be very useful.

Additionally, importing of images to overlay on the canvas would be a nice to have also. I can help out if pointed in the right direction.

Binary encoder/decoder

I have written a binary encoder/decoder for a sketch. This is because the json format which is provided per default consumes too much space for my project. If you are interested to include this encoder/decoder feel free to use it as you want.

import 'dart:typed_data';

import 'package:flutter/services.dart';
import 'package:scribble/scribble.dart';

/// Encodes a Sketch into its binary representation.
///
/// Versions:
/// 0001: Initial version
///
/// Attention. The binary representation of the sketch is not 100% identical because the double values will be stored with a precision of 1/10th.
class ScribbleEncoder {
  List<int> encode(Sketch sketch) {
    List<int> result = [];

    ByteData byteData = ByteData(8);
    // signature: cbbe (the hex-compatible characters of scribble) followed by the version number.
    byteData.setInt32(0, 0xcbbe0001);
    byteData.setInt32(4, sketch.lines.length);
    result.addAll(byteData.buffer.asUint8List());

    sketch.lines.forEach((element) {
      result.addAll(_encodeLine(element));
    });
    return result;
  }

  List<int> _encodeLine(SketchLine line) {
    List<int> result = [];

    ByteData byteData = ByteData(12);
    byteData.setInt32(0, line.color);
    byteData.setInt32(4, (line.width * 10).round());
    byteData.setInt32(8, line.points.length);
    result.addAll(byteData.buffer.asUint8List());
    //print("Encoding line with ${line.points.length} points");
    line.points.forEach((element) {
      result.addAll(_encodePoint(element));
    });
    return result;
  }

  ///
  /// Encodes one Point and returns the encoded bytes. Each point consumes 10 byte.
  List<int> _encodePoint(Point point) {
    ByteData result = ByteData(10);
    result.setInt32(0, (point.x * 10).round());
    result.setInt32(4, (point.y * 10).round());
    result.setInt16(8, (point.pressure * 10).round());
    return result.buffer.asUint8List();
  }
}

import 'dart:typed_data';

import 'package:flutter/services.dart';
import 'package:scribble/scribble.dart';

class ScribbleDecoder {
  Sketch decode(List<int> data) {
    if (data.length < 8) throw Exception("Invalid length (${data.length}");
    if (data[0] != 0xcb || data[1] != 0xbe)
      throw Exception("Invalid signature");
    int version = data[2] * 0xff + data[3];
    if (version != 0x0001) throw Exception("Unknown version ${version}");

    ByteData byteData = ByteData.sublistView(Uint8List.fromList(data));
    int lineLength = byteData.getInt32(4);
    if (lineLength < 0) throw Exception("nbr of Lines invalid");
    int idx = 8;
    List<SketchLine> lines = [];
    for (int lineNbr = 0; lineNbr < lineLength; ++lineNbr) {
      _LineResult _lineResult = _decodeLine(byteData, idx);
      lines.add(_lineResult.line);
      idx = _lineResult.idx;
    }
    Sketch result = Sketch(lines: lines);
    return result;
  }

  _LineResult _decodeLine(ByteData byteData, int idx) {
    if (byteData.lengthInBytes < idx + 12)
      throw Exception(
          "Invalid length of sourcefile to read a line at position $idx");
    int color = byteData.getInt32(idx + 0);
    double width = byteData.getInt32(idx + 4) / 10;
    int pointLength = byteData.getInt32(idx + 8);
    if (pointLength < 0) throw Exception("nbr of Points invalid");
    //print("Decoding line with $pointLength points at index $idx");
    List<Point> points = [];
    idx += 12;
    for (int pointNbr = 0; pointNbr < pointLength; ++pointNbr) {
      Point point = _decodePoint(byteData, idx);
      points.add(point);
      idx += 10;
    }
    return _LineResult(
        SketchLine(points: points, color: color, width: width), idx);
  }

  Point _decodePoint(ByteData byteData, int idx) {
    if (byteData.lengthInBytes < idx + 10)
      throw Exception(
          "Invalid length of sourcefile to read a point at position $idx");
    double x = byteData.getInt32(idx + 0) / 10;
    double y = byteData.getInt32(idx + 4) / 10;
    double pressure = byteData.getInt16(idx + 8) / 10;
    return Point(x, y, pressure: pressure);
  }
}

/////////////////////////////////////////////////////////////////////////////

class _LineResult {
  final SketchLine line;
  final int idx;

  _LineResult(this.line, this.idx);
}

Can I add a listener when the drawing is added at onPointerUp?

I'm doing a project using several canvases in a screen. I wonder that it is possible to revert or redo the drawing with just a button on several scribble widgets.

Here is the scenario I am expecting:

  1. Scribble widgets are in various sized (they're resizable)
제목 없음-2
  1. Drawing lines
2 3
  1. revert with one button. The stack inside stores the orders of the scribbleNotifier which did drawing or erasing.
4
  1. reverted in reverse order.
5

notifier.clear resets color too

I don't know if this is on purpose or not, but after calling notifier.clear, the color as well as the stroke widths get reset.

I set the widths when creating the new notifier and set the color in the build()-method of my widget to white.
after I call notifier.clear with a tap on a button, the color is black again (as per default).

setting the widths
@override void initState() { final width = 3.5; notifier = ScribbleNotifier(widths: [width, width * 2, width * 3], sketch: ); super.initState(); }

changing the color:
@override Widget build(BuildContext context) { final theme = Theme.of(context); notifier.setColor(theme.colorScheme.onBackground);

Straight line between two points?

Is it possible to draw a straight line between two mouse pointer events? For example between onPointerDown and onPointerUp.

I would like to be able to draw arrows or straight lines.

how to identify if lines touch each other

How to identify if the lines touch each other? if 2 lines touch eachother can we change color as different colour or identify and have a popup is that possible.

if possible, please throw some light and i can give a try.

Please help.

Thanks,

Issue Drawing Very Short Lines with Scribble

Problem:

When attempting to draw extremely short lines using the Scribble package, the output is limited to a single point rather than a continuous line. The line only appears when the drawing movement exceeds a certain distance. This behavior is particularly problematic for tasks that require fine detail, such as handwriting.

Request:

Is there a way to modify or reduce this minimum distance threshold so that shorter strokes are recognized as lines rather than points? This adjustment would greatly enhance the package's utility for detailed drawing tasks.

Thank you for your attention to this matter.

scribble_issue

Saving and pen detection

Awesome library. Is there a way to save your drawing to edit at another time? Also, is there a way to make if only work if a pen or pencil is detected?

Thank you!

Undo Redo Issue with loading scribble from json

Hi, its a great package but I have some issues with the Undo Redo feature when loading from json:

  • Redo deletes the whole painting (can redo is also true before executing the action).
  • If I play around with some methods like clearQueue() and set the flag addToUndoHistory to false, it odes not recognise the first line but at least does not remove the whole painting (can redo is also false in this case). Undo does also not work on the first erase on the second case, something seems weird.

In either case I can't make it properly work. Im using flutter_bloc for state and and tried a dirty hack to get the state from the notifier every 100 milliseconds to make sure its not an issue on my side, the behaviour is one of the above described.

Navigate Back Gesture & Drawing

Hi, thats a cool package, I will integrate it into my app!

Description:

  • I have a route where you can paint things and when you navigate back I save the image. (This apply for drawings but also other routes and different content)
  • The navigation back gesture is drawing on the screen

It would be nice if there would be a way to prevent that behavior. I did not found any way in Flutter to detect if a back gesture is currently on going. You can detect gestures in general but thats not always a back gesture.

How to switch back to drawing mode from eraser mode?

Hello,

I'm using the Scribble package in my Flutter project and I've successfully implemented the eraser mode using the setEraser function in the ScribbleNotifier. However, I'm unsure how to switch back to the drawing mode once I'm in the eraser mode.

Is there a specific method or a recommended way to toggle between these modes? Any guidance would be greatly appreciated.

Thank you!

How to load a json sketch?

I have learned that I can save a sketch with notifier.currentSketch.toJson(). I can recreate the sketch with Sketch.fromJson(json) but I cannot assign the new sketch to the state. Did I miss something?

Multiple widgets used the same GlobalKey

Getting GlobalKey Error

Multiple widgets used the same GlobalKey.

════════ Exception caught by widgets library ═══════════════════════════════════
Multiple widgets used the same GlobalKey.
════════════════════════════════════════════════════════════════════════════════

`The following assertion was thrown while finalizing the widget tree:
Multiple widgets used the same GlobalKey.
The key [GlobalKey#beb1f] was used by multiple widgets. The parents of those widgets were:

  • CustomPaint(renderObject: RenderCustomPaint#830c9 NEEDS-PAINT)
  • CustomPaint(renderObject: RenderCustomPaint#e5d2c NEEDS-PAINT)
    A GlobalKey can only be specified on one widget at a time in the widget tree.

When the exception was thrown, this was the stack:
#6 BuildOwner.finalizeTree. (package:flutter/src/widgets/framework.dart:3177:11)
framework.dart:3177
#7 BuildOwner.finalizeTree (package:flutter/src/widgets/framework.dart:3259:8)
framework.dart:3259
#8 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:992:19)
binding.dart:992
#9 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:448:5)
binding.dart:448
#10 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1386:15)
binding.dart:1386
#11 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1311:9)
binding.dart:1311
#12 SchedulerBinding.scheduleWarmUpFrame. (package:flutter/src/scheduler/binding.dart:1034:7)
binding.dart:1034
#16 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
isolate_patch.dart:184
(elided 3 frames from class _Timer and dart:async-patch)`

How to reproduce:

SizedBox(
              width: MediaQuery.of(context).orientation == Orientation.portrait ? MediaQuery.of(context).size.height - 120 : MediaQuery.of(context).size.width - 120,
              height: MediaQuery.of(context).orientation == Orientation.portrait ? MediaQuery.of(context).size.width - 120 : MediaQuery.of(context).size.height - 140,
              child: AspectRatio(
                aspectRatio: 16 / 9,
                child: Card(
                  clipBehavior: Clip.hardEdge,
                  surfaceTintColor: EmintColors.emerald,
                  elevation: 0.2,
                  child: Scribble(
                    notifier: notifier,
                    drawPen: true,
                  ),
                ),
              ),
            ),

Use 3D bezier curves instead of point lists and vertices

Using 3D bezier curves instead of lines would allow for:

  • Simplification of lines (less space complexity)
  • Smoothing lines and pressure
  • "Perfect" collision detection for eraser
  • ... potentially more

This is probably not gonna happen for a while (maybe for 1.0), since the current approach works well enough for our use-case, but we're always happy about PRs

background color

hi how change background color ? default background is transparent !

Scribble listeners detects less and less points

Hello,

I am using this library for a handwriting app. I am facing a problem that the Scribble Listener is detecting less and less points. In the first minutes it detected around 150 points and after around 15 minutes it was reduced to 90-100 points on the same segment. Quite a big drop. Is there a way to reset completely the notifier or anything?

I am on the latest version of Scribble and Flutter 3.7.5

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.