Thứ Sáu, 10 tháng 10, 2014

[JAVAFX] Phần 7 : Paint - Vẽ màu

Phần 7 : Paint - Vẽ màu
Ở những phần trước, chúng ta sử dụng rất nhiều đối tượng Color để trang trí màu sắc cho hình vẽ cũng như giao diện. Trong phần này, chúng ta sẽ tìm hiểu chi tiết về Color class, cũng như các class trong javafx.scene.paint packet.
Javafx.scene.paint packet bao gồm các class sau:
+ Color
+ ImagePattern
+ LinearGradient
+ Material
+ Paint
+ PhongMaterial
+ RadialGradient
+ Stop
Trong đó :
- Paint là abstract class để sử dụng chung các class con của nó: Color, ImagePattern, LinearGradient và RadialGradient.
- Material là abstract class chứa class con PhongMaterial.
Chúng ta lần lượt tìm hiểu những class này:
I. Color :
Color class được sử dụng để biểu diễn color (màu sắc) theo mặc định RGB. Mỗi color có một giá trị alpha mặc định là 1.0 hay 255. Giá trị alpha định nghĩa độ trong suốt của color và được biểu diễn bằng 1 giá trị kiểu double trong khoảng 0.0 -> 1.0 hay 0-> 255. Giá trị alpha là 1.0 hoặc 255 có nghĩa là chắn sáng hoàn toàn, ngược lại giá trị 0.0 hoặc 0 nghĩa là trong suốt hoàn toàn.
Color có thể được tạo bằng hàm dựng hoặc các phương thức kiểu static.
Ví dụ :
Color c = Color.GREEN;
// định nghĩa color theo định dạng RGB, trong đó Red = 0, Blue = 0, Green = 255 , alpha= 1.0
Color c = new Color(0,0,255,1.0);
Color c = Color.color(0,0,255);
Color c = Color.color(0,0,255,0.5);
Color c = Color.rgb(0,0,255);
// định nghĩa color theo định dạng HSB, trong đó hue = 270, saturation = 1.0 và brightness = 1.0 , alpha mặc định là 1.0
Color c = Color.hsb(270,1.0,1.0);
Một số phương thức của Color class :
Kiểu trả về
Phương thức
Miêu tả
Color
brighter()
tạo ra một màu mới tươi hơn màu của color này.
Color
darker()
tạo ra một màu mới tối hơn màu của color này.
static Color
color(double red, double green, double blue)
tạo ra đối tượng Color với màu sắc theo định dạng RGB, các giá trị trong khoảng 0.0 -> 1.0 hoặc 0 -> 255
static Color
color(double red, double green, double blue, double opacity)
tạo ra đối tượng Color với màu sắc theo định dạng RGB và độ trong suốt
double
getBlue()
trả về thành phần blue của color, giá trị nằm trong khoảng 0.0 ->1.0
double
getGreen()
trả về thành phần green của color, giá trị nằm trong khoảng 0.0 ->1.0
double
getRed()
trả về thành phần red của color, giá trị nằm trong khoảng 0.0 ->1.0
double
getBrightness()
trả về thành phần brightness của color.
double
getOpacity()
trả về độ trong suốt của color, giá trị nằm trong khoảng 0.0 ->1.0
II. ImagePattern :
ImagePattern được sử dụng để tạo background cho hình vẽ bằng tập tin hình ảnh.
Hình minh họa :
Hình trên là một hình nón và hình tròn sử dụng ImagePattern để tạo background là một tập tin hình ảnh.
Cách sử dụng :
III. Stop :
javafx.scene.paint.Stop được sử dụng để định nghĩa một màu sắc tham gia trong gradient (độ chênh lệch dần màu sắc). Có 2 class trong Paint sử dụng Stop : javafx.scene.paint.LinearGradient javafx.scene.paint.RadialGradient.
Các tham số chính dành cho đối tượng Stop:
+ offset : có giá trị kiểu double từ 0 ->1, thể hiện vị trí của Stop trong gradient.
+ color : là đối tượng javafx.scene.paint.Color class, định nghĩa màu sắc dành cho đối tượng Stop.
Cách sử dụng :
IV.LinearGrdient :
LinearGradient class được sử dụng để tạo background cho hình vẽ bằng những màu sắc được định dạng tuyến tính:
Các tham số chính dành LinearGradient :
- startX, startY, endX, endY: đây là các giá trị kiểu double, thể hiện khoảng cách mà Gradient được biểu diễn trong khoảng cách này. Nếu khoảng cách này bằng 0, hình vẽ của bạn sẽ không có gradient và background sẽ là màu gần startX hoặc startY nhất.
- proportional: giá trị kiểu boolean.
+ Nếu giá trị này là true, giá trị của startX, startY, endX, endY nằm trong khoảng 0 -> 1. startX = 0 tương ứng là top , startY = 0 : left, endX = 1 : bottom, endY = 1 : right của hình vẽ.
+ Nếu giá trị này là false, giá trị của startX, startY, endX, endY là tọa độ màn hình.
- cycleMethoad : là đối tượng của javafx.scene.paint.CycleMethod class. Class này được sử dụng để định nghĩa màu sắc dành cho các vùng còn lại trừ vùng đã dành cho gradient.
+ CycleMethod.NO_CYCLE : sử dụng màu cuối cùng để lắp đầy vùng còn lại của hình vẽ.
+ CycleMethod.REFLECT : 2 định dạng màu sắc start-to-end và end-to-start được sử dụng để lắp đầy vùng còn lại của hình vẽ.
+ CycleMethod.REPEAT : lặp lại định dạng gradient để lắp đầy vùng còn lại của hình vẽ.
- Mảng đối tượng Stop.
Ví dụ : vẽ 3 vuông như minh họa :
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class exampleStopGradient extends Application {

   public void start(Stage primaryStage) {
      
       // Định nghĩa 1 mảng đối tượng Stop gồm 3 đối tượng Stop
       // tương đương 3 màu YELLOW, RED, GREEN
       Stop[] stops = new Stop[]{
           new Stop(0, Color.YELLOW),
           new Stop(0.5, Color.RED),
           new Stop(1, Color.GREEN)
       };

       //--------------- Hình vuông thứ nhất---------------------
       // startX = 0 : top, startY = 0 : right, endX = 1 : bottom, endY = 1 :right
       // gradient được biểu diễn từ đầu đến cuối hình vẽ
       // các vùng còn lại theo định dạng CycleMethod.NO_CYCLE
       // sratX <> endX và startY <> endY, linearGradient có dạng xiên
       LinearGradient linearGradient1 =
                               new LinearGradient(0, 0, 1, 1, true, CycleMethod.NO_CYCLE, stops);
       Rectangle rectangle1 = new Rectangle(10, 10, 100, 100);
       rectangle1.setFill(linearGradient1);

       //--------------- Hình vuông thứ hai------------------
       // startX = 125, startY = 10 là tọa độ điểm bắt đầu của gradient
       // endX = 225, endY = 10 là tọa độ điểm kết thúc của gradient
       // các vùng còn lại theo định dạng CycleMethod.NO_CYCLE
       // sratX <> endX và startY = endY, linearGradient có dạng đứng
       LinearGradient linearGradient2 =
                     new LinearGradient(125, 10, 225, 10, false, CycleMethod.NO_CYCLE, stops);
       Rectangle rectangle2 = new Rectangle(125, 10, 100, 100);
       rectangle2.setFill(linearGradient2);

        //--------------- Hình vuông thứ ba------------------
       // sratX = endX và startY <> endY, linearGradient có dạng ngang
       LinearGradient linearGradient3 =
                                new LinearGradient(0, 0, 0, 1, true, CycleMethod.NO_CYCLE, stops);
       Rectangle rectangle3 = new Rectangle(240, 10, 100, 100);
       rectangle3.setFill(linearGradient3);

       Group root = new Group();
       root.getChildren().add(rectangle1);
       root.getChildren().add(rectangle2);
       root.getChildren().add(rectangle3);

       Scene scene = new Scene(root, 300, 250);

       primaryStage.setTitle("Hello World!");
       primaryStage.setScene(scene);
       primaryStage.show();
   }

   public static void main(String[] args) {
       launch(args);
   }
}
V. RadialGradient:
Nếu như LinearGradient tạo ra gradient bằng các đường thẳng màu sắc, thì RadialGradient tạo ra gradient bằng các vòng tròn màu sắc.
Các tham số chính dành cho RadialGradient :
- focusAngle : kiểu double, là giá trị của góc được tính từ đường thẳng nằm ngang qua điểm trung tâm của gradient theo ngược chiều kim đồng hồ, giá trị của nó nằm trong khoảng từ 0 -> 360
- focusDistance : kiểu double, là khoảng cách từ điểm trung tâm của gradient đến focus point. focusDistance kết hợp với focusAngle để tìm ra focus point. Focus point là tọa độ điểm mà từ đó tạo ra gradient. Giá trị của focusDistance nằm trong khoảng -1 -> 1.
+ Nếu từ -1->0, gradient sẽ hướng về bên trái.
+ Nếu từ 0->1, gradient sẽ hướng về bên phải.
- centerX, centerY : kiểu double, là tọa độ trung tâm của gradient.
-  radius : kiểu double, là bán kính của gradient.
- proportional: kiểu boolean, ý nghĩa tương tự như proportional của LinearGradient.
+ Nếu giá trị này là true, giá trị của centerX, centertY nằm trong khoảng 0 -> 1. centerX = 0 tương ứng là top , centerX = 0.5 : center , centerX = 1 : bottom, centerY = 0 tương ứng là left , centerY = 0.5 : center , centerY = 1 : right
+ Nếu giá trị này là false, giá trị của centerX, centerY là tọa độ màn hình.
- cycleMethoad : là đối tượng của javafx.scene.paint.CycleMethod class. Class này được sử dụng để định nghĩa màu sắc dành cho các vùng còn lại trừ vùng đã dành cho gradient.
+ CycleMethod.NO_CYCLE : sử dụng màu cuối cùng để lắp đầy vùng còn lại của hình vẽ.
+ CycleMethod.REFLECT : 2 định dạng màu sắc start-to-end và end-to-start được sử dụng để lắp đầy vùng còn lại của hình vẽ.
+ CycleMethod.REPEAT : lặp lại định dạng gradient để lắp đầy vùng còn lại của hình vẽ.
- Mảng đối tượng Stop.
Ví dụ : vẽ 3 vuông như minh họa :
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class exampleRadioGradient extends Application {

   @Override
   public void start(Stage primaryStage) {
       // Định nghĩa 1 mảng đối tượng Stop gồm 3 đối tượng Stop
       // tương đương 3 màu YELLOW, RED, GREEN
       Stop[] stops = new Stop[]{
           new Stop(0, Color.YELLOW),
           new Stop(0.5, Color.RED),
           new Stop(1, Color.GREEN)
       };

       //--------------- Hình tròn thứ nhất---------------------
       // centerX = 0.5 : center, centerY = 0.5 : center
       // focus angle = 0, focus distance = 0 : focus point là center
       // các vùng còn lại theo định dạng CycleMethod.NO_CYCLE
       RadialGradient radialGradient1 =
                   new RadialGradient(0, 0, 0.5, 0.5, 0.5, true, CycleMethod.NO_CYCLE, stops);
       Circle circle1 = new Circle(60, 60, 50);
       circle1.setFill(radialGradient1);

       //--------------- Hình tròn thứ hai------------------
       // centerX = 0.5 : center, centerY = 0.5 : center
       // focus angle = 0, focus distance = -1 : focus point là left
       RadialGradient radialGradient2 =
                   new RadialGradient(0, -1, 0.5, 0.5, 0.5, true, CycleMethod.NO_CYCLE, stops);
       Circle circle2 = new Circle(170, 60, 50);
       circle2.setFill(radialGradient2);

       //--------------- Hình tròn thứ ba------------------
       // focus angle = 0, focus distance = 1 : focus point là right
       RadialGradient radialGradient3 =
                   new RadialGradient(0, 1, 0.5, 0.5, 0.5, true, CycleMethod.NO_CYCLE, stops);
       Circle circle3 = new Circle(280, 60, 50);
       circle3.setFill(radialGradient3);

       Group root = new Group();
       root.getChildren().add(circle1);
       root.getChildren().add(circle2);
       root.getChildren().add(circle3);

       Scene scene = new Scene(root, 400, 250);

       primaryStage.setTitle("Hello World!");
       primaryStage.setScene(scene);
       primaryStage.show();
   }

   public static void main(String[] args) {
       launch(args);
   }
}
VI. PhongMaterial :
Material class được sử dụng để tạo hiệu ứng hình vẽ 3D. PhongMaterial class định nghĩa các thuộc tính hổ trợ các hình vẽ 3D như :
- DiffuseColor : khuếch tán màu sắc.
- DiffuseMap: khuếch tán hình ảnh
- SpecularMap : phản chiếu hình ảnh
- SpecularColor : phản chiếu màu sắc
- SpecularPower: cường độ phản chiếu  
- BumpMap (normal map)
- SelfIlluminationMap
Để sử dụng các thuộc tính này, đối tượng Material class sử dụng phương thức set + tên thuộc tính(). Mặt khác, các hình vẽ 3D sử dụng phương thức setMaterial() với đầu vào là một đối tượng Material class để thể hiện các tính năng của Material class lên hình vẽ 3D.
Ví dụ : vẽ 1 hình 3D, sử dụng một số thuộc tính của Material class :
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Cylinder;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;

public class exampleMaterial extends Application {

   public void start(Stage primaryStage) {

       // tạo một hình vẽ 3D
       Cylinder cylinder = new Cylinder(100, 100, 100);
       cylinder.setLayoutX(300);
       cylinder.setLayoutY(300);
       cylinder.getTransforms().add(new Rotate(20, Rotate.X_AXIS));
       cylinder.getTransforms().add(new Rotate(10, Rotate.Z_AXIS));
       cylinder.getTransforms().add(new Rotate(30, Rotate.Y_AXIS));

       // Tạo đối tượng Mareial class
       PhongMaterial material = new PhongMaterial();
       // sử dụng thuộc tính DiffuseColor
       material.setDiffuseColor(Color.YELLOW);
       // áp dụng material vào hình vẽ
       cylinder.setMaterial(material);

       Group root = new Group();
       root.getChildren().add(cylinder);

       Scene scene = new Scene(root, 600, 600);

       primaryStage.setTitle("Hello World!");
       primaryStage.setScene(scene);
       primaryStage.show();
   }

   public static void main(String[] args) {
       launch(args);
   }
}