painter 0.3.1

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 81

painter

A simple flutter widget to paint with your fingers.

Features

The widget supports:

  • Changing fore- and background color
  • Changing the thickness of lines you draw
  • Exporting your painting as png
  • Undo drawing a line
  • Clearing the hole drawing

Some Notes

  • After calling 'finish()' on a PainterController you can't draw on this painting any more
  • To create a new painting after finishing the old one simply create a new PainterController
  • Calling 'finish()' for the first time will render the drawing. Successive calls will then return a cached version of the rendered picture

Example

For a full example take a look at the example project. Here is a short recording showing it. Note that the color picker is an external dependency which is only required for the example.

demo!

[0.3.1] - 22.06.2018

  • Initial public release

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:painter/painter.dart';
import 'dart:typed_data';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Painter Example',
      home: new ExamplePage(),
    );
  }
}

class ExamplePage extends StatefulWidget {
  @override
  _ExamplePageState createState() => new _ExamplePageState();
}

class _ExamplePageState extends State<ExamplePage> {

  bool _finished;
  PainterController _controller;

  @override
  void initState() {
    super.initState();
    _finished=false;
    _controller=_newController();
  }

  PainterController _newController(){
    PainterController controller=new PainterController();
    controller.thickness=5.0;
    controller.backgroundColor=Colors.green;
    return controller;
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> actions;
    if(_finished){
      actions = <Widget>[
        new IconButton(
          icon: new Icon(Icons.content_copy),
          tooltip: 'New Painting',
          onPressed: ()=>setState((){
            _finished=false;
            _controller=_newController();
          }),
        ),
      ];
    } else {
      actions = <Widget>[
        new IconButton(
            icon: new Icon(Icons.undo),
            tooltip: 'Undo',
            onPressed:  _controller.undo
        ),
        new IconButton(
            icon: new Icon(Icons.delete),
            tooltip: 'Clear',
            onPressed:  _controller.clear
        ),
        new IconButton(
            icon: new Icon(Icons.check),
            onPressed: ()=>_show( _controller.finish(),context)
        ),
      ];
    }
    return new Scaffold(
      appBar: new AppBar(
          title: const Text('Painter Example'),
          actions:actions,
          bottom: new PreferredSize(
            child: new DrawBar(_controller),
            preferredSize: new Size(MediaQuery.of(context).size.width,30.0),
          )
      ),
      body: new Center(
          child:new AspectRatio(
              aspectRatio: 1.0,
              child: new Painter( _controller)
          )
      ),
    );
  }

  void _show(PictureDetails picture,BuildContext context){
    setState(() {
      _finished=true;
    });
    Navigator.of(context).push(
        new MaterialPageRoute(builder: (BuildContext context){
          return new Scaffold(
            appBar: new AppBar(
              title: const Text('View your image'),
            ),
            body: new Container(
                alignment: Alignment.center,
                child:new FutureBuilder<Uint8List>(
                  future:picture.toPNG(),
                  builder: (BuildContext context, AsyncSnapshot<Uint8List> snapshot){
                    switch (snapshot.connectionState)
                    {
                      case ConnectionState.done:
                        if (snapshot.hasError){
                          return new Text('Error: ${snapshot.error}');
                        }else{
                          return Image.memory(snapshot.data);
                        }
                        break;
                      default:
                        return new Container(
                            child:new FractionallySizedBox(
                              widthFactor: 0.1,
                              child: new AspectRatio(
                                  aspectRatio: 1.0,
                                  child: new CircularProgressIndicator()
                              ),
                              alignment: Alignment.center,
                            )
                        );
                    }
                  },
                )
            ),
          );
        })
    );
  }
}

class DrawBar extends StatelessWidget {

  final PainterController _controller;

  DrawBar(this._controller);

  @override
  Widget build(BuildContext context) {
    return  new Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        new Flexible(
            child: new StatefulBuilder(
                builder: (BuildContext context,StateSetter setState){
                  return new Container(
                      child: new Slider(
                        value:  _controller.thickness,
                        onChanged: (double value)=>setState((){
                          _controller.thickness=value;
                        }),
                        min: 1.0,
                        max: 20.0,
                        activeColor: Colors.white,
                      )
                  );
                }
            )
        ),
        new ColorPickerButton( _controller, false),
        new ColorPickerButton( _controller, true),
      ],
    );
  }
}


class ColorPickerButton extends StatefulWidget {

  final PainterController _controller;
  final bool _background;

  ColorPickerButton(this._controller,this._background);

  @override
  _ColorPickerButtonState createState() => new _ColorPickerButtonState();
}

class _ColorPickerButtonState extends State<ColorPickerButton> {
  @override
  Widget build(BuildContext context) {
    return new IconButton(
        icon: new Icon(_iconData,color: _color),
        tooltip: widget._background?'Change background color':'Change draw color',
        onPressed: _pickColor
    );
  }

  void _pickColor(){
    Color pickerColor=_color;
    Navigator.of(context).push(
        new MaterialPageRoute(
            fullscreenDialog: true,
            builder: (BuildContext context){
              return new Scaffold(
                  appBar: new AppBar(
                    title: const Text('Pick color'),
                  ),
                  body: new Container(
                      alignment: Alignment.center,
                      child: new ColorPicker(
                        pickerColor: pickerColor,
                        onColorChanged: (Color c)=>pickerColor=c,
                      )
                  )
              );
            }
        )
    ).then((_){
      setState((){
        _color=pickerColor;
      });
    });
  }

  Color get _color=>widget._background?widget._controller.backgroundColor:widget._controller.drawColor;

  IconData get _iconData=>widget._background?Icons.format_color_fill:Icons.brush;

  set _color(Color color){
    if(widget._background){
      widget._controller.backgroundColor=color;
    } else {
      widget._controller.drawColor=color;
    }
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  painter: ^0.3.1

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

Alternatively, your editor might support flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:painter/painter.dart';
  
Version Uploaded Documentation Archive
0.3.1 Jun 22, 2018 Go to the documentation of painter 0.3.1 Download painter 0.3.1 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
63
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
81
Learn more about scoring.

We analyzed this package on Oct 26, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.1.0-dev.7.1.flutter-b99bcfd309
  • pana: 0.12.5
  • Flutter: 0.10.1

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Health suggestions

Format lib/painter.dart.

Run flutter format to format lib/painter.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.28.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11
meta 1.1.6
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8