feat:web text maxLines
This commit is contained in:
parent
afb3de1fbc
commit
d71e55e673
46
doric-web/dist/index.js
vendored
46
doric-web/dist/index.js
vendored
@ -7204,7 +7204,6 @@ var doric_web = (function (exports, axios, sandbox) {
|
|||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.style.display = "flex";
|
div.style.display = "flex";
|
||||||
div.style.overflow = "hidden";
|
div.style.overflow = "hidden";
|
||||||
div.style.lineHeight = `${this.lineHeight()}em`;
|
|
||||||
this.textElement = document.createElement('span');
|
this.textElement = document.createElement('span');
|
||||||
div.appendChild(this.textElement);
|
div.appendChild(this.textElement);
|
||||||
div.style.justifyContent = "center";
|
div.style.justifyContent = "center";
|
||||||
@ -7300,46 +7299,53 @@ var doric_web = (function (exports, axios, sandbox) {
|
|||||||
configSize() {
|
configSize() {
|
||||||
if (this.maxLines > 0) {
|
if (this.maxLines > 0) {
|
||||||
const computedStyle = window.getComputedStyle(this.view);
|
const computedStyle = window.getComputedStyle(this.view);
|
||||||
const currentContentHeight = this.view.clientHeight - pixelString2Number(computedStyle.paddingTop) - pixelString2Number(computedStyle.paddingBottom);
|
const lineHeight = this.lineHeight(computedStyle);
|
||||||
let maxHeight = Math.ceil(parseFloat(computedStyle.getPropertyValue('font-size')) * this.lineHeight() * this.maxLines);
|
let allowedMaxLines = this.maxLines;
|
||||||
if (currentContentHeight > 0) {
|
const contentHeight = this.view.clientHeight - pixelString2Number(computedStyle.paddingTop) - pixelString2Number(computedStyle.paddingBottom);
|
||||||
maxHeight = Math.min(maxHeight, Math.ceil(currentContentHeight));
|
if (contentHeight > 0) {
|
||||||
|
const contentAllowedLines = Math.floor(contentHeight / lineHeight);
|
||||||
|
allowedMaxLines = Math.min(this.maxLines, contentAllowedLines);
|
||||||
}
|
}
|
||||||
if (this.computedHeight(computedStyle) > maxHeight) {
|
const originalLines = Math.floor(this.originalHeight(computedStyle) / lineHeight);
|
||||||
this.textElement.innerText = this.truncationText(computedStyle, maxHeight);
|
if (originalLines > allowedMaxLines) {
|
||||||
|
this.textElement.innerText = this.truncationText(computedStyle, lineHeight, allowedMaxLines);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lineHeight() {
|
lineHeight(style) {
|
||||||
return 1.3;
|
const canvas = document.createElement('canvas');
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
ctx.font = style.font;
|
||||||
|
const pureText = this.textElement.innerText.replace(/\n/g, '');
|
||||||
|
const metrics = ctx.measureText(pureText);
|
||||||
|
return metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;
|
||||||
}
|
}
|
||||||
computedHeight(style) {
|
originalHeight(style) {
|
||||||
const tempEle = document.createElement('div');
|
const tempEle = document.createElement('div');
|
||||||
tempEle.style.font = style.font;
|
tempEle.style.font = style.font;
|
||||||
tempEle.textContent = this.textElement.innerText;
|
tempEle.textContent = this.textElement.innerText;
|
||||||
tempEle.style.whiteSpace = 'normal';
|
tempEle.style.whiteSpace = style.whiteSpace;
|
||||||
this.view.style.overflow = 'hidden';
|
this.view.style.overflow = style.overflow;
|
||||||
tempEle.style.lineHeight = `${this.lineHeight()}em`;
|
tempEle.style.width = style.width;
|
||||||
tempEle.style.width = this.view.style.width;
|
|
||||||
document.body.appendChild(tempEle);
|
document.body.appendChild(tempEle);
|
||||||
const height = tempEle.offsetHeight;
|
const height = tempEle.offsetHeight;
|
||||||
document.body.removeChild(tempEle);
|
document.body.removeChild(tempEle);
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
truncationText(style, maxHeight) {
|
truncationText(style, lineHeight, maxLines) {
|
||||||
const originalText = this.textElement.innerText;
|
const originalText = this.textElement.innerText;
|
||||||
let start = 0, end = originalText.length;
|
let start = 0, end = originalText.length;
|
||||||
const tempEle = document.createElement('div');
|
const tempEle = document.createElement('div');
|
||||||
tempEle.style.font = style.font;
|
tempEle.style.font = style.font;
|
||||||
tempEle.style.whiteSpace = 'normal';
|
tempEle.style.whiteSpace = style.whiteSpace;
|
||||||
this.view.style.overflow = 'hidden';
|
this.view.style.overflow = style.overflow;
|
||||||
tempEle.style.lineHeight = `${this.lineHeight()}em`;
|
tempEle.style.width = style.width;
|
||||||
tempEle.style.width = this.view.style.width;
|
|
||||||
document.body.appendChild(tempEle);
|
document.body.appendChild(tempEle);
|
||||||
while (start <= end) {
|
while (start <= end) {
|
||||||
const mid = Math.floor((start + end) / 2);
|
const mid = Math.floor((start + end) / 2);
|
||||||
tempEle.textContent = originalText.slice(0, mid) + '...';
|
tempEle.textContent = originalText.slice(0, mid) + '...';
|
||||||
if (tempEle.offsetHeight > maxHeight) {
|
const lines = Math.floor(tempEle.offsetHeight / lineHeight);
|
||||||
|
if (lines > maxLines) {
|
||||||
end = mid - 1;
|
end = mid - 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
2
doric-web/dist/index.js.map
vendored
2
doric-web/dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
@ -8,7 +8,6 @@ export class DoricTextNode extends DoricViewNode {
|
|||||||
const div = document.createElement('div')
|
const div = document.createElement('div')
|
||||||
div.style.display = "flex"
|
div.style.display = "flex"
|
||||||
div.style.overflow = "hidden"
|
div.style.overflow = "hidden"
|
||||||
div.style.lineHeight = `${this.lineHeight()}em`
|
|
||||||
this.textElement = document.createElement('span')
|
this.textElement = document.createElement('span')
|
||||||
div.appendChild(this.textElement)
|
div.appendChild(this.textElement)
|
||||||
div.style.justifyContent = "center"
|
div.style.justifyContent = "center"
|
||||||
@ -100,30 +99,39 @@ export class DoricTextNode extends DoricViewNode {
|
|||||||
|
|
||||||
configSize() {
|
configSize() {
|
||||||
if (this.maxLines > 0) {
|
if (this.maxLines > 0) {
|
||||||
const computedStyle = window.getComputedStyle(this.view)
|
const computedStyle = window.getComputedStyle(this.view)
|
||||||
const currentContentHeight = this.view.clientHeight - pixelString2Number(computedStyle.paddingTop) - pixelString2Number(computedStyle.paddingBottom)
|
const lineHeight = this.lineHeight(computedStyle)
|
||||||
let maxHeight = Math.ceil(parseFloat(computedStyle.getPropertyValue('font-size')) * this.lineHeight() * this.maxLines)
|
let allowedMaxLines = this.maxLines
|
||||||
if (currentContentHeight > 0) {
|
|
||||||
maxHeight = Math.min(maxHeight, Math.ceil(currentContentHeight))
|
const contentHeight = this.view.clientHeight - pixelString2Number(computedStyle.paddingTop) - pixelString2Number(computedStyle.paddingBottom)
|
||||||
|
if (contentHeight > 0) {
|
||||||
|
const contentAllowedLines = Math.floor(contentHeight / lineHeight)
|
||||||
|
allowedMaxLines = Math.min(this.maxLines, contentAllowedLines)
|
||||||
}
|
}
|
||||||
if (this.computedHeight(computedStyle) > maxHeight) {
|
|
||||||
this.textElement.innerText = this.truncationText(computedStyle, maxHeight)
|
const originalLines = Math.floor(this.originalHeight(computedStyle) / lineHeight)
|
||||||
|
if (originalLines > allowedMaxLines) {
|
||||||
|
this.textElement.innerText = this.truncationText(computedStyle, lineHeight, allowedMaxLines)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lineHeight() {
|
lineHeight(style: CSSStyleDeclaration) {
|
||||||
return 1.3
|
const canvas = document.createElement('canvas')
|
||||||
|
const ctx = canvas.getContext('2d')
|
||||||
|
ctx!.font = style.font
|
||||||
|
const pureText = this.textElement.innerText.replace(/\n/g, '')
|
||||||
|
const metrics = ctx!.measureText(pureText)
|
||||||
|
return metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent
|
||||||
}
|
}
|
||||||
|
|
||||||
computedHeight(style:CSSStyleDeclaration) {
|
originalHeight(style:CSSStyleDeclaration) {
|
||||||
const tempEle = document.createElement('div')
|
const tempEle = document.createElement('div')
|
||||||
tempEle.style.font = style.font
|
tempEle.style.font = style.font
|
||||||
tempEle.textContent = this.textElement.innerText
|
tempEle.textContent = this.textElement.innerText
|
||||||
tempEle.style.whiteSpace = 'normal'
|
tempEle.style.whiteSpace = style.whiteSpace
|
||||||
this.view.style.overflow = 'hidden'
|
this.view.style.overflow = style.overflow
|
||||||
tempEle.style.lineHeight = `${this.lineHeight()}em`
|
tempEle.style.width = style.width
|
||||||
tempEle.style.width = this.view.style.width
|
|
||||||
document.body.appendChild(tempEle)
|
document.body.appendChild(tempEle)
|
||||||
|
|
||||||
const height = tempEle.offsetHeight
|
const height = tempEle.offsetHeight
|
||||||
@ -131,22 +139,22 @@ export class DoricTextNode extends DoricViewNode {
|
|||||||
return height
|
return height
|
||||||
}
|
}
|
||||||
|
|
||||||
truncationText(style:CSSStyleDeclaration, maxHeight:number) {
|
truncationText(style:CSSStyleDeclaration, lineHeight:number, maxLines:number) {
|
||||||
const originalText = this.textElement.innerText
|
const originalText = this.textElement.innerText
|
||||||
let start = 0, end = originalText.length
|
let start = 0, end = originalText.length
|
||||||
|
|
||||||
const tempEle = document.createElement('div')
|
const tempEle = document.createElement('div')
|
||||||
tempEle.style.font = style.font
|
tempEle.style.font = style.font
|
||||||
tempEle.style.whiteSpace = 'normal'
|
tempEle.style.whiteSpace = style.whiteSpace
|
||||||
this.view.style.overflow = 'hidden'
|
this.view.style.overflow = style.overflow
|
||||||
tempEle.style.lineHeight = `${this.lineHeight()}em`
|
tempEle.style.width = style.width
|
||||||
tempEle.style.width = this.view.style.width
|
|
||||||
document.body.appendChild(tempEle);
|
document.body.appendChild(tempEle);
|
||||||
|
|
||||||
while(start <= end) {
|
while(start <= end) {
|
||||||
const mid = Math.floor((start + end) / 2)
|
const mid = Math.floor((start + end) / 2)
|
||||||
tempEle.textContent = originalText.slice(0,mid) + '...'
|
tempEle.textContent = originalText.slice(0,mid) + '...'
|
||||||
if (tempEle.offsetHeight > maxHeight) {
|
const lines = Math.floor(tempEle.offsetHeight / lineHeight)
|
||||||
|
if (lines > maxLines) {
|
||||||
end = mid - 1
|
end = mid - 1
|
||||||
} else {
|
} else {
|
||||||
start = mid + 1
|
start = mid + 1
|
||||||
|
Reference in New Issue
Block a user