You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用CSS/JavaScript制作类似RPG游戏的旋转技能加载遮罩?

实现类似RPG游戏的技能旋转加载遮罩

我想制作类似魔兽世界里的技能旋转加载遮罩效果:
魔兽世界技能加载遮罩

但我的尝试效果不理想:
我的尝试效果

希望能得到实现思路,感谢!

以下是我的ClojureScript代码:

(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)}]])

核心实现思路

1. 补全缺失的旋转关键帧

代码中使用了skill-keyframes-rota但未定义,这是旋转效果的核心:

(def skill-keyframes-rota
  ((keyframes (j/lit {"0%" {:transform "rotate(0deg)"}
                      "100%" {:transform "rotate(360deg)"}}))))

这个关键帧负责左侧扇形的匀速360度旋转,是实现“扫过”效果的基础。

2. 调整容器与遮罩的核心逻辑

魔兽世界的效果是半透明遮罩随旋转逐步显露出下方的技能图标,你的现有逻辑搞反了:

  • 容器skill-loading-wrapper应直接显示技能图标,而非白色背景
  • 遮罩用深色半透明层覆盖图标,旋转的扇形是“清除遮罩”的区域

修改容器样式:

(def skill-loading-wrapper
  (css (j/lit {:background "url('技能图标路径') center/cover no-repeat"
               :z-index 1
               :width 45
               :height 45
               :position :relative})))

3. 修正扇形与遮罩的样式

  • skill-loading-pie的背景需与容器一致,去掉多余边框避免破坏圆形外观:
(def skill-loading-pie
  (css (j/lit {:width "50%"
               :height "100%"
               :position :absolute
               :transform-origin "100% 50%"
               :background :inherit})))
  • 新增全容器遮罩层,用深色半透明覆盖技能图标:
(def skill-full-mask
  (css (j/lit {:position :absolute
               :top 0
               :left 0
               :width "100%"
               :height "100%"
               :background "rgba(0,0,0,0.7)"
               :z-index 10})))

4. 优化动画同步逻辑

确保三个动画(旋转、填充显隐、遮罩显隐)时长完全一致:

  • 旋转动画用linear保证匀速
  • 显隐动画在50%节点切换状态,刚好对应旋转180度的时刻

调整后的组件结构:

(defn use-skill [duration]
  [:div {:class (skill-loading-wrapper)}
   [:div {:class (skill-full-mask)}]
   [:div {:class [(skill-loading-pie) (skill-loading-spinner duration)]
          :style {:z-index 20}}]
   [:div {:class [(skill-loading-pie) (skill-loading-filler duration)]
          :style {:z-index 20}}]
   [:div {:class (skill-loading-mask duration)
          :style {:z-index 30
                  :background "rgba(0,0,0,0.7)"}}]])

5. 细节校准

  • 调整遮罩透明度,让未加载完成的图标保持暗化状态
  • 确保所有元素的border-radius统一,维持圆形外观
  • 测试不同时长的动画,保证旋转速度与技能CD匹配

内容的提问来源于stack exchange,提问作者Ertuğrul Çetin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 14:35:11