actionStyles.ts 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import {
  2. isTextElement,
  3. isExcalidrawElement,
  4. redrawTextBoundingBox,
  5. } from "../element";
  6. import { KEYS } from "../keys";
  7. import { register } from "./register";
  8. import { mutateElement, newElementWith } from "../element/mutateElement";
  9. import {
  10. DEFAULT_FONT_SIZE,
  11. DEFAULT_FONT_FAMILY,
  12. DEFAULT_TEXT_ALIGN,
  13. } from "../constants";
  14. // `copiedStyles` is exported only for tests.
  15. export let copiedStyles: string = "{}";
  16. export const actionCopyStyles = register({
  17. name: "copyStyles",
  18. perform: (elements, appState) => {
  19. const element = elements.find((el) => appState.selectedElementIds[el.id]);
  20. if (element) {
  21. copiedStyles = JSON.stringify(element);
  22. }
  23. return {
  24. commitToHistory: false,
  25. };
  26. },
  27. contextItemLabel: "labels.copyStyles",
  28. keyTest: (event) =>
  29. event[KEYS.CTRL_OR_CMD] &&
  30. event.altKey &&
  31. event.keyCode === KEYS.C_KEY_CODE,
  32. contextMenuOrder: 0,
  33. });
  34. export const actionPasteStyles = register({
  35. name: "pasteStyles",
  36. perform: (elements, appState) => {
  37. const pastedElement = JSON.parse(copiedStyles);
  38. if (!isExcalidrawElement(pastedElement)) {
  39. return { elements, commitToHistory: false };
  40. }
  41. return {
  42. elements: elements.map((element) => {
  43. if (appState.selectedElementIds[element.id]) {
  44. const newElement = newElementWith(element, {
  45. backgroundColor: pastedElement?.backgroundColor,
  46. strokeWidth: pastedElement?.strokeWidth,
  47. strokeColor: pastedElement?.strokeColor,
  48. strokeStyle: pastedElement?.strokeStyle,
  49. fillStyle: pastedElement?.fillStyle,
  50. opacity: pastedElement?.opacity,
  51. roughness: pastedElement?.roughness,
  52. });
  53. if (isTextElement(newElement)) {
  54. mutateElement(newElement, {
  55. fontSize: pastedElement?.fontSize || DEFAULT_FONT_SIZE,
  56. fontFamily: pastedElement?.fontFamily || DEFAULT_FONT_FAMILY,
  57. textAlign: pastedElement?.textAlign || DEFAULT_TEXT_ALIGN,
  58. });
  59. redrawTextBoundingBox(newElement);
  60. }
  61. return newElement;
  62. }
  63. return element;
  64. }),
  65. commitToHistory: true,
  66. };
  67. },
  68. contextItemLabel: "labels.pasteStyles",
  69. keyTest: (event) =>
  70. event[KEYS.CTRL_OR_CMD] &&
  71. event.altKey &&
  72. event.keyCode === KEYS.V_KEY_CODE,
  73. contextMenuOrder: 1,
  74. });