Flutter创意绘图插件story_painter的使用

Flutter创意绘图插件story_painter的使用

本插件提供了类似于Instagram故事编辑器中的绘图体验。story_painterhand_signature 的一个修改版本。

使用

初始化控制器

StoryPainterControl painterControl = StoryPainterControl(
    type: PainterDrawType.shape, // 绘制类型
    threshold: 3.0, // 阈值
    smoothRatio: 0.65, // 平滑比率
    velocityRange: 2.0, // 速度范围
    color: Colors.white, // 初始颜色
    width: 8, // 初始宽度
    onDrawStart: () {}, // 开始绘制时的回调
    onDrawEnd: () {}, // 结束绘制时的回调
);

构建带有控制器的StoryPainter

StoryPainter(control: painterControl)

在绘制过程中更改画笔属性

painterControl.setColor(Colors.red); // 更改颜色为红色
painterControl.setWidth(24.0); // 更改线条宽度为24.0

导出图像

ui.Image image = await painterControl.toImage(pixelRatio: 3.0);

显示或使用导出的图像

// 转换数据
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List();

// 使用内存图像显示
Image.memory(pngBytes)

完整示例代码

以下是完整的示例代码,展示了如何使用 story_painter 插件。

import 'dart:typed_data';

import 'package:fast_color_picker/fast_color_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:story_painter/story_painter.dart';

import 'dart:ui' as ui;

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  void initState() {
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  [@override](/user/override)
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  StoryPainterControl painterControl = StoryPainterControl(
    type: PainterDrawType.shape,
    threshold: 3.0,
    smoothRatio: 0.65,
    velocityRange: 2.0,
    color: Colors.black,
    width: 8,
    onDrawStart: () {},
    onDrawEnd: () {},
  );

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('story_painter'),
        actions: [
          IconButton(
            icon: Icon(Icons.undo),
            onPressed: () async {
              painterControl.undo();
            },
          ),
          IconButton(
            icon: Icon(Icons.save),
            onPressed: () async {
              ui.Image image = await painterControl.toImage(pixelRatio: 3.0);
              ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
              var pngBytes = byteData?.buffer.asUint8List();
              if (pngBytes == null) {
                return;
              }
              Navigator.of(context).push(
                MaterialPageRoute(
                  builder: (_) => OnlyImage(
                    imageData: pngBytes,
                  ),
                ),
              );
            },
          ),
        ],
      ),
      body: Stack(
        alignment: Alignment.bottomCenter,
        children: [
          StoryPainter(
            control: painterControl,
          ),
          Column(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              Slider(
                value: painterControl.width,
                onChanged: (width) {
                  painterControl.setWidth(width);
                  setState(() {});
                },
                max: 30,
                min: 5,
              ),
              FastColorPicker(
                selectedColor: painterControl.color,
                onColorSelected: (color) {
                  painterControl.setColor(color);
                  setState(() {});
                },
              ),
            ],
          )
        ],
      ),
    );
  }
}

class OnlyImage extends StatelessWidget {
  final Uint8List imageData;

  const OnlyImage({Key? key, required this.imageData}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('image'),
      ),
      body: Image.memory(
        imageData,
      ),
    );
  }
}

更多关于Flutter创意绘图插件story_painter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter创意绘图插件story_painter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


story_painter 是一个用于 Flutter 的创意绘图插件,允许用户在应用中进行自由绘图、涂鸦或签名。它提供了丰富的功能,如自定义画笔颜色、粗细、背景等,非常适合用于创建绘图或签名功能的应用。

以下是 story_painter 的基本使用方法和示例代码:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 story_painter 依赖:

dependencies:
  flutter:
    sdk: flutter
  story_painter: ^0.1.0 # 使用最新版本

然后运行 flutter pub get 安装依赖。

2. 基本使用

在 Flutter 项目中使用 story_painter 的基本步骤如下:

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

class DrawingScreen extends StatefulWidget {
  [@override](/user/override)
  _DrawingScreenState createState() => _DrawingScreenState();
}

class _DrawingScreenState extends State<DrawingScreen> {
  final StoryPainterController _controller = StoryPainterController();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('创意绘图'),
        actions: [
          IconButton(
            icon: Icon(Icons.undo),
            onPressed: () {
              _controller.undo(); // 撤销上一步
            },
          ),
          IconButton(
            icon: Icon(Icons.clear),
            onPressed: () {
              _controller.clear(); // 清空画布
            },
          ),
        ],
      ),
      body: Center(
        child: StoryPainter(
          controller: _controller,
          backgroundColor: Colors.white, // 设置背景颜色
          onDrawEnd: (points) {
            print("绘制结束,点集: $points");
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 获取绘制的图像
          final image = _controller.toImage();
          // 处理图像,例如保存或显示
        },
        child: Icon(Icons.save),
      ),
    );
  }
}

3. 自定义画笔

StoryPainter 支持自定义画笔的颜色、粗细等属性。可以通过 StoryPainterController 进行设置:

_controller.color = Colors.red; // 设置画笔颜色
_controller.strokeWidth = 5.0; // 设置画笔粗细

4. 获取绘制的图像

可以使用 _controller.toImage() 方法将绘制的图像转换为 ui.Image,然后进一步处理,例如保存到本地或显示在屏幕上。

final image = await _controller.toImage();
// 处理图像

5. 保存绘制的路径

如果需要保存用户绘制的路径,可以通过 _controller.points 获取所有点集,然后进行存储或恢复。

final points = _controller.points;
// 保存或恢复点集

6. 其他功能

  • 橡皮擦功能:可以通过设置画笔颜色为背景颜色来实现橡皮擦效果。
  • 缩放和平移:支持手势缩放和平移画布。
  • 导出为图片:支持将绘制的图像导出为 PNG 或 JPEG 格式。

7. 示例代码

以下是一个完整的示例,展示了如何使用 story_painter 创建一个简单的绘图应用:

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter 绘图示例',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: DrawingScreen(),
    );
  }
}

class DrawingScreen extends StatefulWidget {
  [@override](/user/override)
  _DrawingScreenState createState() => _DrawingScreenState();
}

class _DrawingScreenState extends State<DrawingScreen> {
  final StoryPainterController _controller = StoryPainterController();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('创意绘图'),
        actions: [
          IconButton(
            icon: Icon(Icons.undo),
            onPressed: () {
              _controller.undo();
            },
          ),
          IconButton(
            icon: Icon(Icons.clear),
            onPressed: () {
              _controller.clear();
            },
          ),
        ],
      ),
      body: Center(
        child: StoryPainter(
          controller: _controller,
          backgroundColor: Colors.white,
          onDrawEnd: (points) {
            print("绘制结束,点集: $points");
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final image = await _controller.toImage();
          // 处理图像,例如保存或显示
        },
        child: Icon(Icons.save),
      ),
    );
  }
}
回到顶部