Skip to content

Commit

Permalink
Merge branch 'excalidraw-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
zsviczian committed Jul 23, 2024
2 parents cb47c74 + 67467c9 commit d02b55d
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 16 deletions.
2 changes: 1 addition & 1 deletion excalidraw-app/app-language/language-detector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const getPreferredLanguage = () => {
const initialLanguage =
(detectedLanguage
? // region code may not be defined if user uses generic preferred language
// (e.g. chinese vs instead of chienese-simplified)
// (e.g. chinese vs instead of chinese-simplified)
languages.find((lang) => lang.code.startsWith(detectedLanguage))?.code
: null) || defaultLang.code;

Expand Down
1 change: 0 additions & 1 deletion packages/excalidraw/components/canvases/StaticCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ const getRelevantAppStateProps = (
selectedElementIds: appState.selectedElementIds,
frameToHighlight: appState.frameToHighlight,
editingGroupId: appState.editingGroupId,
isRotating: appState.isRotating,
});

const areEqual = (
Expand Down
6 changes: 3 additions & 3 deletions packages/excalidraw/fractionalIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import { InvalidFractionalIndexError } from "./errors";
* Envisioned relation between array order and fractional indices:
*
* 1) Array (or array-like ordered data structure) should be used as a cache of elements order, hiding the internal fractional indices implementation.
* - it's undesirable to to perform reorder for each related operation, thefeore it's necessary to cache the order defined by fractional indices into an ordered data structure
* - it's undesirable to perform reorder for each related operation, therefore it's necessary to cache the order defined by fractional indices into an ordered data structure
* - it's easy enough to define the order of the elements from the outside (boundaries), without worrying about the underlying structure of fractional indices (especially for the host apps)
* - it's necessary to always keep the array support for backwards compatibility (restore) - old scenes, old libraries, supporting multiple excalidraw versions etc.
* - it's necessary to always keep the fractional indices in sync with the array order
* - elements with invalid indices should be detected and synced, without altering the already valid indices
*
* 2) Fractional indices should be used to reorder the elements, whenever the cached order is expected to be invalidated.
* - as the fractional indices are encoded as part of the elements, it opens up possibilties for incremental-like APIs
* - re-order based on fractional indices should be part of (multiplayer) operations such as reconcillitation & undo/redo
* - as the fractional indices are encoded as part of the elements, it opens up possibilities for incremental-like APIs
* - re-order based on fractional indices should be part of (multiplayer) operations such as reconciliation & undo/redo
* - technically all the z-index actions could perform also re-order based on fractional indices,but in current state it would not bring much benefits,
* as it's faster & more efficient to perform re-order based on array manipulation and later synchronisation of moved indices with the array order
*/
Expand Down
32 changes: 22 additions & 10 deletions packages/excalidraw/renderer/renderElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export interface ExcalidrawElementWithCanvas {
canvas: HTMLCanvasElement;
theme: AppState["theme"];
scale: number;
angle: number;
zoomValue: AppState["zoom"]["value"];
canvasOffsetX: number;
canvasOffsetY: number;
Expand Down Expand Up @@ -237,10 +238,13 @@ const generateElementCanvas = (
}

drawElementOnCanvas(element, rc, context, renderConfig, appState);

context.restore();

const boundTextElement = getBoundTextElement(element, elementsMap);
const boundTextCanvas = document.createElement("canvas");
const boundTextCanvasContext = boundTextCanvas.getContext("2d")!;

if (isArrowElement(element) && boundTextElement) {
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
// Take max dimensions of arrow canvas so that when canvas is rotated
Expand Down Expand Up @@ -299,6 +303,7 @@ const generateElementCanvas = (
scale,
);
}

return {
element,
canvas,
Expand All @@ -312,6 +317,7 @@ const generateElementCanvas = (
containingFrameOpacity:
getContainingFrame(element, elementsMap)?.opacity || 100,
boundTextCanvas,
angle: element.angle,
};
};

Expand Down Expand Up @@ -507,8 +513,8 @@ const generateElementWithCanvas = (
prevElementWithCanvas &&
prevElementWithCanvas.zoomValue !== zoom.value &&
!appState?.shouldCacheIgnoreZoom;
const boundTextElement = getBoundTextElement(element, elementsMap);
const boundTextElementVersion = boundTextElement?.version || null;
const boundTextElement = getBoundTextElement(element, elementsMap);
const boundTextElementVersion = boundTextElement?.version || null;

const containingFrameOpacity =
getContainingFrame(element, elementsMap)?.opacity || 100;
Expand All @@ -519,7 +525,13 @@ const generateElementWithCanvas = (
prevElementWithCanvas.theme !== appState.theme ||
prevElementWithCanvas.boundTextElementVersion !== boundTextElementVersion ||
prevElementWithCanvas.containingFrameOpacity !== containingFrameOpacity ||
(isArrowElement(element) && boundTextElement && appState.isRotating)
// since we rotate the canvas when copying from cached canvas, we don't
// regenerate the cached canvas. But we need to in case of labels which are
// cached alongside the arrow, and we want the labels to remain unrotated
// with respect to the arrow.
(isArrowElement(element) &&
boundTextElement &&
element.angle !== prevElementWithCanvas.angle)
) {
const elementWithCanvas = generateElementCanvas(
element,
Expand Down Expand Up @@ -557,13 +569,13 @@ const drawElementFromCanvas = (

if (isArrowElement(element) && boundTextElement) {
const offsetX =
(elementWithCanvas.boundTextCanvas.width -
elementWithCanvas.canvas!.width) /
2;
const offsetY =
(elementWithCanvas.boundTextCanvas.height -
elementWithCanvas.canvas!.height) /
2;
(elementWithCanvas.boundTextCanvas.width -
elementWithCanvas.canvas!.width) /
2;
const offsetY =
(elementWithCanvas.boundTextCanvas.height -
elementWithCanvas.canvas!.height) /
2;
context.translate(cx, cy);
context.drawImage(
elementWithCanvas.boundTextCanvas,
Expand Down
1 change: 0 additions & 1 deletion packages/excalidraw/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ export type StaticCanvasAppState = Readonly<
selectedElementsAreBeingDragged: AppState["selectedElementsAreBeingDragged"];
gridSize: AppState["gridSize"];
frameRendering: AppState["frameRendering"];
isRotating: AppState["isRotating"];
linkOpacity: AppState["linkOpacity"]; //zsviczian
gridColor: AppState["gridColor"]; //zsviczian
frameColor: AppState["frameColor"]; //zsviczian
Expand Down

0 comments on commit d02b55d

Please sign in to comment.