Short Description
In this example you can see how to create the signature and download the image locally.
This custom widget contains a signature pad that allows users to draw a signature. It distinguishes between web and non-web platforms using kIsWeb.
Example
Custom Widget Code:
Dependencies:
syncfusion_flutter_signaturepad: ^22.2.8
open_file: ^3.3.2
universal_html: ^2.2.3
Before using this syncfusion_flutter_signaturepad package, check out its license.
Code:
// Automatic FlutterFlow imports
import '/backend/schema/structs/index.dart';
import '/backend/supabase/supabase.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/widgets/index.dart'; // Imports other custom widgets
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom widget code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'dart:html';
import 'package:syncfusion_flutter_signaturepad/signaturepad.dart';
import 'dart:ui' as ui;
import 'dart:io' as io;
import 'package:path_provider/path_provider.dart';
import 'package:open_file/open_file.dart';
import 'package:universal_html/html.dart' show AnchorElement;
import 'package:flutter/foundation.dart' show kIsWeb;
import 'dart:convert';
import 'dart:typed_data';
import 'dart:async';
class SignatureWidget extends StatefulWidget {
const SignatureWidget({
Key? key,
this.width,
this.height,
}) : super(key: key);
final double? width;
final double? height;
@override
_SignatureWidgetState createState() => _SignatureWidgetState();
}
class _SignatureWidgetState extends State<SignatureWidget> {
GlobalKey<SfSignaturePadState> _signaturePadStateKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Container(
child: Column(children: [
SfSignaturePad(
key: _signaturePadStateKey,
backgroundColor: Colors.grey,
strokeColor: Colors.white,
minimumStrokeWidth: 4.0),
SizedBox(
height: 15,
),
Row(children: [
ElevatedButton(
onPressed: () async {
_signaturePadStateKey.currentState!.clear();
},
child: Text("Clear"),
),
SizedBox(
width: 30,
),
ElevatedButton(
onPressed: () async {
if (kIsWeb) {
final canvas = CanvasElement(width: 500, height: 500);
final context = canvas.context2D;
//Get the signature in the canvas context.
_signaturePadStateKey.currentState!.renderToContext2D(context);
//Get the image from the canvas context
final blob = await canvas.toBlob('image/png', 1.0);
//Save the image as Uint8List to use it in local device.
final completer = Completer<Uint8List>();
final reader = FileReader();
reader.readAsArrayBuffer(blob);
reader.onLoad.listen((_) {
final Uint8List imageData =
Uint8List.fromList(reader.result as List<int>);
completer.complete(imageData);
});
Uint8List imageData = await completer.future;
// Now you can use the Uint8List as needed.
// Create a blob from the Uint8List.
final blobImage = Blob([imageData]);
// Create an anchor element with a download link.
final anchor =
AnchorElement(href: Url.createObjectUrlFromBlob(blobImage))
..setAttribute("download", "signature.png")
..text = "Download Image";
// Append the anchor element to the document body and click it.
document.body!.append(anchor);
anchor.click();
// Remove the anchor element from the document.
anchor.remove();
} else {
ui.Image image = await _signaturePadStateKey.currentState!
.toImage(pixelRatio: 2.0);
final byteData =
await image.toByteData(format: ui.ImageByteFormat.png);
final Uint8List imageBytes = byteData!.buffer.asUint8List(
byteData.offsetInBytes, byteData.lengthInBytes);
final String path =
(await getApplicationSupportDirectory()).path;
final String fileName = io.Platform.isWindows
? "$path\\signature.png"
: "$path/signature.png";
final io.File file = io.File(fileName);
await file.writeAsBytes(imageBytes, flush: true);
OpenFile.open(fileName);
}
},
child: Text("Save As Image"),
),
])
]),
height: 300,
width: 300,
);
}
}
Some notes about the code
Inside the "Save As Image" button's onPressed function:
If the platform is web (kIsWeb is true), the signature from the SfSignaturePad is rendered onto a canvas, then converted to a Blob (binary large object) and finally to a downloadable image.
If it's not a web platform, the signature is converted to an image, saved as a PNG file, and then opened using the OpenFile package.
Additional resources
SfSiganturePad package: https://pub.dev/packages/syncfusion_flutter_signaturepad
License: https://pub.dev/packages/syncfusion_flutter_signaturepad/license
Syncfusion SignaturePad Help: https://help.syncfusion.com/flutter/signaturepad/getting-started