原文: http://zetcode.com/gui/javafx/canvas/

Canvas是可以使用GraphicsContext提供的一组图形命令绘制的图像。 它是进行绘图的高级工具。

GraphicsContext用于使用缓冲区向Canvas发出绘图调用。

简单的线条

在第一个示例中,我们绘制了简单的线条。 线是基本的图形基元。 需要两个坐标才能形成一条线。

SimpleLinesEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.scene.Scene;
  4. import javafx.scene.canvas.Canvas;
  5. import javafx.scene.canvas.GraphicsContext;
  6. import javafx.scene.layout.Pane;
  7. import javafx.stage.Stage;
  8. /**
  9. * ZetCode JavaFX tutorial
  10. *
  11. * This program draws three lines which
  12. * form a rectangle.
  13. *
  14. * Author: Jan Bodnar
  15. * Website: zetcode.com
  16. * Last modified: June 2015
  17. */
  18. public class SimpleLinesEx extends Application {
  19. @Override
  20. public void start(Stage stage) {
  21. initUI(stage);
  22. }
  23. private void initUI(Stage stage) {
  24. Pane root = new Pane();
  25. Canvas canvas = new Canvas(300, 300);
  26. GraphicsContext gc = canvas.getGraphicsContext2D();
  27. drawLines(gc);
  28. root.getChildren().add(canvas);
  29. Scene scene = new Scene(root, 300, 250, Color.WHITESMOKE);
  30. stage.setTitle("Lines");
  31. stage.setScene(scene);
  32. stage.show();
  33. }
  34. private void drawLines(GraphicsContext gc) {
  35. gc.beginPath();
  36. gc.moveTo(30.5, 30.5);
  37. gc.lineTo(150.5, 30.5);
  38. gc.lineTo(150.5, 150.5);
  39. gc.lineTo(30.5, 30.5);
  40. gc.stroke();
  41. }
  42. public static void main(String[] args) {
  43. launch(args);
  44. }
  45. }

该示例绘制了形成矩形的三条线。

  1. Canvas canvas = new Canvas(300, 300);

Canvas的宽度和高度指定了将画布绘制命令渲染到的图像的大小。 所有绘图操作都被裁剪到该图像的边界。

  1. GraphicsContext gc = canvas.getGraphicsContext2D();

getGraphicsContext2D()返回与画布关联的GraphicsContext

  1. drawLines(gc);

该图形委托给drawLines()方法。

  1. gc.beginPath();

线图元表示为路径元素。 beginPath()方法开始一个新路径。

  1. gc.moveTo(30.5, 30.5);

moveTo()方法将当前路径的起点移动到指定的坐标。

  1. gc.lineTo(150.5, 30.5);
  2. gc.lineTo(150.5, 150.5);
  3. gc.lineTo(30.5, 30.5);

lineTo()方法将线段添加到当前路径。

  1. gc.stroke();

stroke()方法使用当前的描边绘图描边路径。

JavaFX 画布 - 图1

图:直线

描边和填充

描边用于绘制形状的轮廓。 填充用于绘制形状的内部。

StrokeFillEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.scene.Scene;
  4. import javafx.scene.canvas.Canvas;
  5. import javafx.scene.canvas.GraphicsContext;
  6. import javafx.scene.layout.Pane;
  7. import javafx.scene.paint.Color;
  8. import javafx.stage.Stage;
  9. /**
  10. * ZetCode JavaFX tutorial
  11. *
  12. * This program draws an outline of a circle
  13. * and fills an interior of a circle.
  14. *
  15. * Author: Jan Bodnar
  16. * Website: zetcode.com
  17. * Last modified: June 2015
  18. */
  19. public class StrokeFillEx extends Application {
  20. @Override
  21. public void start(Stage stage) {
  22. initUI(stage);
  23. }
  24. private void initUI(Stage stage) {
  25. Pane root = new Pane();
  26. Canvas canvas = new Canvas(300, 300);
  27. GraphicsContext gc = canvas.getGraphicsContext2D();
  28. doDrawing(gc);
  29. root.getChildren().add(canvas);
  30. Scene scene = new Scene(root, 300, 250, Color.WHITESMOKE);
  31. stage.setTitle("Stroke and fill");
  32. stage.setScene(scene);
  33. stage.show();
  34. }
  35. private void doDrawing(GraphicsContext gc) {
  36. gc.setStroke(Color.FORESTGREEN.brighter());
  37. gc.setLineWidth(5);
  38. gc.strokeOval(30, 30, 80, 80);
  39. gc.setFill(Color.FORESTGREEN);
  40. gc.fillOval(130, 30, 80, 80);
  41. }
  42. public static void main(String[] args) {
  43. launch(args);
  44. }
  45. }

该示例绘制了圆的轮廓并填充了圆的内部。

  1. gc.setStroke(Color.FORESTGREEN.brighter());

setStroke()方法设置当前的笔触绘图属性。 默认颜色是黑色。 GraphicsContext的笔触方法使用该属性。

  1. gc.setLineWidth(5);

setLineWidth()设置当前线宽。

  1. gc.strokeOval(130, 30, 80, 80);

strokeOval()方法使用当前的描边绘图描边椭圆。

  1. gc.setFill(Color.FORESTGREEN);

setFill()方法设置当前的填充涂料属性。 默认颜色是黑色。 GraphicsContext的填充方法使用该属性。

  1. gc.fillOval(30, 30, 80, 80);

fillOval()使用当前的填充颜料填充椭圆形。

JavaFX 画布 - 图2

图:描边和填充

颜色

Color类用于处理 JavaFX 中的颜色。 有许多预定义的颜色。 可以使用 RGB 或 HSB 颜色模型创建自定义颜色值。

ColoursEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.scene.Scene;
  4. import javafx.scene.canvas.Canvas;
  5. import javafx.scene.canvas.GraphicsContext;
  6. import javafx.scene.layout.Pane;
  7. import javafx.scene.paint.Color;
  8. import javafx.stage.Stage;
  9. /**
  10. * ZetCode JavaFX tutorial
  11. *
  12. * This program draws six circles in six
  13. * different colours.
  14. *
  15. * Author: Jan Bodnar
  16. * Website: zetcode.com
  17. * Last modified: June 2015
  18. */
  19. public class ColoursEx extends Application {
  20. @Override
  21. public void start(Stage stage) {
  22. initUI(stage);
  23. }
  24. private void initUI(Stage stage) {
  25. Pane root = new Pane();
  26. Canvas canvas = new Canvas(300, 300);
  27. GraphicsContext gc = canvas.getGraphicsContext2D();
  28. drawShapes(gc);
  29. root.getChildren().add(canvas);
  30. Scene scene = new Scene(root, 280, 200, Color.WHITESMOKE);
  31. stage.setTitle("Colours");
  32. stage.setScene(scene);
  33. stage.show();
  34. }
  35. private void drawShapes(GraphicsContext gc) {
  36. gc.setFill(Color.CADETBLUE);
  37. gc.fillOval(30, 30, 50, 50);
  38. gc.setFill(Color.DARKRED);
  39. gc.fillOval(110, 30, 50, 50);
  40. gc.setFill(Color.STEELBLUE);
  41. gc.fillOval(190, 30, 50, 50);
  42. gc.setFill(Color.BURLYWOOD);
  43. gc.fillOval(30, 110, 50, 50);
  44. gc.setFill(Color.LIGHTSEAGREEN);
  45. gc.fillOval(110, 110, 50, 50);
  46. gc.setFill(Color.CHOCOLATE);
  47. gc.fillOval(190, 110, 50, 50);
  48. }
  49. public static void main(String[] args) {
  50. launch(args);
  51. }
  52. }

该示例使用预定义的颜色值绘制六个圆。

  1. gc.setFill(Color.CADETBLUE);

预定义的Color.CADETBLUE颜色设置为当前填充。

  1. gc.fillOval(30, 30, 50, 50);

圆形对象的内部填充有当前的fill属性。

JavaFX 画布 - 图3

图:颜色

渐变

在计算机图形学中,渐变是从浅到深或从一种颜色到另一种颜色的阴影的平滑混合。 在绘图和绘图程序中,渐变用于创建彩色背景和特殊效果以及模拟灯光和阴影。 有两种类型的渐变:线性渐变和径向渐变。

线性渐变

线性渐变是沿直线平滑混合颜色。 它由LinearGradient类定义。

LinearGradientEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.scene.Scene;
  4. import javafx.scene.canvas.Canvas;
  5. import javafx.scene.canvas.GraphicsContext;
  6. import javafx.scene.layout.Pane;
  7. import javafx.scene.paint.Color;
  8. import javafx.scene.paint.CycleMethod;
  9. import javafx.scene.paint.LinearGradient;
  10. import javafx.scene.paint.Stop;
  11. import javafx.stage.Stage;
  12. /*
  13. * ZetCode JavaFX tutorial
  14. *
  15. * This program draws a linear gradient.
  16. *
  17. * Author: Jan Bodnar
  18. * Website: zetcode.com
  19. * Last modified: August 2016
  20. */
  21. public class LinearGradientEx extends Application {
  22. @Override
  23. public void start(Stage stage) {
  24. initUI(stage);
  25. }
  26. private void initUI(Stage stage) {
  27. Pane root = new Pane();
  28. Canvas canvas = new Canvas(300, 300);
  29. GraphicsContext gc = canvas.getGraphicsContext2D();
  30. doDrawing(gc);
  31. root.getChildren().add(canvas);
  32. Scene scene = new Scene(root, 300, 250, Color.WHITESMOKE);
  33. stage.setTitle("Linear gradient");
  34. stage.setScene(scene);
  35. stage.show();
  36. }
  37. private void doDrawing(GraphicsContext gc) {
  38. Stop[] stops1 = new Stop[] { new Stop(0.2, Color.BLACK),
  39. new Stop(0.5, Color.RED), new Stop(0.8, Color.BLACK)};
  40. LinearGradient lg1 = new LinearGradient(0, 0, 1, 0, true,
  41. CycleMethod.NO_CYCLE, stops1);
  42. gc.setFill(lg1);
  43. gc.fillRect(50, 30, 200, 180);
  44. }
  45. public static void main(String[] args) {
  46. launch(args);
  47. }
  48. }

在示例中,我们用线性渐变填充矩形。

  1. Stop[] stops1 = new Stop[] { new Stop(0.2, Color.BLACK),
  2. new Stop(0.5, Color.RED), new Stop(0.8, Color.BLACK)};

我们定义渐变的停止点。 它们指定如何沿渐变分布颜色。

  1. LinearGradient lg1 = new LinearGradient(0, 0, 1, 0, true,
  2. CycleMethod.NO_CYCLE, stops1);

前四个参数指定渐变绘制所沿的线。 第五个参数是比例参数,它设置坐标是否与该渐变填充的形状成比例。 第六个参数设置渐变的循环方法。 最后一个参数为停止点。

JavaFX 画布 - 图4

图:LinearGradient

径向渐变

径向渐变是圆和焦点之间颜色或阴影的平滑混合。 径向渐变由RadialGradient类定义。

RadialGradientEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.scene.Scene;
  4. import javafx.scene.canvas.Canvas;
  5. import javafx.scene.canvas.GraphicsContext;
  6. import javafx.scene.layout.Pane;
  7. import javafx.scene.paint.Color;
  8. import javafx.scene.paint.CycleMethod;
  9. import javafx.scene.paint.RadialGradient;
  10. import javafx.scene.paint.Stop;
  11. import javafx.stage.Stage;
  12. /*
  13. * ZetCode JavaFX tutorial
  14. *
  15. * This program draws a radial gradient.
  16. *
  17. * Author: Jan Bodnar
  18. * Website: zetcode.com
  19. * Last modified: August 2016
  20. */
  21. public class RadialGradientEx extends Application {
  22. @Override
  23. public void start(Stage stage) {
  24. initUI(stage);
  25. }
  26. private void initUI(Stage stage) {
  27. Pane root = new Pane();
  28. Canvas canvas = new Canvas(300, 300);
  29. GraphicsContext gc = canvas.getGraphicsContext2D();
  30. doDrawing(gc);
  31. root.getChildren().add(canvas);
  32. Scene scene = new Scene(root, 300, 250, Color.WHITESMOKE);
  33. stage.setTitle("Radial gradient");
  34. stage.setScene(scene);
  35. stage.show();
  36. }
  37. private void doDrawing(GraphicsContext gc) {
  38. Stop[] stops1 = new Stop[] { new Stop(0, Color.RED),
  39. new Stop(1, Color.BLACK)};
  40. RadialGradient lg1 = new RadialGradient(0, 0, 0.5, 0.5, 0.8, true,
  41. CycleMethod.NO_CYCLE, stops1);
  42. gc.setFill(lg1);
  43. gc.fillOval(30, 30, 150, 150);
  44. }
  45. public static void main(String[] args) {
  46. launch(args);
  47. }
  48. }

该示例使用径向渐变填充圆。

  1. Stop[] stops1 = new Stop[] { new Stop(0, Color.RED),
  2. new Stop(1, Color.BLACK)};

我们定义渐变的终止值。

  1. RadialGradient lg1 = new RadialGradient(0, 0, 0.5, 0.5, 0.8, true,
  2. CycleMethod.NO_CYCLE, stops1);

创建了一个径向渐变。 前两个参数是聚焦角和聚焦距离。 接下来的两个参数是渐变圆的圆心的 x 和 y 坐标。 第五个参数是定义颜色渐变范围的圆的半径。

JavaFX 画布 - 图5

图:RadialGradient

形状

矩形,椭圆形,弧形是基本的几何形状。 GraphicsContext包含用于绘制这些形状的轮廓和内部的方法。

ShapesEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.scene.Scene;
  4. import javafx.scene.canvas.Canvas;
  5. import javafx.scene.canvas.GraphicsContext;
  6. import javafx.scene.layout.Pane;
  7. import javafx.scene.paint.Color;
  8. import javafx.scene.shape.ArcType;
  9. import javafx.stage.Stage;
  10. /**
  11. * ZetCode JavaFX tutorial
  12. *
  13. * This program paints six different
  14. * shapes.
  15. *
  16. * Author: Jan Bodnar
  17. * Website: zetcode.com
  18. * Last modified: June 2015
  19. */
  20. public class ShapesEx extends Application {
  21. @Override
  22. public void start(Stage stage) {
  23. initUI(stage);
  24. }
  25. private void initUI(Stage stage) {
  26. Pane root = new Pane();
  27. Canvas canvas = new Canvas(320, 300);
  28. GraphicsContext gc = canvas.getGraphicsContext2D();
  29. drawShapes(gc);
  30. root.getChildren().add(canvas);
  31. Scene scene = new Scene(root, 300, 200, Color.WHITESMOKE);
  32. stage.setTitle("Shapes");
  33. stage.setScene(scene);
  34. stage.show();
  35. }
  36. private void drawShapes(GraphicsContext gc) {
  37. gc.setFill(Color.GRAY);
  38. gc.fillOval(30, 30, 50, 50);
  39. gc.fillOval(110, 30, 80, 50);
  40. gc.fillRect(220, 30, 50, 50);
  41. gc.fillRoundRect(30, 120, 50, 50, 20, 20);
  42. gc.fillArc(110, 120, 60, 60, 45, 180, ArcType.OPEN);
  43. gc.fillPolygon(new double[]{220, 270, 220},
  44. new double[]{120, 170, 170}, 3);
  45. }
  46. public static void main(String[] args) {
  47. launch(args);
  48. }
  49. }

该示例使用图形上下文的fill方法绘制了六个不同的形状。

  1. gc.setFill(Color.GRAY);

形状涂成灰色。

  1. gc.fillOval(30, 30, 50, 50);
  2. gc.fillOval(110, 30, 80, 50);

fillOval()方法绘制一个圆和一个椭圆。 前两个参数是 x 和 y 坐标。 第三个和第四个参数是椭圆的宽度和高度。

  1. gc.fillRect(220, 30, 50, 50);

fillRect()使用当前的填充颜料填充矩形。

  1. gc.fillRoundRect(30, 120, 50, 50, 20, 20);

fillRoundRect()绘制一个矩形,其角是圆形的。 该方法的最后两个参数是矩形角的圆弧宽度和圆弧高度。

  1. gc.fillArc(110, 120, 60, 60, 45, 180, ArcType.OPEN);

fillArc()方法使用当前的填充涂料填充圆弧。 最后三个参数是起始角度,角度扩展和闭合类型。

  1. gc.fillPolygon(new double[]{220, 270, 220},
  2. new double[]{120, 170, 170}, 3);

fillPolygon()方法使用当前设置的填充涂料用给定的点填充多边形。 在我们的例子中,它绘制了一个直角三角形。 第一个参数是包含多边形点的 x 坐标的数组,第二个参数是包含多边形点的 y 坐标的数组。 最后一个参数是形成多边形的点数。

JavaFX 画布 - 图6

图:颜色

星形

可以使用strokePolygon()fillPolygon()方法绘制更复杂的形状。 下一个示例绘制一个星形。

StarShapeEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.scene.Scene;
  4. import javafx.scene.canvas.Canvas;
  5. import javafx.scene.canvas.GraphicsContext;
  6. import javafx.scene.layout.Pane;
  7. import javafx.scene.paint.Color;
  8. import javafx.stage.Stage;
  9. /**
  10. * ZetCode JavaFX tutorial
  11. *
  12. * This program draws a Star shape on
  13. * a Canvas.
  14. *
  15. * Author: Jan Bodnar
  16. * Website: zetcode.com
  17. * Last modified: June 2015
  18. */
  19. public class StarShapeEx extends Application {
  20. @Override
  21. public void start(Stage stage) {
  22. initUI(stage);
  23. }
  24. private void initUI(Stage stage) {
  25. Pane root = new Pane();
  26. Canvas canvas = new Canvas(300, 300);
  27. GraphicsContext gc = canvas.getGraphicsContext2D();
  28. drawStarShape(gc);
  29. root.getChildren().add(canvas);
  30. Scene scene = new Scene(root, 300, 250, Color.WHITESMOKE);
  31. stage.setTitle("Star");
  32. stage.setScene(scene);
  33. stage.show();
  34. }
  35. private void drawStarShape(GraphicsContext gc) {
  36. double xpoints[] = {10, 85, 110, 135, 210, 160,
  37. 170, 110, 50, 60};
  38. double ypoints[] = {85, 75, 10, 75, 85, 125,
  39. 190, 150, 190, 125};
  40. gc.strokePolygon(xpoints, ypoints, xpoints.length);
  41. }
  42. public static void main(String[] args) {
  43. launch(args);
  44. }
  45. }

该示例绘制了星形的轮廓。 形状由十个坐标组成。

  1. double xpoints[] = {10, 85, 110, 135, 210, 160,
  2. 170, 110, 50, 60};
  3. double ypoints[] = {85, 75, 10, 75, 85, 125,
  4. 190, 150, 190, 125};

这些是形状的 x 和 y 坐标。

  1. gc.strokePolygon(xpoints, ypoints, xpoints.length);

使用strokePolygon()方法绘制形状。

JavaFX 画布 - 图7

图:星星 shape

透明矩形

透明性是指能够透视材料的质量。 在计算机图形学中,我们可以使用 alpha 合成来实现透明效果。 Alpha 合成是将图像与背景组合以创建部分透明外观的过程。

TransparentRectanglesEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.scene.Scene;
  4. import javafx.scene.canvas.Canvas;
  5. import javafx.scene.canvas.GraphicsContext;
  6. import javafx.scene.layout.Pane;
  7. import javafx.scene.paint.Color;
  8. import javafx.stage.Stage;
  9. /**
  10. * ZetCode JavaFX tutorial
  11. *
  12. * This program draws ten rectangles with different
  13. * levels of transparency.
  14. *
  15. * Author: Jan Bodnar
  16. * Website: zetcode.com
  17. * Last modified: June 2015
  18. */
  19. public class TransparentRectanglesEx extends Application {
  20. @Override
  21. public void start(Stage stage) {
  22. initUI(stage);
  23. }
  24. private void initUI(Stage stage) {
  25. Pane root = new Pane();
  26. Canvas canvas = new Canvas(600, 300);
  27. GraphicsContext gc = canvas.getGraphicsContext2D();
  28. drawRectangles(gc);
  29. root.getChildren().add(canvas);
  30. Scene scene = new Scene(root, 600, 100, Color.WHITESMOKE);
  31. stage.setTitle("Transparent rectangles");
  32. stage.setScene(scene);
  33. stage.show();
  34. }
  35. private void drawRectangles(GraphicsContext gc) {
  36. for (int i = 1; i <= 10; i++) {
  37. float alpha = i * 0.1f;
  38. gc.setFill(Color.FORESTGREEN);
  39. gc.setGlobalAlpha(alpha);
  40. gc.fillRect(50 * i, 20, 40, 40);
  41. }
  42. }
  43. public static void main(String[] args) {
  44. launch(args);
  45. }
  46. }

该示例绘制了十个具有不同透明度级别的矩形。

  1. float alpha = i * 0.1f;

在每个for周期中计算一个 alpha 值。

  1. gc.setGlobalAlpha(alpha);

setGlobalAlpha()方法设置当前状态的全局 alpha。

JavaFX 画布 - 图8

图:透明矩形

在本章中,我们在Canvas节点上执行了绘制操作。