buildParticleVisual method

  1. @protected
ParticleVisual? buildParticleVisual(
  1. Particle particle,
  2. SpoilerContext context, {
  3. required double baseRadius,
})

Implementation

@protected
ParticleVisual? buildParticleVisual(
  Particle particle,
  SpoilerContext context, {
  required double baseRadius,
}) {
  final fadeEdgeThickness = context.config.fadeConfig?.edgeThickness ?? 1.0;
  final bounds = context.spoilerBounds;
  final boundaryFadePx = max(baseRadius * 3.0, 6.0);

  double smoothstep(double edge0, double edge1, double x) {
    final t = ((x - edge0) / (edge1 - edge0)).clamp(0.0, 1.0);
    return t * t * (3.0 - 2.0 * t);
  }

  final lifeScale = lifeSizeMin + (1.0 - lifeSizeMin) * particle.life;
  final edgeDist = min(
    min(particle.dx - bounds.left, bounds.right - particle.dx),
    min(particle.dy - bounds.top, bounds.bottom - particle.dy),
  );
  final edgeFade =
      edgeDist <= 0.0 ? 0.0 : smoothstep(0.0, boundaryFadePx, edgeDist);
  final particleRadius = max(baseRadius * lifeScale, 0.0001);
  final edgeClamp = (edgeDist / particleRadius).clamp(0.0, 1.0);
  final edgeScale = edgeFade * edgeClamp;

  if (edgeScale <= 0.0) {
    return null;
  }

  if (context.isFading) {
    final distSq = (context.fadeCenter - particle).distanceSquared;
    final radiusSq = context.fadeRadius * context.fadeRadius;
    if (distSq >= radiusSq) {
      return null;
    }

    final dist = sqrt(distSq);
    final highlight = dist > context.fadeRadius - fadeEdgeThickness;
    final tint = highlight ? Colors.white : particle.color;
    final scaled = (highlight ? 1.5 : 1.0) * lifeScale * edgeScale;
    if (scaled <= 0.0) {
      return null;
    }

    return ParticleVisual(
      scale: scaled,
      color: tint.withValues(alpha: tint.a * edgeScale),
    );
  }

  final scaled = lifeScale * edgeScale;
  if (scaled <= 0.0) {
    return null;
  }

  return ParticleVisual(
    scale: scaled,
    color: particle.color.withValues(alpha: particle.color.a * edgeScale),
  );
}