@jsenv/dom 0.6.1 → 0.7.1
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/jsenv_dom.js +339 -327
- package/package.json +2 -4
- package/index.js +0 -124
- package/src/attr/add_attribute_effect.js +0 -93
- package/src/attr/attributes.js +0 -32
- package/src/color/color_constrast.js +0 -69
- package/src/color/color_parsing.js +0 -319
- package/src/color/color_scheme.js +0 -28
- package/src/color/pick_light_or_dark.js +0 -34
- package/src/color/resolve_css_color.js +0 -60
- package/src/demos/3_columns_resize_demo.html +0 -84
- package/src/demos/3_rows_resize_demo.html +0 -89
- package/src/demos/aside_and_main_demo.html +0 -93
- package/src/demos/coordinates_demo.html +0 -450
- package/src/demos/document_autoscroll_demo.html +0 -517
- package/src/demos/drag_gesture_constraints_demo.html +0 -701
- package/src/demos/drag_gesture_demo.html +0 -1047
- package/src/demos/drag_gesture_element_to_impact_demo.html +0 -445
- package/src/demos/drag_reference_element_demo.html +0 -480
- package/src/demos/flex_details_set_demo.html +0 -302
- package/src/demos/flex_details_set_demo_2.html +0 -315
- package/src/demos/visible_rect_demo.html +0 -525
- package/src/element_signature.js +0 -100
- package/src/interaction/drag/constraint_feedback_line.js +0 -92
- package/src/interaction/drag/drag_constraint.js +0 -659
- package/src/interaction/drag/drag_debug_markers.js +0 -635
- package/src/interaction/drag/drag_element_positioner.js +0 -382
- package/src/interaction/drag/drag_gesture.js +0 -566
- package/src/interaction/drag/drag_resize_demo.html +0 -571
- package/src/interaction/drag/drag_to_move.js +0 -301
- package/src/interaction/drag/drag_to_resize_gesture.js +0 -68
- package/src/interaction/drag/drop_target_detection.js +0 -148
- package/src/interaction/drag/sticky_frontiers.js +0 -160
- package/src/interaction/event_marker.js +0 -14
- package/src/interaction/focus/active_element.js +0 -33
- package/src/interaction/focus/arrow_navigation.js +0 -599
- package/src/interaction/focus/element_is_focusable.js +0 -57
- package/src/interaction/focus/element_visibility.js +0 -111
- package/src/interaction/focus/find_focusable.js +0 -21
- package/src/interaction/focus/focus_group.js +0 -91
- package/src/interaction/focus/focus_group_registry.js +0 -12
- package/src/interaction/focus/focus_nav.js +0 -12
- package/src/interaction/focus/focus_nav_event_marker.js +0 -14
- package/src/interaction/focus/focus_trap.js +0 -105
- package/src/interaction/focus/tab_navigation.js +0 -128
- package/src/interaction/focus/tests/focus_group_skip_tab_test.html +0 -206
- package/src/interaction/focus/tests/tree_focus_test.html +0 -304
- package/src/interaction/focus/tests/tree_focus_test.jsx +0 -261
- package/src/interaction/focus/tests/tree_focus_test_preact.html +0 -13
- package/src/interaction/isolate_interactions.js +0 -161
- package/src/interaction/keyboard.js +0 -26
- package/src/interaction/scroll/capture_scroll.js +0 -47
- package/src/interaction/scroll/is_scrollable.js +0 -159
- package/src/interaction/scroll/scroll_container.js +0 -110
- package/src/interaction/scroll/scroll_trap.js +0 -44
- package/src/interaction/scroll/scrollbar_size.js +0 -20
- package/src/interaction/scroll/wheel_through.js +0 -138
- package/src/iterable_weak_set.js +0 -66
- package/src/position/dom_coords.js +0 -340
- package/src/position/offset_parent.js +0 -15
- package/src/position/position_fixed.js +0 -15
- package/src/position/position_sticky.js +0 -213
- package/src/position/sticky_rect.js +0 -79
- package/src/position/visible_rect.js +0 -486
- package/src/pub_sub.js +0 -31
- package/src/size/can_take_size.js +0 -11
- package/src/size/details_content_full_height.js +0 -63
- package/src/size/flex_details_set.js +0 -974
- package/src/size/get_available_height.js +0 -22
- package/src/size/get_available_width.js +0 -22
- package/src/size/get_border_sizes.js +0 -14
- package/src/size/get_height.js +0 -4
- package/src/size/get_inner_height.js +0 -15
- package/src/size/get_inner_width.js +0 -15
- package/src/size/get_margin_sizes.js +0 -10
- package/src/size/get_max_height.js +0 -57
- package/src/size/get_max_width.js +0 -47
- package/src/size/get_min_height.js +0 -14
- package/src/size/get_min_width.js +0 -14
- package/src/size/get_padding_sizes.js +0 -10
- package/src/size/get_width.js +0 -4
- package/src/size/hooks/use_available_height.js +0 -27
- package/src/size/hooks/use_available_width.js +0 -27
- package/src/size/hooks/use_max_height.js +0 -10
- package/src/size/hooks/use_max_width.js +0 -10
- package/src/size/hooks/use_resize_status.js +0 -62
- package/src/size/resize.js +0 -695
- package/src/size/resolve_css_size.js +0 -32
- package/src/style/dom_styles.js +0 -97
- package/src/style/style_composition.js +0 -121
- package/src/style/style_controller.js +0 -345
- package/src/style/style_default.js +0 -153
- package/src/style/style_default_demo.html +0 -128
- package/src/style/style_parsing.js +0 -375
- package/src/transition/demos/animation_resumption_test.xhtml +0 -500
- package/src/transition/demos/height_toggle_test.xhtml +0 -515
- package/src/transition/dom_transition.js +0 -254
- package/src/transition/easing.js +0 -48
- package/src/transition/group_transition.js +0 -261
- package/src/transition/transform_style_parser.js +0 -32
- package/src/transition/transition_playback.js +0 -366
- package/src/transition/transition_timeline.js +0 -79
- package/src/traversal.js +0 -247
- package/src/ui_transition/demos/content_states_transition_demo.html +0 -628
- package/src/ui_transition/demos/smooth_height_transition_demo.html +0 -149
- package/src/ui_transition/demos/transition_testing.html +0 -354
- package/src/ui_transition/ui_transition.js +0 -1470
- package/src/utils.js +0 -69
- package/src/value_effect.js +0 -35
|
@@ -1,1047 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Drag Gesture Demo - Multiple Cases</title>
|
|
7
|
-
<style>
|
|
8
|
-
body {
|
|
9
|
-
margin: 0;
|
|
10
|
-
padding: 20px;
|
|
11
|
-
font-family: Arial, sans-serif;
|
|
12
|
-
background: #f0f0f0;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.demo-section {
|
|
16
|
-
margin: 40px auto;
|
|
17
|
-
max-width: 800px;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.demo-title {
|
|
21
|
-
background: white;
|
|
22
|
-
padding: 15px 20px;
|
|
23
|
-
border-radius: 8px 8px 0 0;
|
|
24
|
-
border-bottom: 2px solid #333;
|
|
25
|
-
margin: 0;
|
|
26
|
-
font-size: 18px;
|
|
27
|
-
font-weight: bold;
|
|
28
|
-
color: #333;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.container {
|
|
32
|
-
width: 400px;
|
|
33
|
-
height: 200px;
|
|
34
|
-
background: white;
|
|
35
|
-
overflow: auto;
|
|
36
|
-
overscroll-behavior: contain;
|
|
37
|
-
position: relative;
|
|
38
|
-
z-index: 10;
|
|
39
|
-
margin: 0 auto;
|
|
40
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
41
|
-
border-radius: 4px;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/* Horizontal scrollbar only - content wider but same height */
|
|
45
|
-
.horizontal-content {
|
|
46
|
-
width: 600px; /* Wider than container = horizontal scrollbar */
|
|
47
|
-
height: 180px; /* Same height as container = no vertical scrollbar */
|
|
48
|
-
background: linear-gradient(
|
|
49
|
-
90deg,
|
|
50
|
-
transparent 99px,
|
|
51
|
-
#ddd 100px,
|
|
52
|
-
#ddd 101px,
|
|
53
|
-
transparent 102px
|
|
54
|
-
);
|
|
55
|
-
background-size: 100px 100px;
|
|
56
|
-
position: relative;
|
|
57
|
-
z-index: 9;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/* Both scrollbars - content wider and taller */
|
|
61
|
-
.both-content {
|
|
62
|
-
width: 600px; /* Wider than container = horizontal scrollbar */
|
|
63
|
-
height: 400px; /* Taller than container = vertical scrollbar */
|
|
64
|
-
background:
|
|
65
|
-
linear-gradient(
|
|
66
|
-
90deg,
|
|
67
|
-
transparent 99px,
|
|
68
|
-
#ddd 100px,
|
|
69
|
-
#ddd 101px,
|
|
70
|
-
transparent 102px
|
|
71
|
-
),
|
|
72
|
-
linear-gradient(
|
|
73
|
-
transparent 99px,
|
|
74
|
-
#ddd 100px,
|
|
75
|
-
#ddd 101px,
|
|
76
|
-
transparent 102px
|
|
77
|
-
);
|
|
78
|
-
background-size: 100px 100px;
|
|
79
|
-
position: relative;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.draggable-rectangle {
|
|
83
|
-
width: 80px;
|
|
84
|
-
height: 60px;
|
|
85
|
-
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
86
|
-
border: 2px solid #333;
|
|
87
|
-
border-radius: 8px;
|
|
88
|
-
position: absolute;
|
|
89
|
-
top: 50px;
|
|
90
|
-
left: 50px;
|
|
91
|
-
cursor: grab;
|
|
92
|
-
display: flex;
|
|
93
|
-
align-items: center;
|
|
94
|
-
justify-content: center;
|
|
95
|
-
color: white;
|
|
96
|
-
font-weight: bold;
|
|
97
|
-
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
|
|
98
|
-
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
|
99
|
-
transition: box-shadow 0.2s ease;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
.draggable-rectangle:hover {
|
|
103
|
-
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
.draggable-rectangle[data-dragging] {
|
|
107
|
-
cursor: grabbing;
|
|
108
|
-
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.4);
|
|
109
|
-
z-index: 1000;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/* Solid obstacles that cannot be traversed */
|
|
113
|
-
.solid-obstacle {
|
|
114
|
-
position: absolute;
|
|
115
|
-
background: #e91e63;
|
|
116
|
-
border-radius: 4px;
|
|
117
|
-
display: flex;
|
|
118
|
-
align-items: center;
|
|
119
|
-
justify-content: center;
|
|
120
|
-
color: white;
|
|
121
|
-
font-weight: bold;
|
|
122
|
-
font-size: 12px;
|
|
123
|
-
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
|
|
124
|
-
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
|
|
125
|
-
border: 2px solid #c2185b;
|
|
126
|
-
z-index: 100;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
#obstacleContainer {
|
|
130
|
-
width: 600px;
|
|
131
|
-
height: 400px;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/* Content area for Case 3 with obstacles */
|
|
135
|
-
.obstacle-content {
|
|
136
|
-
width: 1600px; /* Wider than container = horizontal scrollbar */
|
|
137
|
-
height: 800px; /* Taller than container = both scrollbars */
|
|
138
|
-
background:
|
|
139
|
-
linear-gradient(
|
|
140
|
-
90deg,
|
|
141
|
-
transparent 99px,
|
|
142
|
-
#ddd 100px,
|
|
143
|
-
#ddd 101px,
|
|
144
|
-
transparent 102px
|
|
145
|
-
),
|
|
146
|
-
linear-gradient(
|
|
147
|
-
0deg,
|
|
148
|
-
transparent 99px,
|
|
149
|
-
#ddd 100px,
|
|
150
|
-
#ddd 101px,
|
|
151
|
-
transparent 102px
|
|
152
|
-
);
|
|
153
|
-
position: relative;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
.info {
|
|
157
|
-
max-width: 800px;
|
|
158
|
-
margin: 0 auto;
|
|
159
|
-
padding: 20px;
|
|
160
|
-
background: white;
|
|
161
|
-
border-radius: 8px;
|
|
162
|
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
.info h1 {
|
|
166
|
-
margin-top: 0;
|
|
167
|
-
color: #333;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
.info ul {
|
|
171
|
-
line-height: 1.6;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
.debug-toggle {
|
|
175
|
-
margin: 20px auto;
|
|
176
|
-
text-align: center;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
.debug-toggle label {
|
|
180
|
-
display: inline-flex;
|
|
181
|
-
align-items: center;
|
|
182
|
-
gap: 8px;
|
|
183
|
-
font-size: 14px;
|
|
184
|
-
color: #333;
|
|
185
|
-
cursor: pointer;
|
|
186
|
-
background: white;
|
|
187
|
-
padding: 10px 15px;
|
|
188
|
-
border-radius: 4px;
|
|
189
|
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
190
|
-
transition: all 0.2s ease;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
.debug-toggle label:hover {
|
|
194
|
-
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
.debug-toggle input[type="checkbox"] {
|
|
198
|
-
width: 18px;
|
|
199
|
-
height: 18px;
|
|
200
|
-
cursor: pointer;
|
|
201
|
-
}
|
|
202
|
-
</style>
|
|
203
|
-
</head>
|
|
204
|
-
<body>
|
|
205
|
-
<div class="info">
|
|
206
|
-
<h1>Drag Gesture Demo - Scrollbar Cases</h1>
|
|
207
|
-
<p>
|
|
208
|
-
This demo tests drag gesture auto-scroll with different scrollbar
|
|
209
|
-
configurations:
|
|
210
|
-
</p>
|
|
211
|
-
<ul>
|
|
212
|
-
<li>
|
|
213
|
-
<strong>Drag rectangles in any direction</strong> - they're not
|
|
214
|
-
restricted to scroll direction
|
|
215
|
-
</li>
|
|
216
|
-
<li>
|
|
217
|
-
<strong>Auto-scroll triggers</strong> when you drag near container
|
|
218
|
-
edges
|
|
219
|
-
</li>
|
|
220
|
-
<li>
|
|
221
|
-
<strong>Case 1:</strong> Only horizontal scrollbar visible (content
|
|
222
|
-
wider, same height)
|
|
223
|
-
</li>
|
|
224
|
-
<li>
|
|
225
|
-
<strong>Case 2:</strong> Both scrollbars visible (content wider and
|
|
226
|
-
taller)
|
|
227
|
-
</li>
|
|
228
|
-
<li>
|
|
229
|
-
<strong>Case 3:</strong> Solid obstacles - dragged element cannot
|
|
230
|
-
overlap with fixed objects
|
|
231
|
-
</li>
|
|
232
|
-
<li>
|
|
233
|
-
<strong>Visual debug markers</strong> show boundaries and scroll areas
|
|
234
|
-
</li>
|
|
235
|
-
</ul>
|
|
236
|
-
</div>
|
|
237
|
-
|
|
238
|
-
<!-- Case 1: Only Horizontal Scrollbar -->
|
|
239
|
-
<div class="demo-section">
|
|
240
|
-
<h2 class="demo-title">
|
|
241
|
-
Case 1: Only Horizontal Scrollbar (content wider, same height)
|
|
242
|
-
</h2>
|
|
243
|
-
<div
|
|
244
|
-
style="
|
|
245
|
-
display: flex;
|
|
246
|
-
gap: 20px;
|
|
247
|
-
align-items: flex-start;
|
|
248
|
-
justify-content: center;
|
|
249
|
-
"
|
|
250
|
-
>
|
|
251
|
-
<div class="container" id="horizontalContainer">
|
|
252
|
-
<div class="horizontal-content">
|
|
253
|
-
<div
|
|
254
|
-
class="draggable-rectangle"
|
|
255
|
-
id="horizontalRectangle"
|
|
256
|
-
style="left: 100px"
|
|
257
|
-
>
|
|
258
|
-
DRAG ME
|
|
259
|
-
</div>
|
|
260
|
-
</div>
|
|
261
|
-
</div>
|
|
262
|
-
|
|
263
|
-
<!-- Programmatic Controls for Case 1 -->
|
|
264
|
-
<div
|
|
265
|
-
style="
|
|
266
|
-
background: white;
|
|
267
|
-
padding: 15px;
|
|
268
|
-
border-radius: 6px;
|
|
269
|
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
270
|
-
min-width: 280px;
|
|
271
|
-
position: relative;
|
|
272
|
-
z-index: 10;
|
|
273
|
-
"
|
|
274
|
-
>
|
|
275
|
-
<h4 style="margin: 0 0 10px 0; font-size: 14px; color: #333">
|
|
276
|
-
Programmatic Controls
|
|
277
|
-
</h4>
|
|
278
|
-
<div style="display: flex; flex-direction: column; gap: 8px">
|
|
279
|
-
<button
|
|
280
|
-
id="grabBtn1"
|
|
281
|
-
style="
|
|
282
|
-
padding: 8px 12px;
|
|
283
|
-
background: #4caf50;
|
|
284
|
-
color: white;
|
|
285
|
-
border: none;
|
|
286
|
-
border-radius: 3px;
|
|
287
|
-
cursor: pointer;
|
|
288
|
-
font-size: 12px;
|
|
289
|
-
"
|
|
290
|
-
>
|
|
291
|
-
Grab
|
|
292
|
-
</button>
|
|
293
|
-
<button
|
|
294
|
-
id="dragLeftBtn1"
|
|
295
|
-
disabled
|
|
296
|
-
style="
|
|
297
|
-
padding: 8px 12px;
|
|
298
|
-
background: #9c27b0;
|
|
299
|
-
color: white;
|
|
300
|
-
border: none;
|
|
301
|
-
border-radius: 3px;
|
|
302
|
-
cursor: pointer;
|
|
303
|
-
font-size: 12px;
|
|
304
|
-
opacity: 0.5;
|
|
305
|
-
"
|
|
306
|
-
>
|
|
307
|
-
Drag Left
|
|
308
|
-
</button>
|
|
309
|
-
<button
|
|
310
|
-
id="dragRightBtn1"
|
|
311
|
-
disabled
|
|
312
|
-
style="
|
|
313
|
-
padding: 8px 12px;
|
|
314
|
-
background: #2196f3;
|
|
315
|
-
color: white;
|
|
316
|
-
border: none;
|
|
317
|
-
border-radius: 3px;
|
|
318
|
-
cursor: pointer;
|
|
319
|
-
font-size: 12px;
|
|
320
|
-
opacity: 0.5;
|
|
321
|
-
"
|
|
322
|
-
>
|
|
323
|
-
Drag Right
|
|
324
|
-
</button>
|
|
325
|
-
<button
|
|
326
|
-
id="dragUpBtn1"
|
|
327
|
-
disabled
|
|
328
|
-
style="
|
|
329
|
-
padding: 8px 12px;
|
|
330
|
-
background: #607d8b;
|
|
331
|
-
color: white;
|
|
332
|
-
border: none;
|
|
333
|
-
border-radius: 3px;
|
|
334
|
-
cursor: pointer;
|
|
335
|
-
font-size: 12px;
|
|
336
|
-
opacity: 0.5;
|
|
337
|
-
"
|
|
338
|
-
>
|
|
339
|
-
Drag Up
|
|
340
|
-
</button>
|
|
341
|
-
<button
|
|
342
|
-
id="dragDownBtn1"
|
|
343
|
-
disabled
|
|
344
|
-
style="
|
|
345
|
-
padding: 8px 12px;
|
|
346
|
-
background: #ff9800;
|
|
347
|
-
color: white;
|
|
348
|
-
border: none;
|
|
349
|
-
border-radius: 3px;
|
|
350
|
-
cursor: pointer;
|
|
351
|
-
font-size: 12px;
|
|
352
|
-
opacity: 0.5;
|
|
353
|
-
"
|
|
354
|
-
>
|
|
355
|
-
Drag Down
|
|
356
|
-
</button>
|
|
357
|
-
<button
|
|
358
|
-
id="releaseBtn1"
|
|
359
|
-
disabled
|
|
360
|
-
style="
|
|
361
|
-
padding: 8px 12px;
|
|
362
|
-
background: #f44336;
|
|
363
|
-
color: white;
|
|
364
|
-
border: none;
|
|
365
|
-
border-radius: 3px;
|
|
366
|
-
cursor: pointer;
|
|
367
|
-
font-size: 12px;
|
|
368
|
-
opacity: 0.5;
|
|
369
|
-
"
|
|
370
|
-
>
|
|
371
|
-
Release
|
|
372
|
-
</button>
|
|
373
|
-
</div>
|
|
374
|
-
<div
|
|
375
|
-
id="status1"
|
|
376
|
-
style="
|
|
377
|
-
margin-top: 10px;
|
|
378
|
-
padding: 8px;
|
|
379
|
-
background: #f9f9f9;
|
|
380
|
-
border-radius: 3px;
|
|
381
|
-
font-family: monospace;
|
|
382
|
-
font-size: 10px;
|
|
383
|
-
color: #666;
|
|
384
|
-
"
|
|
385
|
-
>
|
|
386
|
-
Ready
|
|
387
|
-
</div>
|
|
388
|
-
</div>
|
|
389
|
-
</div>
|
|
390
|
-
</div>
|
|
391
|
-
|
|
392
|
-
<!-- Case 2: Both Scrollbars -->
|
|
393
|
-
<div class="demo-section">
|
|
394
|
-
<h2 class="demo-title">
|
|
395
|
-
Case 2: Both Scrollbars (content wider and taller)
|
|
396
|
-
</h2>
|
|
397
|
-
<div
|
|
398
|
-
style="
|
|
399
|
-
display: flex;
|
|
400
|
-
gap: 20px;
|
|
401
|
-
align-items: flex-start;
|
|
402
|
-
justify-content: center;
|
|
403
|
-
"
|
|
404
|
-
>
|
|
405
|
-
<div class="container" id="bothContainer">
|
|
406
|
-
<div class="both-content">
|
|
407
|
-
<div style="position: relative; left: 50px">
|
|
408
|
-
<!-- position: relative here to make things more complex and ensure it still work -->
|
|
409
|
-
<div class="draggable-rectangle" id="bothRectangle">DRAG ME</div>
|
|
410
|
-
</div>
|
|
411
|
-
</div>
|
|
412
|
-
</div>
|
|
413
|
-
|
|
414
|
-
<!-- Programmatic Controls for Case 2 -->
|
|
415
|
-
<div
|
|
416
|
-
style="
|
|
417
|
-
background: white;
|
|
418
|
-
padding: 15px;
|
|
419
|
-
border-radius: 6px;
|
|
420
|
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
421
|
-
min-width: 280px;
|
|
422
|
-
position: relative;
|
|
423
|
-
z-index: 10;
|
|
424
|
-
"
|
|
425
|
-
>
|
|
426
|
-
<h4 style="margin: 0 0 10px 0; font-size: 14px; color: #333">
|
|
427
|
-
Programmatic Controls
|
|
428
|
-
</h4>
|
|
429
|
-
<div style="display: flex; flex-direction: column; gap: 8px">
|
|
430
|
-
<button
|
|
431
|
-
id="grabBtn2"
|
|
432
|
-
style="
|
|
433
|
-
padding: 8px 12px;
|
|
434
|
-
background: #4caf50;
|
|
435
|
-
color: white;
|
|
436
|
-
border: none;
|
|
437
|
-
border-radius: 3px;
|
|
438
|
-
cursor: pointer;
|
|
439
|
-
font-size: 12px;
|
|
440
|
-
"
|
|
441
|
-
>
|
|
442
|
-
Grab
|
|
443
|
-
</button>
|
|
444
|
-
<button
|
|
445
|
-
id="dragLeftBtn2"
|
|
446
|
-
disabled
|
|
447
|
-
style="
|
|
448
|
-
padding: 8px 12px;
|
|
449
|
-
background: #9c27b0;
|
|
450
|
-
color: white;
|
|
451
|
-
border: none;
|
|
452
|
-
border-radius: 3px;
|
|
453
|
-
cursor: pointer;
|
|
454
|
-
font-size: 12px;
|
|
455
|
-
opacity: 0.5;
|
|
456
|
-
"
|
|
457
|
-
>
|
|
458
|
-
Drag Left
|
|
459
|
-
</button>
|
|
460
|
-
<button
|
|
461
|
-
id="dragRightBtn2"
|
|
462
|
-
disabled
|
|
463
|
-
style="
|
|
464
|
-
padding: 8px 12px;
|
|
465
|
-
background: #2196f3;
|
|
466
|
-
color: white;
|
|
467
|
-
border: none;
|
|
468
|
-
border-radius: 3px;
|
|
469
|
-
cursor: pointer;
|
|
470
|
-
font-size: 12px;
|
|
471
|
-
opacity: 0.5;
|
|
472
|
-
"
|
|
473
|
-
>
|
|
474
|
-
Drag Right
|
|
475
|
-
</button>
|
|
476
|
-
<button
|
|
477
|
-
id="dragUpBtn2"
|
|
478
|
-
disabled
|
|
479
|
-
style="
|
|
480
|
-
padding: 8px 12px;
|
|
481
|
-
background: #607d8b;
|
|
482
|
-
color: white;
|
|
483
|
-
border: none;
|
|
484
|
-
border-radius: 3px;
|
|
485
|
-
cursor: pointer;
|
|
486
|
-
font-size: 12px;
|
|
487
|
-
opacity: 0.5;
|
|
488
|
-
"
|
|
489
|
-
>
|
|
490
|
-
Drag Up
|
|
491
|
-
</button>
|
|
492
|
-
<button
|
|
493
|
-
id="dragDownBtn2"
|
|
494
|
-
disabled
|
|
495
|
-
style="
|
|
496
|
-
padding: 8px 12px;
|
|
497
|
-
background: #ff9800;
|
|
498
|
-
color: white;
|
|
499
|
-
border: none;
|
|
500
|
-
border-radius: 3px;
|
|
501
|
-
cursor: pointer;
|
|
502
|
-
font-size: 12px;
|
|
503
|
-
opacity: 0.5;
|
|
504
|
-
"
|
|
505
|
-
>
|
|
506
|
-
Drag Down
|
|
507
|
-
</button>
|
|
508
|
-
<button
|
|
509
|
-
id="releaseBtn2"
|
|
510
|
-
disabled
|
|
511
|
-
style="
|
|
512
|
-
padding: 8px 12px;
|
|
513
|
-
background: #f44336;
|
|
514
|
-
color: white;
|
|
515
|
-
border: none;
|
|
516
|
-
border-radius: 3px;
|
|
517
|
-
cursor: pointer;
|
|
518
|
-
font-size: 12px;
|
|
519
|
-
opacity: 0.5;
|
|
520
|
-
"
|
|
521
|
-
>
|
|
522
|
-
Release
|
|
523
|
-
</button>
|
|
524
|
-
</div>
|
|
525
|
-
<div
|
|
526
|
-
id="status2"
|
|
527
|
-
style="
|
|
528
|
-
margin-top: 10px;
|
|
529
|
-
padding: 8px;
|
|
530
|
-
background: #f9f9f9;
|
|
531
|
-
border-radius: 3px;
|
|
532
|
-
font-family: monospace;
|
|
533
|
-
font-size: 10px;
|
|
534
|
-
color: #666;
|
|
535
|
-
"
|
|
536
|
-
>
|
|
537
|
-
Ready
|
|
538
|
-
</div>
|
|
539
|
-
</div>
|
|
540
|
-
</div>
|
|
541
|
-
</div>
|
|
542
|
-
|
|
543
|
-
<!-- Case 3: Solid Obstacles -->
|
|
544
|
-
<div class="demo-section">
|
|
545
|
-
<h2 class="demo-title">
|
|
546
|
-
Case 3: Solid Obstacles (content with non-traversable objects)
|
|
547
|
-
</h2>
|
|
548
|
-
<div
|
|
549
|
-
style="
|
|
550
|
-
display: flex;
|
|
551
|
-
gap: 20px;
|
|
552
|
-
align-items: flex-start;
|
|
553
|
-
justify-content: center;
|
|
554
|
-
"
|
|
555
|
-
>
|
|
556
|
-
<div class="container" id="obstacleContainer">
|
|
557
|
-
<div class="obstacle-content">
|
|
558
|
-
<!-- Draggable rectangle that must respect obstacles -->
|
|
559
|
-
<div
|
|
560
|
-
class="draggable-rectangle"
|
|
561
|
-
id="obstacleRectangle"
|
|
562
|
-
style="top: 30px; left: 50px"
|
|
563
|
-
>
|
|
564
|
-
DRAG ME
|
|
565
|
-
</div>
|
|
566
|
-
|
|
567
|
-
<!-- Solid obstacles that cannot be traversed -->
|
|
568
|
-
<div
|
|
569
|
-
class="solid-obstacle"
|
|
570
|
-
data-drag-obstacle
|
|
571
|
-
style="top: 70px; left: 150px; width: 80px; height: 60px"
|
|
572
|
-
>
|
|
573
|
-
WALL A
|
|
574
|
-
</div>
|
|
575
|
-
|
|
576
|
-
<div
|
|
577
|
-
class="solid-obstacle"
|
|
578
|
-
data-drag-obstacle
|
|
579
|
-
style="top: 150px; left: 300px; width: 100px; height: 40px"
|
|
580
|
-
>
|
|
581
|
-
WALL B
|
|
582
|
-
</div>
|
|
583
|
-
|
|
584
|
-
<div
|
|
585
|
-
class="solid-obstacle"
|
|
586
|
-
data-drag-obstacle
|
|
587
|
-
style="top: 50px; left: 500px; width: 60px; height: 80px"
|
|
588
|
-
>
|
|
589
|
-
WALL C
|
|
590
|
-
</div>
|
|
591
|
-
|
|
592
|
-
<div
|
|
593
|
-
class="solid-obstacle"
|
|
594
|
-
data-drag-obstacle
|
|
595
|
-
style="
|
|
596
|
-
position: sticky;
|
|
597
|
-
top: 250px;
|
|
598
|
-
left: 200px;
|
|
599
|
-
width: 60px;
|
|
600
|
-
height: 80px;
|
|
601
|
-
"
|
|
602
|
-
>
|
|
603
|
-
WALL D
|
|
604
|
-
</div>
|
|
605
|
-
</div>
|
|
606
|
-
</div>
|
|
607
|
-
|
|
608
|
-
<!-- Programmatic Controls for Case 3 -->
|
|
609
|
-
<div
|
|
610
|
-
style="
|
|
611
|
-
background: white;
|
|
612
|
-
padding: 15px;
|
|
613
|
-
border-radius: 6px;
|
|
614
|
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
615
|
-
min-width: 280px;
|
|
616
|
-
position: relative;
|
|
617
|
-
z-index: 10;
|
|
618
|
-
"
|
|
619
|
-
>
|
|
620
|
-
<h4 style="margin: 0 0 10px 0; font-size: 14px; color: #333">
|
|
621
|
-
Programmatic Controls
|
|
622
|
-
</h4>
|
|
623
|
-
<div style="display: flex; flex-direction: column; gap: 8px">
|
|
624
|
-
<button
|
|
625
|
-
id="grabBtn3"
|
|
626
|
-
style="
|
|
627
|
-
padding: 8px 12px;
|
|
628
|
-
background: #4caf50;
|
|
629
|
-
color: white;
|
|
630
|
-
border: none;
|
|
631
|
-
border-radius: 3px;
|
|
632
|
-
cursor: pointer;
|
|
633
|
-
font-size: 12px;
|
|
634
|
-
"
|
|
635
|
-
>
|
|
636
|
-
Grab
|
|
637
|
-
</button>
|
|
638
|
-
<button
|
|
639
|
-
id="dragLeftBtn3"
|
|
640
|
-
disabled
|
|
641
|
-
style="
|
|
642
|
-
padding: 8px 12px;
|
|
643
|
-
background: #9c27b0;
|
|
644
|
-
color: white;
|
|
645
|
-
border: none;
|
|
646
|
-
border-radius: 3px;
|
|
647
|
-
cursor: pointer;
|
|
648
|
-
font-size: 12px;
|
|
649
|
-
opacity: 0.5;
|
|
650
|
-
"
|
|
651
|
-
>
|
|
652
|
-
Drag Left
|
|
653
|
-
</button>
|
|
654
|
-
<button
|
|
655
|
-
id="dragRightBtn3"
|
|
656
|
-
disabled
|
|
657
|
-
style="
|
|
658
|
-
padding: 8px 12px;
|
|
659
|
-
background: #2196f3;
|
|
660
|
-
color: white;
|
|
661
|
-
border: none;
|
|
662
|
-
border-radius: 3px;
|
|
663
|
-
cursor: pointer;
|
|
664
|
-
font-size: 12px;
|
|
665
|
-
opacity: 0.5;
|
|
666
|
-
"
|
|
667
|
-
>
|
|
668
|
-
Drag Right
|
|
669
|
-
</button>
|
|
670
|
-
<button
|
|
671
|
-
id="dragUpBtn3"
|
|
672
|
-
disabled
|
|
673
|
-
style="
|
|
674
|
-
padding: 8px 12px;
|
|
675
|
-
background: #607d8b;
|
|
676
|
-
color: white;
|
|
677
|
-
border: none;
|
|
678
|
-
border-radius: 3px;
|
|
679
|
-
cursor: pointer;
|
|
680
|
-
font-size: 12px;
|
|
681
|
-
opacity: 0.5;
|
|
682
|
-
"
|
|
683
|
-
>
|
|
684
|
-
Drag Up
|
|
685
|
-
</button>
|
|
686
|
-
<button
|
|
687
|
-
id="dragDownBtn3"
|
|
688
|
-
disabled
|
|
689
|
-
style="
|
|
690
|
-
padding: 8px 12px;
|
|
691
|
-
background: #ff9800;
|
|
692
|
-
color: white;
|
|
693
|
-
border: none;
|
|
694
|
-
border-radius: 3px;
|
|
695
|
-
cursor: pointer;
|
|
696
|
-
font-size: 12px;
|
|
697
|
-
opacity: 0.5;
|
|
698
|
-
"
|
|
699
|
-
>
|
|
700
|
-
Drag Down
|
|
701
|
-
</button>
|
|
702
|
-
<button
|
|
703
|
-
id="releaseBtn3"
|
|
704
|
-
disabled
|
|
705
|
-
style="
|
|
706
|
-
padding: 8px 12px;
|
|
707
|
-
background: #f44336;
|
|
708
|
-
color: white;
|
|
709
|
-
border: none;
|
|
710
|
-
border-radius: 3px;
|
|
711
|
-
cursor: pointer;
|
|
712
|
-
font-size: 12px;
|
|
713
|
-
opacity: 0.5;
|
|
714
|
-
"
|
|
715
|
-
>
|
|
716
|
-
Release
|
|
717
|
-
</button>
|
|
718
|
-
</div>
|
|
719
|
-
<div
|
|
720
|
-
id="status3"
|
|
721
|
-
style="
|
|
722
|
-
margin-top: 10px;
|
|
723
|
-
padding: 8px;
|
|
724
|
-
background: #f9f9f9;
|
|
725
|
-
border-radius: 3px;
|
|
726
|
-
font-family: monospace;
|
|
727
|
-
font-size: 10px;
|
|
728
|
-
color: #666;
|
|
729
|
-
"
|
|
730
|
-
>
|
|
731
|
-
Ready
|
|
732
|
-
</div>
|
|
733
|
-
</div>
|
|
734
|
-
</div>
|
|
735
|
-
</div>
|
|
736
|
-
|
|
737
|
-
<script type="module">
|
|
738
|
-
// Import the drag gesture functionality
|
|
739
|
-
// Note: You'll need to adjust the import path based on your setup
|
|
740
|
-
import { createDragToMoveGestureController } from "@jsenv/dom";
|
|
741
|
-
|
|
742
|
-
const horizontalRectangle = document.getElementById(
|
|
743
|
-
"horizontalRectangle",
|
|
744
|
-
);
|
|
745
|
-
const bothRectangle = document.getElementById("bothRectangle");
|
|
746
|
-
const obstacleRectangle = document.getElementById("obstacleRectangle");
|
|
747
|
-
|
|
748
|
-
// Programmatic controls for Case 1 (Horizontal)
|
|
749
|
-
const case1Controls = {
|
|
750
|
-
grabBtn: document.getElementById("grabBtn1"),
|
|
751
|
-
dragLeftBtn: document.getElementById("dragLeftBtn1"),
|
|
752
|
-
dragRightBtn: document.getElementById("dragRightBtn1"),
|
|
753
|
-
dragUpBtn: document.getElementById("dragUpBtn1"),
|
|
754
|
-
dragDownBtn: document.getElementById("dragDownBtn1"),
|
|
755
|
-
releaseBtn: document.getElementById("releaseBtn1"),
|
|
756
|
-
statusDiv: document.getElementById("status1"),
|
|
757
|
-
rectangle: horizontalRectangle,
|
|
758
|
-
dragGesture: null,
|
|
759
|
-
dragInstance: null,
|
|
760
|
-
};
|
|
761
|
-
|
|
762
|
-
// Programmatic controls for Case 2 (Both scrollbars)
|
|
763
|
-
const case2Controls = {
|
|
764
|
-
grabBtn: document.getElementById("grabBtn2"),
|
|
765
|
-
dragLeftBtn: document.getElementById("dragLeftBtn2"),
|
|
766
|
-
dragRightBtn: document.getElementById("dragRightBtn2"),
|
|
767
|
-
dragUpBtn: document.getElementById("dragUpBtn2"),
|
|
768
|
-
dragDownBtn: document.getElementById("dragDownBtn2"),
|
|
769
|
-
releaseBtn: document.getElementById("releaseBtn2"),
|
|
770
|
-
statusDiv: document.getElementById("status2"),
|
|
771
|
-
rectangle: bothRectangle,
|
|
772
|
-
dragGesture: null,
|
|
773
|
-
dragInstance: null,
|
|
774
|
-
};
|
|
775
|
-
|
|
776
|
-
// Programmatic controls for Case 3 (Solid obstacles)
|
|
777
|
-
const case3Controls = {
|
|
778
|
-
grabBtn: document.getElementById("grabBtn3"),
|
|
779
|
-
dragLeftBtn: document.getElementById("dragLeftBtn3"),
|
|
780
|
-
dragRightBtn: document.getElementById("dragRightBtn3"),
|
|
781
|
-
dragUpBtn: document.getElementById("dragUpBtn3"),
|
|
782
|
-
dragDownBtn: document.getElementById("dragDownBtn3"),
|
|
783
|
-
releaseBtn: document.getElementById("releaseBtn3"),
|
|
784
|
-
statusDiv: document.getElementById("status3"),
|
|
785
|
-
rectangle: obstacleRectangle,
|
|
786
|
-
dragGesture: null,
|
|
787
|
-
dragInstance: null,
|
|
788
|
-
};
|
|
789
|
-
|
|
790
|
-
function updateStatus(controls, message) {
|
|
791
|
-
controls.statusDiv.textContent = message;
|
|
792
|
-
// console.log("Programmatic Control:", message);
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
function updateButtonStates(controls, grabbed = false) {
|
|
796
|
-
controls.grabBtn.disabled = grabbed;
|
|
797
|
-
controls.dragLeftBtn.disabled = !grabbed;
|
|
798
|
-
controls.dragRightBtn.disabled = !grabbed;
|
|
799
|
-
controls.dragUpBtn.disabled = !grabbed;
|
|
800
|
-
controls.dragDownBtn.disabled = !grabbed;
|
|
801
|
-
controls.releaseBtn.disabled = !grabbed;
|
|
802
|
-
|
|
803
|
-
// Update visual disabled state
|
|
804
|
-
const buttons = [
|
|
805
|
-
controls.dragLeftBtn,
|
|
806
|
-
controls.dragRightBtn,
|
|
807
|
-
controls.dragUpBtn,
|
|
808
|
-
controls.dragDownBtn,
|
|
809
|
-
controls.releaseBtn,
|
|
810
|
-
];
|
|
811
|
-
buttons.forEach((btn) => {
|
|
812
|
-
btn.style.opacity = grabbed ? "1" : "0.5";
|
|
813
|
-
btn.style.cursor = grabbed ? "pointer" : "not-allowed";
|
|
814
|
-
});
|
|
815
|
-
|
|
816
|
-
controls.grabBtn.style.opacity = grabbed ? "0.5" : "1";
|
|
817
|
-
controls.grabBtn.style.cursor = grabbed ? "not-allowed" : "pointer";
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
function setupProgrammaticControls(controls, caseLabel) {
|
|
821
|
-
// Grab button
|
|
822
|
-
controls.grabBtn.addEventListener("click", () => {
|
|
823
|
-
if (controls.dragInstance) return;
|
|
824
|
-
|
|
825
|
-
const rectangle = controls.rectangle;
|
|
826
|
-
|
|
827
|
-
const dragOptions = {
|
|
828
|
-
backdrop: false,
|
|
829
|
-
onGrab: () => {
|
|
830
|
-
updateStatus(controls, `Grabbed ${caseLabel} programmatically`);
|
|
831
|
-
// console.log("Programmatic grab:", gestureInfo);
|
|
832
|
-
},
|
|
833
|
-
onDragStart: () => {
|
|
834
|
-
updateStatus(controls, `Started drag on ${caseLabel}`);
|
|
835
|
-
// console.log("Programmatic drag start:", gestureInfo);
|
|
836
|
-
},
|
|
837
|
-
onDrag: (gestureInfo, phase) => {
|
|
838
|
-
updateStatus(controls, `Dragging ${caseLabel} (${phase})`);
|
|
839
|
-
// console.log("Programmatic drag:", gestureInfo, phase);
|
|
840
|
-
},
|
|
841
|
-
onRelease: () => {
|
|
842
|
-
updateStatus(controls, `Released ${caseLabel}`);
|
|
843
|
-
// console.log("Programmatic release:", gestureInfo);
|
|
844
|
-
controls.dragGesture = null;
|
|
845
|
-
controls.dragInstance = null;
|
|
846
|
-
updateButtonStates(controls, false);
|
|
847
|
-
},
|
|
848
|
-
};
|
|
849
|
-
|
|
850
|
-
controls.dragGesture = createDragToMoveGestureController(dragOptions);
|
|
851
|
-
controls.dragInstance = controls.dragGesture.grab({
|
|
852
|
-
element: rectangle,
|
|
853
|
-
});
|
|
854
|
-
updateButtonStates(controls, true);
|
|
855
|
-
});
|
|
856
|
-
|
|
857
|
-
// Drag Left button
|
|
858
|
-
controls.dragLeftBtn.addEventListener("click", () => {
|
|
859
|
-
if (!controls.dragInstance) return;
|
|
860
|
-
|
|
861
|
-
// Get current gesture position and move left by 50px
|
|
862
|
-
const currentGestureInfo = controls.dragInstance.gestureInfo;
|
|
863
|
-
const newX = currentGestureInfo.moveX - 50;
|
|
864
|
-
|
|
865
|
-
updateStatus(controls, `Dragging ${caseLabel} left by 50px`);
|
|
866
|
-
controls.dragInstance.drag(newX, undefined);
|
|
867
|
-
});
|
|
868
|
-
|
|
869
|
-
// Drag Right button
|
|
870
|
-
controls.dragRightBtn.addEventListener("click", () => {
|
|
871
|
-
if (!controls.dragInstance) return;
|
|
872
|
-
|
|
873
|
-
// Get current gesture position and move right by 50px
|
|
874
|
-
const currentGestureInfo = controls.dragInstance.gestureInfo;
|
|
875
|
-
const newX = currentGestureInfo.moveX + 50;
|
|
876
|
-
|
|
877
|
-
updateStatus(controls, `Dragging ${caseLabel} right by 50px`);
|
|
878
|
-
controls.dragInstance.drag(newX, undefined);
|
|
879
|
-
});
|
|
880
|
-
|
|
881
|
-
// Drag Up button
|
|
882
|
-
controls.dragUpBtn.addEventListener("click", () => {
|
|
883
|
-
if (!controls.dragInstance) return;
|
|
884
|
-
|
|
885
|
-
// Get current gesture position and move up by 50px
|
|
886
|
-
const currentGestureInfo = controls.dragInstance.gestureInfo;
|
|
887
|
-
const newY = currentGestureInfo.moveY - 50;
|
|
888
|
-
|
|
889
|
-
updateStatus(controls, `Dragging ${caseLabel} up by 50px`);
|
|
890
|
-
controls.dragInstance.drag(undefined, newY);
|
|
891
|
-
});
|
|
892
|
-
|
|
893
|
-
// Drag Down button
|
|
894
|
-
controls.dragDownBtn.addEventListener("click", () => {
|
|
895
|
-
if (!controls.dragInstance) return;
|
|
896
|
-
|
|
897
|
-
// Get current gesture position and move down by 50px
|
|
898
|
-
const currentGestureInfo = controls.dragInstance.gestureInfo;
|
|
899
|
-
const newY = currentGestureInfo.moveY + 50;
|
|
900
|
-
|
|
901
|
-
updateStatus(controls, `Dragging ${caseLabel} down by 50px`);
|
|
902
|
-
controls.dragInstance.drag(undefined, newY);
|
|
903
|
-
});
|
|
904
|
-
|
|
905
|
-
// Release button
|
|
906
|
-
controls.releaseBtn.addEventListener("click", () => {
|
|
907
|
-
if (!controls.dragInstance) return;
|
|
908
|
-
|
|
909
|
-
updateStatus(controls, `Releasing ${caseLabel}`);
|
|
910
|
-
controls.dragInstance.release();
|
|
911
|
-
});
|
|
912
|
-
|
|
913
|
-
updateButtonStates(controls, false);
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
// Set up both sets of controls
|
|
917
|
-
setupProgrammaticControls(case1Controls, "horizontal case");
|
|
918
|
-
setupProgrammaticControls(case2Controls, "both scrollbars case");
|
|
919
|
-
setupProgrammaticControls(case3Controls, "solid obstacles case");
|
|
920
|
-
|
|
921
|
-
// Function to set up drag gesture for any rectangle
|
|
922
|
-
function setupDragGesture(rectangle) {
|
|
923
|
-
rectangle.addEventListener("pointerdown", (event) => {
|
|
924
|
-
event.preventDefault(); // prevent drag to select which would allow to scroll
|
|
925
|
-
createDragToMoveGestureController({
|
|
926
|
-
backdrop: false,
|
|
927
|
-
onGrab: () => {
|
|
928
|
-
// console.log(`${caseLabel} - Grab started`, gestureInfo);
|
|
929
|
-
},
|
|
930
|
-
onDragStart: () => {
|
|
931
|
-
// console.log(`${caseLabel} - Drag started`, gestureInfo);
|
|
932
|
-
},
|
|
933
|
-
onDrag: () => {
|
|
934
|
-
// console.log(`${caseLabel} - Dragging`, gestureInfo, phase);
|
|
935
|
-
},
|
|
936
|
-
onRelease: () => {
|
|
937
|
-
// console.log(`${caseLabel} - Drag released`, gestureInfo);
|
|
938
|
-
},
|
|
939
|
-
}).grabViaPointer(event, {
|
|
940
|
-
element: rectangle,
|
|
941
|
-
});
|
|
942
|
-
});
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
// Set up drag gestures for all rectangles
|
|
946
|
-
setupDragGesture(horizontalRectangle, "Horizontal Only");
|
|
947
|
-
setupDragGesture(bothRectangle, "Both Directions");
|
|
948
|
-
setupDragGesture(obstacleRectangle, "With Obstacles"); // Obstacles handled automatically via [drag-obstacle] attribute
|
|
949
|
-
</script>
|
|
950
|
-
|
|
951
|
-
<script>
|
|
952
|
-
// Add visual feedback for multiple containers
|
|
953
|
-
document.addEventListener("DOMContentLoaded", () => {
|
|
954
|
-
const horizontalContainer = document.getElementById(
|
|
955
|
-
"horizontalContainer",
|
|
956
|
-
);
|
|
957
|
-
horizontalContainer.scrollLeft = 60;
|
|
958
|
-
const bothContainer = document.getElementById("bothContainer");
|
|
959
|
-
const horizontalRectangle = document.getElementById(
|
|
960
|
-
"horizontalRectangle",
|
|
961
|
-
);
|
|
962
|
-
const bothRectangle = document.getElementById("bothRectangle");
|
|
963
|
-
|
|
964
|
-
// Create info display for horizontal case
|
|
965
|
-
const horizontalInfo = createInfoDisplay(
|
|
966
|
-
"Horizontal Case",
|
|
967
|
-
"10px",
|
|
968
|
-
"10px",
|
|
969
|
-
);
|
|
970
|
-
const bothInfo = createInfoDisplay("Both Directions", "10px", "200px");
|
|
971
|
-
|
|
972
|
-
function createInfoDisplay(label, top, right) {
|
|
973
|
-
const info = document.createElement("div");
|
|
974
|
-
info.style.position = "fixed";
|
|
975
|
-
info.style.top = top;
|
|
976
|
-
info.style.right = right;
|
|
977
|
-
info.style.background = "rgba(0,0,0,0.8)";
|
|
978
|
-
info.style.color = "white";
|
|
979
|
-
info.style.padding = "8px 12px";
|
|
980
|
-
info.style.borderRadius = "4px";
|
|
981
|
-
info.style.fontSize = "11px";
|
|
982
|
-
info.style.fontFamily = "monospace";
|
|
983
|
-
info.style.zIndex = "10000";
|
|
984
|
-
info.style.lineHeight = "1.4";
|
|
985
|
-
info.style.minWidth = "160px";
|
|
986
|
-
document.body.appendChild(info);
|
|
987
|
-
return info;
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
function updateInfo(container, rectangle, infoDisplay, label) {
|
|
991
|
-
const rect = rectangle.getBoundingClientRect();
|
|
992
|
-
const containerRect = container.getBoundingClientRect();
|
|
993
|
-
const relativeX =
|
|
994
|
-
rect.left - containerRect.left + container.scrollLeft;
|
|
995
|
-
const relativeY = rect.top - containerRect.top + container.scrollTop;
|
|
996
|
-
|
|
997
|
-
infoDisplay.innerHTML = `
|
|
998
|
-
<div style="font-weight: bold; margin-bottom: 4px;">${label}</div>
|
|
999
|
-
<div>Scroll: ${Math.round(container.scrollLeft)}, ${Math.round(container.scrollTop)}</div>
|
|
1000
|
-
<div>Pos: ${Math.round(relativeX)}, ${Math.round(relativeY)}</div>
|
|
1001
|
-
`;
|
|
1002
|
-
}
|
|
1003
|
-
|
|
1004
|
-
// Set up scroll listeners and initial updates
|
|
1005
|
-
function setupContainerMonitoring(
|
|
1006
|
-
container,
|
|
1007
|
-
rectangle,
|
|
1008
|
-
infoDisplay,
|
|
1009
|
-
label,
|
|
1010
|
-
) {
|
|
1011
|
-
function update() {
|
|
1012
|
-
updateInfo(container, rectangle, infoDisplay, label);
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
container.addEventListener("scroll", update);
|
|
1016
|
-
update();
|
|
1017
|
-
|
|
1018
|
-
// Update position info periodically while dragging
|
|
1019
|
-
let updateInterval;
|
|
1020
|
-
rectangle.addEventListener("mousedown", () => {
|
|
1021
|
-
updateInterval = setInterval(update, 16); // ~60fps
|
|
1022
|
-
});
|
|
1023
|
-
|
|
1024
|
-
document.addEventListener("mouseup", () => {
|
|
1025
|
-
if (updateInterval) {
|
|
1026
|
-
clearInterval(updateInterval);
|
|
1027
|
-
update(); // Final update
|
|
1028
|
-
}
|
|
1029
|
-
});
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
setupContainerMonitoring(
|
|
1033
|
-
horizontalContainer,
|
|
1034
|
-
horizontalRectangle,
|
|
1035
|
-
horizontalInfo,
|
|
1036
|
-
"Horizontal Only",
|
|
1037
|
-
);
|
|
1038
|
-
setupContainerMonitoring(
|
|
1039
|
-
bothContainer,
|
|
1040
|
-
bothRectangle,
|
|
1041
|
-
bothInfo,
|
|
1042
|
-
"Both Directions",
|
|
1043
|
-
);
|
|
1044
|
-
});
|
|
1045
|
-
</script>
|
|
1046
|
-
</body>
|
|
1047
|
-
</html>
|