本文详解如何在 processing 中动态将任意长度的句子按单词自动分行,并整体水平居中、垂直合理排布于画布中央,全程通过 for 循环控制文本位置与换行逻辑,确保适配不同输入。
本文详解如何在 processing 中动态将任意长度的句子按单词自动分行,并整体水平居中、垂直合理排布于画布中央,全程通过 for 循环控制文本位置与换行逻辑,确保适配不同输入。
在 Processing 中实现文本居中显示,不能仅靠 text(x, y) 简单设置坐标(如 width/2, height/2),尤其当句子较长需换行时——直接居中单行会导致文字溢出或截断。正确做法是:先按语义(空格)分词 → 按最大字符数或像素宽度动态组行 → 再以画布中心为基准,逐行垂直偏移绘制。本文提供一套轻量、可复用的解决方案,完全基于 for 循环实现,无需第三方库。
核心思路:分步解耦,循环驱动
- 文本预处理:将原始字符串按空格拆分为单词数组;
- 智能组行:用 for 循环遍历单词,累积拼接成“不超长”的行(本例以字符数为约束,亦可升级为 textWidth() 像素级精度);
- 居中渲染:启用 textAlign(CENTER),再用 for 循环遍历行列表,以 width/2 为 x 坐标,y 坐标随行号线性递增。
✅ 完整可运行代码(含注释)
import javax.swing.JOptionPane;
import java.util.ArrayList;
String Answer;
String Secret = "Java";
String riddle = "WHAT IS THIS: high-level, class-based, object-oriented programming language?";
void setup() {
size(500, 500);
textAlign(CENTER); // 全局启用水平居中 —— 关键!
textSize(24); // 推荐使用适中字号(原示例50过大易溢出)
textLeading(32); // 设置行高,提升可读性
}
void draw() {
background(255);
answerBox();
riddle();
answerComparison();
}
void riddle() {
fill(0);
stroke(0);
// 步骤1:调用分词分行动态生成行列表
ArrayList<string> lines = TextSplitter.splitText(riddle, 15); // 每行最多15字符
// 步骤2:计算起始Y位置(使整体文本块垂直居中)
float centerY = height / 2;
float totalHeight = lines.size() * textLeading(); // 总高度 ≈ 行数 × 行高
float startY = centerY - totalHeight / 2 + textAscent() / 2; // 补偿基线偏移
// 步骤3:for循环逐行绘制,x恒为width/2,y动态计算
float y = startY;
for (String line : lines) {
text(line, width/2, y);
y += textLeading();
}
}
void answerBox() {
noFill();
rect(150, 440, 200, 50);
if (mouseX > 150 && mouseX 440 && mouseY splitText(String inputText, int maxCharsPerLine) {
if (inputText == null || inputText.trim().isEmpty())
return new ArrayList<string>();
String[] words = split(inputText, ' ');
ArrayList<string> lines = new ArrayList<string>();
String currentLine = "";
for (String word : words) {
// 尝试加入当前词:若为空则直接加,否则加空格+词
String candidate = currentLine.isEmpty() ? word : currentLine + " " + word;
// 判断是否超长(注意:字符数 ≠ 像素宽,但对简单场景足够)
if (candidate.length() <h3>⚠️ 关键注意事项</h3>
<ul>
<li>
<strong>textAlign(CENTER) 必须在 text() 调用前设置</strong>,且作用于后续所有 text(),避免重复设置;</li>
<li>
<strong>避免硬编码 textSize(50)</strong>:大字号下 textWidth("...") 差异显著,建议先用 textSize(24) 调试,再按需放大;</li>
<li>
<strong>垂直居中需补偿 textAscent()</strong>:Processing 的 text() 绘制基线(baseline)而非几何中心,直接 height/2 会偏高,应叠加 textAscent()/2;</li>
<li>
<strong>字符数限制 vs 像素宽度限制</strong>:上述 splitText 使用字符数(length())判断换行,简洁高效;若需精确像素控制(如多字体混排),请改用 textWidth(str) </li>
<li>
<strong>空行与特殊字符处理</strong>:生产环境建议增强 splitText 对连续空格、换行符、标点粘连的鲁棒性。</li>
</ul>
<h3>✅ 总结</h3>
<p>通过封装 TextSplitter 工具类 + for 循环驱动的行生成与绘制,我们实现了<strong>响应式文本居中</strong>:无论输入“Hello”还是百字谜题,都能自动分行、水平居中、垂直居中排布。该模式结构清晰、易于扩展(如支持字体切换、颜色渐变、动画入场),是 Processing 文本排版的工程化实践范本。</p></string></string></string></string>










