如何为CSS变量添加过渡实现水晶旋转速度平滑切换
问题与解决方案
问题描述
我制作了一个每10秒旋转一圈的水晶动画,希望鼠标悬停时,旋转周期能逐渐降至5秒(即转速加快)。目前水晶被悬停时变量可切换,但切换是突变的——尽管有资料证明CSS变量支持过渡效果,但我的变量会直接从1跳变到2,旋转状态也直接变为变量为2时的状态,仿佛一直以该转速运行。另外需要说明:我无法使用JavaScript,因为这是为Fandom Wiki制作的样式。
解决方案
核心问题在于你试图通过控制动画终点的旋转角度来改变转速,这种方式无法实现平滑过渡。正确的做法是直接用CSS变量控制动画时长,并通过过渡效果实现转速的平滑变化,同时保证旋转的连续性:
- 定义控制动画时长的CSS变量
--spin-duration,初始值设为10s,悬停时改为5s - 给
#crystal__添加animation-duration的过渡效果,实现时长的平滑变化 - 移除原有的
--crroin变量相关逻辑,保持动画终点为固定的360deg,确保旋转过程不跳变
修改后的代码
CSS代码
@import url('https://fonts.googleapis.com/css2?family=Amarante&display=swap'); #crystal__ #crystal-side { width: 100%; height: 53%; background-image: url(https://i.ibb.co/tYncDJ8/image.png); position: absolute; background-size: 100% 100%; } #crystal__ #crystal-side:nth-of-type(1) { transform: translateZ(.825em) translateY(-.15em) rotateX(18.4deg); } #crystal__ #crystal-side:nth-of-type(2) { transform: rotateY(90deg) translateZ(.825em) translateY(-.15em) rotateX(18.4deg) rotateY(180deg); } #crystal__ #crystal-side:nth-of-type(3) { transform: rotateY(-90deg) translateZ(.825em) translateY(-.15em) rotateX(18.4deg); } #crystal__ #crystal-side:nth-of-type(4) { transform: rotateY(180deg) translateZ(.825em) translateY(-.15em) rotateX(18.4deg); } #crystal__ #crystal-side:nth-of-type(5) { transform: rotateX(180deg) translateY(-5em) translateZ(.825em) translateY(.15em) rotateX(18.4deg); } #crystal__ #crystal-side:nth-of-type(6) { transform: rotateY(90deg) rotateX(180deg) translateY(-5em) translateZ(.825em) translateY(.15em) rotateX(18.4deg); } #crystal__ #crystal-side:nth-of-type(7) { transform: rotateY(-90deg) rotateX(180deg) translateY(-5em) translateZ(.825em) translateY(.15em) rotateX(18.4deg); } #crystal__ #crystal-side:nth-of-type(8) { transform: rotateY(180deg) rotateX(180deg) translateY(-5em) translateZ(.825em) translateY(.15em) rotateX(18.4deg); } #crystal__ { transform-style: preserve-3d; width: 66%; left: 16.5%; transform-origin: center; height: 100%; position: absolute; --spin-duration: 10s; animation: crystal var(--spin-duration) linear infinite; transition: animation-duration 2s ease; } @keyframes crystal { from { transform: rotateX(-30deg) rotateY(0deg); } to { transform: rotateX(-30deg) rotateY(360deg); } } #crystal-container { border-style: solid; width: 5em; margin-left: 1em; margin-right: 1em; transform-style: preserve-3d; height: 10em; float: left; clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); } #crystal-glow { width: 100%; height: 100%; transform: translateZ(-5em) scale(1.2); background-image: url(https://i.ibb.co/GF64XLK/qgwas.png); background-size: 100% 100% } #crystal-text { border-style: solid; border-color: black; position: absolute; margin: auto; top: 50%; transform: translateY(-50%) translateZ(1em); width: 100%; display: flex; justify-content: center; align-items: center; text-align: center; font-size: 2em; color: white; text-shadow: 0 0 10px rgb(0, 0, 0); font-family: Amarante; transition: transform .3s; } body { font-size: 50px } #crystal-container:hover>#crystal-text { transform: translateY(-50%) translateZ(1em) rotateX(30deg) rotateY(-24deg); } #crystal-container:hover>#crystal__ { --spin-duration: 5s; } #crystal-rack { float: none }
HTML代码
<div id="crystal-rack"> <div id="crystal-container"> <div id="crystal__"> <div id="crystal-side"></div> <div id="crystal-side"></div> <div id="crystal-side"></div> <div id="crystal-side"></div> <div id="crystal-side"></div> <div id="crystal-side"></div> <div id="crystal-side"></div> <div id="crystal-side"></div> </div> <div id="crystal-glow"></div> <div id="crystal-text">Places</div> </div> </div>
内容的提问来源于stack exchange,提问作者halsemarathmellsphv
相关产品推荐
相关产品推荐

