touchable 0.1.6

  • Readme
  • Changelog
  • Example
  • Installing
  • 89

touchable 👆🏻 #

Flutter library to add various gesture callbacks to each Shape you draw on your canvas in your CustomPainter


           

Index : #

Why Use Touchable ? #

  • The CustomPainter lets you only draw shapes on the canvas. But most would want to let user interact with the drawings.

  • With touchable , you get what the normal canvas always missed : touchability 😉

  • With this , its possible to add all kinds of gesture callbacks to each drawing and thus interaction capability to each Shape you draw on the canvas.

  • Animating individual shapes becomes so much easier than ever before.

  • Handles the painting style (filled ▮ , stroke ▯) and detects touch accordingly.

  • Takes the painting stroke width also into account. So if your shapes are painted thick , we still got it covered ✓

  • Supports clipping and different clipping modes. So, You can have any kind of complex clipping and drawing combinations while getting full interactive capability.

  • Supports HitTestBehavior for each shape.

  • Simple and Easy API. Just wrap your CustomPaint with CanvasTouchDetector and use the TouchyCanvas in your painter.

Installation #

Add the touchable package as dependency in your pubspec.yaml

dependencies:
  touchable:

Usage : #

  • Just Wrap your CustomPaint widget with CanvasTouchDetector. It takes a builder function as argument that expects your CustomPaint widget as shown below.
CanvasTouchDetector(
    builder: (context) => 
        CustomPaint(
            painter: MyPainter(context)
        )
)
  • Inside your CustomPainter class's paint method , create and use the TouchyCanvas object (using the context obtained from the CanvasTouchDetector and canvas) to draw any shape with different gesture callbacks.
var myCanvas = TouchyCanvas(context,canvas);
myCanvas.drawRect( rect , Paint() , onTapDown: (tapDetail){
    //Do stuff here. Probably change your state and animate
});

MyPainter example : #

class MyPainter extends CustomPainter {

  final BuildContext context ;
  MyPainter(this.context); // context from CanvasTouchDetector

  @override
  void paint(Canvas canvas, Size size) {
    var myCanvas = TouchyCanvas(context,canvas); 

    myCanvas.drawCircle(Offset(10, 10), 60, Paint()..color=Colors.orange ,
        onTapDown: (tapdetail) {
         print("orange Circle touched");
       },
        onPanDown:(tapdetail){
          print("orange circle swiped");
        } 
    );

    myCanvas.drawLine(
        Offset(0, 0),
        Offset(size.width - 100, size.height - 100),
        Paint()
          ..color = Colors.black
          ..strokeWidth = 50, 
        onPanUpdate: (detail) {
            print('Black line Swiped'); //do cooler things here. Probably change app state or animate
    });
  }
}


How Touchable Works : #

When you draw shapes on the canvas (TouchyCanvas) , it keeps track of the dimensions of each shape you draw and their painting style , stroke etc.

When user performs any gesture on the screen , based on the location of the gesture , the appropriate shape is selected from the lot taking clipping regions , paint , hitTest behaviour etc into account in an optimized way. Callbacks of the corresponding shapes (one or more depending on the hitTest behavior) are executed.

Road Map #

  • [x] Basic Shape Detection
    • [x] Line
    • [x] Rectangle (Rect)
    • [x] Circle
    • [x] Oval or Ellipse
    • [x] Arc
      • [x] segment
      • [x] sector
    • [x] Rounded Rectangle (RRect)
    • [x] Custom Path [only supports opaque hittest]
    • [x] Points (PointMode.points , PointMode.lines , PointMode.polygon)
    • [ ] Vertices
      • [ ] Traingle
      • [ ] Traingle Strip
      • [ ] Traingle Fan
  • [x] Support for proper edge detection based on the Paint object properties :
    • [x] Paint style
    • [x] Stroke Width
    • [ ] Stroke Cap
      • [x] StrokeCap to draw Points
      • [ ] StrokeCap.round for lines with large width
  • [x] Support Clipping and clipping modes
    • [x] ClipRect
      • [x] intersect mode [Touch detection enabled only inside the clipped region]
      • [x] difference mode [Touch detection enabled only outside the clipped region]
    • [x] ClipRRect
    • [x] ClipPath
  • [x] Support for HitTestBehavior
  • [ ] Make the touch detection handling to run in a seperate isolate.
  • [ ] Support for translation , rotation , scaling and skewing transformations that needs some vector math

[0.1.5] - April 24 2020 #

Added support for HitTestBehavior Minor bug fixes Added Documentation Updated docs in code

[0.1.2] - April 21 2020

updated readme and example

[0.1.0] - April 21 2020 #

Fixed issue which prevented from drawing a Custom Path

[0.1.0] - April 20 2020 #

Fixed a in handling event Stream during Animations Fixed certain edge case bugs related to thick line detection minor refactor

[0.0.1] - April 18 2020 #

Initial Release

example/example.dart

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

class MyExampleWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    FocusScope.of(context).nextFocus();
    return Flexible(
      child: FractionallySizedBox(
          widthFactor: 1,
          heightFactor: 1,
          child: CanvasTouchDetector(
            builder: (context) {
              return CustomPaint(
                painter: MyPainter(context),
              );
            },
          )),
    );
  }
}

class MyPainter extends CustomPainter {
  final BuildContext context;
  MyPainter(this.context); // context from CanvasTouchDetector

  @override
  void paint(Canvas canvas, Size size) {
    var myCanvas = TouchyCanvas(context, canvas);

    myCanvas.drawCircle(Offset(10, 10), 60, Paint()..color = Colors.orange,
        onTapDown: (tapdetail) {
      print('orange Circle touched');
    }, onPanDown: (tapdetail) {
      print('orange circle swiped');
    });

    myCanvas.drawLine(
        Offset(0, 0),
        Offset(size.width - 100, size.height - 100),
        Paint()
          ..color = Colors.black
          ..strokeWidth = 50, onPanUpdate: (detail) {
      print(
          'Black line Swiped'); //do cooler things here. Probably change app state or animate
    });
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

Use this package as a library

1. Depend on it

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


dependencies:
  touchable: ^0.1.6

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

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

3. Import it

Now in your Dart code, you can use:


import 'package:touchable/touchable.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
78
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]
89
Learn more about scoring.

We analyzed this package on Jul 8, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.13
  • Flutter: 1.17.5

Analysis suggestions

Package not compatible with SDK dart

because of import path [touchable] that is in a package requiring null.

Health suggestions

Fix lib/src/shapes/arc.dart. (-0.50 points)

Analysis of lib/src/shapes/arc.dart reported 1 hint:

line 4 col 8: Don't import implementation files from another package.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.12 1.14.13
meta 1.1.8 1.2.1
sky_engine 0.0.99
typed_data 1.1.6 1.2.0
vector_math 2.0.8
Dev dependencies
flutter_test