Друкарня від WE.UA

Створення логотипа Perplexity з матового скла у Jetpack Compose

У цьому туторіалі ми створимо анімований логотип Perplexity, що має ефект матового скла. Ми використаємо бібліотеку haze від Chris Banes для імітації скла та graphicsLayer для 3D-анімації

Налаштування проєкту

Спочатку необхідно додати залежність для haze у build.gradle:

repositories {
    mavenCentral()
}

dependencies {
    implementation("dev.chrisbanes.haze:haze:<version>")
}

Основний компонент

PerplexityLogo містить два блоки (RoundedBoxLeft і RoundedBoxRight), які створюють ефект матового скла.

💡 Таке рішення було зроблено через те, що після обертання елемента на 180° зображення відзеркалювалося і не давало такий ефект, як я хотів. На зображенні знизу видно, що жовтий є як зліва, так і зправа
Зображення відзеркалювалося після 180°
@Composable
fun PerplexityLogo(
    hazeStateLeft: HazeState,
    hazeStateRight: HazeState,
    modifier: Modifier
) {
    val containerColor = MaterialTheme.colorScheme.surface
    val hazeStyle = HazeStyle(
        backgroundColor = containerColor,
        tints = listOf(
            HazeTint(containerColor.copy(alpha = if (containerColor.luminance() >= 0.5) 0.3f else 0.1f))
        ),
        blurRadius = 10.dp,
        noiseFactor = 0.3f
    )

    val infiniteTransition = rememberInfiniteTransition()
    val animationProgress by infiniteTransition.animateFloat(
        initialValue = 1f,
        targetValue = 0f,
        animationSpec = infiniteRepeatable(
            animation = tween(5_000),
            repeatMode = RepeatMode.Restart
        )
    )

    Box(modifier = modifier) {
        val pages = 8
        MutableList(pages) { index ->
            val rotationAngle = (animationProgress * 360 + (index * 360 / pages)) % 360
            if (rotationAngle in 0f..180f) {
                RoundedBoxLeft(rotationAngle - 90f, hazeStateLeft, hazeStyle, Modifier)
            } else {
                RoundedBoxRight(rotationAngle + 90f, hazeStateRight, hazeStyle, Modifier)
            }
        }
    }
}


1/ Я створив свій HazeStyle, бо стандартні не дуже підходили, тай хотілося погратися з різним blurRadius та noiseFactor

  val hazeStyle = HazeStyle(
        backgroundColor = containerColor,
        tints = listOf(
            HazeTint(containerColor.copy(alpha = if (containerColor.luminance() >= 0.5) 0.3f else 0.1f))
        ),
        blurRadius = 10.dp,
        noiseFactor = 0.3f
    )

2/ Створюємо 8 сторінок та вираховуємо для кожної з них кут. Залежно від кута вони будуть або злівої чи правої сторони. Ми віднімаємо 90 чи додаємо 90 градусів, щоб у нас сторінки малювалися з однієї точки, залежно від того, звідки ми починаємо малювати

RoundedBox

@Composable
fun RoundedBoxLeft(rotationAngle: Float, hazeState: HazeState, hazeStyle: HazeStyle, modifier: Modifier) {
    Page(
        hazeState = hazeState,
        hazeStyle = hazeStyle,
        borderColor = Color(0xFF24F4FE),
        modifier = modifier.graphicsLayer {
            rotationY = rotationAngle
            rotationX = -45f
            cameraDistance = 100f
            transformOrigin = TransformOrigin(1f, 0f)
        }
    )
}

Основною різницею між лівою та правою частиною є transformOrigin = TransformOrigin(1f, 0f) та TransformOrigin(1f, 0f)

Ці блоки використовують graphicsLayer для створення ефекту перспективи

Page

@Composable
fun Page(
    hazeState: HazeState,
    hazeStyle: HazeStyle,
    borderColor: Color,
    modifier: Modifier
) {
    Box(
        modifier = modifier
            .hazeEffect(hazeState, style = hazeStyle)
            .border(8.dp, borderColor)
    )
}

Тут все просто. Box з обводкою та нашим ефектом скла. При необхідності можна задати заливки чи паралакс ефект

zIndex

У нашому прикладі є дуже важливим zIndex. Для лівої сторони ми його визначаємо як zIndex(rotationAngle) для правої zIndex(360 - rotationAngle)

Якщо не задати zIndex

hazeSource

Для отримання ефекту розмиття спочатку потрібно отримати інформацію з картинки позаду. Тому ми hazeState витягнули з PerplexityLogo ззовні, де є наш бекграунд і за допомогою hazeSource отримуємо його. Обов’язково потрібно вказати zIndex = 0f.

Box(
                contentAlignment = Alignment.Center
            ) {
                val hazeStateLeft = remember { HazeState() }
                val hazeStateRight = remember { HazeState() }
                Box(
                    modifier = Modifier
                        .offset(y = (-30).dp)
                        .size(300.dp)
                        .hazeSource(hazeStateRight, zIndex = 0f)
                        .hazeSource(hazeStateLeft, zIndex = 0f)
                        .graphicsLayer {
                            rotationZ = animationProgress * 1080
                        }
                        .clip(CircleShape)
                        .paint(
                            painter = painterResource(id = R.drawable.orb_bg),
                            contentScale = ContentScale.Crop
                        )

                )
                PerplexityLogo(
                    hazeStateLeft,
                    hazeStateRight,
                    modifier = Modifier.size(200.dp)
                )
            }

А в PerplexityLogo ми вже вказуємо zIndex залежно від оберту: .hazeSource(hazeStateLeft, rotationAngle + 1f) — за тим самим принципом, що й zIndex, але з +1 (оскільки попередній шар був 0).

Результат

Цей код створює анімований логотип Perplexity з ефектом матового скла. Використовуючи HazeEffect та graphicsLayer, ми досягаємо красивого візуального ефекту з плавною анімацією.

Результат


🔗 Посилання на репозиторій з кодом: https://github.com/rmnkhr/perplexity_ui_experiment


🔗 Посилання на канал по Android в тг
https://t.me/android_fragment

Статті про вітчизняний бізнес та цікавих людей:

  • Як побудована програма Meest China Academy

    Курс про товарний бізнес охоплює різні етапи роботи: від пошуку ідеї до перевірки товару, логістики та масштабування. Програма Meest China Academy містить 17 модулів, які послідовно розкривають ці теми без зведення всього навчання до однієї універсальної поради.

    Теми цього довгочиту:

    Meest
  • Які технології використані в Айфон 17

    Айфон 17 поєднує OLED-дисплей із частотою до 120 Гц, чип A19, дві камери Fusion 48 Мп і швидке заряджання через USB-C. У COMFY можна купити Айфон 17 з накопичувачем на 256 або 512 ГБ, вибравши конфігурацію відповідно до обсягу фото, відео та застосунків

    Теми цього довгочиту:

    Iphone 17
  • Як вибрати вживаний iPhone: коротке керівництво для розумної покупки

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

    Теми цього довгочиту:

    Iphone
  • Як подолати жіночу безплідність за допомогою донорських яйцеклітин

    Діагноз "безпліддя" рідко звучить як вирок одразу. Для багатьох жінок саме в цей момент вперше звучить словосполучення "донорські яйцеклітини" — і це часто не кінець шляху до материнства, а якраз новий, реальний шанс.

    Теми цього довгочиту:

    Донорство
  • Як заспокоїти зубний біль і чому самолікування може призвести до операції?

    Раптовий біль у зубі може призвести до порушення сну та ускладненого вживання їжі. Люди часто приймають таблетки, роблять полоскання або лікуються народними засобами. В таких випадках не варто відкладати візит до стоматолога, адже можуть з’явитись ускладнення.

    Теми цього довгочиту:

    Стоматологія
Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Roman K
Roman K@rmnkhr

4Довгочити
847Перегляди
13Підписники
На Друкарні з 15 квітня 2023

Більше від автора

  • Шпаргалка по Kotlin ч. 1 Колекції

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

    Теми цього довгочиту:

    Kotlin
  • Як перемагати на хакатонах

    Розкажу про хакатони, у яких я брав участь з 2015 року. Ідеї, презентації, перемоги, висновки, смішні ситуації та меми

    Теми цього довгочиту:

    Hackathon
  • Як працює ChatGPT простими словами

    Спробуємо розібратися як працють нейронки та в чому унікальність ChatGPT

    Теми цього довгочиту:

    Chat Gpt

Це також може зацікавити:

Коментарі (0)

Підтримайте автора першим.
Напишіть коментар!

Це також може зацікавити: