Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a spinning loading overlay like in RPG game in CSS/JavaScript?

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);

Skill loadin overlay

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

enter image description here

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)}]])
like image 211
Ertuğrul Çetin Avatar asked Nov 03 '25 07:11

Ertuğrul Çetin


1 Answers

Sources:

  • https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/conic-gradient
  • https://developer.mozilla.org/en-US/docs/Web/CSS/--*
  • https://developer.mozilla.org/en-US/docs/Web/CSS/@property

@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>
like image 159
Dimava Avatar answered Nov 05 '25 00:11

Dimava



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!