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

如何在已有带箭头的SVG路径中间添加指定SVG元素

问题描述

我有一条带箭头的SVG路径,代码如下:

<path {...lineProps} id={id} />

现在想把下面这个SVG元素(粉色圆角矩形内包含白色暂停图标)添加到这条路径的中间位置,最终实现标记位于路径中点的效果:

<svg width="32" height="18" viewBox="0 0 32 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="32" height="18" rx="9" fill="#F8788F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.6531 10.9423L12 9.28917L10.3468 10.9423L10.0577 10.6532L11.7109 9.00003L10.0577 7.34693L10.3468 7.05784L12 8.71094L13.6531 7.05784L13.9421 7.34693L12.289 9.00003L13.9421 10.6532L13.6531 10.9423Z" fill="#FEFEFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.6531 11.4001L12 9.74695L10.3468 11.4001L9.59993 10.6532L11.2531 9.00003L9.59992 7.34693L10.3468 6.60006L12 8.25316L13.6531 6.60006L14.3999 7.34693L12.7468 9.00003L14.3999 10.6532L13.6531 11.4001ZM12.289 9.00003L13.9421 7.34693L13.6531 7.05784L12 8.71094L10.3468 7.05784L10.0577 7.34693L11.7109 9.00003L10.0577 10.6532L10.3468 10.9423L12 9.28917L13.6531 10.9423L13.9421 10.6532L12.289 9.00003Z" fill="#FEFEFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0001 13.7081C13.3154 13.1808 14.0955 12.8115 14.6823 11.926C15.302 10.9909 15.7984 9.31606 15.8863 5.9205C14.5265 5.74148 13.1976 5.26052 12.0002 4.4796C10.8027 5.26052 9.4738 5.74148 8.11402 5.9205C8.20188 9.31606 8.69829 10.9909 9.31803 11.926C9.90483 12.8115 10.6849 13.1808 12.0001 13.7081ZM11.7768 14.911C11.9199 14.968 12.0804 14.968 12.2235 14.911L12.2434 14.9031C15.0408 13.7903 16.9994 13.0112 17.0964 5.40383C17.1006 5.07248 16.8312 4.80237 16.5007 4.77785C15.0545 4.67052 13.6299 4.17427 12.3834 3.2891C12.1546 3.12662 11.8457 3.12662 11.6169 3.2891C10.3705 4.17427 8.94583 4.67052 7.49961 4.77785C7.16914 4.80237 6.8997 5.07248 6.90392 5.40383C7.00086 13.0112 8.95954 13.7903 11.7569 14.9031L11.7768 14.911Z" fill="#FEFEFF"/>
</svg>
实现方案

完全可以实现,核心是定位标记到路径中点,下面提供两种可行方案:

方案一:使用<textPath>(适合静态路径)

把暂停图标转成<symbol>复用,通过<use>结合<textPath>挂载到路径中点:

<svg viewBox="0 0 400 200" xmlns="http://www.w3.org/2000/svg">
  <!-- 定义暂停图标符号 -->
  <symbol id="pause-mark" width="32" height="18" viewBox="0 0 32 18" fill="none">
    <rect width="32" height="18" rx="9" fill="#F8788F"/>
    <path fill-rule="evenodd" clip-rule="evenodd" d="M13.6531 10.9423L12 9.28917L10.3468 10.9423L10.0577 10.6532L11.7109 9.00003L10.0577 7.34693L10.3468 7.05784L12 8.71094L13.6531 7.05784L13.9421 7.34693L12.289 9.00003L13.9421 10.6532L13.6531 10.9423Z" fill="#FEFEFF"/>
    <path fill-rule="evenodd" clip-rule="evenodd" d="M13.6531 11.4001L12 9.74695L10.3468 11.4001L9.59993 10.6532L11.2531 9.00003L9.59992 7.34693L10.3468 6.60006L12 8.25316L13.6531 6.60006L14.3999 7.34693L12.7468 9.00003L14.3999 10.6532L13.6531 11.4001ZM12.289 9.00003L13.9421 7.34693L13.6531 7.05784L12 8.71094L10.3468 7.05784L10.0577 7.34693L11.7109 9.00003L10.0577 10.6532L10.3468 10.9423L12 9.28917L13.6531 10.9423L13.9421 10.6532L12.289 9.00003Z" fill="#FEFEFF"/>
    <path fill-rule="evenodd" clip-rule="evenodd" d="M12.0001 13.7081C13.3154 13.1808 14.0955 12.8115 14.6823 11.926C15.302 10.9909 15.7984 9.31606 15.8863 5.9205C14.5265 5.74148 13.1976 5.26052 12.0002 4.4796C10.8027 5.26052 9.4738 5.74148 8.11402 5.9205C8.20188 9.31606 8.69829 10.9909 9.31803 11.926C9.90483 12.8115 10.6849 13.1808 12.0001 13.7081ZM11.7768 14.911C11.9199 14.968 12.0804 14.968 12.2235 14.911L12.2434 14.9031C15.0408 13.7903 16.9994 13.0112 17.0964 5.40383C17.1006 5.07248 16.8312 4.80237 16.5007 4.77785C15.0545 4.67052 13.6299 4.17427 12.3834 3.2891C12.1546 3.12662 11.8457 3.12662 11.6169 3.2891C10.3705 4.17427 8.94583 4.67052 7.49961 4.77785C7.16914 4.80237 6.8997 5.07248 6.90392 5.40383C7.00086 13.0112 8.95954 13.7903 11.7569 14.9031L11.7768 14.911Z" fill="#FEFEFF"/>
  </symbol>

  <!-- 原路径 -->
  <path id="arrow-path" d="M50 100 L350 100" stroke="#000" stroke-width="2" marker-end="url(#arrowhead)"/>
  <!-- 定义箭头标记 -->
  <defs>
    <marker id="arrowhead" markerWidth="10" markerHeight="7" refX="0" refY="3.5" orient="auto">
      <polygon points="0 0, 10 3.5, 0 7" fill="#000"/>
    </marker>
  </defs>

  <!-- 将暂停图标挂载到路径中点 -->
  <text font-size="0">
    <textPath href="#arrow-path" startOffset="50%">
      <use href="#pause-mark" transform="translate(-16, -9)"/> <!-- 偏移量为图标宽高的一半,实现居中 -->
    </textPath>
  </text>
</svg>

方案二:使用JS动态计算(适合动态路径)

如果路径会动态变化,用JS获取路径总长度,计算中点坐标后设置图标位置:

import { useEffect, useRef } from 'react';

const ArrowWithPause = ({ lineProps, id }) => {
  const pathRef = useRef(null);
  const pauseRef = useRef(null);

  useEffect(() => {
    const path = pathRef.current;
    const pause = pauseRef.current;
    if (!path || !pause) return;

    // 获取路径总长度,计算中点位置
    const totalLength = path.getTotalLength();
    const midPoint = path.getPointAtLength(totalLength / 2);

    // 设置暂停图标的位置(偏移宽高一半实现居中)
    pause.setAttribute('x', midPoint.x - 16);
    pause.setAttribute('y', midPoint.y - 9);
  }, [lineProps]);

  return (
    <svg viewBox="0 0 400 200">
      {/* 原路径 */}
      <path ref={pathRef} {...lineProps} id={id} marker-end="url(#arrowhead)"/>
      {/* 箭头标记定义 */}
      <defs>
        <marker id="arrowhead" markerWidth="10" markerHeight="7" refX="0" refY="3.5" orient="auto">
          <polygon points="0 0, 10 3.5, 0 7" fill="#000"/>
        </marker>
      </defs>
      {/* 暂停图标 */}
      <svg ref={pauseRef} width="32" height="18" viewBox="0 0 32 18" fill="none">
        <rect width="32" height="18" rx="9" fill="#F8788F"/>
        <path fill-rule="evenodd" clip-rule="evenodd" d="M13.6531 10.9423L12 9.28917L10.3468 10.9423L10.0577 10.6532L11.7109 9.00003L10.0577 7.34693L10.3468 7.05784L12 8.71094L13.6531 7.05784L13.9421 7.34693L12.289 9.00003L13.9421 10.6532L13.6531 10.9423Z" fill="#FEFEFF"/>
        <path fill-rule="evenodd" clip-rule="evenodd" d="M13.6531 11.4001L12 9.74695L10.3468 11.4001L9.59993 10.6532L11.2531 9.00003L9.59992 7.34693L10
相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:50:25