前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter:如何使用 CustomPaint 绘制心形

Flutter:如何使用 CustomPaint 绘制心形

原创
作者头像
徐建国
修改2021-10-18 10:37:28
9870
修改2021-10-18 10:37:28
举报
文章被收录于专栏:个人路线

“ 作为程序员其实也有浪漫的一幕,今天我们一起借助CustomPaintCustomPainter绘制心形,本文将带您了解在 Flutter 中使用CustomPaintCustomPainter绘制心形的端到端示例。闲话少说(比如谈论 Flutter 的历史或它有多华丽),让我们深入研究代码并制作一些东西。 ”

例子

预览

我们将创建 4 个心形。第一个没有边界,但其他的有。

img
img

img

步骤

1.通过扩展CustomPainter类来实现一个画笔:

代码语言:javascript
复制
class MyPainter extends CustomPainter {
  // The color of the heart
  final Color bodyColor;

  // The color of the border of the heart
  final Color borderColor;
  // The thickness of the border
  final double borderWith;

  MyPainter(this.bodyColor, this.borderColor, this.borderWith);

  @override
  void paint(Canvas canvas, Size size) {
    // The body of the heart
    final Paint body = Paint();
    body
      ..color = bodyColor
      ..style = PaintingStyle.fill
      ..strokeWidth = 0;

    // The border of the heart
    final Paint border = Paint();
    border
      ..color = borderColor
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round
      ..strokeWidth = borderWith;

    final double width = size.width;
    final double height = size.height;

    final Path path = Path();
    path.moveTo(0.5 * width, height * 0.4);
    path.cubicTo(0.2 * width, height * 0.1, -0.25 * width, height * 0.6,
        0.5 * width, height);
    path.moveTo(0.5 * width, height * 0.4);
    path.cubicTo(0.8 * width, height * 0.1, 1.25 * width, height * 0.6,
        0.5 * width, height);

    canvas.drawPath(path, body);
    canvas.drawPath(path, border);
  }

2.使用 CustomPaint 小部件和我们之前创建的画家绘制心形:

代码语言:javascript
复制
// Non-border heart
          CustomPaint(
            size: const Size(280, 260),
            painter: MyPainter(Colors.pink, Colors.transparent, 0),
          ),

// Hearts with borders
          CustomPaint(
            size: const Size(200, 120),
            painter: MyPainter(Colors.purple, Colors.black, 10),
          ),
          CustomPaint(
            size: const Size(200, 240),
            painter: MyPainter(Colors.red, Colors.redAccent, 5),
          ),
          CustomPaint(
            size: const Size(50, 100),
            painter: MyPainter(Colors.amber, Colors.indigo, 10),
          ),

最终代码

这是main.dart中的完整代码,它生成了上面屏幕截图中显示的很酷的心形:

代码语言:javascript
复制
// main.dart
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Hide the debug banner
      debugShowCheckedModeBanner: false,
      title: 'breeze',
      theme: ThemeData(
        primarySwatch: Colors.indigo,
      ),
      home: const HomeScreen(),
    );
  }
}

// Implementing our heart painter
class MyPainter extends CustomPainter {
  // The color of the heart
  final Color bodyColor;

  // The color of the border of the heart
  final Color borderColor;
  // The thickness of the border
  final double borderWith;

  MyPainter(this.bodyColor, this.borderColor, this.borderWith);

  @override
  void paint(Canvas canvas, Size size) {
    // The body of the heart
    final Paint body = Paint();
    body
      ..color = bodyColor
      ..style = PaintingStyle.fill
      ..strokeWidth = 0;

    // The border of the heart
    final Paint border = Paint();
    border
      ..color = borderColor
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round
      ..strokeWidth = borderWith;

    final double width = size.width;
    final double height = size.height;

    final Path path = Path();
    path.moveTo(0.5 * width, height * 0.4);
    path.cubicTo(0.2 * width, height * 0.1, -0.25 * width, height * 0.6,
        0.5 * width, height);
    path.moveTo(0.5 * width, height * 0.4);
    path.cubicTo(0.8 * width, height * 0.1, 1.25 * width, height * 0.6,
        0.5 * width, height);

    canvas.drawPath(path, body);
    canvas.drawPath(path, border);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

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

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('KindaCode.com'),
      ),
      body: Center(
          child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        mainAxisSize: MainAxisSize.min,
        children: [
          // Non-border heart
          CustomPaint(
            size: const Size(280, 260),
            painter: MyPainter(Colors.pink, Colors.transparent, 0),
          ),

          // Hearts with borders
          CustomPaint(
            size: const Size(200, 120),
            painter: MyPainter(Colors.purple, Colors.black, 10),
          ),
          CustomPaint(
            size: const Size(200, 240),
            painter: MyPainter(Colors.red, Colors.redAccent, 5),
          ),
          CustomPaint(
            size: const Size(50, 100),
            painter: MyPainter(Colors.amber, Colors.indigo, 10),
          ),
        ],
      )),
    );
  }
}

参考

您可以在官方文档中找到有关 CustomPaint 小部件和 CustomPainter 类的更多详细信息:

后记

您已经学会了如何在不使用任何第三方软件包的情况下从头开始绘制自定义心形。此时,您应该对 Flutter 中的绘图有了更好的了解。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 例子
    • 预览
      • 步骤
        • 最终代码
        • 参考
        • 后记
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档