如何使用Tailwind CSS为conic-gradient添加平滑动画(时钟场景)
实现Tailwind CSS平滑过渡的实时锥形渐变时钟
问题背景
我正在开发一款显示日期、时分秒的实时时钟,已经实现了基础的锥形渐变秒针效果,但添加平滑动画后达不到预期,想要实现时分秒均具备平滑过渡的锥形渐变时钟效果。
当前实现代码
<div class="relative h-[200px] w-[200px] rounded-full flex items-center justify-center before:content-[''] before:absolute before:h-[100px] before:w-[100px] before:bg-white before:rounded-[50%]" :style="`background: conic-gradient(#ff5841 ${currentDateTime.getSeconds() * 6}deg, #ededed 0deg);`"> <span class="relative text-3xl font-bold text-gray-800" x-text="currentDateTime.getSeconds() < 10 ? '0' + currentDateTime.getSeconds() : currentDateTime.getSeconds()"></span> <span class="absolute -bottom-10">Seconds</span> </div>
尝试过的无效方案
- 在
tailwind.config.js自定义动画:
animation: { 'conic-gradient': 'conicGradient 4.5s ease-out 0s infinite none running', }, keyframes: { conicGradient: { "50%": { opacity:'0%' }, "100%": { opacity:'100%' } } }
- 注册CSS自定义属性并修改动画关键帧:
先在resource/css/app.css或插件addUtilities()中添加:
@property --conic-opacity { syntax: '<percentage>'; initial-value: 100%; inherits: false; }
再修改tailwind.config.js的关键帧:
conicGradient: { "50%": { '--conic-opacity':'0%' }, "100%": { '--conic-opacity':'100%' } },
添加animate-conic-gradient类后完全没有效果。
解决方案
要实现锥形渐变的平滑过渡,核心是用CSS自定义属性存储渐变角度,配合过渡动画实现角度变化的平滑性,以下是完整实现步骤:
1. 注册可动画的自定义属性
在resource/css/app.css中添加:
@property --second-angle { syntax: '<angle>'; initial-value: 0deg; inherits: false; } @property --minute-angle { syntax: '<angle>'; initial-value: 0deg; inherits: false; } @property --hour-angle { syntax: '<angle>'; initial-value: 0deg; inherits: false; }
这些属性允许我们对角度值应用过渡动画。
2. 配置Tailwind过渡类
在tailwind.config.js中添加自定义过渡属性:
module.exports = { theme: { extend: { transitionProperty: { 'conic-angle': '--second-angle, --minute-angle, --hour-angle', }, transitionDuration: { '1000': '1000ms', }, }, }, }
3. 完整HTML结构(含时分秒)
<!-- 秒针时钟 --> <div class="relative h-[200px] w-[200px] rounded-full flex items-center justify-center before:content-[''] before:absolute before:h-[100px] before:w-[100px] before:bg-white before:rounded-[50%] transition-conic-angle duration-1000 ease-linear" :style="`--second-angle: ${currentDateTime.getSeconds() * 6}deg; background: conic-gradient(#ff5841 var(--second-angle), #ededed 0deg);`"> <span class="relative text-3xl font-bold text-gray-800" x-text="currentDateTime.getSeconds() < 10 ? '0' + currentDateTime.getSeconds() : currentDateTime.getSeconds()"></span> <span class="absolute -bottom-10">Seconds</span> </div> <!-- 分针时钟 --> <div class="relative h-[200px] w-[200px] rounded-full flex items-center justify-center before:content-[''] before:absolute before:h-[100px] before:w-[100px] before:bg-white before:rounded-[50%] transition-conic-angle duration-1000 ease-linear" :style="`--minute-angle: ${(currentDateTime.getMinutes() + currentDateTime.getSeconds()/60) * 6}deg; background: conic-gradient(#4299e1 var(--minute-angle), #ededed 0deg);`"> <span class="relative text-3xl font-bold text-gray-800" x-text="currentDateTime.getMinutes() < 10 ? '0' + currentDateTime.getMinutes() : currentDateTime.getMinutes()"></span> <span class="absolute -bottom-10">Minutes</span> </div> <!-- 时针时钟 --> <div class="relative h-[200px] w-[200px] rounded-full flex items-center justify-center before:content-[''] before:absolute before:h-[100px] before:w-[100px] before:bg-white before:rounded-[50%] transition-conic-angle duration-1000 ease-linear" :style="`--hour-angle: ${(currentDateTime.getHours() % 12 + currentDateTime.getMinutes()/60) * 30}deg; background: conic-gradient(#48bb78 var(--hour-angle), #ededed 0deg);`"> <span class="relative text-3xl font-bold text-gray-800" x-text="currentDateTime.getHours() % 12 || 12"></span> <span class="absolute -bottom-10">Hours</span> </div>
4. 核心逻辑说明
- 给每个时钟元素添加
transition-conic-angle duration-1000 ease-linear类,实现角度变化的平滑过渡 - 计算角度时包含更精细的单位(比如分针加入秒数占比,时针加入分钟占比),避免跳变
- 用自定义属性存储实时计算的角度,绑定到锥形渐变中,配合过渡类实现流畅动画
内容的提问来源于stack exchange,提问作者Moxley
相关产品推荐
相关产品推荐

