কম্পোজে একটি Brush
বর্ণনা করে যে কীভাবে স্ক্রিনে কিছু আঁকা হয়: এটি অঙ্কন এলাকায় আঁকা রঙ(গুলি) নির্ধারণ করে (যেমন একটি বৃত্ত, বর্গক্ষেত্র, পথ)। কিছু অন্তর্নির্মিত ব্রাশ রয়েছে যা আঁকার জন্য উপযোগী, যেমন LinearGradient
, RadialGradient
বা একটি প্লেইন SolidColor
ব্রাশ।
আঁকানো বিষয়বস্তুতে পেইন্টিং শৈলী প্রয়োগ করতে Modifier.background()
, TextStyle
বা DrawScope
ড্র কলের সাথে ব্রাশ ব্যবহার করা যেতে পারে।
উদাহরণস্বরূপ, DrawScope
একটি বৃত্ত আঁকার জন্য একটি অনুভূমিক গ্রেডিয়েন্ট ব্রাশ প্রয়োগ করা যেতে পারে:
val brush = Brush.horizontalGradient(listOf(Color.Red, Color.Blue)) Canvas( modifier = Modifier.size(200.dp), onDraw = { drawCircle(brush) } )
গ্রেডিয়েন্ট ব্রাশ
অনেকগুলি অন্তর্নির্মিত গ্রেডিয়েন্ট ব্রাশ রয়েছে যা বিভিন্ন গ্রেডিয়েন্ট প্রভাব অর্জন করতে ব্যবহার করা যেতে পারে। এই ব্রাশগুলি আপনাকে রংগুলির তালিকা নির্দিষ্ট করতে দেয় যেগুলি থেকে আপনি একটি গ্রেডিয়েন্ট তৈরি করতে চান।
উপলব্ধ গ্রেডিয়েন্ট ব্রাশের একটি তালিকা এবং তাদের সংশ্লিষ্ট আউটপুট:
গ্রেডিয়েন্ট ব্রাশের ধরন | আউটপুট |
---|---|
Brush.horizontalGradient(colorList) | |
Brush.linearGradient(colorList) | |
Brush.verticalGradient(colorList) | |
Brush.sweepGradient(colorList) দ্রষ্টব্য: রঙের মধ্যে একটি মসৃণ রূপান্তর পেতে - শেষ রঙটি শুরুর রঙে সেট করুন। | |
Brush.radialGradient(colorList) |
colorStops
দিয়ে রঙের ডিস্ট্রিবিউশন পরিবর্তন করুন
গ্রেডিয়েন্টে রঙগুলি কীভাবে প্রদর্শিত হবে তা কাস্টমাইজ করতে, আপনি প্রতিটির জন্য colorStops
মান পরিবর্তন করতে পারেন। colorStops
একটি ভগ্নাংশ হিসাবে নির্দিষ্ট করা উচিত, 0 এবং 1 এর মধ্যে। 1-এর বেশি মানগুলির ফলে সেই রংগুলি গ্রেডিয়েন্টের অংশ হিসাবে রেন্ডার হবে না।
আপনি রঙের স্টপগুলিকে বিভিন্ন পরিমাণে কনফিগার করতে পারেন, যেমন এক রঙের কম বা বেশি:
val colorStops = arrayOf( 0.0f to Color.Yellow, 0.2f to Color.Red, 1f to Color.Blue ) Box( modifier = Modifier .requiredSize(200.dp) .background(Brush.horizontalGradient(colorStops = colorStops)) )
কালার colorStop
পেয়ারে সংজ্ঞায়িত হিসাবে প্রদত্ত অফসেটে রং ছড়িয়ে দেওয়া হয়, লাল এবং নীলের চেয়ে কম হলুদ।
TileMode
দিয়ে একটি প্যাটার্ন পুনরাবৃত্তি করুন
প্রতিটি গ্রেডিয়েন্ট ব্রাশে একটি TileMode
সেট করার বিকল্প রয়েছে। আপনি যদি গ্রেডিয়েন্টের জন্য একটি শুরু এবং শেষ সেট না করে থাকেন তবে আপনি TileMode
লক্ষ্য করবেন না, কারণ এটি পুরো এলাকাটি পূরণ করতে ডিফল্ট হবে। একটি TileMode
শুধুমাত্র গ্রেডিয়েন্টকে টাইল করবে যদি এলাকার আকার ব্রাশের আকারের চেয়ে বড় হয়।
নিম্নলিখিত কোডটি গ্রেডিয়েন্ট প্যাটার্নটি 4 বার পুনরাবৃত্তি করবে, যেহেতু endX
50.dp
এ সেট করা হয়েছে এবং আকারটি 200.dp
এ সেট করা হয়েছে:
val listColors = listOf(Color.Yellow, Color.Red, Color.Blue) val tileSize = with(LocalDensity.current) { 50.dp.toPx() } Box( modifier = Modifier .requiredSize(200.dp) .background( Brush.horizontalGradient( listColors, endX = tileSize, tileMode = TileMode.Repeated ) ) )
উপরের HorizontalGradient
উদাহরণের জন্য বিভিন্ন টাইল মোডগুলি কী করে তার বিশদ বিবরণ এখানে একটি টেবিল রয়েছে:
টাইলমোড | আউটপুট |
---|---|
TileMode.Repeated : প্রান্তটি শেষ রঙ থেকে প্রথম পর্যন্ত পুনরাবৃত্তি হয়। | |
TileMode.Mirror : প্রান্তটি শেষ রঙ থেকে প্রথম পর্যন্ত মিরর করা হয়। | |
TileMode.Clamp : প্রান্তটি চূড়ান্ত রঙে আটকানো হয়। তারপরে এটি বাকি অঞ্চলের জন্য নিকটতম রঙটি আঁকবে। | |
TileMode.Decal : শুধুমাত্র সীমার আকার পর্যন্ত রেন্ডার করুন। TileMode.Decal মূল সীমার বাইরে নমুনা সামগ্রীতে স্বচ্ছ কালো ব্যবহার করে যেখানে TileMode.Clamp প্রান্তের রঙের নমুনা দেয়। |
TileMode
অন্যান্য দিকনির্দেশক গ্রেডিয়েন্টের জন্য একইভাবে কাজ করে, যে দিকটি পুনরাবৃত্তি ঘটে তার পার্থক্য।
ব্রাশের আকার পরিবর্তন করুন
আপনার ব্রাশ যে এলাকায় আঁকা হবে তার মাপ যদি আপনি জানেন, আপনি টাইল endX
সেট করতে পারেন যেমনটি আমরা উপরে TileMode
বিভাগে দেখেছি। আপনি যদি একটি DrawScope
এ থাকেন, তাহলে আপনি এলাকার আকার পেতে এর size
বৈশিষ্ট্য ব্যবহার করতে পারেন।
আপনি যদি আপনার অঙ্কন এলাকার আকার না জানেন (উদাহরণস্বরূপ যদি Brush
টেক্সটে বরাদ্দ করা থাকে), আপনি Shader
প্রসারিত করতে পারেন এবং createShader
ফাংশনে অঙ্কন এলাকার আকার ব্যবহার করতে পারেন।
এই উদাহরণে, প্যাটার্নটি 4 বার পুনরাবৃত্তি করতে আকারটিকে 4 দ্বারা ভাগ করুন:
val listColors = listOf(Color.Yellow, Color.Red, Color.Blue) val customBrush = remember { object : ShaderBrush() { override fun createShader(size: Size): Shader { return LinearGradientShader( colors = listColors, from = Offset.Zero, to = Offset(size.width / 4f, 0f), tileMode = TileMode.Mirror ) } } } Box( modifier = Modifier .requiredSize(200.dp) .background(customBrush) )
আপনি রেডিয়াল গ্রেডিয়েন্টের মতো অন্য যে কোনও গ্রেডিয়েন্টের ব্রাশের আকারও পরিবর্তন করতে পারেন। যদি আপনি একটি আকার এবং কেন্দ্র নির্দিষ্ট না করেন, তাহলে গ্রেডিয়েন্টটি DrawScope
এর সম্পূর্ণ সীমানা দখল করবে, এবং রেডিয়াল গ্রেডিয়েন্টের কেন্দ্রটি DrawScope
সীমার কেন্দ্রে ডিফল্ট হবে। এর ফলে রেডিয়াল গ্রেডিয়েন্টের কেন্দ্রটি ছোট মাত্রার কেন্দ্র হিসাবে প্রদর্শিত হয় (প্রস্থ বা উচ্চতা):
Box( modifier = Modifier .fillMaxSize() .background( Brush.radialGradient( listOf(Color(0xFF2be4dc), Color(0xFF243484)) ) ) )
ব্যাসার্ধের আকার সর্বোচ্চ মাত্রায় সেট করতে রেডিয়াল গ্রেডিয়েন্ট পরিবর্তন করা হলে, আপনি দেখতে পাবেন যে এটি একটি ভাল রেডিয়াল গ্রেডিয়েন্ট প্রভাব তৈরি করে:
val largeRadialGradient = object : ShaderBrush() { override fun createShader(size: Size): Shader { val biggerDimension = maxOf(size.height, size.width) return RadialGradientShader( colors = listOf(Color(0xFF2be4dc), Color(0xFF243484)), center = size.center, radius = biggerDimension / 2f, colorStops = listOf(0f, 0.95f) ) } } Box( modifier = Modifier .fillMaxSize() .background(largeRadialGradient) )
এটা লক্ষনীয় যে শেডার তৈরিতে যে প্রকৃত আকারটি প্রেরণ করা হয় তা নির্ধারণ করা হয় যেখান থেকে এটি আহ্বান করা হয়েছে। ডিফল্টরূপে, Brush
তার Shader
অভ্যন্তরীণভাবে পুনঃনির্ধারণ করবে যদি আকারটি Brush
শেষ সৃষ্টির থেকে আলাদা হয়, অথবা যদি শেডার তৈরিতে ব্যবহৃত কোনো স্টেট অবজেক্ট পরিবর্তিত হয়।
নিচের কোডটি বিভিন্ন আকারের সাথে তিনটি ভিন্ন বার শেডার তৈরি করে, যেমন অঙ্কন এলাকার আকার পরিবর্তন হয়:
val colorStops = arrayOf( 0.0f to Color.Yellow, 0.2f to Color.Red, 1f to Color.Blue ) val brush = Brush.horizontalGradient(colorStops = colorStops) Box( modifier = Modifier .requiredSize(200.dp) .drawBehind { drawRect(brush = brush) // will allocate a shader to occupy the 200 x 200 dp drawing area inset(10f) { /* Will allocate a shader to occupy the 180 x 180 dp drawing area as the inset scope reduces the drawing area by 10 pixels on the left, top, right, bottom sides */ drawRect(brush = brush) inset(5f) { /* will allocate a shader to occupy the 170 x 170 dp drawing area as the inset scope reduces the drawing area by 5 pixels on the left, top, right, bottom sides */ drawRect(brush = brush) } } } )
একটি ব্রাশ হিসাবে একটি ছবি ব্যবহার করুন
একটি Brush
হিসাবে একটি ImageBitmap ব্যবহার করতে, একটি ImageBitmap
হিসাবে ছবিটি লোড করুন, এবং একটি ImageShader
ব্রাশ তৈরি করুন:
val imageBrush = ShaderBrush(ImageShader(ImageBitmap.imageResource(id = R.drawable.dog))) // Use ImageShader Brush with background Box( modifier = Modifier .requiredSize(200.dp) .background(imageBrush) ) // Use ImageShader Brush with TextStyle Text( text = "Hello Android!", style = TextStyle( brush = imageBrush, fontWeight = FontWeight.ExtraBold, fontSize = 36.sp ) ) // Use ImageShader Brush with DrawScope#drawCircle() Canvas(onDraw = { drawCircle(imageBrush) }, modifier = Modifier.size(200.dp))
ব্রাশটি কয়েকটি ভিন্ন ধরণের অঙ্কনে প্রয়োগ করা হয়: একটি পটভূমি, পাঠ্য এবং ক্যানভাস। এটি নিম্নলিখিত আউটপুট:
লক্ষ্য করুন যে পাঠ্যটি এখন ImageBitmap
ব্যবহার করে পাঠ্যের জন্য পিক্সেল আঁকার জন্য রেন্ডার করা হয়েছে।
উন্নত উদাহরণ: কাস্টম ব্রাশ
AGSL RuntimeShader
ব্রাশ
AGSL GLSL Shader ক্ষমতার একটি উপসেট অফার করে। শেডার্স এজিএসএল-এ লেখা এবং কম্পোজে ব্রাশ দিয়ে ব্যবহার করা যেতে পারে।
একটি শেডার ব্রাশ তৈরি করতে, প্রথমে শেডারটিকে AGSL শেডার স্ট্রিং হিসাবে সংজ্ঞায়িত করুন:
@Language("AGSL") val CUSTOM_SHADER = """ uniform float2 resolution; layout(color) uniform half4 color; layout(color) uniform half4 color2; half4 main(in float2 fragCoord) { float2 uv = fragCoord/resolution.xy; float mixValue = distance(uv, vec2(0, 1)); return mix(color, color2, mixValue); } """.trimIndent()
উপরের শেডারটি দুটি ইনপুট রঙ নেয়, অঙ্কন এলাকার নীচের বাম দিক থেকে দূরত্ব গণনা করে ( vec2(0, 1)
) এবং দূরত্বের উপর ভিত্তি করে দুটি রঙের মধ্যে একটি mix
করে। এটি একটি গ্রেডিয়েন্ট প্রভাব তৈরি করে।
তারপরে, শেডার ব্রাশ তৈরি করুন এবং resolution
জন্য ইউনিফর্ম সেট করুন - অঙ্কন এলাকার আকার, এবং color
এবং color2
আপনি আপনার কাস্টম গ্রেডিয়েন্টে ইনপুট হিসাবে ব্যবহার করতে চান:
val Coral = Color(0xFFF3A397) val LightYellow = Color(0xFFF8EE94) @RequiresApi(Build.VERSION_CODES.TIRAMISU) @Composable @Preview fun ShaderBrushExample() { Box( modifier = Modifier .drawWithCache { val shader = RuntimeShader(CUSTOM_SHADER) val shaderBrush = ShaderBrush(shader) shader.setFloatUniform("resolution", size.width, size.height) onDrawBehind { shader.setColorUniform( "color", android.graphics.Color.valueOf( LightYellow.red, LightYellow.green, LightYellow .blue, LightYellow.alpha ) ) shader.setColorUniform( "color2", android.graphics.Color.valueOf( Coral.red, Coral.green, Coral.blue, Coral.alpha ) ) drawRect(shaderBrush) } } .fillMaxWidth() .height(200.dp) ) }
এটি চালালে, আপনি স্ক্রিনে নিম্নলিখিত রেন্ডার করা দেখতে পারেন:
এটি লক্ষণীয় যে আপনি কেবল গ্রেডিয়েন্টের চেয়ে শেডারগুলির সাথে আরও অনেক কিছু করতে পারেন, কারণ এটি সমস্ত গণিত-ভিত্তিক গণনা। AGSL সম্পর্কে আরও তথ্যের জন্য, AGSL ডকুমেন্টেশন দেখুন।
অতিরিক্ত সম্পদ
রচনায় ব্রাশ ব্যবহারের আরও উদাহরণের জন্য, নিম্নলিখিত সংস্থানগুলি দেখুন:
- কম্পোজে অ্যানিমেটিং ব্রাশ টেক্সট কালারিং 🖌️
- কম্পোজে কাস্টম গ্রাফিক্স এবং লেআউট - Android Dev Summit 2022
- জেটল্যাগড নমুনা - রানটাইমশেডার ব্রাশ
আপনার জন্য প্রস্তাবিত
- দ্রষ্টব্য: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট প্রদর্শিত হয়
- গ্রাফিক্স মডিফায়ার
- রচনায় গ্রাফিক্স
- শৈলী পাঠ্য