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
119 0
【绘制 widget】Flutter DecratedBox
|
Dart 前端开发
【绘制 widget】Flutter Transform
【绘制 widget】Flutter Transform
147 0
【绘制 widget】Flutter Transform
|
缓存 前端开发
【绘制 widget】Flutter CustomPaint
【绘制 widget】Flutter CustomPaint
104 0
【绘制 widget】Flutter CustomPaint
|
程序员
Flutter:如何使用 CustomPaint 绘制心形
作为程序员其实也有浪漫的一幕,今天我们一起借助CustomPaint和CustomPainter绘制心形,本文将带您了解在 Flutter 中使用CustomPaint和CustomPainter绘制心形的端到端示例。闲话少说(比如谈论 Flutter 的历史或它有多华丽),让我们深入研究代码并制作一些东西。
185 0
Flutter:如何使用 CustomPaint 绘制心形
|
前端开发 JavaScript API
Flutter图像绘制原理深入分析
本文章将讲述 CPU、GPU和显示器 显示图像的协作原理、Vsync 机制、Flutter Vsync 流程
Flutter图像绘制原理深入分析
|
3月前
|
缓存 监控 前端开发
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
【4月更文挑战第30天】本文探讨了Flutter应用启动优化策略,包括理解启动过程、资源加载优化、减少初始化工作、界面布局简化、异步初始化、预加载关键数据、性能监控分析以及案例和未来优化方向。通过这些方法,可以缩短启动时间,提升用户体验。使用Flutter DevTools等工具可助于识别和解决性能瓶颈,实现持续优化。
156 0
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
|
2月前
|
开发框架 前端开发 测试技术
Flutter开发常见问题解答
Flutter开发常见问题解答
|
3月前
|
前端开发 C++ 容器
Flutter-完整开发实战详解(一、Dart-语言和-Flutter-基础)(1)
Flutter-完整开发实战详解(一、Dart-语言和-Flutter-基础)(1)
|
8天前
|
移动开发 前端开发 JavaScript
"跨界大战!React Native、Weex、Flutter:三大混合开发王者正面交锋,揭秘谁才是你移动应用开发的终极利器?"
【8月更文挑战第12天】随着移动应用开发的需求日益增长,高效构建跨平台应用成为关键。React Native、Weex与Flutter作为主流混合开发框架各具特色。React Native依托Facebook的强大支持,以接近原生的性能和丰富的组件库著称;Weex由阿里巴巴开发,性能优越尤其在大数据处理上表现突出;Flutter则凭借Google的支持及独特的Dart语言和Skia渲染引擎,提供出色的定制能力和开发效率。选择时需考量项目特性、团队技能及生态系统的成熟度。希望本文对比能助你做出最佳决策。
29 1
|
2月前
|
开发框架 移动开发 Android开发
构建高效移动应用:探索Flutter开发框架
【6月更文挑战第28天】随着移动设备的普及,用户对移动应用的需求日益增长。开发者面临着在众多平台间提供无缝体验的挑战。本文深入探讨了Flutter框架如何通过其跨平台特性、热重载功能以及丰富的组件库简化移动应用的开发流程,同时确保高性能和优雅的用户界面设计。
39 2