简介
2d编程实际开发中很常见,比如生成一个验证码,二维码,图片裁剪压缩什么的。在桌面应用中,自定控件的外观的渲染,都是通过2D图像接口来实现的。当然,我们也可以利用这些编程接口,做一个画图工具。JavaFX中专门提供一个Canvas的组件,用来画画。比如下图中,用代码画出来的一些几何图形:

Canvas提供了一个操作手柄,叫做GraphicsContext,可以通过Canvas的实例获得:
GraphicsContext gc = canvas.getGraphicsContext2D();
Canvas是一种自上而下的流式画图方式,每次画图之前,采用上文的设置,比如颜色,线条粗细等。同样画下一个图形前,先更改设置,再绘制下一个图形,如果不更改设置,则延用之前的设置。比如:
gc.setFill(Color.GREEN);
gc.setStroke(Color.BLUE);
gc.setLineWidth(5);
gc.strokeLine(40, 10, 10, 40);
gc.fillOval(10, 60, 30, 30);
gc.strokeOval(60, 60, 30, 30);
Canvas中的图像设置
| 属性 | 保存/还原 | 默认值 | 描述 |
|---|---|---|---|
| 常规属性 | |||
| 裁剪 | Yes | No clipping | 各种裁剪路径的抗锯齿相交区域,渲染仅限于此区域内。 |
| 全局透明度 | Yes | 1.0 | 一个不透明度值,用于控制每次渲染操作的可见度或淡入淡出效果。 |
| 全局混合模式 | Yes | SRC_OVER | 一个“混合模式”枚举值,用于控制每个渲染操作所产生的像素如何与现有图像进行合成。 |
| 变形 | Yes | Identity | 一个 3x2 的二维仿射变换矩阵,用于控制坐标如何映射到画布图像的逻辑像素上。 |
| 特效 | Yes | null | 一种单独应用于每个渲染操作的效果。 |
| 填充属性 | |||
| 填充颜色 | Yes | BLACK | 在填充操作中,用于涂抹于图形内部的涂料。 |
| Stroke Attributes | |||
| 线条颜色 | Yes | BLACK | 在描边操作中,用于涂抹于图形边界上的颜料。 |
| 线宽 | Yes | 1.0 | 在描边操作中,应用于形状边界处的描边宽度。 |
| 线帽 | Yes | SQUARE | 在一笔画操作中,应用于每个破折号及其/或子路径起始和结束处的端帽样式。 |
| 连接点 | Yes | MITER | 在描边操作中,用于连接形状边界路径中各个部分的连接方式。 |
斜角限制 | Yes | 10.0 | 在形状边界路径的各段之间存在锐角拐弯处时,对于一条“MITER”线段连接在该锐角拐弯方向上的延伸距离(相对于线宽而言)的限制值,该限制值决定了在绘制操作中该连接线段是否会被截断为“BEVEL”连接形式。 |
| 虚线 | Yes | null | 在描边操作中,应用于形状边界各段的虚线长度数组。 |
虚线偏移量 | Yes | 0.0 | 在绘制操作中,用于确定在形状边界上开始绘制分段图案时所对应的虚线长度数组偏移量的值。 |
| 文本属性 | |||
| 字体 | Yes | Default Font | 用于所有填充和描边文本操作的字体。 |
| 文本对齐 | Yes | LEFT | 文本在与文本操作中指定的 X 坐标相对应的位置上的水平排列方式。 |
| 文本基线 | Yes | BASELINE | 文本相对于文本操作中指定的 Y 坐标的垂直位置。 |
| 字体平滑 | Yes | GRAY | 对于所有填充文本操作而言,该字体中用于字符平滑(即抗锯齿处理)的类型。 |
| 路径属性 | |||
| 曲线路径 | No | Empty path | 通过多种路径构建方法所构建的路径,将用于各种路径填充、描边或裁剪操作。 |
| 填充规则 | Yes | NON_ZERO | 用于确定路径填充或裁剪操作中路径内部区域的方法。 |
| 图片属性 | |||
| 图片平滑 | Yes | true | 一个布尔型状态值,用于控制“drawImage”(所有形式)中图像的平滑效果的开启或关闭。 |
Canvas的画图接口
也就是GraphicsContext可调用的类方法:
| 方法名 | 常规 | 填充 | 线框 | 文本 | 路径 | 图片 |
|---|---|---|---|---|---|---|
| 基本形状 | ||||||
fillRect(), fillRoundRect(), fillOval(), fillArc() | Yes | Yes | No | No | No | No |
strokeLine(), strokeRect(), strokeRoundRect(), strokeOval(), strokeArc() | Yes | No | Yes | No | No | No |
clearRect() | Yes [1] | No | No | No | No | No |
fillPolygon() | Yes | Yes | No | No | Yes [2] | No |
strokePolygon(), strokePolyline() | Yes | No | Yes | No | No | No |
| [1] 只有变形,裁切,特效用于 clearRect() [2] 只有填充规则用于fillPolygon(), 剩余路径不会改变。 | ||||||
| 文本 | ||||||
fillText(), fillText(with maxWidth) | Yes | Yes | No | Yes [3] | No | No |
strokeText(), strokeText(with maxWidth) | Yes | No | Yes | Yes [3] | No | No |
| [3] 只有填充形式的文本才能用字体平滑 | ||||||
| 路径 | ||||||
beginPath(), moveTo(), lineTo(), quadraticCurveTo(), bezierCurveTo(), arc(), arcTo(), appendSVGPath(), closePath(), rect() | Yes [4] | No | No | No | No | No |
fill() | Yes [4] | Yes | No | No | Yes | No |
stroke() | Yes [4] | No | Yes | No | Yes [5] | No |
clip() | No | No | No | No | Yes | No |
| [4] 变形仅用于路径创建的时候 [5] 填充规则只用于 fill() 和clip() | ||||||
| 图片 | ||||||
drawImage(all forms) | Yes | No | No | No | No | Yes |
| 杂项 | ||||||
applyEffect(), PixelWriter methods | No | No | No | No | No | No |
示例1-基本图形

private void drawShapes(GraphicsContext gc) {
gc.setFill(Color.GREEN);
gc.setStroke(Color.BLUE);
gc.setLineWidth(5);
gc.strokeLine(40, 10, 10, 40);
gc.fillOval(10, 60, 30, 30);
gc.strokeOval(60, 60, 30, 30);
gc.fillRoundRect(110, 60, 30, 30, 10, 10);
gc.strokeRoundRect(160, 60, 30, 30, 10, 10);
gc.fillArc(10, 110, 30, 30, 45, 240, ArcType.OPEN);
gc.fillArc(60, 110, 30, 30, 45, 240, ArcType.CHORD);
gc.fillArc(110, 110, 30, 30, 45, 240, ArcType.ROUND);
gc.strokeArc(10, 160, 30, 30, 45, 240, ArcType.OPEN);
gc.strokeArc(60, 160, 30, 30, 45, 240, ArcType.CHORD);
gc.strokeArc(110, 160, 30, 30, 45, 240, ArcType.ROUND);
gc.fillPolygon(new double[]{10, 40, 10, 40},
new double[]{210, 210, 240, 240}, 4);
gc.strokePolygon(new double[]{60, 90, 60, 90},
new double[]{210, 210, 240, 240}, 4);
gc.strokePolyline(new double[]{110, 140, 110, 140},
new double[]{210, 210, 240, 240}, 4);
}
}
示例2-渐变和阴影

/**
* 在画布对象上绘制一个径向渐变效果,该效果表现为一系列向外辐射的圆圈。
* 此示例默认使用红色和黄色。
*
* @param firstColor 渐变的第一段所使用的颜色。
* @param lastColor 渐变的最后一段所使用的颜色。
*/
private void drawRadialGradient(Color firstColor, Color lastColor) {
gc.setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.1, true,
CycleMethod.REFLECT,
new Stop(0.0, firstColor),
new Stop(1.0, lastColor)));
gc.fill();
}
/**
* 渐变的最后一段所使用的颜色。在画布对象上绘制一条线性渐变,从上到下为字母“D”着色。
* 此演示中使用的默认颜色为蓝色和绿色。
*
* @param firstColor
* @param secondColor
*/
private void drawLinearGradient(Color firstColor, Color secondColor) {
LinearGradient lg = new LinearGradient(0, 0, 1, 1, true,
CycleMethod.REFLECT,
new Stop(0.0, firstColor),
new Stop(1.0, secondColor));
gc.setStroke(lg);
gc.setLineWidth(20);
gc.stroke();
}
/**
* 在字母“D”周围绘制四个独立的阴影效果。演示中所使用的默认颜色为灰色、蓝色、绿色和红色。
*
* @param firstColor
* @param secondColor
* @param thirdColor
* @param fourthColor
*/
private void drawDropShadow(Color firstColor, Color secondColor,
Color thirdColor, Color fourthColor) {
gc.applyEffect(new DropShadow(20, 20, 0, firstColor));
gc.applyEffect(new DropShadow(20, 0, 20, secondColor));
gc.applyEffect(new DropShadow(20, -20, 0, thirdColor));
gc.applyEffect(new DropShadow(20, 0, -20, fourthColor));
}
示例3-涂鸦
涂鸦前:

涂鸦后:

鼠标拖拽时,清除掉指针附近的颜色:
canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED,
new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
gc.clearRect(e.getX() - 2, e.getY() - 2, 5, 5);
}
});
示例4-图层

private void createLayers(){
// Layers 1&2 are the same size
layer1 = new Canvas(300,250);
layer2 = new Canvas(300,250);
// Obtain Graphics Contexts
gc1 = layer1.getGraphicsContext2D();
gc1.setFill(Color.GREEN);
gc1.fillOval(50,50,20,20);
gc2 = layer2.getGraphicsContext2D();
gc2.setFill(Color.BLUE);
gc2.fillOval(100,100,20,20);
}
private void handleLayers(){
// Handler for Layer 1
layer1.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
gc1.fillOval(e.getX(),e.getY(),20,20);
}
});
// Handler for Layer 2
layer2.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
gc2.fillOval(e.getX(),e.getY(),20,20);
}
});
}

&spm=1001.2101.3001.5002&articleId=154988398&d=1&t=3&u=5e4f5463d15b4dd8887c6693b5c8d2c8)
707

被折叠的 条评论
为什么被折叠?



