restore.ts 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import { Point } from "roughjs/bin/geometry";
  2. import { ExcalidrawElement } from "../element/types";
  3. import { AppState } from "../types";
  4. import { DataState } from "./types";
  5. import { isInvisiblySmallElement, normalizeDimensions } from "../element";
  6. import nanoid from "nanoid";
  7. import { calculateScrollCenter } from "../scene";
  8. export function restore(
  9. savedElements: readonly ExcalidrawElement[],
  10. savedState: AppState | null,
  11. opts?: { scrollToContent: boolean },
  12. ): DataState {
  13. const elements = savedElements
  14. .filter(el => !isInvisiblySmallElement(el))
  15. .map(element => {
  16. let points: Point[] = [];
  17. if (element.type === "arrow") {
  18. if (Array.isArray(element.points)) {
  19. // if point array is empty, add one point to the arrow
  20. // this is used as fail safe to convert incoming data to a valid
  21. // arrow. In the new arrow, width and height are not being usde
  22. points = element.points.length > 0 ? element.points : [[0, 0]];
  23. } else {
  24. // convert old arrow type to a new one
  25. // old arrow spec used width and height
  26. // to determine the endpoints
  27. points = [
  28. [0, 0],
  29. [element.width, element.height],
  30. ];
  31. }
  32. } else if (element.type === "line") {
  33. // old spec, pre-arrows
  34. // old spec, post-arrows
  35. if (!Array.isArray(element.points) || element.points.length === 0) {
  36. points = [
  37. [0, 0],
  38. [element.width, element.height],
  39. ];
  40. } else {
  41. points = element.points;
  42. }
  43. } else {
  44. normalizeDimensions(element);
  45. }
  46. return {
  47. ...element,
  48. id: element.id || nanoid(),
  49. fillStyle: element.fillStyle || "hachure",
  50. strokeWidth: element.strokeWidth || 1,
  51. roughness: element.roughness || 1,
  52. opacity:
  53. element.opacity === null || element.opacity === undefined
  54. ? 100
  55. : element.opacity,
  56. points,
  57. };
  58. });
  59. if (opts?.scrollToContent && savedState) {
  60. savedState = { ...savedState, ...calculateScrollCenter(elements) };
  61. }
  62. return {
  63. elements: elements,
  64. appState: savedState,
  65. };
  66. }