fillText支持\r; drawTextContent标点禁则; 道具描述多行文本
This commit is contained in:
parent
90d4488ffb
commit
618759f28a
@ -1930,7 +1930,7 @@ baseline: 可为alphabetic, top, hanging, middle, ideographic, bottom
|
||||
参考资料:https://www.w3school.com.cn/tags/canvas_textbaseline.asp
|
||||
|
||||
splitLines: fn(name: string|CanvasRenderingContext2D, text: string, maxWidth?: number, font?: string)
|
||||
字符串自动换行的分割;具有标点禁则功能
|
||||
字符串自动换行的分割
|
||||
|
||||
strokeArc: fn(name: string|CanvasRenderingContext2D, x: number, y: number, r: number, start: number, end: number, style?: string, lineWidth?: number)
|
||||
在某个canvas上绘制一段弧
|
||||
|
||||
@ -3434,7 +3434,7 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
|
||||
"!type": "fn(name: string|CanvasRenderingContext2D)"
|
||||
},
|
||||
"splitLines": {
|
||||
"!doc": "字符串自动换行的分割;具有标点禁则功能",
|
||||
"!doc": "字符串自动换行的分割",
|
||||
"!type": "fn(name: string|CanvasRenderingContext2D, text: string, maxWidth?: number, font?: string)"
|
||||
},
|
||||
"setAlpha": {
|
||||
|
||||
142
libs/ui.js
142
libs/ui.js
@ -82,13 +82,19 @@ ui.prototype.fillText = function (name, text, x, y, style, font, maxWidth) {
|
||||
if (font) core.setFont(name, font);
|
||||
var ctx = this.getContextByName(name);
|
||||
if (!ctx) return;
|
||||
var currentStyle = ctx.fillStyle;
|
||||
text = (text + "").replace(/\\r/g, '\r');
|
||||
var originText = text.replace(/\r(\[.*\])?/g, "");
|
||||
var index = text.indexOf('\r');
|
||||
if (maxWidth != null) {
|
||||
this.setFontForMaxWidth(ctx, index >= 0 ? text.replace(/\r(\[.*\])?/g, "") : text, maxWidth);
|
||||
this.setFontForMaxWidth(ctx, index >= 0 ? originText : text, maxWidth);
|
||||
}
|
||||
if (index >= 0) {
|
||||
var currentStyle = ctx.fillStyle;
|
||||
var textWidth = core.calWidth(ctx, originText);
|
||||
var textAlign = ctx.textAlign;
|
||||
if (textAlign == 'center') x -= textWidth / 2;
|
||||
else if (textAlign == 'right') x -= textWidth;
|
||||
ctx.textAlign = 'left';
|
||||
text = text.replace(/\r(?!\[.*\])/g, "\r[" + currentStyle + "]");
|
||||
var colorArray = text.match(/(?<=\r\[).*(?=\])/g);
|
||||
var textArray = text.split(/\r\[.*\]/);
|
||||
@ -96,9 +102,10 @@ ui.prototype.fillText = function (name, text, x, y, style, font, maxWidth) {
|
||||
for (var i = 0; i < textArray.length; i++) {
|
||||
var subtext = textArray[i];
|
||||
if (colorArray[i-1]) ctx.fillStyle = colorArray[i-1];
|
||||
width += core.calWidth(ctx, subtext, x, y);
|
||||
ctx.fillText(subtext, x + width, y);
|
||||
width += core.calWidth(ctx, subtext, x, y);
|
||||
}
|
||||
ctx.textAlign = textAlign;
|
||||
ctx.fillStyle = currentStyle;
|
||||
} else {
|
||||
ctx.fillText(text, x, y);
|
||||
@ -508,56 +515,23 @@ ui.prototype.splitLines = function (name, text, maxWidth, font) {
|
||||
if (!ctx) return [text];
|
||||
if (font) core.setFont(name, font);
|
||||
|
||||
// 不能在行首的标点
|
||||
var forbidStart = "))】》>﹞>)]»›〕〉}]」}〗』" + ",。?!:;·…,.?!:;、……~&@#~&@#";
|
||||
// 不能在行尾的标点
|
||||
var forbidEnd = "((【《<﹝<([«‹〔〈{[「{〖『";
|
||||
|
||||
var contents = [];
|
||||
var last = 0;
|
||||
var forceChangeLine = false; // 是否强制换行,避免多个连续forbidStart存在
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
if (text.charAt(i) == '\n') {
|
||||
contents.push(text.substring(last, i));
|
||||
last = i + 1;
|
||||
forceChangeLine = false;
|
||||
}
|
||||
else if (text.charAt(i) == '\\' && text.charAt(i + 1) == 'n') {
|
||||
contents.push(text.substring(last, i));
|
||||
last = i + 2;
|
||||
forceChangeLine = false;
|
||||
}
|
||||
else {
|
||||
var curr = text.charAt(i);
|
||||
var toAdd = text.substring(last, i + 1);
|
||||
var width = core.calWidth(name, toAdd);
|
||||
if (maxWidth && width > maxWidth) {
|
||||
// --- 当前应当换行,然而还是检查一下是否是forbidStart
|
||||
if (!forceChangeLine && forbidStart.indexOf(curr) >= 0) {
|
||||
forceChangeLine = true;
|
||||
continue;
|
||||
}
|
||||
contents.push(text.substring(last, i));
|
||||
last = i;
|
||||
forceChangeLine = false;
|
||||
} else {
|
||||
// --- 当前不应该换行;但是提前检查一下是否是行尾标点
|
||||
var curr = text.charAt(i);
|
||||
if (forbidEnd.indexOf(curr) >= 0 && i < text.length -1) {
|
||||
// 检查是否是行尾
|
||||
var nextcurr = text.charAt(i+1);
|
||||
// 确认不是手动换行
|
||||
if (nextcurr != '\n' && !(nextcurr == '\\' && text.charAt(i+2) == 'n')) {
|
||||
var toAdd = text.substring(last, i+2);
|
||||
var width = core.calWidth(name, toAdd);
|
||||
if (maxWidth && width > maxWidth) {
|
||||
// 下一项会换行,因此在此处换行
|
||||
contents.push(text.substring(last, i));
|
||||
last = i;
|
||||
forceChangeLine = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1165,6 +1139,11 @@ ui.prototype._drawTextContent_next = function (tempCtx, content, config) {
|
||||
|
||||
// 绘制下一个字符
|
||||
ui.prototype._drawTextContent_drawChar = function (tempCtx, content, config, ch) {
|
||||
// 标点禁则:不能在行首的标点
|
||||
var forbidStart = "))】》>﹞>)]»›〕〉}]」}〗』" + ",。?!:;·…,.?!:;、……~&@#~&@#";
|
||||
// 标点禁则:不能在行尾的标点
|
||||
var forbidEnd = "((【《<﹝<([«‹〔〈{[「{〖『";
|
||||
|
||||
// \n, \\n
|
||||
if (ch == '\n' || (ch=='\\' && content.charAt(config.index)=='n')) {
|
||||
this._drawTextContent_newLine(tempCtx, config);
|
||||
@ -1191,12 +1170,34 @@ ui.prototype._drawTextContent_drawChar = function (tempCtx, content, config, ch)
|
||||
if (c == 'z') return this._drawTextContent_emptyChar(tempCtx, content, config);
|
||||
}
|
||||
// 检查是不是自动换行
|
||||
var charwidth = core.calWidth(tempCtx, ch) + config.interval;
|
||||
if (config.maxWidth != null && config.offsetX + charwidth > config.maxWidth) {
|
||||
this._drawTextContent_newLine(tempCtx, config);
|
||||
config.index--;
|
||||
return this._drawTextContent_next(tempCtx, content, config);
|
||||
if (config.maxWidth != null) {
|
||||
var charwidth = core.calWidth(tempCtx, ch) + config.interval;
|
||||
if (config.offsetX + charwidth > config.maxWidth) {
|
||||
// --- 当前应当换行,然而还是检查一下是否是forbidStart
|
||||
if (!config.forceChangeLine && forbidStart.indexOf(ch) >= 0) {
|
||||
config.forceChangeLine = true;
|
||||
} else {
|
||||
this._drawTextContent_newLine(tempCtx, config);
|
||||
config.index--;
|
||||
return this._drawTextContent_next(tempCtx, content, config);
|
||||
}
|
||||
} else if (forbidEnd.indexOf(ch) >= 0 && config.index < content.length) {
|
||||
// --- 当前不应该换行;但是提前检查一下是否是行尾标点
|
||||
var nextch = content.charAt(config.index);
|
||||
// 确认不是手动换行
|
||||
if (nextch != '\n' && !(nextch == '\\' && content.charAt(config.index+1) == 'n')) {
|
||||
// 检查是否会换行
|
||||
var nextchwidth = core.calWidth(tempCtx, nextch) + config.interval;
|
||||
if (config.offsetX + charwidth + nextchwidth > config.maxWidth) {
|
||||
// 下一项会换行,因此在此处换行
|
||||
this._drawTextContent_newLine(tempCtx, config);
|
||||
config.index--;
|
||||
return this._drawTextContent_next(tempCtx, content, config);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 输出
|
||||
var left = config.offsetX, top = config.offsetY + config.topMargin;
|
||||
core.fillText(tempCtx, ch, left, top);
|
||||
@ -1230,6 +1231,7 @@ ui.prototype._drawTextContent_newLine = function (tempCtx, config) {
|
||||
config.offsetY += config.lineMaxHeight;
|
||||
config.lineMaxHeight = config.currfont + config.lineMargin;
|
||||
config.line++;
|
||||
config.forceChangeLine = false;
|
||||
}
|
||||
|
||||
ui.prototype._drawTextContent_changeColor = function (tempCtx, content, config) {
|
||||
@ -2535,26 +2537,23 @@ ui.prototype._drawToolbox_drawDescription = function (info, max_height) {
|
||||
core.setTextAlign('ui', 'left');
|
||||
if (!info.selectId) return;
|
||||
var item=core.material.items[info.selectId];
|
||||
core.fillText('ui', item.name, 10, 32, core.status.globalAttribute.selectColor, this._buildFont(20, true))
|
||||
var text = item.text||"该道具暂无描述。";
|
||||
try {
|
||||
// 检查能否eval
|
||||
text = core.replaceText(text);
|
||||
} catch (e) {}
|
||||
var name = item.name || "未知道具";
|
||||
try { name = core.replateText(name); } catch (e) {}
|
||||
core.fillText('ui', name, 10, 32, core.status.globalAttribute.selectColor, this._buildFont(20, true))
|
||||
var text = item.text || "该道具暂无描述。";
|
||||
try { text = core.replaceText(text); } catch (e) {}
|
||||
|
||||
for (var font_size = 17; font_size >= 14; font_size -= 3) {
|
||||
var lines = core.splitLines('ui', text, this.PIXEL - 15, this._buildFont(font_size, false));
|
||||
var line_height = parseInt(font_size * 1.4), curr = 37 + line_height;
|
||||
if (curr + lines.length * line_height < max_height) break;
|
||||
var height = null;
|
||||
for (var fontSize = 17; fontSize >= 9; fontSize -= 2) {
|
||||
var config = { left: 10, top: 46, fontSize: fontSize, maxWidth: this.PIXEL - 15, bold: false, color: "white" };
|
||||
height = 42 + core.getTextContentHeight(text, config);
|
||||
if (height < max_height || fontSize == 9) {
|
||||
core.drawTextContent('ui', text, config);
|
||||
break;
|
||||
}
|
||||
}
|
||||
core.setFillStyle('ui', '#FFFFFF');
|
||||
for (var i=0;i<lines.length;++i) {
|
||||
core.fillText('ui', lines[i], 10, curr);
|
||||
curr += line_height;
|
||||
if (curr>=max_height) break;
|
||||
}
|
||||
if (curr < max_height) {
|
||||
core.fillText('ui', '<继续点击该道具即可进行使用>', 10, curr, '#CCCCCC', this._buildFont(14, false));
|
||||
if (height < max_height - 33) {
|
||||
core.fillText('ui', '<继续点击该道具即可进行使用>', 10, max_height - 15, '#CCCCCC', this._buildFont(14, false));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2647,24 +2646,19 @@ ui.prototype._drawEquipbox_description = function (info, max_height) {
|
||||
core.fillText('ui', equip.name + "(" + equipString + ")", 10, 32, core.status.globalAttribute.selectColor, this._buildFont(20, true))
|
||||
// --- 描述
|
||||
var text = equip.text || "该装备暂无描述。";
|
||||
try {
|
||||
text = core.replaceText(text);
|
||||
} catch (e) {}
|
||||
try { text = core.replaceText(text); } catch (e) {}
|
||||
|
||||
for (var font_size = 17; font_size >= 11; font_size -= 3) {
|
||||
var lines = core.splitLines('ui', text, this.PIXEL - 15, this._buildFont(font_size, false));
|
||||
var line_height = parseInt(font_size * 1.4), curr = 37 + line_height;
|
||||
if (curr + lines.length * line_height < max_height) break;
|
||||
}
|
||||
core.setFillStyle('ui', '#FFFFFF');
|
||||
for (var i = 0; i < lines.length; ++i) {
|
||||
core.fillText('ui', lines[i], 10, curr);
|
||||
curr += line_height;
|
||||
if (curr >= max_height) break;
|
||||
var height = null;
|
||||
for (var fontSize = 17; fontSize >= 9; fontSize -= 2) {
|
||||
var config = { left: 10, top: 46, fontSize: fontSize, maxWidth: this.PIXEL - 15, bold: false, color: "white" };
|
||||
height = 42 + core.getTextContentHeight(text, config);
|
||||
if (height < max_height - 30 || fontSize == 9) {
|
||||
core.drawTextContent('ui', text, config);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// --- 变化值
|
||||
if (curr >= max_height) return;
|
||||
this._drawEquipbox_drawStatusChanged(info, curr, equip, equipType);
|
||||
this._drawEquipbox_drawStatusChanged(info, max_height - 15, equip, equipType);
|
||||
}
|
||||
|
||||
ui.prototype._drawEquipbox_getStatusChanged = function (info, equip, equipType, y) {
|
||||
|
||||
2
runtime.d.ts
vendored
2
runtime.d.ts
vendored
@ -2123,7 +2123,7 @@ declare class ui {
|
||||
/** 设置某个canvas的baseline */
|
||||
setTextBaseline(name: string | CanvasRenderingContext2D, baseline: any): void
|
||||
|
||||
/** 字符串自动换行的分割;具有标点禁则功能 */
|
||||
/** 字符串自动换行的分割 */
|
||||
splitLines(name: string | CanvasRenderingContext2D, text: string, maxWidth?: number, font?: string): void
|
||||
|
||||
/** 在某个canvas上绘制一个图标 */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user