Flutter:使用 CustomClipper 绘制 N 角星

简介: 本文将向您展示如何使用Flutter 中的**CustomClipper类绘制n 角星**(5 角星、6 角星、10 角星、20 角星等)。无需安装任何第三方软件包。我们将从头开始制作东西。

本文将向您展示如何使用Flutter 中的**CustomClipper类绘制n 角星**(5 角星、6 角星、10 角星、20 角星等)。无需安装任何第三方软件包。我们将从头开始制作东西。

重点是什么?

1.通过扩展CustomClipper类实现一个可重用的自定义裁剪器:

// This custom clipper help us achieve n-pointed star shape
class StarClipper extends CustomClipper<Path> {
  /// The number of points of the star
  final int points;
  StarClipper(this.points);
  // Degrees to radians conversion
  double _degreeToRadian(double deg) => deg * (math.pi / 180.0);
  @override
  Path getClip(Size size) {
    Path path = Path();
    double max = 2 * math.pi;
    double width = size.width;
    double halfWidth = width / 2;
    double wingRadius = halfWidth;
    double radius = halfWidth / 2;
    double degreesPerStep = _degreeToRadian(360 / points);
    double halfDegreesPerStep = degreesPerStep / 2;
    path.moveTo(width, halfWidth);
    for (double step = 0; step < max; step += degreesPerStep) {
      path.lineTo(halfWidth + wingRadius * math.cos(step),
          halfWidth + wingRadius * math.sin(step));
      path.lineTo(halfWidth + radius * math.cos(step + halfDegreesPerStep),
          halfWidth + radius * math.sin(step + halfDegreesPerStep));
    }
    path.close();
    return path;
  }
  // If the new instance represents different information than the old instance, this method will return true, otherwise it should return false.
  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    StarClipper starClipper = oldClipper as StarClipper;
    return points != starClipper.points;
  }
}
  1. 现在您可以轻松绘制星星了,如下所示:
 SizedBox(
                height: 360,
                width: 360,
                child: ClipPath(
                  clipper: StarClipper(6),
                  child: Container(
                    height: 300,
                    color: Colors.amber,
                  ),
                ),
              ),

完整示例

预览

此示例生成 4 种不同的星形:5 角星、6 角星、10 角星和 20 角星。image.png

编码

main.dart 中的完整源代码和解释:

// main.dart
import 'package:flutter/material.dart';
import 'dart:math' as math;
// This custom clipper help us achieve n-pointed star shape
class StarClipper extends CustomClipper<Path> {
  /// The number of points of the star
  final int points;
  StarClipper(this.points);
  // Degrees to radians conversion
  double _degreeToRadian(double deg) => deg * (math.pi / 180.0);
  @override
  Path getClip(Size size) {
    Path path = Path();
    double max = 2 * math.pi;
    double width = size.width;
    double halfWidth = width / 2;
    double wingRadius = halfWidth;
    double radius = halfWidth / 2;
    double degreesPerStep = _degreeToRadian(360 / points);
    double halfDegreesPerStep = degreesPerStep / 2;
    path.moveTo(width, halfWidth);
    for (double step = 0; step < max; step += degreesPerStep) {
      path.lineTo(halfWidth + wingRadius * math.cos(step),
          halfWidth + wingRadius * math.sin(step));
      path.lineTo(halfWidth + radius * math.cos(step + halfDegreesPerStep),
          halfWidth + radius * math.sin(step + halfDegreesPerStep));
    }
    path.close();
    return path;
  }
  // If the new instance represents different information than the old instance, this method will return true, otherwise it should return false.
  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    StarClipper starClipper = oldClipper as StarClipper;
    return points != starClipper.points;
  }
}
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'KindaCode.com',
      theme: ThemeData(
        primarySwatch: Colors.indigo,
      ),
      home: const MyHomePage(),
    );
  }
}
class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Kindacode.com'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Center(
          child: Column(
            children: [
              // 5-pointed star
              SizedBox(
                height: 180,
                width: 180,
                child: ClipPath(
                  clipper: StarClipper(5),
                  child: Container(
                    height: 150,
                    color: Colors.green,
                  ),
                ),
              ),
              // 6-pointed star
              SizedBox(
                height: 180,
                width: 180,
                child: ClipPath(
                  clipper: StarClipper(6),
                  child: Container(
                    height: 150,
                    color: Colors.amber,
                  ),
                ),
              ),
              // 10-pointed star
              SizedBox(
                height: 180,
                width: 180,
                child: ClipPath(
                  clipper: StarClipper(10),
                  child: Container(
                    height: 150,
                    color: Colors.indigo,
                  ),
                ),
              ),
              // 20-pointed star
              SizedBox(
                height: 180,
                width: 180,
                child: ClipPath(
                  clipper: StarClipper(20),
                  child: Container(
                    height: 150,
                    color: Colors.cyan,
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

结论

我们从头开始绘制自定义星形,没有使用任何第三个插件。如果您想在现代 Flutter 中探索更多新奇有趣的东西

相关文章
【绘制 widget】Flutter DecratedBox
【绘制 widget】Flutter DecratedBox
143 0
【绘制 widget】Flutter DecratedBox
|
Dart 前端开发
【绘制 widget】Flutter Transform
【绘制 widget】Flutter Transform
195 0
【绘制 widget】Flutter Transform
|
缓存 前端开发
【绘制 widget】Flutter CustomPaint
【绘制 widget】Flutter CustomPaint
134 0
【绘制 widget】Flutter CustomPaint
|
程序员
Flutter:如何使用 CustomPaint 绘制心形
作为程序员其实也有浪漫的一幕,今天我们一起借助CustomPaint和CustomPainter绘制心形,本文将带您了解在 Flutter 中使用CustomPaint和CustomPainter绘制心形的端到端示例。闲话少说(比如谈论 Flutter 的历史或它有多华丽),让我们深入研究代码并制作一些东西。
205 0
Flutter:如何使用 CustomPaint 绘制心形
|
前端开发 JavaScript API
Flutter图像绘制原理深入分析
本文章将讲述 CPU、GPU和显示器 显示图像的协作原理、Vsync 机制、Flutter Vsync 流程
Flutter图像绘制原理深入分析
|
2月前
|
Android开发 iOS开发 容器
鸿蒙harmonyos next flutter混合开发之开发FFI plugin
鸿蒙harmonyos next flutter混合开发之开发FFI plugin
|
1月前
|
开发框架 Dart 前端开发
Flutter 是谷歌推出的一款高效跨平台移动应用开发框架,使用 Dart 语言,具备快速开发、跨平台支持、高性能、热重载及美观界面等特点。
Flutter 是谷歌推出的一款高效跨平台移动应用开发框架,使用 Dart 语言,具备快速开发、跨平台支持、高性能、热重载及美观界面等特点。本文从 Flutter 简介、特点、开发环境搭建、应用架构、组件详解、路由管理、状态管理、与原生代码交互、性能优化、应用发布与部署及未来趋势等方面,全面解析 Flutter 技术,助你掌握这一前沿开发工具。
61 8
|
1月前
|
存储 JavaScript 前端开发
在Flutter开发中,状态管理至关重要。随着应用复杂度的提升,有效管理状态成为挑战
在Flutter开发中,状态管理至关重要。随着应用复杂度的提升,有效管理状态成为挑战。本文介绍了几种常用的状态管理框架,如Provider和Redux,分析了它们的基本原理、优缺点及适用场景,并提供了选择框架的建议和使用实例,旨在帮助开发者提高开发效率和应用性能。
37 4
|
1月前
|
传感器 前端开发 Android开发
在 Flutter 开发中,插件开发与集成至关重要,它能扩展应用功能,满足复杂业务需求
在 Flutter 开发中,插件开发与集成至关重要,它能扩展应用功能,满足复杂业务需求。本文深入探讨了插件开发的基本概念、流程、集成方法、常见类型及开发实例,如相机插件的开发步骤,同时强调了版本兼容性、性能优化等注意事项,并展望了插件开发的未来趋势。
42 2
|
2月前
|
开发者
鸿蒙Flutter实战:07-混合开发
鸿蒙Flutter混合开发支持两种模式:1) 基于har包,便于主项目开发者无需关心Flutter细节,但不支持热重载;2) 基于源码依赖,利于代码维护与热重载,需配置Flutter环境。项目结构包括AppScope、flutter_module等目录,适用于不同开发需求。
114 3