कम्पोज़ में ग्राफ़िक्स

कई ऐप्लिकेशन को यह ठीक से कंट्रोल करने की ज़रूरत होती है कि पेज पर क्या जानकारी दिखाई जाए स्क्रीन. यह स्क्रीन पर बॉक्स या गोला रखने जितना छोटा हो सकता है सही जगह पर दिखाई दे सकती है या हो सकता है कि उस पर ग्राफ़िक कई अलग-अलग स्टाइल के एलिमेंट होते हैं.

मॉडिफ़ायर और DrawScope के साथ बेसिक ड्रॉइंग

लिखें में किसी चीज़ को कस्टम बनाने का मुख्य तरीका मॉडिफ़ायर का इस्तेमाल करना है, जैसे कि Modifier.drawWithContent Modifier.drawBehind, और Modifier.drawWithCache.

उदाहरण के लिए, अपने कंपोज़ेबल के पीछे कुछ ड्रॉ करने के लिए, ड्रॉइंग वाले निर्देशों को एक्ज़ीक्यूट करने के लिए, drawBehind मॉडिफ़ायर:

Spacer(
    modifier = Modifier
        .fillMaxSize()
        .drawBehind {
            // this = DrawScope
        }
)

अगर आपको सिर्फ़ एक कंपोज़ेबल की ज़रूरत है, तो Canvas कंपोज़ेबल. Canvas कंपोज़ेबल Modifier.drawBehind के आस-पास सुविधाजनक रैपर. आपने Canvas को आपका लेआउट ठीक वैसा ही है जैसा आप किसी अन्य Compose के यूज़र इंटरफ़ेस (यूआई) एलिमेंट के साथ करते हैं. इस Canvas, एलिमेंट को उनकी स्टाइल पर पूरा कंट्रोल करके, एलिमेंट बनाए जा सकते हैं स्थान.

सभी ड्रॉइंग मॉडिफ़ायर, DrawScope को दिखाता है, जो एक स्कोप वाला ड्रॉइंग एनवायरमेंट होता है जो अपनी स्थिति बनाए रखे. इससे आपको ग्राफ़िकल एलिमेंट शामिल हैं. DrawScope में कई काम के फ़ील्ड मिलते हैं, जैसे कि size, एक Size ऑब्जेक्ट, जो DrawScope के मौजूदा डाइमेंशन के बारे में बताता है.

कुछ ड्रॉ करने के लिए, DrawScope पर ड्रॉ करने के कई फ़ंक्शन में से किसी एक का इस्तेमाल किया जा सकता है. इसके लिए उदाहरण के लिए, नीचे दिया गया कोड स्क्रीन:

Canvas(modifier = Modifier.fillMaxSize()) {
    val canvasQuadrantSize = size / 2F
    drawRect(
        color = Color.Magenta,
        size = canvasQuadrantSize
    )
}

सफ़ेद बैकग्राउंड पर बना गुलाबी रेक्टैंगल, जो स्क्रीन का एक चौथाई हिस्सा भर लेता है
पहली इमेज. Compose में कैनवस का इस्तेमाल करके बनाया गया रेक्टैंगल.

अलग-अलग ड्रॉइंग मॉडिफ़ायर के बारे में ज़्यादा जानने के लिए, ग्राफ़िक्स मॉडिफ़ायर देखें दस्तावेज़.

कोऑर्डिनेट सिस्टम

स्क्रीन पर कुछ बनाने के लिए, आपको ऑफ़सेट (x और y) और आपका आइटम. DrawScope पर ड्रॉ करने के कई तरीकों से, पोज़िशन और साइज़ पैरामीटर की डिफ़ॉल्ट वैल्यू से मिलती हैं. आम तौर पर, डिफ़ॉल्ट पैरामीटर आइटम को कैनवस पर [0, 0] पॉइंट पर रखें और डिफ़ॉल्ट साइज़ सेट करें पूरे ड्रॉइंग एरिया को भरने वाला size है, जैसा कि ऊपर दिए गए उदाहरण में दिखाया गया है - आपको दिखेगा रेक्टैंगल सबसे ऊपर बाईं ओर मौजूद है. इमेज का साइज़ और पोज़िशन अडजस्ट करने के लिए आपके आइटम के लिए, आपको Compose में निर्देशांक सिस्टम को समझना होगा.

निर्देशांक सिस्टम ([0,0]) का मूल बिंदु ड्रॉइंग एरिया. x के दाएँ चलने पर बढ़ता है और y के मूव होने पर वह बढ़ता है नीचे की ओर.

निर्देशांक सिस्टम को दिखाने वाला ग्रिड, जो सबसे ऊपर बाईं ओर [0, 0] और सबसे नीचे दाईं ओर [चौड़ाई, ऊंचाई] दिखा रहा है
दूसरी इमेज. ड्रॉइंग कोऑर्डिनेट सिस्टम / ड्रॉइंग ग्रिड.

उदाहरण के लिए, यदि आप इसके शीर्ष-दाएं कोने से एक विकर्ण रेखा खींचना चाहते हैं में नीचे बाएं कोने में कैनवस क्षेत्र तक ले जाएं, तो आप 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(), उनसे जुड़ी Lambda फ़ंक्शन में सभी ड्रॉइंग ऑपरेशन पर लागू होती हैं. इसके लिए उदाहरण के लिए, नीचे दिया गया कोड 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
        )
    }
}

एक फ़ोन, जिसकी स्क्रीन के बीच में आपको 45 डिग्री घुमाया गया है
पांचवीं इमेज. हम मौजूदा ड्रॉइंग स्कोप पर रोटेशन लागू करने के लिए rotate() का इस्तेमाल करते हैं. यह रेक्टैंगल को 45 डिग्री घुमाता है.

इनसेट

मौजूदा के डिफ़ॉल्ट पैरामीटर में बदलाव करने के लिए, 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() ज़्यादा बेहतर तरीके से काम करता है ट्रांसफ़ॉर्मेशन ऐक्शन होता है, क्योंकि सभी ट्रांसफ़ॉर्मेशन ऐक्शन एक साथ एक कार्रवाई के बजाय, 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()
)

यह कोड स्निपेट, टेक्स्ट पर गुलाबी बैकग्राउंड बनाता है:

कई लाइनों वाला टेक्स्ट, जो पूरे हिस्से का 2⁄3 साइज़ ले रहा है. इसमें एक रेक्टैंगल है
नौवीं इमेज. कई लाइनों वाला टेक्स्ट, जो पूरे हिस्से का 2⁄3 साइज़ ले रहा है. इसमें एक बैकग्राउंड रेक्टैंगल है.

कंस्ट्रेंट, फ़ॉन्ट साइज़ या ऐसी किसी भी प्रॉपर्टी में बदलाव करना जो मेज़र किए गए साइज़ पर असर डालती हो को एक नए आकार में रिपोर्ट किया जाता है. width, दोनों के लिए एक तय साइज़ सेट किया जा सकता है और height, फिर टेक्स्ट सेट TextOverflow के बाद दिखता है. इसके लिए उदाहरण के लिए, नीचे दिया गया कोड टेक्स्ट को ऊंचाई के 1⁄3 और चौड़ाई के 1⁄3 में रेंडर करता है और 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()
)

टेक्स्ट को अब कंस्ट्रेंट में खींच लिया गया है और इसके आखिर में एलिप्सिस दिखेगा:

गुलाबी बैकग्राउंड पर बनाया गया टेक्स्ट, जिसमें टेक्स्ट को कटा हुआ इलिप्सिस दिखाया गया है.
10वीं इमेज. TextOverflow.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)
    }
)

एपीआई

आउटपुट

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

Compose पर बना बैंगनी रंग के पाथ का उलटा त्रिभुज
12वीं इमेज. Compose में Path बनाना और ड्रॉइंग करना.

Canvas ऑब्जेक्ट ऐक्सेस किया जा रहा है

DrawScope से, आपके पास Canvas ऑब्जेक्ट का सीधे तौर पर ऐक्सेस नहीं होता है. Google Analytics 4 पर माइग्रेट करने के लिए, पाने के लिए DrawScope.drawIntoCanvas() Canvas ऑब्जेक्ट का ही ऐक्सेस दें, ताकि आप फ़ंक्शन कॉल कर सकें.

उदाहरण के लिए, अगर आपके पास एक कस्टम 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()
)

काले रंग का अंडाकार शेपड्रॉबल, जिसका साइज़ बड़ा हो रहा है
13वीं इमेज. Drawable बनाने के लिए कैनवस ऐक्सेस किया जा रहा है.

ज़्यादा जानें

Compose में ड्रॉइंग करने की सुविधा के बारे में ज़्यादा जानकारी पाने के लिए, इन पर देखें संसाधन:

  • ग्राफ़िक्स मॉडिफ़ायर - इसमें अलग-अलग तरह की ड्रॉइंग के बारे में जानकारी होती है मॉडिफ़ायर हैं.
  • ब्रश - अपने वीडियो की पेंटिंग को पसंद के मुताबिक बनाने का तरीका जानें.
  • Compose में कस्टम लेआउट और ग्राफ़िक - Android Dev Summit 2022 - Compose में लेआउट की मदद से पसंद के मुताबिक यूज़र इंटरफ़ेस (यूआई) बनाने का तरीका जानें और ग्राफ़िक्स.
  • JetLagged सैंपल - सैंपल लिखें, ताकि ड्रॉ करने का तरीका बताया जा सके पसंद के मुताबिक बनाया गया ग्राफ़.
{% endverba नया %} {% verbatim %}