serializable_sketch 0.1.0
serializable_sketch: ^0.1.0 copied to clipboard
A Flutter library for creating and serializing sketches into smooth Bezier-based JSON and SVG formats.
import 'package:flutter/material.dart';
import 'package:serializable_sketch/serializable_sketch.dart';
import 'package:file_picker/file_picker.dart';
import 'dart:io';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Serializable Sketch Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<SketchPath> _paths = [];
String? _lastJson;
String? _lastSvg;
void _onPathsChanged(List<SketchPath> newPaths) {
setState(() {
_paths = newPaths;
});
}
void _clearPaths() {
setState(() {
_paths = [];
_lastJson = null;
_lastSvg = null;
});
}
void _saveToJson() {
final json = SketchSerializer.toJson(_paths);
setState(() {
_lastJson = json;
});
_showSnackBar('Saved to JSON');
}
void _loadFromJson() {
if (_lastJson != null) {
final paths = SketchSerializer.fromJson(_lastJson!);
setState(() {
_paths = paths;
});
_showSnackBar('Loaded from JSON');
} else {
_showSnackBar('No JSON to load');
}
}
void _exportSvg() {
final svg = SketchSerializer.toSvg(_paths, width: 500, height: 500);
setState(() {
_lastSvg = svg;
});
_showSnackBar('SVG Exported to preview');
}
Future<void> _saveToFile(
{required String content,
required String fileName,
required String extension}) async {
try {
String? outputFile = await FilePicker.platform.saveFile(
dialogTitle: 'Please select an output file:',
fileName: '$fileName.$extension',
type: FileType.custom,
allowedExtensions: [extension],
);
if (outputFile == null) {
// User canceled the picker
return;
}
final file = File(outputFile);
await file.writeAsString(content);
_showSnackBar('Saved to $outputFile');
} catch (e) {
_showSnackBar('Error saving file: $e');
}
}
void _saveJsonToFile() {
final json = SketchSerializer.toJson(_paths);
_saveToFile(content: json, fileName: 'sketch', extension: 'json');
}
void _saveSvgToFile() {
final svg = SketchSerializer.toSvg(_paths, width: 800, height: 800);
_saveToFile(content: svg, fileName: 'sketch', extension: 'svg');
}
void _showSnackBar(String message) {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text(message)));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Serializable Sketch Demo'),
actions: [
IconButton(
icon: const Icon(Icons.delete),
onPressed: _clearPaths,
tooltip: 'Clear',
),
],
),
body: Column(
children: [
Expanded(
flex: 2,
child: Container(
margin: const EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(8),
color: Colors.white,
),
child: SketchCanvas(
paths: _paths,
onPathsChanged: _onPathsChanged,
strokeColor: Colors.deepPurple,
),
),
),
Expanded(
flex: 1,
child: Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
color: Colors.grey[100],
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Controls:',
style: TextStyle(fontWeight: FontWeight.bold),
),
Row(
children: [
ElevatedButton(
onPressed: _saveToJson,
child: const Text('Preview JSON')),
const SizedBox(width: 8),
ElevatedButton(
onPressed: _loadFromJson,
child: const Text('Load JSON')),
const SizedBox(width: 8),
ElevatedButton(
onPressed: _exportSvg,
child: const Text('Preview SVG')),
],
),
const SizedBox(height: 8),
Row(
children: [
ElevatedButton.icon(
onPressed: _saveJsonToFile,
icon: const Icon(Icons.save),
label: const Text('Save JSON to File'),
),
const SizedBox(width: 8),
ElevatedButton.icon(
onPressed: _saveSvgToFile,
icon: const Icon(Icons
.picture_as_pdf_outlined), // SVG icon would be better if available
label: const Text('Save SVG to File'),
),
],
),
if (_lastJson != null) ...[
const SizedBox(height: 16),
const Text(
'Last Save JSON:',
style: TextStyle(fontWeight: FontWeight.bold),
),
SelectableText(
_lastJson!,
style: const TextStyle(
fontSize: 10,
fontFamily: 'monospace',
),
),
],
if (_lastSvg != null) ...[
const SizedBox(height: 16),
const Text(
'Last Export SVG:',
style: TextStyle(fontWeight: FontWeight.bold),
),
SelectableText(
_lastSvg!,
style: const TextStyle(
fontSize: 10,
fontFamily: 'monospace',
),
),
],
],
),
),
),
),
],
),
);
}
}