D3 图像 SVG 未显示
D3 Image SVG not showing
我想在 svg 圆圈内填充图像,但由于圆形定位,请避免像这样 Whosebug Link 中的“图案”模式。
所以我尝试了这个:
var defs = group
.append('svg:defs')
defs
.append("svg:image")
.attr("id", "chara_avatar")
.attr("xlink:href", imglink)
.attr("width", 3*rad)
.attr("height", 2*rad)
.attr('x', (d,i)=>{ //same x position as the circle
let x = (r * Math.sin(Math.PI * 2 * (i * 36) / 360)) + cx
return x-rad;
})
.attr('y',(d,i)=>{ //same y position as the circle
let y = (r * Math.cos(Math.PI * 2 * (i * 36) / 360)) + cy
return y-rad;
});
并直接与 "url('#chara_avatar')"
一起使用:
var graphic = group
.append('circle')
.attr('cx', (d,i)=>{
let x = (r * Math.sin(Math.PI * 2 * (i * 36) / 360)) + cx
return x;
})
.attr('cy',(d,i)=>{
let y = (r * Math.cos(Math.PI * 2 * (i * 36) / 360)) + cy
return y;
})
.attr('r',rad)
.style('fill', (d)=> {
let init = d.val;
if(init==1) {
return "url(#chara_avatar)" // <------- called the url for fill
} else if (init==0) {
return 'black'
}
})
.style('stroke', 'black')
.style('stroke-width', '3px')
.style('cursor',(d)=> {
let init = d.val;
if (init==1) {
return 'pointer'
}
})
但结果是这样的:
- 我找对了位置,元素在那里,但是没有显示出来。
- 图像标签 AFAIK 已正确放置,但它只显示
href
而不是 xlink:href
即使我写 'xlink:href'
如果我将 defs
更改为 group
(将图像直接附加到组),它会起作用并将图像放在圆圈上方,但我不知道如何剪辑它。我已经使用了 ClipPath 但无法正常工作。
完整代码示例:Codepen Link
更新:
Didn't find any good answer here, and I choose appending divs than svgs, it works with a bit more lines
如果您不想使用图案,您可以用圆圈剪裁图像。
在下一个例子中,我使用了一个圆和一个图像,它们都以点 x=0,y=0 为中心。
接下来我将图像翻译到所需的位置,在您的代码中就是圆心的位置。图像被圆圈剪裁。
<svg viewBox="0 0 1100 600" style="background-color: steelblue;">
<defs>
<image id="chara_avatar" xlink:href="https://images.unsplash.com/photo-1490730141103-6cac27aaab94?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80" width="189.63000000000002" height="126.42000000000002" x="-94.185" y="-63.21"></image>
<clipPath id="cp">
<circle id="c" r="63.21000000000001" style="fill:red; stroke: black; stroke-width: 3px; cursor: pointer;"></circle>
</clipPath>
</defs>
<use transform="translate(509,526.75)" xlink:href="#chara_avatar" clip-path="url(#cp)"></use>
<use transform="translate(641.6925207050258,483.6355864801444)" xlink:href="#chara_avatar" clip-path="url(#cp)"></use>
</svg>
你可以对每个圈子做同样的事情。
这可以通过在适当的位置根据需要添加尽可能多的 SVG <image>
元素来实现。
然后您将使用 <clipPath>
,其中 <circle>
和“link”每个循环 clipPath 到每个 <image>
。同样,每个圆圈的位置应该与它必须剪辑的图像相匹配。
附上工作codepen
片段:
<svg viewBox="0 0 1100 600" style="background-color: steelblue;">
<defs>
<clipPath id="clip-circle-0">
<circle r="50" cx="100" cy="100"></circle>
</clipPath>
</defs>
<image href="https://images.unsplash.com/photo-1490730141103-6cac27aaab94?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80" x="50" y="50" width="100" height="100" style="clip-path: url(#clip-circle-0)"></image>
</svg>
我想在 svg 圆圈内填充图像,但由于圆形定位,请避免像这样 Whosebug Link 中的“图案”模式。
所以我尝试了这个:
var defs = group
.append('svg:defs')
defs
.append("svg:image")
.attr("id", "chara_avatar")
.attr("xlink:href", imglink)
.attr("width", 3*rad)
.attr("height", 2*rad)
.attr('x', (d,i)=>{ //same x position as the circle
let x = (r * Math.sin(Math.PI * 2 * (i * 36) / 360)) + cx
return x-rad;
})
.attr('y',(d,i)=>{ //same y position as the circle
let y = (r * Math.cos(Math.PI * 2 * (i * 36) / 360)) + cy
return y-rad;
});
并直接与 "url('#chara_avatar')"
一起使用:
var graphic = group
.append('circle')
.attr('cx', (d,i)=>{
let x = (r * Math.sin(Math.PI * 2 * (i * 36) / 360)) + cx
return x;
})
.attr('cy',(d,i)=>{
let y = (r * Math.cos(Math.PI * 2 * (i * 36) / 360)) + cy
return y;
})
.attr('r',rad)
.style('fill', (d)=> {
let init = d.val;
if(init==1) {
return "url(#chara_avatar)" // <------- called the url for fill
} else if (init==0) {
return 'black'
}
})
.style('stroke', 'black')
.style('stroke-width', '3px')
.style('cursor',(d)=> {
let init = d.val;
if (init==1) {
return 'pointer'
}
})
但结果是这样的:
- 我找对了位置,元素在那里,但是没有显示出来。
- 图像标签 AFAIK 已正确放置,但它只显示
href
而不是xlink:href
即使我写'xlink:href'
如果我将 defs
更改为 group
(将图像直接附加到组),它会起作用并将图像放在圆圈上方,但我不知道如何剪辑它。我已经使用了 ClipPath 但无法正常工作。
完整代码示例:Codepen Link
更新:
Didn't find any good answer here, and I choose appending divs than svgs, it works with a bit more lines
如果您不想使用图案,您可以用圆圈剪裁图像。
在下一个例子中,我使用了一个圆和一个图像,它们都以点 x=0,y=0 为中心。 接下来我将图像翻译到所需的位置,在您的代码中就是圆心的位置。图像被圆圈剪裁。
<svg viewBox="0 0 1100 600" style="background-color: steelblue;">
<defs>
<image id="chara_avatar" xlink:href="https://images.unsplash.com/photo-1490730141103-6cac27aaab94?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80" width="189.63000000000002" height="126.42000000000002" x="-94.185" y="-63.21"></image>
<clipPath id="cp">
<circle id="c" r="63.21000000000001" style="fill:red; stroke: black; stroke-width: 3px; cursor: pointer;"></circle>
</clipPath>
</defs>
<use transform="translate(509,526.75)" xlink:href="#chara_avatar" clip-path="url(#cp)"></use>
<use transform="translate(641.6925207050258,483.6355864801444)" xlink:href="#chara_avatar" clip-path="url(#cp)"></use>
</svg>
你可以对每个圈子做同样的事情。
这可以通过在适当的位置根据需要添加尽可能多的 SVG <image>
元素来实现。
然后您将使用 <clipPath>
,其中 <circle>
和“link”每个循环 clipPath 到每个 <image>
。同样,每个圆圈的位置应该与它必须剪辑的图像相匹配。
附上工作codepen
片段:
<svg viewBox="0 0 1100 600" style="background-color: steelblue;">
<defs>
<clipPath id="clip-circle-0">
<circle r="50" cx="100" cy="100"></circle>
</clipPath>
</defs>
<image href="https://images.unsplash.com/photo-1490730141103-6cac27aaab94?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80" x="50" y="50" width="100" height="100" style="clip-path: url(#clip-circle-0)"></image>
</svg>