js-draw 1.31.1 → 1.33.0
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/dist/Editor.css +1 -1
- package/dist/bundle.js +38 -24
- package/dist/bundledStyles.js +1 -1
- package/dist/cjs/localizations/de.js +125 -47
- package/dist/cjs/toolbar/utils/makeDraggable.js +46 -16
- package/dist/cjs/version.js +1 -1
- package/dist/mjs/localizations/de.mjs +125 -47
- package/dist/mjs/toolbar/utils/makeDraggable.mjs +46 -16
- package/dist/mjs/version.mjs +1 -1
- package/package.json +4 -4
- package/src/toolbar/widgets/components/makeSnappedList.scss +1 -1
|
@@ -2,116 +2,194 @@ import { defaultEditorLocalization } from '../localization.mjs';
|
|
|
2
2
|
// German localization
|
|
3
3
|
const localization = {
|
|
4
4
|
...defaultEditorLocalization,
|
|
5
|
+
help: 'Hilfe',
|
|
6
|
+
helpHidden: 'Hilfe ausgeblendet',
|
|
7
|
+
next: 'Weiter',
|
|
8
|
+
previous: 'Zurück',
|
|
9
|
+
close: 'Schließen',
|
|
10
|
+
helpScreenNavigationHelp: 'Auf ein Steuerelement klicken, um weitere Informationen zu erhalten.',
|
|
11
|
+
helpControlsAccessibilityLabel: 'Steuerelemente: Aktiviere ein Steuerelement, um Hilfe anzuzeigen.',
|
|
5
12
|
pen: 'Stift',
|
|
6
13
|
eraser: 'Radierer',
|
|
7
14
|
select: 'Auswahl',
|
|
8
15
|
handTool: 'Verschieben',
|
|
9
16
|
zoom: 'Vergrößerung',
|
|
10
17
|
image: 'Bild',
|
|
11
|
-
|
|
12
|
-
|
|
18
|
+
reformatSelection: 'Formatauswahl',
|
|
19
|
+
inputAltText: 'Alt-Text:',
|
|
20
|
+
decreaseImageSize: 'Verkleinern',
|
|
21
|
+
resetImage: 'Zurücksetzen',
|
|
22
|
+
chooseFile: 'Datei wählen',
|
|
23
|
+
dragAndDropHereOrBrowse: 'Hierher ziehen\noder\n{{Durchsuchen}}',
|
|
13
24
|
submit: 'Absenden',
|
|
25
|
+
addAll: 'Alle hinzufügen',
|
|
14
26
|
cancel: 'Abbrechen',
|
|
15
27
|
resetView: 'Ansicht zurücksetzen',
|
|
16
|
-
thicknessLabel: 'Dicke:
|
|
17
|
-
colorLabel: 'Farbe:
|
|
18
|
-
fontLabel: 'Schriftart:
|
|
19
|
-
textSize: 'Größe:
|
|
28
|
+
thicknessLabel: 'Dicke:',
|
|
29
|
+
colorLabel: 'Farbe:',
|
|
30
|
+
fontLabel: 'Schriftart:',
|
|
31
|
+
textSize: 'Größe:',
|
|
20
32
|
resizeImageToSelection: 'Bildgröße an Auswahl anpassen',
|
|
21
33
|
deleteSelection: 'Auswahl löschen',
|
|
22
34
|
duplicateSelection: 'Auswahl duplizieren',
|
|
35
|
+
exit: 'Beenden',
|
|
36
|
+
save: 'Speichern',
|
|
23
37
|
undo: 'Rückgängig',
|
|
24
38
|
redo: 'Wiederholen',
|
|
39
|
+
fullStrokeEraser: 'Vollständiger Radierer',
|
|
40
|
+
selectPenType: 'Stiftstil:',
|
|
41
|
+
selectShape: 'Form',
|
|
25
42
|
pickColorFromScreen: 'Farbe von Bildschirm auswählen',
|
|
26
43
|
clickToPickColorAnnouncement: 'Klicke auf den Bildschirm, um eine Farbe auszuwählen',
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
44
|
+
colorSelectionCanceledAnnouncement: 'Farbauswahl abgebrochen',
|
|
45
|
+
selectionTool__lassoSelect: 'Freihand-Auswahl',
|
|
46
|
+
selectionTool__lassoSelect__help: 'Wenn diese Option aktiviert ist, wird durch Ziehen eine Freiformauswahl (Lasso) erstellt.',
|
|
47
|
+
selectionToolKeyboardShortcuts: 'Auswahl-Werkzeug: Verwende die Pfeiltasten, um ausgewählte Elemente zu verschieben, und die Kleinbuchstaben/Großbuchstaben „i“ und „o“, um die Größe zu ändern.',
|
|
48
|
+
documentProperties: 'Seite',
|
|
49
|
+
backgroundColor: 'Hintergrundfarbe:',
|
|
50
|
+
imageWidthOption: 'Breite:',
|
|
51
|
+
imageHeightOption: 'Höhe:',
|
|
52
|
+
useGridOption: 'Gitter:',
|
|
53
|
+
enableAutoresizeOption: 'Automatische Größenanpassung',
|
|
54
|
+
toggleOverflow: 'Mehr',
|
|
55
|
+
about: 'Über',
|
|
56
|
+
inputStabilization: 'Stabilisierung',
|
|
57
|
+
strokeAutocorrect: 'Autokorrektur',
|
|
58
|
+
pressureSensitivity: 'Druck',
|
|
59
|
+
touchPanning: 'Mit Touch verschieben',
|
|
60
|
+
roundedTipPen: 'Rund',
|
|
61
|
+
roundedTipPen2: 'Polylinie',
|
|
62
|
+
flatTipPen: 'Flach',
|
|
33
63
|
arrowPen: 'Pfeil',
|
|
34
64
|
linePen: 'Linie',
|
|
35
|
-
outlinedRectanglePen: '
|
|
65
|
+
outlinedRectanglePen: 'Umrandetes Rechteck',
|
|
36
66
|
filledRectanglePen: 'Ausgefülltes Rechteck',
|
|
37
|
-
|
|
67
|
+
outlinedCirclePen: 'Umrandeter Kreis.',
|
|
68
|
+
lockRotation: 'Drehung sperren',
|
|
38
69
|
paste: 'Einfügen',
|
|
70
|
+
errorImageHasZeroSize: 'Fehler: Bild hat Größe Null',
|
|
71
|
+
describeTheImage: 'Bildbeschreibung',
|
|
72
|
+
fileInput__loading: 'Lade...',
|
|
73
|
+
fileInput__andNMoreFiles: (n) => `(...${n} mehr)`,
|
|
74
|
+
penDropdown__baseHelpText: 'Dieses Werkzeug zeichnet Formen oder Freihandlinien.',
|
|
75
|
+
penDropdown__colorHelpText: 'Ändert die Farbe des Stifts',
|
|
76
|
+
penDropdown__thicknessHelpText: 'Ändert die Strichstärke des mit dem Stift gezeichneten Strichs.',
|
|
77
|
+
penDropdown__penTypeHelpText: 'Ändert den Stiftstil.\n\nEs kann entweder ein „Stiftstil“ oder eine „Form“ ausgewählt werden. Bei Auswahl eines „Stiftstils“ werden Freihandlinien gezeichnet. Bei Auswahl einer „Form“ werden Formen gezeichnet.',
|
|
78
|
+
penDropdown__autocorrectHelpText: 'Wandelt grobe Freihandlinien und Rechtecke in perfekte Linien und Rechtecke um.\n\nDer Stift muss am Ende eines Strichs still gehalten werden, um eine Korrektur auszulösen.',
|
|
79
|
+
penDropdown__stabilizationHelpText: 'Zeichnet glattere Striche.\n\nDadurch entsteht auch eine kurze Verzögerung zwischen Maus/Stift und Strich.',
|
|
80
|
+
penDropdown__pressureSensitivityHelpText: 'Ändert die Strichstärke entsprechend der Druckstärke, wenn du ein kompatibles Gerät wie einen Stylus verwendest.',
|
|
81
|
+
handDropdown__baseHelpText: 'Dieses Werkzeug ist für das Scrollen, Drehen und Zoomen im Editor zuständig.',
|
|
82
|
+
handDropdown__zoomInHelpText: 'Vergrößert',
|
|
83
|
+
handDropdown__zoomOutHelpText: 'Verkleinert',
|
|
84
|
+
handDropdown__resetViewHelpText: 'Setzt den Zoomfaktor auf 100 % zurück und setzt den Bildlauf zurück.',
|
|
85
|
+
handDropdown__zoomDisplayHelpText: 'Zeigt den aktuellen Zoomfaktor an. 100 % zeigt das Bild in seiner tatsächlichen Größe an.',
|
|
86
|
+
handDropdown__touchPanningHelpText: 'Wenn aktiviert, verschieben Touchscreen-Gesten das Bild, anstatt es auszuwählen oder zu zeichnen.',
|
|
87
|
+
handDropdown__lockRotationHelpText: 'Wenn aktiviert, verhindert diese Option, dass Touch-Gesten den Bildschirm drehen.',
|
|
88
|
+
eraserDropdown__baseHelpText: 'Dieses Werkzeug entfernt Striche, Bilder und Text unter dem Cursor.',
|
|
89
|
+
eraserDropdown__thicknessHelpText: 'Ändert die Größe des Radierers.',
|
|
90
|
+
eraserDropdown__fullStrokeEraserHelpText: 'Im vollständigen Modus werden ganze Formen gelöscht.\n\nAußerhalb des vollständigen Modus können Formen teilweise gelöscht werden.',
|
|
91
|
+
selectionDropdown__baseHelpText: 'Wählt Inhalte aus und bearbeitet die Auswahl',
|
|
92
|
+
selectionDropdown__resizeToHelpText: 'Schneidet die Zeichnung auf die Größe der aktuell ausgewählten Fläche zu.\n\nWenn die automatische Größenanpassung aktiviert ist, wird sie deaktiviert.',
|
|
93
|
+
selectionDropdown__deleteHelpText: 'Löscht ausgewählte Elemente.',
|
|
94
|
+
selectionDropdown__duplicateHelpText: 'Erstellt eine Kopie der ausgewählten Elemente.',
|
|
95
|
+
selectionDropdown__changeColorHelpText: 'Ändert die Farbe ausgewählter Elemente.',
|
|
96
|
+
pageDropdown__baseHelpText: 'Steuert die Hintergrundfarbe, das Muster und die Größe der Zeichenfläche.',
|
|
97
|
+
pageDropdown__backgroundColorHelpText: 'Ändert die Hintergrundfarbe der Zeichenfläche.',
|
|
98
|
+
pageDropdown__gridCheckboxHelpText: 'Aktiviert/deaktiviert ein Hintergrundraster',
|
|
99
|
+
pageDropdown__autoresizeCheckboxHelpText: 'Wenn aktiviert, wird die Seite an die Zeichnung angepasst.\n\nWenn deaktiviert, ist die Seite sichtbar und ihre Größe kann manuell festgelegt werden.',
|
|
100
|
+
pageDropdown__aboutButtonHelpText: 'Zeigt Version, Debugging und andere Informationen an.',
|
|
101
|
+
colorPickerPipetteHelpText: 'Wählt eine Farbe vom Bildschirm aus.',
|
|
102
|
+
colorPickerToggleHelpText: 'Öffnet/schließt den Farbwähler.',
|
|
103
|
+
closeSidebar: (toolName) => `Sidebar für ${toolName} schließen`,
|
|
39
104
|
dropdownShown: (toolName) => `Dropdown-Menü für ${toolName} angezeigt`,
|
|
40
105
|
dropdownHidden: (toolName) => `Dropdown-Menü für ${toolName} versteckt`,
|
|
41
106
|
zoomLevel: (zoomPercent) => `Vergößerung: ${zoomPercent}%`,
|
|
42
107
|
colorChangedAnnouncement: (color) => `Farbe zu ${color} geändert`,
|
|
43
108
|
imageSize: (size, units) => `Bild-Größe: ${size} ${units}`,
|
|
44
109
|
imageLoadError: (message) => `Fehler beim Laden des Bildes: ${message}`,
|
|
45
|
-
errorImageHasZeroSize: 'Fehler: Bild hat Größe Null',
|
|
46
110
|
penTool: (penNumber) => `Stift ${penNumber}`,
|
|
47
111
|
selectionTool: 'Auswahl',
|
|
48
|
-
|
|
112
|
+
selectAllTool: 'Alle auswählen',
|
|
113
|
+
eraserTool: 'Radierer',
|
|
49
114
|
touchPanTool: 'Ansicht mit Touchscreen verschieben',
|
|
50
115
|
twoFingerPanZoomTool: 'Ansicht verschieben und vergrößern',
|
|
51
116
|
undoRedoTool: 'Rückgängig/Wiederholen',
|
|
52
117
|
rightClickDragPanTool: 'Rechtsklick-Ziehen',
|
|
53
118
|
pipetteTool: 'Farbe von Bildschirm auswählen',
|
|
54
119
|
keyboardPanZoom: 'Tastaturkürzel zum Verschieben/Vergrößern der Ansicht',
|
|
55
|
-
|
|
120
|
+
selectionMenu__show: 'Auswahlmenü anzeigen',
|
|
121
|
+
selectionMenu__copyToClipboard: 'In Zwischenablage kopieren',
|
|
122
|
+
selectionMenu__duplicate: 'Duplizieren',
|
|
123
|
+
selectionMenu__delete: 'Löschen',
|
|
124
|
+
selectionMenu__paste: 'Einfügen',
|
|
125
|
+
copyPasteError__heading: 'Kopieren/Einfügen',
|
|
126
|
+
copyPasteError__description: 'Ein Fehler ist aufgetreten – dieses Tool hat möglicherweise keinen Zugriff auf die Zwischenablage.',
|
|
127
|
+
copyPasteError__errorDetails: 'Fehler anzeigen',
|
|
128
|
+
copyPasteError__pasteRetry: 'Um es erneut zu versuchen, füge bitte den Text in das Eingabefeld unten ein:',
|
|
129
|
+
copyPasteError__copyMe: 'Kopiere mich!',
|
|
130
|
+
autocorrectedTo: (strokeDescription) => `Automatisch korrigiert zu ${strokeDescription}`,
|
|
131
|
+
autocorrectionCanceled: 'Autokorrektur abgebrochen',
|
|
56
132
|
enterTextToInsert: 'Einzufügender Text',
|
|
57
|
-
changeTool: '
|
|
58
|
-
pasteHandler: '
|
|
59
|
-
|
|
60
|
-
|
|
133
|
+
changeTool: 'Werkzeug wechseln',
|
|
134
|
+
pasteHandler: 'Kopieren-Einfügen-Handler',
|
|
135
|
+
soundExplorer: 'Klangbasierte Bilderkundung',
|
|
136
|
+
disableAccessibilityExploreTool: 'Klangbasierte Erkundung deaktivieren',
|
|
137
|
+
enableAccessibilityExploreTool: 'Klangbasierte Erkundung aktivieren',
|
|
138
|
+
soundExplorerUsageAnnouncement: 'Soundbasierte Bilduntersuchung aktiviert: Klicke/ziehe den Bildschirm, um eine akustische Darstellung verschiedener Bildbereiche abzuspielen.',
|
|
139
|
+
findLabel: 'Suchen',
|
|
140
|
+
toNextMatch: 'Weiter',
|
|
61
141
|
closeDialog: 'Schließen',
|
|
62
|
-
findDialogShown: '
|
|
63
|
-
findDialogHidden: '
|
|
142
|
+
findDialogShown: 'Suchen-Dialog angezeigt',
|
|
143
|
+
findDialogHidden: 'Suchen-Dialog versteckt',
|
|
64
144
|
focusedFoundText: (matchIdx, totalMatches) => `Sieh Treffer ${matchIdx} von ${totalMatches} an`,
|
|
145
|
+
anyDevicePanning: 'Ansicht mit jedem Eingabegerät verschieben',
|
|
146
|
+
copied: (count) => `Copied ${count} item(s)`,
|
|
147
|
+
pasted: (count) => `Pasted ${count} item(s)`,
|
|
65
148
|
toolEnabledAnnouncement: (toolName) => `${toolName} aktiviert`,
|
|
66
149
|
toolDisabledAnnouncement: (toolName) => `${toolName} deaktiviert`,
|
|
67
150
|
updatedViewport: 'Transformierte Ansicht',
|
|
68
151
|
transformedElements: (elemCount, action) => `${elemCount} Element${1 === elemCount ? '' : 'e'} transformiert (${action})`,
|
|
69
152
|
resizeOutputCommand: (newSize) => `Bildgröße auf ${newSize.w}x${newSize.h} geändert`,
|
|
153
|
+
enabledAutoresizeOutputCommand: 'Automatische Größenanpassung der Ausgabe aktiviert',
|
|
154
|
+
disabledAutoresizeOutputCommand: 'Automatische Größenanpassung der Ausgabe deaktiviert',
|
|
70
155
|
addComponentAction: (componentDescription) => `${componentDescription} hinzugefügt`,
|
|
71
156
|
eraseAction: (elemDescription, countErased) => `${countErased} ${elemDescription} gelöscht`,
|
|
72
157
|
duplicateAction: (elemDescription, countErased) => `${countErased} ${elemDescription} dupliziert`,
|
|
158
|
+
unionOf: (actionDescription, actionCount) => `Vereinigung: ${actionCount} ${actionDescription}`,
|
|
73
159
|
inverseOf: (actionDescription) => `${actionDescription} umgekehrt`,
|
|
74
160
|
elements: 'Elemente',
|
|
75
161
|
erasedNoElements: 'Nichts entfernt',
|
|
76
162
|
duplicatedNoElements: 'Nichts dupliziert',
|
|
77
163
|
rotatedBy: (degrees) => `${Math.abs(degrees)} Grad ${degrees < 0 ? 'im Uhrzeigersinn' : 'gegen den Uhrzeigersinn'} gedreht`,
|
|
78
|
-
movedLeft: '
|
|
79
|
-
movedUp: '
|
|
80
|
-
movedDown: '
|
|
81
|
-
movedRight: '
|
|
164
|
+
movedLeft: 'Nach links bewegt',
|
|
165
|
+
movedUp: 'Nach oben bewegt',
|
|
166
|
+
movedDown: 'Nach unten bewegt',
|
|
167
|
+
movedRight: 'Nach rechts bewegt',
|
|
82
168
|
zoomedOut: 'Ansicht verkleinert',
|
|
83
169
|
zoomedIn: 'Ansicht vergrößert',
|
|
170
|
+
andNMoreCommands: (count) => `Und noch ${count} weitere Befehle.`,
|
|
84
171
|
selectedElements: (count) => `${count} Element${1 === count ? '' : 'e'} ausgewählt`,
|
|
172
|
+
unlabeledImageNode: 'Bild ohne Label',
|
|
85
173
|
stroke: 'Strich',
|
|
86
174
|
svgObject: 'SVG-Objekt',
|
|
175
|
+
emptyBackground: 'Leerer Hintergrund',
|
|
176
|
+
gridBackground: 'Hintergrundraster',
|
|
177
|
+
filledBackgroundWithColor: (color) => `Gefüllter Hintergrund (${color})`,
|
|
87
178
|
text: (text) => `Text-Objekt: ${text}`,
|
|
179
|
+
imageNode: (label) => `Bild: ${label}`,
|
|
180
|
+
restyledElement: (elementDescription) => `${elementDescription} umgestaltet`,
|
|
88
181
|
pathNodeCount: (count) => `Es gibt ${count} sichtbare Pfad-Objekte.`,
|
|
89
182
|
textNodeCount: (count) => `Es gibt ${count} sichtbare Text-Knotenpunkte.`,
|
|
90
|
-
textNode: (content) => `Text: ${content}`,
|
|
91
183
|
imageNodeCount: (nodeCount) => `Es gibt ${nodeCount} sichtbare Bild-Knoten.`,
|
|
92
|
-
|
|
93
|
-
unlabeledImageNode: 'Bild ohne Label',
|
|
184
|
+
textNode: (content) => `Text: ${content}`,
|
|
94
185
|
rerenderAsText: 'Als Text darstellen',
|
|
95
186
|
accessibilityInputInstructions: 'Drücke ‚t‘, um den Inhalt des Ansichtsfensters als Text zu lesen. Verwende die Pfeiltasten, um die Ansicht zu verschieben, und klicke und ziehe, um Striche zu zeichnen. Drücke ‚w‘ zum Vergrößern und ‚s‘ zum Verkleinern der Ansicht.',
|
|
96
|
-
loading: (percentage) =>
|
|
97
|
-
doneLoading: 'Laden fertig',
|
|
187
|
+
loading: (percentage) => `${percentage}% geladen...`,
|
|
98
188
|
imageEditor: 'Bild-Editor',
|
|
189
|
+
doneLoading: 'Fertig geladen',
|
|
99
190
|
undoAnnouncement: (commandDescription) => `${commandDescription} rückgängig gemacht`,
|
|
100
191
|
redoAnnouncement: (commandDescription) => `${commandDescription} wiederholt`,
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
backgroundColor: 'Hintergrundfarbe: ',
|
|
104
|
-
imageWidthOption: 'Breite: ',
|
|
105
|
-
imageHeightOption: 'Höhe: ',
|
|
106
|
-
useGridOption: 'Gitter: ',
|
|
107
|
-
toggleOverflow: 'Mehr',
|
|
108
|
-
selectAllTool: 'Alle auswählen',
|
|
109
|
-
soundExplorer: 'Klangbasierte Bilderkundung',
|
|
110
|
-
disableAccessibilityExploreTool: 'Deaktiviere klangbasierte Erkundung',
|
|
111
|
-
enableAccessibilityExploreTool: 'Aktiviere klangbasierte Erkundung',
|
|
112
|
-
unionOf: (actionDescription, actionCount) => `Vereinigung: ${actionCount} ${actionDescription}`,
|
|
113
|
-
emptyBackground: 'Leerer Hintergrund',
|
|
114
|
-
filledBackgroundWithColor: (color) => `Gefüllter Hintergrund (${color})`,
|
|
115
|
-
restyledElement: (elementDescription) => `${elementDescription} umgestaltet`,
|
|
192
|
+
softwareLibraries: 'Bibliotheken',
|
|
193
|
+
developerInformation: 'Enwicklerinformation',
|
|
116
194
|
};
|
|
117
195
|
export default localization;
|
|
@@ -14,15 +14,13 @@ const makeDraggable = (dragElement, options) => {
|
|
|
14
14
|
if (dragElements.includes(element)) {
|
|
15
15
|
return true;
|
|
16
16
|
}
|
|
17
|
-
// Some
|
|
18
|
-
|
|
19
|
-
const undraggableElementTypes = ['INPUT', 'SELECT', 'IMG'];
|
|
17
|
+
// Some elements need to handle drag events to avoid breaking the UI:
|
|
18
|
+
const undraggableElementTypes = ['INPUT', 'SELECT'];
|
|
20
19
|
let hasSuitableAncestors = false;
|
|
21
20
|
let ancestor = element.parentElement;
|
|
22
21
|
while (ancestor) {
|
|
23
|
-
if (undraggableElementTypes.includes(ancestor.tagName))
|
|
22
|
+
if (undraggableElementTypes.includes(ancestor.tagName))
|
|
24
23
|
break;
|
|
25
|
-
}
|
|
26
24
|
if (dragElements.includes(ancestor)) {
|
|
27
25
|
hasSuitableAncestors = true;
|
|
28
26
|
break;
|
|
@@ -31,6 +29,30 @@ const makeDraggable = (dragElement, options) => {
|
|
|
31
29
|
}
|
|
32
30
|
return !undraggableElementTypes.includes(element.tagName) && hasSuitableAncestors;
|
|
33
31
|
};
|
|
32
|
+
const canScrollAncestorVertically = (element, direction) => {
|
|
33
|
+
if (!(element instanceof HTMLElement))
|
|
34
|
+
return false;
|
|
35
|
+
let ancestor = element;
|
|
36
|
+
// Only consider ancestors within the draggable element: This should not
|
|
37
|
+
// consider the main document scroll element:
|
|
38
|
+
while (ancestor && !dragElements.includes(ancestor)) {
|
|
39
|
+
// Workaround: Certain content can't scroll completely to the start/end
|
|
40
|
+
// (e.g. paged lists). To work around this, define a small, non-zero
|
|
41
|
+
// tolerance. Within this tolerance, the element is considered "completely
|
|
42
|
+
// scrolled":
|
|
43
|
+
const epsilon = 10;
|
|
44
|
+
if (ancestor.scrollHeight > ancestor.clientHeight + epsilon) {
|
|
45
|
+
const canScrollUp = ancestor.scrollTop > epsilon;
|
|
46
|
+
const canScrollDown = ancestor.scrollTop + ancestor.clientHeight < ancestor.scrollHeight - epsilon;
|
|
47
|
+
if (direction.y < 0 && canScrollDown)
|
|
48
|
+
return true;
|
|
49
|
+
if (direction.y > 0 && canScrollUp)
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
ancestor = ancestor.parentElement;
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
};
|
|
34
56
|
const removeEventListenerCallbacks = [];
|
|
35
57
|
const addEventListener = (listenerType, listener, options) => {
|
|
36
58
|
dragElement.addEventListener(listenerType, listener, options);
|
|
@@ -42,8 +64,8 @@ const makeDraggable = (dragElement, options) => {
|
|
|
42
64
|
// Returns whether the current (or if no current, **the last**) gesture is roughly a click.
|
|
43
65
|
// Because this can be called **after** a gesture has just ended, it should not require
|
|
44
66
|
// the gesture to be in progress.
|
|
45
|
-
const isRoughlyClick = () => {
|
|
46
|
-
return Math.hypot(
|
|
67
|
+
const isRoughlyClick = (currentX, currentY) => {
|
|
68
|
+
return Math.hypot(currentX - startX, currentY - startY) < clickThreshold;
|
|
47
69
|
};
|
|
48
70
|
let startedDragging = false;
|
|
49
71
|
addEventListener('pointerdown', (event) => {
|
|
@@ -70,7 +92,7 @@ const makeDraggable = (dragElement, options) => {
|
|
|
70
92
|
capturedPointerId = null;
|
|
71
93
|
}
|
|
72
94
|
options.onDragEnd({
|
|
73
|
-
roughlyClick: isRoughlyClick(),
|
|
95
|
+
roughlyClick: isRoughlyClick(lastX, lastY),
|
|
74
96
|
endTimestamp: performance.now(),
|
|
75
97
|
displacement: Vec2.of(lastX - startX, lastY - startY),
|
|
76
98
|
});
|
|
@@ -88,18 +110,19 @@ const makeDraggable = (dragElement, options) => {
|
|
|
88
110
|
onGestureEnd(event);
|
|
89
111
|
return undefined;
|
|
90
112
|
}
|
|
91
|
-
// Only capture after motion -- capturing early prevents click events in Chrome.
|
|
92
|
-
if (capturedPointerId === null && !isRoughlyClick()) {
|
|
93
|
-
dragElement.setPointerCapture(event.pointerId);
|
|
94
|
-
capturedPointerId = event.pointerId;
|
|
95
|
-
}
|
|
96
113
|
const x = event.clientX;
|
|
97
114
|
const y = event.clientY;
|
|
115
|
+
const isClick = isRoughlyClick(x, y);
|
|
98
116
|
const dx = x - lastX;
|
|
99
117
|
const dy = y - lastY;
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
118
|
+
const deltaToStart = Vec2.of(x - startX, y - startY);
|
|
119
|
+
const isScroll = () => canScrollAncestorVertically(event.target, deltaToStart);
|
|
120
|
+
if (startedDragging || (!isClick && !isScroll())) {
|
|
121
|
+
options.onDrag(dx, dy, deltaToStart);
|
|
122
|
+
if (capturedPointerId === null) {
|
|
123
|
+
dragElement.setPointerCapture(event.pointerId);
|
|
124
|
+
capturedPointerId = event.pointerId;
|
|
125
|
+
}
|
|
103
126
|
lastX = x;
|
|
104
127
|
lastY = y;
|
|
105
128
|
startedDragging = true;
|
|
@@ -114,6 +137,13 @@ const makeDraggable = (dragElement, options) => {
|
|
|
114
137
|
});
|
|
115
138
|
addEventListener('pointerup', onGestureEnd);
|
|
116
139
|
addEventListener('pointercancel', onGestureEnd);
|
|
140
|
+
// In Chrome (as of Dec 2025), .preventDefault needs to be called from ontouchmove
|
|
141
|
+
// to allow the drag event to continue to be handled.
|
|
142
|
+
addEventListener('touchmove', (event) => {
|
|
143
|
+
if (startedDragging && event.touches.length > 0) {
|
|
144
|
+
event.preventDefault();
|
|
145
|
+
}
|
|
146
|
+
});
|
|
117
147
|
return {
|
|
118
148
|
removeListeners: () => {
|
|
119
149
|
for (const removeListenerCallback of removeEventListenerCallbacks) {
|
package/dist/mjs/version.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "js-draw",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.33.0",
|
|
4
4
|
"description": "Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript. ",
|
|
5
5
|
"types": "./dist/mjs/lib.d.ts",
|
|
6
6
|
"main": "./dist/cjs/lib.js",
|
|
@@ -64,11 +64,11 @@
|
|
|
64
64
|
"postpack": "ts-node tools/copyREADME.ts revert"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@js-draw/math": "^1.
|
|
67
|
+
"@js-draw/math": "^1.33.0",
|
|
68
68
|
"@melloware/coloris": "0.22.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@js-draw/build-tool": "^1.
|
|
71
|
+
"@js-draw/build-tool": "^1.33.0",
|
|
72
72
|
"@types/jest": "29.5.5",
|
|
73
73
|
"@types/jsdom": "21.1.3"
|
|
74
74
|
},
|
|
@@ -86,5 +86,5 @@
|
|
|
86
86
|
"freehand",
|
|
87
87
|
"svg"
|
|
88
88
|
],
|
|
89
|
-
"gitHead": "
|
|
89
|
+
"gitHead": "8f427476d052d5a3276aa5dbdac535f0d5f3fcd3"
|
|
90
90
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Repeat for specificity.
|
|
2
2
|
// TODO(v2): Refactor everything to use RCSS.
|
|
3
3
|
:root .toolbar-snapped-scroll-list.toolbar-snapped-scroll-list.toolbar-snapped-scroll-list {
|
|
4
|
-
height: min(
|
|
4
|
+
height: min(140px, 50vh);
|
|
5
5
|
position: relative;
|
|
6
6
|
display: flex;
|
|
7
7
|
align-items: center;
|