如何将图像添加到svg以映射圆圈中的每个饼



如何将图像添加到SVG中的路径中,并旋转路径内的文本并使其更靠近路径的边缘?

我目前在我的React应用程序中使用以下代码来创建具有多个部分的轮盘赌轮。每个部分由一条填充了特定颜色的路径表示。我想在每个路径中添加一个图像,并旋转路径内的文本,使其更靠近路径的边缘。

const RouletteWheel = () => {
const items = ["item1", "item2", "item3", "item4"];
const colors = ["blue", "red", "green", "yellow", "brown", "purple"];
const numItems = items.length;
const angle = items.length === 1 ? 0 : 360 / numItems;
return (
<svg viewBox="0 0 100 100" className="svg-wheel">
{items.length > 1 ? (
items.map((item, index) => {
const x1 = 50 + 45 * Math.cos(angle * index * (Math.PI / 180));
const y1 = 50 + 45 * Math.sin(angle * index * (Math.PI / 180));
const x2 = 50 + 45 * Math.cos(angle * (index + 1) * (Math.PI / 180));
const y2 = 50 + 45 * Math.sin(angle * (index + 1) * (Math.PI / 180));
return (
<React.Fragment>
<defs>
<path
id="text-path"
d={`M 50 50 L ${x1} ${y1} A 45 45 0 0 1 ${x2} ${y2} Z`}
/>
</defs>
<path
key={`path-${index}`}
id={`path-${index}`}
d={`M 50 50 L ${x1} ${y1} A 45 45 0 0 1 ${x2} ${y2} Z`}
fill={`${colors[index]}`}
></path>
<text
x={20}
dy={25}
fill="white"
textAnchor="middle"
fontSize={4}

>
<textPath transform={`rotate(100)`} xlinkHref={`#path-${index}`}>{item}</textPath>
</text>
</React.Fragment>
);
})
) : (
<circle key={"circle"} cx="50" cy="50" r="45" fill="url(#pattern1)" />
)}
</svg>
);
};
ReactDOM.render(
RouletteWheel(),
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container"></div>

下面是纯SVG的示例。在第一个例子中,我只是使用圆圈(#c1)的笔触实现了纯色。

在第二个示例中,我用图像替换了纯色。这里圆圈(#c1)作为图像的蒙版。棘手的部分是将图像与蒙版放在正确的角度。一般来说,所有的旋转都是从一个圆(360度)分成5个项目计算的。各72度

在这两个例子中,文本沿着一个圆圈(#c2)放置,使用textpath元素和属性startOffset。文本的主导基线是"悬挂"。——所以文本是放在"下面"圆/弧。文字的位置可以用圆的半径(#c2)来调整。

<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="300">
<defs>
<circle id="c1" r="23" fill="none" stroke-width="46"
stroke-dasharray="72 360" pathLength="360" />
<circle id="c2" r="45" fill="none" pathLength="360" />
</defs>
<g transform="translate(50 50)">
<use href="#c1" stroke="blue" transform="rotate(0)" />
<use href="#c1" stroke="red" transform="rotate(72)" />
<use href="#c1" stroke="green" transform="rotate(144)" />
<use href="#c1" stroke="yellow" transform="rotate(216)" />
<use href="#c1" stroke="brown" transform="rotate(288)" />
<text font-size="6" fill="white" text-anchor="middle"
dominant-baseline="hanging">
<textPath href="#c2" startOffset="36">item 1</textPath>
<textPath href="#c2" startOffset="108">item 2</textPath>
<textPath href="#c2" startOffset="180">item 3</textPath>
<textPath href="#c2" startOffset="252">item 4</textPath>
<textPath href="#c2" startOffset="324">item 5</textPath>
</text>
</g>
</svg>

<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="300">
<defs>
<mask id="m1">
<circle r="23" fill="none" stroke="white" stroke-width="46"
stroke-dasharray="72 360" pathLength="360" />
</mask>
<circle id="c2" r="45" fill="none" pathLength="360" />
</defs>
<g transform="translate(50 50)">
<g mask="url(#m1)">
<image href="https://via.placeholder.com/300/09f/fff.png" width="60"
x="-30" y="-60" transform="rotate(126)" />
</g>
<g mask="url(#m1)" transform="rotate(72)">
<image href="https://via.placeholder.com/300/080/fff.png" width="60"
x="-30" y="-60" transform="rotate(126)" />
</g>
<g mask="url(#m1)" transform="rotate(144)">
<image href="https://via.placeholder.com/300/800/fff.png" width="60"
x="-30" y="-60" transform="rotate(126)" />
</g>
<g mask="url(#m1)" transform="rotate(216)">
<image href="https://via.placeholder.com/300/f0f/fff.png" width="60"
x="-30" y="-60" transform="rotate(126)" />
</g>
<g mask="url(#m1)" transform="rotate(288)">
<image href="https://via.placeholder.com/300/022/fff.png" width="60"
x="-30" y="-60" transform="rotate(126)" />
</g>
<text font-size="6" fill="white" text-anchor="middle"
dominant-baseline="hanging">
<textPath href="#c2" startOffset="36">item 1</textPath>
<textPath href="#c2" startOffset="108">item 2</textPath>
<textPath href="#c2" startOffset="180">item 3</textPath>
<textPath href="#c2" startOffset="252">item 4</textPath>
<textPath href="#c2" startOffset="324">item 5</textPath>
</text>
</g>
</svg>

最新更新