, October 02, 2022

0 kết quả được tìm thấy

Flutter BoxDecoration Cheat Sheet

  • Đăng bởi  Chau Le
  •  Nov 29, 2021

  •   29 min reads
Flutter BoxDecoration Cheat Sheet

BoxDecoration cung cấp nhiều cách khác nhau để vẽ một box.

Box có border (viền), body (thân) và có thể tạo shadow cho box (boxShadow).

Hình dạng của box có thể là hình tròn hoặc hình chữ nhật. Nếu nó là một hình chữ nhật, thì borderRadius property kiểm soát độ tròn của các góc.

Body box được sơn nhiều lớp. Ở lớp dưới cùng nhất màu sẽ lấp đầy box. Phía trên là gradient, cũng được lấp đầy bởi màu. Cuối cùng là hình ảnh, việc căn chỉnh chính xác được kiểm soát bởi DecorationImage class.

Hãy bắt đầu với một container trống và áp dụng red color property trong boxDecoration class.

Note: Bạn không thể áp dụng color property cho container nếu bạn đang sử dụng decoration property. Đối số màu sắc chỉ là cách viết tắt của “decoration: new BoxDecoration(color:color)”.

new Center(
  child: new Container(
    decoration: new BoxDecoration(
      color: Colors.purple,
    ),
    child: new FlutterLogo(
      size: 200.0,
    )
  ),
);

Gradient Property:

Nếu bạn sử dụng thuộc tính Gradient thì thuộc tính color không có hiệu lực.

Gradient có thể được vẽ dưới hình ảnh.

Giá trị của gradient property có thể là LinearGradient Class hoặc RadialGradient Class.

Hãy bắt đầu với LinearGradient Class.

LinearGradient Class có 5 property chính

  • begin (Offset tại đó bắt đầu gradient)
  • end (Offset tại đó kết thúc gradient)
  • colors (Danh sách các màu)
  • stops (Danh sách các giá trị từ 0.0 đến 1.0 biểu thị các phân số dọc theo gradient)
  • tileMode (Cách gradient này sẽ xếp mặt phẳng trong vùng trước khi bắt đầu và sau khi kết thúc)
Center(
  child: new Container(
    decoration: new BoxDecoration(
      color: Colors.purple,
      gradient: new LinearGradient(
        colors: [Colors.red, Colors.cyan],
      ),
    ),
    child: new FlutterLogo(
      size: 200.0,
    )
  ),
);

Nếu chúng ta không thêm begin property và start property theo mặc định, gradient bắt đầu từ đầu đến cuối (từ trái sang phải)

Hãy thêm bắt đầu và kết thúc. Bạn sẽ sử dụng Alignment Class cho cả hai property.

Center(
  child: new Container(
    decoration: new BoxDecoration(
      color: Colors.purple,
      gradient: new LinearGradient(
        colors: [Colors.red, Colors.cyan],
        begin: Alignment.centerRight,
        end: Alignment.centerLeft
      ),
    ),
    child: new FlutterLogo(
      size: 200.0,
    )
  ),
);

Hãy nhớ rằng nó là một Linear Gradient. Vì vậy, nếu bắt đầu là bottomRight và kết thúc là bottomLeft, gradient sẽ đi từ Phải sang Trái cùng kết quả là:

begin: Alignment.centerRight & end: Alignment.centerLeft

begin: Alignment.topRight & end: Alignment.topLeft

Ngoài ra, bạn có thể sử dụng Alignment class với tọa độ X và Y.

new Center(
  child: new Container(
    decoration: new BoxDecoration(
      color: Colors.purple,
      gradient: new LinearGradient(
        colors: [Colors.red, Colors.cyan],
        begin: Alignment.centerRight,
        end: new Alignment(-1.0, -1.0)
      ),
    ),
    child: new FlutterLogo(
      size: 200.0,
    )
  ),
);

TileMode property

Làm thế nào gradient này sẽ xếp mặt phẳng vượt ra ngoài khu vực trước khi bắt đầu và sau khi kết thúc.

Các giá trị của TileMode là:

  • TileMode.clamp
  • TileMode.mirror
  • TileMode.repeated

TileMode.clamp là TileMode mặc định

new Center(
  child: new Container(
    decoration: new BoxDecoration(
      color: Colors.purple,
      gradient: new LinearGradient(
        colors: [Colors.red, Colors.cyan],
        begin: Alignment.centerRight,
        end: new Alignment(0.8, 0.0),
        tileMode: TileMode.clamp
      ),
    ),
    child: new FlutterLogo(
      size: 200.0,
    )
  ),
);

TileMode.mirror

new Center(
  child: new Container(
    decoration: new BoxDecoration(
      color: Colors.purple,
      gradient: new LinearGradient(
        colors: [Colors.red, Colors.cyan],
        begin: Alignment.centerRight,
        end: new Alignment(0.8, 0.0),
        tileMode: TileMode.mirror
      ),
    ),
    child: new FlutterLogo(
      size: 200.0,
    )
  ),
);
new Center(
  child: new Container(
    decoration: new BoxDecoration(
      color: Colors.purple,
      gradient: new LinearGradient(
        colors: [Colors.red, Colors.cyan],
        begin: Alignment.centerRight,
        end: new Alignment(0.8, 0.0),
        tileMode: TileMode.repeated
      ),
    ),
    child: new FlutterLogo(
      size: 200.0,
    )
  ),
);

Stops

Là một danh sách các giá trị từ 0.0 đến 1.0 biểu thị các phân số dọc theo gradient.

Nếu non-null, danh sách này phải có cùng độ dài với màu sắc.

Nếu giá trị đầu tiên không phải là 0.0, thì điểm dừng ở vị trí 0.0 và màu bằng màu đầu tiên trong các màu được chỉ định.

Nếu giá trị cuối cùng không phải là 1.0, thì điểm dừng ở vị trí 1.0 và màu bằng màu cuối cùng trong các màu được chỉ định.

Các giá trị trong danh sách điểm dừng phải theo thứ tự tăng dần. Nếu một giá trị trong danh sách dừng nhỏ hơn một giá trị trước đó trong danh sách, thì giá trị của nó được giả định bằng giá trị trước đó.

Nếu các điểm dừng là null, thì một tập hợp các điểm dừng được phân bố đồng đều được ngụ ý, với điểm dừng đầu tiên là 0.0 và điểm dừng cuối cùng là 1.0.

new Center(
  child: new Container(
    decoration: new BoxDecoration(
      color: Colors.purple,
      gradient: new LinearGradient(
        colors: [Colors.red, Colors.cyan, Colors.purple, Colors.lightGreenAccent],
        begin: Alignment.centerRight,
        end: Alignment.centerLeft,
        tileMode: TileMode.clamp,
        stops: [0.3, 0.5, 0.6, 0.7]
      ),
    ),
    child: new FlutterLogo(
      size: 200.0,
    )
  ),
);

RadialGradient

RadialGradient Class có 5 property chính

  • center (Tâm của gradient, như một offset vào hình vuông (-1.0, -1.0) x (1.0, 1.0) mô tả gradient sẽ được map vào paint box)
  • radius (Bán kính của gradient, như một phần nhỏ của cạnh ngắn nhất của paint box)
  • colors (Danh sách các màu) Giống như LinearGradient
  • stops (Danh sách các giá trị từ 0,0 đến 1,0 biểu thị các phân số dọc theo gradient) Giống như LinearGradient
  • tileMode (Cách gradient này sẽ xếp mặt phẳng vượt ra ngoài trong vùng trước khi bắt đầu và sau khi kết thúc) Giống như LinearGradient
new Center(
  child: new Container(
    decoration: new BoxDecoration(
      color: Colors.purple,
      gradient: new RadialGradient(
        colors: [Colors.red, Colors.cyan, Colors.purple, Colors.lightGreenAccent],
        center: Alignment(-0.7, -0.6),
        radius: 0.2,
        tileMode: TileMode.clamp,
        stops: [0.3, 0.5, 0.6, 0.7]
      ),
    ),
    child: new FlutterLogo(
      size: 200.0,
    )
  ),
);

Center propery lấy một giá trị của Alignment Class giống như LinearGradient và giá trị của bán kính là từ 0.0 đến 1.0

Nếu một radial gradient được vẽ trên một box rộng 200.0, thì bán kính 0.5 bằng 100.0

Image Property

Một hình ảnh để vẽ phía trên backgroundcolorhoặcgradient. Giá trị của image property là DecorationImage Class.

DecorationImage Class có các property sau:

  • image
  • alignment (để biết thêm chi tiết, hãy kiểm tra container Cheat Sheet)
  • centerSlice
  • colorFilter
  • fit
  • matchTextDirection
  • repeat

Hình ảnh

Hình ảnh có thể được vẽ vào decoration. Thông thường, đây sẽ là AssetImage (đối với hình ảnh local) hoặc NetworkImage (đối với hình ảnh lấy từ network).

new Center(
  child: new Container(
    decoration: new BoxDecoration(
      color: Colors.purple,
      gradient: new RadialGradient(
        colors: [Colors.red, Colors.cyan, Colors.purple, Colors.lightGreenAccent],
        center: Alignment(0.0, 0.0),
        radius: 0.5,
        tileMode: TileMode.clamp,
        stops: [0.3, 0.5, 0.9, 1.0]
      ),
      image: new DecorationImage(
          image: new NetworkImage("http://jlouage.com/images/author.jpg")
      )
    ),
    child: new FlutterLogo(
      size: 200.0,
    )
  ),
);

Bạn có thể thấy rằng hình ảnh được vẽ phía trên color và gradient.

centerSlice Property

centerSlice cũng giống như 9 patch png trong Android Studio. Là một kỹ thuật được sử dụng để chia tỷ lệ hình ảnh theo cách mà 4 góc không được thêm vào chia tỷ lệ, nhưng bốn cạnh được chia tỷ lệ theo một trục và phần giữa được chia tỷ lệ theo cả hai trục.

Giá trị của centerSlice property là Rect Class. Chúng ta cần tạo một hình chữ nhật từ các cạnh bên trái và trên cùng, chiều rộng và chiều cao của nó. Hãy bắt đầu để biết kích thước bức hình của chúng ta.

Width = 320 & the Height = 190

Class chúng ta cần sử dụng là

Rect.fromLTWH(double left, double top, double width, double height)

CenterSlice của chúng ta là hình chữ nhật màu xanh lá cây ở giữa hình. Để tạo nó, chúng ta cần biết chiều rộng của hình chữ nhật màu cam và đặt nó cho giá trị bên trái và chiều cao của hình chữ nhật màu tím và đặt nó cho giá trị trên cùng

Rect.fromLTWH(50.0, 50.0, double width, double height)

Vì vậy, chúng ta đã yêu cầu Rect class di chuyển 50 từ bên trái và 50 từ trên cùng của hình ảnh và bắt đầu vẽ hình chữ nhật từ điểm màu vàng được đánh dấu trên hình trên.

Trong hình trên, chúng ta có chiều rộng của hình chữ nhật là 220 và chiều cao là 90 vì vậy giá trị final class phải là

Rect.fromLTWH(50.0, 50.0, 220.0, 90.0)

Final code là

new Center(
    child: new Container(
      decoration: new BoxDecoration(
        image: new DecorationImage(
            image: new AssetImage('assets/images/9_patch_scaled_320x190.png'),
            centerSlice: new Rect.fromLTWH(50.0, 50.0, 220.0, 90.0),
            fit: BoxFit.fill,
        )
      ),
      child: new Container(
        //color: Colors.yellow,
        width: 110.0,
        height: 110.0,
      )
    ),

  );

Bạn có thể thấy rằng bốn hình vuông màu đỏ không được chia tỷ lệ. Để cho child của container có chiều rộng và chiều cao nhiều hơn.

new Center(
    child: new Container(
      decoration: new BoxDecoration(
        image: new DecorationImage(
            image: new AssetImage('assets/images/9_patch_scaled_320x190.png'),
            centerSlice: new Rect.fromLTWH(50.0, 50.0, 220.0, 90.0),
            fit: BoxFit.fill,
        )
      ),
      child: new Container(
        //color: Colors.yellow,
        width: 350.0,
        height: 450.0,
      )
    ),

  );

ColorFilter Property

Một bộ lọc màu để áp dụng cho hình ảnh trước khi sơn nó. Giá trị của property này là ColorFilter Class và method là mode.

ColorFilter.mode() lấy hai tham số, tham số đầu tiên là bộ lọc màu và tham số thứ hai là blend mode. Chúng ta sẽ sử dụng hình ảnh dưới đây và áp dụng ColorFilter khác trên nó

Chúng ta sẽ sử dụng Colors.red.withOpacity(0.5) với nhiều chế độ hòa trộn (multiple blend mode). Dưới đây chúng ta đang sử dụng BlendMode.src. Thao tác này sẽ làm mất hình ảnh đích (cuối?) (destination image), chỉ vẽ hình ảnh nguồn (ban đầu?) (source image).

new Center(
    child: new Container(
      width: double.infinity,
      height: double.infinity,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-empty.png'),
              colorFilter: new ColorFilter.mode(Colors.red.withOpacity(0.5), BlendMode.src),
          )
        ),
      ),
    ),
  );

Bây giờ sẽ sử dụng BlendMode.clear. Thao tác này sẽ làm mất cả hình ảnh nguồn và hình ảnh đích, không để lại gì.

BlendMode.color

Lấy màu sắc và độ bão hòa (saturation) của hình ảnh nguồn và độ sáng của hình ảnh đích.

Tác dụng là để tô màu hình ảnh đích với hình ảnh nguồn.

Độ mờ của output image được tính theo cách tương tự như đối với srcOver.

Các vùng hoàn toàn trong suốt trong hình ảnh nguồn sẽ lấy màu sắc và độ bão hòa của chúng từ đích.

BlendMode.colorBurn

Chia nghịch đảo của đích cho nguồn và nghịch đảo kết quả.
Đảo ngược các component có nghĩa là channel bão hòa hoàn toàn (màu trắng đục) được coi là giá trị 0.0 và các giá trị thường được coi là 0.0 (màu đen, trong suốt) được coi là 1.0.

BlendMode.colorDodge

Chia đích cho nghịch đảo của nguồn.
Đảo ngược các component có nghĩa là channel bão hòa hoàn toàn (màu trắng đục) được coi là giá trị 0.0 và các giá trị thường được coi là 0.0 (màu đen, trong suốt) được coi là 1.0.

BlendMode.darken

Kết hợp hình ảnh nguồn và hình ảnh đích bằng cách chọn giá trị thấp nhất từ ​​mỗi color channel.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.

BlendMode.difference

Trừ giá trị nhỏ hơn từ giá trị lớn hơn cho mỗi channel.
Kết hợp màu đen không có tác dụng; kết hợp màu trắng sẽ đảo ngược màu sắc của hình ảnh khác.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.
Hiệu quả tương tự như loại trừ (exclusion) nhưng khắc nghiệt hơn.

BlendMode.dst

Bỏ hình ảnh nguồn, chỉ vẽ hình ảnh đích.
Về mặt khái niệm, hình ảnh nguồn bị loại bỏ, không ảnh hưởng đến đích.
Điều này tương ứng với “Destination” Porter-Duff operator.

BlendMode.dstATop

Kết hợp hình ảnh đích trên hình ảnh nguồn, nhưng chỉ nơi nó chồng lên nguồn.
Điều này tương ứng với “Destination atop Source” Porter-Duff operator.
Về cơ bản, đây là dstOver operator, nhưng với opacity channel của output được đặt thành của hình ảnh nguồn thay vì là sự kết hợp của cả hai opacity channel của hình ảnh.
Đối với một variant có nguồn ở trên cùng thay vì đích, hãy xem srcATop.

BlendMode.dstIn

Hiển thị hình ảnh đích, nhưng chỉ nơi hai hình ảnh chồng lên nhau. Hình ảnh nguồn không được hiển thị, nó chỉ được coi như một mặt nạ. Các color channel của nguồn bị bỏ qua, chỉ có độ mờ có ảnh hưởng.
Để hiển thị hình ảnh nguồn thay vào đó, hãy xem xét srcIn.
Để đảo ngược ngữ nghĩa của mặt nạ (semantic of the mask) (chỉ hiển thị nguồn nơi đích hiện diện), hãy xem xét dstOut.
Điều này tương ứng với “Destination in Source” Porter-Duff operator.

BlendMode.dstOut

Hiển thị hình ảnh đích nhưng chỉ hiển thị ở nơi hai hình ảnh không chồng lên nhau. Hình ảnh nguồn không được hiển thị, nó chỉ được coi như một mặt nạ. Các color channel của nguồn bị bỏ qua, chỉ có độ mờ có ảnh hưởng.
Để hiển thị hình ảnh nguồn thay vào đó, hãy xem xét srcOut.
Để đảo ngược ngữ nghĩa của mặt nạ (chỉ hiển thị đích nơi nguồn hiện diện, thay vì nơi nó vắng mặt), hãy xem xét dstIn.
Điều này tương ứng với “Destination out Source” Porter-Duff operator.

BlendMode.dstOver

Kết hợp hình ảnh nguồn dưới hình ảnh đích.
Điều này ngược lại với srcOver.
Điều này tương ứng với “Destination over Source” Porter-Duff operator.

BlendMode.exclusion

Lấy tổng của hai ảnh trừ gấp đôi tích của hai ảnh.
Kết hợp màu đen không có tác dụng; kết hợp màu trắng sẽ đảo ngược màu sắc của hình ảnh khác.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.
Hiệu ứng tương tự như difference nhưng nhẹ nhàng hơn.

BlendMode.hardLight

Nhân các component của ảnh nguồn và ảnh đích sau khi đã điều chỉnh chúng.
Cụ thể, nếu giá trị nguồn nhỏ hơn, thì nhân nó với giá trị đích, trong khi giá trị đích nhỏ hơn, nó nhân nghịch đảo của giá trị đích với nghịch đảo của giá trị nguồn, sau đó đảo ngược kết quả.
Đảo ngược các component có nghĩa là channel bão hòa hoàn toàn (màu trắng đục) được coi là giá trị 0.0 và các giá trị thường được coi là 0.0 (màu đen, trong suốt) được coi là 1.0.

BlendMode.hue

Lấy màu sắc của hình ảnh nguồn, độ bão hòa và độ sáng của hình ảnh đích.
Tác dụng là để tô màu hình ảnh đích với hình ảnh nguồn.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.
Các vùng hoàn toàn trong suốt trong hình ảnh nguồn sẽ lấy màu sắc của chúng từ đích.

BlendMode.lighten

Kết hợp hình ảnh nguồn và hình ảnh đích bằng cách chọn giá trị cao nhất từ ​​mỗi color channel.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.

BlendMode.luminosity

Lấy độ sáng của hình ảnh nguồn, màu sắc và độ bão hòa của hình ảnh đích.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.
Các vùng hoàn toàn trong suốt trong hình ảnh nguồn sẽ lấy độ sáng của chúng từ đích.

BlendMode.modulate

Nhân các color component của ảnh nguồn và ảnh đích.
Điều này chỉ có thể dẫn đến các màu giống nhau hoặc tối hơn (nhân với màu trắng, 1.0, kết quả là không thay đổi; nhân với màu đen, 0.0, kết quả là màu đen).
Khi kết hợp hai hình ảnh mờ, điều này có tác dụng tương tự như chồng chéo hai hình ảnh trong suốt trên máy chiếu.
Đối với một biến thể cũng nhân alpha channel, hãy xem xét việc nhân.

BlendMode.multiply

Nhân các component của hình ảnh nguồn và hình ảnh đích, bao gồm cả alpha channel.
Điều này có thể dẫn đến các màu giống nhau hoặc tối hơn (nhân với màu trắng, 1.0, kết quả là không thay đổi; nhân với màu đen, 0.0, kết quả là màu đen).
Vì alpha channel cũng được nhân lên, pixel hoàn toàn trong suốt (độ mờ 0.0) trong một hình ảnh dẫn đến pixel hoàn toàn trong suốt ở output. Điều này tương tự như dstIn, nhưng với các màu kết hợp.
Đối với một variant nhân các màu nhưng không nhân alpha channel, hãy xem xét điều chỉnh.

BlendMode.overlay

Nhân các component của ảnh nguồn và ảnh đích sau khi đã điều chỉnh chúng để có lợi cho đích.
Cụ thể, nếu giá trị đích nhỏ hơn, điều này nhân nó với giá trị nguồn, trong khi giá trị nguồn nhỏ hơn, nó nhân nghịch đảo của giá trị nguồn với nghịch đảo của giá trị đích, sau đó đảo ngược kết quả.
Đảo ngược các component có nghĩa là channel bão hòa hoàn toàn (màu trắng đục) được coi là giá trị 0.0 và các giá trị thường được coi là 0.0 (màu đen, trong suốt) được coi là 1.0.

BlendMode.plus

Tính tổng các component của ảnh nguồn và ảnh đích.
Độ trong suốt ở một pixel của một trong các hình ảnh làm giảm sự đóng góp của hình ảnh đó vào output pixel tương ứng, như thể màu của pixel đó trong hình ảnh đó tối hơn.
Điều này tương ứng với “Source plus Destination” Porter-Duff operator.

BlendMode.saturation

Lấy độ bão hòa của hình ảnh nguồn và màu sắc và độ sáng của hình ảnh đích.
Độ mờ của output image được tính theo cách tương tự như đối với srcOver.
Các vùng hoàn toàn trong suốt trong hình ảnh nguồn sẽ lấy độ bão hòa của chúng từ đích.

BlendMode.screen

Nhân nghịch đảo của các component của hình ảnh nguồn và ảnh đích, và nghịch đảo kết quả.
Đảo ngược các component có nghĩa là channel bão hòa hoàn toàn (màu trắng đục) được coi là giá trị 0.0 và các giá trị thường được coi là 0.0 (màu đen, trong suốt) được coi là 1.0.
Điều này về cơ bản giống như chế độ hòa trộn điều chế (modulate blend mode), nhưng với các giá trị của màu sắc được đảo ngược trước phép nhân và kết quả được đảo ngược lại trước khi hiển thị.
Điều này có thể dẫn đến các màu giống nhau hoặc nhạt hơn (nhân với màu đen, 1.0, kết quả là không thay đổi; nhân với màu trắng, 0.0, cho kết quả là màu trắng). Tương tự, trong alpha channel, nó chỉ có thể dẫn đến màu sắc mờ hơn.
Điều này có tác dụng tương tự như hai máy chiếu hiển thị hình ảnh của chúng trên cùng một màn hình đồng thời.

BlendMode.softLight

Sử dụng colorDodge cho các giá trị nguồn dưới 0.5 và colorBurn cho các giá trị nguồn trên 0.5.
Điều này dẫn đến một hiệu ứng tương tự nhưng nhẹ nhàng hơn so với overlay.

BlendMode.srcATop

Kết hợp hình ảnh nguồn trên hình ảnh đích, nhưng chỉ ở nơi nó chồng lên điểm đích.
Điều này tương ứng với “Source atop Destination” Porter-Duff operator.
Về cơ bản, đây là srcOver operator, nhưng với opacity channel của output được đặt thành của hình ảnh đích thay vì là sự kết hợp của cả hai opacity channel của hình ảnh.
Đối với một variant có đích ở trên cùng thay vì nguồn, hãy xem dstATop.

BlendMode.srcIn

Hiển thị hình ảnh nguồn, nhưng chỉ nơi hai hình ảnh chồng lên nhau (overlap). Hình ảnh đích không được hiển thị, nó chỉ được coi như một mặt nạ. Các color channel của điểm đích bị bỏ qua, chỉ có độ mờ có ảnh hưởng.
Để hiển thị hình ảnh đích thay thế, hãy xem xét dstIn.
Để đảo ngược ngữ nghĩa của mặt nạ (chỉ hiển thị nguồn nơi đích vắng mặt, thay vì nơi nó hiện diện), hãy xem xét srcOut.
Điều này tương ứng với “Source in Destination” Porter-Duff operator.

BlendMode.srcOut

Hiển thị hình ảnh nguồn, nhưng chỉ hiển thị ở nơi hai hình ảnh không chồng lên nhau. Hình ảnh đích không được hiển thị, nó chỉ được coi như một mặt nạ. Các color channel của điểm đích bị bỏ qua, chỉ có độ mờ có ảnh hưởng.
Để hiển thị hình ảnh đích thay thế, hãy xem xét dstOut.
Để đảo ngược semantic của mặt nạ (chỉ hiển thị nguồn nơi đích hiện diện), hãy xem xét srcIn.
Điều này tương ứng với “Source out Destination” Porter-Duff operator.

BlendMode.srcOver

Kết hợp hình ảnh nguồn với hình ảnh đích.
Đây là giá trị mặc định. Nó đại diện cho trường hợp trực quan nhất, trong đó các shape được vẽ trên đầu những gì bên dưới, với các khu vực trong suốt hiển thị lớp đích.
Điều này tương ứng với “Source over Destination” Porter-Duff operator, còn được gọi là Thuật toán của Họa sĩ (Painter’s Algorithm).

BlendMode.xor

Áp dụng bitwise xor operator cho ảnh nguồn và ảnh đích. Điều này để lại sự rõ rệt ở nơi chúng sẽ chồng lên nhau.
Điều này tương ứng với “Source xor Destination” Porter-Duff operator.

fit Property

Cách hình ảnh được hiển thị trên box. Giá trị của fit property là BoxFit enum.

  • contain
  • cover
  • fill
  • fitHeight
  • fitWidth
  • none
  • scaleDown
Center(
    child: new Container(
      width: double.infinity,
      height: double.infinity,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          image: new DecorationImage(
              image: new NetworkImage('http://jlouage.com/images/author.jpg'),
              fit: BoxFit.contain
          )
        ),
      ),
    ),
  );

contain

Càng lớn càng tốt trong khi vẫn chứa source hoàn toàn trong target box.

cover

Càng nhỏ càng tốt trong khi vẫn bao phủ toàn bộ target box.

fill

Fill vào target box bằng cách bóp méo aspect ratio của source.

fitHeight

Đảm bảo toàn bộ chiều cao của source được hiển thị, bất kể điều này có nghĩa là source tràn target box theo chiều ngang.

fitWidth

Đảm bảo toàn bộ chiều rộng của source được hiển thị, bất kể điều này có nghĩa là source overflows target box theo chiều dọc.

none

Căn chỉnh source bên trong target box (theo mặc định, căn giữa) và loại bỏ bất kỳ phần nào của source nằm bên ngoài box.
Source image không được thay đổi kích thước.

scaleDown

Căn chỉnh source trong target box (theo mặc định, căn giữa) và nếu cần, hãy thu nhỏ source để đảm bảo rằng source vừa với box.
Điều này giống nhưcontainnếu điều đó sẽ thu nhỏ hình ảnh, nếu không thì nó giống nhưnone.

repeat Property

Làm thế nào để tô bất kỳ phần nào của box mà sẽ không bị cover bởi hình ảnh. Giá trị của repeat propery là ImageRepeat enum.

  • noRepeat
  • repeat
  • repeatX
  • repeatY

noRepeat
Để các phần không được cover của box trong suốt.

Center(
    child: new Container(
      width: double.infinity,
      height: double.infinity,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
              repeat: ImageRepeat.noRepeat
          )
        ),
      ),
    ),
  );

repeat

Lặp lại hình ảnh theo cả hai hướng x và y cho đến khi box được lấp đầy.

Center(
    child: new Container(
      width: double.infinity,
      height: double.infinity,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
              repeat: ImageRepeat.repeat
          )
        ),
      ),
    ),
  );

repeatX

Lặp lại hình ảnh theo hướng x cho đến khi box được lấp đầy theo chiều ngang.

Center(
    child: new Container(
      width: double.infinity,
      height: double.infinity,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
              repeat: ImageRepeat.repeatX
          )
        ),
      ),
    ),
  );

repeatY

Lặp lại hình ảnh theo hướng y cho đến khi box được lấp đầy theo chiều dọc.

Center(
    child: new Container(
      width: double.infinity,
      height: double.infinity,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
              repeat: ImageRepeat.repeatY
          )
        ),
      ),
    ),
  );

matchTextDirection Property

Liệu có vẽ hình ảnh theo hướng của TextDirectionTextDirectionhay không. Giá trị là true hoặc false;

Nếu điều này là true, thì trong TextDirection.ltr context, hình ảnh sẽ được vẽ với điểm gốc của nó ở phía trên bên trái (hướng vẽ "bình thường" cho hình ảnh); và trong TextDirection.rtl context, hình ảnh sẽ được vẽ với hệ số tỷ lệ -1 theo hướng ngang sao cho điểm gốc ở trên cùng bên phải.

Border Property

Đường viền để vẽ phía trên màucolor,gradienthoặcimage.

Border Property coi như giá trị Border Class, Border.all Class & BorderDirectional Class.

Border & BorderDirectional nếu bạn muốn đặt đường viền cho một mặt cụ thể.

Border.all nếu bạn đặt đường viền cho tất cả các bên.

Trước tiên hãy sử dụng Border.all - Nó có 3 tham số,

  • color: màu của đường viền
  • width: chiều rộng của đường viền
  • style: kiểu viền, có 2 kiểu.

BorderStyle.solid và BorderStyle.none

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          border: new Border.all(
            color: Colors.green,
            width: 5.0,
            style: BorderStyle.solid
          ),
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

Bây giờ chúng ta sẽ sử dụng Border Class thay vì Border.all. Border Class lấy 4 tham số trên, dưới, trái và phải. Giá trị của mọi tham số phải là BorderSide Class.

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          border: new Border(
            top: new BorderSide(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
            ),
          ),
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

Bây giờ, hãy sử dụng BorderDirectional.

BorderDirectional giống như Border Class có 4 tham số, nhưng thay vì trái và phải, nó sẽ bắt đầu và kết thúc.

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          border: new BorderDirectional(
            top: new BorderSide(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
            ),
            start: new BorderSide(
                color: Colors.green,
                width: 5.0,
                style: BorderStyle.solid
            ),
          ),
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

borderRadius Property

Bạn sử dụng borderRadius nếu bạn muốn làm cho góc của box được bo tròn,

Note: borderRadius chỉ áp dụng cho các box có hình chữ nhật.

Giá trị của borderRadius là BorderRadius.all, BorderRadius.only, BorderRadius.circular, BorderRadius.horizontal, BorderRadius.vertical.

Ngoài ra bạn có thể sử dụng thay cho BorderRadius, BorderRadiusDirectional với các method tương tự ở trên. Nhưng trong các tham số thay vì trái và phải, bạn sẽ sử dụng bắt đầu và kết thúc.

BorderRadius.all Tạo bán kính đường viền trong đó tất cả các bán kính đều làradius.

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          border: new Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
          ),
          borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

BorderRadius.circular Tạo bán kính đường viền trong đó tất cả các bán kính đều là Radius.circular (bán kính).

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          border: new Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
          ),
          borderRadius: new BorderRadius.circular(20.0),
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

Kết quả tương tự như BorderRadius.all nhưng bạn có thể nhập giá trị trực tiếp dưới dạng gấp đôi. không cần thêm Radius Class.

BorderRadius.horizontal Tạo bán kính đường viền đối xứng theo chiều ngang trong đó các cạnh bên trái và bên phải của hình chữ nhật có cùng bán kính.

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          border: new Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
          ),
          borderRadius: new BorderRadius.horizontal(
            left: new Radius.circular(20.0),
            //right: new Radius.circular(20.0),
          ),
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

BorderRadius.vertical Tạo bán kính đường viền đối xứng theo chiều dọc trong đó các cạnh trên và dưới của hình chữ nhật có cùng bán kính.

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          border: new Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
          ),
          borderRadius: new BorderRadius.vertical(
            top: new Radius.circular(20.0),
            //bottom: new Radius.circular(20.0),
          ),
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

BorderRadius.only Tạo bán kính đường viền chỉ với các giá trị khác 0 đã cho. Các góc khác sẽ là góc vuông.

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          border: new Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
          ),
          borderRadius: new BorderRadius.only(
            topLeft: new Radius.circular(20.0),
            //topRight: new Radius.circular(20.0),
            //bottomRight: new Radius.circular(20.0),
            bottomLeft: new Radius.circular(20.0),
          ),
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

Ngoài ra, bạn có thể sử dụng thay thế cho Radius.circular Class, Radius.elliptical.

Radius.elliptical lấy 2 tham số x & y.

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          border: new Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
          ),
          borderRadius: new BorderRadius.only(
            topLeft: new Radius.elliptical(40.0, 10.0),
            //topRight: new Radius.circular(20.0),
            //bottomRight: new Radius.circular(20.0),
            bottomLeft: new Radius.circular(20.0),
          ),
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

boxShadow Property

Danh sách các shadow cast bởi box này phía sau box. Bóng đổ theo hình dạng của box.

Giá trị của boxShadow là một danh sách của BoxShadow class. Bạn có thể sử dụng multipleBoxShadow trong danh sách.

BoxShadow class có 4 tham số

  • color: Màu của bóng
  • offset: Độ dịch chuyển của bóng khỏi box.
  • blurRadius: Độ lệch chuẩn của Gaussian đối với hình dạng của box.
  • spreadRadius: Số lượng box phải được thổi phồng trước khi áp dụng hiệu ứng làm mờ.

Ví dụ đầu tiên, chúng ta sử dụng màu sắc và offset.

Giá trị của tham số offset là một Offset class và lấy 2 tham số kép x và y.

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          color: Colors.white,
          border: new Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
          ),
          borderRadius: new BorderRadius.only(
            topLeft: new Radius.elliptical(40.0, 10.0),
            bottomLeft: new Radius.circular(20.0),
          ),
          boxShadow: [
            new BoxShadow(
              color: Colors.red,
              offset: new Offset(20.0, 10.0),
            )
          ],
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

Chúng ta đã chuyển shadow 20 trên trục X và 10 trên trục Y. Shadow là thể rắn.

Hãy thêm một BlurRadius vào nó để làm cho nó như một cái bóng thực sự.

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          color: Colors.white,
          border: new Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
          ),
          borderRadius: new BorderRadius.only(
            topLeft: new Radius.elliptical(40.0, 10.0),
            bottomLeft: new Radius.circular(20.0),
          ),
          boxShadow: [
            new BoxShadow(
              color: Colors.red,
              offset: new Offset(20.0, 10.0),
              blurRadius: 20.0,
            )
          ],
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

Bây giờ chúng ta sẽ thêm nhiều spread hơn cho shadow. Chúng ta sử dụng spreadRadius.

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      color: Colors.white,
      child: new Container(
        decoration: new BoxDecoration(
          color: Colors.white,
          border: new Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
          ),
          borderRadius: new BorderRadius.only(
            topLeft: new Radius.elliptical(40.0, 10.0),
            bottomLeft: new Radius.circular(20.0),
          ),
          boxShadow: [
            new BoxShadow(
              color: Colors.red,
              offset: new Offset(20.0, 10.0),
              blurRadius: 20.0,
              spreadRadius: 40.0
            )
          ],
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

Bây giờ, hãy sử dụng nhiều BoxShadow.

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      child: new Container(
        decoration: new BoxDecoration(
          color: Colors.white,
          border: new Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
          ),
          boxShadow: [
            new BoxShadow(
              color: Colors.red,
              offset: new Offset(20.0, 10.0),
              blurRadius: 20.0,
              spreadRadius: 40.0
            ),
            new BoxShadow(
                color: Colors.yellow,
                offset: new Offset(20.0, 10.0),
                blurRadius: 20.0,
                spreadRadius: 20.0
            ),
            new BoxShadow(
                color: Colors.green,
                offset: new Offset(10.0, 5.0),
                blurRadius: 20.0,
                spreadRadius: 5.0
            )
          ],
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

shape Property

Shape để fill màu background, gradient và hình ảnh vào và để đúc dưới dạng boxShadow.

Giá trị của shape property là BoxShape enum

  • BoxShape.rectangle
  • BoxShape.circle

Note: Nếu đây là BoxShape.circle thì borderRadius bị bỏ qua.

new Center(
    child: new Container(
      width: 200.0,
      height: 200.0,
      child: new Container(
        decoration: new BoxDecoration(
          color: Colors.white,
          border: new Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
          ),
          boxShadow: [
            new BoxShadow(
              color: Colors.red,
              offset: new Offset(20.0, 10.0),
              blurRadius: 20.0,
              spreadRadius: 40.0
            )
          ],
          shape: BoxShape.circle,
          image: new DecorationImage(
              image: new AssetImage('assets/images/JL-Logo-150.png'),
          )
        ),
      ),
    ),
  );

Mong rằng bạn sẽ thích bài viết này.

Bài viết được lược dịch từ Julien Louage.

Bài viết liên quan

Flutter Tutorial 2022: Giới thiệu Flutter Travel App

Trong series này, chúng ta sẽ cùng nhau thực hiện ứng dụng Travel App với một bản UI Design vô cùng đẹp mắt, thu hút có sẵn....

Flutter Tutorial 2022: Giới thiệu Flutter Travel App
So sánh StatelessWidget và StatefulWidget

Trong bài viết này, các bạn sẽ có cái nhìn tổng quát về hai loại widget lớn nhất là StatelessWidget và StatefulWidget....

So sánh StatelessWidget và StatefulWidget
Tổng hợp các Shortcuts, Extensions & Settings trong VSCode khi lập trình Flutter

Trong bài viết này, mình sẽ liệt kê cho bạn các shortcuts, extensions, setting mà bạn nên sử dụng để lập trình Flutter hàng ngày....

Tổng hợp các Shortcuts, Extensions & Settings trong VSCode khi lập trình Flutter
[Phần 1] Những extension cần thiết khi làm việc với Flutter trên VS Code

VS Code là 1 text editor tuyệt vời được phát triển bởi Mircosoft. Đây là một trong các công cụ được developer trên toàn thế giới yêu thích vì sự tiện lợi, dễ dùng và nó chứa hàng ngàn, thậm chí trăm ngàn các extension phục vụ cho bạn trong quá trình bạn phát triển phần mềm....

[Phần 1] Những extension cần thiết khi làm việc với Flutter trên VS Code
Fix lỗi Flutter 3 không thể build app trên iOS

Cách fix lỗi Flutter 3 không thể build và run được app trên iOS với video hướng dẫn chia tiết...

Fix lỗi Flutter 3 không thể build app trên iOS
You've successfully subscribed to 200Lab Blog
Great! Next, complete checkout for full access to 200Lab Blog
Xin chào mừng bạn đã quay trở lại
OK! Tài khoản của bạn đã kích hoạt thành công.
Success! Your billing info is updated.
Billing info update failed.
Your link has expired.