রচনায় গ্রাফিক্স

অনেক অ্যাপ্লিকেশানের স্ক্রিনে যা আঁকা হয়েছে তা সঠিকভাবে নিয়ন্ত্রণ করতে সক্ষম হওয়া দরকার। এটি ঠিক সঠিক জায়গায় পর্দায় একটি বাক্স বা একটি বৃত্ত রাখার মতো ছোট হতে পারে, বা এটি বিভিন্ন শৈলীতে গ্রাফিক উপাদানগুলির একটি বিস্তৃত বিন্যাস হতে পারে।

মডিফায়ার এবং 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
    )
}

একটি সাদা পটভূমিতে আঁকা গোলাপী আয়তক্ষেত্র যা পর্দার এক চতুর্থাংশ জায়গা নেয়
চিত্র 1 । কম্পোজে ক্যানভাস ব্যবহার করে আয়তক্ষেত্র আঁকা।

বিভিন্ন অঙ্কন মডিফায়ার সম্পর্কে আরও জানতে, গ্রাফিক্স মডিফায়ার ডকুমেন্টেশন দেখুন।

সমন্বয় ব্যবস্থা

স্ক্রিনে কিছু আঁকতে, আপনাকে অফসেট ( x এবং y ) এবং আপনার আইটেমের আকার জানতে হবে। DrawScope এ অনেক ড্র পদ্ধতির সাথে, অবস্থান এবং আকার ডিফল্ট প্যারামিটার মান দ্বারা প্রদান করা হয়। ডিফল্ট প্যারামিটারগুলি সাধারণত আইটেমটিকে ক্যানভাসে [0, 0] পয়েন্টে অবস্থান করে এবং একটি ডিফল্ট size প্রদান করে যা পুরো অঙ্কন এলাকাটি পূরণ করে, যেমন উপরের উদাহরণে - আপনি দেখতে পাচ্ছেন আয়তক্ষেত্রটি উপরের বাম দিকে অবস্থিত। আপনার আইটেমের আকার এবং অবস্থান সামঞ্জস্য করতে, আপনাকে কম্পোজের সমন্বয় সিস্টেমটি বুঝতে হবে।

স্থানাঙ্ক সিস্টেমের উৎপত্তি ( [0,0] ) অঙ্কন এলাকার উপরের বামদিকের পিক্সেলের দিকে। ডানদিকে সরে গেলে x বৃদ্ধি পায় এবং নিচের দিকে অগ্রসর হলে y বৃদ্ধি পায়।

শীর্ষ বাম [0, 0] এবং নীচের ডানদিকে [প্রস্থ, উচ্চতা] দেখানো স্থানাঙ্ক সিস্টেম দেখানো একটি গ্রিড
চিত্র 2 । অঙ্কন স্থানাঙ্ক সিস্টেম / অঙ্কন গ্রিড।

উদাহরণস্বরূপ, আপনি যদি ক্যানভাস এলাকার উপরের-ডান কোণ থেকে নীচে-বাম কোণে একটি তির্যক রেখা আঁকতে চান, তাহলে আপনি 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())
    }
}

একটি বৃত্ত অ-সমভাবে মাপানো হয়েছে
চিত্র 3 । ক্যানভাসে একটি বৃত্তে একটি স্কেল অপারেশন প্রয়োগ করা হচ্ছে।

অনুবাদ করুন

আপনার অঙ্কন ক্রিয়াকলাপগুলিকে উপরে, নীচে, বাম বা ডানে সরাতে DrawScope.translate() ব্যবহার করুন। উদাহরণস্বরূপ, নিম্নলিখিত কোডটি 100 পিক্সেল অঙ্কনটিকে ডানদিকে এবং 300 পিক্সেল উপরে নিয়ে যায়:

Canvas(modifier = Modifier.fillMaxSize()) {
    translate(left = 100f, top = -300f) {
        drawCircle(Color.Blue, radius = 200.dp.toPx())
    }
}

একটি বৃত্ত যা কেন্দ্র থেকে সরে গেছে
চিত্র 4 । ক্যানভাসে একটি বৃত্তে একটি অনুবাদ অপারেশন প্রয়োগ করা হচ্ছে।

ঘোরান

একটি পিভট পয়েন্টের চারপাশে আপনার অঙ্কন ক্রিয়াকলাপ ঘোরাতে 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
        )
    }
}

একটি আয়তক্ষেত্র সহ একটি ফোন স্ক্রিনের কেন্দ্রে 45 ডিগ্রী ঘোরে
চিত্র 5 । আমরা বর্তমান অঙ্কন সুযোগে একটি ঘূর্ণন প্রয়োগ করতে rotate() ব্যবহার করি, যা আয়তক্ষেত্রটিকে 45 ডিগ্রি ঘোরায়।

ইনসেট

DrawScope.inset() ব্যবহার করুন বর্তমান DrawScope এর ডিফল্ট প্যারামিটার সামঞ্জস্য করতে, অঙ্কনের সীমানা পরিবর্তন করতে এবং সেই অনুযায়ী অঙ্কনগুলি অনুবাদ করতে:

Canvas(modifier = Modifier.fillMaxSize()) {
    val canvasQuadrantSize = size / 2F
    inset(horizontal = 50f, vertical = 30f) {
        drawRect(color = Color.Green, size = canvasQuadrantSize)
    }
}

এই কোডটি কার্যকরভাবে অঙ্কন কমান্ডগুলিতে প্যাডিং যুক্ত করে:

একটি আয়তক্ষেত্র যা এর চারপাশে প্যাড করা হয়েছে
চিত্র 6 । অঙ্কন কমান্ডে একটি ইনসেট প্রয়োগ করা হচ্ছে।

একাধিক রূপান্তর

আপনার অঙ্কনে একাধিক রূপান্তর প্রয়োগ করতে, 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
        )
    }
}

একটি ঘূর্ণিত আয়তক্ষেত্র সহ একটি ফোন স্ক্রিনের পাশে স্থানান্তরিত হয়েছে৷
চিত্র 7 । একটি ঘূর্ণন এবং অনুবাদ উভয়ই প্রয়োগ করতে withTransform ব্যবহার করুন, আয়তক্ষেত্রটি ঘোরান এবং এটিকে বাম দিকে সরান৷

সাধারণ অঙ্কন অপারেশন

পাঠ্য আঁকুন

কম্পোজে টেক্সট আঁকতে, আপনি সাধারণত Text কম্পোজেবল ব্যবহার করতে পারেন। যাইহোক, যদি আপনি একটি DrawScope এ থাকেন বা আপনি কাস্টমাইজেশনের মাধ্যমে আপনার লেখা ম্যানুয়ালি আঁকতে চান, তাহলে আপনি DrawScope.drawText() পদ্ধতি ব্যবহার করতে পারেন।

টেক্সট আঁকতে, rememberTextMeasurer ব্যবহার করে একটি TextMeasurer তৈরি করুন এবং মেজারের সাথে drawText কল করুন:

val textMeasurer = rememberTextMeasurer()

Canvas(modifier = Modifier.fillMaxSize()) {
    drawText(textMeasurer, "Hello")
}

ক্যানভাসে আঁকা হ্যালো দেখানো হচ্ছে
চিত্র 8 । ক্যানভাসে পাঠ্য অঙ্কন।

পাঠ্য পরিমাপ করুন

অঙ্কন পাঠ অন্যান্য অঙ্কন কমান্ড থেকে একটু ভিন্নভাবে কাজ করে। সাধারণত, আপনি আকৃতি/ছবি আঁকতে আকার (প্রস্থ এবং উচ্চতা) অঙ্কন কমান্ড দেন। পাঠ্যের সাথে, কয়েকটি পরামিতি রয়েছে যা রেন্ডার করা পাঠ্যের আকার নিয়ন্ত্রণ করে, যেমন ফন্টের আকার, ফন্ট, লিগ্যাচার এবং অক্ষর ব্যবধান।

কম্পোজের মাধ্যমে, উপরের বিষয়গুলির উপর নির্ভর করে, আপনি পাঠ্যের পরিমাপ করা আকারে অ্যাক্সেস পেতে একটি 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()
)

এই কোড স্নিপেটটি পাঠ্যে একটি গোলাপী পটভূমি তৈরি করে:

মাল্টি-লাইন টেক্সট একটি পটভূমি আয়তক্ষেত্র সহ সম্পূর্ণ এলাকার ⅔ আকার নেয়
চিত্র 9 । মাল্টি-লাইন টেক্সট একটি পটভূমি আয়তক্ষেত্র সহ সম্পূর্ণ এলাকার ⅔ আকার নেয়।

সীমাবদ্ধতা, হরফের আকার, বা মাপা আকারকে প্রভাবিত করে এমন কোনো বৈশিষ্ট্য সামঞ্জস্য করার ফলে একটি নতুন আকার রিপোর্ট করা হয়। আপনি 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()
)

পাঠ্যটি এখন সীমাবদ্ধতায় আঁকা হয়েছে শেষে একটি উপবৃত্ত সহ:

গোলাপী পটভূমিতে আঁকা টেক্সট, উপবৃত্তাকার সাথে টেক্সট কেটে গেছে।
চিত্র 10TextOverflow.Ellipsis টেক্সট পরিমাপের নির্দিষ্ট সীমাবদ্ধতা সহ।

ছবি আঁকা

DrawScope দিয়ে একটি ImageBitmap আঁকতে, ImageBitmap.imageResource() ব্যবহার করে ছবিটি লোড করুন এবং তারপর drawImage কল করুন:

val dogImage = ImageBitmap.imageResource(id = R.drawable.dog)

Canvas(modifier = Modifier.fillMaxSize(), onDraw = {
    drawImage(dogImage)
})

ক্যানভাসে আঁকা একটি কুকুরের ছবি
চিত্র 11 । ক্যানভাসে একটি ImageBitmap আঁকা।

মৌলিক আকার আঁকুন

DrawScope এ অনেক শেপ ড্রয়িং ফাংশন আছে। একটি আকৃতি আঁকতে, পূর্বনির্ধারিত ড্র ফাংশনগুলির একটি ব্যবহার করুন, যেমন drawCircle :

val purpleColor = Color(0xFFBA68C8)
Canvas(
    modifier = Modifier
        .fillMaxSize()
        .padding(16.dp),
    onDraw = {
        drawCircle(purpleColor)
    }
)

API

আউটপুট

drawCircle()

বৃত্ত আঁকা

drawRect()

রেক্ট আঁকা

drawRoundedRect()

বৃত্তাকার রেক্ট আঁকা

drawLine()

লাইন আঁকা

drawOval()

ডিম্বাকৃতি আঁকা

drawArc()

চাপ আঁকা

drawPoints()

পয়েন্ট আঁকা

পথ আঁকুন

একটি পথ হল গাণিতিক নির্দেশাবলীর একটি সিরিজ যার ফলস্বরূপ একটি অঙ্কন একবার কার্যকর করা হয়। 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()
)

কম্পোজে আঁকা একটি উলটো-ডাউন বেগুনি পাথ ত্রিভুজ
চিত্র 12 । রচনায় একটি Path তৈরি এবং অঙ্কন করা।

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()
)

একটি ডিম্বাকৃতি কালো আকৃতির পূর্ণ আকার গ্রহণ করা যায়
চিত্র 13Drawable আঁকতে ক্যানভাস অ্যাক্সেস করা হচ্ছে।

আরও জানুন

রচনায় অঙ্কন সম্পর্কে আরও তথ্যের জন্য, নিম্নলিখিত সংস্থানগুলি দেখুন:

{% শব্দার্থে %} {% endverbatim %} {% শব্দার্থে %} {% endverbatim %}