I have an SVG clipPath made of multiple path elements, which I need to apply to a group of elements. I only want to clip out the area under the path stroke itself, not in between the paths. (example that doesn't do what I want follows)
var lineData = [ { "x": 1, "y": 5}, { "x": 100, "y": 400},
{ "x": 300, "y": 100}, { "x": 600, "y": 600},
{ "x": 700, "y": 50} ];
var lineData2 = [ { "x": 1, "y": 500}, { "x": 100, "y": 100},
{ "x": 300, "y": 700}, { "x": 600, "y": 60},
{ "x": 700, "y": 700} ];
var lineFunction = d3.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.curve(d3.curveBundle);
var svg = d3.select('body')
.append('svg')
.attr('id', 'svg')
.attr('width', 660)
.attr('height', 660)
.style('outline', '1px solid red')
.append('g')
.attr('clip-path', 'url(#clippy)');
var polygon = svg.append('polygon')
.attr('points', '230 10, 660 330, 230 650')
.attr('fill', '#c99');
var circle = svg.append('circle')
.attr('cx', 230)
.attr('cy', 330)
.attr('r', 200)
.attr('fill', '#9c6')
var clippy = d3.select('#svg')
.append('defs')
.append('clipPath')
.attr('id', 'clippy');
clippy.append("path")
.attr("d", lineFunction(lineData))
.attr("stroke", "blue")
.attr("stroke-width", 18)
.attr("fill", "none");
clippy.append("path")
.attr("d", lineFunction(lineData2))
.attr("stroke", "blue")
.attr("stroke-width", 18)
.attr("fill", "none");
Basically I want to accomplish something similar to what you get using letters, but instead using lines/paths.
var lineData = [ { "x": 1, "y": 5}, { "x": 100, "y": 400},
{ "x": 300, "y": 100}, { "x": 600, "y": 600},
{ "x": 700, "y": 50} ];
var lineData2 = [ { "x": 1, "y": 500}, { "x": 100, "y": 100},
{ "x": 300, "y": 700}, { "x": 600, "y": 60},
{ "x": 700, "y": 700} ];
var lineFunction = d3.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.curve(d3.curveBundle);
var svg = d3.select('body')
.append('svg')
.attr('id', 'svg')
.attr('width', 660)
.attr('height', 660)
.style('outline', '1px solid red')
.append('g')
.attr('clip-path', 'url(#clippy)');
var polygon = svg.append('polygon')
.attr('points', '230 10, 660 330, 230 650')
.attr('fill', '#c99');
var circle = svg.append('circle')
.attr('cx', 230)
.attr('cy', 330)
.attr('r', 200)
.attr('fill', '#9c6')
var clippy = d3.select('#svg')
.append('defs')
.append('clipPath')
.attr('id', 'clippy');
clippy.append('text')
.attr('x', 120)
.attr('y', 320)
.attr('font-size', '4em')
.attr('font-weight', 'bold')
.attr('font-family', 'Georgia')
.text('This is a clip');
clippy.append('text')
.attr('x', 120)
.attr('y', 420)
.attr('font-size', '4em')
.attr('font-weight', 'bold')
.attr('font-family', 'Georgia')
.text('Also a clip')
Please help!
EDIT: Here's a Codepen with both examples.
From my reading of the SVG spec, it's not possible to use only a
<path>
's stroke as the clipping path:However, converting the
<clipPath>
to a<mask>
element produces what I think is your desired effect. Here's a forked CodePen to demonstrate — the paths have have their strokes set towhite
, and the<text>
elements were also given afill
ofwhite
to match the clip-path effect.