Completed zoom-fade animation
Fix new menu button animation
This commit is contained in:
parent
37a1eaa37d
commit
6d8193671a
@ -1,117 +1,10 @@
|
|||||||
import { findUpTag, whichChild } from "../lib/utils";
|
import { findUpTag, whichChild } from "../lib/utils";
|
||||||
|
import Transition from "./transition";
|
||||||
function slideNavigation(tabContent: HTMLElement, prevTabContent: HTMLElement, width: number, toRight: boolean) {
|
|
||||||
const elements = [tabContent, prevTabContent];
|
|
||||||
if(toRight) elements.reverse();
|
|
||||||
elements[0].style.filter = `brightness(80%)`;
|
|
||||||
elements[0].style.transform = `translate3d(${-width * .25}px, 0, 0)`;
|
|
||||||
elements[1].style.transform = `translate3d(${width}px, 0, 0)`;
|
|
||||||
|
|
||||||
tabContent.classList.add('active');
|
|
||||||
void tabContent.offsetWidth; // reflow
|
|
||||||
|
|
||||||
tabContent.style.transform = '';
|
|
||||||
tabContent.style.filter = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function slideTabs(tabContent: HTMLElement, prevTabContent: HTMLElement, width: number, toRight: boolean) {
|
|
||||||
const elements = [tabContent, prevTabContent];
|
|
||||||
if(toRight) elements.reverse();
|
|
||||||
elements[0].style.transform = `translate3d(${-width}px, 0, 0)`;
|
|
||||||
elements[1].style.transform = `translate3d(${width}px, 0, 0)`;
|
|
||||||
|
|
||||||
tabContent.classList.add('active');
|
|
||||||
void tabContent.offsetWidth; // reflow
|
|
||||||
|
|
||||||
tabContent.style.transform = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function horizontalMenu(tabs: HTMLElement, content: HTMLElement, onClick?: (id: number, tabContent: HTMLDivElement) => void, onTransitionEnd?: () => void, transitionTime = 250) {
|
export function horizontalMenu(tabs: HTMLElement, content: HTMLElement, onClick?: (id: number, tabContent: HTMLDivElement) => void, onTransitionEnd?: () => void, transitionTime = 250) {
|
||||||
const hideTimeouts: {[id: number]: number} = {};
|
|
||||||
//const deferred: (() => void)[] = [];
|
|
||||||
let transitionEndTimeout: number;
|
|
||||||
let prevTabContent: HTMLElement = null;
|
|
||||||
let prevId = -1;
|
let prevId = -1;
|
||||||
|
|
||||||
const selectTab = (id: number, animate = true) => {
|
const selectTab = Transition(content, tabs || content.dataset.slider == 'tabs' ? 'tabs' : 'navigation', transitionTime, onTransitionEnd);
|
||||||
if(id == prevId) return false;
|
|
||||||
|
|
||||||
//console.log('selectTab id:', id);
|
|
||||||
|
|
||||||
const p = prevTabContent;
|
|
||||||
const tabContent = content.children[id] as HTMLElement;
|
|
||||||
|
|
||||||
// * means animation isn't needed
|
|
||||||
if(content.dataset.slider == 'none' || !animate) {
|
|
||||||
if(p) {
|
|
||||||
p.classList.remove('active');
|
|
||||||
}
|
|
||||||
|
|
||||||
tabContent.classList.add('active');
|
|
||||||
|
|
||||||
prevId = id;
|
|
||||||
prevTabContent = tabContent;
|
|
||||||
|
|
||||||
if(onTransitionEnd) onTransitionEnd();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(prevTabContent) {
|
|
||||||
prevTabContent.classList.remove('to');
|
|
||||||
}
|
|
||||||
|
|
||||||
const toRight = prevId < id;
|
|
||||||
if(!tabContent) {
|
|
||||||
//prevTabContent.classList.remove('active');
|
|
||||||
} else if(prevId != -1) {
|
|
||||||
const width = prevTabContent.getBoundingClientRect().width;
|
|
||||||
|
|
||||||
if(tabs || content.dataset.slider == 'tabs') {
|
|
||||||
slideTabs(tabContent, prevTabContent, width, toRight);
|
|
||||||
} else {
|
|
||||||
slideNavigation(tabContent, prevTabContent, width, toRight);
|
|
||||||
}
|
|
||||||
|
|
||||||
tabContent.classList.add('to');
|
|
||||||
} else {
|
|
||||||
tabContent.classList.add('active');
|
|
||||||
}
|
|
||||||
|
|
||||||
const _prevId = prevId;
|
|
||||||
if(hideTimeouts.hasOwnProperty(id)) clearTimeout(hideTimeouts[id]);
|
|
||||||
if(p/* && false */) {
|
|
||||||
hideTimeouts[_prevId] = window.setTimeout(() => {
|
|
||||||
p.style.transform = '';
|
|
||||||
p.style.filter = '';
|
|
||||||
p.classList.remove('active');
|
|
||||||
|
|
||||||
if(tabContent) {
|
|
||||||
tabContent.classList.remove('to');
|
|
||||||
}
|
|
||||||
|
|
||||||
delete hideTimeouts[_prevId];
|
|
||||||
}, /* 420 */transitionTime);
|
|
||||||
|
|
||||||
if(onTransitionEnd) {
|
|
||||||
if(transitionEndTimeout) clearTimeout(transitionEndTimeout);
|
|
||||||
transitionEndTimeout = window.setTimeout(() => {
|
|
||||||
onTransitionEnd();
|
|
||||||
transitionEndTimeout = 0;
|
|
||||||
}, transitionTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prevId = id;
|
|
||||||
prevTabContent = tabContent;
|
|
||||||
|
|
||||||
/* if(p) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
deferred.push(resolve);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return Promise.resolve();
|
|
||||||
} */
|
|
||||||
};
|
|
||||||
|
|
||||||
if(tabs) {
|
if(tabs) {
|
||||||
const useStripe = !tabs.classList.contains('no-stripe');
|
const useStripe = !tabs.classList.contains('no-stripe');
|
||||||
@ -173,6 +66,8 @@ export function horizontalMenu(tabs: HTMLElement, content: HTMLElement, onClick?
|
|||||||
|
|
||||||
target.classList.add('active');
|
target.classList.add('active');
|
||||||
selectTab(id);
|
selectTab(id);
|
||||||
|
|
||||||
|
prevId = id;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,29 +1,30 @@
|
|||||||
//import { logger } from "../polyfill";
|
//import { logger } from "../polyfill";
|
||||||
import appDialogsManager from "../../lib/appManagers/appDialogsManager";
|
|
||||||
import { findUpTag, findUpClassName, formatNumber } from "../../lib/utils";
|
|
||||||
import appImManager from "../../lib/appManagers/appImManager";
|
|
||||||
import AppSearch, { SearchGroup } from "../appSearch";
|
|
||||||
import { parseMenuButtonsTo } from "../misc";
|
|
||||||
import appUsersManager from "../../lib/appManagers/appUsersManager";
|
|
||||||
import { ScrollableX } from "../scrollable";
|
|
||||||
import AvatarElement from "../avatar";
|
|
||||||
import AppNewChannelTab from "./tabs/newChannel";
|
|
||||||
import AppAddMembersTab from "./tabs/addMembers";
|
|
||||||
import AppContactsTab from "./tabs/contacts";
|
|
||||||
import AppNewGroupTab from "./tabs/newGroup";
|
|
||||||
import AppSettingsTab from "./tabs/settings";
|
|
||||||
import AppEditProfileTab from "./tabs/editProfile";
|
|
||||||
import AppChatFoldersTab from "./tabs/chatFolders";
|
|
||||||
import AppEditFolderTab from "./tabs/editFolder";
|
|
||||||
import AppIncludedChatsTab from "./tabs/includedChats";
|
|
||||||
import SidebarSlider from "../slider";
|
|
||||||
import SearchInput from "../searchInput";
|
|
||||||
import appStateManager from "../../lib/appManagers/appStateManager";
|
|
||||||
import appChatsManager from "../../lib/appManagers/appChatsManager";
|
import appChatsManager from "../../lib/appManagers/appChatsManager";
|
||||||
|
import appDialogsManager from "../../lib/appManagers/appDialogsManager";
|
||||||
|
import appImManager from "../../lib/appManagers/appImManager";
|
||||||
|
import appPeersManager from "../../lib/appManagers/appPeersManager";
|
||||||
|
import appStateManager from "../../lib/appManagers/appStateManager";
|
||||||
|
import appUsersManager from "../../lib/appManagers/appUsersManager";
|
||||||
import { MOUNT_CLASS_TO } from "../../lib/mtproto/mtproto_config";
|
import { MOUNT_CLASS_TO } from "../../lib/mtproto/mtproto_config";
|
||||||
import $rootScope from "../../lib/rootScope";
|
import $rootScope from "../../lib/rootScope";
|
||||||
import appPeersManager from "../../lib/appManagers/appPeersManager";
|
import { findUpClassName, findUpTag, formatNumber } from "../../lib/utils";
|
||||||
|
import AppSearch, { SearchGroup } from "../appSearch";
|
||||||
|
import AvatarElement from "../avatar";
|
||||||
|
import { parseMenuButtonsTo } from "../misc";
|
||||||
|
import { ScrollableX } from "../scrollable";
|
||||||
|
import SearchInput from "../searchInput";
|
||||||
|
import SidebarSlider from "../slider";
|
||||||
|
import Transition from "../transition";
|
||||||
|
import AppAddMembersTab from "./tabs/addMembers";
|
||||||
import AppArchivedTab from "./tabs/archivedTab";
|
import AppArchivedTab from "./tabs/archivedTab";
|
||||||
|
import AppChatFoldersTab from "./tabs/chatFolders";
|
||||||
|
import AppContactsTab from "./tabs/contacts";
|
||||||
|
import AppEditFolderTab from "./tabs/editFolder";
|
||||||
|
import AppEditProfileTab from "./tabs/editProfile";
|
||||||
|
import AppIncludedChatsTab from "./tabs/includedChats";
|
||||||
|
import AppNewChannelTab from "./tabs/newChannel";
|
||||||
|
import AppNewGroupTab from "./tabs/newGroup";
|
||||||
|
import AppSettingsTab from "./tabs/settings";
|
||||||
|
|
||||||
AvatarElement;
|
AvatarElement;
|
||||||
|
|
||||||
@ -38,6 +39,30 @@ const editFolderTab = new AppEditFolderTab();
|
|||||||
const includedChatsTab = new AppIncludedChatsTab();
|
const includedChatsTab = new AppIncludedChatsTab();
|
||||||
const archivedTab = new AppArchivedTab();
|
const archivedTab = new AppArchivedTab();
|
||||||
|
|
||||||
|
/* const Transition = (container: HTMLElement, duration: number, from: HTMLElement, to: HTMLElement) => {
|
||||||
|
if(to.classList.contains('active')) return Promise.resolve();
|
||||||
|
|
||||||
|
container.classList.add('animating');
|
||||||
|
|
||||||
|
const backwards = whichChild(to) < whichChild(from);
|
||||||
|
|
||||||
|
if(backwards) {
|
||||||
|
container.classList.add('backwards');
|
||||||
|
}
|
||||||
|
|
||||||
|
from.classList.add('from');
|
||||||
|
to.classList.add('to');
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
from.classList.remove('from', 'active');
|
||||||
|
container.classList.remove('animating', 'backwards');
|
||||||
|
to.classList.replace('to', 'active');
|
||||||
|
resolve();
|
||||||
|
}, duration);
|
||||||
|
});
|
||||||
|
}; */
|
||||||
|
|
||||||
export class AppSidebarLeft extends SidebarSlider {
|
export class AppSidebarLeft extends SidebarSlider {
|
||||||
public static SLIDERITEMSIDS = {
|
public static SLIDERITEMSIDS = {
|
||||||
archived: 1,
|
archived: 1,
|
||||||
@ -195,12 +220,28 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let hideNewBtnMenuTimeout: number;
|
||||||
|
//const transition = Transition.bind(null, this.searchContainer.parentElement, 150);
|
||||||
|
const transition = Transition(this.searchContainer.parentElement, 'zoom-fade', 150, (id) => {
|
||||||
|
if(hideNewBtnMenuTimeout) clearTimeout(hideNewBtnMenuTimeout);
|
||||||
|
|
||||||
|
if(id == 0) {
|
||||||
|
this.globalSearch.reset();
|
||||||
|
hideNewBtnMenuTimeout = window.setTimeout(() => {
|
||||||
|
hideNewBtnMenuTimeout = 0;
|
||||||
|
this.newBtnMenu.classList.remove('is-hidden');
|
||||||
|
}, 150);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
transition(0);
|
||||||
|
|
||||||
const onFocus = () => {
|
const onFocus = () => {
|
||||||
this.toolsBtn.classList.remove('active');
|
this.toolsBtn.classList.remove('active');
|
||||||
this.backBtn.classList.add('active');
|
this.backBtn.classList.add('active');
|
||||||
this.searchContainer.classList.remove('hide');
|
this.newBtnMenu.classList.add('is-hidden');
|
||||||
void this.searchContainer.offsetWidth; // reflow
|
|
||||||
this.searchContainer.classList.add('active');
|
transition(1);
|
||||||
|
|
||||||
if(firstTime) {
|
if(firstTime) {
|
||||||
this.searchGroups.people.setActive();
|
this.searchGroups.people.setActive();
|
||||||
@ -225,13 +266,9 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
//appDialogsManager.chatsArchivedContainer.classList.remove('active');
|
//appDialogsManager.chatsArchivedContainer.classList.remove('active');
|
||||||
this.toolsBtn.classList.add('active');
|
this.toolsBtn.classList.add('active');
|
||||||
this.backBtn.classList.remove('active');
|
this.backBtn.classList.remove('active');
|
||||||
this.searchContainer.classList.remove('active');
|
|
||||||
firstTime = true;
|
firstTime = true;
|
||||||
|
|
||||||
setTimeout(() => {
|
transition(0);
|
||||||
this.searchContainer.classList.add('hide');
|
|
||||||
this.globalSearch.reset();
|
|
||||||
}, 150);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.renderRecentSearch();
|
this.renderRecentSearch();
|
||||||
|
123
src/components/transition.ts
Normal file
123
src/components/transition.ts
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
function slideNavigation(tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) {
|
||||||
|
const width = prevTabContent.getBoundingClientRect().width;
|
||||||
|
const elements = [tabContent, prevTabContent];
|
||||||
|
if(toRight) elements.reverse();
|
||||||
|
elements[0].style.filter = `brightness(80%)`;
|
||||||
|
elements[0].style.transform = `translate3d(${-width * .25}px, 0, 0)`;
|
||||||
|
elements[1].style.transform = `translate3d(${width}px, 0, 0)`;
|
||||||
|
|
||||||
|
tabContent.classList.add('active');
|
||||||
|
void tabContent.offsetWidth; // reflow
|
||||||
|
|
||||||
|
tabContent.style.transform = '';
|
||||||
|
tabContent.style.filter = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function slideTabs(tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) {
|
||||||
|
const width = prevTabContent.getBoundingClientRect().width;
|
||||||
|
const elements = [tabContent, prevTabContent];
|
||||||
|
if(toRight) elements.reverse();
|
||||||
|
elements[0].style.transform = `translate3d(${-width}px, 0, 0)`;
|
||||||
|
elements[1].style.transform = `translate3d(${width}px, 0, 0)`;
|
||||||
|
|
||||||
|
tabContent.classList.add('active');
|
||||||
|
void tabContent.offsetWidth; // reflow
|
||||||
|
|
||||||
|
tabContent.style.transform = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const Transition = (content: HTMLElement, type: 'tabs' | 'navigation' | 'zoom-fade', transitionTime: number, onTransitionEnd?: (id: number) => void) => {
|
||||||
|
const hideTimeouts: {[id: number]: number} = {};
|
||||||
|
//const deferred: (() => void)[] = [];
|
||||||
|
let transitionEndTimeout: number;
|
||||||
|
let prevTabContent: HTMLElement = null;
|
||||||
|
let prevId = -1;
|
||||||
|
|
||||||
|
const animationFunction = type == 'zoom-fade' ? null : (type == 'tabs' ? slideTabs : slideNavigation);
|
||||||
|
|
||||||
|
const selectTab = (id: number, animate = true) => {
|
||||||
|
if(id == prevId) return false;
|
||||||
|
|
||||||
|
//console.log('selectTab id:', id);
|
||||||
|
|
||||||
|
const p = prevTabContent;
|
||||||
|
const tabContent = content.children[id] as HTMLElement;
|
||||||
|
|
||||||
|
// * means animation isn't needed
|
||||||
|
if(content.dataset.slider == 'none' || !animate) {
|
||||||
|
if(p) {
|
||||||
|
p.classList.remove('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
tabContent.classList.add('active');
|
||||||
|
|
||||||
|
prevId = id;
|
||||||
|
prevTabContent = tabContent;
|
||||||
|
|
||||||
|
if(onTransitionEnd) onTransitionEnd(prevId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(prevTabContent) {
|
||||||
|
prevTabContent.classList.remove('to');
|
||||||
|
prevTabContent.classList.add('from');
|
||||||
|
}
|
||||||
|
|
||||||
|
content.classList.add('animating');
|
||||||
|
const toRight = prevId < id;
|
||||||
|
content.classList.toggle('backwards', !toRight);
|
||||||
|
|
||||||
|
if(!tabContent) {
|
||||||
|
//prevTabContent.classList.remove('active');
|
||||||
|
} else if(prevId != -1) {
|
||||||
|
if(animationFunction) {
|
||||||
|
animationFunction(tabContent, prevTabContent, toRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
tabContent.classList.add('to');
|
||||||
|
} else {
|
||||||
|
tabContent.classList.add('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
const _prevId = prevId;
|
||||||
|
if(hideTimeouts.hasOwnProperty(id)) clearTimeout(hideTimeouts[id]);
|
||||||
|
if(p/* && false */) {
|
||||||
|
hideTimeouts[_prevId] = window.setTimeout(() => {
|
||||||
|
p.style.transform = p.style.filter = '';
|
||||||
|
p.classList.remove('active', 'from');
|
||||||
|
|
||||||
|
content.classList.remove('animating', 'backwards');
|
||||||
|
|
||||||
|
if(tabContent) {
|
||||||
|
tabContent.classList.remove('to');
|
||||||
|
tabContent.classList.add('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
delete hideTimeouts[_prevId];
|
||||||
|
}, transitionTime);
|
||||||
|
|
||||||
|
if(onTransitionEnd) {
|
||||||
|
if(transitionEndTimeout) clearTimeout(transitionEndTimeout);
|
||||||
|
transitionEndTimeout = window.setTimeout(() => {
|
||||||
|
onTransitionEnd(prevId);
|
||||||
|
transitionEndTimeout = 0;
|
||||||
|
}, transitionTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prevId = id;
|
||||||
|
prevTabContent = tabContent;
|
||||||
|
|
||||||
|
/* if(p) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
deferred.push(resolve);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return Promise.resolve();
|
||||||
|
} */
|
||||||
|
};
|
||||||
|
|
||||||
|
return selectTab;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Transition;
|
@ -209,8 +209,8 @@
|
|||||||
<div class="btn-icon tgico-back rp sidebar-back-button"></div>
|
<div class="btn-icon tgico-back rp sidebar-back-button"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-content">
|
<div class="sidebar-content transition zoom-fade">
|
||||||
<div id="chats-container">
|
<div class="transition-item active" id="chats-container">
|
||||||
<div class="folders-tabs-scrollable hide">
|
<div class="folders-tabs-scrollable hide">
|
||||||
<nav class="menu-horizontal" id="folders-tabs">
|
<nav class="menu-horizontal" id="folders-tabs">
|
||||||
<ul>
|
<ul>
|
||||||
@ -225,7 +225,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-search hide" id="search-container"></div>
|
<div class="transition-item sidebar-search" id="search-container"></div>
|
||||||
<button class="btn-primary btn-circle btn-icon rp btn-corner tgico-newchat_filled btn-menu-toggle" id="new-menu">
|
<button class="btn-primary btn-circle btn-icon rp btn-corner tgico-newchat_filled btn-menu-toggle" id="new-menu">
|
||||||
<div class="btn-menu top-left">
|
<div class="btn-menu top-left">
|
||||||
<div class="btn-menu-item menu-channel tgico-newchannel rp">New Channel</div>
|
<div class="btn-menu-item menu-channel tgico-newchannel rp">New Channel</div>
|
||||||
|
@ -27,7 +27,7 @@ avatar-element {
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
&.fade-in {
|
&.fade-in {
|
||||||
animation: fadeIn .2s ease forwards;
|
animation: fade-in-opacity .2s ease forwards;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1649,7 +1649,7 @@ poll-element {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation: fadeIn .1s ease forwards;
|
animation: fade-in-opacity .1s ease forwards;
|
||||||
animation-direction: reverse;
|
animation-direction: reverse;
|
||||||
animation-delay: .24s;
|
animation-delay: .24s;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -240,7 +240,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
> img {
|
> img {
|
||||||
animation: fadeIn .2s ease forwards;
|
animation: fade-in-opacity .2s ease forwards;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,31 +273,25 @@
|
|||||||
bottom: 14px;
|
bottom: 14px;
|
||||||
right: 14px;
|
right: 14px;
|
||||||
|
|
||||||
transform: translateY(0px);
|
|
||||||
position: fixed !important;
|
position: fixed !important;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
|
&:not(.is-hidden) {
|
||||||
|
transform: translateZ(0px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include respond-to(not-handhelds) {
|
@include respond-to(not-handhelds) {
|
||||||
html.no-touch &:hover .btn-corner {
|
html.no-touch &:hover .btn-corner:not(.is-hidden) {
|
||||||
transform: translateY(0px);
|
transform: translateZ(0px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#search-container {
|
#search-container {
|
||||||
transition: .15s ease-in-out opacity, .15s ease-in-out transform;
|
|
||||||
transform: scale(1.1, 1.1);
|
|
||||||
opacity: 0;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
&.active {
|
|
||||||
transform: scale(1, 1);
|
|
||||||
transform-origin: center;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.new-channel-container, .new-group-container, .edit-profile-container {
|
.new-channel-container, .new-group-container, .edit-profile-container {
|
||||||
|
@ -455,7 +455,7 @@ input, textarea {
|
|||||||
z-index: 4;
|
z-index: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fadeIn {
|
@keyframes fade-in-opacity {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
@ -465,7 +465,35 @@ input, textarea {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fadeInFadeOut {
|
@keyframes fade-out-opacity {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in-backwards-opacity {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-out-backwards-opacity {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in-opacity-fade-out-opacity {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
@ -493,7 +521,7 @@ input, textarea {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
border-radius: $border-radius-medium;
|
border-radius: $border-radius-medium;
|
||||||
animation: fadeInFadeOut 3s linear forwards;
|
animation: fade-in-opacity-fade-out-opacity 3s linear forwards;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1146,7 +1174,7 @@ img.emoji {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
&.fade-in {
|
&.fade-in {
|
||||||
animation: fadeIn .2s ease forwards;
|
animation: fade-in-opacity .2s ease forwards;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1256,6 +1284,113 @@ img.emoji {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.transition {
|
||||||
|
.transition-item {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
animation-fill-mode: forwards!important;
|
||||||
|
|
||||||
|
&:not(.active):not(.from):not(.to) {
|
||||||
|
display: none !important; // Best performance when animating container
|
||||||
|
//transform: scale(0); // Shortest initial delay
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* zoom-fade
|
||||||
|
*/
|
||||||
|
&.zoom-fade {
|
||||||
|
> .from {
|
||||||
|
transform-origin: center;
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .to {
|
||||||
|
transform-origin: center;
|
||||||
|
opacity: 0;
|
||||||
|
// We can omit `transform: scale(1.1);` here because `opacity` is 0.
|
||||||
|
// We need to for proper position calculation in `InfiniteScroll`.
|
||||||
|
}
|
||||||
|
|
||||||
|
&.animating {
|
||||||
|
> .from {
|
||||||
|
animation: fade-out-opacity .15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .to {
|
||||||
|
animation: fade-in-opacity .15s ease, zoom-fade-in-move .15s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.zoom-fade.backwards {
|
||||||
|
> .from {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
> .to {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.animating {
|
||||||
|
> .from {
|
||||||
|
animation: fade-in-backwards-opacity .1s ease, zoom-fade-in-backwards-move .15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .to {
|
||||||
|
animation: fade-out-backwards-opacity .15s ease, zoom-fade-out-backwards-move .15s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* zoom-fade
|
||||||
|
*/
|
||||||
|
@keyframes zoom-fade-in-move {
|
||||||
|
0% {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes zoom-fade-in-backwards-move {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes zoom-fade-out-backwards-move {
|
||||||
|
0% {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .zoom-fade {
|
||||||
|
transition: .15s ease-in-out opacity, .15s ease-in-out transform;
|
||||||
|
transform: scale3d(1.1, 1.1, 1);
|
||||||
|
opacity: 0;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
transform: scale3d(1, 1, 1);
|
||||||
|
transform-origin: center;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
// *:not(input):not(textarea) {
|
// *:not(input):not(textarea) {
|
||||||
// -webkit-user-select: none; /* disable selection/Copy of UIWebView */
|
// -webkit-user-select: none; /* disable selection/Copy of UIWebView */
|
||||||
// -webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */
|
// -webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user