SVG路径缩放至6倍并居中的平滑CSS动画实现求助
实现SVG路径平滑缩放居中动画的解决方案
问题背景
需要将SVG中的澳大利亚路径缩放6倍并居中显示,但SVG默认以视口左上角为变换原点,直接缩放会导致路径偏离目标位置。尝试分步调整平移和缩放时动画出现锯齿,一步到位设置变换又会导致路径先偏移出视口。现有SVG和尝试的CSS代码如下:
用户提供的SVG:
<svg version="1.1" id="World" viewBox="0 0 1920 1080"> <a href="/Australia" title="Australia" className="nav-link"> <path id="Australia" d="M1530.9,867l-66.4,5.4 c-4.3,0.3-7.9-3.2-7.5-7.5l4.7-60.2c0.3-4,2.6-7.7,6.1-9.7l75.4-43.8c3.2-1.9,7.3-1.4,10,1.2l14.6,14.1c2.7,2.6,6.8,3.1,10.1,1.3 l12-6.8c4.7-2.7,10.6-1,13.2,3.7l32.5,58.6c2.2,4,2.4,8.9,0.5,13l-24.8,53.2c-1.6,3.5-4.9,6-8.7,6.7l-36.6,6.7 c-5.2,1-10.4-1.7-12.7-6.5l-11-22.8C1540.2,869.2,1535.7,866.6,1530.9,867z" /> </a> </svg>
用户尝试的分步动画CSS:
#Australia.clicked { animation: Australia-click-animation 2s ease-out forwards; } @keyframes Australia-click-animation { 0% { transform: scale(1); stroke-width: 15; } 20% { transform: scale(2) translateX(-56%) translateY(-52.5%); stroke-width: 7; } 40% { transform: scale(3) translateX(-65%) translateY(-60%); stroke-width: 7; } 60% { transform: scale(4) translateX(-67.5%) translateY(-64%); stroke-width: 7; } 80% { transform: scale(5) translateX(-71%) translateY(-66.5%); stroke-width: 7; } 100% { transform: scale(6) translateX(-72%) translateY(-68.5%); stroke-width: 7; } }
核心解决方案
问题根源在于SVG默认的变换原点不是路径自身中心,手动调整百分比容易因坐标逻辑错误导致动画不平滑。正确的做法是基于路径自身中心点执行变换,具体步骤如下:
1. 修正SVG基础结构
将className改为标准HTML属性class,并添加基础样式确保路径可见:
<svg version="1.1" id="World" viewBox="0 0 1920 1080" style="width: 100%; height: 100%;"> <a href="/Australia" title="Australia" class="nav-link"> <path id="Australia" d="M1530.9,867l-66.4,5.4 c-4.3,0.3-7.9-3.2-7.5-7.5l4.7-60.2c0.3-4,2.6-7.7,6.1-9.7l75.4-43.8c3.2-1.9,7.3-1.4,10,1.2l14.6,14.1c2.7,2.6,6.8,3.1,10.1,1.3 l12-6.8c4.7-2.7,10.6-1,13.2,3.7l32.5,58.6c2.2,4,2.4,8.9,0.5,13l-24.8,53.2c-1.6,3.5-4.9,6-8.7,6.7l-36.6,6.7 c-5.2,1-10.4-1.7-12.7-6.5l-11-22.8C1540.2,869.2,1535.7,866.6,1530.9,867z" fill="#66cc99" stroke="#333" stroke-width="15" /> </a> </svg>
2. 设置变换基准属性
使用transform-box: fill-box让变换基于路径自身的边界框,transform-origin: center将变换中心设为路径中点,避免手动计算复杂偏移:
#Australia { transform-box: fill-box; transform-origin: center; }
3. 编写平滑动画
通过组合变换实现缩放居中:先将路径中心移到原点,缩放6倍,再平移到SVG视口中心(viewBox中点为960px, 540px)。路径中心可通过getBBox()方法准确获取(该路径中心为1526.7px, 814.6px)。
最终动画CSS:
#Australia.clicked { animation: Australia-click-animation 2s ease-out forwards; } @keyframes Australia-click-animation { 0% { transform: scale(1); stroke-width: 15; } 100% { transform: translate(960px, 540px) scale(6) translate(-1526.7px, -814.6px); stroke-width: 7; } }
4. 动态适配路径位置(可选)
如果路径位置可能变化,可通过JavaScript动态获取中心坐标并绑定到CSS变量:
const path = document.getElementById('Australia'); const bbox = path.getBBox(); const cx = bbox.x + bbox.width / 2; const cy = bbox.y + bbox.height / 2; path.style.setProperty('--cx', `${cx}px`); path.style.setProperty('--cy', `${cy}px`);
对应的CSS改为:
#Australia { --cx: 0; --cy: 0; --svg-center-x: 960px; --svg-center-y: 540px; --scale: 6; transform-box: fill-box; transform-origin: center; } @keyframes Australia-click-animation { 0% { transform: scale(1); stroke-width: 15; } 100% { transform: translate(calc(var(--svg-center-x) - var(--cx) * var(--scale)), calc(var(--svg-center-y) - var(--cy) * var(--scale))) scale(var(--scale)); stroke-width: 7; } }
效果说明
该方案通过基于路径中心的变换逻辑,确保动画从原位置平滑缩放至视口中心,不会出现锯齿状移动或偏移出视口的问题。
内容的提问来源于stack exchange,提问作者Louis Eiden
相关产品推荐
相关产品推荐

