অনেক অ্যাপকে স্ক্রিনে কী আঁকা হচ্ছে তা সঠিকভাবে কন্ট্রোল করতে হয়। এটি স্ক্রিনের ঠিক জায়গায় একটি বক্স বা বৃত্ত বসানোর মতো ছোট কাজ হতে পারে অথবা অনেক আলাদা আলাদা স্টাইলে গ্রাফিক এলিমেন্টের বিস্তারিত অ্যারেঞ্জমেন্ট হতে পারে।
মডিফায়ার ও DrawScope সহ সাধারণ ড্রয়িং
Compose-এ কাস্টম কিছু আঁকার মূল উপায় হল মডিফায়ার ব্যবহার করা, যেমন
Modifier.drawWithContent,
Modifier.drawBehind এবং
Modifier.drawWithCache।
যেমন, আপনার কম্পোজ করার উপযুক্ত আইটেমের পিছনে কিছু আঁকতে, আপনি ড্রয়িং কমান্ড এক্সিকিউট করা শুরু করতে
drawBehind মডিফায়ার ব্যবহার করতে পারেন:
Spacer( modifier = Modifier .fillMaxSize() .drawBehind { // this = DrawScope } )
আপনার যদি শুধু এমন একটি কম্পোজ করার মতো আইটেম প্রয়োজন হয় যা ড্র করে, তাহলে আপনি
Canvas কম্পোজ করার মতো আইটেম ব্যবহার করতে পারেন। Canvas কম্পোজ করার উপযুক্ত হল Modifier.drawBehind-এর
আশেপাশে থাকা একটি সুবিধাজনক র্যাপার। আপনি অন্য যেকোনও Compose UI এলিমেন্টের মতো একই উপায়ে আপনার লেআউটে Canvas প্লেস
করেন। Canvas-এর মধ্যে, আপনি এলিমেন্টের স্টাইল ও
লোকেশন নিখুঁতভাবে কন্ট্রোল করে এলিমেন্ট ড্র করতে পারবেন।
সব ড্রয়িং মডিফায়ার একটি DrawScope, একটি স্কোপ করা ড্রয়িং এনভায়রনমেন্ট
প্রকাশ করে যা নিজের স্টেট বজায় রাখে। এটি আপনাকে গ্রাফিক্যাল এলিমেন্টের
একটি গ্রুপের জন্য প্যারামিটার সেট করতে দেয়। DrawScope-এ size-এর মতো একাধিক উপযোগী ফিল্ড থাকে,
DrawScope-এর বর্তমান ডাইমেনশন নির্দিষ্ট করা Size অবজেক্ট।
কিছু আঁকতে, আপনি DrawScope-এ থাকা অনেক ড্র ফাংশনের মধ্যে একটি ব্যবহার করতে পারেন। যেমন, নিচের কোডটি স্ক্রিনের
উপরের বাঁদিকের কোণে একটি আয়তক্ষেত্র আঁকে:
Canvas(modifier = Modifier.fillMaxSize()) { val canvasQuadrantSize = size / 2F drawRect( color = Color.Magenta, size = canvasQuadrantSize ) }
বিভিন্ন ড্রয়িং মডিফায়ার সম্পর্কে আরও জানতে, গ্রাফিক্স মডিফায়ার ডকুমেন্টেশন দেখুন।
কোঅর্ডিনেট সিস্টেম
স্ক্রিনে কিছু আঁকতে, আপনার আইটেমের অফসেট (x ও y) ও সাইজ
সম্পর্কে জানতে হবে। DrawScope-এ অনেক ড্র পদ্ধতির সাথে, পজিশন ও সাইজ
ডিফল্ট প্যারামিটার ভ্যালু দ্বারা প্রদান করা হয়। ডিফল্ট প্যারামিটার সাধারণত
ক্যানভাসের [0, 0] পয়েন্টে আইটেমটি পজিশন করে এবং একটি ডিফল্ট
size প্রদান করে যা উপরের উদাহরণে দেখানো মতো সম্পূর্ণ ড্রয়িং এরিয়া পূরণ করে - আপনি দেখতে পাবেন
যে আয়তক্ষেত্রটি উপরে বাঁদিকে পজিশন করা হয়েছে। আপনার আইটেমের সাইজ ও পজিশন অ্যাডজাস্ট করতে, Compose-এর কোঅর্ডিনেট সিস্টেম বুঝতে হবে।
কোঅর্ডিনেট সিস্টেমের ([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 ১০ বার এবং scaleY ১৫
বার বাড়ায়:
Canvas(modifier = Modifier.fillMaxSize()) { scale(scaleX = 10f, scaleY = 15f) { drawCircle(Color.Blue, radius = 20.dp.toPx()) } }
অনুবাদ করুন
আপনার ড্রয়িং অপারেশন উপরে, নিচে, বাঁদিকে বা ডানদিকে সরাতে
DrawScope.translate()
ব্যবহার করুন। যেমন, নিম্নলিখিত কোডটি
ড্রয়িংকে ১০০ পিক্সেল ডানদিকে এবং ৩০০ পিক্সেল উপরে সরায়:
Canvas(modifier = Modifier.fillMaxSize()) { translate(left = 100f, top = -300f) { drawCircle(Color.Blue, radius = 200.dp.toPx()) } }
ঘোরান
পিভট পয়েন্টের চারপাশে আপনার ড্রয়িং অপারেশন রোটেট করতে
DrawScope.rotate()
ব্যবহার করুন। যেমন, নিম্নলিখিত কোডটি
একটি আয়তক্ষেত্রকে ৪৫ ডিগ্রি কোণে ঘোরানোর কাজ করে:
Canvas(modifier = Modifier.fillMaxSize()) { rotate(degrees = 45F) { drawRect( color = Color.Gray, topLeft = Offset(x = size.width / 3F, y = size.height / 3F), size = size / 3F ) } }
rotate() ব্যবহার করি, এটি আয়তক্ষেত্রটিকে ৪৫ ডিগ্রি কোণে ঘুরিয়ে দেয়।
ইনসেট
বর্তমান DrawScope-এর ডিফল্ট প্যারামিটার অ্যাডজাস্ট করতে DrawScope.inset() ব্যবহার করুন, এর ফলে ড্রয়িংয়ের সীমানা পরিবর্তন করা এবং সেই অনুযায়ী ড্রয়িং
ট্রান্সলেট করা হয়:
Canvas(modifier = Modifier.fillMaxSize()) { val canvasQuadrantSize = size / 2F inset(horizontal = 50f, vertical = 30f) { drawRect(color = Color.Green, size = canvasQuadrantSize) } }
এই কোডটি কার্যকরভাবে ড্রয়িং কমান্ডে প্যাডিং যোগ করে:
একাধিক ট্রান্সফর্মেশন
আপনার ড্রয়িংয়ে একাধিক ট্রান্সফর্মেশন প্রয়োগ করতে, DrawScope.withTransform() ফাংশন ব্যবহার করুন, যা আপনার পছন্দসই সব পরিবর্তনকে একত্রিত করে একটি ট্রান্সফর্মেশন তৈরি করে
প্রয়োগ করে। আলাদা আলাদা
ট্রান্সফর্মেশনের জন্য নেস্টেড কল করার চেয়ে
withTransform() ব্যবহার করা বেশি কার্যকর, কারণ সমস্ত ট্রান্সফর্মেশন একসাথে একটি
সিঙ্গেল অপারেশনে করা হয়। এর ফলে, Compose-কে প্রতিটি
নেস্টেড ট্রান্সফর্মেশন গণনা ও সেভ করতে হয় না।
যেমন, নিম্নলিখিত কোডটি আয়তাকার ক্ষেত্রের উপর অনুবাদ ও ঘূর্ণন, দুটিই প্রয়োগ করে:
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 ) } }
withTransform ব্যবহার করুন, এর ফলে আয়তক্ষেত্রটি ঘুরবে এবং বাঁদিকে সরে যাবে।আঁকা সম্পর্কিত সাধারণ অপারেশন
টেক্সট আঁকা
Compose-এ টেক্সট ড্র করার জন্য, আপনি সাধারণত Text কম্পোজ করার উপযুক্ত আইটেম ব্যবহার করতে পারেন। তবে,
আপনি যদি DrawScope-এ থাকেন অথবা কাস্টমাইজেশনের মাধ্যমে আপনার টেক্সট ম্যানুয়ালি ড্র করতে চান, তাহলে আপনি
DrawScope.drawText()
পদ্ধতি ব্যবহার করতে পারেন।
টেক্সট আঁকতে, rememberTextMeasurer ব্যবহার করে TextMeasurer তৈরি করুন
এবং পরিমাপক সহ drawText-কে কল করুন:
val textMeasurer = rememberTextMeasurer() Canvas(modifier = Modifier.fillMaxSize()) { drawText(textMeasurer, "Hello") }
টেক্সট পরিমাপ করা
টেক্সট আঁকার প্রসেস অন্যান্য ড্রয়িং কমান্ডের থেকে কিছুটা আলাদা। সাধারণত, আপনি ড্রয়িং কমান্ডকে আকার (প্রস্থ ও উচ্চতা) দেন যাতে সেই অনুযায়ী শেপ/ছবি আঁকা যায়। টেক্সটের ক্ষেত্রে, রেন্ডার করা টেক্সটের সাইজ কন্ট্রোল করার জন্য কয়েকটি প্যারামিটার থাকে, যেমন ফন্ট সাইজ, ফন্ট, লিগেচার ও লেটার স্পেসিং।
Compose-এর মাধ্যমে, উপরে উল্লেখ করা ফ্যাক্টরগুলির উপর নির্ভর করে, টেক্সটের পরিমাপ করা
সাইজ অ্যাক্সেস করতে, আপনি একটি 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() )
টেক্সটটি এখন সীমাবদ্ধতার মধ্যে আঁকা হয়েছে এবং শেষে একটি উপবৃত্ত রয়েছে:
TextOverflow.Ellipsis টেক্সট পরিমাপ করার ক্ষেত্রে নির্দিষ্ট সীমাবদ্ধতা আছে।ছবি আঁকা
DrawScope ব্যবহার করে ImageBitmap আঁকতে, ImageBitmap.imageResource() ব্যবহার করে ছবি লোড করুন
এবং তারপরে drawImage কল করুন:
val dogImage = ImageBitmap.imageResource(id = R.drawable.dog) Canvas(modifier = Modifier.fillMaxSize(), onDraw = { drawImage(dogImage) })
ImageBitmap আঁকছি।প্রাথমিক আকার আঁকা
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() )
Path তৈরি ও আঁকা।Canvas অবজেক্ট অ্যাক্সেস করা
DrawScope-এর মাধ্যমে, আপনি Canvas অবজেক্টে সরাসরি অ্যাক্সেস পান না। আপনি Canvas অবজেক্টে অ্যাক্সেস পেতে
DrawScope.drawIntoCanvas() ব্যবহার করতে পারেন
যেখানে আপনি ফাংশন কল করতে পারবেন।
যেমন, আপনার কাছে কাস্টম Drawable থাকলে এবং আপনি সেটি ক্যানভাসের
উপর আঁকতে চাইলে, আপনি ক্যানভাস অ্যাক্সেস করতে এবং Drawable#draw() কল করতে পারবেন, এর সাথে Canvas অবজেক্ট
পাস করতে পারবেন:
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() )
Drawable আঁকতে ক্যানভাস অ্যাক্সেস করা।আরও জানুন
Compose-এ ড্রয়িং সম্পর্কে আরও জানতে, নিম্নলিখিত রিসোর্স দেখুন:
- গ্রাফিক্স মডিফায়ার - বিভিন্ন ধরনের ড্রয়িং মডিফায়ার সম্পর্কে জানুন।
- ব্রাশ - আপনার কন্টেন্টের পেইন্টিং কীভাবে কাস্টমাইজ করবেন তা জানুন।
- Compose-এ কাস্টম লেআউট ও গ্রাফিক্স - Android Dev Summit ২০২২ - লেআউট ও গ্রাফিক্সের সাহায্যে Compose-এ কীভাবে কাস্টম UI তৈরি করতে হয় তা জানুন।
- JetLagged Sample - Compose Sample যা দেখায় কীভাবে কাস্টম গ্রাফ আঁকতে হয়।
আপনার জন্য সাজেস্ট করা হয়েছে
- মনে রাখবেন: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট দেখানো হয়
- গ্রাফিক্স মডিফায়ার
- Compose-এ গ্রাফিক্স
- Jetpack Compose-এ অ্যালাইনমেন্ট লাইন