Skip to content

Commit 25e67a8

Browse files
authored
Merge pull request #254 from GBSL-Informatik/refactor/excalidraw-tool
refactor: let user decide about export quality, backgrounds and margins
2 parents 80c4070 + ad9752c commit 25e67a8

File tree

20 files changed

+577
-138
lines changed

20 files changed

+577
-138
lines changed

docs/tdev/gallery/tools/image-markup/images/demo.svg

Lines changed: 2 additions & 2 deletions
Loading

docs/tdev/gallery/tools/image-markup/images/demo.svg.excalidraw

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,34 @@
22
"type": "excalidraw",
33
"version": 2,
44
"elements": [
5+
{
6+
"id": "TDEV-STANDALONE-DRAWING",
7+
"type": "rectangle",
8+
"x": -423.0333231608073,
9+
"y": -271.4722315470378,
10+
"width": 833.3333129882812,
11+
"height": 530.6666870117188,
12+
"strokeColor": "#1e1e1ea1",
13+
"backgroundColor": "transparent",
14+
"fillStyle": "solid",
15+
"strokeWidth": 0.05,
16+
"strokeStyle": "dotted",
17+
"roughness": 0,
18+
"opacity": 100,
19+
"locked": true,
20+
"version": 2,
21+
"versionNonce": 943970152,
22+
"index": "Zz",
23+
"isDeleted": false,
24+
"angle": 0,
25+
"seed": 1,
26+
"groupIds": [],
27+
"frameId": null,
28+
"roundness": null,
29+
"boundElements": [],
30+
"updated": 1763308684156,
31+
"link": null
32+
},
533
{
634
"id": "IuZRsqPjub8yxxLCdL9gL",
735
"type": "diamond",
@@ -24,11 +52,11 @@
2452
"type": 2
2553
},
2654
"seed": 306917131,
27-
"version": 56,
28-
"versionNonce": 2025318123,
55+
"version": 59,
56+
"versionNonce": 1746086936,
2957
"isDeleted": false,
3058
"boundElements": [],
31-
"updated": 1755449004392,
59+
"updated": 1763308785072,
3260
"link": null,
3361
"locked": false
3462
},
@@ -84,11 +112,11 @@
84112
"type": 2
85113
},
86114
"seed": 2085431371,
87-
"version": 404,
88-
"versionNonce": 579981707,
115+
"version": 423,
116+
"versionNonce": 1334799638,
89117
"isDeleted": false,
90118
"boundElements": [],
91-
"updated": 1755449004392,
119+
"updated": 1763333706415,
92120
"link": null,
93121
"locked": false
94122
}
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
{
2+
"type": "excalidraw",
3+
"version": 2,
4+
"elements": [
5+
{
6+
"id": "TDEV-STANDALONE-DRAWING",
7+
"type": "rectangle",
8+
"x": 153.2972391220263,
9+
"y": 80.77144694572988,
10+
"width": 68.4215891178082,
11+
"height": 68.73871016204396,
12+
"strokeColor": "#1e1e1ea1",
13+
"backgroundColor": "transparent",
14+
"fillStyle": "solid",
15+
"strokeWidth": 0.05,
16+
"strokeStyle": "dotted",
17+
"roughness": 0,
18+
"opacity": 100,
19+
"locked": true,
20+
"version": 2,
21+
"versionNonce": 45026934,
22+
"index": "a0",
23+
"isDeleted": false,
24+
"angle": 0,
25+
"seed": 1,
26+
"groupIds": [],
27+
"frameId": null,
28+
"roundness": null,
29+
"boundElements": [],
30+
"updated": 1763331244365,
31+
"link": null,
32+
"customData": {
33+
"scale": 20,
34+
"exportPadding": 4
35+
}
36+
},
37+
{
38+
"id": "f6J6K1wrWJi5eNBt8MvZb",
39+
"type": "diamond",
40+
"x": 163.6588626033281,
41+
"y": 95.29143813325153,
42+
"width": 46.42277811615982,
43+
"height": 34.40661337504243,
44+
"angle": 5.478114399932058,
45+
"strokeColor": "#e03131",
46+
"backgroundColor": "#ffc9c9",
47+
"fillStyle": "hachure",
48+
"strokeWidth": 1,
49+
"strokeStyle": "solid",
50+
"roughness": 0,
51+
"opacity": 100,
52+
"groupIds": [],
53+
"frameId": null,
54+
"index": "a1",
55+
"roundness": {
56+
"type": 2
57+
},
58+
"seed": 1748157208,
59+
"version": 283,
60+
"versionNonce": 86830616,
61+
"isDeleted": false,
62+
"boundElements": [],
63+
"updated": 1763331246962,
64+
"link": null,
65+
"locked": false
66+
},
67+
{
68+
"id": "jqOrOKruzPBx9DiZSO44T",
69+
"type": "ellipse",
70+
"x": 181.95561180701282,
71+
"y": 103.38465093816218,
72+
"width": 18.03080681900128,
73+
"height": 18.03080681900128,
74+
"angle": 4.71238898038469,
75+
"strokeColor": "transparent",
76+
"backgroundColor": "#ffffff",
77+
"fillStyle": "solid",
78+
"strokeWidth": 1,
79+
"strokeStyle": "solid",
80+
"roughness": 0,
81+
"opacity": 100,
82+
"groupIds": [],
83+
"frameId": null,
84+
"index": "a2",
85+
"roundness": {
86+
"type": 2
87+
},
88+
"seed": 1744920,
89+
"version": 541,
90+
"versionNonce": 1922525976,
91+
"isDeleted": false,
92+
"boundElements": [],
93+
"updated": 1763331246962,
94+
"link": null,
95+
"locked": false
96+
},
97+
{
98+
"id": "ztn5FE34qIkFrwD-1hrdi",
99+
"type": "ellipse",
100+
"x": 181.95561180701282,
101+
"y": 103.38465093969332,
102+
"width": 18.03080681900128,
103+
"height": 18.03080681900128,
104+
"angle": 4.71238898038469,
105+
"strokeColor": "#e03131",
106+
"backgroundColor": "#ffec99",
107+
"fillStyle": "hachure",
108+
"strokeWidth": 1,
109+
"strokeStyle": "solid",
110+
"roughness": 0,
111+
"opacity": 100,
112+
"groupIds": [],
113+
"frameId": null,
114+
"index": "a3",
115+
"roundness": {
116+
"type": 2
117+
},
118+
"seed": 1761533208,
119+
"version": 535,
120+
"versionNonce": 665471000,
121+
"isDeleted": false,
122+
"boundElements": [],
123+
"updated": 1763331246962,
124+
"link": null,
125+
"locked": false
126+
},
127+
{
128+
"id": "Q3elwXLTOurV93tGOlXIX",
129+
"type": "rectangle",
130+
"x": 164.29664461609673,
131+
"y": 97.62899679240267,
132+
"width": 46.422778129667336,
133+
"height": 35.023610468698365,
134+
"angle": 5.478114399932058,
135+
"strokeColor": "#e03131",
136+
"backgroundColor": "transparent",
137+
"fillStyle": "solid",
138+
"strokeWidth": 11,
139+
"strokeStyle": "solid",
140+
"roughness": 0,
141+
"opacity": 100,
142+
"groupIds": [],
143+
"frameId": null,
144+
"index": "a4",
145+
"roundness": {
146+
"type": 3
147+
},
148+
"seed": 72579608,
149+
"version": 291,
150+
"versionNonce": 1039922024,
151+
"isDeleted": false,
152+
"boundElements": [],
153+
"updated": 1763331374164,
154+
"link": null,
155+
"locked": false
156+
}
157+
],
158+
"files": {}
159+
}
43.5 KB
Loading

docs/tdev/gallery/tools/image-markup/images/image-structure.jpg.excalidraw

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,10 @@
1919
],
2020
"locked": true,
2121
"customData": {
22-
"exportFormatMimeType": "image/jpeg",
23-
"scale": 1,
24-
"initExtension": ".jpg"
22+
"scale": 2
2523
},
2624
"version": 2,
27-
"versionNonce": 1904448331,
25+
"versionNonce": 1904448334,
2826
"index": "a0",
2927
"fillStyle": "solid",
3028
"strokeWidth": 2,
-22.2 KB
Loading

docs/tdev/gallery/tools/image-markup/images/save-as-webp.webp.excalidraw

Lines changed: 3 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020
"locked": true,
2121
"customData": {
2222
"exportFormatMimeType": "image/webp",
23-
"scale": 0.4038364462,
24-
"initExtension": ".webp"
23+
"exportPadding": 2,
24+
"scale": 2
2525
},
2626
"version": 2,
27-
"versionNonce": 1141052185,
27+
"versionNonce": 1141052194,
2828
"index": "a0",
2929
"fillStyle": "solid",
3030
"strokeWidth": 2,
@@ -412,51 +412,6 @@
412412
"originalText": "1",
413413
"autoResize": true,
414414
"lineHeight": 1.15
415-
},
416-
{
417-
"id": "Lj1WGHyEa6pCEoeS9CEQ0",
418-
"type": "line",
419-
"x": -44.888824076497336,
420-
"y": 36.26413686658643,
421-
"width": 0,
422-
"height": 145.33333333333337,
423-
"angle": 0,
424-
"strokeColor": "transparent",
425-
"backgroundColor": "transparent",
426-
"fillStyle": "solid",
427-
"strokeWidth": 4,
428-
"strokeStyle": "solid",
429-
"roughness": 0,
430-
"opacity": 100,
431-
"groupIds": [],
432-
"frameId": null,
433-
"index": "aH",
434-
"roundness": {
435-
"type": 2
436-
},
437-
"seed": 1168197022,
438-
"version": 70,
439-
"versionNonce": 1798543554,
440-
"isDeleted": false,
441-
"boundElements": [],
442-
"updated": 1754817126541,
443-
"link": null,
444-
"locked": false,
445-
"points": [
446-
[
447-
0,
448-
0
449-
],
450-
[
451-
0,
452-
145.33333333333337
453-
]
454-
],
455-
"lastCommittedPoint": null,
456-
"startBinding": null,
457-
"endBinding": null,
458-
"startArrowhead": null,
459-
"endArrowhead": null
460415
}
461416
],
462417
"files": {

docs/tdev/gallery/tools/image-markup/index.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ tags: [excalidraw, bilder]
66
# Bilder Annotieren
77

88
:::warning[Nur für Chrome-Browser]
9-
Die Excalidraw-Integration für das Editieren von Bildern basiert auf der [Local File System Access API](https://developer.mozilla.org/de/docs/Web/API/Window/showOpenFilePicker), welche aktuell nur unter Chrome-basierten Browsern (z.B. Google Chrome, Microsoft Edge) unterstützt wird.
9+
Die Excalidraw-Integration für das Editieren von Bildern basiert auf der [Local File System Access API](https://developer.mozilla.org/de/docs/Web/API/Window/showOpenFilePicker), welche aktuell nur unter Chromium-basierten Browsern (z.B. Google Chrome, Microsoft Edge) unterstützt wird.
1010
:::
1111

1212
Oft müssen Screenshots oder Bilder annotiert werden. Ansich praktisch, bis sich das Bild ändert, die Anmerkungen aber eigentlich gleich bleiben (z.B. wenn das neue Excel eine leicht andere Benutzeroberfläche hat).
@@ -103,6 +103,8 @@ Sobald das SVG-Bild bearbeitet wird, wird die entsprechende `demo.svg.excalidraw
103103

104104
:::note[Technischer Hintergrund]
105105
Ob ein Hintergrundbild vorhanden ist oder nicht, wird vom Vorhandensein einer Element- & File-ID `TDEV-BACKGROUND-IMAGE` bzw. `TDEV-BACKGROUND--FILE` abgeleitet. Ist keine ID vorhanden, wird stets die Bild-Erweiterung (`.png`, `.jpg`, `.svg`, `.webp`) für das Export-Format verwendet.
106+
107+
Für Zeichnungen ohne Hintergrundbild wird ein Meta-Element `TDEV-STANDALONE-DRAWING` hinzugefügt, welches zusätzliche Export-relevante Informationen enthält.
106108
:::
107109

108110
:::info[Empfohlenes Export-Format für reine Excalidraw Bilder]
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React from 'react';
2+
import clsx from 'clsx';
3+
import { PopupActions } from 'reactjs-popup/dist/types';
4+
import Popup from 'reactjs-popup';
5+
import { mdiCog, mdiFileReplace } from '@mdi/js';
6+
import Button from '@tdev-components/shared/Button';
7+
import JsObjectEditor from '@tdev-components/shared/JsObject/Editor';
8+
import type { ExcalidrawImperativeAPI } from '@excalidraw/excalidraw/types';
9+
import { getMetaElementFromScene } from '../../helpers/getElementsFromScene';
10+
import { getCustomProps, CustomProps, updateCustomProps } from '../../helpers/customProps';
11+
import { JsTypes } from '@tdev-components/shared/JsObject/toJsSchema';
12+
import Card from '@tdev-components/shared/Card';
13+
import { SIZE_S } from '@tdev-components/shared/iconSizes';
14+
15+
interface Props {
16+
api: ExcalidrawImperativeAPI;
17+
onSave: () => void;
18+
className?: string;
19+
}
20+
21+
const UpdateCustomProps = (props: Props) => {
22+
const ref = React.useRef<PopupActions>(null);
23+
const [isOpen, setIsOpen] = React.useState(false);
24+
const [tdevProps, setTdevProps] = React.useState(getCustomProps());
25+
26+
return (
27+
<Popup
28+
trigger={
29+
<div className={clsx(props.className)}>
30+
<Button icon={mdiCog} active={isOpen} title="Hintergrundbild ändern" color="primary" />
31+
</div>
32+
}
33+
ref={ref}
34+
onOpen={() => {
35+
const meta = getMetaElementFromScene(props.api.getSceneElementsIncludingDeleted());
36+
const tdevProps = getCustomProps(meta);
37+
setTdevProps(tdevProps);
38+
setIsOpen(true);
39+
}}
40+
onClose={() => setIsOpen(false)}
41+
modal
42+
on="click"
43+
overlayStyle={{ background: 'rgba(0,0,0,0.5)' }}
44+
nested
45+
>
46+
<Card>
47+
{isOpen && (
48+
<JsObjectEditor
49+
js={tdevProps as unknown as Record<string, JsTypes>}
50+
hideAddValue={true}
51+
editorConfig={{
52+
numberStep: 1
53+
}}
54+
onSave={(js) => {
55+
updateCustomProps(props.api, js as unknown as CustomProps);
56+
ref.current?.close();
57+
props.onSave();
58+
}}
59+
/>
60+
)}
61+
</Card>
62+
</Popup>
63+
);
64+
};
65+
66+
export default UpdateCustomProps;

0 commit comments

Comments
 (0)