I'm trying to create spinning loading overlay like in RPG games for the character skills. Here is an example from WoW (I need exactly like this);

This is my attempt (turns out my CSS skills are not that powerful) - as you can see it has weird look.

Any ideas on how to do it, thanks!
Source in ClojureScript, but should not be problem I guess;
(def skill-keyframes-opa
((keyframes (j/lit {"0%" {:opacity "1"}
"50%, 100%" {:opacity "0"}}))))
(def skill-loading-wrapper
(css (j/lit {:background :white
:opacity 0.5
:z-index 1
:width 45
:height 45
:position :relative
:top 2
:left 2})))
(def skill-loading-pie
(css (j/lit {:width "50%"
:height "100%"
:position :absolute
:transform-origin "100% 50%"
:background :grey
:border "10px solid rgba (0, 0, 0, 0.4)"})))
(defn- skill-loading-spinner [duration]
((css (j/lit {:border-radius "100% 0 0 100% / 50% 0 0 50%"
:z-index 200
:border-right :none
:animation (str skill-keyframes-rota " " duration "s linear infinite")}))))
(defn- skill-loading-filler [duration]
((css (j/lit {:border-radius "0 100% 100% 0 / 0 50% 50% 0"
:z-index 100
:border-left :none
:animation (str skill-keyframes-opa " " duration "s steps(1, end) infinite reverse")
:left "50%"
:opacity 0}))))
(defn skill-loading-mask [duration]
((css (j/lit {:width "50%"
:height "100%"
:position :absolute
:z-index 300
:opacity 1
:background :inherit
:animation (str skill-keyframes-opa " " duration "s steps(1, end) infinite")}))))
(defn use-skill [duration]
[:div {:class (skill-loading-wrapper)}
[:div {:class [(skill-loading-pie) (skill-loading-spinner duration)]}]
[:div {:class [(skill-loading-pie) (skill-loading-filler duration)]}]
[:div {:class (skill-loading-mask duration)}]])
Sources:
@property animation should be replaced with style.setProperty('--cooldown', '23.4%') js animation as js values are source of truth
.cooldown {
/* set via style.setProperty('--cooldown', '23.4%') in js */
--cooldown: 50%;
background: conic-gradient(
transparent 0,
transparent var(--cooldown),
rgba(0, 0, 0, 0.5) var(--cooldown),
rgba(0, 0, 0, 0.5)
);
animation: cooldown 1s linear infinite;
}
/* makes --cooldown animateable for css animations */
@property --cooldown {
syntax: "<percentage>";
inherits: false;
initial-value: 0%;
}
@keyframes cooldown {
0% { --cooldown: 0%; }
100% { --cooldown: 100%; }
}
/* makes children be over each other */
.childs-overlayed {
height: 100px;
width: 100px;
border: 2px solid black;
display: grid;
grid-template-areas: "only";
}
.childs-overlayed > * {
grid-area: only;
height: 100%;
width: 100%;
}
<div class="childs-overlayed">
<img src="https://via.placeholder.com/100">
<div class="cooldown"></div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With