An SVG with a line (or path) which uses stroke-dasharray only seems to trigger CSS and JS hover events when the user hovers over the solid parts of the dashed line: https://codepen.io/anon/pen/YeXoZy
Is there a simple way to make both the JS and CSS events trigger when the solid or invisible parts of the line are hovered?
My current plan is to draw a second, invisible line following the same path and use it to detect mouse events. https://codepen.io/anon/pen/BYNgRR This seems heavy handed and I'm hoping there's a cleaner way I'm missing.
I'm not sure how to do it without the second "detector" line, but a less heavy handed way is at least possible without the JS.
Switch the order of the lines, then you can use the hover selector as usual for the dashed line, then use + in a selector for the detector line to change the properties of the line immediately following it:
https://codepen.io/RyanGoree/pen/LQVKBV
This can be solved somewhat by using a rect instead of line and using SVG transforms with patterns.
An example can be seen at this CodePen.
It essentially bubbles down to:
<svg height="210" width="500">
<defs>
<pattern id="pattern1"
width="10" height="10"
patternUnits="userSpaceOnUse"
patternTransform="rotate(0 60 60)">
<line stroke="green" stroke-width="12px" y2="10"/>
</pattern>
<pattern id="pattern2"
width="10" height="10"
patternUnits="userSpaceOnUse"
patternTransform="rotate(0 60 60)">
<line stroke="red" stroke-width="12px" y2="10" stroke="transparent"/>
</pattern>
</defs>
<g transform="rotate(45 60 60)">
<rect x="0" y="0" width="500" height="5"/>
</g>
</svg>
And the following CSS:
rect {
fill: url(#pattern1)
}
rect:hover {
fill: url(#pattern2)
}
This is an old topic I know. But found the answer on Css hover sometimes doesn't work on svg paths
If you want to trigger the event only on stroke/visible, use pointer-events: stroke; or pointer-events: visible; (only the stroke) and pointer-events: all; (on both)
Here is a code example:
<body>
<div id="donut-score" class="svg-item" style="display: block;">
<svg width="100%" height="100%" viewBox="0 0 40 40" class="donut">
<circle class="donut-hole" cx="20" cy="20" r="15.91549430918954" fill="#fff"></circle>
<circle class="donut-ring" cx="20" cy="20" r="15.91549430918954" fill="transparent" stroke-width="3.5"></circle>
<circle id="donut-score-part-1" class="donut-segment donut-segment-1" onmousemove="this.style.stroke ='orange';" onmouseout="this.style.stroke = '#ff8197';" cx="20" cy="20" r="15.91549430918954" fill="transparent" stroke-width="3.5" stroke-dasharray="20 80" stroke-dashoffset="25"></circle>
<g class="donut-text-item donut-text-item">
<text y="50%" transform="translate(0, 2)">
<tspan id="donut-score-text" x="50%" text-anchor="middle" class="donut-text">Score </tspan>
<tspan id="donut-score-aantal" x="50%" Y="65%" text-anchor="middle" class="donut-text">0 </tspan>
</text>
</g>
</svg>
</div>
</body>
ccs:
.donut-segment {
stroke: #ff8197;
}
.svg-item {
width:200px;
font-size: 16px;
margin: 0 auto;
}
.donut-text {
font-size: 0.35em;
line-height: 1;
transform: translateY(0.5em);
font-weight: bold;
}
If you add pointer-events: stroke; to the class .donut-segment then it only works on the stroke. If you use non or pointer-events: all it works on both. I tested it in codepen.
I made this SVG, now I'm trying to get it to cover the button, how do I do this?
As you can see in the code it's hanging off the button, How do I have it cover the button?
Code:
https://jsfiddle.net/ztmvxnft/2/
SVG:
<svg width="266" height="266" viewBox="0 0 266 266">
<line x1="264" y1="1" x2="0" y2="1" style="stroke: #0059dd; stroke-width: 3;" />
<line x1="265" y1="265" x2="265" y2="0" style="stroke: #0059dd;stroke-width: 3; " />
<line x1="100%" y1="265" x2="0" y2="265" style="stroke: #0059dd ; stroke-width: 3;" />
<line x1="1" y1="100%" x2="1" y2="0" style="stroke:#0059dd;stroke-width: 3; " />
<line x1="0" y1="0" x2="100%" y2="100%" style="stroke:#0059dd; stroke-width:3" />
<line x1="0" y1="100%" x2="100%" y2="0" style="stroke:#0059dd; stroke-width:3" />
</svg>
The user-agent stylesheet likely has (and in the case of Chrome definitely has) padding inside buttons. If you add padding:0 to your styling of the button, the SVG fits correctly.
Edit: With that change, you may still see that the SVG does not quite fit, depending on the browser. If so, that is because the "266px" size of the button includes the border of the button. If you want the SVG to fit entirely within the button, you can change the box-sizing to content-box as in the JSfiddle below, but keep in mind that it means your button will be a little larger than 266px. Alternately, you can set the border-width to 0 (or the border to none) to eliminate the border entirely at which point the button will be exactly 266px.
JSfiddle
I am not able to figure out how to make path of a circle to go in the middle. I have an example on jsfiddle.
Basically, how do we make this black path go in the middle? This is the path (2nd in svg tag):
[![enter image description here][1]][1]
https://jsfiddle.net/6e1z6xkq/
<div align="center">
<div class="circleDraw">
<svg width="116" height="100">
<g transform="translate(58,58)">
<path d="M-44.430577700900734,37.281681361819274A58,58 0 1,1 44.43057770090073,37.28168136181928L35.23804438347299,29.568230045580812A46,46 0 1,0 -35.238044383472996,29.568230045580805Z" style="fill: rgb(100, 150, 100);">
</path>
<path d="M-90.430577700900734,97.281681361819274A58,58 0 0,1 -96.07604799105425,3.22779870395063L-96.54307254462923,7.939288627271193A46,46 0 0,0 -35.238044383472996,29.568230045580805Z" style="fill: rgb(255, 1, 1);" width="15px" height="20px">
</path>
</svg>
</div>
</div>
You want something like the below (although I would observe that your SVG source is verbose. You can get the same result from a single move and arc drawing command with a green stroke & appropriate stroke width. And there should be no need for a transform - this looks like a drawing tool export.)
<div align="center">
<div class="speedometer--points">
<svg width="116px" height="100px">
<g transform="translate(58,58)">
<path d="M-44.430577700900734,37.281681361819274A58,58 0 1,1 44.43057770090073,37.28168136181928 L35.23804438347299,29.568230045580812 A46,46 0 1,0 -35.238044383472996,29.568230045580805Z" fill="green">
</path>
<path d="M -45 35 l 45 -45" stroke="red" stroke-width="5">
</path>
</g>
</svg>
</div>
</div>
Positioning and animating a line within the svg
It was easiest to go into Illustrator to create a stroke path that matched your arc.
From there it is just a matter of animating the svg with the following css. For any point along the path you can set the stroke-dashoffset from 285 to 515 (for this example.
.speed{
stroke-dasharray: 260px;
stroke-dashoffset: 285;
}
To Animate The stroke with CSS
You can apply a transition of the stroke-dataoffset to the complete path (css-tricks has a good article on this), like so:
svg:hover .speed{
stroke-dashoffset: 515;
transition: 1s ease;
}
Positioning a circle in the middle of your svg
I apologize I misread the question initially. You will want to add a <circle></circle> svg tag with cx, cy, and r attributes. cx and cy are the positioning attributes and r is the radius. In this case cx and cy are set to zero and I've arbitrarily set the radius.
You can read more about basic svg shapes at MDN
Moving the red path to the middle
You can add transform: translate(x,y) to the appropriate path. 'x' and 'y' represent the x and y coordinates of the path. You can also add other attributes like rotate() and skew(). MDN has good explanations of this as well.
Also I noticed in your fiddle that you hadn't closed the <g> tag.
.speed {
stroke-dasharray: 260px;
stroke-dashoffset: 285;
transition: 1s ease;
}
svg:hover .speed {
stroke-dashoffset: 515;
transition: 1s ease;
}
<div align="center">
Hover over the first svg!
<div class="circleClass">
<svg width="116" height="100">
<g transform="translate(58,58)">
<path d="M-44.430577700900734, 37.281681361819274A58, 58 0 1,1 44.43057770090073,37.28168136181928L35.23804438347299,29.568230045580812A46,46 0 1,0 -35.238044383472996,29.568230045580805Z" style="fill: rgb(100, 150, 100);"/>
<path class="speed" d="M40.1,33.5l3.4-4.9c12.6-19,11.4-44.3-3.6-62.1C29.9-45.3,15.4-52,0-52c-12.2,0-24.1,4.3-33.4,12.2
c-20.4,17.1-24.4,46.8-10,68.5c0,0,2.3,4,3.3,5.1" stroke="red" fill="transparent" stroke-width="12"/>
</g>
</svg>
</div>
</div>
<div align="center">
<div class="circleClass">
<svg width="116" height="100">
<g transform="translate(58,58)">
<path d="M-44.430577700900734,37.281681361819274A58,58 0 1,1 44.43057770090073,37.28168136181928L35.23804438347299,29.568230045580812A46,46 0 1,0 -35.238044383472996,29.568230045580805Z" style="fill: rgb(100, 150, 100);">
</path>
<polygon points="2,2.50 0,-2.5 -40,30" style="fill:red;" />
</g>
</svg>
</div>
</div>
<div align="center">
<svg width="116" height="100">
<g transform="translate(58,58)">
<path d="M-44.430577700900734,37.281681361819274A58,58 0 1,1 44.43057770090073,37.28168136181928L35.23804438347299,29.568230045580812A46,46 0 1,0 -35.238044383472996,29.568230045580805Z" style="fill: rgb(100, 150, 100);">
</path>
<circle cx="0" cy="0" r="25"/>
</g>
</svg>
</div>
Your task is complicated a little due to the fact that your green arc is not a simple little path arc that goes from left to right (or vice versa). It is actually a closed shape that defines the outside of the green shape. So it goes from left to right around the outer radius, then a little straight bit to the inner radius, and another arc back to the start.
It is possible to fill a green shape like that, in a meter like way, using a mask or a clipping path. However it is much simpler to just convert your green meter shape to a simple path that goes from left to right in one direction, and has a thick width.
If we do that, your SVG becomes, something like:
<div align="center">
<div class="circleDraw">
<svg width="116" height="100">
<g transform="translate(58,58)">
<! the green path converted to a simple one directional stroke -->
<path d="M -39.8,33.4 A 52,52, 0, 1, 1, 39.8, 33.4"
style="fill: none; stroke-width: 12; stroke: rgb(100, 150, 100);">
</path>
</g>
</svg>
</div>
</div>
Now that we've done that, we can use a really easy method to produce your black meter line.
What we do is make an exact duplicate of the green line (except black this time of course). Then we apply a dash array to the line that makes it on for 50% of the length and off for 50% of the length.
The length of our arc is 236 units. So we set the dash array to:
stroke-dasharray: 118 118
<div align="center">
<div class="circleDraw">
<svg width="116" height="100">
<g transform="translate(58,58)" style="fill: none; stroke-width: 12;">
<! the green path -->
<path d="M -39.8,33.4 A 52,52, 0, 1, 1, 39.8, 33.4"
style="stroke: rgb(100, 150, 100);">
</path>
<!-- the black path -->
<path d="M -39.8,33.4 A 52,52, 0, 1, 1, 39.8, 33.4"
style="stroke: black; stroke-dasharray: 118 118;">
</path>
</g>
</svg>
</div>
</div>
If you need to change the meter to read something other than 50%, then you need to adjust the value of the stroke-dasharray. Just make sure the two values add up to (at least) 236.
This other question shows how to update the meter with Javascript if that's what you ultimately want to do.
I've a polygon and I want to get the contour of it, it looks like this:
<polygon fill="transparent" points=" -60.48565220947266,46.13742103271485, 56.557547790527344,46.13742103271485, 56.557547790527344,-5.06897780456543, -60.48565220947266,-5.06897780456543, 37.050350115966786,-9.94577780456543, -85.80719033203123,-9.94577780456543, -85.80719033203123,46.13742103271485, 56.34799779052733,46.13742103271485, 56.34799779052733,19.315022195434572, 37.050350115966786,19.315022195434572, -74.9509506591797,-5.06897780456543, -74.9509506591797,46.13742103271485, 56.347997790527344,46.13742103271485, 56.347997790527344,19.315022195434572, 37.0503501159668,19.315022195434572, 37.0503501159668,-9.94577780456543, -30.333590332031253,-9.94577780456543, -30.333590332031253,-5.06897780456543, 37.0503501159668,-5.06897780456543" style="stroke: black; stroke-width: 1px;" stroke-dasharray="5, 5" id="#contour"></polygon>
<svg>
<g transform="translate(100,100)">
<polygon fill="transparent" points=" -60.48565220947266,46.13742103271485, 56.557547790527344,46.13742103271485, 56.557547790527344,-5.06897780456543, -60.48565220947266,-5.06897780456543, 37.050350115966786,-9.94577780456543, -85.80719033203123,-9.94577780456543, -85.80719033203123,46.13742103271485, 56.34799779052733,46.13742103271485, 56.34799779052733,19.315022195434572, 37.050350115966786,19.315022195434572, -74.9509506591797,-5.06897780456543, -74.9509506591797,46.13742103271485, 56.347997790527344,46.13742103271485, 56.347997790527344,19.315022195434572, 37.0503501159668,19.315022195434572, 37.0503501159668,-9.94577780456543, -30.333590332031253,-9.94577780456543, -30.333590332031253,-5.06897780456543, 37.0503501159668,-5.06897780456543" style="stroke: black; stroke-width: 1px;" stroke-dasharray="5, 5" id="#contour"></polygon>
</g>
</svg>
I want to remove everything that is inside of the polygon and keep only the border, my math skills are low and I'm having trouble making it to work.
How can I achive this?
I notice that svg adds some gradient borders in very tiny pixels around elements. Here's the jsfiddle for it:
http://jsfiddle.net/XrkRT/
<rect x="1" y="1" width="1198" height="398"
fill="none" stroke="blue" stroke-width="10" />
<g stroke="green" >
<line x1="100" y1="300" x2="300" y2="300"
stroke-width="20" fill="none" />
</g>
How do I draw solid color line and rect. It's hard to see with normal zoom. I take a screenshot and zoom it in pixlr.com. Here's the image:
That's antialiasing. You can turn it off with shape-rendering="crispEdges" but be aware that any diagonal lines will look rougher.