createParticles static method

List<Particle> createParticles(
  1. ConfettiShowcase showcase,
  2. Size size, {
  3. List<String>? emojiPool,
  4. ConfettiCustomization? customization,
  5. Random? random,
})

Default unicode pool when emojiPool is null (see kDefaultCelebrationEmojis).

Implementation

static List<Particle> createParticles(
  ConfettiShowcase showcase,
  Size size, {
  List<String>? emojiPool,
  ConfettiCustomization? customization,
  Random? random,
}) {
  final rng = random ?? Random();
  final safe = _safeSize(size);
  final emojis = _emojiPool(emojiPool);

  switch (showcase) {
    case ConfettiShowcase.centerPop:
    case ConfettiShowcase.controlledBurst:
      return _burst(
        safe,
        rng,
        customization,
        count: ConfettiCustomization.effectiveCount(100, customization),
        opts: const TickConfettiSpawnOptions(
          angle: 90,
          spread: 70,
          decay: 0.9,
          gravity: 1,
          scalar: 1,
          ticks: 220,
        ),
        emitter: (s) => Offset(s.width / 2, s.height * 0.6),
        shapes: const [
          ParticleShape.circle,
          ParticleShape.square,
        ],
        colors: _palette(customization),
      );
    case ConfettiShowcase.randomAngle:
      final angle = _randomRange(rng, 55, 125);
      final spread = _randomRange(rng, 50, 70);
      final n = ConfettiCustomization.effectiveCount(
        rng.nextInt(51) + 50,
        customization,
      );
      return _burst(
        safe,
        rng,
        customization,
        count: n,
        opts: TickConfettiSpawnOptions(
          angle: angle,
          spread: spread,
          decay: 0.9,
          gravity: 1,
          scalar: 1,
          ticks: 220,
        ),
        emitter: (s) => Offset(s.width / 2, s.height * 0.6),
        shapes: const [
          ParticleShape.circle,
          ParticleShape.square,
          ParticleShape.triangle,
        ],
        colors: _palette(customization),
      );
    case ConfettiShowcase.dualLaunch:
      final countEach = max(
        8,
        (ConfettiCustomization.effectiveCount(25, customization) / 2).round(),
      );
      const baseOpts = TickConfettiSpawnOptions(
        spread: 360,
        startVelocity: 30,
        ticks: 60,
        decay: 0.92,
        gravity: 0.85,
        scalar: 1,
        angle: 90,
      );
      final left = _burst(
        safe,
        rng,
        customization,
        count: countEach,
        opts: baseOpts,
        emitter: (s) => Offset(
          s.width * rng.nextDouble().clamp(0.1, 0.3),
          s.height * (rng.nextDouble() - 0.2).clamp(0.15, 0.85),
        ),
        shapes: const [ParticleShape.circle, ParticleShape.star],
        colors: _palette(customization),
      );
      final right = _burst(
        safe,
        rng,
        customization,
        count: countEach,
        opts: baseOpts,
        emitter: (s) => Offset(
          s.width * rng.nextDouble().clamp(0.7, 0.9),
          s.height * (rng.nextDouble() - 0.2).clamp(0.15, 0.85),
        ),
        shapes: const [ParticleShape.circle, ParticleShape.star],
        colors: _palette(customization),
      );
      return [...left, ...right];
    case ConfettiShowcase.starField:
      final n = ConfettiCustomization.effectiveCount(50, customization);
      const warm = [
        Color(0xffFFE400),
        Color(0xffFFBD00),
        Color(0xffE89400),
        Color(0xffFFCA6C),
        Color(0xffFDFFB8),
      ];
      final colors = _palette(customization, fallback: warm);
      return _burst(
        safe,
        rng,
        customization,
        count: n,
        opts: const TickConfettiSpawnOptions(
          spread: 360,
          ticks: 50,
          gravity: 0,
          decay: 0.94,
          startVelocity: 30,
          angle: 90,
          scalar: 1,
        ),
        emitter: (s) => Offset(s.width / 2, s.height * 0.55),
        shapes: const [ParticleShape.star],
        colors: colors,
        scalarJitter: true,
      );
    case ConfettiShowcase.emojiPop:
      final n = ConfettiCustomization.effectiveCount(50, customization);
      return _burst(
        safe,
        rng,
        customization,
        count: n,
        opts: const TickConfettiSpawnOptions(
          spread: 360,
          ticks: 50,
          gravity: 0,
          decay: 0.94,
          startVelocity: 30,
          angle: 90,
          scalar: 1,
        ),
        emitter: (s) => Offset(s.width / 2, s.height * 0.55),
        shapes: const [ParticleShape.emoji],
        colors: _palette(customization),
        emojiPool: emojis,
      );
    case ConfettiShowcase.dualStream:
      const prideColors = [
        Color(0xffbb0000),
        Color(0xffffffff),
      ];
      final custom = customization?.colors;
      final colors = custom != null && custom.isNotEmpty
          ? List<Color>.from(custom)
          : prideColors;
      final half = max(
        4,
        ConfettiCustomization.effectiveCount(50, customization) ~/ 2,
      );
      final left = _burst(
        safe,
        rng,
        customization,
        count: half,
        opts: const TickConfettiSpawnOptions(
          angle: 60,
          spread: 55,
          decay: 0.9,
          gravity: 1,
          ticks: 240,
          scalar: 1,
        ),
        emitter: (s) => Offset(12, s.height * 0.45),
        shapes: const [ParticleShape.circle, ParticleShape.square],
        colors: colors,
      );
      final right = _burst(
        safe,
        rng,
        customization,
        count: half,
        opts: const TickConfettiSpawnOptions(
          angle: 120,
          spread: 55,
          decay: 0.9,
          gravity: 1,
          ticks: 240,
          scalar: 1,
        ),
        emitter: (s) => Offset(s.width - 12, s.height * 0.45),
        shapes: const [ParticleShape.circle, ParticleShape.square],
        colors: colors,
      );
      return [...left, ...right];
    case ConfettiShowcase.inlineEmitter:
      return _burst(
        safe,
        rng,
        customization,
        count: ConfettiCustomization.effectiveCount(100, customization),
        opts: const TickConfettiSpawnOptions(
          angle: 90,
          spread: 70,
          decay: 0.9,
          gravity: 1,
          ticks: 200,
          scalar: 1,
        ),
        emitter: (s) => Offset(s.width / 2, s.height - 2),
        shapes: const [
          ParticleShape.circle,
          ParticleShape.square,
        ],
        colors: _palette(customization),
      );
  }
}