mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
sync intermediate text updates (#1174)
* sync intermediate text updates * fix initial render text position * batch updates * tweak onChange subscription
This commit is contained in:
parent
0c9459e9e5
commit
4912a29e75
4 changed files with 168 additions and 120 deletions
|
@ -37,7 +37,7 @@ export function getSyncableElements(elements: readonly ExcalidrawElement[]) {
|
|||
// There are places in Excalidraw where synthetic invisibly small elements are added and removed.
|
||||
// It's probably best to keep those local otherwise there might be a race condition that
|
||||
// gets the app into an invalid state. I've never seen it happen but I'm worried about it :)
|
||||
return elements.filter((el) => !isInvisiblySmallElement(el));
|
||||
return elements.filter((el) => el.isDeleted || !isInvisiblySmallElement(el));
|
||||
}
|
||||
|
||||
export function getElementMap(elements: readonly ExcalidrawElement[]) {
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
} from "../element/types";
|
||||
import { measureText } from "../utils";
|
||||
import { randomInteger, randomId } from "../random";
|
||||
import { newElementWith } from "./mutateElement";
|
||||
|
||||
type ElementConstructorOpts = {
|
||||
x: ExcalidrawGenericElement["x"];
|
||||
|
@ -75,17 +76,21 @@ export function newTextElement(
|
|||
): ExcalidrawTextElement {
|
||||
const { text, font } = opts;
|
||||
const metrics = measureText(text, font);
|
||||
const textElement = {
|
||||
..._newElementBase<ExcalidrawTextElement>("text", opts),
|
||||
text: text,
|
||||
font: font,
|
||||
// Center the text
|
||||
x: opts.x - metrics.width / 2,
|
||||
y: opts.y - metrics.height / 2,
|
||||
width: metrics.width,
|
||||
height: metrics.height,
|
||||
baseline: metrics.baseline,
|
||||
};
|
||||
const textElement = newElementWith(
|
||||
{
|
||||
..._newElementBase<ExcalidrawTextElement>("text", opts),
|
||||
isDeleted: false,
|
||||
text: text,
|
||||
font: font,
|
||||
// Center the text
|
||||
x: opts.x - metrics.width / 2,
|
||||
y: opts.y - metrics.height / 2,
|
||||
width: metrics.width,
|
||||
height: metrics.height,
|
||||
baseline: metrics.baseline,
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
return textElement;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ type TextWysiwygParams = {
|
|||
opacity: number;
|
||||
zoom: number;
|
||||
angle: number;
|
||||
onChange?: (text: string) => void;
|
||||
onSubmit: (text: string) => void;
|
||||
onCancel: () => void;
|
||||
};
|
||||
|
@ -34,6 +35,7 @@ export function textWysiwyg({
|
|||
opacity,
|
||||
zoom,
|
||||
angle,
|
||||
onChange,
|
||||
onSubmit,
|
||||
onCancel,
|
||||
}: TextWysiwygParams) {
|
||||
|
@ -96,6 +98,12 @@ export function textWysiwyg({
|
|||
}
|
||||
};
|
||||
|
||||
if (onChange) {
|
||||
editable.oninput = () => {
|
||||
onChange(trimText(editable.innerText));
|
||||
};
|
||||
}
|
||||
|
||||
editable.onkeydown = (ev) => {
|
||||
if (ev.key === KEYS.ESCAPE) {
|
||||
ev.preventDefault();
|
||||
|
@ -121,9 +129,6 @@ export function textWysiwyg({
|
|||
}
|
||||
|
||||
function cleanup() {
|
||||
editable.onblur = null;
|
||||
editable.onkeydown = null;
|
||||
editable.onpaste = null;
|
||||
window.removeEventListener("wheel", stopEvent, true);
|
||||
document.body.removeChild(editable);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue