Flutter ile Clip(Kırpma)

Emre Karataş
Flutter Türkiye
Published in
5 min readOct 18, 2019

Selam Millet !

Bu benim Medium’daki ilk yazım ve Flutter gibi geleceği güçlü olan bir teknolojide ilk yazımı yazdığım için mutluyum :) Direkt mevzuya geçelim.

Mobil uygulamalarda performans kadar kullanıcıyı uygulamaya bağlayan en önemli unsurlardan biride etkileyici tasarımlardır. Çoğu zaman UI konusunda tasarımcılardan destek alabiliyoruz fakat bazı durumlarda tasarımı kod kısmında çözmemiz daha efektif olabiliyor.

Etkileyici tasarım unsurlarını tek bir yazıda ele almak fazlasıyla uzun ve sıkıcı olabilir. Bu yüzden konuları tek tek ele alıp en vitaminli noktalarına değinerek ilerleyelim :) Bu yazımda Flutter’da Clip işlemleriyle neler yapabileceğimize değineceğiz.

Clip: Bilgisayar grafiğinde, görüntülmeyi belirli bir alanda sınırlama işlemine kırpma denir. Bir alana / bir widget’a clip alanı verilir. Render motoru sadece tanımlanan alanı boyar.

Fazla uzatmadan başlıkta belirttiğimiz Clip Path ile Flutter’da neler yapabiliriz, kodlamaya başlayalım !

Custom Clipper

CustomClipper Flutter’da kırpma işlemi için temel sınıftır ve 4 widget tarafından kullanılır. ClipRect, ClipRRect, ClipOval, ClipPath.

Boş sayfamızın ortasına 200x200 alanında mavi bir Container ekleyelim.

Container’ımızı ClipOval veya ClipRect ile Container’ı sardığımızda Container belirtilen kırpma işlemine uygun davranacaktır.

ClipRect:

return Scaffold(
appBar: AppBar(),
body: Center(
child: ClipRect(
child: Container(
color: Colors.blue,
width: 200.0,
height: 200.0,
),
),
),
);

ClipOval:

return Scaffold(
appBar: AppBar(),
body: Center(
child: ClipOval(
child: Container(
color: Colors.blue,
width: 200.0,
height: 200.0,
),
),
),
);
ClipOval

ClipRRect: ClipRect’ten farkı aradaki “R” harfi. Yani bu kırpma şekli bize şöyle diyor, Ben bir Rect’im fakat ben de “R” (radius) var. Biraz daha özelleştirebilirsin beni diyor kendileri. Sağımı solumu üstümü altımı her yerimi radiuslayabilirsin diyor. Nasıl mı? borderRadius özelliği sayesinde.

return Scaffold(
appBar: AppBar(),
body: Center(
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50.0),
bottomRight: Radius.circular(50.0),
),
child: Container(
color: Colors.blue,
width: 200.0,
height: 200.0,
),
),
),
);
ClipRRect

Şimdi buraya kadar her şey süper. Buraya kadar kalıplaşmış widget’lar kullanarak kalıplaşmış şekilleri anlattık. Peki ya özel bir şekil oluşturmak istersek ne yapacağız? Burada da imdadımıza ClipPath koşuyor.

ClipPath:

Özel bir alanı yol olarak kullanıp kırpmak için kullanılırlar. Yani burada pathlerimiz var. Path’lere verdiğimiz özelliklere göre kırpılan alanı boyuyoruz. Bu işlem için CustomClipper’dan türeyen bir class yaratalım.

Class’ı MyCustomClipper gibi yaratıcı(!) bir isimle onurlandırdım :)

getClip: Bütün CustomClipper’lar getClip yönteminden bir boyut alırlar. Bu boyut ClipPath child’ındaki genişliği ve yüksekliği ifade eder. Kısacası bu metod kırpılacak alan bilgisini bize döndürür.

shouldReclip: Buradaki bool değere göre getClip’in tekrar tetiklenmesi sağlanır. Geliştirme aşamasındayken hot reload özelliğinden faydalanmak için “true” olmalı. Böylece değişiklikleri kaydettiğinizde direkt değişikliği görebilirsiniz. “false” yaptığınızda sadece clipper tetiklendiğinde getClip yapacaktır.

Alanımızı aşağıdaki gibi koordinat sisteminde düşünebiliriz,

MyCustomClipper’a path.lineTo ekleyelim.

Ne demek bu?

(0,0) koordinat düzleminde lineTo ile çizgiler çiziyoruz, peki nasıl?

void lineTo(double x, double y) // lineTo bizden koordinat düzlemindeki tabirle bir x ve bir de y değeri bekliyor. path.lineTo(0.0, size.height);// Burada x koordinatı 0 , y koordinatı Containerdan gelen height kadar olan bir çizgi çiziyoruz. Tek bir çizgi yetmez tabi. Bir alan oluşturabilmesi için en az iki çizgi çizmeliyiz.yukardaki satıra ek aşağıdaki line'ı çiziyoruz.path.lineTo(size.width, size.height);

yazdığımız 2 line ile aşağıdaki gibi bir alan oluşturmuş olduk.

Biraz derinleşelim..

Tamam çok güzel basit basit şekilleri yaptık öğrendik uyguladık. Aşağıdaki gibi tasarım geldi, bunun arka planındaki gibi kesik yapıyı nasıl yapacağız?

Flutter’la her şey çok kolay (Mottomuz) !

Az önce değindiğimiz kodlara 2–3 satır ekleyerek bu güzel tasarımı elde edebiliriz.

main.dart

return Scaffold(
body: ClipPath(
clipper: MyCustomClipper(),
child: Container(
color: Colors.blue,
width: double.infinity,
height: 300.0,
),
),
);

my_custom_clipper.dart

Koordinat üzerinde noktaları işaretleyip, birleştirdiğimizde aşağıdaki gibi bir çıktımız olacak.

getClip’te belirttiğimiz noktalarla basit bir şekilde amacımıza ulaşmış olduk. Madem flutter da işler bu kadar kolay, o zaman biraz daha derinleşelim :) Karşınıza aşağıdaki görseldeki gibi bir tasarım geldi. Arkaplandaki turuncu yapıyı yapmak için nasıl bir yol izlememiz gerekiyor?

Şimdiye kadar hep lineTo ile noktalar arasında çizgi oluşturduk. Şimdi karşımızda eğri oluşturmamız gereken bir tasarım var.

quadraticBezierTo: ClipPath bize bu metodla ikinci dereceden Bezier Eğri’si ekleme imkanı sağlıyor. (Bezier Eğri’sini ben de yazıyı yazarken öğrendim açıkçası)

Metod içeriği aşağıdaki gibi;

void quadraticBezierTo(double x1, double y1, double x2, double y2)

Göründüğü üzere bizden 2 nokta beklemektedir.

Resmin tamamını düşünürsek yukarıdaki tasarımda oluşturmamız gereken noktalar aşağıdaki gibidir;

path.lineTo(0, size.height);
path.quadraticBezierTo(size.width/4, size.height-60, size.width/2, size.height-30);
path.quadraticBezierTo(3/4*size.width, size.height, size.width, size.height-40);
path.lineTo(size.width, 0);

ve çıktımız..

Mantığını anladıktan sonra flutter ile etkileyici UI lar çizmeye başlamak bu kadar kolay. Örneğin bir tane CircleAvatar ekleyerek oluşturduğumuz Container daha da güzelleştirilebiliriz.

main.dart

return Scaffold(
body: Stack(
overflow: Overflow.visible,
children: <Widget>[
Positioned(
child: ClipPath(
clipper: MyCustomClipper(),
child: Container(
color: Colors.blue,
width: double.infinity,
height: 300.0,
),
),
),
Positioned(
left: 12,
top: 230,
height: 120,
width: 120,
child: CircleAvatar(
backgroundImage: NetworkImage("https://www.beliefnet.com/columnists//truthsyoucanuse/files/2013/05/stress-free.jpg"),
),
)
],
),
);

Stack ekleyip kırptığımız kısmın üstüne bir profil resmi ekleyebilirsiniz.

getClip içerisine ufak dokunuşlarla container’ı basitçe farklı şekillere kırpabiliriz.

path.lineTo(0, size.height);
path.quadraticBezierTo(
size.width / 2, size.height - 100, size.width, size.height);
path.lineTo(size.width, 0);

getClip içerisinde path verirken arcToPoint, arcTo, relativeConicTo, relativeLineTo gibi bir sürü özellik mevcut. Fakat kafa karışıklığı olmamasından dolayı bana göre en çok kullanılan ve genel olarak güzel UI yaratabileceğimiz yapılardan bahsetmek istedim.

Yazıyı okumak için zaman ayırdığınız için teşekkürler, umarım faydalı olmuştur.

--

--