بسیاری از برنامهها باید بتوانند دقیقاً آنچه را که روی صفحه نمایش داده میشود کنترل کنند. این کنترل میتواند به کوچکی قرار دادن یک کادر یا دایره روی صفحه در جای مناسب باشد، یا میتواند چیدمان دقیقی از عناصر گرافیکی در سبکهای مختلف باشد.
طراحی اولیه با اصلاح کننده ها و DrawScope
روش اصلی برای رسم چیزی سفارشی در Compose استفاده از اصلاحکنندههایی مانند 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 ) }

برای کسب اطلاعات بیشتر در مورد اصلاحکنندههای مختلف ترسیم، به مستندات اصلاحکنندههای گرافیکی مراجعه کنید.
سیستم مختصات
برای رسم چیزی روی صفحه، باید آفست ( x و y ) و اندازه آیتم خود را بدانید. در بسیاری از متدهای رسم در DrawScope ، موقعیت و اندازه توسط مقادیر پارامتر پیشفرض ارائه میشوند. پارامترهای پیشفرض معمولاً آیتم را در نقطه [0, 0] روی بوم قرار میدهند و size پیشفرضی را ارائه میدهند که کل ناحیه رسم را پر میکند، همانطور که در مثال بالا میبینید - میتوانید ببینید که مستطیل در بالا سمت چپ قرار گرفته است. برای تنظیم اندازه و موقعیت آیتم خود، باید سیستم مختصات را در Compose درک کنید.
مبدا سیستم مختصات ( [0,0] ) در بالاترین و سمت چپترین پیکسل در ناحیه ترسیم قرار دارد. x با حرکت به سمت راست و y با حرکت به سمت پایین افزایش مییابد.
![یک شبکه که سیستم مختصات بالا سمت چپ [0، 0] و پایین سمت راست [عرض، ارتفاع] را نشان میدهد](https://developer.android.google.cn/static/develop/ui/compose/images/graphics/introduction/compose_coordinate_system_drawing.png?authuser=0&hl=fa)
برای مثال، اگر میخواهید یک خط مورب از گوشه بالا سمت راست ناحیه بوم به گوشه پایین سمت چپ رسم کنید، میتوانید از تابع 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() برای جابجایی عملیات ترسیم خود به بالا، پایین، چپ یا راست استفاده کنید. برای مثال، کد زیر ترسیم را ۱۰۰ پیکسل به سمت راست و ۳۰۰ پیکسل به بالا منتقل میکند:
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.inset() برای تنظیم پارامترهای پیشفرض DrawScope فعلی، تغییر مرزهای ترسیم و انتقال ترسیمات بر اساس آن استفاده کنید:
Canvas(modifier = Modifier.fillMaxSize()) { val canvasQuadrantSize = size / 2F inset(horizontal = 50f, vertical = 30f) { drawRect(color = Color.Green, size = canvasQuadrantSize) } }
این کد به طور موثری به دستورات ترسیم، فاصلهگذاری (padding) اضافه میکند:

تبدیلهای چندگانه
برای اعمال چندین تبدیل به ترسیمات خود، از تابع 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 composable استفاده کنید. با این حال، اگر در DrawScope هستید یا میخواهید متن خود را به صورت دستی با قابلیت شخصیسازی رسم کنید، میتوانید از متد DrawScope.drawText() استفاده کنید.
برای رسم متن، با استفاده از rememberTextMeasurer یک TextMeasurer ایجاد کنید و drawText با measurer فراخوانی کنید:
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 . حذف با محدودیتهای ثابت در اندازهگیری متن.تصویر را رسم کنید
برای رسم یک ImageBitmap با DrawScope ، تصویر را با استفاده از ImageBitmap.imageResource() بارگذاری کنید و سپس drawImage فراخوانی کنید:
val dogImage = ImageBitmap.imageResource(id = R.drawable.dog) Canvas(modifier = Modifier.fillMaxSize(), onDraw = { drawImage(dogImage) })

ImageBitmap روی Canvas.رسم اشکال اولیه
توابع رسم شکل زیادی در DrawScope وجود دارد. برای رسم یک شکل، از یکی از توابع رسم از پیش تعریف شده، مانند drawCircle ، استفاده کنید:
val purpleColor = Color(0xFFBA68C8) Canvas( modifier = Modifier .fillMaxSize() .padding(16.dp), onDraw = { drawCircle(purpleColor) } )
رابط برنامهنویسی کاربردی | خروجی |
![]() | |
![]() | |
![]() | |
![]() | |
![]() | |
![]() | |
![]() |
رسم مسیر
یک مسیر مجموعهای از دستورالعملهای ریاضی است که پس از اجرا، منجر به ترسیم میشود. 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 در Compose. دسترسی به شیء Canvas
با DrawScope ، شما دسترسی مستقیم به شیء Canvas ندارید. میتوانید از 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() )

Drawable .بیشتر بدانید
برای اطلاعات بیشتر در مورد طراحی در Compose، به منابع زیر نگاهی بیندازید:
- اصلاحکنندههای گرافیکی - با انواع مختلف اصلاحکنندههای ترسیم آشنا شوید.
- قلممو - یاد بگیرید که چگونه نقاشی محتوای خود را سفارشی کنید.
- طرحبندیها و گرافیکهای سفارشی در Compose - اجلاس توسعهدهندگان اندروید ۲۰۲۲ - یاد بگیرید که چگونه با استفاده از طرحبندیها و گرافیکها، یک رابط کاربری سفارشی در Compose بسازید.
- نمونه JetLagged - نمونه Compose که نحوه رسم نمودار سفارشی را نشان میدهد.
برای شما توصیه میشود
- توجه: متن لینک زمانی نمایش داده میشود که جاوا اسکریپت غیرفعال باشد.
- اصلاحکنندههای گرافیکی
- گرافیک در نوشتن
- خطوط ترازبندی در Jetpack Compose






