@littlecarlito/blorktools 0.50.4 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +69 -0
- package/package.json +13 -7
- package/src/asset_debugger/axis-indicator/axis-indicator.css +6 -0
- package/src/asset_debugger/axis-indicator/axis-indicator.html +20 -0
- package/src/asset_debugger/axis-indicator/axis-indicator.js +822 -0
- package/src/asset_debugger/debugger-scene/debugger-scene.css +142 -0
- package/src/asset_debugger/debugger-scene/debugger-scene.html +80 -0
- package/src/asset_debugger/debugger-scene/debugger-scene.js +791 -0
- package/src/asset_debugger/header/header.css +73 -0
- package/src/asset_debugger/header/header.html +24 -0
- package/src/asset_debugger/header/header.js +224 -0
- package/src/asset_debugger/index.html +76 -0
- package/src/asset_debugger/landing-page/landing-page.css +396 -0
- package/src/asset_debugger/landing-page/landing-page.html +81 -0
- package/src/asset_debugger/landing-page/landing-page.js +611 -0
- package/src/asset_debugger/loading-splash/loading-splash.css +195 -0
- package/src/asset_debugger/loading-splash/loading-splash.html +22 -0
- package/src/asset_debugger/loading-splash/loading-splash.js +59 -0
- package/src/asset_debugger/loading-splash/preview-loading-splash.js +66 -0
- package/src/asset_debugger/main.css +14 -0
- package/src/asset_debugger/modals/examples-modal/examples-modal.css +41 -0
- package/src/asset_debugger/modals/examples-modal/examples-modal.html +18 -0
- package/src/asset_debugger/modals/examples-modal/examples-modal.js +111 -0
- package/src/asset_debugger/modals/examples-modal/examples.js +125 -0
- package/src/asset_debugger/modals/html-editor-modal/html-editor-modal.css +452 -0
- package/src/asset_debugger/modals/html-editor-modal/html-editor-modal.html +87 -0
- package/src/asset_debugger/modals/html-editor-modal/html-editor-modal.js +675 -0
- package/src/asset_debugger/modals/mesh-info-modal/mesh-info-modal.css +219 -0
- package/src/asset_debugger/modals/mesh-info-modal/mesh-info-modal.html +20 -0
- package/src/asset_debugger/modals/mesh-info-modal/mesh-info-modal.js +548 -0
- package/src/asset_debugger/modals/settings-modal/settings-modal.css +103 -0
- package/src/asset_debugger/modals/settings-modal/settings-modal.html +158 -0
- package/src/asset_debugger/modals/settings-modal/settings-modal.js +475 -0
- package/src/asset_debugger/panels/asset-panel/asset-panel.css +263 -0
- package/src/asset_debugger/panels/asset-panel/asset-panel.html +123 -0
- package/src/asset_debugger/panels/asset-panel/asset-panel.js +136 -0
- package/src/asset_debugger/panels/asset-panel/atlas-heading/atlas-heading.css +94 -0
- package/src/asset_debugger/panels/asset-panel/atlas-heading/atlas-heading.js +312 -0
- package/src/asset_debugger/panels/asset-panel/mesh-heading/mesh-heading.css +129 -0
- package/src/asset_debugger/panels/asset-panel/mesh-heading/mesh-heading.js +486 -0
- package/src/asset_debugger/panels/asset-panel/rig-heading/rig-heading.css +545 -0
- package/src/asset_debugger/panels/asset-panel/rig-heading/rig-heading.js +538 -0
- package/src/asset_debugger/panels/asset-panel/uv-heading/uv-heading.css +70 -0
- package/src/asset_debugger/panels/asset-panel/uv-heading/uv-heading.js +586 -0
- package/src/asset_debugger/panels/world-panel/world-panel.css +364 -0
- package/src/asset_debugger/panels/world-panel/world-panel.html +173 -0
- package/src/asset_debugger/panels/world-panel/world-panel.js +1891 -0
- package/src/asset_debugger/router.js +190 -0
- package/src/asset_debugger/util/animation/playback/animation-playback-controller.js +150 -0
- package/src/asset_debugger/util/animation/playback/animation-preview-controller.js +316 -0
- package/src/asset_debugger/util/animation/playback/css3d-bounce-controller.js +400 -0
- package/src/asset_debugger/util/animation/playback/css3d-reversal-controller.js +821 -0
- package/src/asset_debugger/util/animation/render/css3d-prerender-controller.js +696 -0
- package/src/asset_debugger/util/animation/render/debug-texture-factory.js +0 -0
- package/src/asset_debugger/util/animation/render/iframe2texture-render-controller.js +199 -0
- package/src/asset_debugger/util/animation/render/image2texture-prerender-controller.js +461 -0
- package/src/asset_debugger/util/animation/render/pbr-material-factory.js +82 -0
- package/src/asset_debugger/util/common.css +280 -0
- package/src/asset_debugger/util/data/animation-classifier.js +323 -0
- package/src/asset_debugger/util/data/duplicate-handler.js +20 -0
- package/src/asset_debugger/util/data/glb-buffer-manager.js +407 -0
- package/src/asset_debugger/util/data/glb-classifier.js +290 -0
- package/src/asset_debugger/util/data/html-formatter.js +76 -0
- package/src/asset_debugger/util/data/html-linter.js +276 -0
- package/src/asset_debugger/util/data/localstorage-manager.js +265 -0
- package/src/asset_debugger/util/data/mesh-html-manager.js +295 -0
- package/src/asset_debugger/util/data/string-serder.js +303 -0
- package/src/asset_debugger/util/data/texture-classifier.js +663 -0
- package/src/asset_debugger/util/data/upload/background-file-handler.js +292 -0
- package/src/asset_debugger/util/data/upload/dropzone-preview-controller.js +396 -0
- package/src/asset_debugger/util/data/upload/file-upload-manager.js +495 -0
- package/src/asset_debugger/util/data/upload/glb-file-handler.js +36 -0
- package/src/asset_debugger/util/data/upload/glb-preview-controller.js +317 -0
- package/src/asset_debugger/util/data/upload/lighting-file-handler.js +194 -0
- package/src/asset_debugger/util/data/upload/model-file-manager.js +104 -0
- package/src/asset_debugger/util/data/upload/texture-file-handler.js +166 -0
- package/src/asset_debugger/util/data/upload/zip-handler.js +686 -0
- package/src/asset_debugger/util/loaders/html2canvas-loader.js +107 -0
- package/src/asset_debugger/util/rig/bone-kinematics.js +403 -0
- package/src/asset_debugger/util/rig/rig-constraint-manager.js +618 -0
- package/src/asset_debugger/util/rig/rig-controller.js +612 -0
- package/src/asset_debugger/util/rig/rig-factory.js +628 -0
- package/src/asset_debugger/util/rig/rig-handle-factory.js +46 -0
- package/src/asset_debugger/util/rig/rig-label-factory.js +441 -0
- package/src/asset_debugger/util/rig/rig-mouse-handler.js +377 -0
- package/src/asset_debugger/util/rig/rig-state-manager.js +175 -0
- package/src/asset_debugger/util/rig/rig-tooltip-manager.js +267 -0
- package/src/asset_debugger/util/rig/rig-ui-factory.js +700 -0
- package/src/asset_debugger/util/scene/background-manager.js +284 -0
- package/src/asset_debugger/util/scene/camera-controller.js +243 -0
- package/src/asset_debugger/util/scene/css3d-debug-controller.js +406 -0
- package/src/asset_debugger/util/scene/css3d-frame-factory.js +113 -0
- package/src/asset_debugger/util/scene/css3d-scene-manager.js +529 -0
- package/src/asset_debugger/util/scene/glb-controller.js +208 -0
- package/src/asset_debugger/util/scene/lighting-manager.js +690 -0
- package/src/asset_debugger/util/scene/threejs-model-manager.js +437 -0
- package/src/asset_debugger/util/scene/threejs-preview-manager.js +207 -0
- package/src/asset_debugger/util/scene/threejs-preview-setup.js +478 -0
- package/src/asset_debugger/util/scene/threejs-scene-controller.js +286 -0
- package/src/asset_debugger/util/scene/ui-manager.js +107 -0
- package/src/asset_debugger/util/state/animation-state.js +128 -0
- package/src/asset_debugger/util/state/css3d-state.js +83 -0
- package/src/asset_debugger/util/state/glb-preview-state.js +31 -0
- package/src/asset_debugger/util/state/log-util.js +197 -0
- package/src/asset_debugger/util/state/scene-state.js +452 -0
- package/src/asset_debugger/util/state/threejs-state.js +54 -0
- package/src/asset_debugger/util/workers/lighting-worker.js +61 -0
- package/src/asset_debugger/util/workers/model-worker.js +109 -0
- package/src/asset_debugger/util/workers/texture-worker.js +54 -0
- package/src/asset_debugger/util/workers/worker-manager.js +212 -0
- package/src/asset_debugger/widgets/mesh-info-widget.js +280 -0
- package/src/index.html +261 -0
- package/src/index.js +8 -0
- package/vite.config.js +66 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import { classifyAnimation, classifyTransition } from "../../data/animation-classifier";
|
|
2
|
+
import {
|
|
3
|
+
animationProperties,
|
|
4
|
+
animationStack,
|
|
5
|
+
batchTimeWindow,
|
|
6
|
+
currentAnimationBatch,
|
|
7
|
+
isCapturingAnimations,
|
|
8
|
+
lastAnimationTime,
|
|
9
|
+
lastBatchTime,
|
|
10
|
+
pushAnimationBatch,
|
|
11
|
+
resetAnimationState,
|
|
12
|
+
resetCurrentAniamtionBatch,
|
|
13
|
+
setLastAnimationTime,
|
|
14
|
+
setLastBatchTime
|
|
15
|
+
} from "../../state/css3d-state";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Set up bounce animation tracking for the iframe
|
|
19
|
+
* @param {HTMLIFrameElement} iframe - The iframe to track animations in
|
|
20
|
+
*/
|
|
21
|
+
export function setupBounceAnimationTracking(iframe) {
|
|
22
|
+
if (!iframe) return;
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
resetAnimationState();
|
|
26
|
+
|
|
27
|
+
// Check if iframe and its content document are available
|
|
28
|
+
if (!iframe.contentDocument) {
|
|
29
|
+
console.debug('Iframe content document not available, skipping animation tracking setup');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
console.debug('Setting up animation tracking for bounce mode');
|
|
34
|
+
|
|
35
|
+
// Clean up any existing event listeners to prevent duplicates
|
|
36
|
+
if (iframe._animationStartHandler) {
|
|
37
|
+
iframe.contentDocument.removeEventListener('animationstart', iframe._animationStartHandler);
|
|
38
|
+
}
|
|
39
|
+
if (iframe._transitionStartHandler) {
|
|
40
|
+
iframe.contentDocument.removeEventListener('transitionstart', iframe._transitionStartHandler);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Track all animations that start
|
|
44
|
+
const animationStartHandler = (event) => {
|
|
45
|
+
// Skip if we're in reversal mode and not capturing
|
|
46
|
+
if (!isCapturingAnimations) return;
|
|
47
|
+
|
|
48
|
+
// Verify iframe is still valid
|
|
49
|
+
if (!iframe || !iframe.contentDocument || !iframe.contentDocument.contains(event.target)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const now = Date.now();
|
|
54
|
+
|
|
55
|
+
// If there was a delay since the last animation, add a delay entry to the stack
|
|
56
|
+
const timeSinceLastAnimation = now - lastAnimationTime;
|
|
57
|
+
|
|
58
|
+
// Check if this animation should start a new batch
|
|
59
|
+
if (timeSinceLastAnimation > batchTimeWindow || currentAnimationBatch.length === 0) {
|
|
60
|
+
// If we have items in the current batch, push it to the stack
|
|
61
|
+
if (currentAnimationBatch.length > 0) {
|
|
62
|
+
animationStack.push({
|
|
63
|
+
type: 'batch',
|
|
64
|
+
animations: [...currentAnimationBatch],
|
|
65
|
+
time: lastBatchTime
|
|
66
|
+
});
|
|
67
|
+
console.debug(`Added batch of ${currentAnimationBatch.length} animations to stack`);
|
|
68
|
+
resetCurrentAniamtionBatch();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// If there's a significant delay, add a delay marker
|
|
72
|
+
if (timeSinceLastAnimation > batchTimeWindow) {
|
|
73
|
+
animationStack.push({
|
|
74
|
+
type: 'delay',
|
|
75
|
+
duration: timeSinceLastAnimation,
|
|
76
|
+
time: now
|
|
77
|
+
});
|
|
78
|
+
console.debug(`Delay added to stack: ${timeSinceLastAnimation}ms`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Update batch time
|
|
82
|
+
setLastBatchTime(now);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Generate a unique selector for this element
|
|
86
|
+
const uniqueSelector = generateUniqueSelector(event.target);
|
|
87
|
+
|
|
88
|
+
// Store animation properties
|
|
89
|
+
const animatedElement = event.target;
|
|
90
|
+
const animationName = event.animationName;
|
|
91
|
+
const computedStyle = window.getComputedStyle(animatedElement);
|
|
92
|
+
|
|
93
|
+
// Capture parent info for potential DOM recreation
|
|
94
|
+
let parentSelector = null;
|
|
95
|
+
if (animatedElement.parentElement) {
|
|
96
|
+
parentSelector = generateUniqueSelector(animatedElement.parentElement);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Capture the animation properties from the computed style
|
|
100
|
+
const animDuration = parseFloat(computedStyle.animationDuration) || 0.3;
|
|
101
|
+
const animDelay = parseFloat(computedStyle.animationDelay) || 0;
|
|
102
|
+
const animTiming = computedStyle.animationTimingFunction || 'ease';
|
|
103
|
+
const animFillMode = computedStyle.animationFillMode || 'none';
|
|
104
|
+
|
|
105
|
+
// Get initial style snapshot before animation fully applies
|
|
106
|
+
const initialStyle = {
|
|
107
|
+
opacity: computedStyle.opacity,
|
|
108
|
+
transform: computedStyle.transform,
|
|
109
|
+
visibility: computedStyle.visibility,
|
|
110
|
+
display: computedStyle.display,
|
|
111
|
+
width: computedStyle.width,
|
|
112
|
+
height: computedStyle.height,
|
|
113
|
+
top: computedStyle.top,
|
|
114
|
+
left: computedStyle.left,
|
|
115
|
+
position: computedStyle.position,
|
|
116
|
+
parentSelector: parentSelector
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// Capture final state after animation is complete
|
|
120
|
+
// We use a timeout to capture the state at the end of the animation
|
|
121
|
+
const durationMs = animDuration * 1000;
|
|
122
|
+
setTimeout(() => {
|
|
123
|
+
try {
|
|
124
|
+
// Verify iframe and element are still valid
|
|
125
|
+
if (animatedElement && iframe && iframe.contentDocument &&
|
|
126
|
+
iframe.contentDocument.contains(animatedElement)) {
|
|
127
|
+
const finalComputedStyle = window.getComputedStyle(animatedElement);
|
|
128
|
+
const finalStyle = {
|
|
129
|
+
opacity: finalComputedStyle.opacity,
|
|
130
|
+
transform: finalComputedStyle.transform,
|
|
131
|
+
visibility: finalComputedStyle.visibility,
|
|
132
|
+
display: finalComputedStyle.display,
|
|
133
|
+
width: finalComputedStyle.width,
|
|
134
|
+
height: finalComputedStyle.height,
|
|
135
|
+
top: finalComputedStyle.top,
|
|
136
|
+
left: finalComputedStyle.left,
|
|
137
|
+
position: finalComputedStyle.position
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// Store the final state in our properties map
|
|
141
|
+
const propKey = `${uniqueSelector}:${animationName}`;
|
|
142
|
+
if (animationProperties[propKey]) {
|
|
143
|
+
animationProperties[propKey].finalStyle = finalStyle;
|
|
144
|
+
console.debug(`Captured final state for: ${propKey}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
} catch (err) {
|
|
148
|
+
console.debug('Error capturing final animation state:', err);
|
|
149
|
+
}
|
|
150
|
+
}, durationMs + 50); // Add a small buffer to ensure animation is complete
|
|
151
|
+
|
|
152
|
+
// Get the animation properties for reverse playback
|
|
153
|
+
const properties = {
|
|
154
|
+
name: animationName,
|
|
155
|
+
selector: uniqueSelector,
|
|
156
|
+
elementTagName: animatedElement.tagName,
|
|
157
|
+
elementId: animatedElement.id,
|
|
158
|
+
elementClasses: animatedElement.className,
|
|
159
|
+
cssText: animatedElement.style.cssText,
|
|
160
|
+
parentSelector: parentSelector,
|
|
161
|
+
type: 'animation',
|
|
162
|
+
// Animation specifics
|
|
163
|
+
duration: animDuration,
|
|
164
|
+
delay: animDelay,
|
|
165
|
+
timingFunction: animTiming,
|
|
166
|
+
fillMode: animFillMode,
|
|
167
|
+
initialStyle: initialStyle,
|
|
168
|
+
// Record animation type
|
|
169
|
+
classified: classifyAnimation(animationName, initialStyle),
|
|
170
|
+
time: now
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// Save animation properties
|
|
174
|
+
const key = `${uniqueSelector}:${animationName}`;
|
|
175
|
+
animationProperties[key] = properties;
|
|
176
|
+
|
|
177
|
+
// Add to current batch instead of directly to stack
|
|
178
|
+
pushAnimationBatch(properties);
|
|
179
|
+
console.debug(`Animation added to current batch: ${animationName}, batch size: ${currentAnimationBatch.length}`);
|
|
180
|
+
|
|
181
|
+
// Update time tracking
|
|
182
|
+
setLastAnimationTime(now);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
// Also track transitions
|
|
186
|
+
const transitionStartHandler = (event) => {
|
|
187
|
+
// Skip if we're in reversal mode and not capturing
|
|
188
|
+
if (!isCapturingAnimations) return;
|
|
189
|
+
|
|
190
|
+
// Verify iframe is still valid
|
|
191
|
+
if (!iframe || !iframe.contentDocument || !iframe.contentDocument.contains(event.target)) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const now = Date.now();
|
|
196
|
+
|
|
197
|
+
// If there was a delay since the last animation, and we have a batch to save
|
|
198
|
+
const timeSinceLastAnimation = now - lastAnimationTime;
|
|
199
|
+
|
|
200
|
+
// Check if this transition should start a new batch
|
|
201
|
+
if (timeSinceLastAnimation > batchTimeWindow || currentAnimationBatch.length === 0) {
|
|
202
|
+
// If we have items in the current batch, push it to the stack
|
|
203
|
+
if (currentAnimationBatch.length > 0) {
|
|
204
|
+
animationStack.push({
|
|
205
|
+
type: 'batch',
|
|
206
|
+
animations: [...currentAnimationBatch],
|
|
207
|
+
time: lastBatchTime
|
|
208
|
+
});
|
|
209
|
+
console.debug(`Added batch of ${currentAnimationBatch.length} animations to stack`);
|
|
210
|
+
resetCurrentAniamtionBatch();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// If there's a significant delay, add a delay marker
|
|
214
|
+
if (timeSinceLastAnimation > batchTimeWindow) {
|
|
215
|
+
animationStack.push({
|
|
216
|
+
type: 'delay',
|
|
217
|
+
duration: timeSinceLastAnimation,
|
|
218
|
+
time: now
|
|
219
|
+
});
|
|
220
|
+
console.debug(`Delay added to stack: ${timeSinceLastAnimation}ms`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Update batch time
|
|
224
|
+
setLastBatchTime(now);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Only track if it's a property we care about for visual animations
|
|
228
|
+
const relevantProperties = ['opacity', 'transform', 'left', 'top', 'right', 'bottom', 'height', 'width'];
|
|
229
|
+
if (!relevantProperties.includes(event.propertyName)) return;
|
|
230
|
+
|
|
231
|
+
// Generate a unique selector for this element
|
|
232
|
+
const uniqueSelector = generateUniqueSelector(event.target);
|
|
233
|
+
|
|
234
|
+
// Store transition properties
|
|
235
|
+
const transitionElement = event.target;
|
|
236
|
+
const propertyName = event.propertyName;
|
|
237
|
+
const computedStyle = window.getComputedStyle(transitionElement);
|
|
238
|
+
|
|
239
|
+
// Capture parent info for potential DOM recreation
|
|
240
|
+
let parentSelector = null;
|
|
241
|
+
if (transitionElement.parentElement) {
|
|
242
|
+
parentSelector = generateUniqueSelector(transitionElement.parentElement);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Capture full transition properties
|
|
246
|
+
const transDuration = parseFloat(computedStyle.transitionDuration) || 0.3;
|
|
247
|
+
const transDelay = parseFloat(computedStyle.transitionDelay) || 0;
|
|
248
|
+
const transTiming = computedStyle.transitionTimingFunction || 'ease';
|
|
249
|
+
|
|
250
|
+
// Get initial snapshot before transition fully applies
|
|
251
|
+
const initialStyle = {};
|
|
252
|
+
relevantProperties.forEach(prop => {
|
|
253
|
+
initialStyle[prop] = computedStyle[prop];
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// Add parent selector to initial style
|
|
257
|
+
initialStyle.parentSelector = parentSelector;
|
|
258
|
+
|
|
259
|
+
// Remember initial value for this property
|
|
260
|
+
const initialValue = computedStyle[propertyName];
|
|
261
|
+
transitionElement.setAttribute(`data-initial-${propertyName}`, initialValue);
|
|
262
|
+
|
|
263
|
+
// Capture final state after transition is complete
|
|
264
|
+
const durationMs = transDuration * 1000;
|
|
265
|
+
setTimeout(() => {
|
|
266
|
+
try {
|
|
267
|
+
// Verify iframe and element are still valid
|
|
268
|
+
if (transitionElement && iframe && iframe.contentDocument &&
|
|
269
|
+
iframe.contentDocument.contains(transitionElement)) {
|
|
270
|
+
const finalComputedStyle = window.getComputedStyle(transitionElement);
|
|
271
|
+
const finalValue = finalComputedStyle[propertyName];
|
|
272
|
+
|
|
273
|
+
// Store the final value
|
|
274
|
+
const propKey = `${uniqueSelector}:${propertyName}`;
|
|
275
|
+
if (animationProperties[propKey]) {
|
|
276
|
+
animationProperties[propKey].finalValue = finalValue;
|
|
277
|
+
console.debug(`Captured final value for: ${propKey} = ${finalValue}`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
} catch (err) {
|
|
281
|
+
console.debug('Error capturing final transition state:', err);
|
|
282
|
+
}
|
|
283
|
+
}, durationMs + 50);
|
|
284
|
+
|
|
285
|
+
// Create transition info object
|
|
286
|
+
const properties = {
|
|
287
|
+
name: `transition-${propertyName}`,
|
|
288
|
+
selector: uniqueSelector,
|
|
289
|
+
elementTagName: transitionElement.tagName,
|
|
290
|
+
elementId: transitionElement.id,
|
|
291
|
+
elementClasses: transitionElement.className,
|
|
292
|
+
property: propertyName,
|
|
293
|
+
cssText: transitionElement.style.cssText,
|
|
294
|
+
parentSelector: parentSelector,
|
|
295
|
+
type: 'transition',
|
|
296
|
+
// Transition specifics
|
|
297
|
+
duration: transDuration,
|
|
298
|
+
delay: transDelay,
|
|
299
|
+
timingFunction: transTiming,
|
|
300
|
+
initialStyle: initialStyle,
|
|
301
|
+
initialValue: initialValue,
|
|
302
|
+
// Classify what kind of transition this is
|
|
303
|
+
classified: classifyTransition(propertyName, initialValue, computedStyle[propertyName]),
|
|
304
|
+
time: now
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
// Save transition properties
|
|
308
|
+
const key = `${uniqueSelector}:${propertyName}`;
|
|
309
|
+
animationProperties[key] = properties;
|
|
310
|
+
|
|
311
|
+
// Add to current batch instead of directly to stack
|
|
312
|
+
pushAnimationBatch(properties);
|
|
313
|
+
console.debug(`Transition added to current batch: ${propertyName}, batch size: ${currentAnimationBatch.length}`);
|
|
314
|
+
|
|
315
|
+
// Update time tracking
|
|
316
|
+
setLastAnimationTime(now);
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
// Store handlers for cleanup
|
|
320
|
+
iframe._animationStartHandler = animationStartHandler;
|
|
321
|
+
iframe._transitionStartHandler = transitionStartHandler;
|
|
322
|
+
|
|
323
|
+
// Add event listeners
|
|
324
|
+
iframe.contentDocument.addEventListener('animationstart', animationStartHandler);
|
|
325
|
+
iframe.contentDocument.addEventListener('transitionstart', transitionStartHandler);
|
|
326
|
+
|
|
327
|
+
} catch (err) {
|
|
328
|
+
console.error('Error setting up animation tracking:', err);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Generate a unique CSS selector for an element that can be used to find it later
|
|
334
|
+
* @param {Element} element - The element to create a selector for
|
|
335
|
+
* @returns {string} A unique CSS selector
|
|
336
|
+
*/
|
|
337
|
+
function generateUniqueSelector(element) {
|
|
338
|
+
if (!element) return '';
|
|
339
|
+
|
|
340
|
+
try {
|
|
341
|
+
// Start with the tag name
|
|
342
|
+
let selector = element.tagName.toLowerCase();
|
|
343
|
+
|
|
344
|
+
// Add ID if it exists (most specific)
|
|
345
|
+
if (element.id) {
|
|
346
|
+
return `${selector}#${element.id}`;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Add classes
|
|
350
|
+
if (element.className && typeof element.className === 'string') {
|
|
351
|
+
const classes = element.className.trim().split(/\s+/);
|
|
352
|
+
if (classes.length > 0 && classes[0] !== '') {
|
|
353
|
+
selector += '.' + classes.join('.');
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Add position among siblings for more specificity
|
|
358
|
+
const parent = element.parentNode;
|
|
359
|
+
if (parent && parent.children.length > 1) {
|
|
360
|
+
const siblings = Array.from(parent.children);
|
|
361
|
+
const index = siblings.indexOf(element);
|
|
362
|
+
|
|
363
|
+
// Use nth-child for position
|
|
364
|
+
selector += `:nth-child(${index + 1})`;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Add nearest parent with ID or distinctive class for context
|
|
368
|
+
let context = '';
|
|
369
|
+
let parentElement = element.parentNode;
|
|
370
|
+
let depth = 0;
|
|
371
|
+
const maxDepth = 3; // Limit how far up we go
|
|
372
|
+
|
|
373
|
+
while (parentElement && parentElement.tagName && depth < maxDepth) {
|
|
374
|
+
if (parentElement.id) {
|
|
375
|
+
context = `${parentElement.tagName.toLowerCase()}#${parentElement.id} > ${context}`;
|
|
376
|
+
break;
|
|
377
|
+
} else if (parentElement.className && typeof parentElement.className === 'string' && parentElement.className.trim()) {
|
|
378
|
+
const parentClass = parentElement.className.trim().split(/\s+/)[0];
|
|
379
|
+
context = `${parentElement.tagName.toLowerCase()}.${parentClass} > ${context}`;
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// If we couldn't find a good identifier, just add the tag
|
|
384
|
+
context = `${parentElement.tagName.toLowerCase()} > ${context}`;
|
|
385
|
+
parentElement = parentElement.parentNode;
|
|
386
|
+
depth++;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Combine context with our selector if we have context
|
|
390
|
+
if (context) {
|
|
391
|
+
selector = context + selector;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return selector;
|
|
395
|
+
} catch (err) {
|
|
396
|
+
console.error('Error generating selector:', err);
|
|
397
|
+
// Fallback to simple tag selector
|
|
398
|
+
return element.tagName ? element.tagName.toLowerCase() : '*';
|
|
399
|
+
}
|
|
400
|
+
}
|