Skip to content

Commit 4a1a4b2

Browse files
authored
Merge pull request #5 from adil192/new_interactive_viewer
Modified flutter's InteractiveCanvas
2 parents 8deb179 + eb423ae commit 4a1a4b2

File tree

7 files changed

+1355
-90
lines changed

7 files changed

+1355
-90
lines changed

lib/components/canvas/canvas.dart

Lines changed: 9 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11

2-
import 'dart:ui';
3-
42
import 'package:flutter/material.dart';
53

64
import '_stroke.dart';
@@ -12,15 +10,8 @@ class Canvas extends StatelessWidget {
1210
required this.path,
1311
required this.pageIndex,
1412
required this.innerCanvasKey,
15-
required this.undo,
16-
required this.redo,
1713
required this.strokes,
1814
required this.currentStroke,
19-
20-
required this.onScaleStart,
21-
required this.onScaleUpdate,
22-
required this.onScaleEnd,
23-
required this.onPressureChanged,
2415
}) : super(key: key);
2516

2617
static const double canvasWidth = 1000;
@@ -29,61 +20,25 @@ class Canvas extends StatelessWidget {
2920
final String path;
3021
final int pageIndex;
3122

32-
final VoidCallback undo;
33-
final VoidCallback redo;
34-
35-
final ValueChanged<ScaleStartDetails> onScaleStart;
36-
final ValueChanged<ScaleUpdateDetails> onScaleUpdate;
37-
final ValueChanged<ScaleEndDetails> onScaleEnd;
38-
final ValueChanged<double?> onPressureChanged;
39-
4023
final Iterable<Stroke> strokes;
4124
final Stroke? currentStroke;
4225

4326
final GlobalKey<State<InnerCanvas>>? innerCanvasKey;
4427

45-
bool _isPointerDeviceAStylus(PointerDeviceKind kind) {
46-
return kind == PointerDeviceKind.stylus || kind == PointerDeviceKind.invertedStylus;
47-
}
48-
49-
_listenerPointerEvent(PointerEvent event) {
50-
onPressureChanged(_isPointerDeviceAStylus(event.kind) ? event.pressure : null);
51-
}
52-
5328
@override
5429
Widget build(BuildContext context) {
5530
return Hero(
5631
tag: "inner-canvas-$path-page$pageIndex",
57-
58-
child: Container(
59-
clipBehavior: Clip.hardEdge,
60-
decoration: const BoxDecoration(),
61-
child: Listener(
62-
onPointerDown: _listenerPointerEvent,
63-
onPointerMove: _listenerPointerEvent,
64-
child: GestureDetector(
65-
onSecondaryTapUp: (TapUpDetails details) => undo(),
66-
onTertiaryTapUp: (TapUpDetails details) => redo(),
67-
child: InteractiveViewer(
68-
panEnabled: false,
69-
maxScale: 5,
70-
clipBehavior: Clip.none,
71-
72-
onInteractionStart: onScaleStart,
73-
onInteractionUpdate: onScaleUpdate,
74-
onInteractionEnd: onScaleEnd,
7532

76-
child: Center(
77-
child: FittedBox(
78-
child: InnerCanvas(
79-
key: innerCanvasKey,
80-
width: canvasWidth,
81-
height: canvasHeight,
82-
strokes: strokes,
83-
currentStroke: currentStroke,
84-
),
85-
),
86-
),
33+
child: ClipRect(
34+
child: Center(
35+
child: FittedBox(
36+
child: InnerCanvas(
37+
key: innerCanvasKey,
38+
width: canvasWidth,
39+
height: canvasHeight,
40+
strokes: strokes,
41+
currentStroke: currentStroke,
8742
),
8843
),
8944
),
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
2+
import 'dart:ui';
3+
4+
import 'package:flutter/material.dart';
5+
import 'package:saber/components/canvas/interactive_canvas.dart';
6+
7+
class CanvasGestureDetector extends StatelessWidget {
8+
const CanvasGestureDetector({
9+
Key? key,
10+
11+
required this.isDrawGesture,
12+
required this.onDrawStart,
13+
required this.onDrawUpdate,
14+
required this.onDrawEnd,
15+
required this.onPressureChanged,
16+
17+
required this.undo,
18+
required this.redo,
19+
20+
required this.child,
21+
}) : super(key: key);
22+
23+
final bool Function(ScaleStartDetails scaleDetails) isDrawGesture;
24+
final ValueChanged<ScaleStartDetails> onDrawStart;
25+
final ValueChanged<ScaleUpdateDetails> onDrawUpdate;
26+
final ValueChanged<ScaleEndDetails> onDrawEnd;
27+
final ValueChanged<double?> onPressureChanged;
28+
29+
final VoidCallback undo;
30+
final VoidCallback redo;
31+
32+
final Widget child;
33+
34+
bool _isPointerDeviceAStylus(PointerDeviceKind kind) {
35+
return kind == PointerDeviceKind.stylus || kind == PointerDeviceKind.invertedStylus;
36+
}
37+
38+
_listenerPointerEvent(PointerEvent event) {
39+
onPressureChanged(_isPointerDeviceAStylus(event.kind) ? event.pressure : null);
40+
}
41+
42+
@override
43+
Widget build(BuildContext context) {
44+
return Listener(
45+
onPointerDown: _listenerPointerEvent,
46+
onPointerMove: _listenerPointerEvent,
47+
child: GestureDetector(
48+
onSecondaryTapUp: (TapUpDetails details) => undo(),
49+
onTertiaryTapUp: (TapUpDetails details) => redo(),
50+
child: InteractiveCanvasViewer(
51+
minScale: 0.01,
52+
maxScale: 5,
53+
constrained: false,
54+
55+
isDrawGesture: isDrawGesture,
56+
onDrawStart: onDrawStart,
57+
onDrawUpdate: onDrawUpdate,
58+
onDrawEnd: onDrawEnd,
59+
60+
child: child,
61+
)
62+
)
63+
);
64+
}
65+
66+
}

lib/components/canvas/canvas_preview.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
import 'package:flutter/material.dart';
33
import 'package:saber/components/canvas/canvas.dart';
4+
import 'package:saber/components/canvas/interactive_canvas.dart';
45

56
import '_stroke.dart';
67
import 'inner_canvas.dart';
@@ -24,7 +25,7 @@ class CanvasPreview extends StatelessWidget {
2425
return Hero(
2526
tag: "inner-canvas-$path-page$pageIndex",
2627

27-
child: InteractiveViewer(
28+
child: InteractiveCanvasViewer(
2829
maxScale: 5,
2930

3031
child: FittedBox(

0 commit comments

Comments
 (0)