From bd58bca39c029e693eefee1a99433ab927ef706e Mon Sep 17 00:00:00 2001 From: Tilman Vatteroth Date: Wed, 4 May 2022 19:21:26 +0200 Subject: [PATCH] Add new loading animation Signed-off-by: Tilman Vatteroth --- .../animated-hedge-doc-logo.tsx | 35 ------- .../loading-screen/animations.module.scss | 97 +++++++++++++++++++ .../loading-screen/icon-row.tsx | 19 ++++ .../animations.module.scss => keyframes.scss} | 86 +++++++++------- .../loading-screen/loading-animation.tsx | 39 ++++++++ .../loading-screen/loading-screen.tsx | 4 +- .../loading-screen/random-icon.tsx | 34 +++++++ 7 files changed, 242 insertions(+), 72 deletions(-) delete mode 100644 src/components/application-loader/loading-screen/animated-hedge-doc-logo/animated-hedge-doc-logo.tsx create mode 100644 src/components/application-loader/loading-screen/animations.module.scss create mode 100644 src/components/application-loader/loading-screen/icon-row.tsx rename src/components/application-loader/loading-screen/{animated-hedge-doc-logo/animations.module.scss => keyframes.scss} (52%) create mode 100644 src/components/application-loader/loading-screen/loading-animation.tsx create mode 100644 src/components/application-loader/loading-screen/random-icon.tsx diff --git a/src/components/application-loader/loading-screen/animated-hedge-doc-logo/animated-hedge-doc-logo.tsx b/src/components/application-loader/loading-screen/animated-hedge-doc-logo/animated-hedge-doc-logo.tsx deleted file mode 100644 index 74661f69c..000000000 --- a/src/components/application-loader/loading-screen/animated-hedge-doc-logo/animated-hedge-doc-logo.tsx +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) - * - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import React from 'react' -import LogoColor from '../../../common/hedge-doc-logo/logo_color.svg' -import styles from './animations.module.scss' - -export interface HedgeDocLogoProps { - animation: AnimationType -} - -export enum AnimationType { - JUMP = 'animation-jump', - SHAKE = 'animation-shake' -} - -/** - * Shows an animated hedgedoc logo. - * - * @param animation The name of the animation - */ -export const AnimatedHedgeDocLogo: React.FC = ({ animation }) => { - return ( - - ) -} diff --git a/src/components/application-loader/loading-screen/animations.module.scss b/src/components/application-loader/loading-screen/animations.module.scss new file mode 100644 index 000000000..a3fac7966 --- /dev/null +++ b/src/components/application-loader/loading-screen/animations.module.scss @@ -0,0 +1,97 @@ +/*! + * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +@import "keyframes"; + +.rows { + transition: opacity 0.2s; + + .row { + position: absolute; + top: 50%; + left: 50%; + } + + .particle { + width: 24px; + height: 24px; + position: absolute; + font-size: 1.3em !important; + top: calc(50% - 12px); + left: calc(50% - 12px); + animation: particle 3s infinite; + } + + @for $i from 1 through 12 { + .row:nth-child(#{$i}) { + transform: rotateZ(30deg * ($i - 1)); + + @for $j from 1 through 10 { + & .particle:nth-child(#{$j}) { + opacity: 0; + animation-timing-function: ease-out; + animation-delay: -$i * 830ms - $j * 600ms; + } + } + } + } +} + +.logo { + z-index: 1000; + position: relative; + font-size: 3em; + height: 240px; + width: 203px; + color: #ffffff; + text-shadow: 4px 4px 0 #3b4045; + + .overlay { + color: rgb(181, 31, 8); + height: 0; + overflow: hidden; + animation: fill 6s infinite; + width: 100%; + + &, :global(.fa) { + position: absolute; + bottom: 0; + left: 0; + } + } +} + +.pulse { + animation: 3s pulse infinite; + box-shadow: #404040 0 0 200px 100px; + position: absolute; + left: 0; + top: 0; + width: 1px; + height: 1px; + border-radius: 100%; + margin: auto; + right: 0; + bottom: 0; +} + +.error { + .channels { + opacity: 0; + } + + .pulse { + animation: none; + } + + .logo { + .overlay { + animation: none; + } + + color: rgb(181, 31, 8); + animation: 1s shake; + } +} diff --git a/src/components/application-loader/loading-screen/icon-row.tsx b/src/components/application-loader/loading-screen/icon-row.tsx new file mode 100644 index 000000000..6c4562b08 --- /dev/null +++ b/src/components/application-loader/loading-screen/icon-row.tsx @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import React, { useMemo } from 'react' +import { createNumberRangeArray } from '../../common/number-range/number-range' +import { RandomIcon } from './random-icon' +import styles from './animations.module.scss' + +/** + * Shows a number of {@link RandomIcon random icons in a row}. + */ +export const IconRow: React.FC = () => { + const children = useMemo(() => createNumberRangeArray(5).map((index) => ), []) + + return
{children}
+} diff --git a/src/components/application-loader/loading-screen/animated-hedge-doc-logo/animations.module.scss b/src/components/application-loader/loading-screen/keyframes.scss similarity index 52% rename from src/components/application-loader/loading-screen/animated-hedge-doc-logo/animations.module.scss rename to src/components/application-loader/loading-screen/keyframes.scss index 9370c9ab7..2fbbb70fe 100644 --- a/src/components/application-loader/loading-screen/animated-hedge-doc-logo/animations.module.scss +++ b/src/components/application-loader/loading-screen/keyframes.scss @@ -1,34 +1,10 @@ -/* - * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) +/*! + * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ -@keyframes animation-jump { - 0% { - transform: scale(1, 1) translateY(0); - } - 10% { - transform: scale(1.1, .9) translateY(0); - } - 30% { - transform: scale(.9, 1.1) translateY(-100px); - } - 50% { - transform: scale(1.05, .95) translateY(0); - } - 57% { - transform: scale(1, 1) translateY(-7px); - } - 64% { - transform: scale(1, 1) translateY(0); - } - 100% { - transform: scale(1, 1) translateY(0); - } -} - -@keyframes animation-shake { +@keyframes shake { 0% { transform: translate(1px, 1px) rotate(0deg); } @@ -64,14 +40,54 @@ } } -.animation-jump { - transform-origin: bottom; - animation-duration: 2s; - animation-iteration-count: infinite; - animation-name: animation-jump; - animation-timing-function: cubic-bezier(0.280, 0.840, 0.420, 1); +@keyframes particle { + 0% { + opacity: 0.3; + transform: translate(300px, 300px) rotateZ(360deg); + border-radius: 0; + color: #ffffff; + } + 20% { + border-radius: 0; + } + 70% { + opacity: 1; + transform: translate(120px, 120px) rotateZ(180deg); + border-radius: 10px; + } + 90% { + opacity: 0; + } + 100% { + transform: translate(0px, 0px) rotateZ(0deg); + color: rgb(181, 31, 8); + } } -.animation-shake { - animation: animation-shake 0.3s ease-in-out; +@keyframes fill { + 0% { + height: 0%; + } + + 50% { + height: 70%; + } + + 100%{ + height: 100%; + } +} + +@keyframes pulse { + 0% { + box-shadow: #ffffff00 0 0 200px 100px; + } + + 30% { + box-shadow: #ffffff33 0 0 200px 100px; + } + + 100% { + box-shadow: #ffffff00 0 0 200px 100px; + } } diff --git a/src/components/application-loader/loading-screen/loading-animation.tsx b/src/components/application-loader/loading-screen/loading-animation.tsx new file mode 100644 index 000000000..0a34610e3 --- /dev/null +++ b/src/components/application-loader/loading-screen/loading-animation.tsx @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import React, { useMemo } from 'react' +import styles from './animations.module.scss' +import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { IconRow } from './icon-row' +import { createNumberRangeArray } from '../../common/number-range/number-range' + +export interface HedgeDocLogoProps { + error: boolean +} + +/** + * Shows a loading animation. + * + * @param error Defines if the error animation should be shown instead + */ +export const LoadingAnimation: React.FC = ({ error }) => { + const iconRows = useMemo(() => createNumberRangeArray(12).map((index) => ), []) + + return ( +
+
+
+ +
+
+ +
+
+
+
{iconRows}
+
+ ) +} diff --git a/src/components/application-loader/loading-screen/loading-screen.tsx b/src/components/application-loader/loading-screen/loading-screen.tsx index 69f2891ee..6cb7667f7 100644 --- a/src/components/application-loader/loading-screen/loading-screen.tsx +++ b/src/components/application-loader/loading-screen/loading-screen.tsx @@ -6,7 +6,7 @@ import React from 'react' import { Alert } from 'react-bootstrap' -import { AnimatedHedgeDocLogo, AnimationType } from './animated-hedge-doc-logo/animated-hedge-doc-logo' +import { LoadingAnimation } from './loading-animation' import { ShowIf } from '../../common/show-if/show-if' import styles from '../application-loader.module.scss' @@ -24,7 +24,7 @@ export const LoadingScreen: React.FC = ({ failedTaskName })
- +
diff --git a/src/components/application-loader/loading-screen/random-icon.tsx b/src/components/application-loader/loading-screen/random-icon.tsx new file mode 100644 index 000000000..dfda67f9c --- /dev/null +++ b/src/components/application-loader/loading-screen/random-icon.tsx @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import React, { useMemo } from 'react' +import type { IconName } from '../../common/fork-awesome/types' +import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import styles from './animations.module.scss' + +const elements: IconName[] = [ + 'file-text', + 'markdown', + 'pencil', + 'bold', + 'italic', + 'align-justify', + 'tag', + 'user', + 'file', + 'keyboard-o', + 'cog', + 'font' +] + +/** + * Chooses a random fork awesome icon from a predefined set and renders it. + */ +export const RandomIcon: React.FC = () => { + const icon = useMemo(() => elements[Math.floor(Math.random() * elements.length)], []) + + return +}