|
|
@ -2,6 +2,7 @@ import React 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";
|
|
|
|
|
|
|
|
import { SketchPicker } from "react-color";
|
|
|
|
|
|
|
|
|
|
|
|
import { moveOneLeft, moveAllLeft, moveOneRight, moveAllRight } from "./zindex";
|
|
|
|
import { moveOneLeft, moveAllLeft, moveOneRight, moveAllRight } from "./zindex";
|
|
|
|
|
|
|
|
|
|
|
@ -816,9 +817,16 @@ function restore(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
enum ColorPicker {
|
|
|
|
|
|
|
|
CANVAS_BACKGROUND,
|
|
|
|
|
|
|
|
SHAPE_STROKE,
|
|
|
|
|
|
|
|
SHAPE_BACKGROUND
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type AppState = {
|
|
|
|
type AppState = {
|
|
|
|
draggingElement: ExcalidrawElement | null;
|
|
|
|
draggingElement: ExcalidrawElement | null;
|
|
|
|
resizingElement: ExcalidrawElement | null;
|
|
|
|
resizingElement: ExcalidrawElement | null;
|
|
|
|
|
|
|
|
currentColorPicker: ColorPicker | null;
|
|
|
|
elementType: string;
|
|
|
|
elementType: string;
|
|
|
|
exportBackground: boolean;
|
|
|
|
exportBackground: boolean;
|
|
|
|
currentItemStrokeColor: string;
|
|
|
|
currentItemStrokeColor: string;
|
|
|
@ -889,7 +897,6 @@ const SHAPES = [
|
|
|
|
|
|
|
|
|
|
|
|
const shapesShortcutKeys = SHAPES.map(shape => shape.value[0]);
|
|
|
|
const shapesShortcutKeys = SHAPES.map(shape => shape.value[0]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function capitalize(str: string) {
|
|
|
|
function capitalize(str: string) {
|
|
|
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
|
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -953,6 +960,7 @@ class App extends React.Component<{}, AppState> {
|
|
|
|
draggingElement: null,
|
|
|
|
draggingElement: null,
|
|
|
|
resizingElement: null,
|
|
|
|
resizingElement: null,
|
|
|
|
elementType: "selection",
|
|
|
|
elementType: "selection",
|
|
|
|
|
|
|
|
currentColorPicker: null,
|
|
|
|
exportBackground: true,
|
|
|
|
exportBackground: true,
|
|
|
|
currentItemStrokeColor: "#000000",
|
|
|
|
currentItemStrokeColor: "#000000",
|
|
|
|
currentItemBackgroundColor: "#ffffff",
|
|
|
|
currentItemBackgroundColor: "#ffffff",
|
|
|
@ -1134,7 +1142,11 @@ class App extends React.Component<{}, AppState> {
|
|
|
|
<h4>Shapes</h4>
|
|
|
|
<h4>Shapes</h4>
|
|
|
|
<div className="panelTools">
|
|
|
|
<div className="panelTools">
|
|
|
|
{SHAPES.map(({ value, icon }) => (
|
|
|
|
{SHAPES.map(({ value, icon }) => (
|
|
|
|
<label key={value} className="tool" title={`${capitalize(value)} - ${capitalize(value)[0]}`}>
|
|
|
|
<label
|
|
|
|
|
|
|
|
key={value}
|
|
|
|
|
|
|
|
className="tool"
|
|
|
|
|
|
|
|
title={`${capitalize(value)} - ${capitalize(value)[0]}`}
|
|
|
|
|
|
|
|
>
|
|
|
|
<input
|
|
|
|
<input
|
|
|
|
type="radio"
|
|
|
|
type="radio"
|
|
|
|
checked={this.state.elementType === value}
|
|
|
|
checked={this.state.elementType === value}
|
|
|
@ -1152,36 +1164,123 @@ class App extends React.Component<{}, AppState> {
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<h4>Colors</h4>
|
|
|
|
<h4>Colors</h4>
|
|
|
|
<div className="panelColumn">
|
|
|
|
<div className="panelColumn">
|
|
|
|
<label>
|
|
|
|
<h5>Canvas Background</h5>
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
|
|
|
className="swatch"
|
|
|
|
|
|
|
|
style={{
|
|
|
|
|
|
|
|
backgroundColor: this.state.viewBackgroundColor
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
onClick={() =>
|
|
|
|
|
|
|
|
this.setState(s => ({
|
|
|
|
|
|
|
|
currentColorPicker:
|
|
|
|
|
|
|
|
s.currentColorPicker === ColorPicker.CANVAS_BACKGROUND
|
|
|
|
|
|
|
|
? null
|
|
|
|
|
|
|
|
: ColorPicker.CANVAS_BACKGROUND
|
|
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
></button>
|
|
|
|
|
|
|
|
{this.state.currentColorPicker === ColorPicker.CANVAS_BACKGROUND ? (
|
|
|
|
|
|
|
|
<div className="popover">
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
|
|
|
className="cover"
|
|
|
|
|
|
|
|
onClick={() => this.setState({ currentColorPicker: null })}
|
|
|
|
|
|
|
|
></div>
|
|
|
|
|
|
|
|
<SketchPicker
|
|
|
|
|
|
|
|
color={this.state.viewBackgroundColor}
|
|
|
|
|
|
|
|
onChange={color => {
|
|
|
|
|
|
|
|
this.setState({ viewBackgroundColor: color.hex });
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
) : null}
|
|
|
|
<input
|
|
|
|
<input
|
|
|
|
type="color"
|
|
|
|
type="text"
|
|
|
|
|
|
|
|
className="swatch-input"
|
|
|
|
value={this.state.viewBackgroundColor}
|
|
|
|
value={this.state.viewBackgroundColor}
|
|
|
|
onChange={e => {
|
|
|
|
onChange={e =>
|
|
|
|
this.setState({ viewBackgroundColor: e.target.value });
|
|
|
|
this.setState({ viewBackgroundColor: e.target.value })
|
|
|
|
}}
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
Background
|
|
|
|
</div>
|
|
|
|
</label>
|
|
|
|
<h5>Shape Stroke</h5>
|
|
|
|
<label>
|
|
|
|
<div>
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
|
|
|
className="swatch"
|
|
|
|
|
|
|
|
style={{
|
|
|
|
|
|
|
|
backgroundColor: this.state.currentItemStrokeColor
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
onClick={() =>
|
|
|
|
|
|
|
|
this.setState(s => ({
|
|
|
|
|
|
|
|
currentColorPicker:
|
|
|
|
|
|
|
|
s.currentColorPicker === ColorPicker.SHAPE_STROKE
|
|
|
|
|
|
|
|
? null
|
|
|
|
|
|
|
|
: ColorPicker.SHAPE_STROKE
|
|
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
></button>
|
|
|
|
|
|
|
|
{this.state.currentColorPicker === ColorPicker.SHAPE_STROKE ? (
|
|
|
|
|
|
|
|
<div className="popover">
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
|
|
|
className="cover"
|
|
|
|
|
|
|
|
onClick={() => this.setState({ currentColorPicker: null })}
|
|
|
|
|
|
|
|
></div>
|
|
|
|
|
|
|
|
<SketchPicker
|
|
|
|
|
|
|
|
color={this.state.currentItemStrokeColor}
|
|
|
|
|
|
|
|
onChange={color => {
|
|
|
|
|
|
|
|
this.setState({ currentItemStrokeColor: color.hex });
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
) : null}
|
|
|
|
<input
|
|
|
|
<input
|
|
|
|
type="color"
|
|
|
|
type="text"
|
|
|
|
|
|
|
|
className="swatch-input"
|
|
|
|
value={this.state.currentItemStrokeColor}
|
|
|
|
value={this.state.currentItemStrokeColor}
|
|
|
|
onChange={e => {
|
|
|
|
onChange={e => {
|
|
|
|
this.setState({ currentItemStrokeColor: e.target.value });
|
|
|
|
this.setState({ currentItemStrokeColor: e.target.value });
|
|
|
|
}}
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
Shape Stroke
|
|
|
|
</div>
|
|
|
|
</label>
|
|
|
|
<h5>Shape Background</h5>
|
|
|
|
<label>
|
|
|
|
<div>
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
|
|
|
className="swatch"
|
|
|
|
|
|
|
|
style={{
|
|
|
|
|
|
|
|
backgroundColor: this.state.currentItemBackgroundColor
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
onClick={() =>
|
|
|
|
|
|
|
|
this.setState(s => ({
|
|
|
|
|
|
|
|
currentColorPicker:
|
|
|
|
|
|
|
|
s.currentColorPicker === ColorPicker.SHAPE_BACKGROUND
|
|
|
|
|
|
|
|
? null
|
|
|
|
|
|
|
|
: ColorPicker.SHAPE_BACKGROUND
|
|
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
></button>
|
|
|
|
|
|
|
|
{this.state.currentColorPicker === ColorPicker.SHAPE_BACKGROUND ? (
|
|
|
|
|
|
|
|
<div className="popover">
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
|
|
|
className="cover"
|
|
|
|
|
|
|
|
onClick={() => this.setState({ currentColorPicker: null })}
|
|
|
|
|
|
|
|
></div>
|
|
|
|
|
|
|
|
<SketchPicker
|
|
|
|
|
|
|
|
color={this.state.currentItemBackgroundColor}
|
|
|
|
|
|
|
|
onChange={color => {
|
|
|
|
|
|
|
|
this.setState({ currentItemBackgroundColor: color.hex });
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
) : null}
|
|
|
|
<input
|
|
|
|
<input
|
|
|
|
type="color"
|
|
|
|
type="text"
|
|
|
|
value={this.state.currentItemBackgroundColor}
|
|
|
|
className="swatch-input"
|
|
|
|
|
|
|
|
value={this.state.currentItemStrokeColor}
|
|
|
|
onChange={e => {
|
|
|
|
onChange={e => {
|
|
|
|
this.setState({ currentItemBackgroundColor: e.target.value });
|
|
|
|
this.setState({ currentItemStrokeColor: e.target.value });
|
|
|
|
}}
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
Shape Background
|
|
|
|
</div>
|
|
|
|
</label>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<h4>Canvas</h4>
|
|
|
|
<h4>Canvas</h4>
|
|
|
|
<div className="panelColumn">
|
|
|
|
<div className="panelColumn">
|
|
|
|