如何调整SVG坐标系(仅缩放Y轴)且不扭曲图形元素?
解决SVG单轴缩放不扭曲元素的问题
要实现仅缩放Y轴且不扭曲圆形、文本等元素,同时避免逐个调整坐标,核心思路是分离坐标系缩放与元素渲染缩放,以下是针对你的场景的具体方案:
方案1:嵌套SVG实现坐标映射+等比渲染
这是最稳妥的方法,通过外层SVG定义新的画布尺寸和坐标系,内层SVG保留原内容和等比渲染规则:
<!-- 外层SVG:新尺寸400px×200px,坐标系对应0 0 10 5 --> <svg width="400px" height="200px" viewBox="0 0 10 5"> <!-- 内层SVG:保留原viewBox和所有元素,通过scale适配外层Y轴缩放 --> <svg viewBox="0 0 10 10" width="10" height="10" transform="scale(1, 0.5)"> <!-- 原有的四个角落圆形 --> <circle cx="0" cy="0" r="0.5" fill="red" /> <circle cx="10" cy="0" r="0.5" fill="blue" /> <circle cx="0" cy="10" r="0.5" fill="green" /> <circle cx="10" cy="10" r="0.5" fill="yellow" /> <!-- 其他文本或元素 --> <text x="5" y="5" text-anchor="middle">示例文本</text> </svg> </svg>
- 外层SVG的
viewBox="0 0 10 5"直接将Y轴坐标系压缩为原来的一半,匹配新的200px高度 - 内层SVG通过
transform="scale(1, 0.5)"将自身内容的Y轴缩放0.5,刚好适配外层坐标系,同时元素保持原比例(圆形不变椭圆、文本不拉伸) - 所有原元素的坐标无需修改,自动对应到新SVG的角落
方案2:使用标签包裹内容+调整viewBox
如果不想嵌套SVG,可以用<g>标签包裹所有内容,配合viewBox和transform:
<svg width="400px" height="200px" viewBox="0 0 10 5"> <g transform="scale(1, 0.5)"> <!-- 原有的四个角落圆形 --> <circle cx="0" cy="0" r="0.5" fill="red" /> <circle cx="10" cy="0" r="0.5" fill="blue" /> <circle cx="0" cy="10" r="0.5" fill="green" /> <circle cx="10" cy="10" r="0.5" fill="yellow" /> <text x="5" y="5" text-anchor="middle">示例文本</text> </g> </svg>
- 原理和嵌套SVG一致:外层viewBox定义新坐标系,
<g>的transform将内容Y轴缩放适配坐标系,元素保持原比例 - 注意:如果元素有基于原坐标系的动画或交互,此方法同样适用,无需修改动画参数
为什么直接改height或scale无效?
- 直接设置
height="200px":SVG会自动拉伸内容以填充新尺寸,导致X/Y轴缩放比例不一致,圆形变椭圆 - 直接给SVG加
transform="scale(1,0.5)":会同时缩放SVG画布和内容,导致元素位置偏移(比如原角落的圆形会跑到新画布的中间位置),且没有匹配新的坐标系
内容的提问来源于stack exchange,提问作者Script Raccoon
相关产品推荐
相关产品推荐

