introduce baseline in element making it backward compat

This commit is contained in:
Aakansha Doshi 2023-03-31 15:53:03 +05:30
parent 974745b9e5
commit f8b25375a4
8 changed files with 62 additions and 79 deletions

View file

@ -42,7 +42,7 @@ export const actionUnbindText = register({
selectedElements.forEach((element) => {
const boundTextElement = getBoundTextElement(element);
if (boundTextElement) {
const { width, height } = measureText(
const { width, height, baseline } = measureText(
boundTextElement.originalText,
getFontString(boundTextElement),
boundTextElement.lineHeight,
@ -56,6 +56,7 @@ export const actionUnbindText = register({
containerId: null,
width,
height,
baseline,
text: boundTextElement.originalText,
});
mutateElement(element, {

View file

@ -1348,14 +1348,13 @@ class App extends React.Component<AppProps, AppState> {
return false;
}
}
return true;
// don't render text element that's being currently edited (it's
// rendered on remote only)
// return (
// !this.state.editingElement ||
// this.state.editingElement.type !== "text" ||
// element.id !== this.state.editingElement.id
// );
return (
!this.state.editingElement ||
this.state.editingElement.type !== "text" ||
element.id !== this.state.editingElement.id
);
});
const selectionColor = getComputedStyle(

View file

@ -31,11 +31,15 @@ import {
import { getDefaultAppState } from "../appState";
import { LinearElementEditor } from "../element/linearElementEditor";
import { bumpVersion } from "../element/mutateElement";
import { getUpdatedTimestamp, updateActiveTool } from "../utils";
import { getFontString, getUpdatedTimestamp, updateActiveTool } from "../utils";
import { arrayToMap } from "../utils";
import oc from "open-color";
import { MarkOptional, Mutable } from "../utility-types";
import { detectLineHeight, getDefaultLineHeight } from "../element/textElement";
import {
detectLineHeight,
getDefaultLineHeight,
measureBaseline,
} from "../element/textElement";
type RestoredAppState = Omit<
AppState,
@ -170,7 +174,19 @@ const restoreElement = (
fontFamily = getFontFamilyByName(_fontFamily);
}
const text = element.text ?? "";
// line-height might not be specified either when creating elements
// programmatically, or when importing old diagrams.
// For the latter we want to detect the original line height which
// will likely differ from our per-font fixed line height we now use,
// to maintain backward compatibility.
const lineHeight =
element.lineHeight ||
(element.height
? // detect line-height from current element height and font-size
detectLineHeight(element)
: // no element height likely means programmatic use, so default
// to a fixed line height
getDefaultLineHeight(element.fontFamily));
element = restoreElementWithProperties(element, {
fontSize,
fontFamily,
@ -179,19 +195,13 @@ const restoreElement = (
verticalAlign: element.verticalAlign || DEFAULT_VERTICAL_ALIGN,
containerId: element.containerId ?? null,
originalText: element.originalText || text,
// line-height might not be specified either when creating elements
// programmatically, or when importing old diagrams.
// For the latter we want to detect the original line height which
// will likely differ from our per-font fixed line height we now use,
// to maintain backward compatibility.
lineHeight:
element.lineHeight ||
(element.height
? // detect line-height from current element height and font-size
detectLineHeight(element)
: // no element height likely means programmatic use, so default
// to a fixed line height
getDefaultLineHeight(element.fontFamily)),
lineHeight,
baseline: measureBaseline(
element.text,
getFontString(element),
lineHeight,
),
});
if (refreshDimensions) {

View file

@ -30,6 +30,7 @@ import {
wrapText,
getMaxContainerWidth,
getDefaultLineHeight,
measureBaseline,
} from "./textElement";
import { VERTICAL_ALIGN } from "../constants";
import { isArrowElement } from "./typeChecks";
@ -145,6 +146,7 @@ export const newTextElement = (
const text = normalizeText(opts.text);
const metrics = measureText(text, getFontString(opts), lineHeight);
const offsets = getTextElementPositionOffsets(opts, metrics);
const textElement = newElementWith(
{
..._newElementBase<ExcalidrawTextElement>("text", opts),
@ -157,6 +159,7 @@ export const newTextElement = (
y: opts.y - offsets.y,
width: metrics.width,
height: metrics.height,
baseline: metrics.baseline,
containerId: opts.containerId || null,
originalText: text,
lineHeight,
@ -174,14 +177,15 @@ const getAdjustedDimensions = (
y: number;
width: number;
height: number;
baseline: number;
} => {
const container = getContainerElement(element);
const { width: nextWidth, height: nextHeight } = measureText(
nextText,
getFontString(element),
element.lineHeight,
);
const {
width: nextWidth,
height: nextHeight,
baseline: nextBaseline,
} = measureText(nextText, getFontString(element), element.lineHeight);
const { textAlign, verticalAlign } = element;
let x: number;
let y: number;
@ -256,6 +260,7 @@ const getAdjustedDimensions = (
return {
width: nextWidth,
height: nextHeight,
baseline: nextBaseline,
x: Number.isFinite(x) ? x : element.x,
y: Number.isFinite(y) ? y : element.y,
};

View file

@ -58,6 +58,7 @@ export const redrawTextBoundingBox = (
text: textElement.text,
width: textElement.width,
height: textElement.height,
baseline: textElement.baseline,
};
boundTextUpdates.text = textElement.text;
@ -78,6 +79,7 @@ export const redrawTextBoundingBox = (
boundTextUpdates.width = metrics.width;
boundTextUpdates.height = metrics.height;
boundTextUpdates.baseline = metrics.baseline;
if (container) {
if (isArrowElement(container)) {
@ -183,6 +185,7 @@ export const handleBindTextResize = (
const maxWidth = getMaxContainerWidth(container);
const maxHeight = getMaxContainerHeight(container);
let containerHeight = containerDims.height;
let nextBaseLine = textElement.baseline;
if (transformHandleType !== "n" && transformHandleType !== "s") {
if (text) {
text = wrapText(
@ -191,13 +194,14 @@ export const handleBindTextResize = (
maxWidth,
);
}
const dimensions = measureText(
const metrics = measureText(
text,
getFontString(textElement),
textElement.lineHeight,
);
nextHeight = dimensions.height;
nextWidth = dimensions.width;
nextHeight = metrics.height;
nextWidth = metrics.width;
nextBaseLine = metrics.baseline;
}
// increase height in case text element height exceeds
if (nextHeight > maxHeight) {
@ -225,6 +229,7 @@ export const handleBindTextResize = (
text,
width: nextWidth,
height: nextHeight,
baseline: nextBaseLine,
});
if (!isArrowElement(container)) {
@ -285,8 +290,8 @@ export const measureText = (
const fontSize = parseFloat(font);
const height = getTextHeight(text, fontSize, lineHeight);
const width = getTextWidth(text, font);
return { width, height };
const baseline = measureBaseline(text, font, lineHeight);
return { width, height, baseline };
};
export const measureBaseline = (
@ -300,7 +305,7 @@ export const measureBaseline = (
container.style.whiteSpace = "pre";
container.style.font = font;
container.style.minHeight = "1em";
console.log("HEYYY you are here!!");
if (wrapInContainer) {
container.style.overflow = "hidden";
container.style.wordBreak = "break-word";

View file

@ -34,7 +34,6 @@ import {
wrapText,
getMaxContainerHeight,
getMaxContainerWidth,
measureBaseline,
computeContainerDimensionForBoundText,
} from "./textElement";
import {
@ -273,7 +272,10 @@ export const textWysiwyg = ({
textElementWidth += 0.5;
}
const top = viewportY;
let verticalOffset = 0;
if (element.verticalAlign === VERTICAL_ALIGN.BOTTOM) {
//verticalOffset = getBoundTextElementOffset(element);
}
// Make sure text editor height doesn't go beyond viewport
const editorMaxHeight =
(appState.height - viewportY) / appState.zoom.value;
@ -284,7 +286,7 @@ export const textWysiwyg = ({
width: `${textElementWidth}px`,
height: `${textElementHeight}px`,
left: `${viewportX}px`,
top: `${top}px`,
top: `${viewportY + verticalOffset}px`,
transform: getTransform(
textElementWidth,
textElementHeight,
@ -295,8 +297,7 @@ export const textWysiwyg = ({
),
textAlign,
verticalAlign,
// color: updatedTextElement.strokeColor,
color: "red",
color: updatedTextElement.strokeColor,
opacity: updatedTextElement.opacity / 100,
filter: "var(--theme-filter)",
maxHeight: `${editorMaxHeight}px`,

View file

@ -131,6 +131,7 @@ export type ExcalidrawTextElement = _ExcalidrawElementBase &
fontSize: number;
fontFamily: FontFamilyValues;
text: string;
baseline: number;
textAlign: TextAlign;
verticalAlign: VerticalAlign;
containerId: ExcalidrawGenericElement["id"] | null;

View file

@ -46,7 +46,6 @@ import {
getLineHeightInPx,
getMaxContainerHeight,
getMaxContainerWidth,
measureBaseline,
} from "../element/textElement";
import { LinearElementEditor } from "../element/linearElementEditor";
@ -201,17 +200,6 @@ const drawImagePlaceholder = (
size,
);
};
//@ts-ignore
const drawLine = (x, y, width, height, stroke, context) => {
context.lineWidth = "2";
context.strokeStyle = stroke;
context.beginPath();
context.moveTo(x, y);
context.lineTo(x + width, y);
context.closePath();
context.stroke();
};
const drawElementOnCanvas = (
element: NonDeletedExcalidrawElement,
rc: RoughCanvas,
@ -288,33 +276,6 @@ const drawElementOnCanvas = (
context.save();
context.font = getFontString(element);
// drawLine(0, 0, metrics.width, element.height, "green", context);
// drawLine(
// 0,
// -metrics.actualBoundingBoxAscent,
// metrics.width,
// element.height,
// "magenta",
// context,
// );
// drawLine(
// 0,
// metrics.actualBoundingBoxDescent,
// metrics.width,
// element.height,
// "magenta",
// context,
// );
const container = getContainerElement(element);
const baseline = measureBaseline(
element.text,
getFontString(element),
element.lineHeight,
!!container,
);
context.fillStyle = element.strokeColor;
context.textAlign = element.textAlign as CanvasTextAlign;
@ -331,7 +292,7 @@ const drawElementOnCanvas = (
element.fontSize,
element.lineHeight,
);
const verticalOffset = element.height - baseline;
const verticalOffset = element.height - element.baseline;
for (let index = 0; index < lines.length; index++) {
context.fillText(