free_form_text 0.4.4 copy "free_form_text: ^0.4.4" to clipboard
free_form_text: ^0.4.4 copied to clipboard

Styled, free form text painted to a Canvas at arbitrary angles and along a path

example/lib/main.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:free_form_text/free_form_text.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Free Form Text Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.primary,
        title: Text(
          widget.title,
          style: const TextStyle(color: Colors.white),
        ),
      ),
      body: const Center(
        child: TextExample(),
      ),
    );
  }
}

class TextExample extends StatefulWidget {
  const TextExample({super.key});

  @override
  State<TextExample> createState() => _TextExampleState();
}

class _TextExampleState extends State<TextExample> {
  late Future<FreeFormText> textFuture;
  _TextExampleState();
  @override
  void initState() {
    super.initState();
    FreeFormText text = FreeFormText(
        label: 'Lorem ipsum dolor sit amet.',
        context: context,
        style: const TextStyle(
            fontSize: 16,
            color: Colors.black,
            wordSpacing: 2.0,
            letterSpacing: 0.5,
            fontWeight: FontWeight.bold));
    textFuture = text.layout();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<FreeFormText>(
        future: textFuture,
        builder: (BuildContext context, AsyncSnapshot<FreeFormText> snapshot) {
          if (snapshot.hasData) {
            return Center(
              child: Container(
                width: MediaQuery.of(context).size.width,
                height: MediaQuery.of(context).size.height,
                padding: EdgeInsets.zero,
                margin: const EdgeInsets.all(20.0),
                child: CustomPaint(
                  painter: ExampleTextPainter(snapshot.data!),
                ),
              ),
            );
          } else {
            return const Center(child: CircularProgressIndicator());
          }
        });
  }
}

class ExampleTextPainter extends CustomPainter {
  FreeFormText text;
  ExampleTextPainter(this.text);
  @override
  void paint(Canvas canvas, Size size) {
    var painter = FreeFormTextPainter(canvas);
    painter.paintText(
        text: text, offset: const Offset(50.0, 200.0), angle: 30.0);
    painter.paintText(
        text: text, offset: const Offset(50.0, 250.0), angle: -30.0);
    List<Offset> path = List.empty(growable: true);
    path.add(const Offset(50.0, 375.0));
    path.add(const Offset(100.0, 375.0));
    path.add(const Offset(125.0, 400.0));
    path.add(const Offset(150.0, 425.0));
    path.add(const Offset(175.0, 450.0));
    path.add(const Offset(225.0, 475.0));
    path.add(const Offset(250.0, 475.0));
    path.add(const Offset(275.0, 450.0));
    final smoothPath = CubicBezier().smooth(path, 0.5);
    Paint paint = Paint();
    paint.color = const Color(0xFF0000FF);
    paint.style = PaintingStyle.stroke;
    paint.strokeWidth = 2.0;
    Path linePath = Path();
    linePath.moveTo(smoothPath[0].dx, smoothPath[0].dy);
    for (var i = 1; i < smoothPath.length; i++) {
      linePath.lineTo(smoothPath[i].dx, smoothPath[i].dy);
    }
    canvas.drawPath(linePath, paint);
    try {
      painter.paintTextAlongPath(text, smoothPath);
    } on FreeFormTextException catch (e) {
      if(kDebugMode) {
        print(e.reason);
      }
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}
1
likes
160
points
59
downloads

Publisher

verified publisherredfishresearch.com

Weekly Downloads

Styled, free form text painted to a Canvas at arbitrary angles and along a path

Repository (GitHub)
View/report issues

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

flutter, image, path_provider

More

Packages that depend on free_form_text