Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transition animation cleanup and page animation turned off by default #1102

Merged
merged 10 commits into from
Sep 19, 2023
46 changes: 8 additions & 38 deletions www/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,17 +351,8 @@ document.getElementById('btnHome').addEventListener('click', function (event) {
document.getElementById('liAboutNav').setAttribute('class', '');
$('.navbar-collapse').collapse('hide');
// Show the selected content in the page
uiUtil.removeAnimationClasses();
if (params.showUIAnimations) {
uiUtil.applyAnimationToSection('home');
} else {
document.getElementById('articleContent').style.display = '';
document.getElementById('about').style.display = 'none';
document.getElementById('configuration').style.display = 'none';
}
document.getElementById('navigationButtons').style.display = '';
document.getElementById('formArticleSearch').style.display = '';
document.getElementById('welcomeText').style.display = '';
uiUtil.tabTransitionToSection('home', params.showUIAnimations);

// Give the focus to the search field, and clean up the page contents
document.getElementById('prefix').value = '';
document.getElementById('prefix').focus();
Expand Down Expand Up @@ -390,19 +381,9 @@ document.getElementById('btnConfigure').addEventListener('click', function (even
document.getElementById('liAboutNav').setAttribute('class', '');
$('.navbar-collapse').collapse('hide');
// Show the selected content in the page
uiUtil.removeAnimationClasses();
if (params.showUIAnimations) {
uiUtil.applyAnimationToSection('config');
} else {
document.getElementById('about').style.display = 'none';
document.getElementById('configuration').style.display = '';
document.getElementById('articleContent').style.display = 'none';
}
document.getElementById('navigationButtons').style.display = 'none';
document.getElementById('formArticleSearch').style.display = 'none';
document.getElementById('welcomeText').style.display = 'none';
document.getElementById('searchingArticles').style.display = 'none';
document.querySelector('.kiwix-alert').style.display = 'none';

uiUtil.tabTransitionToSection('config', params.showUIAnimations);

refreshAPIStatus();
refreshCacheStatus();
uiUtil.checkUpdateStatus(appstate);
Expand All @@ -416,21 +397,10 @@ document.getElementById('btnAbout').addEventListener('click', function (event) {
document.getElementById('liConfigureNav').setAttribute('class', '');
document.getElementById('liAboutNav').setAttribute('class', 'active');
$('.navbar-collapse').collapse('hide');

// Show the selected content in the page
uiUtil.removeAnimationClasses();
if (params.showUIAnimations) {
uiUtil.applyAnimationToSection('about');
} else {
document.getElementById('about').style.display = '';
document.getElementById('configuration').style.display = 'none';
document.getElementById('articleContent').style.display = 'none';
}
document.getElementById('navigationButtons').style.display = 'none';
document.getElementById('formArticleSearch').style.display = 'none';
document.getElementById('welcomeText').style.display = 'none';
document.getElementById('articleListWithHeader').style.display = 'none';
document.getElementById('searchingArticles').style.display = 'none';
document.querySelector('.kiwix-alert').style.display = 'none';
uiUtil.tabTransitionToSection('about', params.showUIAnimations);

// Use a timeout of 400ms because uiUtil.applyAnimationToSection uses a timeout of 300ms
setTimeout(resizeIFrame, 400);
});
Expand Down
2 changes: 1 addition & 1 deletion www/js/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ params['storeType'] = getBestAvailableStorageAPI();
// The key prefix used by the settingsStore.js (see comment there for explanation), but we also need it below
params['keyPrefix'] = 'kiwixjs-';
params['hideActiveContentWarning'] = getSetting('hideActiveContentWarning') === true;
params['showUIAnimations'] = getSetting('showUIAnimations') !== false;
params['showUIAnimations'] = getSetting('showUIAnimations') === true;
// Maximum number of article titles to return (range is 5 - 50, default 25)
params['maxSearchResultsSize'] = getSetting('maxSearchResultsSize') || 25;
// Turns caching of assets on or off and deletes the cache (it defaults to true unless explicitly turned off in UI)
Expand Down
210 changes: 141 additions & 69 deletions www/js/lib/uiUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -467,78 +467,156 @@ function isElementInView (el, fully) {
}
Rishabhg71 marked this conversation as resolved.
Show resolved Hide resolved

/**
* Removes the animation effect between various sections
* Show elements in bulk (using display: '')
*
* @param {Array<HTMLElement>} elements It takes the name of the section to which the animation is to be added
* @example showElements(element1, element2, element3)
* @returns {void}
*/
function showElements (...elements) {
for (const element of elements) {
if (element) element.style.display = '';
}
}

/**
* Hide elements in bulk (using display: none)
*
* @param {Array<HTMLElement>} elements Any element that you want to be hidden
* @example hideElements(element1, element2, element3)
* @returns {void}
*/
function hideElements (...elements) {
for (const element of elements) {
if (element) element.style.display = 'none';
}
}

/**
* Removes the animation classes that are added by the slide animation in previous transition
* @returns {void}
*/
function removeAnimationClasses () {
var configuration = document.getElementById('configuration');
configuration.classList.remove('slideIn_L');
configuration.classList.remove('slideIn_R');
configuration.classList.remove('slideOut_L');
configuration.classList.remove('slideOut_R');
document.getElementById('about').classList.remove('slideIn_L');
document.getElementById('about').classList.remove('slideOut_R');
document.getElementById('articleContent').classList.remove('slideIn_R');
document.getElementById('articleContent').classList.remove('slideOut_L');
const config = document.getElementById('configuration');
const about = document.getElementById('about');
const home = document.getElementById('articleContent');

const tabs = [config, about, home]
tabs.forEach(tab => {
tab.classList.remove('slideIn_L');
tab.classList.remove('slideIn_R');
tab.classList.remove('slideOut_L');
tab.classList.remove('slideOut_R');
});
}

/**
* Adds the slide animation between different sections
*
* @param {String} section It takes the name of the section to which the animation is to be added
* @param {HTMLElement} sectionToShow Element which is gonna be slide in from left (show)
* @param {HTMLElement} sectionToHide Element which is gonna be slide to the left (hide)
* @returns {void}
*/
function slideToLeft (sectionToShow, sectionToHide) {
sectionToShow.classList.add('slideIn_L');
setTimeout(function () {
sectionToShow.style.display = '';
// sectionToShow.classList.remove('slideIn_L');
}, 300);

sectionToHide.classList.add('slideOut_L');
setTimeout(function () {
sectionToHide.style.display = 'none';
// sectionToHide.classList.remove('slideOut_L');
}, 300);
}

/**
* Adds the slide animation between different sections
*
* @param {HTMLElement} sectionToShow Element which is gonna be slide in from right (show)
* @param {HTMLElement} sectionToHide Element which is gonna be slide to the right (hide)
* @returns {void}
*/
function applyAnimationToSection (section) {
if (section === 'home') {
if (!$('#configuration').is(':hidden')) {
document.getElementById('configuration').classList.add('slideOut_R');
setTimeout(function () {
document.getElementById('configuration').style.display = 'none';
}, 300);
}
if (!$('#about').is(':hidden')) {
document.getElementById('about').classList.add('slideOut_R');
setTimeout(function () {
document.getElementById('about').style.display = 'none';
}, 300);
function slideToRight (sectionToShow, sectionToHide) {
sectionToHide.classList.add('slideOut_R');
setTimeout(function () {
sectionToHide.style.display = 'none';
// sectionToHide.classList.remove('slideOut_R');
}, 300);

sectionToShow.classList.add('slideIn_R');
setTimeout(function () {
sectionToShow.style.display = '';
// sectionToShow.classList.remove('slideIn_R');
}, 300);
}

/**
* Returns the name of the section which is currently visible
* @returns {String} The name of the section which is currently visible
*/
function fromSection () {
const isConfigPageVisible = !$('#configuration').is(':hidden');
const isAboutPageVisible = !$('#about').is(':hidden');
const isArticlePageVisible = !$('#articleContent').is(':hidden');
if (isConfigPageVisible) return 'config';
else if (isAboutPageVisible) return 'about';
else if (isArticlePageVisible) return 'home';
}
Rishabhg71 marked this conversation as resolved.
Show resolved Hide resolved

/**
* Adds the slide animation between different sections
*
* @param {String} toSection It takes the name of the section to which the animation is to be added
* @param {Boolean} isAnimationRequired To enable or disable the animation
* @returns {void}
*/
function tabTransitionToSection (toSection, isAnimationRequired = false) {
// all the references of the sections/tabs
const config = document.getElementById('configuration');
const about = document.getElementById('about');
const home = document.getElementById('articleContent');

// references of extra elements that are in UI but not tabs
// prefix with extra to avoid confusion and easy identification
const extraNavBtns = document.getElementById('navigationButtons');
const extraArticleSearch = document.getElementById('formArticleSearch');
const extraWelcomeText = document.getElementById('welcomeText');
const extraSearchingArticles = document.getElementById('searchingArticles');
const extraKiwixAlert = document.getElementById('kiwix-alert');

// removing any classes that have been added by previous transition
removeAnimationClasses()
const from = fromSection();

if (isAnimationRequired) {
if (toSection === 'home') {
if (from === 'config') slideToRight(home, config);
if (from === 'about') slideToRight(home, about);
showElements(extraNavBtns, extraArticleSearch, extraWelcomeText, extraKiwixAlert);
} else if (toSection === 'config') {
if (from === 'about') slideToRight(config, about);
if (from === 'home') slideToLeft(config, home);
hideElements(extraNavBtns, extraArticleSearch, extraWelcomeText, extraSearchingArticles, extraKiwixAlert);
} else if (toSection === 'about') {
if (from === 'home') slideToLeft(about, home);
if (from === 'config') slideToLeft(about, config);
hideElements(extraNavBtns, extraArticleSearch, extraWelcomeText, extraSearchingArticles, extraKiwixAlert);
}
$('#articleContent').addClass('slideIn_R');
setTimeout(function () {
document.getElementById('articleContent').style.display = '';
}, 300);
} else if (section === 'config') {
if (!$('#about').is(':hidden')) {
$('#about').addClass('slideOut_R');
$('#configuration').addClass('slideIn_R');
setTimeout(function () {
document.getElementById('about').style.display = 'none';
}, 300);
} else if (!$('#articleContent').is(':hidden')) {
document.getElementById('configuration').classList.add('slideIn_L');
document.getElementById('articleContent').classList.add('slideOut_L');
setTimeout(function () {
document.getElementById('articleContent').style.display = 'none';
}, 300);
} else {
if (toSection === 'home') {
hideElements(config, about);
showElements(home, extraNavBtns, extraArticleSearch, extraWelcomeText);
}
setTimeout(function () {
document.getElementById('configuration').style.display = '';
}, 300);
} else if (section === 'about') {
if (!$('#configuration').is(':hidden')) {
document.getElementById('configuration').classList.add('slideOut_L');
setTimeout(function () {
document.getElementById('configuration').style.display = 'none';
}, 300);
if (toSection === 'config') {
hideElements(about, home, extraNavBtns, extraArticleSearch, extraWelcomeText, extraSearchingArticles, extraKiwixAlert);
showElements(config);
}
if (!$('#articleContent').is(':hidden')) {
document.getElementById('articleContent').classList.add('slideOut_L');
setTimeout(function () {
document.getElementById('articleContent').style.display = 'none';
}, 300);
if (toSection === 'about') {
hideElements(config, home);
showElements(about);
}
document.getElementById('about').classList.add('slideIn_L');
setTimeout(function () {
document.getElementById('about').style.display = '';
}, 300);
}
}

Expand Down Expand Up @@ -633,15 +711,9 @@ function showReturnLink () {
e.preventDefault();
document.getElementById('liConfigureNav').classList.remove('active');
document.getElementById('liHomeNav').classList.add('active');
removeAnimationClasses();
if (params.showUIAnimations) {
applyAnimationToSection('home');
} else {
document.getElementById('configuration').style.display = 'none';
document.getElementById('articleContent').style.display = 'block';
}
document.getElementById('navigationButtons').style.display = 'inline-flex';
document.getElementById('formArticleSearch').style.display = 'block';
tabTransitionToSection('home', params.showUIAnimations);
const welcomeText = document.getElementById('welcomeText');
welcomeText.style.display = 'none';
viewArticle.style.display = 'none';
});
}
Expand Down Expand Up @@ -763,7 +835,7 @@ export default {
spinnerDisplay: spinnerDisplay,
isElementInView: isElementInView,
removeAnimationClasses: removeAnimationClasses,
applyAnimationToSection: applyAnimationToSection,
tabTransitionToSection: tabTransitionToSection,
applyAppTheme: applyAppTheme,
reportAssemblerErrorToAPIStatusPanel: reportAssemblerErrorToAPIStatusPanel,
reportSearchProviderToAPIStatusPanel: reportSearchProviderToAPIStatusPanel,
Expand Down