@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,515 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>Height Toggle Animation Test</title>
|
|
5
|
-
<style>
|
|
6
|
-
body {
|
|
7
|
-
margin: 0;
|
|
8
|
-
font-family: system-ui;
|
|
9
|
-
padding: 20px;
|
|
10
|
-
background: #f0f0f0;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.controls {
|
|
14
|
-
background: white;
|
|
15
|
-
padding: 20px;
|
|
16
|
-
border-radius: 8px;
|
|
17
|
-
margin-bottom: 20px;
|
|
18
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.control-group {
|
|
22
|
-
margin-bottom: 16px;
|
|
23
|
-
display: flex;
|
|
24
|
-
gap: 12px;
|
|
25
|
-
align-items: center;
|
|
26
|
-
flex-wrap: wrap;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.control-group label {
|
|
30
|
-
font-weight: bold;
|
|
31
|
-
min-width: 120px;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.toggle-button {
|
|
35
|
-
padding: 12px 24px;
|
|
36
|
-
border: 2px solid #0066cc;
|
|
37
|
-
border-radius: 8px;
|
|
38
|
-
background: #0066cc;
|
|
39
|
-
color: white;
|
|
40
|
-
cursor: pointer;
|
|
41
|
-
font-size: 16px;
|
|
42
|
-
font-weight: bold;
|
|
43
|
-
transition:
|
|
44
|
-
background 0.2s,
|
|
45
|
-
border-color 0.2s;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.toggle-button:hover {
|
|
49
|
-
background: #0052a3;
|
|
50
|
-
border-color: #0052a3;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.toggle-button.expanding {
|
|
54
|
-
background: #28a745;
|
|
55
|
-
border-color: #28a745;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.toggle-button.collapsing {
|
|
59
|
-
background: #dc3545;
|
|
60
|
-
border-color: #dc3545;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.quick-test-buttons {
|
|
64
|
-
display: flex;
|
|
65
|
-
gap: 8px;
|
|
66
|
-
margin-top: 12px;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.quick-test-buttons button {
|
|
70
|
-
padding: 6px 12px;
|
|
71
|
-
border: 1px solid #ccc;
|
|
72
|
-
border-radius: 4px;
|
|
73
|
-
background: #f8f9fa;
|
|
74
|
-
cursor: pointer;
|
|
75
|
-
font-size: 14px;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.quick-test-buttons button:hover {
|
|
79
|
-
background: #e9ecef;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.test-element {
|
|
83
|
-
background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
|
|
84
|
-
border: 2px solid #333;
|
|
85
|
-
border-radius: 8px;
|
|
86
|
-
color: white;
|
|
87
|
-
font-weight: bold;
|
|
88
|
-
text-align: center;
|
|
89
|
-
display: flex;
|
|
90
|
-
align-items: center;
|
|
91
|
-
justify-content: center;
|
|
92
|
-
margin: 20px 0;
|
|
93
|
-
width: 300px;
|
|
94
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
95
|
-
transition: box-shadow 0.2s;
|
|
96
|
-
position: relative;
|
|
97
|
-
overflow: hidden;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
.test-element[data-height-animated] {
|
|
101
|
-
box-shadow: 0 8px 24px rgba(255, 107, 107, 0.6);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
.height-indicator {
|
|
105
|
-
position: absolute;
|
|
106
|
-
top: 5px;
|
|
107
|
-
right: 10px;
|
|
108
|
-
background: rgba(0, 0, 0, 0.7);
|
|
109
|
-
color: white;
|
|
110
|
-
padding: 4px 8px;
|
|
111
|
-
border-radius: 4px;
|
|
112
|
-
font-size: 12px;
|
|
113
|
-
font-family: monospace;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
.status {
|
|
117
|
-
background: white;
|
|
118
|
-
padding: 16px;
|
|
119
|
-
border-radius: 8px;
|
|
120
|
-
margin-bottom: 20px;
|
|
121
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.status-item {
|
|
125
|
-
margin: 8px 0;
|
|
126
|
-
padding: 8px;
|
|
127
|
-
border-radius: 4px;
|
|
128
|
-
background: #f8f9fa;
|
|
129
|
-
display: flex;
|
|
130
|
-
justify-content: space-between;
|
|
131
|
-
align-items: center;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
.status-item.expanding {
|
|
135
|
-
background: #d4edda;
|
|
136
|
-
border-left: 4px solid #28a745;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.status-item.collapsing {
|
|
140
|
-
background: #f8d7da;
|
|
141
|
-
border-left: 4px solid #dc3545;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
.status-item.idle {
|
|
145
|
-
background: #e2e3e5;
|
|
146
|
-
border-left: 4px solid #6c757d;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
.progress-bar {
|
|
150
|
-
width: 100%;
|
|
151
|
-
height: 12px;
|
|
152
|
-
background: #e9ecef;
|
|
153
|
-
border-radius: 6px;
|
|
154
|
-
overflow: hidden;
|
|
155
|
-
margin: 8px 0;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
.progress-fill {
|
|
159
|
-
height: 100%;
|
|
160
|
-
background: linear-gradient(90deg, #ff6b6b, #4ecdc4);
|
|
161
|
-
transition: width 0.1s linear;
|
|
162
|
-
border-radius: 6px;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
.debug-log {
|
|
166
|
-
background: #1e1e1e;
|
|
167
|
-
color: #00ff00;
|
|
168
|
-
padding: 16px;
|
|
169
|
-
border-radius: 8px;
|
|
170
|
-
font-family: monospace;
|
|
171
|
-
font-size: 12px;
|
|
172
|
-
height: 250px;
|
|
173
|
-
overflow-y: auto;
|
|
174
|
-
margin-top: 20px;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
.stats {
|
|
178
|
-
display: grid;
|
|
179
|
-
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
180
|
-
gap: 12px;
|
|
181
|
-
margin-top: 16px;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
.stat {
|
|
185
|
-
background: #f8f9fa;
|
|
186
|
-
padding: 12px;
|
|
187
|
-
border-radius: 6px;
|
|
188
|
-
text-align: center;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
.stat-value {
|
|
192
|
-
font-size: 24px;
|
|
193
|
-
font-weight: bold;
|
|
194
|
-
color: #0066cc;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
.stat-label {
|
|
198
|
-
font-size: 12px;
|
|
199
|
-
color: #6c757d;
|
|
200
|
-
margin-top: 4px;
|
|
201
|
-
}
|
|
202
|
-
</style>
|
|
203
|
-
</head>
|
|
204
|
-
<body>
|
|
205
|
-
<h1>Height Toggle Animation Test</h1>
|
|
206
|
-
<p>
|
|
207
|
-
Test rapid height animation toggling and mid-animation direction changes
|
|
208
|
-
using updateTarget
|
|
209
|
-
</p>
|
|
210
|
-
|
|
211
|
-
<div class="controls">
|
|
212
|
-
<h3>Animation Controls</h3>
|
|
213
|
-
|
|
214
|
-
<div class="control-group">
|
|
215
|
-
<button id="toggle-btn" class="toggle-button">
|
|
216
|
-
Toggle Height (100px ↔ 300px)
|
|
217
|
-
</button>
|
|
218
|
-
</div>
|
|
219
|
-
|
|
220
|
-
<div class="control-group">
|
|
221
|
-
<label>Quick Tests:</label>
|
|
222
|
-
<div class="quick-test-buttons">
|
|
223
|
-
<button id="rapid-test">Rapid Toggle (5x)</button>
|
|
224
|
-
<button id="interrupt-test">Interrupt Test</button>
|
|
225
|
-
<button id="reset-btn">Reset Element</button>
|
|
226
|
-
</div>
|
|
227
|
-
</div>
|
|
228
|
-
</div>
|
|
229
|
-
|
|
230
|
-
<div class="status">
|
|
231
|
-
<h3>Animation Status</h3>
|
|
232
|
-
<div id="status-content">
|
|
233
|
-
<div class="status-item idle">
|
|
234
|
-
<span>Ready - Element at 150px</span>
|
|
235
|
-
<span>Target: 300px</span>
|
|
236
|
-
</div>
|
|
237
|
-
</div>
|
|
238
|
-
<div class="progress-bar">
|
|
239
|
-
<div class="progress-fill" id="progress-fill" style="width: 0%"></div>
|
|
240
|
-
</div>
|
|
241
|
-
<div id="progress-text">Progress: 0%</div>
|
|
242
|
-
|
|
243
|
-
<div class="stats">
|
|
244
|
-
<div class="stat">
|
|
245
|
-
<div class="stat-value" id="toggle-count">0</div>
|
|
246
|
-
<div class="stat-label">Total Toggles</div>
|
|
247
|
-
</div>
|
|
248
|
-
<div class="stat">
|
|
249
|
-
<div class="stat-value" id="current-height">150</div>
|
|
250
|
-
<div class="stat-label">Current Height (px)</div>
|
|
251
|
-
</div>
|
|
252
|
-
<div class="stat">
|
|
253
|
-
<div class="stat-value" id="target-height">300</div>
|
|
254
|
-
<div class="stat-label">Target Height (px)</div>
|
|
255
|
-
</div>
|
|
256
|
-
<div class="stat">
|
|
257
|
-
<div class="stat-value" id="animation-state">idle</div>
|
|
258
|
-
<div class="stat-label">Animation State</div>
|
|
259
|
-
</div>
|
|
260
|
-
</div>
|
|
261
|
-
</div>
|
|
262
|
-
|
|
263
|
-
<div id="test-element" class="test-element" style="height: 150px">
|
|
264
|
-
<span>Height Animation Test</span>
|
|
265
|
-
<div class="height-indicator" id="height-indicator">150px</div>
|
|
266
|
-
</div>
|
|
267
|
-
|
|
268
|
-
<div class="debug-log" id="debug-log"></div>
|
|
269
|
-
|
|
270
|
-
<script type="module">
|
|
271
|
-
import { createHeightAnimation } from "@jsenv/dom";
|
|
272
|
-
|
|
273
|
-
const testElement = document.getElementById("test-element");
|
|
274
|
-
const debugLog = document.getElementById("debug-log");
|
|
275
|
-
const statusContent = document.getElementById("status-content");
|
|
276
|
-
const progressFill = document.getElementById("progress-fill");
|
|
277
|
-
const progressText = document.getElementById("progress-text");
|
|
278
|
-
const heightIndicator = document.getElementById("height-indicator");
|
|
279
|
-
|
|
280
|
-
// Controls
|
|
281
|
-
const toggleBtn = document.getElementById("toggle-btn");
|
|
282
|
-
const rapidTestBtn = document.getElementById("rapid-test");
|
|
283
|
-
const interruptTestBtn = document.getElementById("interrupt-test");
|
|
284
|
-
const resetBtn = document.getElementById("reset-btn");
|
|
285
|
-
|
|
286
|
-
// Stats
|
|
287
|
-
const toggleCountEl = document.getElementById("toggle-count");
|
|
288
|
-
const currentHeightEl = document.getElementById("current-height");
|
|
289
|
-
const targetHeightEl = document.getElementById("target-height");
|
|
290
|
-
const animationStateEl = document.getElementById("animation-state");
|
|
291
|
-
|
|
292
|
-
// State
|
|
293
|
-
let currentAnimation = null;
|
|
294
|
-
let isExpanded = false; // false = 150px (collapsed), true = 300px (expanded)
|
|
295
|
-
let toggleCount = 0;
|
|
296
|
-
|
|
297
|
-
const COLLAPSED_HEIGHT = 100;
|
|
298
|
-
const EXPANDED_HEIGHT = 300;
|
|
299
|
-
const ANIMATION_DURATION = 1000;
|
|
300
|
-
|
|
301
|
-
function log(message) {
|
|
302
|
-
const timestamp = new Date().toLocaleTimeString();
|
|
303
|
-
debugLog.innerHTML += `[${timestamp}] ${message}<br>`;
|
|
304
|
-
debugLog.scrollTop = debugLog.scrollHeight;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
function updateStats() {
|
|
308
|
-
const currentHeight = Math.round(
|
|
309
|
-
parseFloat(testElement.style.height) || 150,
|
|
310
|
-
);
|
|
311
|
-
const targetHeight = isExpanded ? COLLAPSED_HEIGHT : EXPANDED_HEIGHT;
|
|
312
|
-
|
|
313
|
-
toggleCountEl.textContent = toggleCount;
|
|
314
|
-
currentHeightEl.textContent = currentHeight;
|
|
315
|
-
targetHeightEl.textContent = targetHeight;
|
|
316
|
-
heightIndicator.textContent = `${currentHeight}px`;
|
|
317
|
-
|
|
318
|
-
if (currentAnimation) {
|
|
319
|
-
animationStateEl.textContent = currentAnimation.playState;
|
|
320
|
-
} else {
|
|
321
|
-
animationStateEl.textContent = "idle";
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
function updateStatus(message, type = "idle") {
|
|
326
|
-
const targetHeight = isExpanded ? COLLAPSED_HEIGHT : EXPANDED_HEIGHT;
|
|
327
|
-
const currentHeight = Math.round(
|
|
328
|
-
parseFloat(testElement.style.height) || 150,
|
|
329
|
-
);
|
|
330
|
-
|
|
331
|
-
statusContent.innerHTML = `
|
|
332
|
-
<div class="status-item ${type}">
|
|
333
|
-
<span>${message}</span>
|
|
334
|
-
<span>${currentHeight}px → ${targetHeight}px</span>
|
|
335
|
-
</div>
|
|
336
|
-
`;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
function updateProgress(progress) {
|
|
340
|
-
const percentage = Math.round(progress * 100);
|
|
341
|
-
progressFill.style.width = `${percentage}%`;
|
|
342
|
-
progressText.textContent = `Progress: ${percentage}%`;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
function updateButtonState() {
|
|
346
|
-
const isAnimating =
|
|
347
|
-
currentAnimation && currentAnimation.playState === "running";
|
|
348
|
-
|
|
349
|
-
if (isAnimating) {
|
|
350
|
-
// During animation, determine direction by comparing current height to target
|
|
351
|
-
const currentHeight = Math.round(
|
|
352
|
-
parseFloat(testElement.style.height) || 150,
|
|
353
|
-
);
|
|
354
|
-
const targetHeight = isExpanded ? EXPANDED_HEIGHT : COLLAPSED_HEIGHT;
|
|
355
|
-
|
|
356
|
-
if (targetHeight > currentHeight) {
|
|
357
|
-
toggleBtn.className = "toggle-button expanding";
|
|
358
|
-
toggleBtn.textContent = `Expanding to ${targetHeight}px...`;
|
|
359
|
-
} else {
|
|
360
|
-
toggleBtn.className = "toggle-button collapsing";
|
|
361
|
-
toggleBtn.textContent = `Collapsing to ${targetHeight}px...`;
|
|
362
|
-
}
|
|
363
|
-
} else {
|
|
364
|
-
toggleBtn.className = "toggle-button";
|
|
365
|
-
const nextTarget = isExpanded ? COLLAPSED_HEIGHT : EXPANDED_HEIGHT;
|
|
366
|
-
const action = nextTarget === EXPANDED_HEIGHT ? "Expand" : "Collapse";
|
|
367
|
-
toggleBtn.textContent = `${action} to ${nextTarget}px`;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
function resetElement() {
|
|
372
|
-
if (currentAnimation) {
|
|
373
|
-
currentAnimation.cancel();
|
|
374
|
-
currentAnimation = null;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
testElement.style.height = "150px";
|
|
378
|
-
isExpanded = false;
|
|
379
|
-
toggleCount = 0;
|
|
380
|
-
|
|
381
|
-
updateStatus("Element reset to initial state", "idle");
|
|
382
|
-
updateProgress(0);
|
|
383
|
-
updateStats();
|
|
384
|
-
updateButtonState();
|
|
385
|
-
log("Element reset to 150px initial state");
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
function toggleHeight() {
|
|
389
|
-
toggleCount++;
|
|
390
|
-
const targetHeight = isExpanded ? COLLAPSED_HEIGHT : EXPANDED_HEIGHT;
|
|
391
|
-
const action =
|
|
392
|
-
targetHeight === EXPANDED_HEIGHT ? "Expanding" : "Collapsing";
|
|
393
|
-
|
|
394
|
-
log(`Toggle ${toggleCount}: ${action} to ${targetHeight}px`);
|
|
395
|
-
|
|
396
|
-
if (currentAnimation && currentAnimation.playState === "running") {
|
|
397
|
-
// Animation is running, update target
|
|
398
|
-
log(`Updating target mid-animation to ${targetHeight}px`);
|
|
399
|
-
currentAnimation.updateTarget(targetHeight);
|
|
400
|
-
updateStatus(
|
|
401
|
-
`Target updated mid-animation`,
|
|
402
|
-
targetHeight === COLLAPSED_HEIGHT ? "collapsing" : "expanding",
|
|
403
|
-
);
|
|
404
|
-
} else {
|
|
405
|
-
// Start new animation
|
|
406
|
-
const currentHeight = Math.round(
|
|
407
|
-
parseFloat(testElement.style.height) || 150,
|
|
408
|
-
);
|
|
409
|
-
log(
|
|
410
|
-
`Starting new animation from ${currentHeight}px to ${targetHeight}px`,
|
|
411
|
-
);
|
|
412
|
-
|
|
413
|
-
currentAnimation = createHeightAnimation(testElement, targetHeight, {
|
|
414
|
-
duration: ANIMATION_DURATION,
|
|
415
|
-
// Uncomment the line below to test with linear easing
|
|
416
|
-
// easing: (x) => x, // Linear easing for comparison
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
// Set up progress tracking
|
|
420
|
-
currentAnimation.channels.progress.add(({ progress }) => {
|
|
421
|
-
updateProgress(progress);
|
|
422
|
-
updateStats();
|
|
423
|
-
});
|
|
424
|
-
|
|
425
|
-
// Handle animation completion
|
|
426
|
-
currentAnimation.channels.finish.add(() => {
|
|
427
|
-
// Log the actual height when animation completes
|
|
428
|
-
const actualHeight = Math.round(
|
|
429
|
-
parseFloat(testElement.style.height) || 0,
|
|
430
|
-
);
|
|
431
|
-
log(
|
|
432
|
-
`Animation completed. Target was ${targetHeight}px, actual height is ${actualHeight}px`,
|
|
433
|
-
);
|
|
434
|
-
updateStatus(`Animation completed`, "idle");
|
|
435
|
-
updateProgress(0);
|
|
436
|
-
updateStats();
|
|
437
|
-
updateButtonState();
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
currentAnimation.play();
|
|
441
|
-
updateStatus(
|
|
442
|
-
`${action} animation started`,
|
|
443
|
-
targetHeight === COLLAPSED_HEIGHT ? "collapsing" : "expanding",
|
|
444
|
-
);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// Toggle the state for next click
|
|
448
|
-
isExpanded = !isExpanded;
|
|
449
|
-
updateStats();
|
|
450
|
-
updateButtonState();
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
function rapidToggleTest() {
|
|
454
|
-
log("Starting rapid toggle test (5 clicks in 2 seconds)");
|
|
455
|
-
let clickCount = 0;
|
|
456
|
-
const interval = setInterval(() => {
|
|
457
|
-
toggleHeight();
|
|
458
|
-
clickCount++;
|
|
459
|
-
if (clickCount >= 5) {
|
|
460
|
-
clearInterval(interval);
|
|
461
|
-
log("Rapid toggle test completed");
|
|
462
|
-
}
|
|
463
|
-
}, 400);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
function interruptTest() {
|
|
467
|
-
log("Starting interrupt test");
|
|
468
|
-
|
|
469
|
-
// First, start an animation
|
|
470
|
-
toggleHeight();
|
|
471
|
-
|
|
472
|
-
// Then interrupt it multiple times
|
|
473
|
-
setTimeout(() => {
|
|
474
|
-
log("Interrupt 1: Changing direction");
|
|
475
|
-
toggleHeight();
|
|
476
|
-
}, 500);
|
|
477
|
-
|
|
478
|
-
setTimeout(() => {
|
|
479
|
-
log("Interrupt 2: Changing direction again");
|
|
480
|
-
toggleHeight();
|
|
481
|
-
}, 1000);
|
|
482
|
-
|
|
483
|
-
setTimeout(() => {
|
|
484
|
-
log("Interrupt 3: Final direction change");
|
|
485
|
-
toggleHeight();
|
|
486
|
-
}, 1500);
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
// Event listeners
|
|
490
|
-
toggleBtn.onclick = toggleHeight;
|
|
491
|
-
rapidTestBtn.onclick = rapidToggleTest;
|
|
492
|
-
interruptTestBtn.onclick = interruptTest;
|
|
493
|
-
resetBtn.onclick = resetElement;
|
|
494
|
-
|
|
495
|
-
// Real-time height monitoring
|
|
496
|
-
const observer = new MutationObserver(() => {
|
|
497
|
-
updateStats();
|
|
498
|
-
});
|
|
499
|
-
observer.observe(testElement, {
|
|
500
|
-
attributes: true,
|
|
501
|
-
attributeFilter: ["style"],
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
// Initialize
|
|
505
|
-
log("Height toggle animation test initialized");
|
|
506
|
-
log(
|
|
507
|
-
`Element starts at 150px, toggles between ${COLLAPSED_HEIGHT}px and ${EXPANDED_HEIGHT}px`,
|
|
508
|
-
);
|
|
509
|
-
log("Click toggle button to test updateTarget behavior");
|
|
510
|
-
updateStats();
|
|
511
|
-
updateButtonState();
|
|
512
|
-
updateStatus("Ready to start animation", "idle");
|
|
513
|
-
</script>
|
|
514
|
-
</body>
|
|
515
|
-
</html>
|