ক্যানভাস বস্তুর উপর অঙ্কন

এই কোডল্যাবটি অ্যাডভান্সড অ্যান্ড্রয়েড ইন কোটলিন কোর্সের অংশ। আপনি যদি কোডল্যাবগুলি ক্রমানুসারে কাজ করেন তবে আপনি এই কোর্সের সর্বাধিক মূল্য পাবেন, তবে এটি বাধ্যতামূলক নয়৷ সমস্ত কোর্স কোডল্যাবগুলি কোটলিন কোডল্যাবস ল্যান্ডিং পৃষ্ঠায় অ্যাডভান্সড অ্যান্ড্রয়েডে তালিকাভুক্ত করা হয়েছে।

ভূমিকা

অ্যান্ড্রয়েডে, আপনার কাছে কাস্টম 2D গ্রাফিক্স এবং ভিউতে অ্যানিমেশন বাস্তবায়নের জন্য বেশ কিছু কৌশল উপলব্ধ রয়েছে।

অঙ্কনযোগ্য ব্যবহার করার পাশাপাশি, আপনি Canvas ক্লাসের অঙ্কন পদ্ধতি ব্যবহার করে 2D অঙ্কন তৈরি করতে পারেন। Canvas হল একটি 2D অঙ্কন পৃষ্ঠ যা অঙ্কনের পদ্ধতি প্রদান করে। এটি দরকারী যখন আপনার অ্যাপকে নিয়মিত নিজেকে পুনরায় আঁকতে হবে, কারণ ব্যবহারকারী যা দেখেন তা সময়ের সাথে পরিবর্তিত হয়। এই কোডল্যাবে, আপনি একটি View প্রদর্শিত ক্যানভাসে কীভাবে তৈরি এবং আঁকতে হয় তা শিখবেন।

আপনি ক্যানভাসে যে ধরনের অপারেশন করতে পারেন তার মধ্যে রয়েছে:

  • রঙ দিয়ে পুরো ক্যানভাস পূরণ করুন।
  • একটি Paint অবজেক্টে সংজ্ঞায়িত হিসাবে আয়তক্ষেত্র, আর্কস এবং পাথের মতো আকারগুলি আঁকুন। Paint অবজেক্ট কীভাবে জ্যামিতি (যেমন রেখা, আয়তক্ষেত্র, ডিম্বাকৃতি এবং পাথ) আঁকতে হয় সে সম্পর্কে শৈলী এবং রঙের তথ্য ধারণ করে, বা উদাহরণস্বরূপ, পাঠ্যের টাইপফেস।
  • রূপান্তর প্রয়োগ করুন, যেমন অনুবাদ, স্কেলিং, বা কাস্টম রূপান্তর।
  • ক্লিপ, অর্থাৎ, ক্যানভাসের দৃশ্যমান অংশগুলিকে সংজ্ঞায়িত করতে একটি আকৃতি বা পথ প্রয়োগ করুন।

আপনি কীভাবে অ্যান্ড্রয়েড অঙ্কন সম্পর্কে ভাবতে পারেন (সুপার-সরলীকৃত!)

অ্যান্ড্রয়েড বা অন্য যে কোনও আধুনিক সিস্টেমে অঙ্কন করা একটি জটিল প্রক্রিয়া যাতে বিমূর্তকরণের স্তরগুলি এবং হার্ডওয়্যার পর্যন্ত অপ্টিমাইজেশন অন্তর্ভুক্ত থাকে। অ্যান্ড্রয়েড কীভাবে আঁকে তা একটি আকর্ষণীয় বিষয় যা সম্পর্কে অনেক কিছু লেখা হয়েছে এবং এর বিশদ বিবরণ এই কোডল্যাবের সুযোগের বাইরে।

এই কোডল্যাবের প্রেক্ষাপটে, এবং এর অ্যাপ যা একটি পূর্ণ-স্ক্রীন দৃশ্যে প্রদর্শনের জন্য একটি ক্যানভাসে আঁকে, আপনি এটিকে নিম্নলিখিত উপায়ে ভাবতে পারেন।

  1. আপনি যা আঁকছেন তা প্রদর্শনের জন্য আপনার একটি দৃশ্য প্রয়োজন। এটি অ্যান্ড্রয়েড সিস্টেম দ্বারা প্রদত্ত মতামতগুলির মধ্যে একটি হতে পারে৷ অথবা, এই কোডল্যাবে, আপনি একটি কাস্টম ভিউ তৈরি করেন যা আপনার অ্যাপের ( MyCanvasView ) কন্টেন্ট ভিউ হিসেবে কাজ করে।
  2. এই ভিউ, সমস্ত ভিউ হিসাবে, তার নিজস্ব ক্যানভাস ( canvas ) নিয়ে আসে।
  3. একটি দৃশ্যের ক্যানভাসে আঁকার সবচেয়ে মৌলিক উপায়ের জন্য, আপনি এটির onDraw() পদ্ধতিকে ওভাররাইড করুন এবং এর ক্যানভাসে আঁকুন।
  4. অঙ্কন তৈরি করার সময়, আপনি আগে যা আঁকেছেন তা ক্যাশে করতে হবে। আপনার ডেটা ক্যাশে করার বিভিন্ন উপায় রয়েছে, একটি বিটম্যাপে ( extraBitmap )। আরেকটি হল স্থানাঙ্ক এবং নির্দেশাবলী হিসাবে আপনি যা আঁকেছেন তার একটি ইতিহাস সংরক্ষণ করা।
  5. ক্যানভাস অঙ্কন API ব্যবহার করে আপনার ক্যাশিং বিটম্যাপ ( extraBitmap ) এ আঁকার জন্য, আপনি আপনার ক্যাশিং বিটম্যাপের জন্য একটি ক্যাশিং ক্যানভাস ( extraCanvas ) তৈরি করুন৷
  6. তারপরে আপনি আপনার ক্যাশিং ক্যানভাসে ( extraCanvas ), যা আপনার ক্যাশিং বিটম্যাপের ( extraBitmap ) উপর আঁকেন।
  7. স্ক্রিনে আঁকা সবকিছু প্রদর্শন করতে, আপনি দৃশ্যের ক্যানভাস ( canvas ) কে ক্যাশিং বিটম্যাপ ( extraBitmap ) আঁকতে বলুন।

আপনি ইতিমধ্যে কি জানা উচিত

  • কিভাবে একটি অ্যাক্টিভিটি, একটি বেসিক লেআউট সহ একটি অ্যাপ তৈরি করবেন এবং অ্যান্ড্রয়েড স্টুডিও ব্যবহার করে এটি চালাবেন।
  • কীভাবে ইভেন্ট হ্যান্ডলারদের ভিউয়ের সাথে সংযুক্ত করবেন।
  • কিভাবে একটি কাস্টম ভিউ তৈরি করতে হয়।

আপনি কি শিখবেন

  • কীভাবে একটি Canvas তৈরি করবেন এবং ব্যবহারকারীর স্পর্শের প্রতিক্রিয়া হিসাবে এটিতে আঁকবেন।

আপনি কি করবেন

  • এমন একটি অ্যাপ তৈরি করুন যা ব্যবহারকারীর স্ক্রীন স্পর্শ করার প্রতিক্রিয়ায় স্ক্রিনে লাইন আঁকে।
  • মোশন ইভেন্টগুলি ক্যাপচার করুন এবং প্রতিক্রিয়া হিসাবে, একটি ক্যানভাসে লাইন আঁকুন যা স্ক্রিনে একটি পূর্ণস্ক্রীন কাস্টম ভিউতে প্রদর্শিত হয়।

MiniPaint অ্যাপটি ব্যবহারকারীর স্পর্শের প্রতিক্রিয়ায় একটি লাইন প্রদর্শন করতে একটি কাস্টম ভিউ ব্যবহার করে, যেমনটি নীচের স্ক্রিনশটে দেখানো হয়েছে।

ধাপ 1. মিনিপেইন্ট প্রকল্প তৈরি করুন

  1. MiniPaint নামে একটি নতুন কোটলিন প্রকল্প তৈরি করুন যা খালি কার্যকলাপ টেমপ্লেট ব্যবহার করে।
  2. app/res/values/colors.xml ফাইলটি খুলুন এবং নিম্নলিখিত দুটি রং যোগ করুন।
<color name="colorBackground">#FFFF5500</color>
<color name="colorPaint">#FFFFEB3B</color>
  1. styles.xml খুলুন
  2. প্রদত্ত AppTheme স্টাইলের প্যারেন্টে, DarkActionBar NoActionBar দিয়ে প্রতিস্থাপন করুন। এটি অ্যাকশন বারটি সরিয়ে দেয়, যাতে আপনি পূর্ণস্ক্রীন আঁকতে পারেন।
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

ধাপ 2. MyCanvasView ক্লাস তৈরি করুন

এই ধাপে আপনি আঁকার জন্য একটি কাস্টম ভিউ, MyCanvasView তৈরি করুন।

  1. app/java/com.example.android.minipaint প্যাকেজে, MyCanvasView নামে একটি নতুন > Kotlin ফাইল/ক্লাস তৈরি করুন।
  2. MyCanvasView ক্লাসটিকে View ক্লাস প্রসারিত করুন এবং context: Context । প্রস্তাবিত আমদানি গ্রহণ করুন.
import android.content.Context
import android.view.View

class MyCanvasView(context: Context) : View(context) {
}

ধাপ 3. MyCanvasView কে বিষয়বস্তু ভিউ হিসেবে সেট করুন

আপনি MyCanvasView এ কী আঁকবেন তা প্রদর্শন করতে, আপনাকে এটি MainActivity এর বিষয়বস্তু ভিউ হিসেবে সেট করতে হবে।

  1. strings.xml খুলুন এবং দৃশ্যের বিষয়বস্তুর বিবরণের জন্য ব্যবহার করার জন্য একটি স্ট্রিং সংজ্ঞায়িত করুন।
<string name="canvasContentDescription">Mini Paint is a simple line drawing app.
   Drag your fingers to draw. Rotate the phone to clear.</string>
  1. MainActivity.kt খুলুন
  2. onCreate() এ, setContentView(R.layout.activity_main) মুছে দিন।
  3. MyCanvasView এর একটি উদাহরণ তৈরি করুন।
val myCanvasView = MyCanvasView(this)
  1. এর নীচে, myCanvasView এর বিন্যাসের জন্য পূর্ণ স্ক্রীনের জন্য অনুরোধ করুন। myCanvasViewSYSTEM_UI_FLAG_FULLSCREEN পতাকা সেট করে এটি করুন। এইভাবে, দৃশ্যটি সম্পূর্ণরূপে স্ক্রিনটি পূরণ করে।
myCanvasView.systemUiVisibility = SYSTEM_UI_FLAG_FULLSCREEN
  1. একটি বিষয়বস্তু বিবরণ যোগ করুন.
myCanvasView.contentDescription = getString(R.string.canvasContentDescription)
  1. এর নীচে, বিষয়বস্তু দৃশ্যটিকে myCanvasView এ সেট করুন।
setContentView(myCanvasView)
  1. আপনার অ্যাপ চালান। আপনি একটি সম্পূর্ণ সাদা পর্দা দেখতে পাবেন, কারণ ক্যানভাসের কোন আকার নেই এবং আপনি এখনও কিছু আঁকেননি।

ধাপ 1. ওভাররাইড onSizeChanged()

onSizeChanged() পদ্ধতিটি Android সিস্টেম দ্বারা কল করা হয় যখনই একটি ভিউ আকার পরিবর্তন করে। যেহেতু ভিউটি কোন আকার ছাড়াই শুরু হয়, তাই ভিউটির onSizeChanged() পদ্ধতিটিও বলা হয় যখন Activity প্রথমে এটি তৈরি করে এবং ফুলিয়ে দেয়। এই onSizeChanged() পদ্ধতি তাই ভিউ এর ক্যানভাস তৈরি এবং সেট আপ করার জন্য আদর্শ জায়গা।

  1. MyCanvasView এ, ক্লাস লেভেলে, একটি ক্যানভাস এবং একটি বিটম্যাপের জন্য ভেরিয়েবল সংজ্ঞায়িত করুন। তাদের extraCanvas এবং extraBitmap বলুন। এইগুলি হল আপনার বিটম্যাপ এবং ক্যাশ করার জন্য ক্যানভাস যা আগে আঁকা হয়েছে।
private lateinit var extraCanvas: Canvas
private lateinit var extraBitmap: Bitmap
  1. ক্যানভাসের পটভূমির রঙের জন্য একটি শ্রেণি স্তরের পরিবর্তনশীল backgroundColor সংজ্ঞায়িত করুন এবং এটিকে আপনি আগে সংজ্ঞায়িত colorBackground শুরু করুন।
private val backgroundColor = ResourcesCompat.getColor(resources, R.color.colorBackground, null)
  1. MyCanvasView এ, onSizeChanged() পদ্ধতিটি ওভাররাইড করুন। এই কলব্যাক পদ্ধতিটিকে অ্যান্ড্রয়েড সিস্টেম দ্বারা পরিবর্তিত স্ক্রিনের মাত্রা সহ বলা হয়, অর্থাৎ, একটি নতুন প্রস্থ এবং উচ্চতা (তে পরিবর্তন করতে) এবং পুরানো প্রস্থ এবং উচ্চতা (থেকে পরিবর্তন করতে)।
override fun onSizeChanged(width: Int, height: Int, oldWidth: Int, oldHeight: Int) {
   super.onSizeChanged(width, height, oldWidth, oldHeight)
}
  1. onSizeChanged() ভিতরে, নতুন প্রস্থ এবং উচ্চতা সহ Bitmap একটি উদাহরণ তৈরি করুন, যা স্ক্রীনের আকার, এবং এটি extraBitmap এ বরাদ্দ করুন। তৃতীয় আর্গুমেন্ট হল বিটম্যাপ কালার কনফিগারেশনARGB_8888 প্রতিটি রঙ 4 বাইটে সঞ্চয় করে এবং সুপারিশ করা হয়।
extraBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
  1. extraBitmap থেকে একটি Canvas উদাহরণ তৈরি করুন এবং এটি extraCanvas এ বরাদ্দ করুন।
 extraCanvas = Canvas(extraBitmap)
  1. পটভূমির রঙ নির্দিষ্ট করুন যেখানে extraCanvas পূরণ করতে হবে।
extraCanvas.drawColor(backgroundColor)
  1. onSizeChanged() এর দিকে তাকিয়ে, প্রতিবার ফাংশনটি চালানোর সময় একটি নতুন বিটম্যাপ এবং ক্যানভাস তৈরি করা হয়। আপনার একটি নতুন বিটম্যাপ প্রয়োজন, কারণ আকার পরিবর্তন হয়েছে। যাইহোক, এটি একটি মেমরি লিক, চারপাশে পুরানো বিটম্যাপ রেখে। এটি ঠিক করতে, super কল করার ঠিক পরে এই কোডটি যোগ করে পরবর্তীটি তৈরি করার আগে extraBitmap পুনর্ব্যবহার করুন।
if (::extraBitmap.isInitialized) extraBitmap.recycle()

ধাপ 2. ওভাররাইড onDraw()

MyCanvasView জন্য সমস্ত অঙ্কনের কাজ onDraw() এ হয়।

শুরু করার জন্য, ক্যানভাস প্রদর্শন করুন, আপনি onSizeChanged() এ সেট করা ব্যাকগ্রাউন্ডের রঙ দিয়ে স্ক্রীনটি পূরণ করুন।

  1. onDraw() ওভাররাইড করুন এবং দৃশ্যের সাথে যুক্ত ক্যানভাসে ক্যাশে করা extraBitmap বিষয়বস্তু আঁকুন। drawBitmap() Canvas পদ্ধতি বিভিন্ন সংস্করণে আসে। এই কোডে, আপনি উপরের বাম কোণে বিটম্যাপ, x এবং y স্থানাঙ্ক (পিক্সেলে) এবং Paint জন্য null প্রদান করেন, কারণ আপনি এটি পরে সেট করবেন।
override fun onDraw(canvas: Canvas) {
   super.onDraw(canvas)
canvas.drawBitmap(extraBitmap, 0f, 0f, null)
}


লক্ষ্য করুন যে ক্যানভাসটি onDraw() এ পাস করা হয়েছে এবং বিটম্যাপ প্রদর্শনের জন্য সিস্টেম দ্বারা ব্যবহৃত হয়েছে তা আপনি onSizeChanged() পদ্ধতিতে তৈরি করেছেন এবং বিটম্যাপে আঁকার জন্য ব্যবহার করেছেন তার থেকে আলাদা।

  1. আপনার অ্যাপ চালান। আপনি নির্দিষ্ট ব্যাকগ্রাউন্ডের রঙ দিয়ে পুরো স্ক্রিনটি দেখতে পাবেন।

আঁকার জন্য, আপনার একটি Paint অবজেক্টের প্রয়োজন যা নির্দিষ্ট করে যে জিনিসগুলি আঁকার সময় কীভাবে স্টাইল করা হয়, এবং একটি Path যা আঁকা হচ্ছে তা নির্দিষ্ট করে।

ধাপ 1. একটি পেইন্ট অবজেক্ট শুরু করুন

  1. MyCanvasView.kt- এ, শীর্ষ ফাইল স্তরে, স্ট্রোকের প্রস্থের জন্য একটি ধ্রুবক সংজ্ঞায়িত করুন।
private const val STROKE_WIDTH = 12f // has to be float
  1. MyCanvasView এর শ্রেণী স্তরে, আঁকার জন্য রঙ ধরে রাখার জন্য একটি পরিবর্তনশীল drawColor সংজ্ঞায়িত করুন এবং আপনার পূর্বে সংজ্ঞায়িত colorPaint রিসোর্স দিয়ে শুরু করুন।
private val drawColor = ResourcesCompat.getColor(resources, R.color.colorPaint, null)
  1. শ্রেণী স্তরে, নীচে, একটি Paint অবজেক্টের জন্য একটি পরিবর্তনশীল paint যোগ করুন এবং এটিকে নিম্নরূপ শুরু করুন।
// Set up the paint with which to draw.
private val paint = Paint().apply {
   color = drawColor
   // Smooths out edges of what is drawn without affecting shape.
   isAntiAlias = true
   // Dithering affects how colors with higher-precision than the device are down-sampled.
   isDither = true
   style = Paint.Style.STROKE // default: FILL
   strokeJoin = Paint.Join.ROUND // default: MITER
   strokeCap = Paint.Cap.ROUND // default: BUTT
   strokeWidth = STROKE_WIDTH // default: Hairline-width (really thin)
}
  • paint color হল drawColor যা আপনি আগে সংজ্ঞায়িত করেছেন।
  • isAntiAlias প্রান্ত স্মুথিং প্রয়োগ করতে হবে কিনা তা নির্ধারণ করে। isAntiAlias true সেট করা, আকৃতিকে প্রভাবিত না করেই যা আঁকা হয়েছে তার প্রান্তগুলিকে মসৃণ করে।
  • isDither , যখন true , যন্ত্রের চেয়ে উচ্চ-নির্ভুলতা সহ রঙগুলিকে কীভাবে ডাউন-স্যাম্পল করা হয় তা প্রভাবিত করে। উদাহরণস্বরূপ, চিত্রের রঙের পরিসরকে 256 (বা তার চেয়ে কম) রঙে হ্রাস করার সবচেয়ে সাধারণ উপায় হল ডাইথারিং।
  • style একটি স্ট্রোকের জন্য পেইন্টিংয়ের ধরন সেট করে, যা মূলত একটি লাইন। Paint.Style সুনির্দিষ্ট করে যদি আঁকা আদিম জিনিসটি ভরা, স্ট্রোক করা বা উভয়ই (একই রঙে)। ডিফল্ট হল পেইন্ট প্রয়োগ করা বস্তুটি পূরণ করা। ("ভরাট" আকৃতির ভিতরের রঙ করে, যখন "স্ট্রোক" তার রূপরেখা অনুসরণ করে।)
  • Paint.Join এর strokeJoin নির্দিষ্ট করে কিভাবে রেখা এবং বক্ররেখার অংশগুলি একটি স্ট্রোক করা পথে যুক্ত হয়। ডিফল্ট হল MITER
  • strokeCap লাইনের শেষের আকৃতিকে ক্যাপ হিসাবে সেট করে। Paint.Cap নির্দিষ্ট করে কিভাবে স্ট্রোক করা লাইন এবং পাথের শুরু এবং শেষ। ডিফল্ট হল BUTT
  • strokeWidth পিক্সেলে স্ট্রোকের প্রস্থ নির্দিষ্ট করে। ডিফল্ট হল হেয়ারলাইন প্রস্থ, যা সত্যিই পাতলা, তাই এটি আপনার আগে সংজ্ঞায়িত STROKE_WIDTH ধ্রুবকটিতে সেট করা হয়েছে।

ধাপ 2. একটি পাথ অবজেক্ট শুরু করুন

Path হল ব্যবহারকারী যা আঁকছে তার পথ।

  1. MyCanvasView এ, একটি পরিবর্তনশীল path যোগ করুন এবং স্ক্রিনে ব্যবহারকারীর স্পর্শ অনুসরণ করার সময় যে পথটি আঁকা হচ্ছে সেটি সংরক্ষণ করতে একটি Path অবজেক্টের সাহায্যে এটি শুরু করুন। Path জন্য android.graphics.Path আমদানি করুন।
private var path = Path()

ধাপ 1. ডিসপ্লেতে গতিতে সাড়া দিন

ব্যবহারকারী যখনই ডিসপ্লে স্পর্শ করে তখন একটি ভিউতে onTouchEvent() পদ্ধতিটিকে বলা হয়।

  1. MyCanvasView এ, পাস করা event x এবং y স্থানাঙ্ক ক্যাশে করতে onTouchEvent() পদ্ধতিটি ওভাররাইড করুন। তারপর স্ক্রিনে টাচ ডাউন, স্ক্রিনে চলাফেরা এবং স্ক্রিনে টাচ রিলিজ করার জন্য মোশন ইভেন্টগুলি পরিচালনা করতে when এক্সপ্রেশন ব্যবহার করুন। এই পর্দায় একটি লাইন আঁকা জন্য আগ্রহের ঘটনা. প্রতিটি ইভেন্টের প্রকারের জন্য, একটি ইউটিলিটি পদ্ধতিতে কল করুন, যেমনটি নীচের কোডে দেখানো হয়েছে। স্পর্শ ইভেন্টের সম্পূর্ণ তালিকার জন্য MotionEvent ক্লাস ডকুমেন্টেশন দেখুন।
override fun onTouchEvent(event: MotionEvent): Boolean {
   motionTouchEventX = event.x
   motionTouchEventY = event.y

   when (event.action) {
       MotionEvent.ACTION_DOWN -> touchStart()
       MotionEvent.ACTION_MOVE -> touchMove()
       MotionEvent.ACTION_UP -> touchUp()
   }
   return true
}
  1. ক্লাস লেভেলে, বর্তমান টাচ ইভেন্টের ( MotionEvent স্থানাঙ্ক) x এবং y স্থানাঙ্ক ক্যাশ করার জন্য অনুপস্থিত motionTouchEventX এবং motionTouchEventY ভেরিয়েবল যোগ করুন। তাদের 0f এ আরম্ভ করুন।
private var motionTouchEventX = 0f
private var motionTouchEventY = 0f
  1. touchStart() , touchMove() এবং touchUp() এই তিনটি ফাংশনের জন্য স্টাব তৈরি করুন।
private fun touchStart() {}

private fun touchMove() {}

private fun touchUp() {}
  1. আপনার কোড তৈরি এবং চালানো উচিত, কিন্তু আপনি এখনও রঙিন পটভূমি থেকে ভিন্ন কিছু দেখতে পাবেন না।

ধাপ 2. টাচস্টার্ট বাস্তবায়ন করুন()

এই পদ্ধতি বলা হয় যখন ব্যবহারকারী প্রথম স্ক্রীন স্পর্শ করে।

  1. ক্লাস লেভেলে, সর্বশেষ x এবং y মান ক্যাশে করতে ভেরিয়েবল যোগ করুন। ব্যবহারকারী নড়াচড়া বন্ধ করে এবং তাদের স্পর্শ তুলে নেওয়ার পরে, এগুলি হল পরবর্তী পথের সূচনা বিন্দু (আঁকতে হবে লাইনের পরবর্তী অংশ)।
private var currentX = 0f
private var currentY = 0f
  1. touchStart() পদ্ধতিটি নিম্নরূপ প্রয়োগ করুন। path রিসেট করুন, টাচ ইভেন্টের xy স্থানাঙ্কে যান ( motionTouchEventX এবং motionTouchEventY ), এবং সেই মানটিতে currentX এবং currentY বরাদ্দ করুন।
private fun touchStart() {
   path.reset()
   path.moveTo(motionTouchEventX, motionTouchEventY)
   currentX = motionTouchEventX
   currentY = motionTouchEventY
}

ধাপ 3. touchMove() বাস্তবায়ন করুন

  1. ক্লাস লেভেলে, একটি touchTolerance ভেরিয়েবল যোগ করুন এবং ViewConfiguration.get(context).scaledTouchSlop এ সেট করুন।
private val touchTolerance = ViewConfiguration.get(context).scaledTouchSlop

একটি পথ ব্যবহার করে, প্রতিটি পিক্সেল আঁকতে হবে না এবং প্রতিবার ডিসপ্লে রিফ্রেশ করার জন্য অনুরোধ করুন। পরিবর্তে, আপনি অনেক ভাল পারফরম্যান্সের জন্য পয়েন্টগুলির মধ্যে একটি পথ প্রসারিত করতে পারেন (এবং করবেন)।

  • আঙুল সবে সরানো হলে, আঁকার প্রয়োজন নেই।
  • যদি আঙুল touchTolerance দূরত্বের চেয়ে কম সরে থাকে তবে আঁকবেন না।
  • scaledTouchSlop পিক্সেলে দূরত্ব ফেরত দেয় যা ব্যবহারকারী স্ক্রোল করছে বলে সিস্টেম মনে করার আগে একটি স্পর্শ ঘুরে যেতে পারে।
  1. touchMove() পদ্ধতি সংজ্ঞায়িত করুন। ভ্রমণের দূরত্ব গণনা করুন ( dx , dy ), দুটি বিন্দুর মধ্যে একটি বক্ররেখা তৈরি করুন এবং এটিকে path সংরক্ষণ করুন, চলমান currentX এবং currentY ট্যালি আপডেট করুন এবং path আঁকুন। তারপর invalidate() কল করুন আপডেট করা path সাথে পর্দার পুনরায় অঙ্কন করতে বাধ্য করতে।
private fun touchMove() {
   val dx = Math.abs(motionTouchEventX - currentX)
   val dy = Math.abs(motionTouchEventY - currentY)
   if (dx >= touchTolerance || dy >= touchTolerance) {
       // QuadTo() adds a quadratic bezier from the last point,
       // approaching control point (x1,y1), and ending at (x2,y2).
       path.quadTo(currentX, currentY, (motionTouchEventX + currentX) / 2, (motionTouchEventY + currentY) / 2)
       currentX = motionTouchEventX
       currentY = motionTouchEventY
       // Draw the path in the extra bitmap to cache it.
       extraCanvas.drawPath(path, paint)
   }
   invalidate()
}

এই পদ্ধতিটি আরও বিশদে:

  1. স্থানান্তরিত দূরত্ব গণনা করুন ( dx, dy )।
  2. যদি আন্দোলনটি স্পর্শ সহনশীলতার চেয়ে বেশি হয় তবে পথটিতে একটি অংশ যোগ করুন।
  3. এই সেগমেন্টের শেষ পয়েন্টে পরবর্তী সেগমেন্টের প্রারম্ভিক বিন্দু সেট করুন।
  4. quadTo() এর পরিবর্তে lineTo() ব্যবহার করে কোণ ছাড়া একটি মসৃণভাবে আঁকা লাইন তৈরি করুন। বেজিয়ার কার্ভস দেখুন।
  5. কল invalidate() থেকে (অবশেষে কল onDraw() এবং) ভিউটি পুনরায় আঁকুন।

ধাপ 4: টাচআপ প্রয়োগ করুন()

যখন ব্যবহারকারী তাদের স্পর্শ উত্তোলন করে, তখন যা প্রয়োজন তা হল পথটি পুনরায় সেট করা যাতে এটি আবার আঁকা না হয়। কিছুই আঁকা হয় না, তাই কোন অবৈধকরণ প্রয়োজন হয় না.

  1. touchUp() পদ্ধতি প্রয়োগ করুন।
private fun touchUp() {
   // Reset the path so it doesn't get drawn again.
   path.reset()
}
  1. আপনার কোড চালান এবং স্ক্রিনে আঁকতে আপনার আঙুল ব্যবহার করুন। লক্ষ্য করুন যে আপনি যদি ডিভাইসটি ঘোরান, স্ক্রীনটি সাফ হয়ে যায়, কারণ অঙ্কন অবস্থা সংরক্ষণ করা হয় না। এই নমুনা অ্যাপের জন্য, এটি ডিজাইনের মাধ্যমে, ব্যবহারকারীকে স্ক্রীন পরিষ্কার করার একটি সহজ উপায় দিতে।

ধাপ 5: স্কেচের চারপাশে একটি ফ্রেম আঁকুন

ব্যবহারকারী যখন স্ক্রিনে আঁকেন, আপনার অ্যাপটি পথ তৈরি করে এবং বিটম্যাপ extraBitmap সংরক্ষণ করে। onDraw() পদ্ধতি ভিউ এর ক্যানভাসে অতিরিক্ত বিটম্যাপ প্রদর্শন করে। আপনি onDraw() এ আরও অঙ্কন করতে পারেন। উদাহরণস্বরূপ, আপনি বিটম্যাপ আঁকার পরে আকার আঁকতে পারেন।

এই ধাপে আপনি ছবির প্রান্তের চারপাশে একটি ফ্রেম আঁকুন।

  1. MyCanvasView এ, frame নামক একটি ভেরিয়েবল যোগ করুন যা একটি Rect অবজেক্ট ধারণ করে।
private lateinit var frame: Rect
  1. onSizeChanged() এর শেষে একটি ইনসেট সংজ্ঞায়িত করুন এবং নতুন মাত্রা এবং ইনসেট ব্যবহার করে ফ্রেমের জন্য ব্যবহার করা হবে এমন Rect তৈরি করতে কোড যোগ করুন।
// Calculate a rectangular frame around the picture.
val inset = 40
frame = Rect(inset, inset, width - inset, height - inset)
  1. onDraw() এ, বিটম্যাপ আঁকার পর একটি আয়তক্ষেত্র আঁকুন।
// Draw a frame around the canvas.
canvas.drawRect(frame, paint)
  1. আপনার অ্যাপ চালান। ফ্রেম লক্ষ্য করুন।

টাস্ক (ঐচ্ছিক): একটি পাথে ডেটা সংরক্ষণ করা

বর্তমান অ্যাপে, অঙ্কনের তথ্য একটি বিটম্যাপে সংরক্ষণ করা হয়। যদিও এটি একটি ভাল সমাধান, এটি অঙ্কন সংক্রান্ত তথ্য সংরক্ষণের একমাত্র সম্ভাব্য উপায় নয়। আপনি কীভাবে আপনার অঙ্কন ইতিহাস সংরক্ষণ করবেন তা অ্যাপ এবং আপনার বিভিন্ন প্রয়োজনীয়তার উপর নির্ভর করে। উদাহরণস্বরূপ, আপনি যদি আকৃতি আঁকছেন, আপনি তাদের অবস্থান এবং মাত্রা সহ আকারগুলির একটি তালিকা সংরক্ষণ করতে পারেন। MiniPaint অ্যাপের জন্য, আপনি পথটিকে Path হিসেবে সংরক্ষণ করতে পারেন। আপনি যদি এটি চেষ্টা করতে চান তবে কীভাবে এটি করবেন তার সাধারণ রূপরেখা নীচে দেওয়া হল।

  1. MyCanvasView এ, extraCanvas এবং extraBitmap জন্য সমস্ত কোড মুছে ফেলুন।
  2. এখন পর্যন্ত পথের জন্য ভেরিয়েবল যোগ করুন এবং বর্তমানে যে পথটি আঁকা হচ্ছে।
// Path representing the drawing so far
private val drawing = Path()

// Path representing what's currently being drawn
private val curPath = Path()
  1. onDraw() এ, বিটম্যাপ আঁকার পরিবর্তে, সঞ্চিত এবং বর্তমান পাথগুলি আঁকুন।
// Draw the drawing so far
canvas.drawPath(drawing, paint)
// Draw any current squiggle
canvas.drawPath(curPath, paint)
// Draw a frame around the canvas
canvas.drawRect(frame, paint)
  1. touchUp() এ, আগের পাথে বর্তমান পাথ যোগ করুন এবং বর্তমান পাথ রিসেট করুন।
// Add the current path to the drawing so far
drawing.addPath(curPath)
// Rewind the current path for the next touch
curPath.reset()
  1. আপনার অ্যাপটি চালান, এবং হ্যাঁ, কোন পার্থক্য থাকা উচিত নয়।

সমাপ্ত কোডল্যাবের জন্য কোডটি ডাউনলোড করুন..

$  git clone https://github.com/googlecodelabs/android-kotlin-drawing-canvas


বিকল্পভাবে আপনি একটি জিপ ফাইল হিসাবে সংগ্রহস্থলটি ডাউনলোড করতে পারেন, এটি আনজিপ করতে পারেন এবং এটি অ্যান্ড্রয়েড স্টুডিওতে খুলতে পারেন।

জিপ ডাউনলোড করুন

  • একটি Canvas একটি 2D অঙ্কন পৃষ্ঠ যা অঙ্কন জন্য পদ্ধতি প্রদান করে।
  • Canvas একটি View ইনস্ট্যান্সের সাথে যুক্ত হতে পারে যা এটি প্রদর্শন করে।
  • Paint অবজেক্ট কীভাবে জ্যামিতি (যেমন রেখা, আয়তক্ষেত্র, ডিম্বাকৃতি এবং পাথ) এবং পাঠ্য আঁকতে হয় সে সম্পর্কে শৈলী এবং রঙের তথ্য ধারণ করে।
  • একটি ক্যানভাসের সাথে কাজ করার জন্য একটি সাধারণ প্যাটার্ন হল একটি কাস্টম ভিউ তৈরি করা এবং onDraw() এবং onSizeChanged() পদ্ধতিগুলিকে ওভাররাইড করা।
  • ব্যবহারকারীর স্পর্শ ক্যাপচার করার জন্য onTouchEvent() পদ্ধতিটি ওভাররাইড করুন এবং জিনিসগুলি অঙ্কন করে তাদের প্রতিক্রিয়া জানান৷
  • সময়ের সাথে পরিবর্তিত অঙ্কনগুলির জন্য তথ্য ক্যাশে করার জন্য আপনি একটি অতিরিক্ত বিটম্যাপ ব্যবহার করতে পারেন। বিকল্পভাবে, আপনি আকার বা পথ সংরক্ষণ করতে পারেন।

উদাসীনতা কোর্স:

অ্যান্ড্রয়েড বিকাশকারী ডকুমেন্টেশন:

এই বিভাগে একজন প্রশিক্ষকের নেতৃত্বে একটি কোর্সের অংশ হিসাবে এই কোডল্যাবের মাধ্যমে কাজ করা শিক্ষার্থীদের জন্য সম্ভাব্য হোমওয়ার্ক অ্যাসাইনমেন্ট তালিকাভুক্ত করা হয়েছে। নিম্নলিখিতগুলি করা প্রশিক্ষকের উপর নির্ভর করে:

  • প্রয়োজনে হোমওয়ার্ক বরাদ্দ করুন।
  • শিক্ষার্থীদের সাথে যোগাযোগ করুন কিভাবে হোমওয়ার্ক অ্যাসাইনমেন্ট জমা দিতে হয়।
  • হোমওয়ার্ক অ্যাসাইনমেন্ট গ্রেড.

প্রশিক্ষকরা এই পরামর্শগুলি যতটা কম বা যতটা চান ততটা ব্যবহার করতে পারেন, এবং তাদের উপযুক্ত মনে করে অন্য কোনও হোমওয়ার্ক বরাদ্দ করতে নির্দ্বিধায় করা উচিত।

আপনি যদি নিজে থেকে এই কোডল্যাবের মাধ্যমে কাজ করে থাকেন, তাহলে আপনার জ্ঞান পরীক্ষা করার জন্য এই হোমওয়ার্ক অ্যাসাইনমেন্টগুলিকে নির্দ্বিধায় ব্যবহার করুন৷

এই প্রশ্নগুলোর উত্তর দাও

প্রশ্ন 1

Canvas সাথে কাজ করার জন্য নিম্নলিখিত উপাদানগুলির মধ্যে কোনটি প্রয়োজন? প্রযোজ্য সব নির্বাচন করুন.

Bitmap

Paint

Path

View

প্রশ্ন 2

একটি কল invalidate() কি করে (সাধারণ ভাষায়)?

▢ আপনার অ্যাপটিকে অবৈধ করে এবং পুনরায় চালু করে।

▢ বিটম্যাপ থেকে অঙ্কন মুছে দেয়।

▢ নির্দেশ করে যে পূর্ববর্তী কোড চালানো উচিত নয়।

▢ সিস্টেমকে বলে যে এটি পর্দাটি পুনরায় আঁকতে হবে৷

প্রশ্ন 3

Canvas , Bitmap এবং Paint অবজেক্টের কাজ কী?

▢ 2D অঙ্কন পৃষ্ঠ, স্ক্রিনে প্রদর্শিত বিটম্যাপ, অঙ্কনের জন্য স্টাইলিং তথ্য।

▢ 3D অঙ্কন পৃষ্ঠ, পাথ ক্যাশে করার জন্য বিটম্যাপ, অঙ্কনের জন্য স্টাইলিং তথ্য।

▢ 2D অঙ্কন পৃষ্ঠ, স্ক্রিনে প্রদর্শিত বিটম্যাপ, দৃশ্যের জন্য স্টাইল।

▢ অঙ্কন তথ্যের জন্য ক্যাশে, আঁকার জন্য বিটম্যাপ, অঙ্কনের জন্য স্টাইলিং তথ্য।

এই কোর্সে অন্যান্য কোডল্যাবগুলির লিঙ্কগুলির জন্য, কোটলিন কোডল্যাবগুলির ল্যান্ডিং পৃষ্ঠাতে উন্নত Android দেখুন৷