تا حالا براتون سوال شده چجوری میشه توی اپلیکیشنتون انیمیشن هایی مثل انیمیشنی که توی اپ Wordle هست پیاده سازی کنید؟ توی این پست با استفاده از Jetpack Compose و graphicsLayer modifier بهتون میگم چجوری میشه.
اگه این براتون جذاب و هیجان انگیز نبود ، توی مثال پایینی نشون میدم چجوری یه برگه کارت پاسور رو در جهات مختلف بچرخونیم و انیمیشن های دیگه بهش بدیم. این هم با استفاده از موارد قبلی.
میتونید کد هاشو از اینجا ببینید.
در این پست در مورد اینا حرف میزنیم :
- این graphicsLayer چیا داره و به چه دردی میخوره
- چجوری یه کارت دو طرفه بسازیم که توی هر دو مثال بالا ازش استفاده شد
توی کد پایین همه پارامتر های graphicsLayer رو لیست کردم:
Modifier
.graphicsLayer(
alpha = alpha,
translationX = translationX,
translationY = translationY,
shadowElevation = shadowElevation,
scaleX = scaleX,
scaleY = scaleY,
rotationX = rotationX,
rotationY = rotationY,
rotationZ = rotationZ,
cameraDistance = cameraDistance,
transformOrigin = TransformOrigin(originX, originY),
shape = roundedDegree,
clip = true,
renderEffect = BlurEffect(blur, blur)
)
آلفا باعث میشه ویو شفاف یا غیر شفاف بشه
پارامتر translationX ویو رو به سمت چپ و راست میبره و translationY به سمت بالا و پایین
با زیاد کردن این پارامتر سایه دور ویو بیشتر میشه
مقیاس افقی با scaleX تنظیم میشه و عمودی با scaleY
پارامتر rotationX چرخش افقی ، rotationY چرخش عمودی ، rotationZ چرخش در محور Z
توجه کنید موقع چرخش ، متن NE هم میچرخن وقتی کارت برمیگرده . چون این نتیجه توی ساخت انیمیشن Wordle بدردمون نمیخوره ، باید یه ویو بسازیم که دو طرفه باشه.
با استفاده از این نقطه چرخش ویو رو تنظیم میکنیم. به صورت پیشفرض مقادیر (0.5 , 0.5) داره که اگه ما تغییرش بدیم به (0,0) اینجوری میشه
این هم یکی دیگه از پارامتراییه که مربوط به چرخشه و بیانگر اینه که دوربین چقد با ویو فاصله داره. هر چی جلو تر باشه ویو موقع چرخش بزرگ تر دیده میشه. مقدار پیشفرض 8.0f هستش.
وقتی تغییرش بدیم به 3.0f موقع چرخش حس میکنیم دوربین جلوتره.
وقتی هم که بدیم 50.0f انگار دوربین خیلی دوره و ویو صاف و مسطح میچرخه.
با استفاده از این میشه برای ویو ها شکل درنظر گرفت . نمونه های پایین مثال هایی از شکل ها هستن . البته باید clip رو برابر true قرار بدید تا کار کنه.
من یه composable ساختم که یه ویو دو طرفه میسازه یعنی وقتی میچرخه ، کارت برمیگرده.
برای چرخش این کارت فقط کافیه عکس جلو و پشت کارت رو به تابع بدیم
DoubleSide( rotationX = rotationX, rotationY = rotationY, rotationZ = rotationZ, cameraDistance = 16f, flipType = FLIPTYPE.HORIZONTAL, front = { Image( painterResource(R.drawable.card_front), contentDescription = "Poker Front", modifier = Modifier.border( 2.dp, Color.Black, shape = roundedDegree) ) }, back = { Image( painterResource(R.drawable.card_back), contentDescription = "Poker Front", modifier = Modifier.border( 2.dp, Color.Black, shape = roundedDegree) ) })
قسمت Composable هم کداش اینجوریه
@Composable fun DoubleSide( translationX: Float = 0f, translationY: Float = 0f, rotationX: Float = 0f, rotationY: Float = 0f, rotationZ: Float = 0f, cameraDistance: Float = 8f, flipType: FLIPTYPE, front: @Composable () -> Unit, back: @Composable () -> Unit ) { fun isHorizontallyFlip() = (abs(rotationX) % 360 > 90f && abs(rotationX) % 360 < 270f) fun isVerticallyFlip() = (abs(rotationY) % 360 > 90f && abs(rotationY) % 360 < 270f) fun isFlipped() = isVerticallyFlip() xor isHorizontallyFlip() if (isFlipped()) { val rotationXBack = if (flipType == FLIPTYPE.HORIZONTAL) rotationX - 180 else rotationX val rotationYBack = if (flipType == FLIPTYPE.VERTICAL) rotationY - 180 else -rotationY Box( Modifier .graphicsLayer( translationX = translationX, translationY = translationY, rotationX = rotationXBack, rotationY = rotationYBack, rotationZ = -rotationZ, cameraDistance = cameraDistance ) ) { back() } } else { Box( Modifier .graphicsLayer( translationX = translationX, translationY = translationY, rotationX = rotationX, rotationY = rotationY, rotationZ = rotationZ, cameraDistance = cameraDistance ) ) { front() } } }
برای اینکه تابع DoubleSide بهتری داشته باشیم نیاز به محاسبات بیشتری هست توی قسمت چرخش که توی کارت پاسور به چشم نمیومد، چونکه کارت های پاسور به صورت عمودی متقارن هستن ولی بعضی کارت ها عمودی و افقی نا متقارن هستن
به همین دلیل توی تابع DoubleSide من شما میتونید flipType بدید که یا FLIPTYPE.HORIZONTAL یا FLIPTYPE.VERTICAL .
اینجا پشت کارت به صورت افقی میچرخه.
- اگه افقی بچرخونید ، کلمه ای که پشت کارته رو به شکل درست میبینید
- اگه عمودی بچرخونید ، کلمه پشت کارت برعکس میشه
اینجا پشت کارت به صورت عمودی میچرخه.
- اگه عمودی بچرخونید ، کلمه ای که پشت کارته رو به شکل درست میبینید
- اگه افقی بچرخونید ، کلمه پشت کارت برعکس میشه
پس پارامتر fliptype برای اینکار استفاده میشه.
امیدوارم از این modifier خوشتون اومده باشه و یه جذابیت خاصی به اپلیکیشنتون داده باشه.
اگه این پست رو دوست داشتید میتونید با استفاده از این لینک ازم حمایت کنید :)