mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Add possibility to update text and fontsize
This commit is contained in:
parent
e3eef04e00
commit
91896c3c11
2 changed files with 100 additions and 7 deletions
28
src/components/ElementOption.tsx
Normal file
28
src/components/ElementOption.tsx
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
type PropsElementOption = {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
onChange: Function;
|
||||||
|
};
|
||||||
|
function ElementOption(props: PropsElementOption) {
|
||||||
|
const handleChangeInput = (e: React.FormEvent<HTMLInputElement>) => {
|
||||||
|
props.onChange(e.currentTarget.value);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<label style={{ display: "flex", flexDirection: "row" }}>
|
||||||
|
<span style={{ marginRight: 5, fontSize: 14, minWidth: 40 }}>
|
||||||
|
{props.label}:
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
onChange={handleChangeInput}
|
||||||
|
value={props.value}
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ElementOption;
|
|
@ -1,4 +1,4 @@
|
||||||
import React from "react";
|
import React, { ReactNode } from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import rough from "roughjs/bin/wrappers/rough";
|
import rough from "roughjs/bin/wrappers/rough";
|
||||||
import { RoughCanvas } from "roughjs/bin/canvas";
|
import { RoughCanvas } from "roughjs/bin/canvas";
|
||||||
|
@ -12,6 +12,7 @@ import { roundRect } from "./roundRect";
|
||||||
import EditableText from "./components/EditableText";
|
import EditableText from "./components/EditableText";
|
||||||
|
|
||||||
import "./styles.scss";
|
import "./styles.scss";
|
||||||
|
import ElementOption from "./components/ElementOption";
|
||||||
|
|
||||||
type ExcalidrawElement = ReturnType<typeof newElement>;
|
type ExcalidrawElement = ReturnType<typeof newElement>;
|
||||||
type ExcalidrawTextElement = ExcalidrawElement & {
|
type ExcalidrawTextElement = ExcalidrawElement & {
|
||||||
|
@ -742,12 +743,7 @@ function generateDraw(element: ExcalidrawElement) {
|
||||||
leftY
|
leftY
|
||||||
] = getDiamondPoints(element);
|
] = getDiamondPoints(element);
|
||||||
return generator.polygon(
|
return generator.polygon(
|
||||||
[
|
[[topX, topY], [rightX, rightY], [bottomX, bottomY], [leftX, leftY]],
|
||||||
[topX, topY],
|
|
||||||
[rightX, rightY],
|
|
||||||
[bottomX, bottomY],
|
|
||||||
[leftX, leftY]
|
|
||||||
],
|
|
||||||
{
|
{
|
||||||
stroke: element.strokeColor,
|
stroke: element.strokeColor,
|
||||||
fill: element.backgroundColor,
|
fill: element.backgroundColor,
|
||||||
|
@ -1397,9 +1393,70 @@ class App extends React.Component<{}, AppState> {
|
||||||
this.setState({ currentItemBackgroundColor: color });
|
this.setState({ currentItemBackgroundColor: color });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private updateElement = (element: any, values: any) => {
|
||||||
|
/** Use of Object.assign instead spread because we want to keep ref to element for update is value in initial object */
|
||||||
|
Object.assign(element, values);
|
||||||
|
if (values.text || values.font) {
|
||||||
|
const fontSize = values.font
|
||||||
|
? values.font.split("px")[0]
|
||||||
|
: element.font.split("px")[0];
|
||||||
|
context.font = `${fontSize}px Virgil`;
|
||||||
|
const textMeasure = context.measureText(values.text || element.text);
|
||||||
|
const width = textMeasure.width;
|
||||||
|
const actualBoundingBoxAscent =
|
||||||
|
textMeasure.actualBoundingBoxAscent || fontSize;
|
||||||
|
const actualBoundingBoxDescent =
|
||||||
|
textMeasure.actualBoundingBoxDescent || 0;
|
||||||
|
element.actualBoundingBoxAscent = actualBoundingBoxAscent;
|
||||||
|
const height = actualBoundingBoxAscent + actualBoundingBoxDescent;
|
||||||
|
element.width = width;
|
||||||
|
element.height = height;
|
||||||
|
}
|
||||||
|
this.forceUpdate();
|
||||||
|
};
|
||||||
|
|
||||||
|
private updateFontSizeElement = (element: any, size: string) => {
|
||||||
|
if (size.match(/[^0-9.]/g)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.updateElement(element, { font: `${size}px Virgil` });
|
||||||
|
};
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const canvasWidth = window.innerWidth - CANVAS_WINDOW_OFFSET_LEFT;
|
const canvasWidth = window.innerWidth - CANVAS_WINDOW_OFFSET_LEFT;
|
||||||
const canvasHeight = window.innerHeight - CANVAS_WINDOW_OFFSET_TOP;
|
const canvasHeight = window.innerHeight - CANVAS_WINDOW_OFFSET_TOP;
|
||||||
|
/** elementSelectedOptions is array of option for a selected element, ex in text : Input text, font size ... */
|
||||||
|
const elementSelectedOptions: Array<ReactNode> = [];
|
||||||
|
const selectedElement = elements.find(element => element.isSelected);
|
||||||
|
|
||||||
|
if (selectedElement) {
|
||||||
|
/** If the selected item is a Text so : */
|
||||||
|
if (isTextElement(selectedElement)) {
|
||||||
|
// Text value option
|
||||||
|
elementSelectedOptions.push(
|
||||||
|
<ElementOption
|
||||||
|
key="value"
|
||||||
|
label="Value"
|
||||||
|
value={selectedElement.text}
|
||||||
|
onChange={(text: string) =>
|
||||||
|
this.updateElement(selectedElement, { text })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
// Font size option
|
||||||
|
elementSelectedOptions.push(
|
||||||
|
<ElementOption
|
||||||
|
key="size"
|
||||||
|
label="Size"
|
||||||
|
value={selectedElement.font.split("px")[0]}
|
||||||
|
onChange={(size: string) =>
|
||||||
|
this.updateFontSizeElement(selectedElement, size)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/** TODO: Do some option for other element's type */
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -1469,6 +1526,13 @@ class App extends React.Component<{}, AppState> {
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
{someElementIsSelected() && (
|
{someElementIsSelected() && (
|
||||||
|
<>
|
||||||
|
<h4>Element's options</h4>
|
||||||
|
<div className="panelColumn">
|
||||||
|
{elementSelectedOptions.length > 0
|
||||||
|
? elementSelectedOptions
|
||||||
|
: "No options available"}
|
||||||
|
</div>
|
||||||
<div className="panelColumn">
|
<div className="panelColumn">
|
||||||
<h4>Selection</h4>
|
<h4>Selection</h4>
|
||||||
<div className="buttonList">
|
<div className="buttonList">
|
||||||
|
@ -1617,6 +1681,7 @@ class App extends React.Component<{}, AppState> {
|
||||||
Load file...
|
Load file...
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
</div>
|
</div>
|
||||||
<canvas
|
<canvas
|
||||||
id="canvas"
|
id="canvas"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue