@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.
Files changed (109) hide show
  1. package/dist/jsenv_dom.js +339 -327
  2. package/package.json +2 -4
  3. package/index.js +0 -124
  4. package/src/attr/add_attribute_effect.js +0 -93
  5. package/src/attr/attributes.js +0 -32
  6. package/src/color/color_constrast.js +0 -69
  7. package/src/color/color_parsing.js +0 -319
  8. package/src/color/color_scheme.js +0 -28
  9. package/src/color/pick_light_or_dark.js +0 -34
  10. package/src/color/resolve_css_color.js +0 -60
  11. package/src/demos/3_columns_resize_demo.html +0 -84
  12. package/src/demos/3_rows_resize_demo.html +0 -89
  13. package/src/demos/aside_and_main_demo.html +0 -93
  14. package/src/demos/coordinates_demo.html +0 -450
  15. package/src/demos/document_autoscroll_demo.html +0 -517
  16. package/src/demos/drag_gesture_constraints_demo.html +0 -701
  17. package/src/demos/drag_gesture_demo.html +0 -1047
  18. package/src/demos/drag_gesture_element_to_impact_demo.html +0 -445
  19. package/src/demos/drag_reference_element_demo.html +0 -480
  20. package/src/demos/flex_details_set_demo.html +0 -302
  21. package/src/demos/flex_details_set_demo_2.html +0 -315
  22. package/src/demos/visible_rect_demo.html +0 -525
  23. package/src/element_signature.js +0 -100
  24. package/src/interaction/drag/constraint_feedback_line.js +0 -92
  25. package/src/interaction/drag/drag_constraint.js +0 -659
  26. package/src/interaction/drag/drag_debug_markers.js +0 -635
  27. package/src/interaction/drag/drag_element_positioner.js +0 -382
  28. package/src/interaction/drag/drag_gesture.js +0 -566
  29. package/src/interaction/drag/drag_resize_demo.html +0 -571
  30. package/src/interaction/drag/drag_to_move.js +0 -301
  31. package/src/interaction/drag/drag_to_resize_gesture.js +0 -68
  32. package/src/interaction/drag/drop_target_detection.js +0 -148
  33. package/src/interaction/drag/sticky_frontiers.js +0 -160
  34. package/src/interaction/event_marker.js +0 -14
  35. package/src/interaction/focus/active_element.js +0 -33
  36. package/src/interaction/focus/arrow_navigation.js +0 -599
  37. package/src/interaction/focus/element_is_focusable.js +0 -57
  38. package/src/interaction/focus/element_visibility.js +0 -111
  39. package/src/interaction/focus/find_focusable.js +0 -21
  40. package/src/interaction/focus/focus_group.js +0 -91
  41. package/src/interaction/focus/focus_group_registry.js +0 -12
  42. package/src/interaction/focus/focus_nav.js +0 -12
  43. package/src/interaction/focus/focus_nav_event_marker.js +0 -14
  44. package/src/interaction/focus/focus_trap.js +0 -105
  45. package/src/interaction/focus/tab_navigation.js +0 -128
  46. package/src/interaction/focus/tests/focus_group_skip_tab_test.html +0 -206
  47. package/src/interaction/focus/tests/tree_focus_test.html +0 -304
  48. package/src/interaction/focus/tests/tree_focus_test.jsx +0 -261
  49. package/src/interaction/focus/tests/tree_focus_test_preact.html +0 -13
  50. package/src/interaction/isolate_interactions.js +0 -161
  51. package/src/interaction/keyboard.js +0 -26
  52. package/src/interaction/scroll/capture_scroll.js +0 -47
  53. package/src/interaction/scroll/is_scrollable.js +0 -159
  54. package/src/interaction/scroll/scroll_container.js +0 -110
  55. package/src/interaction/scroll/scroll_trap.js +0 -44
  56. package/src/interaction/scroll/scrollbar_size.js +0 -20
  57. package/src/interaction/scroll/wheel_through.js +0 -138
  58. package/src/iterable_weak_set.js +0 -66
  59. package/src/position/dom_coords.js +0 -340
  60. package/src/position/offset_parent.js +0 -15
  61. package/src/position/position_fixed.js +0 -15
  62. package/src/position/position_sticky.js +0 -213
  63. package/src/position/sticky_rect.js +0 -79
  64. package/src/position/visible_rect.js +0 -486
  65. package/src/pub_sub.js +0 -31
  66. package/src/size/can_take_size.js +0 -11
  67. package/src/size/details_content_full_height.js +0 -63
  68. package/src/size/flex_details_set.js +0 -974
  69. package/src/size/get_available_height.js +0 -22
  70. package/src/size/get_available_width.js +0 -22
  71. package/src/size/get_border_sizes.js +0 -14
  72. package/src/size/get_height.js +0 -4
  73. package/src/size/get_inner_height.js +0 -15
  74. package/src/size/get_inner_width.js +0 -15
  75. package/src/size/get_margin_sizes.js +0 -10
  76. package/src/size/get_max_height.js +0 -57
  77. package/src/size/get_max_width.js +0 -47
  78. package/src/size/get_min_height.js +0 -14
  79. package/src/size/get_min_width.js +0 -14
  80. package/src/size/get_padding_sizes.js +0 -10
  81. package/src/size/get_width.js +0 -4
  82. package/src/size/hooks/use_available_height.js +0 -27
  83. package/src/size/hooks/use_available_width.js +0 -27
  84. package/src/size/hooks/use_max_height.js +0 -10
  85. package/src/size/hooks/use_max_width.js +0 -10
  86. package/src/size/hooks/use_resize_status.js +0 -62
  87. package/src/size/resize.js +0 -695
  88. package/src/size/resolve_css_size.js +0 -32
  89. package/src/style/dom_styles.js +0 -97
  90. package/src/style/style_composition.js +0 -121
  91. package/src/style/style_controller.js +0 -345
  92. package/src/style/style_default.js +0 -153
  93. package/src/style/style_default_demo.html +0 -128
  94. package/src/style/style_parsing.js +0 -375
  95. package/src/transition/demos/animation_resumption_test.xhtml +0 -500
  96. package/src/transition/demos/height_toggle_test.xhtml +0 -515
  97. package/src/transition/dom_transition.js +0 -254
  98. package/src/transition/easing.js +0 -48
  99. package/src/transition/group_transition.js +0 -261
  100. package/src/transition/transform_style_parser.js +0 -32
  101. package/src/transition/transition_playback.js +0 -366
  102. package/src/transition/transition_timeline.js +0 -79
  103. package/src/traversal.js +0 -247
  104. package/src/ui_transition/demos/content_states_transition_demo.html +0 -628
  105. package/src/ui_transition/demos/smooth_height_transition_demo.html +0 -149
  106. package/src/ui_transition/demos/transition_testing.html +0 -354
  107. package/src/ui_transition/ui_transition.js +0 -1470
  108. package/src/utils.js +0 -69
  109. 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>