|
@@ -2,6 +2,7 @@ import React from "react";
|
2
|
2
|
import ReactDOM from "react-dom";
|
3
|
3
|
import rough from "roughjs/bin/wrappers/rough";
|
4
|
4
|
import { RoughCanvas } from "roughjs/bin/canvas";
|
|
5
|
+import { SketchPicker } from "react-color";
|
5
|
6
|
|
6
|
7
|
import { moveOneLeft, moveAllLeft, moveOneRight, moveAllRight } from "./zindex";
|
7
|
8
|
|
|
@@ -816,9 +817,16 @@ function restore(
|
816
|
817
|
}
|
817
|
818
|
}
|
818
|
819
|
|
|
820
|
+enum ColorPicker {
|
|
821
|
+ CANVAS_BACKGROUND,
|
|
822
|
+ SHAPE_STROKE,
|
|
823
|
+ SHAPE_BACKGROUND
|
|
824
|
+}
|
|
825
|
+
|
819
|
826
|
type AppState = {
|
820
|
827
|
draggingElement: ExcalidrawElement | null;
|
821
|
828
|
resizingElement: ExcalidrawElement | null;
|
|
829
|
+ currentColorPicker: ColorPicker | null;
|
822
|
830
|
elementType: string;
|
823
|
831
|
exportBackground: boolean;
|
824
|
832
|
currentItemStrokeColor: string;
|
|
@@ -889,7 +897,6 @@ const SHAPES = [
|
889
|
897
|
|
890
|
898
|
const shapesShortcutKeys = SHAPES.map(shape => shape.value[0]);
|
891
|
899
|
|
892
|
|
-
|
893
|
900
|
function capitalize(str: string) {
|
894
|
901
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
895
|
902
|
}
|
|
@@ -953,6 +960,7 @@ class App extends React.Component<{}, AppState> {
|
953
|
960
|
draggingElement: null,
|
954
|
961
|
resizingElement: null,
|
955
|
962
|
elementType: "selection",
|
|
963
|
+ currentColorPicker: null,
|
956
|
964
|
exportBackground: true,
|
957
|
965
|
currentItemStrokeColor: "#000000",
|
958
|
966
|
currentItemBackgroundColor: "#ffffff",
|
|
@@ -1134,7 +1142,11 @@ class App extends React.Component<{}, AppState> {
|
1134
|
1142
|
<h4>Shapes</h4>
|
1135
|
1143
|
<div className="panelTools">
|
1136
|
1144
|
{SHAPES.map(({ value, icon }) => (
|
1137
|
|
- <label key={value} className="tool" title={`${capitalize(value)} - ${capitalize(value)[0]}`}>
|
|
1145
|
+ <label
|
|
1146
|
+ key={value}
|
|
1147
|
+ className="tool"
|
|
1148
|
+ title={`${capitalize(value)} - ${capitalize(value)[0]}`}
|
|
1149
|
+ >
|
1138
|
1150
|
<input
|
1139
|
1151
|
type="radio"
|
1140
|
1152
|
checked={this.state.elementType === value}
|
|
@@ -1152,36 +1164,123 @@ class App extends React.Component<{}, AppState> {
|
1152
|
1164
|
</div>
|
1153
|
1165
|
<h4>Colors</h4>
|
1154
|
1166
|
<div className="panelColumn">
|
1155
|
|
- <label>
|
|
1167
|
+ <h5>Canvas Background</h5>
|
|
1168
|
+ <div>
|
|
1169
|
+ <button
|
|
1170
|
+ className="swatch"
|
|
1171
|
+ style={{
|
|
1172
|
+ backgroundColor: this.state.viewBackgroundColor
|
|
1173
|
+ }}
|
|
1174
|
+ onClick={() =>
|
|
1175
|
+ this.setState(s => ({
|
|
1176
|
+ currentColorPicker:
|
|
1177
|
+ s.currentColorPicker === ColorPicker.CANVAS_BACKGROUND
|
|
1178
|
+ ? null
|
|
1179
|
+ : ColorPicker.CANVAS_BACKGROUND
|
|
1180
|
+ }))
|
|
1181
|
+ }
|
|
1182
|
+ ></button>
|
|
1183
|
+ {this.state.currentColorPicker === ColorPicker.CANVAS_BACKGROUND ? (
|
|
1184
|
+ <div className="popover">
|
|
1185
|
+ <div
|
|
1186
|
+ className="cover"
|
|
1187
|
+ onClick={() => this.setState({ currentColorPicker: null })}
|
|
1188
|
+ ></div>
|
|
1189
|
+ <SketchPicker
|
|
1190
|
+ color={this.state.viewBackgroundColor}
|
|
1191
|
+ onChange={color => {
|
|
1192
|
+ this.setState({ viewBackgroundColor: color.hex });
|
|
1193
|
+ }}
|
|
1194
|
+ />
|
|
1195
|
+ </div>
|
|
1196
|
+ ) : null}
|
1156
|
1197
|
<input
|
1157
|
|
- type="color"
|
|
1198
|
+ type="text"
|
|
1199
|
+ className="swatch-input"
|
1158
|
1200
|
value={this.state.viewBackgroundColor}
|
1159
|
|
- onChange={e => {
|
1160
|
|
- this.setState({ viewBackgroundColor: e.target.value });
|
1161
|
|
- }}
|
|
1201
|
+ onChange={e =>
|
|
1202
|
+ this.setState({ viewBackgroundColor: e.target.value })
|
|
1203
|
+ }
|
1162
|
1204
|
/>
|
1163
|
|
- Background
|
1164
|
|
- </label>
|
1165
|
|
- <label>
|
|
1205
|
+ </div>
|
|
1206
|
+ <h5>Shape Stroke</h5>
|
|
1207
|
+ <div>
|
|
1208
|
+ <button
|
|
1209
|
+ className="swatch"
|
|
1210
|
+ style={{
|
|
1211
|
+ backgroundColor: this.state.currentItemStrokeColor
|
|
1212
|
+ }}
|
|
1213
|
+ onClick={() =>
|
|
1214
|
+ this.setState(s => ({
|
|
1215
|
+ currentColorPicker:
|
|
1216
|
+ s.currentColorPicker === ColorPicker.SHAPE_STROKE
|
|
1217
|
+ ? null
|
|
1218
|
+ : ColorPicker.SHAPE_STROKE
|
|
1219
|
+ }))
|
|
1220
|
+ }
|
|
1221
|
+ ></button>
|
|
1222
|
+ {this.state.currentColorPicker === ColorPicker.SHAPE_STROKE ? (
|
|
1223
|
+ <div className="popover">
|
|
1224
|
+ <div
|
|
1225
|
+ className="cover"
|
|
1226
|
+ onClick={() => this.setState({ currentColorPicker: null })}
|
|
1227
|
+ ></div>
|
|
1228
|
+ <SketchPicker
|
|
1229
|
+ color={this.state.currentItemStrokeColor}
|
|
1230
|
+ onChange={color => {
|
|
1231
|
+ this.setState({ currentItemStrokeColor: color.hex });
|
|
1232
|
+ }}
|
|
1233
|
+ />
|
|
1234
|
+ </div>
|
|
1235
|
+ ) : null}
|
1166
|
1236
|
<input
|
1167
|
|
- type="color"
|
|
1237
|
+ type="text"
|
|
1238
|
+ className="swatch-input"
|
1168
|
1239
|
value={this.state.currentItemStrokeColor}
|
1169
|
1240
|
onChange={e => {
|
1170
|
1241
|
this.setState({ currentItemStrokeColor: e.target.value });
|
1171
|
1242
|
}}
|
1172
|
1243
|
/>
|
1173
|
|
- Shape Stroke
|
1174
|
|
- </label>
|
1175
|
|
- <label>
|
|
1244
|
+ </div>
|
|
1245
|
+ <h5>Shape Background</h5>
|
|
1246
|
+ <div>
|
|
1247
|
+ <button
|
|
1248
|
+ className="swatch"
|
|
1249
|
+ style={{
|
|
1250
|
+ backgroundColor: this.state.currentItemBackgroundColor
|
|
1251
|
+ }}
|
|
1252
|
+ onClick={() =>
|
|
1253
|
+ this.setState(s => ({
|
|
1254
|
+ currentColorPicker:
|
|
1255
|
+ s.currentColorPicker === ColorPicker.SHAPE_BACKGROUND
|
|
1256
|
+ ? null
|
|
1257
|
+ : ColorPicker.SHAPE_BACKGROUND
|
|
1258
|
+ }))
|
|
1259
|
+ }
|
|
1260
|
+ ></button>
|
|
1261
|
+ {this.state.currentColorPicker === ColorPicker.SHAPE_BACKGROUND ? (
|
|
1262
|
+ <div className="popover">
|
|
1263
|
+ <div
|
|
1264
|
+ className="cover"
|
|
1265
|
+ onClick={() => this.setState({ currentColorPicker: null })}
|
|
1266
|
+ ></div>
|
|
1267
|
+ <SketchPicker
|
|
1268
|
+ color={this.state.currentItemBackgroundColor}
|
|
1269
|
+ onChange={color => {
|
|
1270
|
+ this.setState({ currentItemBackgroundColor: color.hex });
|
|
1271
|
+ }}
|
|
1272
|
+ />
|
|
1273
|
+ </div>
|
|
1274
|
+ ) : null}
|
1176
|
1275
|
<input
|
1177
|
|
- type="color"
|
1178
|
|
- value={this.state.currentItemBackgroundColor}
|
|
1276
|
+ type="text"
|
|
1277
|
+ className="swatch-input"
|
|
1278
|
+ value={this.state.currentItemStrokeColor}
|
1179
|
1279
|
onChange={e => {
|
1180
|
|
- this.setState({ currentItemBackgroundColor: e.target.value });
|
|
1280
|
+ this.setState({ currentItemStrokeColor: e.target.value });
|
1181
|
1281
|
}}
|
1182
|
1282
|
/>
|
1183
|
|
- Shape Background
|
1184
|
|
- </label>
|
|
1283
|
+ </div>
|
1185
|
1284
|
</div>
|
1186
|
1285
|
<h4>Canvas</h4>
|
1187
|
1286
|
<div className="panelColumn">
|