如何让JavaFX Canvas的fillText旋转效果与Node Text保持一致
JavaFX Canvas fillText 旋转匹配 Text Node 行为的解决方案
Text Node的rotate是围绕自身边界框中心旋转的,而Canvas的rotate默认围绕坐标系原点(0,0)旋转,直接调用会导致文本旋转中心错位。要实现完全一致的效果,需要通过坐标变换对齐旋转中心,步骤如下:
- 计算待绘制文本的边界框中心坐标
- 将Canvas坐标系原点平移到该中心
- 执行旋转操作
- 平移回文本绘制起点相对于中心的偏移量,确保文本绘制在初始目标位置
- 绘制文本后恢复Canvas的变换状态,避免影响后续绘制
完整代码示例
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.layout.HBox; import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.scene.text.FontMetrics; import javafx.scene.text.Text; import javafx.stage.Stage; public class RotatedTextComparison extends Application { private static final String TEXT = "Hello Rotated"; private static final double ROTATE_ANGLE = 45; private static final Font FONT = Font.font(24); @Override public void start(Stage stage) { // 左侧标准Text Node(旋转基准) Text textNode = new Text(TEXT); textNode.setFont(FONT); textNode.setFill(Color.BLUE); textNode.setRotate(ROTATE_ANGLE); // 右侧Canvas绘制旋转文本 Canvas canvas = new Canvas(300, 200); GraphicsContext gc = canvas.getGraphicsContext2D(); gc.setFont(FONT); gc.setFill(Color.RED); drawRotatedText(gc, TEXT, 50, 100, ROTATE_ANGLE); HBox root = new HBox(20, textNode, canvas); root.setStyle("-fx-padding: 20; -fx-background-color: #f0f0f0;"); stage.setScene(new Scene(root)); stage.setTitle("Text Rotation Comparison"); stage.show(); } private void drawRotatedText(GraphicsContext gc, String text, double x, double y, double angle) { // 获取文本精确度量信息 FontMetrics metrics = gc.getFontMetrics(); double textWidth = metrics.computeStringWidth(text); double textHeight = metrics.getHeight(); // 计算文本边界框的中心坐标(基于绘制起点x,y) double centerX = x + textWidth / 2; double centerY = y - metrics.getDescent() + textHeight / 2; gc.save(); // 保存当前变换状态,隔离本次操作 // 1. 平移坐标系原点到文本中心 gc.translate(centerX, centerY); // 2. 执行旋转 gc.rotate(angle); // 3. 平移回文本绘制起点的偏移量,确保文本位置正确 gc.translate(-centerX, -centerY); // 绘制目标文本 gc.fillText(text, x, y); gc.restore(); // 恢复变换状态,不影响后续Canvas绘制 } public static void main(String[] args) { launch(args); } }
关键细节说明
- 使用
FontMetrics获取文本的精确尺寸(包括下沉量descent),确保旋转中心计算和Text Node的边界框中心完全一致 save()和restore()方法用来隔离变换操作,避免本次旋转影响Canvas上的其他绘制内容- 变换顺序不可颠倒:必须先平移到中心,再旋转,最后平移回偏移,才能保证旋转中心正确
内容的提问来源于stack exchange,提问作者tretonis
相关产品推荐
相关产品推荐

