@visactor/vrender-core
Version:
## Description
132 lines (128 loc) • 9.6 kB
JavaScript
import { DIRECTION_KEY } from "./utils";
export default class Frame {
constructor(left, top, width, height, ellipsis, wordBreak, verticalDirection, globalAlign, globalBaseline, layoutDirection, isWidthMax, isHeightMax, singleLine, icons) {
this.left = left, this.top = top, this.width = width, this.height = height, this.actualHeight = 0,
this.bottom = top + height, this.right = left + width, this.ellipsis = ellipsis,
this.wordBreak = wordBreak, this.verticalDirection = verticalDirection, this.lines = [],
this.globalAlign = globalAlign, this.globalBaseline = globalBaseline, this.layoutDirection = layoutDirection,
this.directionKey = DIRECTION_KEY[this.layoutDirection], this.isWidthMax = isWidthMax,
this.isHeightMax = isHeightMax, this.singleLine = singleLine, icons ? (icons.clear(),
this.icons = icons) : this.icons = new Map;
}
draw(ctx, drawIcon) {
const {width: actualWidth, height: actualHeight} = this.getActualSize(), width = this.isWidthMax ? Math.min(this.width, actualWidth) : this.width || actualWidth || 0;
let height = this.isHeightMax ? Math.min(this.height, actualHeight) : this.height || actualHeight || 0;
height = Math.min(height, actualHeight);
let deltaY = 0;
switch (this.globalBaseline) {
case "top":
deltaY = 0;
break;
case "middle":
deltaY = -height / 2;
break;
case "bottom":
deltaY = -height;
}
let deltaX = 0;
"right" === this.globalAlign || "end" === this.globalAlign ? deltaX = -width : "center" === this.globalAlign && (deltaX = -width / 2);
let frameHeight = this[this.directionKey.height];
this.singleLine && (frameHeight = this.lines[0].height + 1);
let lastLineTag = !1;
if ("middle" === this.verticalDirection) if (this.actualHeight >= frameHeight && 0 !== frameHeight) for (let i = 0; i < this.lines.length; i++) {
const {top: top, height: height} = this.lines[i];
if (top + height < this[this.directionKey.top] || top + height > this[this.directionKey.top] + frameHeight) return lastLineTag;
let lastLine = !1;
this.ellipsis && this.lines[i + 1] && this.lines[i + 1].top + this.lines[i + 1].height > this[this.directionKey.top] + frameHeight && (lastLine = !0,
lastLineTag = !0), this.lines[i].draw(ctx, lastLine, this.lines[i][this.directionKey.left] + deltaX, this.lines[i][this.directionKey.top] + deltaY, this.ellipsis, drawIcon);
} else {
const detalHeight = Math.floor((frameHeight - this.actualHeight) / 2);
"vertical" === this.layoutDirection ? deltaX += detalHeight : deltaY += detalHeight;
for (let i = 0; i < this.lines.length; i++) this.lines[i].draw(ctx, !1, this.lines[i][this.directionKey.left] + deltaX, this.lines[i][this.directionKey.top] + deltaY, this.ellipsis, drawIcon);
} else if ("bottom" === this.verticalDirection && "vertical" !== this.layoutDirection) for (let i = 0; i < this.lines.length; i++) {
const {top: top, height: height} = this.lines[i], y = frameHeight - this.lines[i].top - this.lines[i].height;
if (0 === frameHeight) this.lines[i].draw(ctx, !1, deltaX, y + deltaY, this.ellipsis, drawIcon); else {
if (y + height > this[this.directionKey.top] + frameHeight || y < this[this.directionKey.top]) return lastLineTag;
{
let lastLine = !1;
this.ellipsis && this.lines[i + 1] && y - this.lines[i + 1].height < this[this.directionKey.top] && (lastLine = !0,
lastLineTag = !0), this.lines[i].draw(ctx, lastLine, deltaX, y + deltaY, this.ellipsis, drawIcon);
}
}
} else {
"bottom" === this.verticalDirection && "vertical" === this.layoutDirection && this.singleLine && this.isWidthMax && (deltaX += this.lines[0].height + 1);
for (let i = 0; i < this.lines.length; i++) {
"bottom" === this.verticalDirection && "vertical" === this.layoutDirection && (deltaX -= this.lines[i].height + this.lines[i].top);
const {top: top, height: height} = this.lines[i];
if (0 === frameHeight) this.lines[i].draw(ctx, !1, this.lines[i][this.directionKey.left] + deltaX, this.lines[i][this.directionKey.top] + deltaY, this.ellipsis, drawIcon); else {
if (top + height < this[this.directionKey.top] || top + height > this[this.directionKey.top] + frameHeight) return lastLineTag;
{
let lastLine = !1;
this.ellipsis && this.lines[i + 1] && this.lines[i + 1].top + this.lines[i + 1].height > this[this.directionKey.top] + frameHeight && (lastLine = !0,
lastLineTag = !0), this.lines[i].draw(ctx, lastLine, this.lines[i][this.directionKey.left] + deltaX, this.lines[i][this.directionKey.top] + deltaY, this.ellipsis, drawIcon);
}
}
}
}
return lastLineTag;
}
getActualSize() {
return this.ellipsis ? this.getActualSizeWidthEllipsis() : this.getRawActualSize();
}
getRawActualSize() {
let width = 0, height = 0;
for (let i = 0; i < this.lines.length; i++) {
const line = this.lines[i];
line.actualWidth > width && (width = line.actualWidth), height += line.height;
}
return {
width: "vertical" === this.layoutDirection ? height : width,
height: "vertical" === this.layoutDirection ? width : height
};
}
getActualSizeWidthEllipsis() {
let widthBound = 0, heightBound = 0;
const {width: actualWidth, height: actualHeight} = this.getRawActualSize();
this.width;
let height = this.height || actualHeight || 0;
height = Math.min(height, actualHeight);
let frameHeight = this[this.directionKey.height];
if (this.singleLine && (frameHeight = this.lines[0].height + 1), "middle" === this.verticalDirection) if (this.actualHeight >= frameHeight && 0 !== frameHeight) for (let i = 0; i < this.lines.length; i++) {
const {top: top, height: height} = this.lines[i];
if (top + height < this[this.directionKey.top] || top + height > this[this.directionKey.top] + frameHeight) ; else if (this.ellipsis && this.lines[i + 1] && this.lines[i + 1].top + this.lines[i + 1].height > this[this.directionKey.top] + frameHeight) {
const ellipsis = !0 === this.ellipsis ? "..." : this.ellipsis || "", lineWidth = this.lines[i].getWidthWithEllips(ellipsis);
lineWidth > widthBound && (widthBound = lineWidth), heightBound += this.lines[i].height;
} else this.lines[i].actualWidth > widthBound && (widthBound = this.lines[i].actualWidth),
heightBound += this.lines[i].height;
} else {
Math.floor((frameHeight - this.actualHeight) / 2);
for (let i = 0; i < this.lines.length; i++) this.lines[i].actualWidth > widthBound && (widthBound = this.lines[i].actualWidth),
heightBound += this.lines[i].height;
} else if ("bottom" === this.verticalDirection) for (let i = 0; i < this.lines.length; i++) {
const {top: top, height: height} = this.lines[i], y = frameHeight - this.lines[i].top - this.lines[i].height;
if (0 === frameHeight) this.lines[i].actualWidth > widthBound && (widthBound = this.lines[i].actualWidth),
heightBound += this.lines[i].height; else if (y + height > this[this.directionKey.top] + frameHeight || y < this[this.directionKey.top]) ; else {
if (this.ellipsis && this.lines[i + 1] && y - this.lines[i + 1].height < this[this.directionKey.top]) {
const ellipsis = !0 === this.ellipsis ? "..." : this.ellipsis || "", lineWidth = this.lines[i].getWidthWithEllips(ellipsis);
lineWidth > widthBound && (widthBound = lineWidth), heightBound += this.lines[i].height;
} else this.lines[i].actualWidth > widthBound && (widthBound = this.lines[i].actualWidth),
heightBound += this.lines[i].height;
}
} else for (let i = 0; i < this.lines.length; i++) {
const {top: top, height: height} = this.lines[i];
if (0 === frameHeight) this.lines[i].actualWidth > widthBound && (widthBound = this.lines[i].actualWidth),
heightBound += this.lines[i].height; else if (top + height < this[this.directionKey.top] || top + height > this[this.directionKey.top] + frameHeight) ; else {
if (this.ellipsis && this.lines[i + 1] && this.lines[i + 1].top + this.lines[i + 1].height > this[this.directionKey.top] + frameHeight) {
const ellipsis = !0 === this.ellipsis ? "..." : this.ellipsis || "", lineWidth = this.lines[i].getWidthWithEllips(ellipsis);
lineWidth > widthBound && (widthBound = lineWidth), heightBound += this.lines[i].height;
} else this.lines[i].actualWidth > widthBound && (widthBound = this.lines[i].actualWidth),
heightBound += this.lines[i].height;
}
}
return {
width: "vertical" === this.layoutDirection ? heightBound : widthBound,
height: "vertical" === this.layoutDirection ? widthBound : heightBound
};
}
}
//# sourceMappingURL=frame.js.map