ছায়া আপনার UI-কে দৃশ্যত উন্নত করে, ব্যবহারকারীদের ইন্ট্যার্যাক্টিভিটি সম্পর্কে ইঙ্গিত দেয় এবং ব্যবহারকারীর অ্যাকশনের ব্যাপারে তৎক্ষণাৎ ফিডব্যাক প্রদান করে। Compose আপনার অ্যাপে শ্যাডো যোগ করার বিভিন্ন উপায় প্রদান করে:
Modifier.shadow(): মেটেরিয়াল ডিজাইন নির্দেশিকা মেনে চলে এমন কম্পোজ করার উপযুক্ত আইটেমের পিছনে উচ্চতা-ভিত্তিক শেডো তৈরি করে।Modifier.dropShadow(): কাস্টমাইজ করা যায় এমন একটি শ্যাডো তৈরি করে যা কম্পোজ করা যায় এমন এলিমেন্টের পিছনে দেখা যায়, এর ফলে এলিমেন্টটি উঁচু হয়ে আছে বলে মনে হয়।Modifier.innerShadow(): কম্পোজ করার উপযুক্ত আইটেমের বর্ডারের মধ্যে একটি ছায়া তৈরি করে, যার ফলে মনে হয় যে এটি এর পিছনের সারফেসে প্রেস করা হয়েছে।
Modifier.shadow() হল প্রাথমিক শেডিংয়ের জন্য উপযুক্ত, যেখানে
dropShadow() ও innerShadow() মডিফায়ার আরও সূক্ষ্ম কন্ট্রোল ও
শেডিংয়ের ক্ষেত্রে আরও নিখুঁত ফলাফল প্রদান করে।
এই পৃষ্ঠায় প্রতিটি মডিফায়ার কীভাবে প্রয়োগ করতে হয় তা বর্ণনা করা হয়েছে। এর মধ্যে ব্যবহারকারীর ইন্টার্যাকশনের উপর ভিত্তি করে কীভাবে
ছায়া অ্যানিমেট করতে হয় এবং কীভাবে
innerShadow() ও dropShadow() মডিফায়ার চেইন করে
গ্রেডিয়েন্ট শ্যাডো,
নিউমর্ফিক শ্যাডো ও আরও অনেক কিছু তৈরি করতে হয় তা অন্তর্ভুক্ত।
প্রাথমিক শ্যাডো তৈরি করা
Modifier.shadow() মেটেরিয়াল ডিজাইন
নির্দেশিকা মেনে একটি প্রাথমিক ছায়া তৈরি করে যা ওভারহেড লাইট সোর্সকে সিমুলেট করে। ছায়ার
গভীরতা elevation ভ্যালুর উপর ভিত্তি করে হয় এবং কাস্ট করা ছায়া কম্পোজ করার উপযুক্ত আইটেমের
আকৃতিতে ক্লিপ করা হয়।
@Composable fun ElevationBasedShadow() { Box( modifier = Modifier.aspectRatio(1f).fillMaxSize(), contentAlignment = Alignment.Center ) { Box( Modifier .size(100.dp, 100.dp) .shadow(10.dp, RectangleShape) .background(Color.White) ) } }
Modifier.shadow()-এর সাহায্যে তৈরি করা উচ্চতা-ভিত্তিক শেড।ড্রপ শ্যাডো প্রয়োগ করা
আপনার কন্টেন্টের পিছনে নিখুঁতভাবে
ছায়া আঁকতে dropShadow() মডিফায়ার ব্যবহার করুন, যা এলিমেন্টটিকে উঁচু করে দেখায়।
আপনি এর Shadow প্যারামিটারের মাধ্যমে নিম্নলিখিত মূল বিষয়গুলি নিয়ন্ত্রণ করতে পারবেন:
radius: আপনার ব্লারের মসৃণতা ও ডিফিউশন নির্ধারণ করে।color: টিন্টের রঙ নির্ধারণ করে।offset: x ও y অক্ষ বরাবর জ্যামিতির ছায়া পজিশন করে।spread: এটি ছায়ার জ্যামিতির প্রসারণ বা সংকোচনকে নিয়ন্ত্রণ করে।
এছাড়াও, shape প্যারামিটারটি ছায়ার সামগ্রিক আকার নির্ধারণ করে। এটি androidx.compose.foundation.shape প্যাকেজ থেকে যেকোনও জ্যামিতি ব্যবহার করতে
পারে, সেইসাথে Material Expressive shapes-ও ব্যবহার করতে
পারে।
সাধারণ ড্রপ শ্যাডো প্রয়োগ করতে, আপনার কম্পোজ করার মতো চেনে dropShadow() মডিফায়ার যোগ করুন,
যা রেডিয়াস, রঙ ও স্প্রেড প্রদান করে। মনে রাখবেন যে,
purpleColor ছায়ার উপরে যে ব্যাকগ্রাউন্ড দেখা যায় তা
dropShadow() মডিফায়ারের পরে আঁকা হয়:
@Composable fun SimpleDropShadowUsage() { Box(Modifier.fillMaxSize()) { Box( Modifier .width(300.dp) .height(300.dp) .dropShadow( shape = RoundedCornerShape(20.dp), shadow = Shadow( radius = 10.dp, spread = 6.dp, color = Color(0x40000000), offset = DpOffset(x = 4.dp, 4.dp) ) ) .align(Alignment.Center) .background( color = Color.White, shape = RoundedCornerShape(20.dp) ) ) { Text( "Drop Shadow", modifier = Modifier.align(Alignment.Center), fontSize = 32.sp ) } } }
কোড সম্পর্কে গুরুত্বপূর্ণ পয়েন্ট
- ভেতরের
Box-এdropShadow()মডিফায়ার প্রয়োগ করা হয়। ছায়ার মধ্যে নিচের বৈশিষ্ট্যগুলি রয়েছে:- গোলাকৃতি আয়তাকার শেপ (
RoundedCornerShape(20.dp)) 10.dp-এর ব্লার রেডিয়াস, যা প্রান্তগুলিকে সফ্ট ও ডিফিউজ করে6.dp-এর স্প্রেড, যা ছায়ার সাইজকে বড় করে এবং এটিকে যে বক্সটি কাস্ট করছে তার থেকে বড় করে তোলে0.5f-এর আলফা, যা ছায়াটিকে অর্ধ-স্বচ্ছ করে তোলে
- গোলাকৃতি আয়তাকার শেপ (
- ছায়া নির্ধারণ করার পরে, .
background()মডিফায়ার প্রয়োগ করা হয়েছে।Box-এ সাদা রঙ ভরা থাকে।- ছায়ার মতো একই গোলাকার কোণযুক্ত আয়তাকার শেপে ব্যাকগ্রাউন্ড ক্লিপ করা হয়।
ফলাফল
ইনার শ্যাডো প্রয়োগ করা
dropShadow()-এর বিপরীত এফেক্ট তৈরি করতে, Modifier.innerShadow() ব্যবহার করুন, যা এমন বিভ্রম তৈরি করে যে কোনও এলিমেন্ট
নিচে নেমে গেছে বা ভিতরের দিকে প্রেস করা হয়েছে।
ইনার শ্যাডো তৈরি করার সময় ক্রম গুরুত্বপূর্ণ। innerShadow() মডিফায়ার
কন্টেন্টের উপরে ড্র করে। ছায়া দেখা যাচ্ছে কিনা তা নিশ্চিত করতে, সাধারণত
নিচে উল্লেখ করা ধাপগুলি অনুসরণ করুন:
- আপনার ব্যাকগ্রাউন্ড কন্টেন্ট আঁকুন।
- অবতল আকৃতি তৈরি করতে
innerShadow()মডিফায়ার প্রয়োগ করুন।
innerShadow() ব্যাকগ্রাউন্ডের আগে প্লেস করা হলে, ব্যাকগ্রাউন্ডটি
ছায়ার উপরে ড্র করা হয়, ফলে সেটি সম্পূর্ণভাবে ঢাকা পড়ে যায়।
নিচের উদাহরণে
RoundedCornerShape-এ innerShadow()-এর প্রয়োগ দেখানো হয়েছে::
@Composable fun SimpleInnerShadowUsage() { Box(Modifier.fillMaxSize()) { Box( Modifier .width(300.dp) .height(200.dp) .align(Alignment.Center) // note that the background needs to be defined before defining the inner shadow .background( color = Color.White, shape = RoundedCornerShape(20.dp) ) .innerShadow( shape = RoundedCornerShape(20.dp), shadow = Shadow( radius = 10.dp, spread = 2.dp, color = Color(0x40000000), offset = DpOffset(x = 6.dp, 7.dp) ) ) ) { Text( "Inner Shadow", modifier = Modifier.align(Alignment.Center), fontSize = 32.sp ) } } }
Modifier.innerShadow() প্রয়োগ করা হয়েছে।ব্যবহারকারীর ইন্টার্যাকশনের উপর ভিত্তি করে অ্যানিমেট করা ছায়া
আপনার শ্যাডোকে ব্যবহারকারীর ইন্টার্যাকশনের প্রতি প্রতিক্রিয়াশীল করে তুলতে, আপনি Compose-এর অ্যানিমেশন API-এর সাথে শ্যাডো প্রপার্টি ইন্টিগ্রেট করতে পারেন। ব্যবহারকারী কোনও বোতামে প্রেস করলে, উদাহরণস্বরূপ, তাৎক্ষণিক ভিজ্যুয়াল ফিডব্যাক প্রদান করতে, শ্যাডো পরিবর্তন হতে পারে।
নিচের কোডটি একটি শেডোর মাধ্যমে "প্রেস করা" এফেক্ট তৈরি করে (এই বিভ্রম যে সারফেসটি স্ক্রিনের মধ্যে নিচের দিকে পুশ করা হচ্ছে):
@Composable fun AnimatedColoredShadows() { SnippetsTheme { Box(Modifier.fillMaxSize()) { val interactionSource = remember { MutableInteractionSource() } val isPressed by interactionSource.collectIsPressedAsState() // Create transition with pressed state val transition = updateTransition( targetState = isPressed, label = "button_press_transition" ) fun <T> buttonPressAnimation() = tween<T>( durationMillis = 400, easing = EaseInOut ) // Animate all properties using the transition val shadowAlpha by transition.animateFloat( label = "shadow_alpha", transitionSpec = { buttonPressAnimation() } ) { pressed -> if (pressed) 0f else 1f } // ... val blueDropShadow by transition.animateColor( label = "shadow_color", transitionSpec = { buttonPressAnimation() } ) { pressed -> if (pressed) Color.Transparent else blueDropShadowColor } // ... Box( Modifier .clickable( interactionSource, indication = null ) { // ** ...... **// } .width(300.dp) .height(200.dp) .align(Alignment.Center) .dropShadow( shape = RoundedCornerShape(70.dp), shadow = Shadow( radius = 10.dp, spread = 0.dp, color = blueDropShadow, offset = DpOffset(x = 0.dp, -(2).dp), alpha = shadowAlpha ) ) .dropShadow( shape = RoundedCornerShape(70.dp), shadow = Shadow( radius = 10.dp, spread = 0.dp, color = darkBlueDropShadow, offset = DpOffset(x = 2.dp, 6.dp), alpha = shadowAlpha ) ) // note that the background needs to be defined before defining the inner shadow .background( color = Color(0xFFFFFFFF), shape = RoundedCornerShape(70.dp) ) .innerShadow( shape = RoundedCornerShape(70.dp), shadow = Shadow( radius = 8.dp, spread = 4.dp, color = innerShadowColor2, offset = DpOffset(x = 4.dp, 0.dp) ) ) .innerShadow( shape = RoundedCornerShape(70.dp), shadow = Shadow( radius = 20.dp, spread = 4.dp, color = innerShadowColor1, offset = DpOffset(x = 4.dp, 0.dp), alpha = innerShadowAlpha ) ) ) { Text( "Animated Shadows", // ... ) } } } }
কোড সম্পর্কে গুরুত্বপূর্ণ পয়েন্ট
transition.animateColorওtransition.animateFloat-এর মাধ্যমে প্রেস করার পরে অ্যানিমেট করার জন্য প্যারামিটারের শুরু ও শেষ অবস্থা ঘোষণা করে।updateTransitionব্যবহার করে এবং বেছে নেওয়াtargetState (targetState = isPressed)-এর সাথে প্রদান করে যাতে সব অ্যানিমেশন সিনক্রোনাইজ করা হয়েছে কিনা তা যাচাই করা যায়। যখনইisPressedপরিবর্তন হয়, ট্রানজিশন অবজেক্ট অটোমেটিক সব চাইল্ড প্রপার্টির অ্যানিমেশন তাদের বর্তমান ভ্যালু থেকে নতুন টার্গেট ভ্যালু পর্যন্ত ম্যানেজ করে।buttonPressAnimationস্পেসিফিকেশনকে সংজ্ঞায়িত করে, যা ট্রানজিশনের টাইমিং ও ইজিং নিয়ন্ত্রণ করে। এটিtween(ইন-বিটুয়েন শব্দের সংক্ষিপ্ত রূপ) নির্দিষ্ট করে, যার সময়সীমা ৪০০ মিলিসেকেন্ড এবং একটিEaseInOutকার্ভ, যার অর্থ হল অ্যানিমেশন ধীরে ধীরে শুরু হয়, মাঝখানে স্পিড বেড়ে যায় এবং শেষে স্পিড কমে যায়।- মডিফায়ার ফাংশনের চেনের মাধ্যমে
Boxনির্ধারণ করে যা ভিজ্যুয়াল এলিমেন্ট তৈরি করতে সব অ্যানিমেটেড প্রপার্টি প্রয়োগ করে, এর মধ্যে নিম্নলিখিত বিষয়গুলি অন্তর্ভুক্ত:- .
clickable(): একটি মডিফায়ার যাBox-কে ইন্ট্যার্যাক্টিভ করে তোলে। .dropShadow(): প্রথমে দুটি বাইরের ড্রপ শ্যাডো প্রয়োগ করা হয়। এগুলির কালার ও আলফা প্রপার্টি অ্যানিমেটেড ভ্যালুর (blueDropShadowইত্যাদি) সাথে লিঙ্ক করা থাকে এবং প্রাথমিক উঁচু হয়ে থাকা চেহারা তৈরি করে।.innerShadow(): ব্যাকগ্রাউন্ডের উপরে দুটি ইনার শ্যাডো আঁকা হয়েছে। তাদের প্রপার্টি অ্যানিমেটেড ভ্যালুর অন্য সেটের সাথে লিঙ্ক করা থাকে (innerShadowColor1ইত্যাদি) এবং ইন্ডেন্ট করা চেহারা তৈরি করে।
- .
ফলাফল
গ্রেডিয়েন্ট শেড তৈরি করা
ছায়া শুধুমাত্র গাঢ় রঙের মধ্যেই সীমাবদ্ধ নয়। ছায়া API একটি Brush গ্রহণ করে, যা
আপনাকে গ্রেডিয়েন্ট ছায়া তৈরি করতে দেয়।
Box( modifier = Modifier .width(240.dp) .height(200.dp) .dropShadow( shape = RoundedCornerShape(70.dp), shadow = Shadow( radius = 10.dp, spread = animatedSpread.dp, brush = Brush.sweepGradient( colors ), offset = DpOffset(x = 0.dp, y = 0.dp), alpha = animatedAlpha ) ) .clip(RoundedCornerShape(70.dp)) .background(Color(0xEDFFFFFF)), contentAlignment = Alignment.Center ) { Text( text = breathingText, color = Color.Black, style = MaterialTheme.typography.bodyLarge ) }
কোড সম্পর্কে গুরুত্বপূর্ণ পয়েন্ট
dropShadow()বক্সের পিছনে একটি ছায়া যোগ করে।brush = Brush.sweepGradient(colors)একটি গ্রেডিয়েন্ট দিয়ে ছায়াটিকে কালার করে যা আগে থেকে সংজ্ঞায়িতcolors-এর একটি তালিকার মাধ্যমে রোটেট করে, যার ফলে একটি রামধনুর মতো প্রভাব তৈরি হয়।
ফলাফল
আপনি একটি ব্রাশকে ছায়া হিসেবে ব্যবহার করে একটি গ্রেডিয়েন্ট dropShadow() তৈরি করতে পারেন যার মধ্যে
"শ্বাস-প্রশ্বাস" অ্যানিমেশন রয়েছে:
ছায়া যোগ করা
বিভিন্ন ধরনের এফেক্ট তৈরি করতে, আপনি dropShadow() ও innerShadow() মডিফায়ারগুলিকে
একসাথে ব্যবহার করতে ও লেয়ার করতে পারবেন। এই কৌশল ব্যবহার করে কীভাবে
নিউমর্ফিক, নিওব্রুটালিস্ট ও বাস্তবসম্মত শেড তৈরি করবেন তা নিম্নলিখিত বিভাগগুলি থেকে জানতে পারবেন।
নিউমর্ফিক শ্যাডো তৈরি করা
নিউমর্ফিক শেডোর বৈশিষ্ট্য হল এর সফ্ট চেহারা যা ব্যাকগ্রাউন্ড থেকে স্বাভাবিকভাবে ফুটে ওঠে। নিউমর্ফিক শ্যাডো তৈরি করতে, নিম্নলিখিত ধাপগুলি অনুসরণ করুন:
- এমন এলিমেন্ট ব্যবহার করুন যার রঙ ব্যাকগ্রাউন্ডের রঙের সাথে একই।
- দুটি হালকা, বিপরীতমুখী ড্রপ শ্যাডো প্রয়োগ করুন: একটি কোণে হালকা শ্যাডো এবং বিপরীত কোণে গাঢ় শ্যাডো।
নিচের স্নিপেটে নিউমর্ফিক এফেক্ট তৈরি করতে দুটি dropShadow() মডিফায়ার ব্যবহার করা হয়েছে:
@Composable fun NeumorphicRaisedButton( shape: RoundedCornerShape = RoundedCornerShape(30.dp) ) { val bgColor = Color(0xFFe0e0e0) val lightShadow = Color(0xFFFFFFFF) val darkShadow = Color(0xFFb1b1b1) val upperOffset = -10.dp val lowerOffset = 10.dp val radius = 15.dp val spread = 0.dp Box( modifier = Modifier .fillMaxSize() .background(bgColor) .wrapContentSize(Alignment.Center) .size(240.dp) .dropShadow( shape, shadow = Shadow( radius = radius, color = lightShadow, spread = spread, offset = DpOffset(upperOffset, upperOffset) ), ) .dropShadow( shape, shadow = Shadow( radius = radius, color = darkShadow, spread = spread, offset = DpOffset(lowerOffset, lowerOffset) ), ) .background(bgColor, shape) ) }
নিওব্রুটালিস্ট শেড তৈরি করা
নিওব্রুটালিস্ট স্টাইলে হাই-কনট্রাস্ট, ব্লক করা লেআউট, উজ্জ্বল রঙ
এবং মোটা বর্ডার দেখানো হয়। এই এফেক্ট তৈরি করতে, dropShadow() ব্যবহার করুন যাতে কোনও অস্পষ্টতা না থাকে
এবং একটি আলাদা অফসেট থাকে, যেমনটি নিম্নলিখিত স্নিপেটে দেখানো হয়েছে:
@Composable fun NeoBrutalShadows() { SnippetsTheme { val dropShadowColor = Color(0xFF007AFF) val borderColor = Color(0xFFFF2D55) Box(Modifier.fillMaxSize()) { Box( Modifier .width(300.dp) .height(200.dp) .align(Alignment.Center) .dropShadow( shape = RoundedCornerShape(0.dp), shadow = Shadow( radius = 0.dp, spread = 0.dp, color = dropShadowColor, offset = DpOffset(x = 8.dp, 8.dp) ) ) .border( 8.dp, borderColor ) .background( color = Color.White, shape = RoundedCornerShape(0.dp) ) ) { Text( "Neobrutal Shadows", modifier = Modifier.align(Alignment.Center), style = MaterialTheme.typography.bodyMedium ) } } } }
বাস্তবসম্মত ছায়া তৈরি করা
বাস্তবসম্মত ছায়াগুলি বাস্তব জগতে ছায়ার মতো— সেগুলি একটি
প্রাথমিক আলোর উৎস দ্বারা আলোকিত হয়, যার ফলে একটি সরাসরি ছায়া এবং আরও বেশি ডিফিউজ
ছায়া তৈরি হয়। বাস্তবসম্মত ছায়া প্রভাব রিক্রিয়েট করতে, আপনি একাধিক dropShadow() এবং innerShadow() ইনস্ট্যান্সকে
বিভিন্ন প্রপার্টির সাথে স্ট্যাক করতে পারেন, যেমনটি
নিম্নলিখিত স্নিপেটে দেখানো হয়েছে:
@Composable fun RealisticShadows() { Box(Modifier.fillMaxSize()) { val dropShadowColor1 = Color(0xB3000000) val dropShadowColor2 = Color(0x66000000) val innerShadowColor1 = Color(0xCC000000) val innerShadowColor2 = Color(0xFF050505) val innerShadowColor3 = Color(0x40FFFFFF) val innerShadowColor4 = Color(0x1A050505) Box( Modifier .width(300.dp) .height(200.dp) .align(Alignment.Center) .dropShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 40.dp, spread = 0.dp, color = dropShadowColor1, offset = DpOffset(x = 2.dp, 8.dp) ) ) .dropShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 4.dp, spread = 0.dp, color = dropShadowColor2, offset = DpOffset(x = 0.dp, 4.dp) ) ) // note that the background needs to be defined before defining the inner shadow .background( color = Color.Black, shape = RoundedCornerShape(100.dp) ) // // .innerShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 12.dp, spread = 3.dp, color = innerShadowColor1, offset = DpOffset(x = 6.dp, 6.dp) ) ) .innerShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 4.dp, spread = 1.dp, color = Color.White, offset = DpOffset(x = 5.dp, 5.dp) ) ) .innerShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 12.dp, spread = 5.dp, color = innerShadowColor2, offset = DpOffset(x = (-3).dp, (-12).dp) ) ) .innerShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 3.dp, spread = 10.dp, color = innerShadowColor3, offset = DpOffset(x = 0.dp, 0.dp) ) ) .innerShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 3.dp, spread = 9.dp, color = innerShadowColor4, offset = DpOffset(x = 1.dp, 1.dp) ) ) ) { Text( "Realistic Shadows", modifier = Modifier.align(Alignment.Center), fontSize = 24.sp, color = Color.White ) } } }
কোড সম্পর্কে গুরুত্বপূর্ণ পয়েন্ট
- আলাদা আলাদা প্রপার্টি সহ দুটি চেইন করা
dropShadow()মডিফায়ার প্রয়োগ করা হয়, তারপরে একটিbackground()মডিফায়ার প্রয়োগ করা হয়। - কম্পোনেন্টের প্রান্তের চারপাশে মেটালিক রিম এফেক্ট তৈরি করতে চেইন করা
innerShadow()মডিফায়ার প্রয়োগ করা হয়।
ফলাফল
আগের কোড স্নিপেট থেকে নিম্নলিখিত আউটপুট পাওয়া যায়: