Release 2.21.2: fix animation timing
This commit is contained in:
1 parent
c923dcc1c5
commit
554678b3c4
13 files changed
+151
-54
No files matched your search
@@ -144,6 +144,7 @@ function clearRegionAnimationClasses(root) {
|
||||
element.style.removeProperty('--animate-duration');
|
||||
element.style.removeProperty('--animate-delay');
|
||||
element.style.removeProperty('--animate-repeat');
|
||||
element.style.removeProperty('animation-delay');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -161,13 +162,16 @@ function applyAnimationStep(element, step, phase) {
|
||||
return;
|
||||
}
|
||||
|
||||
element.classList.add('animate__animated', 'animate__' + preset);
|
||||
element.style.setProperty('--animate-duration', String(Math.max(1, Number(step.duration_ms || 0) || 1000)) + 'ms');
|
||||
if (Number(step.delay_ms || 0) > 0) {
|
||||
element.style.setProperty('--animate-delay', String(Math.max(0, Number(step.delay_ms || 0))) + 'ms');
|
||||
var delayMs = phase === 'outro' ? 0 : Math.max(0, Number(step.delay_ms || 0));
|
||||
if (delayMs > 0) {
|
||||
element.style.setProperty('--animate-delay', String(delayMs) + 'ms');
|
||||
element.style.setProperty('animation-delay', String(delayMs) + 'ms');
|
||||
} else {
|
||||
element.style.removeProperty('--animate-delay');
|
||||
element.style.removeProperty('animation-delay');
|
||||
}
|
||||
element.classList.add('animate__animated', 'animate__' + preset);
|
||||
|
||||
if (phase === 'loop') {
|
||||
var repeatCount = Number(step.iterations);
|
||||
|
||||
@@ -76,8 +76,22 @@
|
||||
});
|
||||
return normalize(config);
|
||||
}
|
||||
function clampAdvancedField(input) {
|
||||
if (!input || !input.dataset) return;
|
||||
var field = input.dataset.animationModalField;
|
||||
var value = String(input.value || '').trim();
|
||||
if (!value) return;
|
||||
var number = Number(value);
|
||||
if (!Number.isFinite(number)) return;
|
||||
var normalized;
|
||||
if (field === 'duration_ms') normalized = Math.min(200, Math.max(1, Math.round(number)));
|
||||
else if (field === 'iterations' && input.dataset.animationModalStep === 'loop') normalized = Math.min(999, Math.max(1, Math.round(number)));
|
||||
else return;
|
||||
if (String(normalized) !== String(input.value)) input.value = String(normalized);
|
||||
}
|
||||
window.pulseRegionAnimationControls = {
|
||||
read: read, write: write, setPreset: setPreset, bind: bind,
|
||||
populateAdvanced: populateAdvanced, readAdvanced: readAdvanced
|
||||
populateAdvanced: populateAdvanced, readAdvanced: readAdvanced,
|
||||
clampAdvancedField: clampAdvancedField
|
||||
};
|
||||
})();
|
||||
@@ -141,7 +141,7 @@ export function createSlideAnimationEditor(options) {
|
||||
element.className.split(/\s+/).forEach(function (className) {
|
||||
if (className.indexOf('animate__') === 0) element.classList.remove(className);
|
||||
});
|
||||
['--animate-duration', '--animate-delay', '--animate-repeat'].forEach(function (property) { element.style.removeProperty(property); });
|
||||
['--animate-duration', '--animate-delay', '--animate-repeat', 'animation-delay'].forEach(function (property) { element.style.removeProperty(property); });
|
||||
});
|
||||
updatePreviewButtons();
|
||||
}
|
||||
@@ -168,16 +168,18 @@ export function createSlideAnimationEditor(options) {
|
||||
previewMode = mode;
|
||||
var token = previewToken;
|
||||
var longest = 0;
|
||||
getPreviewElements().forEach(function (element, index) {
|
||||
getPreviewElements().forEach(function (element) {
|
||||
var config = window.templateDesignerUtils.normalizeAnimationConfig(getConfig(element.dataset.regionKey));
|
||||
var step = config[mode] || {};
|
||||
var preset = window.templateAnimationPresets.normalize(step.preset);
|
||||
if (preset === 'none') return;
|
||||
var delay = Math.max(0, Number(step.delay_ms) || 0) + index * 90;
|
||||
var configuredDelay = mode === 'outro' ? 0 : Math.max(0, Number(step.delay_ms) || 0);
|
||||
var delay = configuredDelay;
|
||||
var duration = Math.max(1, Number(step.duration_ms) || 1000);
|
||||
var iterations = mode === 'loop' ? Math.max(1, Number(step.iterations) || 1) : 1;
|
||||
element.style.setProperty('--animate-duration', duration + 'ms');
|
||||
element.style.setProperty('--animate-delay', delay + 'ms');
|
||||
element.style.setProperty('animation-delay', delay + 'ms');
|
||||
element.style.setProperty('--animate-repeat', String(iterations));
|
||||
element.classList.remove('animate__animated', 'animate__' + preset, 'animate__repeat-1');
|
||||
void element.offsetWidth;
|
||||
@@ -266,6 +268,9 @@ export function createSlideAnimationEditor(options) {
|
||||
advanced.addEventListener('shown.bs.modal', function () {
|
||||
advanced.querySelector('[data-animation-modal-field]').focus();
|
||||
});
|
||||
advanced.addEventListener('input', function (event) {
|
||||
controls.clampAdvancedField(event.target);
|
||||
});
|
||||
advanced.addEventListener('hidden.bs.modal', function () {
|
||||
window.pulseModal.getOrCreate(advanced)._scrollBar = advancedScrollBar;
|
||||
advancedScrollBar = null;
|
||||
|
||||
@@ -363,6 +363,7 @@
|
||||
rect.style.removeProperty('--animate-duration');
|
||||
rect.style.removeProperty('--animate-delay');
|
||||
rect.style.removeProperty('--animate-repeat');
|
||||
rect.style.removeProperty('animation-delay');
|
||||
rect.style.opacity = '';
|
||||
rect.style.transform = '';
|
||||
rect.style.filter = '';
|
||||
@@ -442,15 +443,20 @@
|
||||
var durationMs = Number(step && step.duration_ms);
|
||||
var delayMs = Number(step && step.delay_ms);
|
||||
var repeatCount = Number(step && step.iterations);
|
||||
if (mode === 'out') delayMs = 0;
|
||||
var isAttentionSeeker = preset === 'bounce' || preset === 'flash' || preset === 'pulse' || preset === 'rubberBand' || preset === 'shakeX' || preset === 'shakeY' || preset === 'headShake' || preset === 'swing' || preset === 'tada' || preset === 'wobble' || preset === 'jello' || preset === 'heartBeat';
|
||||
|
||||
rect.classList.remove('animate__animated', 'animate__infinite');
|
||||
rect.style.removeProperty('--animate-duration');
|
||||
rect.style.removeProperty('--animate-delay');
|
||||
rect.style.removeProperty('--animate-repeat');
|
||||
rect.style.removeProperty('animation-delay');
|
||||
rect.style.setProperty('--animate-duration', Math.max(0, Number.isFinite(durationMs) && durationMs > 0 ? durationMs : 1000) + 'ms');
|
||||
if (Number.isFinite(delayMs) && delayMs > 0) {
|
||||
rect.style.setProperty('--animate-delay', Math.max(0, delayMs) + 'ms');
|
||||
rect.style.setProperty('animation-delay', Math.max(0, delayMs) + 'ms');
|
||||
} else {
|
||||
rect.style.removeProperty('animation-delay');
|
||||
}
|
||||
rect.classList.add('animate__animated', animateClass);
|
||||
if (isAttentionSeeker) {
|
||||
@@ -475,6 +481,9 @@
|
||||
if (!Number.isFinite(delayMs) || delayMs < 0) {
|
||||
delayMs = 0;
|
||||
}
|
||||
if (normalizedMode === 'out') {
|
||||
delayMs = 0;
|
||||
}
|
||||
if (!Number.isFinite(iterations) || iterations < 1) {
|
||||
iterations = 1;
|
||||
}
|
||||
@@ -595,39 +604,6 @@
|
||||
window.pulseRegionAnimationControls.populateAdvanced(animationAdvancedModal, config);
|
||||
}
|
||||
|
||||
function readNumberField(value) {
|
||||
var raw = String(value || '').trim();
|
||||
if (!raw) {
|
||||
return null;
|
||||
}
|
||||
var next = Number(raw);
|
||||
return Number.isFinite(next) ? Math.round(next) : null;
|
||||
}
|
||||
|
||||
function clampAnimationModalField(field) {
|
||||
if (!field || !field.matches) {
|
||||
return;
|
||||
}
|
||||
|
||||
var isLoopIterationsField = field.matches('[data-animation-modal-step="loop"][data-animation-modal-field="iterations"]');
|
||||
var isDurationField = field.matches('[data-animation-modal-field="duration_ms"]');
|
||||
if (!isLoopIterationsField && !isDurationField) {
|
||||
return;
|
||||
}
|
||||
|
||||
var fieldValue = readNumberField(field.value);
|
||||
if (fieldValue === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var normalizedValue = isLoopIterationsField
|
||||
? Math.min(MAX_ANIMATION_REPEAT_COUNT, Math.max(1, fieldValue))
|
||||
: Math.min(200, Math.max(1, fieldValue));
|
||||
if (String(normalizedValue) !== String(field.value)) {
|
||||
field.value = String(normalizedValue);
|
||||
}
|
||||
}
|
||||
|
||||
function readAnimationModalConfig() {
|
||||
if (!animationAdvancedModal) {
|
||||
return null;
|
||||
@@ -732,7 +708,6 @@
|
||||
function animatePreviewRects(mode, regions) {
|
||||
var rects = getPreviewRects();
|
||||
var token = previewState.token;
|
||||
var stagger = 90;
|
||||
var duration = 900;
|
||||
var overlayRect = getOverlayRect();
|
||||
var canvasMovement = Math.max(12, Math.round(overlayRect.height * 0.02));
|
||||
@@ -740,11 +715,11 @@
|
||||
|
||||
previewState.animations = [];
|
||||
|
||||
rects.forEach(function (rect, index) {
|
||||
rects.forEach(function (rect) {
|
||||
var region = regions && regions[index] ? regions[index] : null;
|
||||
var step = getPreviewRegionAnimationStep(region, mode);
|
||||
var preset = normalizePreviewAnimation(step && step.preset);
|
||||
var delay = index * stagger;
|
||||
var delay = mode === 'out' ? 0 : Math.max(0, Number(step && step.delay_ms) || 0);
|
||||
var animation = null;
|
||||
var animateCssMode = isAnimateCssPreset(preset);
|
||||
var timingMs = delay + getPreviewAnimationStepTimingMs(step, mode, animateCssMode);
|
||||
@@ -1785,7 +1760,7 @@
|
||||
activeAnimationCard = null;
|
||||
});
|
||||
animationAdvancedModal.addEventListener('input', function (event) {
|
||||
clampAnimationModalField(event.target);
|
||||
window.pulseRegionAnimationControls.clampAdvancedField(event.target);
|
||||
markTemplateFormDirty();
|
||||
});
|
||||
animationAdvancedModal.addEventListener('change', function () {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<div class="card-body d-grid gap-3 align-content-start">
|
||||
<label class="d-grid gap-1">Preset<select class="form-select" data-animation-modal-step="outro" data-animation-modal-field="preset">{{#each animationPresets.advanced.outro}}<option value="{{value}}">{{label}}</option>{{/each}}</select></label>
|
||||
<label class="d-grid gap-1">Duration %<input class="form-control" type="number" min="1" max="200" step="1" data-animation-modal-step="outro" data-animation-modal-field="duration_ms" placeholder="100" /></label>
|
||||
<label class="d-grid gap-1">Delay ms<input class="form-control" type="number" min="0" step="1" data-animation-modal-step="outro" data-animation-modal-field="delay_ms" placeholder="0" /></label>
|
||||
<label class="d-grid gap-1">Finish before transition (ms)<input class="form-control" type="number" min="0" step="1" data-animation-modal-step="outro" data-animation-modal-field="delay_ms" placeholder="0" /></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user