|
@@ -17863,6 +17863,7 @@
|
|
|
this.textAlign = options.textAlign || 'center';
|
|
|
this.name = options.name;
|
|
|
this.transform2Dpercent = options.transform2Dpercent;
|
|
|
+ this.maxLineWidth = options.maxLineWidth;
|
|
|
this.setText(options.text);
|
|
|
}
|
|
|
setText(text) {
|
|
@@ -17875,6 +17876,24 @@
|
|
|
this.updateTexture();
|
|
|
}
|
|
|
}
|
|
|
+ /* setText(text){
|
|
|
+ if(text == void 0)text = ''
|
|
|
+ if (this.text !== text) {
|
|
|
+ if (!(text instanceof Array)) {
|
|
|
+ this.text = text.split('\n') //如果是input手动输入的\n这里会是\\n且不会被拆分, 绘制的依然是\n。
|
|
|
+ if(this.maxRowWordsCount){//每行显示最大字数
|
|
|
+ this.text.forEach(str=>{
|
|
|
+ if(str.length > this.maxRowWordsCount){
|
|
|
+
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ //this.text = [text + '']
|
|
|
+ } else this.text = text
|
|
|
+ this.updateTexture()
|
|
|
+ }
|
|
|
+ } */
|
|
|
setTextColor(color) {
|
|
|
this.textColor = Common.CloneObject(color);
|
|
|
this.updateTexture();
|
|
@@ -17909,7 +17928,19 @@
|
|
|
context.textBaseline = 'alphabetic'; // "middle" //设置文字基线。当起点y设置为0时,只有该线以下的部分被绘制出来。middle时文字显示一半(但是对该字体所有字的一半,有的字是不一定显示一半的,尤其汉字),alphabetic时是英文字母的那条基线。
|
|
|
|
|
|
var textHeightAll = 0;
|
|
|
- for (var text of this.text) {
|
|
|
+ var texts = [];
|
|
|
+ if (this.maxLineWidth) {
|
|
|
+ this.text.forEach(words => {
|
|
|
+ if (!words) {
|
|
|
+ texts.push("");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ texts = texts.concat(breakLinesForCanvas(words, context, this.maxLineWidth));
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ texts = this.text;
|
|
|
+ }
|
|
|
+ for (var text of texts) {
|
|
|
var metrics = context.measureText(text);
|
|
|
var textWidth = metrics.width;
|
|
|
infos.push(metrics);
|
|
@@ -17921,7 +17952,7 @@
|
|
|
var rectBorderThick = this.rectBorderThick * r,
|
|
|
textBorderThick = this.textBorderThick * r;
|
|
|
var spriteWidth = 2 * (margin.x + rectBorderThick + textBorderThick) + textMaxWidth; //还要考虑this.textshadowColor,太麻烦了不写了
|
|
|
- var spriteHeight = 2 * (margin.y + rectBorderThick + textBorderThick * this.text.length) + lineSpace * (this.text.length - 1) + textHeightAll;
|
|
|
+ var spriteHeight = 2 * (margin.y + rectBorderThick + textBorderThick * texts.length) + lineSpace * (texts.length - 1) + textHeightAll;
|
|
|
|
|
|
//canvas宽高只会向下取整数,所以为了防止拉伸模糊这里必须先取整
|
|
|
spriteWidth = Math.floor(spriteWidth);
|
|
@@ -17931,7 +17962,7 @@
|
|
|
context.font = this.fontWeight + ' ' + this.fontsize * r + 'px ' + this.fontface; //为何要再写一遍??
|
|
|
|
|
|
if (spriteWidth > 4000) {
|
|
|
- console.error('spriteWidth', spriteWidth, 'spriteHeight', spriteHeight, this.fontsize, r, this.text, margin);
|
|
|
+ console.error('spriteWidth', spriteWidth, 'spriteHeight', spriteHeight, this.fontsize, r, texts, margin);
|
|
|
}
|
|
|
var expand = 0; //Math.max(1, Math.pow(this.fontsize / 16, 1.1)) * r // 针对英文大部分在baseLine之上所以降低一点,或者可以识别当不包含jgqp时才加这个值 . 但即使都是汉字也会不同,如"哈哈"和"粉色",前者居中后者不
|
|
|
|
|
@@ -17941,7 +17972,7 @@
|
|
|
this.roundRect(context, rectBorderThick / 2, rectBorderThick / 2, spriteWidth - rectBorderThick, spriteHeight - rectBorderThick, this.borderRadius * r);
|
|
|
context.fillStyle = 'rgba(' + this.textColor.r + ',' + this.textColor.g + ',' + this.textColor.b + ',' + this.textColor.a + ')';
|
|
|
var y = margin.y + rectBorderThick;
|
|
|
- for (var i = 0; i < this.text.length; i++) {
|
|
|
+ for (var i = 0; i < texts.length; i++) {
|
|
|
//文字y向距离从textBaseline向上算
|
|
|
var actualBoundingBoxAscent = infos[i].fontBoundingBoxAscent == void 0 ? this.fontsize * r * 0.8 : infos[i].fontBoundingBoxAscent; //有的流览器没有。只能大概给一个
|
|
|
y += actualBoundingBoxAscent + textBorderThick;
|
|
@@ -17960,7 +17991,7 @@
|
|
|
context.shadowColor = this.textshadowColor; //'red'
|
|
|
context.shadowBlur = (this.textShadowBlur || this.fontSize / 3) * r;
|
|
|
}
|
|
|
- context.fillText(this.text[i], x, y);
|
|
|
+ context.fillText(texts[i], x, y);
|
|
|
var actualBoundingBoxDescent = infos[i].fontBoundingBoxDescent == void 0 ? this.fontsize * r * 0.2 : infos[i].fontBoundingBoxDescent;
|
|
|
y += actualBoundingBoxDescent + textBorderThick + lineSpace;
|
|
|
}
|
|
@@ -18013,6 +18044,79 @@
|
|
|
this.dispatchEvent('dispose');
|
|
|
}
|
|
|
}
|
|
|
+ function findBreakPoint(text, width, context) {
|
|
|
+ var min = 0;
|
|
|
+ var max = text.length - 1;
|
|
|
+ while (min <= max) {
|
|
|
+ var middle = Math.floor((min + max) / 2);
|
|
|
+ var middleWidth = context.measureText(text.substr(0, middle)).width;
|
|
|
+ var oneCharWiderThanMiddleWidth = context.measureText(text.substr(0, middle + 1)).width;
|
|
|
+ if (middleWidth <= width && oneCharWiderThanMiddleWidth > width) {
|
|
|
+ return middle;
|
|
|
+ }
|
|
|
+ if (middleWidth < width) {
|
|
|
+ min = middle + 1;
|
|
|
+ } else {
|
|
|
+ max = middle - 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ function breakLinesForCanvas(text, context, width, font) {
|
|
|
+ var result = [];
|
|
|
+ var breakPoint = 0;
|
|
|
+ if (font) {
|
|
|
+ context.font = font;
|
|
|
+ }
|
|
|
+ while ((breakPoint = findBreakPoint(text, width, context)) !== -1) {
|
|
|
+ result.push(text.substr(0, breakPoint));
|
|
|
+ text = text.substr(breakPoint);
|
|
|
+ }
|
|
|
+ if (text) {
|
|
|
+ result.push(text);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ } //'使用很寻常的二分查找,如果某一个位置之前的文字宽度小于等于设定的宽度,并且它之后一个字之前的文字宽度大于设定的宽度,那么这个位置就是文本的换行点。上面只是找到一个换行点,对于输入的一段文本,需要循环查找,直到不存在这样的换行点为止, 完整的代码如下',
|
|
|
+
|
|
|
+ /*
|
|
|
+ function wrapText(text, maxWidth) {
|
|
|
+ // 创建一个 canvas 元素来测量文本宽度
|
|
|
+ const canvas = document.createElement('canvas');
|
|
|
+ const ctx = canvas.getContext('2d');
|
|
|
+
|
|
|
+ // 设置字体样式
|
|
|
+ ctx.font = '16px Arial';
|
|
|
+
|
|
|
+ let currentLine = '';
|
|
|
+ const lines = [];
|
|
|
+
|
|
|
+ // 拆分文本为单词数组
|
|
|
+ const words = text.split(' ');
|
|
|
+
|
|
|
+ for (let i = 0; i < words.length; i++) {
|
|
|
+ const word = words[i];
|
|
|
+ const wordWidth = ctx.measureText(word).width;
|
|
|
+ const currentLineWidth = ctx.measureText(currentLine).width;
|
|
|
+
|
|
|
+ if (currentLineWidth + wordWidth < maxWidth) {
|
|
|
+ // 如果当前行加上这个单词不会超出最大宽度,就将它添加到当前行
|
|
|
+ currentLine += (currentLine ? ' ' : '') + word;
|
|
|
+ } else {
|
|
|
+ // 如果当前行加上这个单词会超出最大宽度,就将当前行添加到结果数组,并开始新的一行
|
|
|
+ lines.push(currentLine.trim());
|
|
|
+ currentLine = word;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加最后一行
|
|
|
+ if (currentLine) {
|
|
|
+ lines.push(currentLine.trim());
|
|
|
+ }
|
|
|
+
|
|
|
+ return lines;
|
|
|
+ }
|
|
|
+
|
|
|
+ */
|
|
|
|
|
|
/*
|
|
|
|
|
@@ -39990,12 +40094,14 @@
|
|
|
this.dataset_points = this.dataset_points.map(e => {
|
|
|
return e && new Vector3().copy(e);
|
|
|
});
|
|
|
+ var oldPoints = prop.points;
|
|
|
prop.points = this.dataset_points.map((p, i) => {
|
|
|
- return Potree.Utils.datasetPosTransform({
|
|
|
+ var point = Potree.Utils.datasetPosTransform({
|
|
|
fromDataset: true,
|
|
|
datasetId: this.points_datasets[i],
|
|
|
position: p
|
|
|
});
|
|
|
+ return point || oldPoints && oldPoints[i]; //path
|
|
|
});
|
|
|
if (prop.points.some(e => e == void 0)) {
|
|
|
return false;
|
|
@@ -42311,7 +42417,9 @@
|
|
|
transform2Dpercent: {
|
|
|
x: 0,
|
|
|
y: 0.5
|
|
|
- } //向上移动一半
|
|
|
+ },
|
|
|
+ //向上移动一半
|
|
|
+ maxLineWidth: 300
|
|
|
}));
|
|
|
this.titleLabel.sprite.material.depthTest = false;
|
|
|
var line = LineDraw.createFatLine([new Vector3(0, 0, 0), new Vector3(0, 0, titleLineHeight)], Object.assign({}, depthProps, {
|
|
@@ -42520,6 +42628,7 @@
|
|
|
a: 1
|
|
|
},
|
|
|
fadeFar: this.fadeFar,
|
|
|
+ maxLineWidth: 300,
|
|
|
transform2D: {
|
|
|
x: 0,
|
|
|
y: 0.2
|
|
@@ -56763,6 +56872,7 @@
|
|
|
renderOrder: Potree.config.renderOrders.tag.label,
|
|
|
pickOrder: Potree.config.renderOrders.tag.label,
|
|
|
useDepth: true,
|
|
|
+ maxLineWidth: 300,
|
|
|
transform2Dpercent: {
|
|
|
x: 0,
|
|
|
y: 0.5
|