Skip to content

Commit

Permalink
ENH Improve loading screen and indicator (#582)
Browse files Browse the repository at this point in the history
* MINOR Improve loading spinner and loading splash

* Always show loading text immediately
  • Loading branch information
Luke Edwards authored and Aaron Carlino committed Nov 1, 2018
1 parent 742a306 commit 2f2fb2b
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 49 deletions.
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/dist/styles/bundle.css

Large diffs are not rendered by default.

44 changes: 43 additions & 1 deletion client/src/components/Loading/Loading.js
@@ -1,3 +1,4 @@
/* global window */
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';

Expand All @@ -11,7 +12,48 @@ class Loading extends PureComponent {
return (
<div className={containerClass}>
<div key="overlay" className="cms-content-loading-overlay ui-widget-overlay-light" />
<div key="spinner" className="cms-content-loading-spinner" />
<div key="spinner" className="cms-content-loading-spinner">
<div className="spinner">
{/* window.location is neccessary for Safari which otherwise prepends the base tag */}
<svg
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
viewBox="0 0 30 30"
width="30"
height="30"
className="spinner__animation"
>
<g>
<defs>
<path
id="spinner__animation__outline"
d="M17.6,9.8c-2.3,1.7-2.8,5-1.1,7.3l4.2-3.1
c1.1-0.8,2.7-0.6,3.6,0.5c0.8,1.1,0.6,2.7-0.5,3.6l-6.2,4.6
c-2.3,1.7-2.8,5-1.1,7.3l10.4-7.7c3.4-2.6,4.1-7.4,1.6-10.8
C25.9,8,21.1,7.3,17.6,9.8z M13.4,12.9L9.3,16c-1.1,0.8-2.7,0.6-3.6-0.5
s-0.6-2.7,0.5-3.6l6.2-4.6c2.3-1.7,2.8-5,1.1-7.3L3.1,7.7
c-3.4,2.6-4.1,7.4-1.6,10.8c2.6,3.4,7.4,4.1,10.8,1.6
C14.7,18.4,15.1,15.2,13.4,12.9z"
/>
<clipPath id="spinner__animation__mask">
<use xlinkHref={`${window.location}#spinner__animation__outline`} />
</clipPath>
</defs>
<use
className="spinner__animation__empty"
xlinkHref={`${window.location}#spinner__animation__outline`}
/>
<path
className="spinner__animation__fill"
clipPath={`url(${window.location}#spinner__animation__mask)`}
d="M15,2.1L4.7,9.8c-2.3,1.7-2.8,4.9-1.1,7.2
s4.9,2.8,7.2,1.1l8.3-6.1c2.3-1.7,5.5-1.2,7.2,1.1
s1.2,5.5-1.1,7.2L15,27.9"
/>
</g>
</svg>
</div>
</div>
</div>
);
}
Expand Down
13 changes: 10 additions & 3 deletions client/src/legacy/LeftAndMain.js
Expand Up @@ -5,7 +5,8 @@ import $ from 'jquery';
import React from 'react';
import ReactDOM from 'react-dom';
import IframeDialog from 'components/IframeDialog/IframeDialog';
import Search from 'components/Search/Search.js';
import Search from 'components/Search/Search';
import Loading from 'components/Loading/Loading';
import { schemaMerge } from 'lib/schemaFieldValues';
import { loadComponent } from 'lib/Injector';

Expand Down Expand Up @@ -1046,12 +1047,18 @@ $.entwine('ss', function($) {
*/
$('form.loading,.cms-content.loading,.cms-content-fields.loading,.cms-content-view.loading,.ss-gridfield-item.loading').entwine({
onmatch: function() {
this.append('<div class="cms-content-loading-overlay ui-widget-overlay-light"></div><div class="cms-content-loading-spinner"></div>');
this._super();
ReactDOM.render(
<Loading />,
this[0]
);
},
onunmatch: function() {
this.find('.cms-content-loading-overlay,.cms-content-loading-spinner').remove();
this._super();
const container = this[0];
if (container) {
ReactDOM.unmountComponentAtNode(container);
}
}
});

Expand Down
6 changes: 0 additions & 6 deletions client/src/styles/legacy/_retina.scss
Expand Up @@ -13,12 +13,6 @@
only screen and ( min-resolution: 192dpi),
only screen and ( min-resolution: 2dppx) {

/* Loading spinner */
.cms-content-loading-spinner {
background-image: url('../../images/spinner@2x.gif');
background-size: 43px 43px;
}

/* Sitetree */
.tree-holder, .cms-tree {
&.jstree-apple {
Expand Down
163 changes: 128 additions & 35 deletions client/src/styles/legacy/_style.scss
Expand Up @@ -708,7 +708,61 @@ html, body {
width: 100%;
height: 100%;
z-index: 9999;
background: url("../images/spinner.gif") no-repeat 50% 50%;
display: flex;
align-items: center;
justify-content: center;

.spinner {
width: 3rem;
height: 3rem;
padding: .5rem;

background-color: $white;
border-radius: $border-radius-sm;

&__animation {
width: 100%;
height: 100%;

&__empty {
fill: $gray-400;
}

&__fill {
fill: none;
stroke: $blue;
stroke-width: 5;
stroke-dasharray: 70;
transform: translateZ(0);
animation: spinner__animation__keyframes 1.5s infinite cubic-bezier(.445, .05, .55, .95)
forwards;

// IE11 doesn't support svg animation so we just animate opacity
@media all and (-ms-high-contrast: none) {
animation: spinner__animation__keyframes_ie .5s alternate infinite cubic-bezier(.445, .05, .55, .95)
forwards;
}

@keyframes spinner__animation__keyframes {
from {
stroke-dashoffset: 140;
}
to {
stroke-dashoffset: 0;
}
}

@keyframes spinner__animation__keyframes_ie {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
}
}
}

// -----------------------------------------------
Expand All @@ -727,53 +781,92 @@ html, body {
z-index: 100000;
background: $body-bg;

&:before {
font-size: 90px; // logo size
&__logo {
&__part {
fill: $blue;
stroke: $blue;
stroke-width: 1;
stroke-linejoin: miter;
stroke-dasharray: 225;
stroke-dashoffset: 0;

animation: logo__draw 2s cubic-bezier(.445, .05, .55, .95) 2 alternate both 1s;

@keyframes logo__draw {
0% {
fill-opacity: 1;
stroke-dashoffset: 0;
}
40% {
fill-opacity: 0;
stroke-dashoffset: 0;
}
90% {
fill-opacity: 0;
stroke-dashoffset: 225;
}
100% {
fill-opacity: 0;
stroke-dashoffset: 225;
}
}
}
}

noscript {
z-index: 1; // Above loading indicator
&__text {
color: $blue;
position: relative;
font-weight: normal;
margin: $spacer * 2 $spacer 0 $spacer * 1.5;
}

.nojs-warning {
text-align: center;
margin-top: -$spacer;
&__dots {
display: inline-block;
margin-left: .1em;

&#{&} { // overrides the svg:not(:root) selector without !important
overflow: visible;
vertical-align: baseline;
}
}
}

.ss-loading-screen__text {
color: $blue;
position: relative;
font-weight: normal;
margin: $spacer * 2 $spacer 0 $spacer * 1.5;
}
&__dot {
fill: $blue;
opacity: 1;

.ss-loading-screen__text-dots {
color: $body-bg;
$dot-animation--timing: .5s;
$dot-animation: dot__animate $dot-animation--timing cubic-bezier(.445, .05, .55, .95) infinite alternate both;

&:before {
content: attr(data-text);
position: absolute;
overflow: hidden;
max-width: $spacer;
white-space: nowrap;
color: $blue;
animation: loading 3s infinite;
}
}
@keyframes dot__animate {
0% {
opacity: 0;
}
75% {
opacity: 1;
}
100% {
opacity: 1;
}
}

@keyframes loading {
0% {
max-width: 0;
&--1 {
animation: $dot-animation;
}
&--2 {
animation: $dot-animation ($dot-animation--timing * .33);
}
&--3 {
animation: $dot-animation ($dot-animation--timing * .66);
}
}

80% {
max-width: $spacer;
color: $blue;
noscript {
z-index: 1; // Above loading indicator
}

100% {
color: $body-bg;
.nojs-warning {
text-align: center;
margin-top: -$spacer;
}
}

Expand Down
30 changes: 28 additions & 2 deletions templates/SilverStripe/Admin/Includes/CMSLoadingScreen.ss
@@ -1,4 +1,30 @@
<div class="ss-loading-screen font-icon-silverstripe">
<h3 class="ss-loading-screen__text">Loading<span data-text="..." class="ss-loading-screen__text-dots">...</span></h3>
<div class="ss-loading-screen">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 90 90"
width="90"
height="90"
class="ss-loading-screen__logo"
>
<path class="ss-loading-screen__logo__part ss-loading-screen__logo__top" d="M40.1,39.8c4.3,6.5,2.9,15.4-3.5,20.1c-3.9,2.9-8.5,4.4-13.4,4.4c-7.2,0-13.8-3.3-18.1-9.1C1.6,50.4,0.1,44.5,1,38.5
c0.9-5.9,4-11.2,8.8-14.8L40.3,1.1c4.3,6.5,2.9,15.4-3.5,20.1L18.2,35c-3.7,2.8-4.5,8.1-1.7,11.8c1.6,2.1,4.1,3.4,6.8,3.4
c1.8,0,3.6-0.6,5-1.7L40.1,39.8z"/>
<path class="ss-loading-screen__logo__part ss-loading-screen__logo__bot" d="M49.9,50.2c-4.3-6.5-2.9-15.4,3.5-20.1c3.9-2.9,8.5-4.4,13.4-4.4c7.2,0,13.8,3.3,18.1,9.1c3.6,4.8,5.1,10.8,4.2,16.7
c-0.9,5.9-4,11.2-8.8,14.8L49.7,88.9c-2-3.1-2.9-6.7-2.3-10.4c0.6-3.9,2.6-7.4,5.8-9.7L71.8,55c1.8-1.3,3-3.3,3.3-5.6
c0.3-2.2-0.2-4.5-1.6-6.3c-1.6-2.1-4.1-3.4-6.8-3.4c-1.8,0-3.6,0.6-5,1.7L49.9,50.2z"/>
</svg>
<h3 class="ss-loading-screen__text">
Loading<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 10 3"
width="10"
height="3"
class="ss-loading-screen__dots"
>
<circle cx="1" cy="1.75" r="1.25" class="ss-loading-screen__dot ss-loading-screen__dot--1" />
<circle cx="5.5" cy="1.75" r="1.25" class="ss-loading-screen__dot ss-loading-screen__dot--2" />
<circle cx="10.5" cy="1.75" r="1.25" class="ss-loading-screen__dot ss-loading-screen__dot--3" />
</svg>
</h3>
<noscript><p class="nojs-warning alert alert-warning"><%t SilverStripe\\Admin\\LeftAndMain.REQUIREJS 'The CMS requires that you have JavaScript enabled.' %></p></noscript>
</div>

0 comments on commit 2f2fb2b

Please sign in to comment.