Wait for full animation preview duration
This commit is contained in:
1 parent
b5301f3f16
commit
8ee59e97d3
3 files changed
+22
-4
No files matched your search
+1
-1
@@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Animation delays now work in slide and template previews and player playback. Outro timing follows each preset's computed Animate.css duration, is configured as time before transition, and preview-only region staggering is removed; slide animation controls enforce the same advanced limits as templates.
|
- Animation delays now work in slide and template previews and player playback. Outro timing follows each preset's computed Animate.css duration and is configured as time before transition; preview cleanup waits for each preset's computed runtime, preview-only region staggering is removed, and slide animation controls enforce the same advanced limits as templates.
|
||||||
|
|
||||||
## 2.21.1 - 2026-10-26
|
## 2.21.1 - 2026-10-26
|
||||||
|
|
||||||
|
|||||||
@@ -132,6 +132,17 @@ export function createSlideAnimationEditor(options) {
|
|||||||
function getPreviewElements() {
|
function getPreviewElements() {
|
||||||
return Array.prototype.slice.call(previewHost.querySelectorAll('.slide-preview-region[data-region-key]'));
|
return Array.prototype.slice.call(previewHost.querySelectorAll('.slide-preview-region[data-region-key]'));
|
||||||
}
|
}
|
||||||
|
function getAnimationDurationMs(element, fallbackDurationMs) {
|
||||||
|
if (typeof window.getComputedStyle !== 'function') return fallbackDurationMs;
|
||||||
|
var durations = String(window.getComputedStyle(element).animationDuration || '').split(',');
|
||||||
|
var longestDuration = durations.reduce(function (longest, value) {
|
||||||
|
var match = value.trim().match(/^([\d.]+)\s*(ms|s)$/i);
|
||||||
|
if (!match) return longest;
|
||||||
|
var duration = Number(match[1]) * (match[2].toLowerCase() === 's' ? 1000 : 1);
|
||||||
|
return Number.isFinite(duration) ? Math.max(longest, duration) : longest;
|
||||||
|
}, 0);
|
||||||
|
return longestDuration || fallbackDurationMs;
|
||||||
|
}
|
||||||
function stopPreview() {
|
function stopPreview() {
|
||||||
if (previewTimer) window.clearTimeout(previewTimer);
|
if (previewTimer) window.clearTimeout(previewTimer);
|
||||||
previewTimer = 0;
|
previewTimer = 0;
|
||||||
@@ -185,7 +196,7 @@ export function createSlideAnimationEditor(options) {
|
|||||||
void element.offsetWidth;
|
void element.offsetWidth;
|
||||||
element.classList.add('animate__animated', 'animate__' + preset);
|
element.classList.add('animate__animated', 'animate__' + preset);
|
||||||
if (mode === 'loop') element.classList.add('animate__repeat-1');
|
if (mode === 'loop') element.classList.add('animate__repeat-1');
|
||||||
longest = Math.max(longest, delay + duration * iterations);
|
longest = Math.max(longest, delay + getAnimationDurationMs(element, duration) * iterations);
|
||||||
});
|
});
|
||||||
updatePreviewButtons();
|
updatePreviewButtons();
|
||||||
previewTimer = window.setTimeout(function () {
|
previewTimer = window.setTimeout(function () {
|
||||||
|
|||||||
@@ -383,7 +383,13 @@ test('slide advanced popup applies changes, cancels drafts and preserves the par
|
|||||||
};
|
};
|
||||||
const modalInstances = new Map();
|
const modalInstances = new Map();
|
||||||
const scrollBarCalls = [];
|
const scrollBarCalls = [];
|
||||||
const context = { window: { innerWidth: 1200, setTimeout() { return 1; }, clearTimeout() {}, pulseModal: {
|
const previewTimers = [];
|
||||||
|
const context = { window: { innerWidth: 1200,
|
||||||
|
setTimeout(_callback, delay) { previewTimers.push(delay); return previewTimers.length; }, clearTimeout() {},
|
||||||
|
getComputedStyle() {
|
||||||
|
return { animationDuration: '400ms' };
|
||||||
|
},
|
||||||
|
pulseModal: {
|
||||||
show(modal) { this.getOrCreate(modal)._scrollBar.hide(); modal.shown = true; },
|
show(modal) { this.getOrCreate(modal)._scrollBar.hide(); modal.shown = true; },
|
||||||
hide(modal) { this.getOrCreate(modal)._scrollBar.reset(); modal.shown = false; modal.handlers['hidden.bs.modal'](); },
|
hide(modal) { this.getOrCreate(modal)._scrollBar.reset(); modal.shown = false; modal.handlers['hidden.bs.modal'](); },
|
||||||
getOrCreate(modal) {
|
getOrCreate(modal) {
|
||||||
@@ -410,7 +416,7 @@ test('slide advanced popup applies changes, cancels drafts and preserves the par
|
|||||||
getTemplate() { return { regions: [
|
getTemplate() { return { regions: [
|
||||||
{ region_key: 'hero', animation_json: { intro: { preset: 'bounceIn' }, outro: { preset: 'fadeOut' } } },
|
{ region_key: 'hero', animation_json: { intro: { preset: 'bounceIn' }, outro: { preset: 'fadeOut' } } },
|
||||||
{ region_key: 'fixed_brand', read_only: true, animation_json: {
|
{ region_key: 'fixed_brand', read_only: true, animation_json: {
|
||||||
outro: { preset: 'fadeOut', duration_ms: 200, delay_ms: 500 },
|
outro: { preset: 'hinge', duration_ms: 200, delay_ms: 500 },
|
||||||
loop: { preset: 'pulse', duration_ms: 200, delay_ms: 240, iterations: 1 }
|
loop: { preset: 'pulse', duration_ms: 200, delay_ms: 240, iterations: 1 }
|
||||||
} },
|
} },
|
||||||
{ region_key: 'fixed_brand_second', read_only: true, animation_json: { loop: { preset: 'pulse', duration_ms: 200, iterations: 1 } } }
|
{ region_key: 'fixed_brand_second', read_only: true, animation_json: { loop: { preset: 'pulse', duration_ms: 200, iterations: 1 } } }
|
||||||
@@ -432,6 +438,7 @@ test('slide advanced popup applies changes, cancels drafts and preserves the par
|
|||||||
animationPreviewButtons[1].handlers.click();
|
animationPreviewButtons[1].handlers.click();
|
||||||
assert.equal(readonlyPreviewRegion.style.values['animation-delay'], '0ms');
|
assert.equal(readonlyPreviewRegion.style.values['animation-delay'], '0ms');
|
||||||
animationPreviewButtons[1].handlers.click();
|
animationPreviewButtons[1].handlers.click();
|
||||||
|
assert.equal(previewTimers[previewTimers.length - 1], 580);
|
||||||
const resetRegion = ids['slide-animation-reset-region'];
|
const resetRegion = ids['slide-animation-reset-region'];
|
||||||
const resetAll = ids['slide-animation-reset-all'];
|
const resetAll = ids['slide-animation-reset-all'];
|
||||||
assert.equal(resetRegion.disabled, true);
|
assert.equal(resetRegion.disabled, true);
|
||||||
|
|||||||
Reference in new issue
Block a user