Repository: excalidraw/excalidraw
File: packages/element/src/sizeHelpers.ts (TypeScript)

Code before:

import { pointsEqual } from "@excalidraw/math";

import type { AppState, Offsets, Zoom } from "@excalidraw/excalidraw/types";

import { getCommonBounds, getElementBounds } from "./bounds";
import { isFreeDrawElement, isLinearElement } from "./typeChecks";

import type { ElementsMap, ExcalidrawElement } from "./types";

export const INVISIBLY_SMALL_ELEMENT_SIZE = 0.1;

// TODO:  remove invisible elements consistently actions, so that invisible elements are not recorded by the store, exported, broadcasted or persisted
//        - perhaps could be as part of a standalone 'cleanup' action, in addition to 'finalize'
//        - could also be part of `_clearElements`
export const isInvisiblySmallElement = (
  element: ExcalidrawElement,
): boolean => {
  if (isLinearElement(element) || isFreeDrawElement(element)) {
    return (
      element.points.length < 2 ||
      pointsEqual(
        element.points[0],
        element.points[element.points.length - 1],
        INVISIBLY_SMALL_ELEMENT_SIZE,
      )
    );
  }
  return element.width === 0 && element.height === 0;
};

export const isElementInViewport = (
  element: ExcalidrawElement,
  width: number,
  height: number,
  viewTransformations: {
    zoom: Zoom;
    offsetLeft: number;
    offsetTop: number;
    scrollX: number;
    scrollY: number;
  },
  elementsMap: ElementsMap,
) => {
  const [x1, y1, x2, y2] = getElementBounds(element, elementsMap); // scene coordinates
  const topLeftSceneCoords = viewportCoordsToSceneCoords(
    {
      clientX: viewTransformations.offsetLeft,
      clientY: viewTransformations.offsetTop,
    },
    viewTransformations,

Review comment (suggestion):
should apply this only to `points.length === 2` else this prevents making lines & arrows like these: 
![image](https://github.com/user-attachments/assets/448d6706-0617-4d6b-a6e5-5bf4792a8c98)




Code after:

import { pointsEqual } from "@excalidraw/math";

import type { AppState, Offsets, Zoom } from "@excalidraw/excalidraw/types";

import { getCommonBounds, getElementBounds } from "./bounds";
import {
  isArrowElement,
  isFreeDrawElement,
  isLinearElement,
} from "./typeChecks";

import type { ElementsMap, ExcalidrawElement } from "./types";

export const INVISIBLY_SMALL_ELEMENT_SIZE = 0.1;

// TODO:  remove invisible elements consistently actions, so that invisible elements are not recorded by the store, exported, broadcasted or persisted
//        - perhaps could be as part of a standalone 'cleanup' action, in addition to 'finalize'
//        - could also be part of `_clearElements`
export const isInvisiblySmallElement = (
  element: ExcalidrawElement,
): boolean => {
  if (isLinearElement(element) || isFreeDrawElement(element)) {
    return (
      element.points.length < 2 ||
      (element.points.length === 2 &&
        isArrowElement(element) &&
        pointsEqual(
          element.points[0],
          element.points[element.points.length - 1],
          INVISIBLY_SMALL_ELEMENT_SIZE,
        ))
    );
  }

  return element.width === 0 && element.height === 0;
};

export const isElementInViewport = (
  element: ExcalidrawElement,
  width: number,
  height: number,
  viewTransformations: {
    zoom: Zoom;
    offsetLeft: number;
    offsetTop: number;
    scrollX: number;
    scrollY: number;
  },
  elementsMap: ElementsMap,
) => {