欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、 肝小叶迷宫与细胞色素 P450 的微观战争

在生物组学与系统生物学的视野中,人体的每一次心跳、每一轮代谢都伴随着内源性废料(如氨、胆红素)与外源性毒素(如酒精、药物代谢产物)的生成。肝脏(Liver),作为人体最核心的生化反应堆,通过其数以百万计的肝小叶(Hepatic Lobules)进行着精密的向心过滤。而这场过滤战役的主力军,便是大名鼎鼎的细胞色素 P450(CYP450)超家族酶类。

然而,最新的临床代谢组学数据无情地揭示了一条铁律:CYP450的合成与活性,深度受制于宿主的昼夜节律(Circadian Rhythm)与深度睡眠时长。在睡眠剥夺的极端状态下,酶的转录被阻断,毒素如同脱缰的野马,从汇管区侵入肝血窦,却无法被有效地中和,最终导致脂质过氧化(Lipid Peroxidation)与不可逆的肝纤维化(Hepatic Fibrosis)。

本文将以极致的跨端前端架构为载体,通过 Flutter 的底图 Canvas 原语结合数据驱动模型,构建一台拥有双路环境(对照组 vs 干预实验组)的《肝脏代谢清除率演算仪》。在本项目中,我们将彻底驯服横跨桌面、平板、手机的 Overflow 布局溢出痛点,以严谨的代码与申论般的逻辑,向您呈现昼夜节律干预下的微观流体力学悲歌。


二、 数学建模: CYP450 活性与流场渗透概率

为了在前端内存中重构肝脏代谢系统,我们需要构建一套独立于后端的微积分演进模型。

2.1 CYP450 活性的 Sigmoid 衰减拟合

传统的线性衰减无法反映生物酶在面临压力时的“崩溃点”。我们采用类 Sigmoid 变种函数来拟合 CYP450 活性( E c y p E_{cyp} Ecyp)与实际睡眠时长( S t i m e S_{time} Stime)之间的非线性关系:

E c y p ( S t i m e ) = 100 ⋅ 1 1 + e − 1.2 ⋅ ( S t i m e − 4.5 ) E_{cyp}(S_{time}) = 100 \cdot \frac{1}{1 + e^{-1.2 \cdot (S_{time} - 4.5)}} Ecyp(Stime)=1001+e1.2(Stime4.5)1

通过该函数,当 S t i m e ≥ 8 S_{time} \ge 8 Stime8 时,酶活性趋于健康的 100%;而当睡眠跌破 4.5 小时的生死线时,酶活性将发生雪崩式断崖下降。

2.2 毒素粒子向心流场中的解毒概率

每一颗由周边向中心(中央静脉)渗透的毒素粒子(Toxin Particle),在流经肝索的每一个时间积分( d t dt dt)内,都有被 CYP450 酶中和转化为无毒水溶性物质的概率( P d e t o x P_{detox} Pdetox)。这表现为一个离散的泊松过程:

P d e t o x = α ⋅ E c y p 100 ⋅ d t P_{detox} = \alpha \cdot \frac{E_{cyp}}{100} \cdot dt Pdetox=α100Ecypdt

若粒子在到达中央静脉前未命中该概率,则会在肝血窦中滞留并淤积,引发周围肝星状细胞的活化,即 UI 界面上呈现的【脂化/纤维化指数】的飙升。


三、 双环境隔离流水的系统工程抽象

为防止两组数据的交叉污染以及避免 Widget 构建树的冗余计算,本系统在工程架构上引入了严格的 MVC 隔离模式。

图 1:生化双引擎与渲染管线拓扑图

S_time 更新

写保护隔离

Tick dt 积分

Tick dt 积分

Slider 昼夜节律控制板

实验组肝脏环境

对照组肝脏环境 S_time=8.0

实验组向心流场演算: 酶活性降低, 毒素拥堵

对照组向心流场演算: 酶解迅速, 通畅排空

实验组 CustomPainter 重绘

对照组 CustomPainter 重绘


四、 跨端架构深度解剖:四点核心源码决战防溢出

在 Flutter 开发界,伴随多端分辨率剧变而来的 RIGHT OVERFLOWED BY XX PIXELS 犹如梦魇。在本系统的四段核心代码中,我们将展示如何通过弹性力学容器与底层 Canvas 逃逸,彻底消灭这一宿敌。

4.1 核心源码一:领域环境的内存级封装与生化推演

所有业务逻辑全部前置,且被封装于独立的 LiverEnvironment 类中。通过 isControlGroup 标识,我们将对照组的数据彻底锁死在最佳生理态,保障了生物学比对的严谨性。

// -----------------------------------------------------
// 核心源码一:肝脏生化流场与清除率方程
// -----------------------------------------------------
class LiverEnvironment {
  final bool isControlGroup;
  double targetSleepDuration; 
  double cyp450EnzymeLevel = 100.0; 
  double toxinLoadPercentage = 0.0; 
  
  void _updateBiochemicalField() {
    // 强制防呆:防止对照组被外部 Slider 污染
    if (isControlGroup) {
      targetSleepDuration = 8.0; 
    }

    // Sigmoid 酶活性衰减数学拟合
    cyp450EnzymeLevel = 100.0 * (1.0 / (1.0 + exp(-1.2 * (targetSleepDuration - 4.5))));

    // 毒素滞留浓度计算
    if (particles.isNotEmpty) {
      int toxicCount = particles.where((p) => !p.isNeutralized).length;
      toxinLoadPercentage = (toxicCount / particles.length) * 100.0;
    }
  }
}

4.2 核心源码二:微积分粒子流体动力学

我们绕开了繁重的 AnimatedBuilder 或海量的组件堆叠,在每一帧的回调(Tick)中直接利用三角函数推演粒子的向心渗透。同时,融入纤维化带来的微观流速阻力。

// -----------------------------------------------------
// 核心源码二:毒素粒子的向心渗透碰撞检测
// -----------------------------------------------------
    for (int i = particles.length - 1; i >= 0; i--) {
      var p = particles[i];
      p.lifetime += dt;

      // CYP450 酶促概率判定:睡眠越少,解毒概率越趋近于零
      if (!p.isNeutralized) {
        double detoxProbability = (cyp450EnzymeLevel / 100.0) * 0.02; 
        if (_rnd.nextDouble() < detoxProbability) {
          p.isNeutralized = true;
          p.speed *= 2.5; // 水溶化后加速通过中央静脉
        }
      }

      // 根据纤维化危机的渗透阻力模型
      double resistance = p.isNeutralized ? 1.0 : max(0.2, 1.0 - (fibrosisRiskIndex * 0.005));
      p.x += cos(p.angle) * p.speed * dt * resistance + (_rnd.nextDouble() - 0.5) * 2.0;
      p.y += sin(p.angle) * p.speed * dt * resistance + (_rnd.nextDouble() - 0.5) * 2.0;
      
      // [...] 中央静脉排空判定
    }

4.3 核心源码三:双路对照视窗与弹性降维打击

这是解决屏幕溢出问题的核武器。我们不能假设宿主设备拥有无限宽度。通过 LayoutBuilder 嗅探物理极限,当宽度跌破 750px(如手机竖屏)时,立刻从水平比对(Row)降维为垂直比对(Column)。而无处不在的 Expanded 则彻底吞噬了任何向外延展的不稳定边界。

// -----------------------------------------------------
// 核心源码三:防溢出响应式双态视窗管线
// -----------------------------------------------------
  Expanded(
    child: LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.maxWidth > 750) {
          return Row(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              Expanded(child: _buildHepaticViewport('标准对照组', _controlEnv)),
              const SizedBox(width: 16),
              Expanded(child: _buildHepaticViewport('干预实验组', _experimentEnv)),
            ],
          );
        } else {
          // 窄屏触发降维防御:纵向层叠
          return Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              Expanded(child: _buildHepaticViewport('标准对照组', _controlEnv)),
              const SizedBox(height: 16),
              Expanded(child: _buildHepaticViewport('干预实验组', _experimentEnv)),
            ],
          );
        }
      },
    ),
  ),

不仅在主框架中,哪怕是小如数据播报面板的局部,我们也严禁使用具有无限横向延展风险的 Row,转而使用 Wrap 组件,辅以 spacingrunSpacing。如此一来,纵使内部数字跳跃导致长度剧增,也会被安全折流进下一行。

4.4 核心源码四:高维 Canvas 直接绘制与发光滤镜

由于粒子数量在极端拥堵时会达到数百,且其坐标与颜色透明度每 16.6ms 都在狂暴重塑,必须祭出原生的 Canvas。利用 MaskFilter.blur 模拟了毒素粒子的放射性与酶促反应的生命光晕。

// -----------------------------------------------------
// 核心源码四:高频粒子流场原语绘制
// -----------------------------------------------------
  
  void paint(Canvas canvas, Size size) {
    // [...] 省略背景与肝索线绘制
    final Paint particlePaint = Paint();
    
    for (var p in env.particles) {
      if (p.isNeutralized) {
        // 清洁水分子
        particlePaint.color = const Color(0xFF42A5F5).withOpacity(0.6);
        particlePaint.maskFilter = null; 
      } else {
        // 剧毒代谢废料堆积:荧光亮黄绿
        double toxicIntensity = (p.lifetime / 10.0).clamp(0.0, 1.0);
        int r = (100 + 155 * toxicIntensity).toInt();
        int g = (255 - 100 * toxicIntensity).toInt();
        particlePaint.color = Color.fromARGB(220, r, g, 50);
        particlePaint.maskFilter = const MaskFilter.blur(BlurStyle.solid, 3.0); 
      }
      double radius = p.isNeutralized ? 2.5 : 3.5 + (env.fibrosisRiskIndex * 0.05);
      canvas.drawCircle(Offset(p.x, p.y), radius, particlePaint);
    }
  }

五、 结尾:从代码架构审视生命哲学的必然

这套由 main.dart 单文件承载的宏大代谢演算仪,向我们直观而冷酷地揭露了一个事实:

在代码的世界里,只要做好弹性布局(Expanded),内存就不再轻易越界;而在生命系统的架构中,一旦对生物钟(Circadian Rhythm)的约束失去敬畏,毒素必将淤积成无可挽回的纤维化灾变。

当您在系统右侧滑动干预条,将虚拟生命的睡眠剥离殆尽时,满屏凄厉的荧光绿粒子淤积与紫红色警告光晕,其实也是生命对碳基体躯发出的最沉痛控诉。我们所设计的每一个 clamp(0.0, 1.0) 与边界检测判断,也是在祈愿每一位开发者在浩瀚的项目周期中,依然能找到属于自己生命的平衡原点。


源码

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

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

class HepaticDetoxSimulatorApp extends StatelessWidget {
  const HepaticDetoxSimulatorApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '肝脏代谢演算仪',
      theme: ThemeData(
        brightness: Brightness.dark,
        scaffoldBackgroundColor: const Color(0xFF070B14), // 极深暗黑
        fontFamily: 'Courier',
        sliderTheme: SliderThemeData(
          activeTrackColor: const Color(0xFF00FFCC),
          inactiveTrackColor: Colors.white24,
          thumbColor: const Color(0xFF00FFCC),
          overlayColor: const Color(0xFF00FFCC).withOpacity(0.2),
        ),
      ),
      home: const HepaticHomeScreen(),
    );
  }
}

// ==========================================
// 领域模型:肝小叶微循环与毒素渗透流场
// ==========================================

class ToxinParticle {
  double x;
  double y;
  double angle;     // 朝向中心的角度
  double speed;     // 径向向心流速
  bool isNeutralized; // 是否已被酶解
  double lifetime;    // 存在时间,用于淤积变色判定

  ToxinParticle({
    required this.x,
    required this.y,
    required this.angle,
    required this.speed,
    this.isNeutralized = false,
  }) : lifetime = 0;
}

class LiverEnvironment {
  final bool isControlGroup;
  double targetSleepDuration; // 用户给定的睡眠时长 (Control 组固定为 8)
  
  // 核心演算指标
  double cyp450EnzymeLevel = 100.0; // 细胞色素 P450 活性基线 (0-100)
  double toxinLoadPercentage = 0.0; // 毒素淤积率 (0-100%)
  double fibrosisRiskIndex = 0.0;   // 纤维化/脂质过氧化风险指数
  
  List<ToxinParticle> particles = [];
  final Random _rnd = Random();

  LiverEnvironment({this.isControlGroup = false, this.targetSleepDuration = 8.0});

  // 更新肝脏生化流场方程
  void _updateBiochemicalField() {
    if (isControlGroup) {
      targetSleepDuration = 8.0; 
    }

    // 数学拟合:睡眠不足导致酶合成显著受阻
    // 采用 S 型曲线 (Sigmoid-like) 或指数衰减拟合
    // S=8 时酶活性最高(100), S=4 时大约剩余(30)
    cyp450EnzymeLevel = 100.0 * (1.0 / (1.0 + exp(-1.2 * (targetSleepDuration - 4.5))));

    // 毒素淤积计算:未被中和的粒子占比
    if (particles.isEmpty) {
      toxinLoadPercentage = 0;
    } else {
      int toxicCount = particles.where((p) => !p.isNeutralized).length;
      toxinLoadPercentage = (toxicCount / particles.length) * 100.0;
    }

    // 纤维化风险:淤积率持续居高引发
    fibrosisRiskIndex = max(0.0, toxinLoadPercentage - 20.0) * 1.5;
  }

  // 向心流体物理积分与酶解碰撞检测
  void tickUpdate(double dt, double width, double height) {
    if (width <= 0 || height <= 0) return;
    _updateBiochemicalField();

    double centerX = width / 2;
    double centerY = height / 2;
    double maxRadius = sqrt(width*width + height*height) / 2;

    // 1. 生成外源性代谢废料 (从血管汇管区向中心肝静脉流动)
    // 高应激(睡眠少)或者正常态都会产生代谢物,但基数是一样的
    double spawnRate = 2.0; 
    if (_rnd.nextDouble() < spawnRate * dt * 60) {
      // 沿圆周随机位置生成
      double spawnAngle = _rnd.nextDouble() * pi * 2;
      particles.add(ToxinParticle(
        x: centerX + cos(spawnAngle) * (maxRadius + 20),
        y: centerY + sin(spawnAngle) * (maxRadius + 20),
        angle: spawnAngle + pi, // 指向中心
        speed: 15.0 + _rnd.nextDouble() * 10.0, // 缓慢向心渗透
      ));
    }

    // 2. 积分演算粒子位移与酶促反应
    for (int i = particles.length - 1; i >= 0; i--) {
      var p = particles[i];
      p.lifetime += dt;

      // 如果未被中和,基于 CYP450 浓度进行概率性解毒
      // 酶活性越高,越容易在半途中和
      if (!p.isNeutralized) {
        double detoxProbability = (cyp450EnzymeLevel / 100.0) * 0.02; // 每帧的解毒命中率
        if (_rnd.nextDouble() < detoxProbability) {
          p.isNeutralized = true;
          p.speed *= 2.5; // 被解毒变为水溶性后,流出速度加快
        }
      }

      // 纤维化阻力模型:如果纤维化高,中心区域流速变慢(淤滞)
      double resistance = p.isNeutralized ? 1.0 : max(0.2, 1.0 - (fibrosisRiskIndex * 0.005));
      
      // 更新位移 (加入微小的布朗运动扰动)
      p.x += cos(p.angle) * p.speed * dt * resistance + (_rnd.nextDouble() - 0.5) * 2.0;
      p.y += sin(p.angle) * p.speed * dt * resistance + (_rnd.nextDouble() - 0.5) * 2.0;

      // 3. 淘汰判定:到达中央静脉(中心点极小范围内)则排入大循环并消失
      double distToCenter = sqrt(pow(p.x - centerX, 2) + pow(p.y - centerY, 2));
      if (distToCenter < 15.0) {
        particles.removeAt(i);
      }
    }

    // 粒子上限熔断,防止极端情况卡死
    if (particles.length > 500) {
      particles.removeRange(0, particles.length - 500);
    }
  }
}

// ==========================================
// 主视图控制器
// ==========================================

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

  @override
  State<HepaticHomeScreen> createState() => _HepaticHomeScreenState();
}

class _HepaticHomeScreenState extends State<HepaticHomeScreen> with SingleTickerProviderStateMixin {
  late Ticker _ticker;
  Duration _lastElapsed = Duration.zero;

  // 实例化双引擎隔离架构
  final LiverEnvironment _controlEnv = LiverEnvironment(isControlGroup: true);
  final LiverEnvironment _experimentEnv = LiverEnvironment(isControlGroup: false);

  @override
  void initState() {
    super.initState();
    _ticker = createTicker((elapsed) {
      double dt = (elapsed.inMilliseconds - _lastElapsed.inMilliseconds) / 1000.0;
      if (dt > 0.1) dt = 0.016; 
      _lastElapsed = elapsed;

      if (!mounted) return;
      setState(() {
        // 全局驱动画布高频重绘,但不重建深层 Widget 树
      });
    });
    _ticker.start();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: const BoxDecoration(
          image: DecorationImage(
            image: AssetImage('assets/images/explore_ohos.png'),
            fit: BoxFit.cover,
            opacity: 0.05,
          ),
        ),
        child: SafeArea(
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                _buildHeader(),
                const SizedBox(height: 12),
                
                // 核心防溢出区域:Expanded 吸收纵向弹性空间,LayoutBuilder 吸纳横向
                Expanded(
                  child: LayoutBuilder(
                    builder: (context, constraints) {
                      // 响应式截断降维:当宽度小于 750 时改为上下叠放,彻底杜绝 Right Overflow
                      if (constraints.maxWidth > 750) {
                        return Row(
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: [
                            Expanded(child: _buildHepaticViewport('标准对照组 (稳态)', _controlEnv)),
                            const SizedBox(width: 16),
                            Expanded(child: _buildHepaticViewport('干预实验组 (剥夺)', _experimentEnv)),
                          ],
                        );
                      } else {
                        return Column(
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: [
                            Expanded(child: _buildHepaticViewport('标准对照组 (稳态)', _controlEnv)),
                            const SizedBox(height: 16),
                            Expanded(child: _buildHepaticViewport('干预实验组 (剥夺)', _experimentEnv)),
                          ],
                        );
                      }
                    },
                  ),
                ),
                
                const SizedBox(height: 16),
                _buildControlPanel(),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildHeader() {
    return Row(
      children: [
        const Icon(Icons.hub, color: Color(0xFF00FFCC), size: 30),
        const SizedBox(width: 12),
        // 对长标题进行横向溢出防御
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: const [
              Text(
                'HEPATIC CLEARANCE ENGINE // 肝脏代谢清除率演算仪',
                style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white, letterSpacing: 1.1),
                softWrap: true,
              ),
              Text(
                'Circadian Rhythm Disruption vs CYP450 Enzymatic Detoxification',
                style: TextStyle(fontSize: 11, color: Colors.white54),
                softWrap: true,
              ),
            ],
          ),
        ),
      ],
    );
  }

  // 肝小叶向心流场观测视窗
  Widget _buildHepaticViewport(String title, LiverEnvironment env) {
    return Container(
      decoration: BoxDecoration(
        color: const Color(0xFF161B22).withOpacity(0.8),
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: env.isControlGroup ? const Color(0xFF00FFCC).withOpacity(0.4) : const Color(0xFFE2B93B).withOpacity(0.4)),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          // 面板数据输出区:强烈依赖 Wrap 防治内部文本撑爆宽度
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
            decoration: const BoxDecoration(
              color: Colors.black45,
              borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)),
            ),
            child: Wrap(
              spacing: 12,
              runSpacing: 8,
              children: [
                Text(
                  title, 
                  style: TextStyle(color: env.isControlGroup ? const Color(0xFF00FFCC) : const Color(0xFFE2B93B), fontWeight: FontWeight.bold, fontSize: 13)
                ),
                Text('睡眠: ${env.targetSleepDuration.toStringAsFixed(1)} h', style: const TextStyle(color: Colors.white70, fontSize: 12)),
                Text('CYP450: ${env.cyp450EnzymeLevel.toStringAsFixed(1)}%', style: TextStyle(color: env.cyp450EnzymeLevel < 50 ? Colors.redAccent : Colors.white70, fontSize: 12)),
                Text('淤积率: ${env.toxinLoadPercentage.toStringAsFixed(1)}%', style: TextStyle(color: env.toxinLoadPercentage > 40 ? Colors.redAccent : Colors.white70, fontSize: 12)),
                Text('脂化/纤维化: ${env.fibrosisRiskIndex.toStringAsFixed(1)}', style: TextStyle(color: env.fibrosisRiskIndex > 20 ? Colors.deepPurpleAccent : Colors.white70, fontSize: 12)),
              ],
            ),
          ),
          
          // 原生 Canvas 渲染区,彻底吸收所有高度,无 Widget 树膨胀
          Expanded(
            child: LayoutBuilder(
              builder: (context, constraints) {
                // 每帧都在此触发积分推演
                env.tickUpdate(0.016, constraints.maxWidth, constraints.maxHeight);
                return ClipRect( // 防治粒子越界绘制
                  child: CustomPaint(
                    painter: HepaticLobulePainter(env),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }

  // 底部睡眠干预操作台
  Widget _buildControlPanel() {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
      decoration: BoxDecoration(
        color: Colors.black54,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: Colors.white12),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text('CIRCADIAN RHYTHM OVERRIDE // 昼夜节律干预: 强制缩短宿主睡眠周期 (0-12 Hrs)', 
            style: TextStyle(color: Color(0xFFE2B93B), fontWeight: FontWeight.bold, fontSize: 13)),
          Row(
            children: [
              const Icon(Icons.nights_stay, color: Colors.indigoAccent),
              // 滑动条外裹 Expanded,自适应填充
              Expanded(
                child: Slider(
                  value: _experimentEnv.targetSleepDuration,
                  min: 0.0,
                  max: 12.0,
                  divisions: 24,
                  label: '${_experimentEnv.targetSleepDuration.toStringAsFixed(1)} H',
                  onChanged: (val) {
                    setState(() {
                      _experimentEnv.targetSleepDuration = val;
                    });
                  },
                ),
              ),
              const Icon(Icons.wb_sunny, color: Colors.orangeAccent),
            ],
          ),
        ],
      ),
    );
  }
}

// ==========================================
// 肝小叶生化流场高性能渲染器
// ==========================================

class HepaticLobulePainter extends CustomPainter {
  final LiverEnvironment env;

  HepaticLobulePainter(this.env);

  @override
  void paint(Canvas canvas, Size size) {
    double centerX = size.width / 2;
    double centerY = size.height / 2;

    // 1. 绘制肝小叶背景与六边形边界骨架抽象
    final Paint bgPaint = Paint()..color = const Color(0xFF1E1116).withOpacity(0.4);
    canvas.drawRect(Offset.zero & size, bgPaint);

    final Paint veinPaint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.0
      ..color = Colors.white10;

    // 绘制肝索发散状抽象虚线
    for (int i = 0; i < 12; i++) {
      double angle = (i * pi) / 6;
      canvas.drawLine(
        Offset(centerX, centerY),
        Offset(centerX + cos(angle) * size.width, centerY + sin(angle) * size.width),
        veinPaint
      );
    }

    // 2. 绘制微粒流场
    final Paint particlePaint = Paint();
    
    for (var p in env.particles) {
      // 未被中和的毒素呈现荧光黄绿,已被中和的水溶代谢物呈现暗蓝色
      if (p.isNeutralized) {
        particlePaint.color = const Color(0xFF42A5F5).withOpacity(0.6);
        particlePaint.maskFilter = null; // 干净的水分子
      } else {
        // 毒素滞留越久(lifetime长),荧光越亮且趋向于有害的亮黄/橙色
        double toxicIntensity = (p.lifetime / 10.0).clamp(0.0, 1.0);
        int r = (100 + 155 * toxicIntensity).toInt();
        int g = (255 - 100 * toxicIntensity).toInt();
        particlePaint.color = Color.fromARGB(220, r, g, 50);
        particlePaint.maskFilter = const MaskFilter.blur(BlurStyle.solid, 3.0); // 散发毒素光晕
      }

      // 纤维化阻力导致的大毒素结节:若纤维化高且未解毒,粒子表现为肿大
      double radius = p.isNeutralized ? 2.5 : 3.5 + (env.fibrosisRiskIndex * 0.05);
      canvas.drawCircle(Offset(p.x, p.y), radius, particlePaint);
    }

    // 3. 绘制中央静脉 (Central Vein)
    final Paint centerPaint = Paint()..color = const Color(0xFF6B1D25).withOpacity(0.8);
    canvas.drawCircle(Offset(centerX, centerY), 12.0, centerPaint);
    
    // 如果酶浓度高,中央静脉附近散发健康的生命光晕
    if (env.cyp450EnzymeLevel > 80) {
      final Paint glowPaint = Paint()
        ..color = const Color(0xFF00FFCC).withOpacity(0.15)
        ..maskFilter = const MaskFilter.blur(BlurStyle.normal, 10.0);
      canvas.drawCircle(Offset(centerX, centerY), 20.0 + sin(DateTime.now().millisecondsSinceEpoch/200)*2, glowPaint);
    } else if (env.fibrosisRiskIndex > 30) {
      // 纤维化危机光晕:深红/紫色报警
      final Paint dangerPaint = Paint()
        ..color = Colors.deepPurpleAccent.withOpacity(0.3)
        ..maskFilter = const MaskFilter.blur(BlurStyle.normal, 15.0);
      canvas.drawCircle(Offset(centerX, centerY), 30.0, dangerPaint);
    }
  }

  // 全时重绘
  @override
  bool shouldRepaint(covariant HepaticLobulePainter oldDelegate) => true;
}

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐