Skip to content

Commit b09ffea

Browse files
committed
update text widget editor
- text size - text color - text edge weight - text edge color - background color - width - height - position
1 parent 963ff38 commit b09ffea

File tree

3 files changed

+248
-22
lines changed

3 files changed

+248
-22
lines changed

src/components/TextWidget/editor.tsx

Lines changed: 232 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,68 @@ type Props = {
1212
const FormGroup = styled.div`
1313
display: flex;
1414
margin-bottom: 1rem;
15-
width: 480px;
16-
& > label {
17-
width: 20%;
18-
}
19-
& > input {
15+
min-width: 480px;
16+
& > div {
2017
flex-grow: 1;
18+
margin-left: 0.25rem;
2119
}
2220
`;
2321

22+
class Color {
23+
public r: number;
24+
public g: number;
25+
public b: number;
26+
public a: number;
27+
28+
constructor(r: number, g: number, b: number, a: number) {
29+
this.r = r;
30+
this.g = g;
31+
this.b = b;
32+
this.a = a;
33+
}
34+
35+
// from #rrggbb
36+
static fromRGBCode(rgb: string): Color {
37+
return new Color(
38+
parseInt(rgb.substr(1,2), 16),
39+
parseInt(rgb.substr(3,2), 16),
40+
parseInt(rgb.substr(5,2), 16),
41+
1,
42+
);
43+
}
44+
45+
// from rgba(r,g,b,a)
46+
static fromRGBA(rgba: string): Color {
47+
const match = rgba.match(/rgba\((\d+),(\d+),(\d+),(\d(\.\d+)?)\)/);
48+
return new Color(
49+
parseInt(match[1]),
50+
parseInt(match[2]),
51+
parseInt(match[3]),
52+
parseFloat(match[4])
53+
);
54+
}
55+
56+
toRGBA(): string {
57+
const rgba = [this.r, this.g, this.b, this.a];
58+
return `rgba(${rgba.join(',')})`;
59+
}
60+
61+
toRGBCode(): string {
62+
function toHex(num): string {
63+
let res = num.toString(16);
64+
if (res.length === 1) {
65+
res = `0${res}`;
66+
}
67+
return res;
68+
}
69+
const r = toHex(this.r);
70+
const g = toHex(this.g);
71+
const b = toHex(this.b);
72+
73+
return `#${r}${g}${b}`;
74+
}
75+
}
76+
2477
class TextWidgetEditor extends Component<Props, TextWidgetProps> {
2578
constructor(props) {
2679
super(props);
@@ -46,6 +99,180 @@ class TextWidgetEditor extends Component<Props, TextWidgetProps> {
4699
value={this.state.text}
47100
/>
48101
</FormGroup>
102+
<FormGroup>
103+
<TextField
104+
type="text"
105+
label="text size"
106+
fullWidth
107+
variant="outlined"
108+
onChange={(e) => {
109+
this.setState({ ...this.state, fontSize: e.target.value });
110+
}}
111+
value={this.state.fontSize}
112+
/>
113+
<TextField
114+
type="color"
115+
label="text color"
116+
fullWidth
117+
variant="outlined"
118+
onChange={(e) => {
119+
this.setState({ ...this.state, textColor: e.target.value });
120+
}}
121+
value={this.state.textColor}
122+
/>
123+
<TextField
124+
type="number"
125+
label="text edge weight"
126+
fullWidth
127+
variant="outlined"
128+
onChange={(e) => {
129+
this.setState({ ...this.state, edgeWeight: parseFloat(e.target.value) });
130+
}}
131+
value={this.state.edgeWeight}
132+
/>
133+
<TextField
134+
type="color"
135+
label="text edge color"
136+
fullWidth
137+
variant="outlined"
138+
onChange={(e) => {
139+
this.setState({ ...this.state, edgeColor: e.target.value });
140+
}}
141+
value={this.state.edgeColor}
142+
/>
143+
<TextField
144+
type="color"
145+
label="background color"
146+
fullWidth
147+
variant="outlined"
148+
onChange={(e) => {
149+
const color = Color.fromRGBA(this.state.backgroundColor);
150+
const newColor = Color.fromRGBCode(e.target.value);
151+
newColor.a = color.a;
152+
this.setState({ ...this.state, backgroundColor: newColor.toRGBA() });
153+
}}
154+
value={Color.fromRGBA(this.state.backgroundColor).toRGBCode()}
155+
/>
156+
<TextField
157+
type="number"
158+
label="background opacity"
159+
fullWidth
160+
variant="outlined"
161+
onChange={(e) => {
162+
const color = Color.fromRGBA(this.state.backgroundColor)
163+
color.a = parseFloat(e.target.value);
164+
this.setState({ ...this.state, backgroundColor: color.toRGBA() });
165+
}}
166+
value={Color.fromRGBA(this.state.backgroundColor).a}
167+
/>
168+
</FormGroup>
169+
<FormGroup>
170+
<TextField
171+
type="number"
172+
label="width"
173+
fullWidth
174+
variant="outlined"
175+
onChange={(e) => {
176+
this.setState({ ...this.state, width: parseFloat(e.target.value) });
177+
}}
178+
value={this.state.width}
179+
/>
180+
<TextField
181+
type="number"
182+
label="height"
183+
fullWidth
184+
variant="outlined"
185+
onChange={(e) => {
186+
this.setState({ ...this.state, height: parseFloat(e.target.value) });
187+
}}
188+
value={this.state.height}
189+
/>
190+
191+
<TextField
192+
type="number"
193+
label="position top"
194+
fullWidth
195+
variant="outlined"
196+
onChange={(e) => {
197+
const pos = this.state.position || {};
198+
if (e.target.value !== "") {
199+
const v = parseInt(e.target.value);
200+
if (isNaN(v)) {
201+
delete pos.top;
202+
} else {
203+
pos.top = v;
204+
}
205+
} else {
206+
delete pos.top;
207+
}
208+
this.setState({ ...this.state, position: pos });
209+
}}
210+
value={this.state?.position?.top}
211+
/>
212+
<TextField
213+
type="number"
214+
label="position right"
215+
fullWidth
216+
variant="outlined"
217+
onChange={(e) => {
218+
const pos = this.state.position || {};
219+
if (e.target.value !== "") {
220+
const v = parseInt(e.target.value);
221+
if (isNaN(v)) {
222+
delete pos.right;
223+
} else {
224+
pos.right = v;
225+
}
226+
} else {
227+
delete pos.right;
228+
}
229+
this.setState({ ...this.state, position: pos });
230+
}}
231+
value={this.state.position?.right}
232+
/>
233+
<TextField
234+
type="number"
235+
label="position bottom"
236+
fullWidth
237+
variant="outlined"
238+
onChange={(e) => {
239+
const pos = this.state.position || {};
240+
if (e.target.value !== "") {
241+
const v = parseInt(e.target.value);
242+
if (isNaN(v)) {
243+
delete pos.bottom;
244+
} else {
245+
pos.bottom = v;
246+
}
247+
} else {
248+
delete pos.bottom;
249+
}
250+
this.setState({ ...this.state, position: pos });
251+
}}
252+
value={this.state.position?.bottom}
253+
/>
254+
<TextField
255+
type="number"
256+
label="position left"
257+
fullWidth
258+
variant="outlined"
259+
onChange={(e) => {
260+
const pos = this.state.position || {};
261+
if (e.target.value !== "") {
262+
const v = parseInt(e.target.value);
263+
if (isNaN(v)) {
264+
delete pos.left;
265+
} else {
266+
pos.left = v;
267+
}
268+
} else {
269+
delete pos.left;
270+
}
271+
this.setState({ ...this.state, position: pos });
272+
}}
273+
value={this.state.position?.left}
274+
/>
275+
</FormGroup>
49276

50277
<FirebaseDatabaseMutation
51278
type="set"

src/components/TextWidget/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ type Position = {
88
type TextWidgetProps = {
99
text: string;
1010
textColor?: string;
11+
fontSize?: string;
1112
backgroundColor?: string;
1213
edgeWeight?: number; // px
1314
edgeColor?: string;

src/components/TextWidget/widget.tsx

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,19 @@ const defaultStyle: CSSProperties = {
1919
boxSizing: 'border-box',
2020
whiteSpace: 'pre-wrap',
2121
overflow: 'hidden',
22-
color: 'white',
23-
backgroundColor: 'rgba(0, 0, 0 0.1)',
24-
textShadow: calcTextShadow(1, 'black'),
22+
color: '#ffffff',
23+
backgroundColor: 'rgba(0,0,0,0.1)',
24+
textShadow: calcTextShadow(1, '#000000'),
2525
width: 320,
2626
height: 540,
27-
padding: '4px 8px',
27+
padding: '0.25rem 0.5rem',
2828
position: 'absolute',
2929
};
3030

3131
const TextWidget: VFC<TextWidgetProps> = ({
3232
text,
3333
textColor,
34+
fontSize,
3435
backgroundColor,
3536
edgeWeight,
3637
edgeColor,
@@ -39,26 +40,23 @@ const TextWidget: VFC<TextWidgetProps> = ({
3940
padding,
4041
position,
4142
}) => {
42-
const edge = calcTextShadow(edgeWeight || 1, edgeColor || 'black');
43+
const edge = calcTextShadow(edgeWeight || 1, edgeColor || '#000000');
4344

4445
const style: CSSProperties = {
4546
...defaultStyle,
4647
width: `${width || 320}px`,
47-
height: `${height | 540}px`,
48-
padding: padding || '4px 8px',
49-
color: textColor || 'white',
48+
height: `${height || 540}px`,
49+
padding: padding || '0.25rem 0.5rem',
50+
color: textColor || '#ffffff',
51+
fontSize: fontSize || '1rem',
5052
textShadow: edge,
51-
backgroundColor: backgroundColor || 'rgba(0, 0, 0, 0.1)',
53+
backgroundColor: backgroundColor || 'rgba(0,0,0,0.1)',
5254
};
5355

54-
if (position?.top || position?.right || position?.bottom || position?.left) {
55-
if (position?.top) style.top = position.top;
56-
if (position?.right) style.right = position.right;
57-
if (position?.bottom) style.bottom = position.bottom;
58-
if (position?.left) style.left = position.left;
59-
} else {
60-
style.right = 0;
61-
}
56+
if (position?.top !== undefined) style.top = position.top;
57+
if (position?.right !== undefined) style.right = position.right;
58+
if (position?.bottom !== undefined) style.bottom = position.bottom;
59+
if (position?.left !== undefined) style.left = position.left;
6260

6361
console.log(style);
6462

0 commit comments

Comments
 (0)