offset-anchor导致SVG图形位置异常,如何正确控制该属性?
offset-anchor 属性的调整问题 我无法理解如何调整offset-anchor的值以符合预期效果。
更新说明
截至2022年12月17日,谷歌浏览器暂不支持offset-anchor,相关支持工单及规范跟踪可查看Chromium相关平台。
我正在绘制一个箭头,希望将移动时的锚点(示例中的红色圆点)设置在箭头头部而非尾部。
当前示例里的红色圆点高亮了箭头移动时默认使用的锚点。但我尝试修改offset-anchor值时出现问题:设置为offset-anchor: left,箭头会跳到奇怪位置;设置为offset-anchor: right,箭头直接消失。这是为什么?
请问如何按照预期控制offset-anchor的值?我不确定是否需要搭配offset-rotate,但想先搞清楚调整offset-anchor时哪里出错了。
附言:我的代码基于MDN的offset-anchor文档示例,但制作动画时似乎遗漏了关键内容。
代码示例
<style> #placeholder {} #arrow { offset-path: path("M275,50 h-200"); animation: move 3s; } #offset-anchor-1 { offset-path: path("M275,50 h-200"); animation: move 3s; } #rectangle { offset-path: path("m575,50 h-200"); animation: move 3s; } #offset-anchor-2 { offset-path: path("m575,50 h-200"); animation: move 3s; } @keyframes move { 100% { offset-distance: 100%; } } </style>
<svg height=100 width=650 viewPort="0 0 100 650" style="border: 1px solid #999"> <path id="arrow" d="M0,0 h50" stroke-width="2" stroke="black" marker-end="url(#arrow-head)"></path> <path id="travel-path1" d="M275,50 h-200" stroke-width="1" stroke-dasharray="4" stroke="red"></path> <circle id="offset-anchor-1" cx="0" cy="0" r="4" fill="red"></circle> <rect id="rectangle" x="0" y="0" width="50" height="20" fill="yellow" stroke="navy" stroke-width="1"></rect> <path id="travel-path2" d="M575,50 h-200" stroke-width="1" stroke-dasharray="4" stroke="red"></path> <circle id="offset-anchor-2" cx="0" cy="0" r="4" fill="red"></circle> <defs> <marker id="arrow-head" markerWidth="5" markerHeight="5" refX="2.5" refY="2.5" viewBox="0 0 5 5" orient="auto"> <polygon points="0,5 1.6666666666666667,2.5 0,0 5,2.5" fill="black"></polygon> </marker> </defs> </svg>
问题分析与解决方法
1. 核心障碍:浏览器支持
首先要明确,你遇到的异常表现根源是Chrome暂不支持offset-anchor——你设置的该属性在当前环境下完全不会生效,所有奇怪的偏移、消失行为都是浏览器忽略该属性后的兼容异常。
2. offset-anchor的生效逻辑(兼容环境下)
offset-anchor的作用是指定元素的哪个点对齐到offset-path的路径节点,默认值是元素的transform-origin(SVG元素默认是边界框中心或定义的参考点)。
你的箭头路径是从M0,0到h50(左到右线段,头部在(50,0)),要让锚点对齐头部,正确的设置应该是:
- 使用具体坐标:
offset-anchor: 50px 0 - 或使用百分比:
offset-anchor: 100% 50%(100%对应路径x轴末端,50%对应y轴中心)
设置left/right出错的原因:SVG元素的方向关键字依赖于边界框计算,若浏览器对SVG元素的关键字解析逻辑存在问题,就会导致偏移异常,直接用坐标或百分比更可靠。
3. Chrome环境下的替代方案
既然Chrome不支持该属性,可通过以下方法实现需求:
- 调整SVG原点:将箭头路径起点改到头部,比如把
d="M0,0 h50"改为d="M50,0 h-50",让元素默认锚点(原点)直接对应箭头头部,无需依赖offset-anchor。 - 手动transform偏移:在动画中配合
transform: translateX(50px),同步偏移元素使头部对齐路径节点。
修正后的示例代码
以下是调整SVG原点后的代码,无需offset-anchor即可实现锚点在头部的效果:
<style> #arrow { offset-path: path("M275,50 h-200"); animation: move 3s; } #offset-anchor-1 { offset-path: path("M275,50 h-200"); animation: move 3s; } @keyframes move { 100% { offset-distance: 100%; } } </style>
<svg height=100 width=650 viewPort="0 0 100 650" style="border: 1px solid #999"> <!-- 调整箭头路径原点到头部 --> <path id="arrow" d="M50,0 h-50" stroke-width="2" stroke="black" marker-end="url(#arrow-head)"></path> <path id="travel-path1" d="M275,50 h-200" stroke-width="1" stroke-dasharray="4" stroke="red"></path> <circle id="offset-anchor-1" cx="0" cy="0" r="4" fill="red"></circle> <defs> <marker id="arrow-head" markerWidth="5" markerHeight="5" refX="2.5" refY="2.5" viewBox="0 0 5 5" orient="auto"> <polygon points="0,5 1.6666666666666667,2.5 0,0 5,2.5" fill="black"></polygon> </marker> </defs> </svg>
内容的提问来源于stack exchange,提问作者oldhomemovie

