✍️ Etch

Flutter 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,
        ),
    ),
  • 轻松支持路径

    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—-’ 的元素都可以放入其中(EtchParagraph, EtchPath, EtchCircle 等)。

默认构造函数参数通常接受点,而 .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..// add your props,
      ),
    ),
  • 要向元素添加路径,请使用 EtchPath。Etch 路径元素的命名格式为 EtchPath---EtchPathAddPolygon, EtchPathAddArc, EtchPathCubicTo 等)

    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 一样,它可以包含多个 EtchElements。图层可以有自己的变换而不影响画布的其他部分——因此您可以旋转或缩放一个图层而不影响其他图层。EtchLayerTransform 小部件一样,有多个内置的变换——但您可以使用默认构造函数传递自己的 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),
                ),
              ],
            ),
        ],
    ),

附加信息

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

GitHub

查看 Github