@visactor/vrender-core
Version:
## Description
196 lines (176 loc) • 8.18 kB
JavaScript
import { application } from "../../application";
import { createColor } from "../../common/canvas-utils";
import { DEFAULT_TEXT_FONT_FAMILY } from "../../constants";
export const DIRECTION_KEY = {
horizontal: {
width: "width",
height: "height",
left: "left",
top: "top",
x: "x",
y: "y",
bottom: "bottom"
},
vertical: {
width: "height",
height: "width",
left: "top",
top: "left",
x: "y",
y: "x",
bottom: "right"
}
};
const defaultFormatting = {
fontSize: 16,
fontFamily: DEFAULT_TEXT_FONT_FAMILY,
fill: !0,
stroke: !1,
fontWeight: "normal",
lineHeight: "normal",
fontStyle: "normal",
textDecoration: "none",
textAlign: "left",
script: "normal"
}, nbsp = String.fromCharCode(160);
export const regLetter = /\w|\(|\)|-/;
const regPunctuation = /[.?!,;:/,。?!、;:]/;
export const regFirstSpace = /\S/;
const setTextStyle = (ctx, character) => {
let fontSize = character.fontSize || 16;
switch (character.script) {
case "super":
case "sub":
fontSize *= .8;
}
ctx.setTextStyle({
textAlign: "left",
textBaseline: character.textBaseline || "alphabetic",
fontStyle: character.fontStyle || "",
fontWeight: character.fontWeight || "",
fontSize: fontSize,
fontFamily: character.fontFamily
});
};
export function applyFillStyle(ctx, character, b) {
const fillStyle = character && character.fill || defaultFormatting.fill;
if (!fillStyle) return void (ctx.globalAlpha = 0);
const {fillOpacity: fillOpacity = 1, opacity: opacity = 1} = character;
ctx.globalAlpha = fillOpacity * opacity, ctx.fillStyle = b ? createColor(ctx, fillStyle, {
AABBBounds: b
}) : fillStyle, setTextStyle(ctx, character);
}
export function applyStrokeStyle(ctx, character) {
const strokeStyle = character && character.stroke || defaultFormatting.stroke;
if (!strokeStyle) return void (ctx.globalAlpha = 0);
const {strokeOpacity: strokeOpacity = 1, opacity: opacity = 1} = character;
ctx.globalAlpha = strokeOpacity * opacity, ctx.lineWidth = character && "number" == typeof character.lineWidth ? character.lineWidth : 1,
ctx.strokeStyle = strokeStyle, setTextStyle(ctx, character);
}
export function prepareContext(ctx) {
ctx.setTextStyle({
textAlign: "left",
textBaseline: "bottom"
});
}
export function getStrByWithDom(desc, width, style, guessIndex, needTestLetter) {
desc = desc.replace(/\s/g, nbsp);
const span = document.createElement("span");
span.setAttribute("style", style), span.style.visibility = "hidden", span.style.whiteSpace = "nowrap",
document.body.appendChild(span);
let index = guessIndex, temp = desc.slice(0, index);
span.innerText = temp;
let tempWidth = span.offsetWidth, tempNext = desc.slice(0, index + 1);
span.innerText = tempNext;
let tempWidthNext = span.offsetWidth;
for (;tempWidth > width || tempWidthNext <= width; ) tempWidth > width ? index-- : index++,
temp = desc.slice(0, index), span.innerText = temp, tempWidth = span.offsetWidth,
tempNext = desc.slice(0, index + 1), span.innerText = tempNext, tempWidthNext = span.offsetWidth;
return needTestLetter && (index = testLetter(desc, index)), document.body.removeChild(span),
index;
}
export function getStrByWithCanvas(desc, width, character, guessIndex, needTestLetter) {
if (!width || width <= 0) return 0;
const textMeasure = application.graphicUtil.textMeasure;
let index = guessIndex, temp = desc.slice(0, index), tempWidth = Math.floor(textMeasure.measureText(temp, character).width), tempNext = desc.slice(0, index + 1), tempWidthNext = Math.floor(textMeasure.measureText(tempNext, character).width);
for (;tempWidth > width || tempWidthNext <= width; ) {
if (tempWidth > width ? index-- : index++, index > desc.length) {
index = desc.length;
break;
}
if (index < 0) {
index = 0;
break;
}
temp = desc.slice(0, index), tempWidth = Math.floor(textMeasure.measureText(temp, character).width),
tempNext = desc.slice(0, index + 1), tempWidthNext = Math.floor(textMeasure.measureText(tempNext, character).width);
}
return needTestLetter && (index = testLetter(desc, index)), index;
}
export function getWordStartEndIdx(string, index) {
let startIdx = index;
for (;(regLetter.test(string[startIdx - 1]) && regLetter.test(string[startIdx]) || regPunctuation.test(string[startIdx])) && (startIdx--,
!(startIdx <= 0)); ) ;
let endIdx = index;
for (;(regLetter.test(string[endIdx + 1]) && regLetter.test(string[endIdx]) || regPunctuation.test(string[endIdx])) && (endIdx++,
!(endIdx >= string.length)); ) ;
return endIdx = Math.min(endIdx + 1, string.length), {
startIdx: startIdx,
endIdx: endIdx
};
}
export function testLetter(string, index, negativeWrongMatch = !1) {
let i = index;
for (;regLetter.test(string[i - 1]) && regLetter.test(string[i]) || regPunctuation.test(string[i]); ) if (i--,
i <= 0) return negativeWrongMatch ? testLetter2(string, index) : index;
return i;
}
export function testLetter2(string, index) {
let i = index;
for (;regLetter.test(string[i + 1]) && regLetter.test(string[i]) || regPunctuation.test(string[i]); ) if (i++,
i >= string.length) return i;
return i + 1;
}
export function measureTextDom(text, style) {
var _a;
let div;
const span = document.createElement("span"), block = document.createElement("div");
div = document.createElement("div"), block.style.display = "inline-block", block.style.width = "1px",
block.style.height = "0", div.style.visibility = "hidden", div.style.position = "absolute",
div.style.top = "0", div.style.left = "0", div.style.width = "500px", div.style.height = "200px",
div.style.whiteSpace = "nowrap", div.appendChild(span), div.appendChild(block),
document.body.appendChild(div);
const result = {};
try {
span.setAttribute("style", style), span.style.whiteSpace = "nowrap", span.style.display = "inline-block",
span.innerHTML = "", span.appendChild(document.createTextNode(text.replace(/\s/g, nbsp))),
block.style.verticalAlign = "baseline", result.ascent = block.offsetTop - span.offsetTop,
block.style.verticalAlign = "bottom", result.height = block.offsetTop - span.offsetTop,
result.descent = result.height - result.ascent, result.width = span.offsetWidth;
} finally {
null === (_a = div.parentNode) || void 0 === _a || _a.removeChild(div), div = null;
}
return result;
}
export function measureTextCanvas(text, character, mode = "actual") {
const measurement = application.graphicUtil.textMeasure.measureText(text, character), result = {
ascent: 0,
height: 0,
descent: 0,
width: 0
}, ascent = "actual" === mode ? measurement.actualBoundingBoxAscent : measurement.fontBoundingBoxAscent, descent = "actual" === mode ? measurement.actualBoundingBoxDescent : measurement.fontBoundingBoxDescent;
return "number" != typeof ascent || "number" != typeof descent ? (result.width = Math.floor(measurement.width),
result.height = character.fontSize || 0, result.ascent = result.height, result.descent = 0) : (result.width = Math.floor(measurement.width),
result.height = Math.floor(ascent + descent), result.ascent = Math.floor(ascent),
result.descent = result.height - result.ascent), result;
}
export function getFontString(character, ctx) {
let fontSize = character && character.fontSize || defaultFormatting.fontSize;
if (character) switch (character.script) {
case "super":
case "sub":
fontSize *= .8;
}
return (character && character.fontStyle || "") + " " + (character && character.fontWeight || "") + " " + (fontSize || 12) + "px " + (character && character.fontFamily || defaultFormatting.fontFamily);
}
//# sourceMappingURL=utils.js.map