Реалізація анімації Confetti/Celebration у мобільному додатку

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Реалізація анімації Confetti/Celebration у мобільному додатку
Середній
від 4 годин до 2 днів
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Реалізація анімації Confetti/Celebration у мобільних додатках

Confetti-анімація потрібна там, де додаток повинен емоційно відреагувати на досягнення: перша покупка, виконана мета, завершений урок. Користувачі бачать, як частинки розлітаються — це активує психологію винагороди. Технічно, «багато рухомих об'єктів» становить потенційне навантаження на рендеринг.

iOS: CAEmitterLayer

CAEmitterLayer — правильний інструмент для particle effects на iOS. Рендеринг через Metal, анімація на render thread — головний потік не бере участі.

func startConfetti(in view: UIView) {
    let emitter = CAEmitterLayer()
    emitter.emitterPosition = CGPoint(x: view.bounds.midX, y: -10)
    emitter.emitterShape = .line
    emitter.emitterSize = CGSize(width: view.bounds.width, height: 0)

    let colors: [UIColor] = [.systemRed, .systemBlue, .systemYellow, .systemGreen, .systemPurple]
    let shapes = ["square", "circle", "triangle"]  // або UIImage для кастомних форм

    emitter.emitterCells = colors.flatMap { color in
        shapes.map { _ in
            let cell = CAEmitterCell()
            cell.contents = UIImage(systemName: "circle.fill")?.withTintColor(color).cgImage
            cell.birthRate = 8
            cell.lifetime = 4.0
            cell.velocity = 200
            cell.velocityRange = 100
            cell.emissionLongitude = .pi  // вниз
            cell.emissionRange = .pi / 4
            cell.spin = 3.5
            cell.spinRange = 1.0
            cell.scaleRange = 0.5
            cell.scale = 0.4
            cell.color = color.cgColor
            cell.alphaSpeed = -0.15  // fade out в кінці
            return cell
        }
    }

    view.layer.addSublayer(emitter)

    // Зупиняємо spawning через 2 секунди, частинки рухаються самі
    DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
        emitter.birthRate = 0
    }
    DispatchQueue.main.asyncAfter(deadline: .now() + 6.0) {
        emitter.removeFromSuperlayer()
    }
}

CAEmitterCell.birthRate — частиц на секунду на ячейку. При 5 кольорах × 3 формах × 8 частиц/с = 120 частиц/с всього. При lifetime 4 секунди — до 480 частиц одночасно на екрані. На iPhone 12+ це комфортно. На iPhone SE 2nd gen починає гріватися. Зменшуємо birthRate до 4–5 для середньорівневих пристроїв.

Для кастомних форм confetti (прямокутники, зірки): створюємо через UIGraphicsImageRenderer, малюємо форму, конвертуємо в CGImage для cell.contents.

Android: Canvas-based або бібліотека

Кастомний ConfettiView через Canvas:

class ConfettiView(context: Context) : View(context) {
    private val particles = mutableListOf<ConfettiParticle>()
    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private var animator: ValueAnimator? = null

    data class ConfettiParticle(
        var x: Float, var y: Float,
        var vx: Float, var vy: Float,
        val color: Int,
        val size: Float,
        var rotation: Float,
        val rotationSpeed: Float,
        var alpha: Float = 1f
    )

    fun start() {
        repeat(80) {
            particles.add(ConfettiParticle(
                x = Random.nextFloat() * width,
                y = -Random.nextFloat() * 100,
                vx = Random.nextFloat() * 6 - 3,
                vy = Random.nextFloat() * 4 + 3,
                color = listOf(Color.RED, Color.BLUE, Color.YELLOW, Color.GREEN).random(),
                size = Random.nextFloat() * 12 + 6,
                rotation = Random.nextFloat() * 360,
                rotationSpeed = Random.nextFloat() * 6 - 3
            ))
        }

        animator = ValueAnimator.ofFloat(0f, 1f).apply {
            duration = 5000
            addUpdateListener {
                updateParticles()
                invalidate()
            }
            start()
        }
    }

    private fun updateParticles() {
        particles.forEach { p ->
            p.x += p.vx
            p.vy += 0.1f  // гравітація
            p.y += p.vy
            p.rotation += p.rotationSpeed
            if (p.y > height * 0.7f) p.alpha -= 0.02f
        }
        particles.removeAll { it.alpha <= 0 || it.y > height + 50 }
    }

    override fun onDraw(canvas: Canvas) {
        particles.forEach { p ->
            paint.color = p.color
            paint.alpha = (p.alpha * 255).toInt()
            canvas.save()
            canvas.translate(p.x, p.y)
            canvas.rotate(p.rotation)
            canvas.drawRect(-p.size/2, -p.size/2, p.size/2, p.size/2, paint)
            canvas.restore()
        }
    }
}

ValueAnimator + invalidate() — це перерисовка Canvas на кожному кадрі. При 80 частицах та кастомному onDraw — прийнятно. При 200+ частицах зі складними формами — переходимо на SurfaceView з окремим render thread.

Готова бібліотека: nl.dionsegijn:konfetti:2.0.4 — непоганий варіант, підтримує кастомні форми та KonfettiView.

Flutter

// Через CustomPainter
class ConfettiPainter extends CustomPainter {
  final List<ConfettiParticle> particles;
  ConfettiPainter(this.particles);

  @override
  void paint(Canvas canvas, Size size) {
    for (final p in particles) {
      final paint = Paint()..color = p.color.withOpacity(p.alpha);
      canvas.save();
      canvas.translate(p.x, p.y);
      canvas.rotate(p.rotation);
      canvas.drawRect(Rect.fromCenter(center: Offset.zero, width: p.size, height: p.size * 0.5), paint);
      canvas.restore();
    }
  }

  @override
  bool shouldRepaint(ConfettiPainter old) => true;
}

У Flutter простіше використовувати готовий пакет confetti: ^0.7.0 — там ConfettiController з play(), stop() та параметрами для напрямку, кольорів, форм.

Терміни

Confetti через CAEmitterLayer або готову бібліотеку з базовими параметрами: 4–8 годин. Кастомна реалізація з унікальними формами, фізикою (вітер, гравітація) та оптимізацією під різні пристрої: 1–2 дні. Вартість розраховується індивідуально.