mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Refactor ExcalidrawElement (#874)
* Get rid of isSelected, canvas, canvasZoom, canvasOffsetX and canvasOffsetY on ExcalidrawElement. * Fix most unit tests. Fix cmd a. Fix alt drag * Focus on paste * shift select should include previously selected items * Fix last test * Move this.shape out of ExcalidrawElement and into a WeakMap
This commit is contained in:
parent
8ecb4201db
commit
ccbbdb75a6
39 changed files with 416 additions and 306 deletions
|
@ -14,10 +14,11 @@ import { register } from "./register";
|
|||
|
||||
const changeProperty = (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
callback: (element: ExcalidrawElement) => ExcalidrawElement,
|
||||
) => {
|
||||
return elements.map(element => {
|
||||
if (element.isSelected) {
|
||||
if (appState.selectedElementIds[element.id]) {
|
||||
return callback(element);
|
||||
}
|
||||
return element;
|
||||
|
@ -25,15 +26,16 @@ const changeProperty = (
|
|||
};
|
||||
|
||||
const getFormValue = function<T>(
|
||||
editingElement: AppState["editingElement"],
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
getAttribute: (element: ExcalidrawElement) => T,
|
||||
defaultValue?: T,
|
||||
): T | null {
|
||||
const editingElement = appState.editingElement;
|
||||
return (
|
||||
(editingElement && getAttribute(editingElement)) ??
|
||||
(isSomeElementSelected(elements)
|
||||
? getCommonAttributeOfSelectedElements(elements, getAttribute)
|
||||
(isSomeElementSelected(elements, appState)
|
||||
? getCommonAttributeOfSelectedElements(elements, appState, getAttribute)
|
||||
: defaultValue) ??
|
||||
null
|
||||
);
|
||||
|
@ -43,9 +45,8 @@ export const actionChangeStrokeColor = register({
|
|||
name: "changeStrokeColor",
|
||||
perform: (elements, appState, value) => {
|
||||
return {
|
||||
elements: changeProperty(elements, el => ({
|
||||
elements: changeProperty(elements, appState, el => ({
|
||||
...el,
|
||||
shape: null,
|
||||
strokeColor: value,
|
||||
})),
|
||||
appState: { ...appState, currentItemStrokeColor: value },
|
||||
|
@ -59,8 +60,8 @@ export const actionChangeStrokeColor = register({
|
|||
type="elementStroke"
|
||||
label={t("labels.stroke")}
|
||||
color={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
appState,
|
||||
element => element.strokeColor,
|
||||
appState.currentItemStrokeColor,
|
||||
)}
|
||||
|
@ -74,9 +75,8 @@ export const actionChangeBackgroundColor = register({
|
|||
name: "changeBackgroundColor",
|
||||
perform: (elements, appState, value) => {
|
||||
return {
|
||||
elements: changeProperty(elements, el => ({
|
||||
elements: changeProperty(elements, appState, el => ({
|
||||
...el,
|
||||
shape: null,
|
||||
backgroundColor: value,
|
||||
})),
|
||||
appState: { ...appState, currentItemBackgroundColor: value },
|
||||
|
@ -90,8 +90,8 @@ export const actionChangeBackgroundColor = register({
|
|||
type="elementBackground"
|
||||
label={t("labels.background")}
|
||||
color={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
appState,
|
||||
element => element.backgroundColor,
|
||||
appState.currentItemBackgroundColor,
|
||||
)}
|
||||
|
@ -105,9 +105,8 @@ export const actionChangeFillStyle = register({
|
|||
name: "changeFillStyle",
|
||||
perform: (elements, appState, value) => {
|
||||
return {
|
||||
elements: changeProperty(elements, el => ({
|
||||
elements: changeProperty(elements, appState, el => ({
|
||||
...el,
|
||||
shape: null,
|
||||
fillStyle: value,
|
||||
})),
|
||||
appState: { ...appState, currentItemFillStyle: value },
|
||||
|
@ -125,8 +124,8 @@ export const actionChangeFillStyle = register({
|
|||
]}
|
||||
group="fill"
|
||||
value={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
appState,
|
||||
element => element.fillStyle,
|
||||
appState.currentItemFillStyle,
|
||||
)}
|
||||
|
@ -142,9 +141,8 @@ export const actionChangeStrokeWidth = register({
|
|||
name: "changeStrokeWidth",
|
||||
perform: (elements, appState, value) => {
|
||||
return {
|
||||
elements: changeProperty(elements, el => ({
|
||||
elements: changeProperty(elements, appState, el => ({
|
||||
...el,
|
||||
shape: null,
|
||||
strokeWidth: value,
|
||||
})),
|
||||
appState: { ...appState, currentItemStrokeWidth: value },
|
||||
|
@ -162,8 +160,8 @@ export const actionChangeStrokeWidth = register({
|
|||
{ value: 4, text: t("labels.extraBold") },
|
||||
]}
|
||||
value={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
appState,
|
||||
element => element.strokeWidth,
|
||||
appState.currentItemStrokeWidth,
|
||||
)}
|
||||
|
@ -177,9 +175,8 @@ export const actionChangeSloppiness = register({
|
|||
name: "changeSloppiness",
|
||||
perform: (elements, appState, value) => {
|
||||
return {
|
||||
elements: changeProperty(elements, el => ({
|
||||
elements: changeProperty(elements, appState, el => ({
|
||||
...el,
|
||||
shape: null,
|
||||
roughness: value,
|
||||
})),
|
||||
appState: { ...appState, currentItemRoughness: value },
|
||||
|
@ -197,8 +194,8 @@ export const actionChangeSloppiness = register({
|
|||
{ value: 2, text: t("labels.cartoonist") },
|
||||
]}
|
||||
value={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
appState,
|
||||
element => element.roughness,
|
||||
appState.currentItemRoughness,
|
||||
)}
|
||||
|
@ -212,9 +209,8 @@ export const actionChangeOpacity = register({
|
|||
name: "changeOpacity",
|
||||
perform: (elements, appState, value) => {
|
||||
return {
|
||||
elements: changeProperty(elements, el => ({
|
||||
elements: changeProperty(elements, appState, el => ({
|
||||
...el,
|
||||
shape: null,
|
||||
opacity: value,
|
||||
})),
|
||||
appState: { ...appState, currentItemOpacity: value },
|
||||
|
@ -246,8 +242,8 @@ export const actionChangeOpacity = register({
|
|||
}}
|
||||
value={
|
||||
getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
appState,
|
||||
element => element.opacity,
|
||||
appState.currentItemOpacity,
|
||||
) ?? undefined
|
||||
|
@ -261,11 +257,10 @@ export const actionChangeFontSize = register({
|
|||
name: "changeFontSize",
|
||||
perform: (elements, appState, value) => {
|
||||
return {
|
||||
elements: changeProperty(elements, el => {
|
||||
elements: changeProperty(elements, appState, el => {
|
||||
if (isTextElement(el)) {
|
||||
const element: ExcalidrawTextElement = {
|
||||
...el,
|
||||
shape: null,
|
||||
font: `${value}px ${el.font.split("px ")[1]}`,
|
||||
};
|
||||
redrawTextBoundingBox(element);
|
||||
|
@ -295,8 +290,8 @@ export const actionChangeFontSize = register({
|
|||
{ value: 36, text: t("labels.veryLarge") },
|
||||
]}
|
||||
value={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
appState,
|
||||
element => isTextElement(element) && +element.font.split("px ")[0],
|
||||
+(appState.currentItemFont || DEFAULT_FONT).split("px ")[0],
|
||||
)}
|
||||
|
@ -310,11 +305,10 @@ export const actionChangeFontFamily = register({
|
|||
name: "changeFontFamily",
|
||||
perform: (elements, appState, value) => {
|
||||
return {
|
||||
elements: changeProperty(elements, el => {
|
||||
elements: changeProperty(elements, appState, el => {
|
||||
if (isTextElement(el)) {
|
||||
const element: ExcalidrawTextElement = {
|
||||
...el,
|
||||
shape: null,
|
||||
font: `${el.font.split("px ")[0]}px ${value}`,
|
||||
};
|
||||
redrawTextBoundingBox(element);
|
||||
|
@ -343,8 +337,8 @@ export const actionChangeFontFamily = register({
|
|||
{ value: "Cascadia", text: t("labels.code") },
|
||||
]}
|
||||
value={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
appState,
|
||||
element => isTextElement(element) && element.font.split("px ")[1],
|
||||
(appState.currentItemFont || DEFAULT_FONT).split("px ")[1],
|
||||
)}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue