将文本环绕成一个圆圈

Wrapping text in a circle

您好,刚接触编码,但已经做到了这一点。我想做的就是理解/学习如何包装我的文本,使其适合一个圆圈,例如文本变成两行而不是一行,因此它位于圆的边界内。任何帮助将非常感激。下面的代码可以通过 google 驱动器 link 找到 - 最好用 SUBLIME TEXT 打开。

HTML file. code can be opened with Sublime text

超出圆圈的文字图片以及它在圆圈中的外观

一行中的文字图像以及我希望它看起来像的文字被换行了

运行 全屏页面

var json = {
  "name": "Career to date",
  "children": [{
      "name": "Consumer",
      "children": [{
          "name": "Pet care",
          "children": [{
            "name": "Pet vitamins",
            "size": 3000,
          }]
        },
        {
          "name": "Sports & Activity",
          "children": [{
              "name": "Kinneir Dufort | Daily gathering & clustering of wearbal tech",
              "size": 3000
            },
            {
              "name": "RYA | Sailing evaluation",
              "size": 3000
            },
            {
              "name": "Sony | Wearable technology",
              "size": 3000
            },
            {
              "name": "UEFA | International football tournament",
              "size": 3000
            },
          ]
        },
        {
          "name": "Food",
          "children": [{
            "name": "Cargill | The future of poultry",
            "size": 3000
          }, ]
        },
        {
          "name": "Transport",
          "children": [{
              "name": "Shell | Engine maintenance",
              "size": 3000
            },
            {
              "name": "HS2 | High speed intercity train travel",
              "size": 3000
            },
          ]
        },
        {
          "name": "Screen based technology",
          "children": [{
              "name": "Google | Advertisement attention",
              "size": 3000
            },
            {
              "name": "BBC Iplayer | On demand & catch up video services",
              "size": 3000
            },
            {
              "name": "Cbeebies | Children's AR & VR apps",
              "size": 3000
            },
          ]
        },
        {
          "name": "FMCG packaging",
          "children": [{
              "name": "Cooper Vision | Contact lenses",
              "size": 3000
            },
            {
              "name": "Beiersdorf | Sensorial shower",
              "size": 3000
            },
            {
              "name": "Tetrapak | Ambient still drinks",
              "size": 3000
            },
            {
              "name": "Coca Cola | USA childrens drink packaging",
              "size": 3000
            },
          ]
        },
        {
          "name": "Family",
          "children": [{
              "name": "Healthy food goals",
              "size": 3000
            },
            {
              "name": "Me time",
              "size": 3000
            },
            {
              "name": "First aid & safety",
              "size": 3000
            },
          ]
        },
        {
          "name": "Interiors",
          "children": [{
              "name": "Unilever | Household cleaning",
              "size": 3000
            },
            {
              "name": "Canary WHARF Group | Luxury rental appartments",
              "size": 3000
            },
            {
              "name": "HS2 | Staff break areas in train stations",
              "size": 3000
            },
          ]
        },
        {
          "name": "Finance",
          "children": [{
              "name": "Newham Council | Emergency loans",
              "size": 3000
            },
            {
              "name": "Money Advice Service | Debt advice",
              "size": 3000
            },
          ]
        },
        {
          "name": "Construction",
          "children": [{
              "name": "CITB | Onsite digital technology",
              "size": 3000
            },
            {
              "name": "CITB | Current and future workforce skilling",
              "size": 3000
            },
            {
              "name": "CITB | VR & AR for learning & training",
              "size": 3000
            },
          ]
        },
        {
          "name": "Energy",
          "children": [{
              "name": "Ofgem | Smart meter data",
              "size": 3000
            },
            {
              "name": "Ofgem | Energy price caps",
              "size": 3000
            },
            {
              "name": "Ofgem | The future energy market",
              "size": 3000
            },
            {
              "name": "Ofgem | Energy bill information, design & layout",
              "size": 3000
            },
            {
              "name": "Ofgem | Price control process & DNO's",
              "size": 3000
            }
          ]
        },
        {
          "name": "360 video",
          "size": 3000
        }
      ]
    },
    {
      "name": "Medical",
      "children": [{
          "name": "Respiratory drug delivery",
          "children": [{
            "name": "ACTIVIS | Dry powder inhalers",
            "size": 3000
          }, ]
        },
        {
          "name": "Diabetes Management",
          "children": [{
              "name": "Roche | CGM data management with AGP",
              "size": 3000
            },
            {
              "name": "Roche | Insulin pump configuration",
              "size": 3000
            },
            {
              "name": "Roche | Infusion set inserters",
              "size": 3000
            },
            {
              "name": "Roche | Continuous glucose monitoring (CGM)",
              "size": 3000
            },
            {
              "name": "Roche | Blood glucose meters",
              "size": 3000
            },
            {
              "name": "Roche | Insulin pumps & injections",
              "size": 3000
            },
          ]
        },
        {
          "name": "Advanced Wound Care",
          "children": [{
              "name": "Smith & nephew | Silicone gel dressings for highly exeduing wounds",
              "size": 3000
            },
            {
              "name": "Smith & Nephew | Biosynthetic dressings for burns",
              "size": 3000
            },
            {
              "name": "Smith & Nephew | Abdominal cavity closure",
              "size": 3000
            },
            {
              "name": "Negative pressure wound therapy (NPWT)",
              "size": 3000
            },
          ]
        },
        {
          "name": "Musculoskeletal Disorders",
          "children": [{
            "name": "HSE | MSDs in & out of the workplace",
            "size": 3000
          }, ]
        },
        {
          "name": "Stoma Care",
          "children": [{
            "name": "Eakin | Colostomies, illeostomies & urostomies",
            "size": 3000
          }]
        }
      ]
    },
    {}
  ]
}
var svg = d3.select("svg"),
  margin = 20,
  diameter = +svg.attr("width"),
  g = svg.append("g").attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");

var color = d3.scaleLinear()
  .domain([-1, 5])

  // CHANGE COLOUR HERE
  .range(["rgb(0,0,0)", "rgb(255,255,255)"])
  .interpolate(d3.interpolateHcl);

//CHANGES HOW CLOSE THE CIRLCES ARE
var pack = d3.pack()
  .size([diameter - margin, diameter - margin])
  .padding(5);

d3.json('flare.json', function(error, root) {
  // if (error) throw error;

  root = d3.hierarchy(json)
    .sum(function(d) {
      return d.size;
    })
    .sort(function(a, b) {
      return b.value - a.value;
    });

  var focus = root,
    nodes = pack(root).descendants(),
    view;

  var circle = g.selectAll("circle")
    .data(nodes)
    .enter().append("circle")
    .attr("class", function(d) {
      return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root";
    })
    .style("fill", function(d) {
      return color(d.depth);
    })
    .on("click", function(d) {
      if (focus !== d) zoom(d),
        d3.event.stopPropagation();
    });

  var text = g.selectAll("text")
    .data(nodes)
    .enter().append("text")
    .attr("class", "label")
    .style("fill-opacity", function(d) {
      return d.parent === root ? 1 : 0;
    })
    .style("display", function(d) {
      return d.parent === root ? "inline" : "none";
    })

    // ITEMS FONT SIZE HERE
    .style("font-size", function(d) {
      if (d.parent) {
//            console.log(d.depth, d.r);
        var size = (d.r * d.depth * 0.175)
      }
      return size + "px";
    })
    .text(function(d) {
      return d.data.name;
    });

  var node = g.selectAll("circle,text");

  svg
    .style("background", color(-1))
    .on("click", function() {
      zoom(root);
    });

  zoomTo([root.x, root.y, root.r * 2 + margin]);

  function zoom(d) {
    var focus0 = focus;
    focus = d;

    var transition = d3.transition()
      .duration(d3.event.altKey ? 7500 : 750)
      .tween("zoom", function(d) {
        var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]);
        return function(t) {
          zoomTo(i(t));
        };
      });

    transition.selectAll("text")
      .filter(function(d) {
        return d.parent === focus || this.style.display === "inline";
      })
      .style("fill-opacity", function(d) {
        return d.parent === focus ? 1 : 0;
      })
      .on("start", function(d) {
        if (d.parent === focus) this.style.display = "inline";
      })
      .on("end", function(d) {
        if (d.parent !== focus) this.style.display = "none";
      });
  }

  function zoomTo(v) {
    var k = diameter / v[2];
    view = v;
    node.attr("transform", function(d) {
      return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")";
    });
    circle.attr("r", function(d) {
      return d.r * k;
    });
  }
});
.node {
  cursor: pointer;
}

.node:hover {
  stroke: rgb(255, 255, 255);
  stroke-width: 1px;
}

.node--leaf {
  fill: white;
}

.label {
  font: 10px "din", Helvetica, Arial, sans-serif;
  text-anchor: middle;
  fill: rgb(0, 0, 0);
  /* text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff, 0 -1px 0 #fff; */
}

.label,
.node--root,
.node--leaf {
  pointer-events: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>

<svg width="960" height="960"></svg>

SVG 不提供文本换行,但使用 foreignObject 可以实现类似的效果。为什么不尝试使用 foreignObjects。您可以在此处阅读更多相关信息 https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject,通过使用它,我能够根据您的要求包装文本,请查看下面的工作代码段。

svg {
  width: 700px;
  height: 200px;
  background-color: #000;
  padding: 50px;
}
.circle {
  background-color: rgb(119, 119, 119);
  height: 100%;
  border-radius: 100%;
  text-align: center;
  line-height: 200px;
  font-size: 30px;
}
.circle span {
  color: black;
  line-height: normal;
  display: inline-block;
  vertical-align: middle;
  font-family: sans-serif;
  font-size: 18px;
  padding: 20px;
}
<svg xmlns="http://www.w3.org/2000/svg">
  <foreignObject width="200" height="200" x="0" y="0">
    <div class="circle">
      <span>paragraph</span>
    </div>
  </foreignObject>
  <foreignObject width="200" height="200" x="250" y="0">
    <div class="circle">
      <span>Here is a paragraph</span>
    </div>
  </foreignObject>
  <foreignObject width="200" height="200" x="500" y="0">
    <div class="circle">
      <span>Here is a paragraph that requires word wrap</span>
    </div>
  </foreignObject>
</svg>