Skip to content

Commit

Permalink
fix(loader): tweak loading animations to work in Safari (#7564)
Browse files Browse the repository at this point in the history
**Related Issue:** #6383 

## Summary

This revisits how the loader animates its different segments to play
nicely across all browsers. It seems like the percentages calculated
[here](https://github.com/Esri/calcite-design-system/blob/main/packages/calcite-components/src/components/loader/loader.scss#L179-L181)
are causing Safari to interrupt the animation before resetting (there
are some [existing](https://bugs.webkit.org/show_bug.cgi?id=258897)
[issues](https://bugs.webkit.org/show_bug.cgi?id=249307) on this
behavior). It comes close to the original, but it's not identical, so
I'm open to suggestions on how to improve this. cc @driskull
@macandcheese @paulcpederson

Also, the `loader-clockwise` (rotating) animation is now applied to the
SVG container to avoid it being overwritten by the `loader-offset-#`
animations.

This also fixes the determinate loader logic that mimics a loader
updating dynamically (demo page).
  • Loading branch information
jcfranco authored Aug 24, 2023
1 parent b5fa7f4 commit 2103654
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 13 deletions.
21 changes: 12 additions & 9 deletions packages/calcite-components/src/components/loader/loader.scss
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ $loader-circumference: ($loader-scale - (2 * $stroke-width)) * 3.14159;
block-size: var(--calcite-loader-size);
inset-inline-start: 50%;
margin-inline-start: calc(var(--calcite-loader-size) / 2 * -1);
transform: scale(1, 1);
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-duration: scaleDuration(--calcite-internal-animation-timing-slow, 6.66);
animation-name: loader-clockwise;
}

.loader__svg {
Expand All @@ -94,7 +97,6 @@ $loader-circumference: ($loader-scale - (2 * $stroke-width)) * 3.14159;
block-size: var(--calcite-loader-size);
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-name: loader-clockwise;
}

// in newer browsers use the stroke-dash-offset animation as it looks better
Expand All @@ -113,6 +115,9 @@ $loader-circumference: ($loader-scale - (2 * $stroke-width)) * 3.14159;
:host([type="determinate"]) {
@apply animate-none;
stroke: var(--calcite-ui-border-3);
.loader__svgs {
@apply animate-none;
}
.loader__svg--3 {
@apply animate-none;
stroke: var(--calcite-ui-brand);
Expand Down Expand Up @@ -176,9 +181,10 @@ $loader-circumference: ($loader-scale - (2 * $stroke-width)) * 3.14159;
- duration how long the segment takes to rotate 360° (seconds)
*/
@mixin generateSegment($i, $size, $growth, $duration) {
$circumference: calc($loader-circumference / $loader-scale) * 100%;
$circumference: calc($loader-circumference / $loader-scale) * 100;
$length: ($size * 0.01) * $circumference;
$end: $length + ($growth * 0.01) * $circumference;

.loader__svg--#{$i} {
stroke-dasharray: $length $circumference - $end;
animation-duration: $duration;
Expand All @@ -199,9 +205,9 @@ $loader-circumference: ($loader-scale - (2 * $stroke-width)) * 3.14159;
}
}

@include generateSegment(1, 10, 40, scaleDuration(--calcite-internal-animation-timing-slow, 2.4));
@include generateSegment(2, 20, 30, scaleDuration(--calcite-internal-animation-timing-slow, 3.2));
@include generateSegment(3, 05, 45, scaleDuration(--calcite-internal-animation-timing-slow, 3.867));
@include generateSegment(1, 10, 40, scaleDuration(--calcite-internal-animation-timing-slow, 4.8));
@include generateSegment(2, 20, 30, scaleDuration(--calcite-internal-animation-timing-slow, 6.4));
@include generateSegment(3, 05, 45, scaleDuration(--calcite-internal-animation-timing-slow, 7.734));

@keyframes loader-color-shift {
0% {
Expand All @@ -219,9 +225,6 @@ $loader-circumference: ($loader-scale - (2 * $stroke-width)) * 3.14159;
}

@keyframes loader-clockwise {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
Expand Down
11 changes: 7 additions & 4 deletions packages/calcite-components/src/demos/loader.html
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,14 @@ <h1 style="margin: 0 auto; text-align: center">Loader</h1>
const determinateLoaderMedium = document.querySelector("#loader-determinate-m");
const determinateLoaderLarge = document.querySelector("#loader-determinate-l");
const randoms = [0, 0, 0, 0, 0, 0, 1, 3];

function updateLoader() {
const random = randoms[Math.floor(Math.random() * randoms.length)];
determinateLoaderSmall.value = Math.min(determinateLoaderSmall.value + random, 100);
determinateLoaderMedium.value = Math.min(determinateLoaderMedium.value + random, 100);
determinateLoaderLarge.value = Math.min(determinateLoaderLarge.value + random, 100);
const random = randoms[Math.floor(Math.random() * (randoms.length - 1))];

determinateLoaderSmall.value = Math.min((determinateLoaderSmall.value ?? 0) + random, 100);
determinateLoaderMedium.value = Math.min((determinateLoaderMedium.value ?? 0) + random, 100);
determinateLoaderLarge.value = Math.min((determinateLoaderLarge.value ?? 0) + random, 100);

if (
determinateLoaderSmall.value !== 100 ||
determinateLoaderMedium.value !== 100 ||
Expand Down

0 comments on commit 2103654

Please sign in to comment.