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

CSS帧旋转动画问题:如何实现不同起始角度的平滑旋转?

多区块背景渐变旋转动画卡顿修复

我正在开发网站,需要为多个区块的帧添加动画,要求每个区块的background-image旋转起始角度不同。我尝试了以下代码,但动画不流畅、存在间歇性卡顿,请问该如何修复?


原代码

JavaScript

var carousel_items = document.getElementsByClassName("carousel-item");
var root = document.documentElement;

function setFrames() {
    let frame = 70;
    for (let i = 1; i < carousel_items.length + 1; i++) {
        root.style.setProperty("--icon-" + String(i), String(frame) + "deg");
        $("head").append("<style> #test" + i + ":before {content: ''; width: 102%; height: 102%; border-radius: 40px/40px; background-image: linear-gradient(var(--icon-" + i +"), #F9BEFF, #B8EAFF, #83C7FF); position: absolute; z-index: -1; top: -1%; left: -1%; animation: spin-" + i + " 5s linear infinite;}</style>");
        $("head").append("<style> #test" + i +":after {position: absolute; top: calc(var(--carousel-item-height)); left: 0; right: 0; z-index: -1; height: 100%; width: 100%; margin: 0 auto; transform: scale(0.6); background-image: linear-gradient(var(--icon-" + i + "), #F9BEFF, #B8EAFF, #83C7FF); opacity: 1; transition: opacity .5s; animation: spin-" + i + " 5s linear infinite;}  @keyframes spin-" + i +" {0% {--icon-" + i + ": 0deg;}100% {--icon- " + i + ": 360deg;}} </style>")
        frame += 70;
    }
};

CSS

.carousel {
    display: flex;
    width: 100%;
    height: 165px;
    overflow-x: scroll;
    overflow-y: hidden;
    -ms-overflow-style: none;
    scrollbar-width: none;
}

.carousel:first-child {
    margin-left: 0px;
}

.carousel::-webkit-scrollbar {
    display: none;
}

.carousel-item {
    background: var(--back-color);
    margin-top: 5px;
    margin-left: 10px;
    padding: 3px;
    width: 150px;
    height: 149px;
    min-width: 150px;
    min-height: 149px;
    position: relative;
    border-radius: 40px/39px;
}

:root {
    --back-color: #EFEFF4;
}

HTML

<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body onload="setFrames()">
    <div class="carousel">
        <div id="test1" class="carousel-item">
            <span width="100%">test1</span>
        </div>
        <div id="test2" class="carousel-item">
            <span width="100%">test2</span>
        </div>
        <div id="test3" class="carousel-item">
            <span width="100%">test3</span>
        </div>
    </div>
</body>
</html>

问题原因与修复方案

核心问题

  • CSS变量动画无GPU加速:通过动画CSS变量实现渐变旋转,不属于浏览器合成层优化范畴,无法利用GPU加速,导致卡顿。
  • 冗余DOM与样式:循环中多次插入<style>标签,每个元素单独定义@keyframes,增加渲染开销。
  • 渐变重复计算:CSS变量更新时会反复重新计算线性渐变,加重浏览器负担。

优化思路

改用transform: rotate()控制伪元素旋转(GPU加速支持),用CSS变量仅控制初始角度,统一复用动画样式,减少冗余操作。

优化后代码

HTML(无需修改)

<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body onload="setFrames()">
    <div class="carousel">
        <div id="test1" class="carousel-item">
            <span width="100%">test1</span>
        </div>
        <div id="test2" class="carousel-item">
            <span width="100%">test2</span>
        </div>
        <div id="test3" class="carousel-item">
            <span width="100%">test3</span>
        </div>
    </div>
</body>
</html>

CSS(统一复用样式)

.carousel {
    display: flex;
    width: 100%;
    height: 165px;
    overflow-x: scroll;
    overflow-y: hidden;
    -ms-overflow-style: none;
    scrollbar-width: none;
}

.carousel:first-child {
    margin-left: 0px;
}

.carousel::-webkit-scrollbar {
    display: none;
}

.carousel-item {
    background: var(--back-color);
    margin-top: 5px;
    margin-left: 10px;
    padding: 3px;
    width: 150px;
    height: 149px;
    min-width: 150px;
    min-height: 149px;
    position: relative;
    border-radius: 40px/39px;
    overflow: hidden; /* 避免伪元素旋转超出容器 */
}

/* 统一伪元素基础样式 */
.carousel-item::before,
.carousel-item::after {
    content: '';
    position: absolute;
    z-index: -1;
    background-image: linear-gradient(0deg, #F9BEFF, #B8EAFF, #83C7FF);
    transform-origin: center;
    animation: spin 5s linear infinite;
    will-change: transform; /* 提前通知浏览器准备GPU加速 */
}

.carousel-item::before {
    width: 102%;
    height: 102%;
    border-radius: 40px;
    top: -1%;
    left: -1%;
    transform: rotate(var(--initial-rotate)); /* 初始角度由变量控制 */
}

.carousel-item::after {
    top: calc(var(--carousel-item-height, 149px));
    left: 0;
    right: 0;
    height: 100%;
    width: 100%;
    margin: 0 auto;
    transform: scale(0.6) rotate(var(--initial-rotate));
    opacity: 1;
    transition: opacity .5s;
}

/* 复用单个动画 */
@keyframes spin {
    100% {
        transform: rotate(calc(var(--initial-rotate) + 360deg));
    }
}

:root {
    --back-color: #EFEFF4;
}

JavaScript(仅设置初始角度)

var carousel_items = document.getElementsByClassName("carousel-item");

function setFrames() {
    let frame = 70;
    for (let i = 0; i < carousel_items.length; i++) {
        // 直接给每个元素设置初始旋转角度变量
        carousel_items[i].style.setProperty("--initial-rotate", `${frame}deg`);
        frame += 70;
    }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 19:30:55