fix: font not rendered correctly on init (#8002)

This commit is contained in:
David Luzar
2024-05-10 16:37:46 +02:00
committed by GitHub
parent 301e83805d
commit 273ba803d9
10 changed files with 53 additions and 64 deletions
+6 -22
View File
@@ -1,7 +1,5 @@
import { isTextElement, refreshTextDimensions } from "../element";
import { isTextElement } from "../element";
import { newElementWith } from "../element/mutateElement";
import { getContainerElement } from "../element/textElement";
import { isBoundToContainer } from "../element/typeChecks";
import type {
ExcalidrawElement,
ExcalidrawTextElement,
@@ -12,17 +10,9 @@ import { ShapeCache } from "./ShapeCache";
export class Fonts {
private scene: Scene;
private onSceneUpdated: () => void;
constructor({
scene,
onSceneUpdated,
}: {
scene: Scene;
onSceneUpdated: () => void;
}) {
constructor({ scene }: { scene: Scene }) {
this.scene = scene;
this.onSceneUpdated = onSceneUpdated;
}
// it's ok to track fonts across multiple instances only once, so let's use
@@ -57,22 +47,16 @@ export class Fonts {
let didUpdate = false;
this.scene.mapElements((element) => {
if (isTextElement(element) && !isBoundToContainer(element)) {
ShapeCache.delete(element);
if (isTextElement(element)) {
didUpdate = true;
return newElementWith(element, {
...refreshTextDimensions(
element,
getContainerElement(element, this.scene.getNonDeletedElementsMap()),
this.scene.getNonDeletedElementsMap(),
),
});
ShapeCache.delete(element);
return newElementWith(element, {}, true);
}
return element;
});
if (didUpdate) {
this.onSceneUpdated();
this.scene.triggerUpdate();
}
};
+3 -4
View File
@@ -107,9 +107,8 @@ export class Renderer {
width,
editingElement,
pendingImageElementId,
// unused but serves we cache on it to invalidate elements if they
// get mutated
versionNonce: _versionNonce,
// cache-invalidation nonce
sceneNonce: _sceneNonce,
}: {
zoom: AppState["zoom"];
offsetLeft: AppState["offsetLeft"];
@@ -120,7 +119,7 @@ export class Renderer {
width: AppState["width"];
editingElement: AppState["editingElement"];
pendingImageElementId: AppState["pendingImageElementId"];
versionNonce: ReturnType<InstanceType<typeof Scene>["getVersionNonce"]>;
sceneNonce: ReturnType<InstanceType<typeof Scene>["getSceneNonce"]>;
}) => {
const elements = this.scene.getNonDeletedElements();
+15 -9
View File
@@ -138,7 +138,17 @@ class Scene {
elements: null,
cache: new Map(),
};
private versionNonce: number | undefined;
/**
* Random integer regenerated each scene update.
*
* Does not relate to elements versions, it's only a renderer
* cache-invalidation nonce at the moment.
*/
private sceneNonce: number | undefined;
getSceneNonce() {
return this.sceneNonce;
}
getNonDeletedElementsMap() {
return this.nonDeletedElementsMap;
@@ -214,10 +224,6 @@ class Scene {
return (this.elementsMap.get(id) as T | undefined) || null;
}
getVersionNonce() {
return this.versionNonce;
}
getNonDeletedElement(
id: ExcalidrawElement["id"],
): NonDeleted<ExcalidrawElement> | null {
@@ -286,18 +292,18 @@ class Scene {
this.frames = nextFrameLikes;
this.nonDeletedFramesLikes = getNonDeletedElements(this.frames).elements;
this.informMutation();
this.triggerUpdate();
}
informMutation() {
this.versionNonce = randomInteger();
triggerUpdate() {
this.sceneNonce = randomInteger();
for (const callback of Array.from(this.callbacks)) {
callback();
}
}
addCallback(cb: SceneStateCallback): SceneStateCallbackRemover {
onUpdate(cb: SceneStateCallback): SceneStateCallbackRemover {
if (this.callbacks.has(cb)) {
throw new Error();
}