Prevent layout recalculations in some animations
This commit is contained in:
parent
97454b6bac
commit
e3299b0445
10 changed files with 52 additions and 27 deletions
|
@ -3924,8 +3924,8 @@ button.module-image__border-overlay:focus {
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
transition: top 200ms linear, left 200ms linear, width 200ms linear,
|
transform: translate(0, 0);
|
||||||
height 200ms linear;
|
transition: transform 200ms linear, width 200ms linear, height 200ms linear;
|
||||||
|
|
||||||
&__remote-video {
|
&__remote-video {
|
||||||
// The background-color is seen while the video loads.
|
// The background-color is seen while the video loads.
|
||||||
|
|
|
@ -13,12 +13,13 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
top: 12px;
|
top: 12px;
|
||||||
transition: top 200ms ease-out, opacity 200ms ease-out;
|
transform: translateY(0);
|
||||||
|
transition: transform 200ms ease-out, opacity 200ms ease-out;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
z-index: $z-index-above-above-base;
|
z-index: $z-index-above-above-base;
|
||||||
|
|
||||||
&--hidden {
|
&--hidden {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
top: 5px;
|
transform: translateY(-7px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,11 +55,12 @@
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
min-width: 24px;
|
min-width: 24px;
|
||||||
margin-left: -24px;
|
margin-left: 12px;
|
||||||
|
transform: translateX(-36px);
|
||||||
vertical-align: text-bottom;
|
vertical-align: text-bottom;
|
||||||
border: none;
|
border: none;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: margin-left $transition, opacity $transition;
|
transition: transform $transition, opacity $transition;
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
@ -68,7 +69,7 @@
|
||||||
&--show {
|
&--show {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
margin-left: 12px;
|
transform: translateX(0px);
|
||||||
}
|
}
|
||||||
|
|
||||||
@include light-theme {
|
@include light-theme {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
&__container {
|
&__container {
|
||||||
animation: IncomingCallBar--animation 0.2s forwards ease-out;
|
animation: IncomingCallBar--animation 0.2s forwards ease-out;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
top: 22px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: $z-index-popup;
|
z-index: $z-index-popup;
|
||||||
padding: {
|
padding: {
|
||||||
|
@ -185,12 +186,12 @@
|
||||||
|
|
||||||
@keyframes IncomingCallBar--animation {
|
@keyframes IncomingCallBar--animation {
|
||||||
from {
|
from {
|
||||||
top: -100px;
|
transform: translateY(-100px);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
top: 22px;
|
transform: translateY(0px);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
animation: 500ms module-InstallScreenQrCodeNotScannedStep__slide-in;
|
animation: 500ms module-InstallScreenQrCodeNotScannedStep__slide-in;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
@include light-theme {
|
@include light-theme {
|
||||||
max-width: $base-max-width;
|
max-width: $base-max-width;
|
||||||
|
@ -113,12 +114,12 @@
|
||||||
|
|
||||||
@keyframes module-InstallScreenQrCodeNotScannedStep__slide-in {
|
@keyframes module-InstallScreenQrCodeNotScannedStep__slide-in {
|
||||||
from {
|
from {
|
||||||
top: -8px;
|
transform: translateY(-8px);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
top: 0;
|
transform: translateY(0px);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,7 +238,9 @@
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
display: block;
|
display: block;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
transition: width 500ms ease-out;
|
width: 100%;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
transition: transform 500ms ease-out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,33 +115,33 @@ export function CallingToastManager(props: PropsType): JSX.Element {
|
||||||
toast = screenSharingToast;
|
toast = screenSharingToast;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [toastMessage, setToastMessage] = useState('');
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||||
|
|
||||||
const dismissToast = useCallback(() => {
|
const dismissToast = useCallback(() => {
|
||||||
if (timeoutRef) {
|
if (timeoutRef) {
|
||||||
setToastMessage('');
|
setIsVisible(false);
|
||||||
}
|
}
|
||||||
}, [setToastMessage, timeoutRef]);
|
}, [setIsVisible, timeoutRef]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (toast) {
|
setIsVisible(toast !== undefined);
|
||||||
if (toast.type === 'dismissable') {
|
}, [toast]);
|
||||||
clearTimeoutIfNecessary(timeoutRef.current);
|
|
||||||
timeoutRef.current = setTimeout(dismissToast, DEFAULT_LIFETIME);
|
|
||||||
}
|
|
||||||
|
|
||||||
setToastMessage(toast.message);
|
useEffect(() => {
|
||||||
|
if (toast?.type === 'dismissable') {
|
||||||
|
clearTimeoutIfNecessary(timeoutRef.current);
|
||||||
|
timeoutRef.current = setTimeout(dismissToast, DEFAULT_LIFETIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeoutIfNecessary(timeoutRef.current);
|
clearTimeoutIfNecessary(timeoutRef.current);
|
||||||
};
|
};
|
||||||
}, [dismissToast, setToastMessage, timeoutRef, toast]);
|
}, [dismissToast, setIsVisible, timeoutRef, toast]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CallingToast isVisible={Boolean(toastMessage)} onClick={dismissToast}>
|
<CallingToast isVisible={isVisible} onClick={dismissToast}>
|
||||||
{toastMessage}
|
{toast?.message}
|
||||||
</CallingToast>
|
</CallingToast>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { action } from '@storybook/addon-actions';
|
||||||
import { DialogUpdate } from './DialogUpdate';
|
import { DialogUpdate } from './DialogUpdate';
|
||||||
import { DialogType } from '../types/Dialogs';
|
import { DialogType } from '../types/Dialogs';
|
||||||
import { WidthBreakpoint } from './_util';
|
import { WidthBreakpoint } from './_util';
|
||||||
|
import { SECOND } from '../util/durations';
|
||||||
import { FakeLeftPaneContainer } from '../test-both/helpers/FakeLeftPaneContainer';
|
import { FakeLeftPaneContainer } from '../test-both/helpers/FakeLeftPaneContainer';
|
||||||
|
|
||||||
import { setupI18n } from '../util/setupI18n';
|
import { setupI18n } from '../util/setupI18n';
|
||||||
|
@ -110,10 +111,29 @@ FullDownloadReadyWide.story = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function DownloadingWide(): JSX.Element {
|
export function DownloadingWide(): JSX.Element {
|
||||||
|
const [downloadedSize, setDownloadedSize] = React.useState(0);
|
||||||
|
|
||||||
|
const { downloadSize } = defaultProps;
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
setDownloadedSize(x => {
|
||||||
|
const newValue = x + 0.25 * downloadSize;
|
||||||
|
if (newValue > downloadSize) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
|
}, SECOND);
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [downloadSize]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FakeLeftPaneContainer containerWidthBreakpoint={WidthBreakpoint.Wide}>
|
<FakeLeftPaneContainer containerWidthBreakpoint={WidthBreakpoint.Wide}>
|
||||||
<DialogUpdate
|
<DialogUpdate
|
||||||
{...defaultProps}
|
{...defaultProps}
|
||||||
|
downloadedSize={downloadedSize}
|
||||||
containerWidthBreakpoint={WidthBreakpoint.Wide}
|
containerWidthBreakpoint={WidthBreakpoint.Wide}
|
||||||
currentVersion="5.24.0"
|
currentVersion="5.24.0"
|
||||||
dialogType={DialogType.Downloading}
|
dialogType={DialogType.Downloading}
|
||||||
|
|
|
@ -204,7 +204,7 @@ export function DialogUpdate({
|
||||||
<div className="LeftPaneDialog__progress--container">
|
<div className="LeftPaneDialog__progress--container">
|
||||||
<div
|
<div
|
||||||
className="LeftPaneDialog__progress--bar"
|
className="LeftPaneDialog__progress--bar"
|
||||||
style={{ width: `${width}%` }}
|
style={{ transform: `translateX(${width - 100}%)` }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</LeftPaneDialog>
|
</LeftPaneDialog>
|
||||||
|
|
|
@ -235,8 +235,7 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = React.memo(
|
||||||
|
|
||||||
if ('top' in props) {
|
if ('top' in props) {
|
||||||
containerStyles.position = 'absolute';
|
containerStyles.position = 'absolute';
|
||||||
containerStyles.top = props.top;
|
containerStyles.transform = `translate(${props.left}px, ${props.top}px)`;
|
||||||
containerStyles.left = props.left;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue