অনেক অ্যাপ্লিকেশানের স্ক্রিনে যা আঁকা হয়েছে তা সঠিকভাবে নিয়ন্ত্রণ করতে সক্ষম হওয়া দরকার। এটি ঠিক সঠিক জায়গায় পর্দায় একটি বাক্স বা একটি বৃত্ত রাখার মতো ছোট হতে পারে, বা এটি বিভিন্ন শৈলীতে গ্রাফিক উপাদানগুলির একটি বিস্তৃত বিন্যাস হতে পারে।
মডিফায়ার এবং DrawScope
সহ মৌলিক অঙ্কন
কম্পোজে কিছু কাস্টম আঁকার মূল উপায় হল মডিফায়ারের সাথে, যেমন Modifier.drawWithContent
, Modifier.drawBehind
, এবং Modifier.drawWithCache
।
উদাহরণস্বরূপ, আপনার কম্পোজেবলের পিছনে কিছু আঁকতে, আপনি অঙ্কন কমান্ডগুলি চালানো শুরু করতে drawBehind
modifier ব্যবহার করতে পারেন:
Spacer( modifier = Modifier .fillMaxSize() .drawBehind { // this = DrawScope } )
যদি আপনার প্রয়োজন হয় একটি কম্পোজেবল যা আঁকে, আপনি Canvas
কম্পোজেবল ব্যবহার করতে পারেন। Canvas
কম্পোজেবল হল Modifier.drawBehind
চারপাশে একটি সুবিধাজনক মোড়ক। আপনি আপনার লেআউটে Canvas
একইভাবে স্থাপন করেন যেভাবে আপনি অন্য কোনো রচনা UI উপাদানের সাথে করেন৷ Canvas
মধ্যে, আপনি তাদের শৈলী এবং অবস্থানের উপর সুনির্দিষ্ট নিয়ন্ত্রণ সহ উপাদানগুলি আঁকতে পারেন।
সমস্ত অঙ্কন সংশোধক একটি DrawScope
প্রকাশ করে, একটি স্কোপযুক্ত অঙ্কন পরিবেশ যা তার নিজস্ব অবস্থা বজায় রাখে। এটি আপনাকে গ্রাফিকাল উপাদানগুলির একটি গ্রুপের জন্য পরামিতি সেট করতে দেয়। DrawScope
বিভিন্ন দরকারী ক্ষেত্র প্রদান করে, যেমন size
, একটি Size
বস্তু যা DrawScope
এর বর্তমান মাত্রা নির্দিষ্ট করে।
কিছু আঁকতে, আপনি DrawScope
এ অনেকগুলি ড্র ফাংশনের মধ্যে একটি ব্যবহার করতে পারেন। উদাহরণস্বরূপ, নিম্নলিখিত কোডটি পর্দার উপরের বাম কোণে একটি আয়তক্ষেত্র আঁকে:
Canvas(modifier = Modifier.fillMaxSize()) { val canvasQuadrantSize = size / 2F drawRect( color = Color.Magenta, size = canvasQuadrantSize ) }
বিভিন্ন অঙ্কন সংশোধক সম্পর্কে আরও জানতে, গ্রাফিক্স মডিফায়ার ডকুমেন্টেশন দেখুন।
সমন্বয় ব্যবস্থা
স্ক্রিনে কিছু আঁকতে, আপনাকে অফসেট ( x
এবং y
) এবং আপনার আইটেমের আকার জানতে হবে। DrawScope
এ অনেক ড্র পদ্ধতির সাথে, অবস্থান এবং আকার ডিফল্ট প্যারামিটার মান দ্বারা প্রদান করা হয়। ডিফল্ট প্যারামিটারগুলি সাধারণত আইটেমটিকে ক্যানভাসে [0, 0]
পয়েন্টে অবস্থান করে এবং একটি ডিফল্ট size
প্রদান করে যা পুরো অঙ্কন এলাকাটি পূরণ করে, যেমন উপরের উদাহরণে - আপনি দেখতে পাচ্ছেন আয়তক্ষেত্রটি উপরের বাম দিকে অবস্থিত। আপনার আইটেমের আকার এবং অবস্থান সামঞ্জস্য করতে, আপনাকে কম্পোজের সমন্বয় সিস্টেমটি বুঝতে হবে।
স্থানাঙ্ক সিস্টেমের উৎপত্তি ( [0,0]
) অঙ্কন এলাকার উপরের বামদিকের পিক্সেলের দিকে। ডানদিকে সরে গেলে x
বৃদ্ধি পায় এবং নিচের দিকে অগ্রসর হলে y
বৃদ্ধি পায়।
উদাহরণস্বরূপ, আপনি যদি ক্যানভাস এলাকার উপরের-ডান কোণ থেকে নীচে-বাম কোণে একটি তির্যক রেখা আঁকতে চান, তাহলে আপনি DrawScope.drawLine()
ফাংশনটি ব্যবহার করতে পারেন এবং সংশ্লিষ্ট x দিয়ে একটি শুরু এবং শেষ অফসেট নির্দিষ্ট করতে পারেন। এবং y অবস্থান:
Canvas(modifier = Modifier.fillMaxSize()) { val canvasWidth = size.width val canvasHeight = size.height drawLine( start = Offset(x = canvasWidth, y = 0f), end = Offset(x = 0f, y = canvasHeight), color = Color.Blue ) }
মৌলিক রূপান্তর
অঙ্কন কমান্ডগুলি কোথায় বা কীভাবে কার্যকর করা হয় তা পরিবর্তন করতে DrawScope
রূপান্তরের প্রস্তাব দেয়।
স্কেল
একটি ফ্যাক্টর দ্বারা আপনার অঙ্কন অপারেশন আকার বৃদ্ধি DrawScope.scale()
ব্যবহার করুন. scale()
এর মতো অপারেশনগুলি সংশ্লিষ্ট ল্যাম্বডার মধ্যে সমস্ত অঙ্কন ক্রিয়াকলাপে প্রযোজ্য। উদাহরণস্বরূপ, নিম্নলিখিত কোডটি scaleX
10 গুণ এবং scaleY
15 গুণ বৃদ্ধি করে:
Canvas(modifier = Modifier.fillMaxSize()) { scale(scaleX = 10f, scaleY = 15f) { drawCircle(Color.Blue, radius = 20.dp.toPx()) } }
অনুবাদ করুন
আপনার অঙ্কন ক্রিয়াকলাপগুলিকে উপরে, নীচে, বাম বা ডানে সরাতে DrawScope.translate()
ব্যবহার করুন। উদাহরণস্বরূপ, নিম্নলিখিত কোডটি 100 পিক্সেল অঙ্কনটিকে ডানদিকে এবং 300 পিক্সেল উপরে নিয়ে যায়:
Canvas(modifier = Modifier.fillMaxSize()) { translate(left = 100f, top = -300f) { drawCircle(Color.Blue, radius = 200.dp.toPx()) } }
ঘোরান
একটি পিভট পয়েন্টের চারপাশে আপনার অঙ্কন ক্রিয়াকলাপ ঘোরাতে DrawScope.rotate()
ব্যবহার করুন। উদাহরণস্বরূপ, নিম্নলিখিত কোডটি একটি আয়তক্ষেত্রকে 45 ডিগ্রি ঘোরায়:
Canvas(modifier = Modifier.fillMaxSize()) { rotate(degrees = 45F) { drawRect( color = Color.Gray, topLeft = Offset(x = size.width / 3F, y = size.height / 3F), size = size / 3F ) } }
ইনসেট
DrawScope.inset()
ব্যবহার করুন বর্তমান DrawScope
এর ডিফল্ট প্যারামিটার সামঞ্জস্য করতে, অঙ্কনের সীমানা পরিবর্তন করতে এবং সেই অনুযায়ী অঙ্কনগুলি অনুবাদ করতে:
Canvas(modifier = Modifier.fillMaxSize()) { val canvasQuadrantSize = size / 2F inset(horizontal = 50f, vertical = 30f) { drawRect(color = Color.Green, size = canvasQuadrantSize) } }
এই কোডটি কার্যকরভাবে অঙ্কন কমান্ডগুলিতে প্যাডিং যুক্ত করে:
একাধিক রূপান্তর
আপনার অঙ্কনে একাধিক রূপান্তর প্রয়োগ করতে, DrawScope.withTransform()
ফাংশনটি ব্যবহার করুন, যা একটি একক রূপান্তর তৈরি করে এবং প্রয়োগ করে যা আপনার সমস্ত পছন্দসই পরিবর্তনগুলিকে একত্রিত করে। স্বতন্ত্র ট্রান্সফর্মেশনে নেস্টেড কল করার চেয়ে withTransform()
ব্যবহার করা বেশি কার্যকর, কারণ সমস্ত রূপান্তরগুলি একটি একক অপারেশনে একসাথে সঞ্চালিত হয়, এর পরিবর্তে প্রতিটি নেস্টেড রূপান্তর গণনা এবং সংরক্ষণ করতে হয়।
উদাহরণস্বরূপ, নিম্নলিখিত কোডটি আয়তক্ষেত্রে অনুবাদ এবং ঘূর্ণন উভয় ক্ষেত্রেই প্রযোজ্য:
Canvas(modifier = Modifier.fillMaxSize()) { withTransform({ translate(left = size.width / 5F) rotate(degrees = 45F) }) { drawRect( color = Color.Gray, topLeft = Offset(x = size.width / 3F, y = size.height / 3F), size = size / 3F ) } }
সাধারণ অঙ্কন অপারেশন
পাঠ্য আঁকুন
কম্পোজে টেক্সট আঁকতে, আপনি সাধারণত Text
কম্পোজেবল ব্যবহার করতে পারেন। যাইহোক, যদি আপনি একটি DrawScope
এ থাকেন বা আপনি কাস্টমাইজেশনের মাধ্যমে আপনার লেখা ম্যানুয়ালি আঁকতে চান, তাহলে আপনি DrawScope.drawText()
পদ্ধতি ব্যবহার করতে পারেন।
টেক্সট আঁকতে, rememberTextMeasurer
ব্যবহার করে একটি TextMeasurer
তৈরি করুন এবং মেজারের সাথে drawText
কল করুন:
val textMeasurer = rememberTextMeasurer() Canvas(modifier = Modifier.fillMaxSize()) { drawText(textMeasurer, "Hello") }
পাঠ্য পরিমাপ করুন
অঙ্কন পাঠ অন্যান্য অঙ্কন কমান্ড থেকে একটু ভিন্নভাবে কাজ করে। সাধারণত, আপনি আকৃতি/ছবি আঁকতে আকার (প্রস্থ এবং উচ্চতা) অঙ্কন কমান্ড দেন। পাঠ্যের সাথে, কয়েকটি পরামিতি রয়েছে যা রেন্ডার করা পাঠ্যের আকার নিয়ন্ত্রণ করে, যেমন ফন্টের আকার, ফন্ট, লিগ্যাচার এবং অক্ষর ব্যবধান।
কম্পোজের মাধ্যমে, উপরের বিষয়গুলির উপর নির্ভর করে, আপনি পাঠ্যের পরিমাপ করা আকারে অ্যাক্সেস পেতে একটি TextMeasurer
ব্যবহার করতে পারেন। আপনি যদি পাঠ্যের পিছনে একটি পটভূমি আঁকতে চান, আপনি পরিমাপ করা তথ্য ব্যবহার করে পাঠ্যটি যে জায়গাটি নেয় তার আকার পেতে পারেন:
val textMeasurer = rememberTextMeasurer() Spacer( modifier = Modifier .drawWithCache { val measuredText = textMeasurer.measure( AnnotatedString(longTextSample), constraints = Constraints.fixedWidth((size.width * 2f / 3f).toInt()), style = TextStyle(fontSize = 18.sp) ) onDrawBehind { drawRect(pinkColor, size = measuredText.size.toSize()) drawText(measuredText) } } .fillMaxSize() )
এই কোড স্নিপেটটি পাঠ্যে একটি গোলাপী পটভূমি তৈরি করে:
সীমাবদ্ধতা, হরফের আকার, বা মাপা আকারকে প্রভাবিত করে এমন কোনো বৈশিষ্ট্য সামঞ্জস্য করার ফলে একটি নতুন আকার রিপোর্ট করা হয়। আপনি width
এবং height
উভয়ের জন্য একটি নির্দিষ্ট আকার সেট করতে পারেন এবং পাঠ্যটি তারপরে সেট TextOverflow
অনুসরণ করে। উদাহরণ স্বরূপ, নিম্নলিখিত কোডটি কম্পোজযোগ্য এলাকার উচ্চতার ⅓ এবং প্রস্থের ⅓ টেক্সট রেন্ডার করে এবং TextOverflow
কে TextOverflow.Ellipsis
এ সেট করে:
val textMeasurer = rememberTextMeasurer() Spacer( modifier = Modifier .drawWithCache { val measuredText = textMeasurer.measure( AnnotatedString(longTextSample), constraints = Constraints.fixed( width = (size.width / 3f).toInt(), height = (size.height / 3f).toInt() ), overflow = TextOverflow.Ellipsis, style = TextStyle(fontSize = 18.sp) ) onDrawBehind { drawRect(pinkColor, size = measuredText.size.toSize()) drawText(measuredText) } } .fillMaxSize() )
পাঠ্যটি এখন সীমাবদ্ধতায় আঁকা হয়েছে শেষে একটি উপবৃত্ত সহ:
ছবি আঁকা
DrawScope
দিয়ে একটি ImageBitmap
আঁকতে, ImageBitmap.imageResource()
ব্যবহার করে ছবিটি লোড করুন এবং তারপর drawImage
কল করুন:
val dogImage = ImageBitmap.imageResource(id = R.drawable.dog) Canvas(modifier = Modifier.fillMaxSize(), onDraw = { drawImage(dogImage) })
মৌলিক আকার আঁকুন
DrawScope
এ অনেক শেপ ড্রয়িং ফাংশন আছে। একটি আকৃতি আঁকতে, পূর্বনির্ধারিত ড্র ফাংশনগুলির একটি ব্যবহার করুন, যেমন drawCircle
:
val purpleColor = Color(0xFFBA68C8) Canvas( modifier = Modifier .fillMaxSize() .padding(16.dp), onDraw = { drawCircle(purpleColor) } )
API | আউটপুট |
পথ আঁকুন
একটি পথ হল গাণিতিক নির্দেশাবলীর একটি সিরিজ যার ফলস্বরূপ একটি অঙ্কন একবার কার্যকর করা হয়। DrawScope
DrawScope.drawPath()
পদ্ধতি ব্যবহার করে একটি পথ আঁকতে পারে।
উদাহরণস্বরূপ, বলুন আপনি একটি ত্রিভুজ আঁকতে চেয়েছিলেন। আপনি lineTo()
এবং moveTo()
ড্রয়িং এরিয়ার আকার ব্যবহার করে ফাংশন সহ একটি পাথ তৈরি করতে পারেন। তারপর, একটি ত্রিভুজ পেতে এই নতুন তৈরি পাথের সাথে drawPath()
কল করুন।
Spacer( modifier = Modifier .drawWithCache { val path = Path() path.moveTo(0f, 0f) path.lineTo(size.width / 2f, size.height / 2f) path.lineTo(size.width, 0f) path.close() onDrawBehind { drawPath(path, Color.Magenta, style = Stroke(width = 10f)) } } .fillMaxSize() )
Canvas
অবজেক্ট অ্যাক্সেস করা হচ্ছে
DrawScope
এর সাথে, আপনার Canvas
অবজেক্টে সরাসরি অ্যাক্সেস নেই। আপনি Canvas
অবজেক্টে অ্যাক্সেস পেতে DrawScope.drawIntoCanvas()
ব্যবহার করতে পারেন যেটিতে আপনি ফাংশন কল করতে পারেন।
উদাহরণস্বরূপ, যদি আপনার কাছে একটি কাস্টম Drawable
থাকে যা আপনি ক্যানভাসে আঁকতে চান, আপনি ক্যানভাস অ্যাক্সেস করতে পারেন এবং Canvas
অবজেক্টে পাস করে Drawable#draw()
কল করতে পারেন:
val drawable = ShapeDrawable(OvalShape()) Spacer( modifier = Modifier .drawWithContent { drawIntoCanvas { canvas -> drawable.setBounds(0, 0, size.width.toInt(), size.height.toInt()) drawable.draw(canvas.nativeCanvas) } } .fillMaxSize() )
আরও জানুন
রচনায় অঙ্কন সম্পর্কে আরও তথ্যের জন্য, নিম্নলিখিত সংস্থানগুলি দেখুন:
- গ্রাফিক্স মডিফায়ার - বিভিন্ন ধরনের অঙ্কন মডিফায়ার সম্পর্কে জানুন।
- ব্রাশ - আপনার সামগ্রীর পেইন্টিং কীভাবে কাস্টমাইজ করবেন তা শিখুন।
- কম্পোজে কাস্টম লেআউট এবং গ্রাফিক্স - অ্যান্ড্রয়েড ডেভ সামিট 2022 - লেআউট এবং গ্রাফিক্সের সাথে কম্পোজে একটি কাস্টম UI কীভাবে তৈরি করবেন তা শিখুন।
- জেটল্যাগড নমুনা - একটি কাস্টম গ্রাফ কিভাবে আঁকতে হয় তা দেখায় নমুনা রচনা করুন।
আপনার জন্য প্রস্তাবিত
- দ্রষ্টব্য: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট প্রদর্শিত হয়
- গ্রাফিক্স মডিফায়ার
- রচনায় গ্রাফিক্স
- জেটপ্যাক রচনায় সারিবদ্ধ লাইন