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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 21:22:02