首页 > 其他分享 >flutter的custompaint组件示例6

flutter的custompaint组件示例6

时间:2024-10-20 13:49:24浏览次数:3  
标签:custompaint dots 示例 圆点 radius double override flutter size

这段代码是一个Flutter应用程序,它创建了一个动态的艺术效果,其中包含随机颜色的点在屏幕上不断更新位置。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Dynamic Art Example'),
        ),
        body: DynamicArtWidget(),
      ),
    );
  }
}

class DynamicArtWidget extends StatefulWidget {
  @override
  _DynamicArtWidgetState createState() => _DynamicArtWidgetState();
}

class _DynamicArtWidgetState extends State<DynamicArtWidget>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  final List<ColoredDot> _dots = [];
  late double _centerX;
  late double _centerY;
  late double _radius;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 10),
      vsync: this,
    )..repeat();

    // Initialize the dots
    for (int i = 0; i < 50; i++) {
      _dots.add(ColoredDot(Offset(0, 0), _generateRandomColor()));
    }

    _controller.addListener(() {
      setState(() {
        for (var dot in _dots) {
          dot.updatePosition(_centerX, _centerY, _radius);
        }
      });
    });
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    final Size size = MediaQuery.of(context).size;
    _centerX = size.width / 2;
    _centerY = size.height / 2;
    _radius = min(size.width, size.height) /
        4; // Use 1/4 of the screen size as the radius
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  Color _generateRandomColor() {
    return Color.fromRGBO(
      Random().nextInt(256),
      Random().nextInt(256),
      Random().nextInt(256),
      1,
    );
  }

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: ArtPainter(_dots),
      child: Container(),
    );
  }
}

class ArtPainter extends CustomPainter {
  final List<ColoredDot> dots;

  ArtPainter(this.dots);

  @override
  void paint(Canvas canvas, Size size) {
    for (var dot in dots) {
      final paint = Paint()
        ..color = dot.color
        ..style = PaintingStyle.fill;
      canvas.drawCircle(dot.position, 10.0, paint);
    }
  }

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

class ColoredDot {
  Offset position;
  Color color;
  final Random _random = Random();

  ColoredDot(this.position, this.color);

  void updatePosition(double centerX, double centerY, double radius) {
    // Calculate a random offset within the radius
    double dx = _random.nextDouble() * radius * 2 - radius;
    double dy = _random.nextDouble() * radius * 2 - radius;
    // Normalize the offset if it's outside the radius
    double distance = sqrt(dx * dx + dy * dy);
    if (distance > radius) {
      dx *= radius / distance;
      dy *= radius / distance;
    }
    // Update the position
    position = Offset(centerX + dx, centerY + dy);
  }
}

以下是对这段代码的分析:
一、整体功能概述
这段 Flutter 代码实现了一个动态艺术效果的应用,在屏幕上显示不断移动的彩色圆点,这些圆点围绕着屏幕中心在一定半径范围内随机移动。

二、代码结构解析
导入部分
import ‘package:flutter/material.dart’;:导入 Flutter 的核心库,用于构建用户界面。
import ‘dart:math’;:导入 Dart 的数学库,用于生成随机数和进行数学计算。

main函数
void main() { runApp(MyApp()); }:应用的入口点,启动 Flutter 应用并显示MyApp组件。

MyApp类
继承自StatelessWidget,表示无状态组件。
build方法返回一个MaterialApp,设置了应用的标题栏和主页内容为DynamicArtWidget。

DynamicArtWidget类
继承自StatefulWidget,表示有状态组件。
createState方法返回一个_DynamicArtWidgetState实例,用于管理该组件的状态。

_DynamicArtWidgetState类
定义了一个AnimationController用于控制动画,一个List存储彩色圆点,以及屏幕中心的坐标和半径。
initState方法中初始化动画控制器,设置动画持续时间并重复播放。同时初始化 50 个彩色圆点,每个圆点都有一个初始位置和随机颜色。并且添加了动画监听器,在动画每一帧更新时,调用setState触发界面重新绘制。
didChangeDependencies方法在组件依赖发生变化时被调用,这里获取屏幕尺寸,计算屏幕中心坐标和半径。
dispose方法中释放动画控制器资源。
_generateRandomColor方法生成随机颜色。
build方法返回一个CustomPaint,使用ArtPainter绘制彩色圆点。

ArtPainter类
继承自CustomPainter,用于自定义绘制。
接收一个彩色圆点列表作为参数,在paint方法中遍历列表,为每个圆点创建画笔并在画布上绘制圆形。
shouldRepaint方法返回true,表示在任何情况下都需要重新绘制。

ColoredDot类
表示一个彩色圆点,包含位置和颜色属性,以及一个随机数生成器。
updatePosition方法根据屏幕中心坐标和半径,计算并更新圆点的位置,确保圆点在半径范围内随机移动。

三、总结
这段代码通过动画控制器、自定义画家和有状态组件的配合,实现了一个动态的艺术效果,展示了 Flutter 在动画和自定义绘制方面的强大功能。用户可以看到屏幕上不断变化位置的彩色圆点,为应用增添了生动和趣味性。

标签:custompaint,dots,示例,圆点,radius,double,override,flutter,size
From: https://blog.csdn.net/weixin_42668920/article/details/143056420

相关文章

  • flutter的custompaint组件示例5
    这段代码是一个简单的Flutter应用程序,它创建了一个可拖动的自定义圆角矩形组件。import'package:flutter/material.dart';voidmain(){runApp(MyApp());}classMyAppextendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){return......
  • SpringBoot + Activiti工作流项目示例(源码)
    前言activiti工作流引擎项目,企业erp、oa、hr、crm等企事业办公系统轻松落地,一套完整并且实际运用在多套项目中的案例,满足日常业务流程审批需求。一、项目形式springboot+vue+activiti集成了activiti在线编辑器,流行的前后端分离部署开发模式,快速开发平台,可插拔工作流服务。工......
  • AOP - Advisor 示例
    定义通知publicclassLoggingAdviceimplementsMethodInterceptor{@OverridepublicObjectinvoke(MethodInvocationinvocation)throwsThrowable{System.out.println("Method"+invocation.getMethod().getName()+"isbeingcalle......
  • AOP - AspectJ 示例
    //自定义注解@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public@interfaceLogExecution{}@Aspect//切面类@Order(1000)//数字越小,优先级越高@Component//也要注册到容器publicclassLoggingAspect{//定义切点@Pointcut("ex......
  • 低功耗4G模组:tcs3472颜色传感器示例
    ​今天我们学习合宙低功耗4G模组Air780EP的LuatOS开发tcs3472示例,文末【阅读原文】获取最新资料1一、简介tcs3472颜色传感器能够读取照射到的物体的RGB三种数值,从而识别颜色关联文档和使用工具:LuatOS固件获取tcs3472颜色传感器接口说明Luatools下载调试工具二......
  • 低功耗4G模组:LCD应用示例
    ​今天我们学习合宙Air780E开发板LCD应用示例,文末【阅读原文】获取最新资料。本文档适用于Air780E开发板关联文档和使用工具lcd-demo:https://gitee.com/openLuat/LuatOS/tree/master/demo/lcdLuatools下载调试工具一、环境准备1.1Air780E开发板一套 ​1.......
  • celery简单配置示例
    目录生产者消费者配置信息celery的配置文件示例celer简单示例tree-I'containerd|vminit|__pycache__'.#app.py属于生产者├──app.py#celery_app用于配置消费者及队列信息└──celery_app#confi.py配置信息├──config.py#__init__.pycelery实例初始......
  • java堆排序的示例代码
    publicclassHeapSort{publicstaticvoidmain(String[]args){int[]arr={12,11,13,5,6,7};System.out.println("Originalarray:");for(intvalue:arr){System.out.print(value+"");......
  • RabbitMQ 通配符(Topic)模式示例
    总结自:BV15k4y1k7Ep模式说明Topic类型与Direct相比,都是可以根据Routingkey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routingkey的时候使用通配符!Topic类型的Routingkey一般都是由一个或多个单词组成,多个单词之间以.分隔,例如:item.insert通配符规......
  • RabbitMQ 路由(Routing)模式示例
    总结自:BV15k4y1k7Ep模式说明和消费订阅模式相比,路由模式特点:交换机的类型为Direct。队列与交换机绑定时,要指定一个Routingkey(路由key)。消息的发送方在向Exchange发送消息时,也必须指定消息的Routingkey。Exchange不再把消息交给每一个绑定的队列,而是根据消息的Rout......