pcm-shared-components 0.0.45 → 0.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/dist/components/Buttons/CanvasPaint/index.js +207 -0
- package/dist/components/Buttons/CustomFab/CustomFab.js +9 -5
- package/dist/components/Buttons/HelpButton/HelpButton.js +16 -5
- package/dist/components/Buttons/ImageCanvasDraw/components/Controls.js +191 -0
- package/dist/components/Buttons/ImageCanvasDraw/constants/index.js +1 -0
- package/dist/components/Buttons/ImageCanvasDraw/constants/types.js +4 -0
- package/dist/components/Buttons/ImageCanvasDraw/index.js +183 -0
- package/dist/components/Buttons/ImageCanvasDraw/service/image_tools.js +37 -0
- package/dist/components/Buttons/ImageCanvasDraw/service/local_storage.js +20 -0
- package/dist/components/Buttons/ImageCanvasDraw/testMap.test.js +1 -0
- package/dist/styles/tailwind.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
1
|
# Shared Components between client and admin portal
|
|
2
2
|
|
|
3
3
|
The Library is published to NPM on the github build.
|
|
4
|
+
|
|
5
|
+
# Deploying
|
|
6
|
+
|
|
7
|
+
- When the code is checked into Github it will publish it automatically if the package.json version is bumped.
|
|
8
|
+
|
|
9
|
+
# Manual Deploy
|
|
10
|
+
|
|
11
|
+
Manually deploying is faster then committing the code as it doesn't need to create a ful build.
|
|
12
|
+
|
|
13
|
+
```shell
|
|
14
|
+
# Must build the Storybook dist folder before manually publishing
|
|
15
|
+
> npm run build
|
|
16
|
+
|
|
17
|
+
# Edit the package.json file and up he version.
|
|
18
|
+
> npm version patch --force
|
|
19
|
+
|
|
20
|
+
# Login if not already logged in
|
|
21
|
+
> npm login
|
|
22
|
+
|
|
23
|
+
# Publish your new library
|
|
24
|
+
> npm publish
|
|
25
|
+
|
|
26
|
+
```
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import tinycolor from "tinycolor2"; // Brush colour and size
|
|
3
|
+
// // Geometry
|
|
4
|
+
// // Drawing functions
|
|
5
|
+
// // Event helpers
|
|
6
|
+
// // Event handlers
|
|
7
|
+
|
|
8
|
+
export const CanvasPain = () => {
|
|
9
|
+
const canvas = useRef();
|
|
10
|
+
let context; // // Set up our drawing context
|
|
11
|
+
// // const canvas = document.getElementById("canvas");
|
|
12
|
+
// canvas.current.width = window.innerWidth;
|
|
13
|
+
// canvas.current.height = window.innerHeight - 10;
|
|
14
|
+
|
|
15
|
+
let colour;
|
|
16
|
+
const strokeWidth = 40;
|
|
17
|
+
const varyBrightness = 5; // Drawing state
|
|
18
|
+
|
|
19
|
+
let latestPoint;
|
|
20
|
+
let drawing = false;
|
|
21
|
+
let currentAngle;
|
|
22
|
+
|
|
23
|
+
const mouseDown = evt => {
|
|
24
|
+
if (drawing) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
evt.preventDefault();
|
|
29
|
+
canvas.current.addEventListener("mousemove", mouseMove, false);
|
|
30
|
+
startStroke([evt.offsetX, evt.offsetY]);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const mouseEnter = evt => {
|
|
34
|
+
if (!mouseButtonIsDown(evt.buttons) || drawing) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
mouseDown(evt);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const endStroke = evt => {
|
|
42
|
+
if (!drawing) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
drawing = false;
|
|
47
|
+
evt.currentTarget.removeEventListener("mousemove", mouseMove, false);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const continueStroke = newPoint => {
|
|
51
|
+
const newAngle = getNewAngle(latestPoint, newPoint, currentAngle);
|
|
52
|
+
drawStroke(currentBrush, latestPoint, newPoint, currentAngle, newAngle);
|
|
53
|
+
currentAngle = newAngle % (Math.PI * 2);
|
|
54
|
+
latestPoint = newPoint;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const startStroke = point => {
|
|
58
|
+
colour = document.getElementById("colourInput").value;
|
|
59
|
+
currentAngle = undefined;
|
|
60
|
+
currentBrush = makeBrush(strokeWidth);
|
|
61
|
+
drawing = true;
|
|
62
|
+
latestPoint = point;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const touchStart = evt => {
|
|
66
|
+
if (drawing) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
evt.preventDefault();
|
|
71
|
+
startStroke(getTouchPoint(evt));
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const mouseMove = evt => {
|
|
75
|
+
if (!drawing) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
continueStroke([evt.offsetX, evt.offsetY]);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const touchMove = evt => {
|
|
83
|
+
if (!drawing) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
continueStroke(getTouchPoint(evt));
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const touchEnd = evt => {
|
|
91
|
+
drawing = false;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const varyColour = sourceColour => {
|
|
95
|
+
const amount = Math.round(Math.random() * 2 * varyBrightness);
|
|
96
|
+
const c = tinycolor(sourceColour);
|
|
97
|
+
const varied = amount > varyBrightness ? c.brighten(amount - varyBrightness) : c.darken(amount);
|
|
98
|
+
return varied.toHexString();
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const makeBrush = size => {
|
|
102
|
+
const brush = [];
|
|
103
|
+
let bristleCount = Math.round(size / 3);
|
|
104
|
+
const gap = strokeWidth / bristleCount;
|
|
105
|
+
|
|
106
|
+
for (let i = 0; i < bristleCount; i++) {
|
|
107
|
+
const distance = i === 0 ? 0 : gap * i + Math.random() * gap / 2 - gap / 2;
|
|
108
|
+
brush.push({
|
|
109
|
+
distance,
|
|
110
|
+
thickness: Math.random() * 2 + 2,
|
|
111
|
+
colour: varyColour(colour)
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return brush;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
let currentBrush = makeBrush(strokeWidth);
|
|
119
|
+
|
|
120
|
+
const getNewAngle = (origin, destination, oldAngle) => {
|
|
121
|
+
const bearing = getBearing(origin, destination);
|
|
122
|
+
|
|
123
|
+
if (typeof oldAngle === "undefined") {
|
|
124
|
+
console.log(bearing);
|
|
125
|
+
return bearing;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return oldAngle - angleDiff(oldAngle, bearing);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const rotatePoint = (distance, angle, origin) => [origin[0] + distance * Math.cos(angle), origin[1] + distance * Math.sin(angle)];
|
|
132
|
+
|
|
133
|
+
const getBearing = (origin, destination) => (Math.atan2(destination[1] - origin[1], destination[0] - origin[0]) - Math.PI / 2) % (Math.PI * 2);
|
|
134
|
+
|
|
135
|
+
const angleDiff = (angleA, angleB) => {
|
|
136
|
+
const twoPi = Math.PI * 2;
|
|
137
|
+
const diff = (angleA - (angleB > 0 ? angleB : angleB + twoPi) + Math.PI) % twoPi - Math.PI;
|
|
138
|
+
return diff < -Math.PI ? diff + twoPi : diff;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const drawStroke = (bristles, origin, destination, oldAngle, newAngle) => {
|
|
142
|
+
bristles.forEach(bristle => {
|
|
143
|
+
context.beginPath();
|
|
144
|
+
let bristleOrigin = rotatePoint(bristle.distance - strokeWidth / 2, oldAngle, origin);
|
|
145
|
+
let bristleDestination = rotatePoint(bristle.distance - strokeWidth / 2, newAngle, destination);
|
|
146
|
+
const controlPoint = rotatePoint(bristle.distance - strokeWidth / 2, newAngle, origin);
|
|
147
|
+
bristleDestination = rotatePoint(bristle.distance - strokeWidth / 2, newAngle, destination);
|
|
148
|
+
strokeBristle(bristleOrigin, bristleDestination, bristle, controlPoint);
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const strokeBristle = (origin, destination, bristle, controlPoint) => {
|
|
153
|
+
context.beginPath();
|
|
154
|
+
context.moveTo(origin[0], origin[1]);
|
|
155
|
+
context.strokeStyle = bristle.colour;
|
|
156
|
+
context.lineWidth = bristle.thickness;
|
|
157
|
+
context.lineCap = "round";
|
|
158
|
+
context.lineJoin = "round";
|
|
159
|
+
context.shadowColor = bristle.colour;
|
|
160
|
+
context.shadowBlur = bristle.thickness / 2;
|
|
161
|
+
context.quadraticCurveTo(controlPoint[0], controlPoint[1], destination[0], destination[1]);
|
|
162
|
+
context.lineTo(destination[0], destination[1]);
|
|
163
|
+
context.stroke();
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const getTouchPoint = evt => {
|
|
167
|
+
if (!evt.currentTarget) {
|
|
168
|
+
return [0, 0];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const rect = evt.currentTarget.getBoundingClientRect();
|
|
172
|
+
const touch = evt.targetTouches[0];
|
|
173
|
+
console.log(rect, touch);
|
|
174
|
+
return [touch.clientX - rect.left, touch.clientY - rect.top];
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const BUTTON = 0b01;
|
|
178
|
+
|
|
179
|
+
const mouseButtonIsDown = buttons => (BUTTON & buttons) === BUTTON;
|
|
180
|
+
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
// Register event handlers
|
|
183
|
+
canvas.current.addEventListener("touchstart", touchStart, false);
|
|
184
|
+
canvas.current.addEventListener("touchend", touchEnd, false);
|
|
185
|
+
canvas.current.addEventListener("touchcancel", touchEnd, false);
|
|
186
|
+
canvas.current.addEventListener("touchmove", touchMove, false);
|
|
187
|
+
canvas.current.addEventListener("mousedown", mouseDown, false);
|
|
188
|
+
canvas.current.addEventListener("mouseup", endStroke, false);
|
|
189
|
+
canvas.current.addEventListener("mouseout", endStroke, false);
|
|
190
|
+
canvas.current.addEventListener("mouseenter", mouseEnter, false);
|
|
191
|
+
context = canvas.current.getContext("2d");
|
|
192
|
+
}, []);
|
|
193
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("canvas", {
|
|
194
|
+
id: "canvas",
|
|
195
|
+
ref: canvas,
|
|
196
|
+
height: "450",
|
|
197
|
+
width: "800",
|
|
198
|
+
style: {
|
|
199
|
+
backgroundColor: 'yellow'
|
|
200
|
+
}
|
|
201
|
+
}), /*#__PURE__*/React.createElement("input", {
|
|
202
|
+
type: "color",
|
|
203
|
+
id: "colourInput",
|
|
204
|
+
value: "#3d34a5"
|
|
205
|
+
}));
|
|
206
|
+
};
|
|
207
|
+
export default CanvasPain;
|
|
@@ -7,8 +7,6 @@ import clsx from 'clsx';
|
|
|
7
7
|
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
|
8
8
|
import { ThemeProvider } from '@mui/system';
|
|
9
9
|
import { createTheme } from '@mui/material/styles';
|
|
10
|
-
import { theme } from '../../Theme/theme';
|
|
11
|
-
const defaultTheme = createTheme(theme.pitchCamp);
|
|
12
10
|
const useStyles = makeStyles(() => ({
|
|
13
11
|
rootFabElement: {
|
|
14
12
|
margin: 2,
|
|
@@ -59,8 +57,10 @@ const CustomFab = props => {
|
|
|
59
57
|
Icon,
|
|
60
58
|
buttonText,
|
|
61
59
|
boxShadow,
|
|
62
|
-
iconLocation
|
|
60
|
+
iconLocation,
|
|
61
|
+
theme
|
|
63
62
|
} = props;
|
|
63
|
+
const defaultTheme = createTheme(theme);
|
|
64
64
|
const classes = useStyles(props);
|
|
65
65
|
console.log('debug boxShadow', boxShadow);
|
|
66
66
|
return /*#__PURE__*/React.createElement(ThemeProvider, {
|
|
@@ -106,7 +106,8 @@ CustomFab.defaultProps = {
|
|
|
106
106
|
textColor: 'textPrimary',
|
|
107
107
|
hoverTextColor: 'textPrimary',
|
|
108
108
|
className: '',
|
|
109
|
-
color: 'primary'
|
|
109
|
+
color: 'primary',
|
|
110
|
+
theme: {}
|
|
110
111
|
};
|
|
111
112
|
CustomFab.propTypes = {
|
|
112
113
|
/** onClick function passed to the button */
|
|
@@ -154,5 +155,8 @@ CustomFab.propTypes = {
|
|
|
154
155
|
className: PropTypes.string,
|
|
155
156
|
|
|
156
157
|
/** Theme colors if not using backgroundColor ['primary','secondary'] */
|
|
157
|
-
color: PropTypes.oneOf(['primary', 'secondary'])
|
|
158
|
+
color: PropTypes.oneOf(['primary', 'secondary']),
|
|
159
|
+
|
|
160
|
+
/** Theme object to use on this component*/
|
|
161
|
+
theme: PropTypes.object
|
|
158
162
|
};
|
|
@@ -2,6 +2,8 @@ import React from 'react';
|
|
|
2
2
|
import CustomFab from '../CustomFab/CustomFab';
|
|
3
3
|
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
|
+
import { ThemeProvider } from '@mui/system';
|
|
6
|
+
import { createTheme } from '@mui/material/styles';
|
|
5
7
|
export const HelpButton = props => {
|
|
6
8
|
const {
|
|
7
9
|
onClickLink,
|
|
@@ -9,9 +11,13 @@ export const HelpButton = props => {
|
|
|
9
11
|
color,
|
|
10
12
|
tooltipText,
|
|
11
13
|
size,
|
|
12
|
-
iconSize
|
|
14
|
+
iconSize,
|
|
15
|
+
theme
|
|
13
16
|
} = props;
|
|
14
|
-
|
|
17
|
+
const defaultTheme = createTheme(theme);
|
|
18
|
+
return /*#__PURE__*/React.createElement(ThemeProvider, {
|
|
19
|
+
theme: defaultTheme
|
|
20
|
+
}, /*#__PURE__*/React.createElement(CustomFab, {
|
|
15
21
|
className: className,
|
|
16
22
|
Icon: HelpOutlineIcon,
|
|
17
23
|
tooltipText: tooltipText,
|
|
@@ -19,10 +25,11 @@ export const HelpButton = props => {
|
|
|
19
25
|
size: size,
|
|
20
26
|
iconSize: iconSize,
|
|
21
27
|
variant: 'round',
|
|
28
|
+
theme: theme,
|
|
22
29
|
onClick: () => {
|
|
23
30
|
window.open(onClickLink, "_blank");
|
|
24
31
|
}
|
|
25
|
-
});
|
|
32
|
+
}));
|
|
26
33
|
};
|
|
27
34
|
export default HelpButton;
|
|
28
35
|
HelpButton.defaultProps = {
|
|
@@ -31,7 +38,8 @@ HelpButton.defaultProps = {
|
|
|
31
38
|
color: 'primary',
|
|
32
39
|
tooltipText: '',
|
|
33
40
|
size: 'large',
|
|
34
|
-
iconSize: 24
|
|
41
|
+
iconSize: 24,
|
|
42
|
+
theme: {}
|
|
35
43
|
};
|
|
36
44
|
HelpButton.propTypes = {
|
|
37
45
|
/** On click link, it's the URL to navigate too */
|
|
@@ -50,5 +58,8 @@ HelpButton.propTypes = {
|
|
|
50
58
|
iconSize: PropTypes.number,
|
|
51
59
|
|
|
52
60
|
/** The size of the button ['small','medium','large'] */
|
|
53
|
-
size: PropTypes.oneOf(['small', 'medium', 'large'])
|
|
61
|
+
size: PropTypes.oneOf(['small', 'medium', 'large']),
|
|
62
|
+
|
|
63
|
+
/** Theme object to use on this component*/
|
|
64
|
+
theme: PropTypes.object
|
|
54
65
|
};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Slider from '@mui/material/Slider';
|
|
3
|
+
import Typography from '@mui/material/Typography';
|
|
4
|
+
import { combineDrawing } from '../service/image_tools';
|
|
5
|
+
import imageCompression from 'browser-image-compression';
|
|
6
|
+
import { ChromePicker } from 'react-color';
|
|
7
|
+
import Button from '@mui/material/Button';
|
|
8
|
+
import { OUTPUT_TYPES } from '.././constants';
|
|
9
|
+
const imageScaleMarks = [{
|
|
10
|
+
value: 1.5,
|
|
11
|
+
label: 'Full'
|
|
12
|
+
}, {
|
|
13
|
+
value: 2,
|
|
14
|
+
label: 'Medium'
|
|
15
|
+
}, {
|
|
16
|
+
value: 2.5,
|
|
17
|
+
label: 'Small'
|
|
18
|
+
}];
|
|
19
|
+
export const downloadImage = (blob, filename = `pitchcamp_${new Date().toString()}.jpg`) => {
|
|
20
|
+
//Used for testing
|
|
21
|
+
const a = document.createElement('a');
|
|
22
|
+
document.body.appendChild(a);
|
|
23
|
+
a.style = 'display: none';
|
|
24
|
+
const url = window.URL.createObjectURL(blob);
|
|
25
|
+
a.href = url;
|
|
26
|
+
a.download = filename;
|
|
27
|
+
a.click();
|
|
28
|
+
window.URL.revokeObjectURL(url);
|
|
29
|
+
};
|
|
30
|
+
export const toBase64 = async blob => {
|
|
31
|
+
try {
|
|
32
|
+
const reader = new FileReader();
|
|
33
|
+
reader.readAsDataURL(blob);
|
|
34
|
+
return await new Promise(resolve => {
|
|
35
|
+
reader.onloadend = () => {
|
|
36
|
+
resolve(reader.result);
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error('Error in toBase64 function of hte ImageCanvasDraw component: ', error);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
function valueLabelFormat(value) {
|
|
45
|
+
return imageScaleMarks.findIndex(mark => mark.value === value) + 0.5;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const exportImage = async (thisFunction, saveableCanvas, outputFormat, imageCompressionOptions) => {
|
|
49
|
+
try {
|
|
50
|
+
const {
|
|
51
|
+
blob,
|
|
52
|
+
dataUri
|
|
53
|
+
} = combineDrawing(saveableCanvas);
|
|
54
|
+
imageCompression(blob, imageCompressionOptions).then(function (compressedBlob) {
|
|
55
|
+
if (OUTPUT_TYPES.BLOB === outputFormat.toLowerCase()) {
|
|
56
|
+
//Return the blob object
|
|
57
|
+
thisFunction(compressedBlob);
|
|
58
|
+
} else {
|
|
59
|
+
//Return the base64 url
|
|
60
|
+
toBase64(compressedBlob).then(base64Data => {
|
|
61
|
+
thisFunction(base64Data);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}).catch(function (error) {
|
|
65
|
+
console.log(error.message);
|
|
66
|
+
});
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.log('error in exportImage in ImageCanvasDraw comp: ', error);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const Controls = props => {
|
|
73
|
+
const {
|
|
74
|
+
state,
|
|
75
|
+
setState,
|
|
76
|
+
saveableCanvas,
|
|
77
|
+
onSave,
|
|
78
|
+
outputFormat,
|
|
79
|
+
showDownloadButton
|
|
80
|
+
} = props;
|
|
81
|
+
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
|
|
82
|
+
className: "flex flex-col"
|
|
83
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
84
|
+
className: "flex flex-row justify-between "
|
|
85
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
86
|
+
color: "secondary",
|
|
87
|
+
onClick: () => {
|
|
88
|
+
saveableCanvas.current.eraseAll();
|
|
89
|
+
}
|
|
90
|
+
}, "Erase"), /*#__PURE__*/React.createElement(Button, {
|
|
91
|
+
color: "secondary",
|
|
92
|
+
onClick: () => {
|
|
93
|
+
saveableCanvas.current.undo();
|
|
94
|
+
}
|
|
95
|
+
}, "Undo"), /*#__PURE__*/React.createElement(Button, {
|
|
96
|
+
variant: "outlined",
|
|
97
|
+
onClick: () => {
|
|
98
|
+
exportImage(onSave, saveableCanvas, outputFormat, state.imageCompressionOptions);
|
|
99
|
+
}
|
|
100
|
+
}, "Save")), /*#__PURE__*/React.createElement("div", {
|
|
101
|
+
className: "m-auto my-12"
|
|
102
|
+
}, /*#__PURE__*/React.createElement(ChromePicker, {
|
|
103
|
+
className: "drop-shadow-none",
|
|
104
|
+
disableAlpha: true,
|
|
105
|
+
color: state.color,
|
|
106
|
+
onChange: (color, event) => {
|
|
107
|
+
setState(previousState => {
|
|
108
|
+
return { ...previousState,
|
|
109
|
+
color: color.hex
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
114
|
+
className: "my-6"
|
|
115
|
+
}, /*#__PURE__*/React.createElement(Typography, {
|
|
116
|
+
id: "image-scale"
|
|
117
|
+
}, "Pull String Length"), /*#__PURE__*/React.createElement("div", {
|
|
118
|
+
className: "mx-8"
|
|
119
|
+
}, /*#__PURE__*/React.createElement(Slider, {
|
|
120
|
+
className: "w-full",
|
|
121
|
+
defaultValue: 1.5,
|
|
122
|
+
"aria-labelledby": "image-scale",
|
|
123
|
+
valueLabelDisplay: "auto",
|
|
124
|
+
value: state.lazyRadius,
|
|
125
|
+
onChange: event => {
|
|
126
|
+
setState(previousState => {
|
|
127
|
+
return { ...previousState,
|
|
128
|
+
lazyRadius: Number(event.target.value)
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
},
|
|
132
|
+
step: 1,
|
|
133
|
+
min: 1,
|
|
134
|
+
max: 30
|
|
135
|
+
}))), /*#__PURE__*/React.createElement("div", {
|
|
136
|
+
className: "my-6"
|
|
137
|
+
}, /*#__PURE__*/React.createElement(Typography, {
|
|
138
|
+
id: "image-scale"
|
|
139
|
+
}, "Brush Size"), /*#__PURE__*/React.createElement("div", {
|
|
140
|
+
className: "mx-8"
|
|
141
|
+
}, /*#__PURE__*/React.createElement(Slider, {
|
|
142
|
+
className: "w-full",
|
|
143
|
+
defaultValue: 1.5,
|
|
144
|
+
"aria-labelledby": "image-scale",
|
|
145
|
+
valueLabelDisplay: "auto",
|
|
146
|
+
value: state.brushRadius,
|
|
147
|
+
onChange: event => {
|
|
148
|
+
setState(previousState => {
|
|
149
|
+
return { ...previousState,
|
|
150
|
+
brushRadius: Number(event.target.value)
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
},
|
|
154
|
+
step: 1,
|
|
155
|
+
min: 1,
|
|
156
|
+
max: 10
|
|
157
|
+
}))), /*#__PURE__*/React.createElement("div", {
|
|
158
|
+
className: "my-6"
|
|
159
|
+
}, /*#__PURE__*/React.createElement(Typography, {
|
|
160
|
+
id: "image-scale"
|
|
161
|
+
}, "Image Size"), /*#__PURE__*/React.createElement("div", {
|
|
162
|
+
className: "mx-8"
|
|
163
|
+
}, /*#__PURE__*/React.createElement(Slider, {
|
|
164
|
+
className: "w-full",
|
|
165
|
+
defaultValue: 1.5,
|
|
166
|
+
valueLabelFormat: valueLabelFormat,
|
|
167
|
+
"aria-labelledby": "image-scale",
|
|
168
|
+
step: null // valueLabelDisplay="auto"
|
|
169
|
+
,
|
|
170
|
+
value: state.imageScale,
|
|
171
|
+
onChange: event => {
|
|
172
|
+
setState(previousState => {
|
|
173
|
+
return { ...previousState,
|
|
174
|
+
imageScale: Number(event.target.value)
|
|
175
|
+
};
|
|
176
|
+
});
|
|
177
|
+
},
|
|
178
|
+
marks: imageScaleMarks,
|
|
179
|
+
min: 1.5,
|
|
180
|
+
max: 2.5
|
|
181
|
+
})))), /*#__PURE__*/React.createElement("div", {
|
|
182
|
+
className: "flex flex-row justify-center mt-12"
|
|
183
|
+
}, showDownloadButton && /*#__PURE__*/React.createElement(Button, {
|
|
184
|
+
variant: "outlined",
|
|
185
|
+
onClick: () => {
|
|
186
|
+
exportImage(downloadImage, saveableCanvas, OUTPUT_TYPES.BLOB, state.imageCompressionOptions);
|
|
187
|
+
}
|
|
188
|
+
}, "Download")));
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
export default Controls;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types';
|