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

Firefox下@property的替代方案:圆形动画兼容问题求助

兼容全浏览器的圆形填充动画替代方案

问题背景

之前用@property实现了圆形填充动画,但@property仅部分浏览器支持,需要替换成全兼容方案。原实现通过动态修改锥形渐变的角度变量实现填充效果,尝试直接用transform: rotate没达到预期。

核心思路

放弃自定义属性,改用双层元素+旋转遮罩的方式:

  • 外层容器固定圆形尺寸,作为边界
  • 底层是带渐变效果的完整圆形
  • 上层用白色遮罩层(和页面背景色一致),通过分阶段旋转遮罩层,逐步露出底层渐变圆形,模拟从0到360度的填充动画

完整代码实现

HTML结构

保留原有布局,调整内部元素适配新逻辑:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="circle-graph">
  <div class="graph-wrap">
    <div id="graph-2">
      <div class="circle-wrap">
        <!-- 底层渐变圆形 -->
        <div class="circle-bg"></div>
        <!-- 旋转遮罩层 -->
        <div class="circle-mask"></div>
        <div class="outer-border"></div>
        <div class="inner-border"></div>
        <div class="fade-in-img">填充完成后的内容</div>
      </div>
    </div>
  </div>
</div>

CSS样式

.circle-graph-info {
    align-items: center;
    display: flex;
    justify-content: center;
    margin: 0 0 0 240px;
    position: relative;
}

.circle-graph-info p {
    color: #479F56;
    font-size: 120px;
    font-weight: 800;
    margin: 0 -50px 0 0;
    max-width: 275px;
    position: relative;
}

.circle-graph-info span {
    color: #000;
    display: block;
    font-size: 28px;
    font-weight: 400;
}

.circle-graph-info p:first-of-type::before {
    content: '';
    display: block;
    background: #479F56;
    height: 5px;
    left: -200px;
    position: absolute;
    top: 50%;
    width: 161px;
    border-radius: 5px;
}

.circle-wrap {
    padding: 5px;
    position: relative;
    height: 484px;
    width: 484px;
    border-radius: 50%;
    overflow: hidden; /* 隐藏遮罩层溢出部分 */
}

/* 底层渐变圆形 */
.circle-bg {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: rgb(138,173,81);
    background: linear-gradient(90deg, rgba(138,173,81,1) 0%, rgba(71,159,86,1) 0%, rgba(138,173,81,1) 100%);
}

/* 遮罩层:初始覆盖整个圆形,通过旋转露出底层渐变 */
.circle-mask {
    position: absolute;
    top: 0;
    left: 0;
    width: 50%;
    height: 100%;
    background: #fff; /* 必须和页面背景色一致 */
    transform-origin: right center; /* 以右侧中心为旋转轴 */
    animation: mask-rotate 2s .3s ease forwards;
    -webkit-animation: mask-rotate 2s .3s ease forwards;
}

/* 分阶段旋转动画,模拟完整填充效果 */
@keyframes mask-rotate {
    0% {
        transform: rotate(0deg);
        width: 50%;
        left: 0;
        transform-origin: right center;
    }
    50% {
        transform: rotate(180deg);
        width: 50%;
        left: 0;
        transform-origin: right center;
    }
    51% {
        transform: rotate(0deg);
        width: 100%;
        left: 0;
        transform-origin: center center;
    }
    100% {
        transform: rotate(360deg);
        width: 100%;
        left: 0;
        transform-origin: center center;
    }
}

/* 兼容webkit内核浏览器 */
@-webkit-keyframes mask-rotate {
    0% {
        -webkit-transform: rotate(0deg);
        width: 50%;
        left: 0;
        -webkit-transform-origin: right center;
    }
    50% {
        -webkit-transform: rotate(180deg);
        width: 50%;
        left: 0;
        -webkit-transform-origin: right center;
    }
    51% {
        -webkit-transform: rotate(0deg);
        width: 100%;
        left: 0;
        -webkit-transform-origin: center center;
    }
    100% {
        -webkit-transform: rotate(360deg);
        width: 100%;
        left: 0;
        -webkit-transform-origin: center center;
    }
}

.fade-in-img {
    display: none;
    position: absolute;
    z-index: 9;
    top: 32%;
    left: 0;
    right: 0;
    margin: 0 auto;
    width: 140px;
    text-align: center;
}

.outer-border {
    position: absolute;
    top: 0;
    left: 0;
    border-radius: 50%;
    box-shadow: inset 0px 0px 10px rgba(0, 0, 0, 0.25);
    height: 102%;
    width: 102%;
    pointer-events: none; /* 不干扰下层元素交互 */
}

.inner-border {
    background: #fff;
    position: absolute;
    top: 32px;
    left: 32px;
    border-radius: 50%;
    box-shadow: 0px 0px 10px rgba(0,0,0,0.25);
    height: 89%;
    width: 89%;
    pointer-events: none;
}

JavaScript逻辑

保留原有交互逻辑,仅调整选择器:

var circleMask = $(".circle-mask");
var circleImg = $('.fade-in-img');

// 监听动画结束事件,兼容webkit内核
circleMask.on('animationend webkitAnimationEnd', function() {
  $(circleImg).fadeIn();
});

方案说明

  1. 兼容所有支持CSS动画的浏览器(包括IE10+),无需依赖@property
  2. 动画分两段执行:前半段旋转半宽遮罩覆盖左半圆,后半段切换旋转轴用全宽遮罩旋转一圈,完美还原原实现的填充效果
  3. 遮罩层颜色必须和页面背景色一致,确保视觉上是“填充”而非单纯旋转
  4. 保留了原动画的时长、延迟和缓动曲线,体验和原实现完全一致

内容的提问来源于stack exchange,提问作者justDan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:09:55