Canvas
কম্পোজেবল ছাড়াও, কম্পোজে বেশ কিছু দরকারী গ্রাফিক্স Modifiers
রয়েছে যা কাস্টম বিষয়বস্তু আঁকতে সাহায্য করে। এই মডিফায়ারগুলি দরকারী কারণ এগুলি যে কোনও কম্পোজেবলে প্রয়োগ করা যেতে পারে।
অঙ্কন সংশোধক
সমস্ত অঙ্কন কমান্ড রচনায় একটি অঙ্কন সংশোধক দিয়ে সম্পন্ন করা হয়। রচনায় তিনটি প্রধান অঙ্কন সংশোধক রয়েছে:
অঙ্কনের জন্য বেস মডিফায়ার হল drawWithContent
, যেখানে আপনি আপনার কম্পোজেবলের অঙ্কন ক্রম এবং মডিফায়ারের ভিতরে জারি করা অঙ্কন কমান্ডগুলি নির্ধারণ করতে পারেন। drawBehind
হল drawWithContent
চারপাশে একটি সুবিধাজনক র্যাপার যেখানে কম্পোজেবলের বিষয়বস্তুর পিছনে অঙ্কন ক্রম সেট করা আছে। drawWithCache
এর ভিতরের onDrawBehind
বা onDrawWithContent
কল করে - এবং সেগুলির মধ্যে তৈরি বস্তুগুলিকে ক্যাশ করার জন্য একটি প্রক্রিয়া প্রদান করে।
Modifier.drawWithContent
: অঙ্কন ক্রম নির্বাচন করুন
Modifier.drawWithContent
আপনাকে কম্পোজেবলের বিষয়বস্তুর আগে বা পরে DrawScope
অপারেশন চালাতে দেয়। কম্পোজেবলের প্রকৃত বিষয়বস্তু রেন্ডার করতে drawContent
কল করতে ভুলবেন না। এই সংশোধকটির সাহায্যে, আপনি অপারেশনের ক্রম নির্ধারণ করতে পারেন, যদি আপনি চান যে আপনার সামগ্রীটি আপনার কাস্টম অঙ্কন অপারেশনের আগে বা পরে আঁকা হোক৷
উদাহরণস্বরূপ, আপনি যদি UI-তে একটি ফ্ল্যাশলাইট কীহোল প্রভাব তৈরি করতে আপনার সামগ্রীর উপরে একটি রেডিয়াল গ্রেডিয়েন্ট রেন্ডার করতে চান তবে আপনি নিম্নলিখিতগুলি করতে পারেন:
var pointerOffset by remember { mutableStateOf(Offset(0f, 0f)) } Column( modifier = Modifier .fillMaxSize() .pointerInput("dragging") { detectDragGestures { change, dragAmount -> pointerOffset += dragAmount } } .onSizeChanged { pointerOffset = Offset(it.width / 2f, it.height / 2f) } .drawWithContent { drawContent() // draws a fully black area with a small keyhole at pointerOffset that’ll show part of the UI. drawRect( Brush.radialGradient( listOf(Color.Transparent, Color.Black), center = pointerOffset, radius = 100.dp.toPx(), ) ) } ) { // Your composables here }
Modifier.drawBehind
: একটি কম্পোজেবলের পিছনে আঁকা
Modifier.drawBehind
আপনাকে স্ক্রীনে আঁকা কম্পোজযোগ্য বিষয়বস্তুর পিছনে DrawScope
অপারেশন করতে দেয়। আপনি যদি Canvas
বাস্তবায়নের দিকে নজর দেন, তাহলে আপনি লক্ষ্য করবেন যে এটি Modifier.drawBehind
চারপাশে একটি সুবিধাজনক মোড়ক মাত্র।
Text
পিছনে একটি বৃত্তাকার আয়তক্ষেত্র আঁকতে:
Text( "Hello Compose!", modifier = Modifier .drawBehind { drawRoundRect( Color(0xFFBBAAEE), cornerRadius = CornerRadius(10.dp.toPx()) ) } .padding(4.dp) )
যা নিম্নলিখিত ফলাফল তৈরি করে:
Modifier.drawWithCache
: ড্র অবজেক্ট অঙ্কন এবং ক্যাশে করা
Modifier.drawWithCache
এর ভিতরে তৈরি করা বস্তুগুলোকে ক্যাশে রাখে। যতক্ষণ পর্যন্ত অঙ্কন এলাকার আকার একই থাকে ততক্ষণ অবজেক্টগুলি ক্যাশ করা হয়, বা পঠিত কোনও স্টেট অবজেক্ট পরিবর্তিত না হয়। এই সংশোধকটি অঙ্কন কলগুলির কার্যকারিতা উন্নত করার জন্য দরকারী কারণ এটি ড্রতে তৈরি করা বস্তুগুলি (যেমন: Brush, Shader, Path
ইত্যাদি) পুনরায় বরাদ্দ করার প্রয়োজন এড়ায়।
বিকল্পভাবে, আপনি মোডিফায়ারের বাইরে, remember
ব্যবহার করে অবজেক্ট ক্যাশেও করতে পারেন। যাইহোক, এটি সর্বদা সম্ভব নয় কারণ আপনার সর্বদা রচনাটিতে অ্যাক্সেস থাকে না। বস্তুগুলি শুধুমাত্র অঙ্কনের জন্য ব্যবহার করা হলে drawWithCache
ব্যবহার করা আরও কার্যকরী হতে পারে।
উদাহরণস্বরূপ, যদি আপনি একটি Text
পিছনে একটি গ্রেডিয়েন্ট আঁকার জন্য একটি Brush
তৈরি করেন, drawWithCache
ব্যবহার করে অঙ্কন এলাকার আকার পরিবর্তন না হওয়া পর্যন্ত Brush
অবজেক্টটিকে ক্যাশ করে:
Text( "Hello Compose!", modifier = Modifier .drawWithCache { val brush = Brush.linearGradient( listOf( Color(0xFF9E82F0), Color(0xFF42A5F5) ) ) onDrawBehind { drawRoundRect( brush, cornerRadius = CornerRadius(10.dp.toPx()) ) } } )
গ্রাফিক্স মডিফায়ার
Modifier.graphicsLayer
: কম্পোজেবলে রূপান্তর প্রয়োগ করুন
Modifier.graphicsLayer
হল একটি মডিফায়ার যা কম্পোজেবল ড্রয়ের বিষয়বস্তুকে ড্র লেয়ারে পরিণত করে। একটি স্তর কয়েকটি ভিন্ন ফাংশন প্রদান করে, যেমন:
- এর অঙ্কন নির্দেশাবলীর জন্য বিচ্ছিন্নতা (
RenderNode
অনুরূপ)। একটি স্তরের অংশ হিসাবে ক্যাপচার করা অঙ্কন নির্দেশাবলী অ্যাপ্লিকেশন কোড পুনরায় নির্বাহ না করে রেন্ডারিং পাইপলাইন দ্বারা দক্ষতার সাথে পুনরায় জারি করা যেতে পারে। - একটি স্তরের মধ্যে থাকা সমস্ত অঙ্কন নির্দেশাবলীতে প্রযোজ্য রূপান্তর।
- রচনা ক্ষমতার জন্য রাস্টারাইজেশন। যখন একটি স্তর রাস্টারাইজ করা হয়, তখন এর অঙ্কন নির্দেশাবলী কার্যকর করা হয় এবং আউটপুট একটি অফস্ক্রিন বাফারে ক্যাপচার করা হয়। পরবর্তী ফ্রেমের জন্য এই ধরনের একটি বাফার সংমিশ্রণ করা স্বতন্ত্র নির্দেশাবলী কার্যকর করার চেয়ে দ্রুততর, কিন্তু স্কেলিং বা ঘূর্ণনের মতো রূপান্তর প্রয়োগ করা হলে এটি একটি বিটম্যাপ হিসাবে আচরণ করবে।
রূপান্তর
Modifier.graphicsLayer
এর অঙ্কন নির্দেশাবলীর জন্য বিচ্ছিন্নতা প্রদান করে; উদাহরণস্বরূপ, Modifier.graphicsLayer
ব্যবহার করে বিভিন্ন রূপান্তর প্রয়োগ করা যেতে পারে। অঙ্কন ল্যাম্বডা পুনরায় চালানোর প্রয়োজন ছাড়াই এগুলি অ্যানিমেটেড বা পরিবর্তন করা যেতে পারে।
Modifier.graphicsLayer
আপনার কম্পোজেবলের পরিমাপকৃত আকার বা স্থান পরিবর্তন করে না, কারণ এটি শুধুমাত্র ড্র ফেজকে প্রভাবিত করে। এর মানে হল যে আপনার কম্পোজেবল অন্যদের ওভারল্যাপ করতে পারে যদি এটি তার লেআউট সীমার বাইরে অঙ্কন করে।
এই সংশোধকের সাথে নিম্নলিখিত রূপান্তরগুলি প্রয়োগ করা যেতে পারে:
স্কেল - আকার বৃদ্ধি
scaleX
এবং scaleY
যথাক্রমে অনুভূমিক বা উল্লম্ব দিক থেকে বিষয়বস্তুকে বড় করে বা সঙ্কুচিত করে। 1.0f
এর মান স্কেলে কোন পরিবর্তন নির্দেশ করে না, 0.5f
এর মান মানে মাত্রার অর্ধেক।
Image( painter = painterResource(id = R.drawable.sunset), contentDescription = "Sunset", modifier = Modifier .graphicsLayer { this.scaleX = 1.2f this.scaleY = 0.8f } )
অনুবাদ
translationX
এবং translationY
graphicsLayer
দিয়ে পরিবর্তন করা যেতে পারে, translationX
কম্পোজযোগ্য বাম বা ডান দিকে নিয়ে যায়। translationY
কম্পোজেবলকে উপরে বা নিচে নিয়ে যায়।
Image( painter = painterResource(id = R.drawable.sunset), contentDescription = "Sunset", modifier = Modifier .graphicsLayer { this.translationX = 100.dp.toPx() this.translationY = 10.dp.toPx() } )
ঘূর্ণন
অনুভূমিকভাবে ঘোরানোর জন্য rotationX
, উল্লম্বভাবে ঘোরানোর জন্য rotationY
এবং Z অক্ষে ঘোরানোর জন্য rotationZ
সেট করুন (স্ট্যান্ডার্ড ঘূর্ণন)। এই মান ডিগ্রী (0-360) নির্দিষ্ট করা হয়.
Image( painter = painterResource(id = R.drawable.sunset), contentDescription = "Sunset", modifier = Modifier .graphicsLayer { this.rotationX = 90f this.rotationY = 275f this.rotationZ = 180f } )
উৎপত্তি
একটি transformOrigin
নির্দিষ্ট করা যেতে পারে। এটি তখন বিন্দু হিসাবে ব্যবহৃত হয় যেখান থেকে রূপান্তর ঘটে। এখন পর্যন্ত সমস্ত উদাহরণ TransformOrigin.Center
ব্যবহার করেছে, যা (0.5f, 0.5f)
। যদি আপনি (0f, 0f)
এ উৎপত্তি উল্লেখ করেন, তাহলে রূপান্তরগুলি কম্পোজেবলের উপরের-বাম কোণ থেকে শুরু হয়।
আপনি যদি একটি rotationZ
রূপান্তর দিয়ে মূল পরিবর্তন করেন, আপনি দেখতে পাবেন যে আইটেমটি কম্পোজেবলের উপরের বাম দিকে ঘোরে:
Image( painter = painterResource(id = R.drawable.sunset), contentDescription = "Sunset", modifier = Modifier .graphicsLayer { this.transformOrigin = TransformOrigin(0f, 0f) this.rotationX = 90f this.rotationY = 275f this.rotationZ = 180f } )
ক্লিপ এবং আকৃতি
আকৃতি সেই রূপরেখাটি নির্দিষ্ট করে যে বিষয়বস্তুটি যখন clip = true
। এই উদাহরণে, আমরা দুটি আলাদা ক্লিপ রাখার জন্য দুটি বাক্স সেট করেছি - একটি graphicsLayer
ক্লিপ ভেরিয়েবল ব্যবহার করে এবং অন্যটি সুবিধাজনক র্যাপার Modifier.clip
ব্যবহার করে।
Column(modifier = Modifier.padding(16.dp)) { Box( modifier = Modifier .size(200.dp) .graphicsLayer { clip = true shape = CircleShape } .background(Color(0xFFF06292)) ) { Text( "Hello Compose", style = TextStyle(color = Color.Black, fontSize = 46.sp), modifier = Modifier.align(Alignment.Center) ) } Box( modifier = Modifier .size(200.dp) .clip(CircleShape) .background(Color(0xFF4DB6AC)) ) }
প্রথম বাক্সের বিষয়বস্তু ("হ্যালো কম্পোজ" লেখা লেখা) বৃত্তের আকারে ক্লিপ করা হয়েছে:
আপনি যদি উপরের গোলাপী বৃত্তে একটি translationY
প্রয়োগ করেন, আপনি দেখতে পাবেন যে কম্পোজেবলের সীমানা এখনও একই, কিন্তু বৃত্তটি নীচের বৃত্তের নীচে (এবং এর সীমানার বাইরে) আঁকে।
এটি যে অঞ্চলে আঁকা হয়েছে তাতে কম্পোজযোগ্য ক্লিপ করতে, আপনি মডিফায়ার চেইনের শুরুতে আরেকটি Modifier.clip(RectangleShape)
যোগ করতে পারেন। বিষয়বস্তু তারপর মূল সীমার ভিতরে থেকে যায়.
Column(modifier = Modifier.padding(16.dp)) { Box( modifier = Modifier .clip(RectangleShape) .size(200.dp) .border(2.dp, Color.Black) .graphicsLayer { clip = true shape = CircleShape translationY = 50.dp.toPx() } .background(Color(0xFFF06292)) ) { Text( "Hello Compose", style = TextStyle(color = Color.Black, fontSize = 46.sp), modifier = Modifier.align(Alignment.Center) ) } Box( modifier = Modifier .size(200.dp) .clip(RoundedCornerShape(500.dp)) .background(Color(0xFF4DB6AC)) ) }
আলফা
Modifier.graphicsLayer
পুরো স্তরের জন্য একটি alpha
(অস্বচ্ছতা) সেট করতে ব্যবহার করা যেতে পারে। 1.0f
সম্পূর্ণ অস্বচ্ছ এবং 0.0f
অদৃশ্য।
Image( painter = painterResource(id = R.drawable.sunset), contentDescription = "clock", modifier = Modifier .graphicsLayer { this.alpha = 0.5f } )
কম্পোজিটিং কৌশল
আলফা এবং স্বচ্ছতার সাথে কাজ করা একটি একক আলফা মান পরিবর্তন করার মতো সহজ নাও হতে পারে। একটি আলফা পরিবর্তন করার পাশাপাশি, একটি graphicsLayer
একটি CompositingStrategy
সেট করার বিকল্পও রয়েছে। একটি CompositingStrategy
নির্ধারণ করে যে কীভাবে কম্পোজেবলের বিষয়বস্তুটি ইতিমধ্যেই স্ক্রিনে আঁকা অন্যান্য সামগ্রীর সাথে সংমিশ্রিত (একত্রে রাখা) হয়।
বিভিন্ন কৌশল হল:
স্বয়ংক্রিয় (ডিফল্ট)
কম্পোজিটিং কৌশলটি বাকি graphicsLayer
প্যারামিটার দ্বারা নির্ধারিত হয়। আলফা 1.0f এর কম হলে বা RenderEffect
সেট করা থাকলে এটি লেয়ারটিকে অফস্ক্রিন বাফারে রেন্ডার করে। যখনই আলফা 1f-এর কম হয়, তখন বিষয়বস্তু রেন্ডার করার জন্য একটি সংমিশ্রণ স্তর স্বয়ংক্রিয়ভাবে তৈরি হয় এবং তারপরে সংশ্লিষ্ট আলফার সাথে এই অফস্ক্রিন বাফারটিকে গন্তব্যে আঁকতে হয়। একটি RenderEffect
সেট করা বা ওভারস্ক্রোল সর্বদা CompositingStrategy
সেট নির্বিশেষে একটি অফস্ক্রিন বাফারে সামগ্রী রেন্ডার করে৷
অফস্ক্রিন
গন্তব্যে রেন্ডার করার আগে কম্পোজেবলের বিষয়বস্তু সবসময় একটি অফস্ক্রিন টেক্সচার বা বিটম্যাপে রাস্টারাইজ করা হয়। এটি মাস্ক বিষয়বস্তুতে BlendMode
ক্রিয়াকলাপ প্রয়োগ করার জন্য এবং অঙ্কন নির্দেশাবলীর জটিল সেট রেন্ডার করার সময় কার্য সম্পাদনের জন্য দরকারী।
CompositingStrategy.Offscreen
ব্যবহার করার একটি উদাহরণ হল BlendModes
এর সাথে। নীচের উদাহরণটি একবার দেখে বলুন যে আপনি BlendMode.Clear
ব্যবহার করে এমন একটি ড্র কমান্ড জারি করে কম্পোজযোগ্য একটি Image
অংশগুলি সরাতে চান। আপনি যদি CompositingStrategy.Offscreen
এ compositingStrategy
সেট না করেন, তাহলে BlendMode
এর নিচের সমস্ত বিষয়বস্তুর সাথে ইন্টারঅ্যাক্ট করে।
Image( painter = painterResource(id = R.drawable.dog), contentDescription = "Dog", contentScale = ContentScale.Crop, modifier = Modifier .size(120.dp) .aspectRatio(1f) .background( Brush.linearGradient( listOf( Color(0xFFC5E1A5), Color(0xFF80DEEA) ) ) ) .padding(8.dp) .graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen } .drawWithCache { val path = Path() path.addOval( Rect( topLeft = Offset.Zero, bottomRight = Offset(size.width, size.height) ) ) onDrawWithContent { clipPath(path) { // this draws the actual image - if you don't call drawContent, it wont // render anything this@onDrawWithContent.drawContent() } val dotSize = size.width / 8f // Clip a white border for the content drawCircle( Color.Black, radius = dotSize, center = Offset( x = size.width - dotSize, y = size.height - dotSize ), blendMode = BlendMode.Clear ) // draw the red circle indication drawCircle( Color(0xFFEF5350), radius = dotSize * 0.8f, center = Offset( x = size.width - dotSize, y = size.height - dotSize ) ) } } )
CompositingStrategy
Offscreen
সেট করার মাধ্যমে, এটি কমান্ডগুলি কার্যকর করার জন্য একটি অফস্ক্রিন টেক্সচার তৈরি করে (শুধুমাত্র এই কম্পোজেবলের বিষয়বস্তুতে BlendMode
প্রয়োগ করে)। এটি তারপরে এটিকে স্ক্রীনে ইতিমধ্যে রেন্ডার করা হয়েছে তার উপরে রেন্ডার করে, ইতিমধ্যে আঁকা বিষয়বস্তুকে প্রভাবিত করে না।
আপনি যদি CompositingStrategy.Offscreen
ব্যবহার না করে থাকেন, তাহলে BlendMode.Clear
প্রয়োগের ফলাফল গন্তব্যের সমস্ত পিক্সেল সাফ করে, আগে থেকে যা সেট করা ছিল তা নির্বিশেষে- উইন্ডোর রেন্ডারিং বাফার (কালো) দৃশ্যমান রেখে৷ আলফা জড়িত অনেক BlendModes
অফস্ক্রিন বাফার ছাড়া আশানুরূপ কাজ করবে না। লাল বৃত্ত নির্দেশকের চারপাশে কালো রিং নোট করুন:
এটি আরও কিছুটা বোঝার জন্য: যদি অ্যাপটির একটি স্বচ্ছ উইন্ডো ব্যাকগ্রাউন্ড থাকে এবং আপনি CompositingStrategy.Offscreen
ব্যবহার না করেন, তাহলে BlendMode
পুরো অ্যাপের সাথে ইন্টারঅ্যাক্ট করবে। এটি নীচের অ্যাপ বা ওয়ালপেপার দেখানোর জন্য সমস্ত পিক্সেল সাফ করবে, যেমন এই উদাহরণে:
এটা লক্ষণীয় যে CompositingStrategy.Offscreen
ব্যবহার করার সময়, একটি অফস্ক্রিন টেক্সচার তৈরি করা হয় যা অঙ্কন এলাকার আকার হয় এবং পর্দায় আবার রেন্ডার করা হয়। এই কৌশলের সাহায্যে করা যেকোনো অঙ্কন কমান্ড ডিফল্টরূপে এই অঞ্চলে ক্লিপ করা হয়। নিচের কোড স্নিপেটটি অফস্ক্রিন টেক্সচার ব্যবহারে স্যুইচ করার সময় পার্থক্যগুলিকে চিত্রিত করে:
@Composable fun CompositingStrategyExamples() { Column( modifier = Modifier .fillMaxSize() .wrapContentSize(Alignment.Center) ) { // Does not clip content even with a graphics layer usage here. By default, graphicsLayer // does not allocate + rasterize content into a separate layer but instead is used // for isolation. That is draw invalidations made outside of this graphicsLayer will not // re-record the drawing instructions in this composable as they have not changed Canvas( modifier = Modifier .graphicsLayer() .size(100.dp) // Note size of 100 dp here .border(2.dp, color = Color.Blue) ) { // ... and drawing a size of 200 dp here outside the bounds drawRect(color = Color.Magenta, size = Size(200.dp.toPx(), 200.dp.toPx())) } Spacer(modifier = Modifier.size(300.dp)) /* Clips content as alpha usage here creates an offscreen buffer to rasterize content into first then draws to the original destination */ Canvas( modifier = Modifier // force to an offscreen buffer .graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen) .size(100.dp) // Note size of 100 dp here .border(2.dp, color = Color.Blue) ) { /* ... and drawing a size of 200 dp. However, because of the CompositingStrategy.Offscreen usage above, the content gets clipped */ drawRect(color = Color.Red, size = Size(200.dp.toPx(), 200.dp.toPx())) } } }
ModulateAlpha
এই রচনা কৌশলটি graphicsLayer
মধ্যে রেকর্ড করা প্রতিটি অঙ্কন নির্দেশাবলীর জন্য আলফা মডিউল করে। এটি 1.0f এর নিচে আলফার জন্য একটি অফস্ক্রিন বাফার তৈরি করবে না যদি না একটি RenderEffect
সেট করা হয়, তাই এটি আলফা রেন্ডারিংয়ের জন্য আরও দক্ষ হতে পারে। যাইহোক, এটি ওভারল্যাপিং বিষয়বস্তুর জন্য বিভিন্ন ফলাফল প্রদান করতে পারে। ব্যবহারের ক্ষেত্রে যেখানে এটি আগে থেকেই জানা যায় যে বিষয়বস্তু ওভারল্যাপ হচ্ছে না, এটি 1-এর কম আলফা মান সহ CompositingStrategy.Auto
থেকে ভাল পারফরম্যান্স প্রদান করতে পারে৷
বিভিন্ন কম্পোজিশন কৌশলের আরেকটি উদাহরণ নিচে দেওয়া হল - কম্পোজেবলের বিভিন্ন অংশে বিভিন্ন আলফা প্রয়োগ করা এবং একটি Modulate
কৌশল প্রয়োগ করা:
@Preview @Composable fun CompositingStrategy_ModulateAlpha() { Column( modifier = Modifier .fillMaxSize() .padding(32.dp) ) { // Base drawing, no alpha applied Canvas( modifier = Modifier.size(200.dp) ) { drawSquares() } Spacer(modifier = Modifier.size(36.dp)) // Alpha 0.5f applied to whole composable Canvas( modifier = Modifier .size(200.dp) .graphicsLayer { alpha = 0.5f } ) { drawSquares() } Spacer(modifier = Modifier.size(36.dp)) // 0.75f alpha applied to each draw call when using ModulateAlpha Canvas( modifier = Modifier .size(200.dp) .graphicsLayer { compositingStrategy = CompositingStrategy.ModulateAlpha alpha = 0.75f } ) { drawSquares() } } } private fun DrawScope.drawSquares() { val size = Size(100.dp.toPx(), 100.dp.toPx()) drawRect(color = Red, size = size) drawRect( color = Purple, size = size, topLeft = Offset(size.width / 4f, size.height / 4f) ) drawRect( color = Yellow, size = size, topLeft = Offset(size.width / 4f * 2f, size.height / 4f * 2f) ) } val Purple = Color(0xFF7E57C2) val Yellow = Color(0xFFFFCA28) val Red = Color(0xFFEF5350)
একটি বিটম্যাপে একটি রচনাযোগ্য বিষয়বস্তু লিখুন
একটি সাধারণ ব্যবহারের ক্ষেত্রে একটি কম্পোজেবল থেকে একটি Bitmap
তৈরি করা হয়। একটি Bitmap
আপনার কম্পোজেবল বিষয়বস্তু অনুলিপি করতে, rememberGraphicsLayer()
ব্যবহার করে একটি GraphicsLayer
তৈরি করুন।
drawWithContent()
এবং graphicsLayer.record{}
ব্যবহার করে অঙ্কন কমান্ডগুলিকে নতুন স্তরে পুনর্নির্দেশ করুন। তারপর drawLayer
ব্যবহার করে দৃশ্যমান ক্যানভাসে স্তরটি আঁকুন:
val coroutineScope = rememberCoroutineScope() val graphicsLayer = rememberGraphicsLayer() Box( modifier = Modifier .drawWithContent { // call record to capture the content in the graphics layer graphicsLayer.record { // draw the contents of the composable into the graphics layer this@drawWithContent.drawContent() } // draw the graphics layer on the visible canvas drawLayer(graphicsLayer) } .clickable { coroutineScope.launch { val bitmap = graphicsLayer.toImageBitmap() // do something with the newly acquired bitmap } } .background(Color.White) ) { Text("Hello Android", fontSize = 26.sp) }
আপনি ডিস্কে বিটম্যাপ সংরক্ষণ করতে পারেন এবং শেয়ার করতে পারেন। আরো বিস্তারিত জানার জন্য, সম্পূর্ণ উদাহরণ স্নিপেট দেখুন। ডিস্কে সংরক্ষণ করার চেষ্টা করার আগে ডিভাইসের অনুমতিগুলি পরীক্ষা করতে ভুলবেন না।
কাস্টম অঙ্কন সংশোধক
আপনার নিজস্ব কাস্টম মডিফায়ার তৈরি করতে, DrawModifier
ইন্টারফেস প্রয়োগ করুন। এটি আপনাকে একটি ContentDrawScope
এ অ্যাক্সেস দেয়, যা Modifier.drawWithContent()
ব্যবহার করার সময় উন্মুক্ত করা হয়। তারপর আপনি কোড পরিষ্কার করতে এবং সুবিধাজনক মোড়ক প্রদান করতে কাস্টম ড্রয়িং মডিফায়ারে সাধারণ অঙ্কন ক্রিয়াকলাপগুলি বের করতে পারেন; উদাহরণস্বরূপ, Modifier.background()
একটি সুবিধাজনক DrawModifier
।
উদাহরণস্বরূপ, আপনি যদি একটি Modifier
প্রয়োগ করতে চান যা উল্লম্বভাবে বিষয়বস্তু ফ্লিপ করে, আপনি নিম্নরূপ একটি তৈরি করতে পারেন:
class FlippedModifier : DrawModifier { override fun ContentDrawScope.draw() { scale(1f, -1f) { this@draw.drawContent() } } } fun Modifier.flipped() = this.then(FlippedModifier())
তারপর Text
প্রয়োগ করা এই ফ্লিপড মডিফায়ারটি ব্যবহার করুন:
Text( "Hello Compose!", modifier = Modifier .flipped() )
অতিরিক্ত সম্পদ
graphicsLayer
এবং কাস্টম অঙ্কন ব্যবহার করে আরও উদাহরণের জন্য, নিম্নলিখিত সংস্থানগুলি দেখুন:
আপনার জন্য প্রস্তাবিত
- দ্রষ্টব্য: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট প্রদর্শিত হয়
- রচনায় গ্রাফিক্স
- একটি ছবি কাস্টমাইজ করুন {:#customize-image}
- জেটপ্যাক রচনার জন্য কোটলিন