Flutter自定义绘制或图形处理插件etch的使用

发布于 1周前 作者 songsunli 最后一次编辑是 5天前 来自 Flutter

Flutter自定义绘制或图形处理插件etch的使用

✍️ Etch #

一个简化、声明式的CustomPaint实现 #

特性 #

  • 以声明方式创建CustomPaint小部件。
    EtchCanvas(
        etchElements: [
            EtchCircle.alignment(
                centerAlignment: Offset.zero,
                radius: 50.0,
            ),
        ],
        child: SizedBox(
          width: 100.0,
          height: 100.0,
        ),
    ),
  • 可以使用点或对齐方式来定义点。
    EtchCanvas(
        etchElements: [
            EtchCircle(
              center: Offset(100, 100),
              radius: 50.0,
            ),
            EtchCircle.alignment(
               centerAlignment: Offset.zero,
               radius: 50.0,
               etchStyle: EtchStyle(
                   color: Colors.red,
               ),
           ),
        ],
        child: SizedBox(
          width: 100.0,
          height: 100.0,
        ),
    ),
  • 支持Paths。
    EtchCanvas(
      etchElements: [
        EtchPath(
          etchPathElements: [
            EtchPathMoveTo(point: Offset(0, 0)),
            EtchPathAddPolygon.alignment(
              pointAlignments: [
                Offset(-1, -1),
                Offset(1, -1),
                Offset(1, 1),
              ],
            ),
            EtchPathQuadraticBezierTo.alignment(
              controlPointAlignment: Offset(1, 0.75),
              endPointAlignment: Offset(-1, 1),
            ),
            EtchPathClose(),
          ],
        ),
      ],
      child: SizedBox(
        width: 100.0,
        height: 100.0,
      ),
    ),
  • 轻松处理画布层。
    EtchCanvas(
      etchElements: [
        EtchLayer.rotate(
          rotateZ: 1.2,
          etchElements: [
            EtchRect.alignment(
              topLeftAlignment: Offset(-1, -1),
              bottomRightAlignment: Offset(1, 1),
            ),
          ],
        ),
      ],
      child: SizedBox(
        width: 100.0,
        height: 100.0,
      ),
    ),
  • 使用<TweenAnimationBuilder>进行动画。

可以使用<TweenAnimationBuilder>或普通动画控制器轻松添加动画,无需传递进度或其他逻辑。

    TweenAnimationBuilder<double>(
      duration: const Duration(seconds: 1),
      tween: Tween(begin: 0, end: 2 * pi),
      builder: (context, val, _) {
        return EtchCanvas(
          etchElements: [
            EtchLayer.rotate(
              rotateZ: val,
              etchElements: [
                EtchRect.alignment(
                  topLeftAlignment: Offset(-1, -1),
                  bottomRightAlignment: Offset(1, 1),
                ),
              ],
            ),
          ],
          child: const SizedBox(
            width: 100.0,
            height: 100.0,
          ),
        );
      }
    ),

开始使用 #

  • 要开始使用,只需在应用中添加EtchCanvas
    EtchCanvas(
        etchElements: [],
    ),

所有格式为'Etch----'的元素都可以放入这些元素中(EtchParagraphEtchPathEtchCircle等)。

默认构造函数参数通常接受点,而.alignment构造函数接受对齐方式。对齐方式中,(-1, -1) 是左上角,(1, 1) 是右下角。

    EtchCanvas(
        etchElements: [
            EtchRect.alignment(
              topLeftAlignment: Offset.zero,
              bottomRightAlignment: Offset(1, 1),
            ),
            EtchOval.alignment(
              topLeftAlignment: Offset(-1, -1),
              bottomRightAlignment: Offset(0, 0),
            ),
            EtchArc.alignment(
              topLeftAlignment: Offset(-1, -1),
              bottomRightAlignment: Offset(1, 1),
              startAngle: 0,
              sweepAngle: 2,
            ),
        ],
    ),
  • 使用EtchStyle修改画笔属性。
    EtchPath(
      etchPathElements: [
        //...
      ],
      etchStyle: EtchStyle(
        style: PaintingStyle.stroke,
      ),
    ),

也可以使用EtchStyle.raw()提供自己的Paint对象。

    EtchPath(
      etchPathElements: [
        //...
      ],
      etchStyle: EtchStyle.raw(
        Paint()..color = Colors.black..// 添加你的属性,
      ),
    ),
  • 要向元素中添加路径,使用EtchPath。Etch路径元素的命名格式为EtchPath---EtchPathAddPolygonEtchPathAddArcEtchPathCubicTo等)。
    EtchCanvas(
        etchElements: [
             EtchPath(
                 etchPathElements: [
                     EtchPathMoveTo(point: Offset(0, 0)),
                     EtchPathLine(point: Offset(110, 0)),
                     EtchPathLine(point: Offset(110, 110)),
                     EtchPathClose(),
                 ],
                 etchStyle: EtchStyle(
                     style: PaintingStyle.stroke,
                 ),
             ),
        ],
    ),
  • 要添加图层,使用EtchLayer元素。这可以像普通的EtchCanvas一样包含多个EtchElement。图层可以有独立的变换,不会影响其他部分 - 因此你可以旋转或缩放一层而不影响其他层。EtchLayer,就像Transform小部件一样,具有多种内置变换 - 但你也可以使用默认构造函数传递自己的Matrix4
    EtchCanvas(
        etchElements: [
            EtchLayer.rotate(
              rotateX: 1.2,
              etchElements: [
                EtchRect.alignment(
                  topLeftAlignment: Offset(-1, -1),
                  bottomRightAlignment: Offset(1, 1),
                ),
              ],
            ),
            EtchLayer.scale(
              scale: Offset(1, 2),
              etchElements: [
                EtchRect.alignment(
                  topLeftAlignment: Offset(-1, -1),
                  bottomRightAlignment: Offset(1, 1),
                ),
              ],
            ),
            EtchLayer(
              transform: Matrix4.identity(),
              etchElements: [
                EtchRect.alignment(
                  topLeftAlignment: Offset(-1, -1),
                  bottomRightAlignment: Offset(1, 1),
                ),
              ],
            ),
        ],
    ),

额外信息 #

注意:该包目前处于实验阶段,尚未确定完整的指标。如果您在使用过程中遇到任何意外情况,请随时提交问题或PR。

完整示例demo

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

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // 这个小部件是您的应用的根。
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const DemoPage());
  }
}

class DemoPage extends StatefulWidget {
  const DemoPage({Key? key}) : super(key: key);

  [@override](/user/override)
  _DemoPageState createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: EtchCanvas(
          etchElements: [
            EtchLayer.scale(
              scale: const Offset(1, 2),
              etchElements: [
                EtchLine(
                    start: const Offset(0, 0), end: const Offset(100, 100)),
                EtchLine(
                    start: const Offset(0, 50), end: const Offset(100, 100)),
              ],
            ),
            EtchPath(
              etchPathElements: [
                EtchPathMoveTo(point: Offset(0, 0)),
                EtchPathLine(point: Offset(110, 0)),
                EtchPathLine(point: Offset(110, 110)),
                EtchPathClose(),
              ],
              etchStyle: EtchStyle(
                style: PaintingStyle.stroke,
              ),
            ),
            EtchPath(
              etchPathElements: [
                EtchPathMoveTo(point: const Offset(0, 0)),
                EtchPathAddPolygon.alignment(
                  pointAlignments: [
                    const Offset(0, 0),
                    const Offset(1, 0),
                    const Offset(1, 1),
                  ],
                ),
                EtchPathConicTo.alignment(
                  controlPointAlignment: const Offset(0.2, 0.4),
                  endPointAlignment: const Offset(0.5, -0.5),
                ),
                EtchPathClose(),
              ],
              etchStyle: EtchStyle(
                style: PaintingStyle.stroke,
              ),
            ),
          ],
          child: const SizedBox(
            width: 100.0,
            height: 100.0,
          ),
        ),
      ),
    );
  }
}

更多关于Flutter自定义绘制或图形处理插件etch的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自定义绘制或图形处理插件etch的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


基于你提到的Flutter插件etch(虽然具体介绍为undefined,但从名称推测可能与自定义绘制或图形处理相关),以下是一个假设性的代码案例,展示如何在Flutter中使用一个自定义绘制的插件。请注意,这不是针对真实存在的etch插件的官方指南,而是一个假设性的示例。

假设etch插件提供了一个用于绘制自定义图形的CustomCanvas小部件,我们可以像下面这样使用它:

import 'package:flutter/material.dart';
import 'package:etch/etch.dart'; // 假设etch插件的导入路径

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Etch Plugin Demo'),
        ),
        body: Center(
          child: CustomCanvasDemo(),
        ),
      ),
    );
  }
}

class CustomCanvasDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: double.infinity,
      child: CustomPaint(
        painter: EtchPainter(),
        child: Container(), // 这里通常不需要子小部件,但为了CustomPaint结构完整性保留
      ),
    );
  }
}

class EtchPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // 假设etch插件提供了某种绘图API
    // 这里使用Flutter自带的Canvas API作为示例
    final paint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.stroke
      ..strokeWidth = 4.0;

    // 画一个矩形
    final rect = Rect.fromLTWH(50, 50, 200, 100);
    canvas.drawRect(rect, paint);

    // 画一个圆形
    final center = Offset(size.width / 2, size.height / 2);
    final radius = 50.0;
    canvas.drawCircle(center, radius, paint);

    // 假设etch插件允许我们进行更复杂的图形处理
    // 例如,通过某种etch特有的API绘制自定义形状
    // etch.drawCustomShape(canvas, someCustomShapeData, customPaintOptions);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // 假设没有需要更新的状态,返回false
    return false;
  }
}

在这个假设性的示例中:

  1. 我们导入了etch插件(假设其导入路径为package:etch/etch.dart)。
  2. 创建了一个CustomCanvasDemo小部件,它使用CustomPaint和自定义的EtchPainter来绘制图形。
  3. EtchPainter类中,我们重写了paint方法来定义绘制逻辑。这里使用了Flutter自带的CanvasPaint类来绘制一个矩形和一个圆形,作为示例。
  4. 注释中提到了假设性的etch特有的API调用,这展示了如果etch插件提供了更复杂的图形处理功能,我们可能会如何使用它。

请注意,由于etch插件是假设性的,上述代码中的etch相关部分(如导入路径和API调用)需要根据实际插件的文档进行调整。如果你找到了一个真实的etch插件,请参考其官方文档以获取正确的使用方法和API。

回到顶部