Update slideIn and slideOut to use requestAnimationFrame
For smoother animations.
This commit is contained in:
parent
7ae735c4d0
commit
349d097e0a
80
src/utils.js
80
src/utils.js
@ -73,16 +73,6 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function calculateSlideStep (height) {
|
|
||||||
if (height > 100) {
|
|
||||||
return 10;
|
|
||||||
} else if (height > 50) {
|
|
||||||
return 5;
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateElementHeight (el) {
|
function calculateElementHeight (el) {
|
||||||
/* Return the height of the passed in DOM element,
|
/* Return the height of the passed in DOM element,
|
||||||
* based on the heights of its children.
|
* based on the heights of its children.
|
||||||
@ -186,7 +176,7 @@
|
|||||||
return _.includes(el.classList, className);
|
return _.includes(el.classList, className);
|
||||||
};
|
};
|
||||||
|
|
||||||
u.slideOut = function (el, duration=1000) {
|
u.slideOut = function (el, duration=250) {
|
||||||
/* Shows/expands an element by sliding it out of itself
|
/* Shows/expands an element by sliding it out of itself
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
@ -200,10 +190,10 @@
|
|||||||
reject(new Error(err));
|
reject(new Error(err));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let interval_marker = el.getAttribute('data-slider-marker');
|
const marker = el.getAttribute('data-slider-marker');
|
||||||
if (interval_marker) {
|
if (marker) {
|
||||||
el.removeAttribute('data-slider-marker');
|
el.removeAttribute('data-slider-marker');
|
||||||
window.clearInterval(interval_marker);
|
window.cancelAnimationFrame(marker);
|
||||||
}
|
}
|
||||||
const end_height = calculateElementHeight(el);
|
const end_height = calculateElementHeight(el);
|
||||||
if (window.converse_disable_effects) { // Effects are disabled (for tests)
|
if (window.converse_disable_effects) { // Effects are disabled (for tests)
|
||||||
@ -217,34 +207,40 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const step = calculateSlideStep(end_height),
|
const steps = duration/17; // We assume 17ms per animation which is ~60FPS
|
||||||
interval = end_height/duration*step;
|
let height = 0;
|
||||||
let h = 0;
|
|
||||||
interval_marker = window.setInterval(function () {
|
function draw () {
|
||||||
h += step;
|
height += end_height/steps;
|
||||||
if (h < end_height) {
|
if (height < end_height) {
|
||||||
el.style.height = h + 'px';
|
el.style.height = height + 'px';
|
||||||
|
el.setAttribute(
|
||||||
|
'data-slider-marker',
|
||||||
|
window.requestAnimationFrame(draw)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// We recalculate the height to work around an apparent
|
// We recalculate the height to work around an apparent
|
||||||
// browser bug where browsers don't know the correct
|
// browser bug where browsers don't know the correct
|
||||||
// offsetHeight beforehand.
|
// offsetHeight beforehand.
|
||||||
|
el.removeAttribute('data-slider-marker');
|
||||||
el.style.height = calculateElementHeight(el) + 'px';
|
el.style.height = calculateElementHeight(el) + 'px';
|
||||||
el.style.overflow = "";
|
el.style.overflow = "";
|
||||||
el.style.height = "";
|
el.style.height = "";
|
||||||
window.clearInterval(interval_marker);
|
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
}, interval);
|
}
|
||||||
|
|
||||||
el.style.height = '0';
|
el.style.height = '0';
|
||||||
el.style.overflow = 'hidden';
|
el.style.overflow = 'hidden';
|
||||||
el.classList.remove('hidden');
|
el.classList.remove('hidden');
|
||||||
el.classList.remove('collapsed');
|
el.classList.remove('collapsed');
|
||||||
el.setAttribute('data-slider-marker', interval_marker);
|
el.setAttribute(
|
||||||
|
'data-slider-marker',
|
||||||
|
window.requestAnimationFrame(draw)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
u.slideIn = function (el, duration=800) {
|
u.slideIn = function (el, duration=250) {
|
||||||
/* Hides/collapses an element by sliding it into itself. */
|
/* Hides/collapses an element by sliding it into itself. */
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (_.isNil(el)) {
|
if (_.isNil(el)) {
|
||||||
@ -258,30 +254,36 @@
|
|||||||
el.style.height = "";
|
el.style.height = "";
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
let interval_marker = el.getAttribute('data-slider-marker');
|
const marker = el.getAttribute('data-slider-marker');
|
||||||
if (interval_marker) {
|
if (marker) {
|
||||||
el.removeAttribute('data-slider-marker');
|
el.removeAttribute('data-slider-marker');
|
||||||
window.clearInterval(interval_marker);
|
window.cancelAnimationFrame(marker);
|
||||||
}
|
}
|
||||||
let h = el.offsetHeight;
|
const original_height = el.offsetHeight,
|
||||||
const step = calculateSlideStep(h),
|
steps = duration/17; // We assume 17ms per animation which is ~60FPS
|
||||||
interval = h/duration*step;
|
let height = original_height;
|
||||||
|
|
||||||
el.style.overflow = 'hidden';
|
el.style.overflow = 'hidden';
|
||||||
|
|
||||||
interval_marker = window.setInterval(function () {
|
function draw () {
|
||||||
h -= step;
|
height -= original_height/steps;
|
||||||
if (h > 0) {
|
if (height > 0) {
|
||||||
el.style.height = h + 'px';
|
el.style.height = height + 'px';
|
||||||
|
el.setAttribute(
|
||||||
|
'data-slider-marker',
|
||||||
|
window.requestAnimationFrame(draw)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
el.removeAttribute('data-slider-marker');
|
el.removeAttribute('data-slider-marker');
|
||||||
window.clearInterval(interval_marker);
|
|
||||||
el.classList.add('collapsed');
|
el.classList.add('collapsed');
|
||||||
el.style.height = "";
|
el.style.height = "";
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
}, interval);
|
}
|
||||||
el.setAttribute('data-slider-marker', interval_marker);
|
el.setAttribute(
|
||||||
|
'data-slider-marker',
|
||||||
|
window.requestAnimationFrame(draw)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user