Реализация анимации 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 — main 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 частиц/с суммарно. На 4 секунды lifetime — до 480 частиц одновременно на экране. На iPhone 12+ — комфортно. На iPhone SE 2nd gen — начинает греться. Снижаем birthRate до 4–5 для mid-range устройств.

Для кастомных форм 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 дня. Стоимость рассчитывается индивидуально.