[FIX] website: fix footer slideout animations
This commit ensures that the slideout footer is visible by the visitor before start its animations. Now to start an option in the footer slideout, you have to scroll enough for the element to be visible. Steps to reproduce the fixed bug: - Enter edit mode - click on the footer - choose a slideout effect other than "Regular" - set an animation to an item inside the footer and select "Everytime" in Animation Launch => the element is animated only once on page load (because the footer is actually directly in the viewport but behind the content of the page) task-2878421 closes odoo/odoo#93133 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
@@ -1235,7 +1235,7 @@ registry.WebsiteAnimate = publicWidget.Widget.extend({
|
||||
});
|
||||
$(window).off('.o_animate');
|
||||
this.$scrollingElement[0].removeEventListener('scroll', this.__onScrollWebsiteAnimate, {capture: true});
|
||||
this.$scrollingElement[0].classList.remove('o_wanim_overflow_x_hidden');
|
||||
this.$scrollingElement[0].classList.remove('o_wanim_overflow_xy_hidden');
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -1251,13 +1251,13 @@ registry.WebsiteAnimate = publicWidget.Widget.extend({
|
||||
_startAnimation($el) {
|
||||
// Forces the browser to redraw using setTimeout.
|
||||
setTimeout(() => {
|
||||
this._toggleOverflowXHidden(true);
|
||||
this._toggleOverflowXYHidden(true);
|
||||
$el
|
||||
.css({"animation-play-state": "running"})
|
||||
.addClass("o_animating")
|
||||
.one('webkitAnimationEnd oanimationend msAnimationEnd animationend', () => {
|
||||
$el.addClass("o_animated").removeClass("o_animating");
|
||||
this._toggleOverflowXHidden(false);
|
||||
this._toggleOverflowXYHidden(false);
|
||||
$(window).trigger("resize");
|
||||
});
|
||||
});
|
||||
@@ -1271,22 +1271,23 @@ registry.WebsiteAnimate = publicWidget.Widget.extend({
|
||||
$el.css({"animation-name": "dummy-none", "animation-play-state": ""})
|
||||
.removeClass("o_animated o_animating");
|
||||
|
||||
this._toggleOverflowXHidden(false);
|
||||
this._toggleOverflowXYHidden(false);
|
||||
// trigger a DOM reflow
|
||||
void $el[0].offsetWidth;
|
||||
$el.css({'animation-name': animationName , 'animation-play-state': 'paused'});
|
||||
},
|
||||
/**
|
||||
* Shows/hides the horizontal scrollbar (on the #wrapwrap).
|
||||
* Shows/hides the horizontal scrollbar (on the #wrapwrap) and prevents
|
||||
* flicker of the page height (on the slideout footer).
|
||||
*
|
||||
* @private
|
||||
* @param {Boolean} add
|
||||
*/
|
||||
_toggleOverflowXHidden(add) {
|
||||
_toggleOverflowXYHidden(add) {
|
||||
if (add) {
|
||||
this.$scrollingElement[0].classList.add('o_wanim_overflow_x_hidden');
|
||||
this.$scrollingElement[0].classList.add('o_wanim_overflow_xy_hidden');
|
||||
} else if (!this.$scrollingElement.find('.o_animating').length) {
|
||||
this.$scrollingElement[0].classList.remove('o_wanim_overflow_x_hidden');
|
||||
this.$scrollingElement[0].classList.remove('o_wanim_overflow_xy_hidden');
|
||||
}
|
||||
},
|
||||
/**
|
||||
@@ -1294,13 +1295,18 @@ registry.WebsiteAnimate = publicWidget.Widget.extend({
|
||||
*
|
||||
* @private
|
||||
* @param {Element} el
|
||||
* @param {HTMLElement} [topEl] if specified, calculates the top distance to
|
||||
* this element.
|
||||
*/
|
||||
_getElementOffsetTop(el) {
|
||||
_getElementOffsetTop(el, topEl) {
|
||||
// Loop through the DOM tree and add its parent's offset to get page offset.
|
||||
var top = 0;
|
||||
do {
|
||||
top += el.offsetTop || 0;
|
||||
el = el.offsetParent;
|
||||
if (topEl && el === topEl) {
|
||||
return top;
|
||||
}
|
||||
} while (el);
|
||||
return top;
|
||||
},
|
||||
@@ -1325,12 +1331,29 @@ registry.WebsiteAnimate = publicWidget.Widget.extend({
|
||||
// Cookies bar might be opened and considered as a modal but it is
|
||||
// not really one (eg 'discrete' layout), and should not be used as
|
||||
// scrollTop value.
|
||||
const scrollTop = document.body.classList.contains("modal-open") ?
|
||||
this.$target.find('.modal:visible').scrollTop() :
|
||||
this.$scrollingElement.scrollTop();
|
||||
const elTop = this._getElementOffsetTop($el[0]) - scrollTop;
|
||||
|
||||
const visible = this.windowsHeight > (elTop + elOffset) && 0 < (elTop + elHeight - elOffset);
|
||||
let visible;
|
||||
const footerEl = el.closest('.o_footer_slideout');
|
||||
const wrapEl = this.$target[0];
|
||||
if (footerEl && wrapEl.classList.contains('o_footer_effect_enable')) {
|
||||
// Since the footer slideout is always in the viewport but not
|
||||
// always displayed, the way to calculate if an element is
|
||||
// visible in the footer is different. We decided to handle this
|
||||
// case specifically instead of a generic solution using
|
||||
// elementFromPoint as it is a rare case and the implementation
|
||||
// would have been too complicated for such a small use case.
|
||||
const actualScroll = wrapEl.scrollTop + this.windowsHeight;
|
||||
const totalScrollHeight = wrapEl.scrollHeight;
|
||||
const heightFromFooter = this._getElementOffsetTop(el, footerEl);
|
||||
visible = actualScroll >=
|
||||
totalScrollHeight - heightFromFooter - elHeight + elOffset;
|
||||
} else {
|
||||
const scrollTop = document.body.classList.contains("modal-open") ?
|
||||
this.$target.find('.modal:visible').scrollTop() :
|
||||
this.$scrollingElement.scrollTop();
|
||||
const elTop = this._getElementOffsetTop($el[0]) - scrollTop;
|
||||
visible = this.windowsHeight > (elTop + elOffset) &&
|
||||
0 < (elTop + elHeight - elOffset);
|
||||
}
|
||||
if (visible && state === "paused") {
|
||||
$el.addClass("o_visible");
|
||||
this._startAnimation($el);
|
||||
|
||||
@@ -3093,10 +3093,10 @@ options.registry.WebsiteAnimate = options.Class.extend({
|
||||
// Trigger a DOM reflow.
|
||||
void this.$target[0].offsetWidth;
|
||||
this.$target.addClass('o_animating');
|
||||
$scrollingElement[0].classList.add('o_wanim_overflow_x_hidden');
|
||||
$scrollingElement[0].classList.add('o_wanim_overflow_xy_hidden');
|
||||
this.$target.css('animation-name', '');
|
||||
this.$target.one('webkitAnimationEnd oanimationend msAnimationEnd animationend', () => {
|
||||
$scrollingElement[0].classList.remove('o_wanim_overflow_x_hidden');
|
||||
$scrollingElement[0].classList.remove('o_wanim_overflow_xy_hidden');
|
||||
this.$target.removeClass('o_animating');
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1511,8 +1511,11 @@ ul.o_checklist > li.o_checked::after {
|
||||
.o_animate_preview {
|
||||
visibility: visible;
|
||||
}
|
||||
.o_wanim_overflow_x_hidden {
|
||||
.o_wanim_overflow_xy_hidden {
|
||||
overflow-x: hidden !important;
|
||||
.o_footer_slideout {
|
||||
overflow-y: hidden !important;
|
||||
}
|
||||
}
|
||||
.o_animated_text {
|
||||
display: inline-block;
|
||||
|
||||
Reference in New Issue
Block a user