Apply CSS on part of line element in SVG [duplicate] - d3.js
This question already has an answer here:
line segmentation in D3.js
(1 answer)
Closed 6 years ago.
I am creating several horizontal and vertical lines and I want to paint a segment of the line say from point a to point b in some other color. I can to the same creting multiple lines but can it be done using some svg or d3 library where you can keep the same line and just paint a segment part of that line in different css?
You can use a gradient for the stroke
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Gradients -->
<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="Gradient1">
<stop class="stop1" offset="0%" />
<stop class="stop2" offset="50%" />
<stop class="stop3" offset="100%" />
</linearGradient>
<linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
<stop offset="0%" stop-color="red" />
<stop offset="50%" stop-color="black" stop-opacity="0" />
<stop offset="100%" stop-color="blue" />
</linearGradient>
<style type="text/css">
<![CDATA[ #rect1 {
fill: url(#Gradient1);
}
.stop1 {
stop-color: red;
}
.stop2 {
stop-color: black;
stop-opacity: 0;
}
.stop3 {
stop-color: blue;
}
]]>
</style>
</defs>
<line x1="20" y1="100" x2="100" y2="20" stroke="url(#Gradient2)" />
<rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#Gradient2)" />
</svg>
Related
SVG animate gradient along path
I have the following svg that i would like to animate. I would like the red part moves along the path up to the end (so from the top right side to the left bottom side) : The problem is : obviously is quite impossible to have a gradient following a path. Here is my code so far : <svg id="fil" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 783.53 362"> <defs> <style> .cls-3{ fill: none; stroke-miterlimit:10; stroke-width:3px; } </style> <linearGradient id="light" x1="100%" y1="100%"> <stop offset="70%" stop-color="#3E3E3E"> <!-- <animate attributeName="stop-color" to="#CF4B59" from="#3E3E3E" dur="0.5s" fill="freeze" /> --> </stop> <stop offset="100%" stop-color="#CF4B59"> <!-- <animate attributeName="stop-color" from="#CF4B59" to="#3E3E3E" dur="0.5s" fill="freeze" /> --> </stop> </linearGradient> </defs> <g id="Calque_2" data-name="Calque 2"> <g id="Calque_1-2" data-name="Calque 1"> <g class="cls-2"> <path class="cls-3" id="base" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" transform="translate(-52.32 -8.93)" stroke="url(#light)"/> </g> </g> </g> </svg> I tried to use "animate" to make it move along the path, but it's a vertical gradient which is applied and goes from the top to the bottom and not a gradient which follows the path. I had other ideas to overcome this : Maybe by using a second path which would be the same shape than the first one but with inverted gradient so I could make it slide along the initial path maybe Or, I could use opacity to make the final path appear but i'm not sure i will be able to make the red part move in this way... If you have some ideas to make the red part move from the top right to the bottom left it would help me a lot!
Question I would like the red part moves along the path up to the end (so from the top right side to the left bottom side) : Consider using fill-line animation with stroke-dashoffset. For clarity, I placed exactly the same curve below which will show the route of filling the line with color If this indication of the motion path is not necessary, simply remove the path id = "trace" <svg id="fil" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 783.53 362"> <defs> <style> .cls-3{ fill: none; stroke-miterlimit:10; stroke-width:3px; stroke:#E7E7E7; } #base { fill: none; stroke:crimson; stroke-width:3px; stroke-dashoffset:1732; stroke-dasharray:1732; animation: fillStroke 10s linear forwards; } #keyframes fillStroke { to {stroke-dashoffset:0;} } </style> </defs> <g transform="translate(-352.32 -8.93)"> <path id="trace" class="cls-3" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" /> <g class="cls-2"> <path id="base" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" > </path> </g> </g> </svg> Gradient animation option Instead of filling with color as the length of the curve increases, a gradient will perform this function <svg id="fil" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 783.53 362"> <defs> <style> .cls-3{ fill: none; stroke-miterlimit:10; stroke-width:3px; stroke:#E7E7E7; } #base { fill: none; stroke:url(#light); stroke-width:3px; stroke-dashoffset:1732; stroke-dasharray:1732; animation: fillStroke 10s linear forwards; } #keyframes fillStroke { to {stroke-dashoffset:0;} } </style> <linearGradient id="light" x1="100%" y1="100%"> <stop offset="50%" stop-color="#CF4B59"> <!-- <animate attributeName="stop-color" from="#CF4B59" to="#3E3E3E" dur="10s" fill="freeze" /> --> </stop> <stop offset="100%" stop-color="#3E3E3E"> <!-- <animate attributeName="stop-color" to="#CF4B59" from="#3E3E3E" dur="10s" fill="freeze" /> --> </stop> </linearGradient> </defs> <g transform="translate(-352.32 -8.93)"> <path class="cls-3" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" /> <g class="cls-2"> <path id="base" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" > </path> </g> </g> </svg>
Svg shows different on Firefox and Edge
I'm having some trouble with a svg image that has a number in the middle. It shows correct when using Chrome and other browsers but in Firefox and Edge the number gets wrong position. Link Here is my code. #maindiv { position: relative; width: 50px; height: 50px; } .number { font-family: initial; font-size: 2.5em; font-weight: 700; text-align: center; } <div id="maindiv" class="" style=""> <svg viewBox="0 -10 50 90" enable-background="new 0 0 50 50"> <defs> <!-- Background image for the svg --> <pattern id="image_594121ec06330" patternUnits="userSpaceOnUse" height="50" width="50" x="0" y="20"> <image x="0" y="0" height="50" width="50" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://via.placeholder.com/50x50"> </image> </pattern> <!-- two colors for the number --> <linearGradient id="textcolor_594121ec06343" x1="0%" y1="0%" x2="0%" y2="100%"> <stop offset="50%" stop-color="#ff0100"></stop> <stop offset="50%" stop-color="#0600c4"></stop> <stop offset="50%" stop-color="#0600c4"></stop> <stop offset="0" stop-color="#0600c4"></stop> </linearGradient> </defs> <rect class="cellImage" id="top" x="0" y="20" width="50" height="50" style="" fill="url(#image_594121ec06330)"></rect> <text class="number " x="50%" y="55%" alignment-baseline="middle" text-anchor="middle" fill="url(#textcolor_594121ec06343)">0</text> </svg> And here is the same code on jsfiddle https://jsfiddle.net/41s39p63/ I know this can be fixed by making some if-conditions that changes some svg attributes to place the number in the middle, if the user is on Firefox or Edge but I prefer not to use that solution. Is there anyone out there who can help me with a solution to this issue so it works on all browsers?
Firefox does not support alignment-baseline. You should be able to use dominant-baseline instead to get the same effect.
D3 - add shadow ONLY at the top of bubble chart
I am using D3.js to draw bubble graph. I want to add shadow effect at the top of SVG circle. But when I use filter to add shadow then shadow is added to all the sides. How can I just have it at the top like: Expected: Current: Here is the html file code: <html><head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta charset="utf-8"> <style> .inner-point{ width: 20px; height: 10px; background: white; } .header{ //margin-top:100px; } #left,#right{ border:2px solid #78A9A9; } #right{ border-left: none; } .head-top{ color:#78A9A9; } .right{ text-align: center; margin-right: -17px; width: 460px; } .text-center{ text-align: center; padding-right: 0px; padding-left: 0px; } .link{ position: relative; margin: 396px; bottom: 0px; color:#A37512; } .left-circle,.right-circle{ padding-left: 0px; padding-right: 0px; } </style> </head> <body cz-shortcut-listen="true"> <div class="header"> <div class="left-circle col-sm-5"> <svg id="left" width="458" height="500"> <defs> <linearGradient id="gradient1" x1="65%" y1="100%" x2="54%" y2="44%" spreadMethod="pad"> <stop offset="0%" stop-color="#0365C0" stop-opacity="1"></stop> <stop offset="100%" stop-color="#51A7F9" stop-opacity="1"></stop> </linearGradient> </defs> <defs> <linearGradient id="gradient2" x1="65%" y1="100%" x2="54%" y2="44%" spreadMethod="pad"> <stop offset="0%" stop-color="#773F9B" stop-opacity="1"></stop> <stop offset="100%" stop-color="#885CB2" stop-opacity="1"></stop> </linearGradient> </defs> <defs> <filter id="drop-shadow" height="130%"> <feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"></feGaussianBlur> <feOffset in="blur" dx="0" dy="0" result="offsetBlur"></feOffset> <feMerge><feMergeNode in="offsetBlur"></feMergeNode> <feMergeNode in="SourceGraphic"></feMergeNode> </feMerge></filter> </defs> <g class="node" transform="translate(197.1414719461316,229)"> <circle class="shadowed" id="Provider25S1511" r="131.42764796408775" onclick="demo('Provider25S151','Amount of Spend $49979.62',1,262.14147194613156,327);" stroke="#0365C0" stroke-width="1" style="filter: url("#drop-shadow"); fill: url("#gradient1");"></circle> <clipPath id="clip-Provider25S151"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#Provider25S151"> </use></clipPath> </g> </svg> </div> </div> </body></html>
In the <feOffset> element in the filter, make the dy value negative by a little to move the shadow up a bit. Negative values move it up, positive values move it down. So change <feOffset in="blur" dx="0" dy="0" result="offsetBlur"></feOffset> to (for example) <feOffset in="blur" dx="0" dy="-4" result="offsetBlur"></feOffset> <svg id="left" width="458" height="500"> <defs> <linearGradient id="gradient1" x1="65%" y1="100%" x2="54%" y2="44%" spreadMethod="pad"> <stop offset="0%" stop-color="#0365C0" stop-opacity="1"></stop> <stop offset="100%" stop-color="#51A7F9" stop-opacity="1"></stop> </linearGradient> </defs> <defs> <linearGradient id="gradient2" x1="65%" y1="100%" x2="54%" y2="44%" spreadMethod="pad"> <stop offset="0%" stop-color="#773F9B" stop-opacity="1"></stop> <stop offset="100%" stop-color="#885CB2" stop-opacity="1"></stop> </linearGradient> </defs> <defs> <filter id="drop-shadow" height="130%"> <feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"></feGaussianBlur> <feOffset in="blur" dx="0" dy="-4" result="offsetBlur"></feOffset> <feMerge><feMergeNode in="offsetBlur"></feMergeNode> <feMergeNode in="SourceGraphic"></feMergeNode> </feMerge></filter> </defs> <g class="node" transform="translate(197.1414719461316,229)"> <circle class="shadowed" id="Provider25S1511" r="131.42764796408775" onclick="demo('Provider25S151','Amount of Spend $49979.62',1,262.14147194613156,327);" stroke="#0365C0" stroke-width="1" style="filter: url("#drop-shadow"); fill: url("#gradient1");"></circle> <clipPath id="clip-Provider25S151"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#Provider25S151"> </use></clipPath> </g> </svg>
SVG horizontal gradient animation
I've created the fiddle <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="280.089px" height="280.089px" viewBox="0 0 280.089 280.089" enable-background="new 0 0 280.089 280.089" xml:space="preserve"> <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-229.002" y1="335.0444" x2="-47.9087" y2="335.0444" gradientTransform="matrix(1 0 0 -1 278.5 475.0889)"> <stop offset="0" style="stop-color:#4D75B1" /> <stop offset="0.1138" style="stop-color:#4C7BB0" /> <stop offset="0.2617" style="stop-color:#4A8BAD" /> <stop offset="0.4278" style="stop-color:#46A6A7" /> <stop offset="0.5117" style="stop-color:#44B6A4" /> <stop offset="0.9093" style="stop-color:#828282" /> <animate attributeName="offset" dur="20s" values="0;1;0" repeatCount="indefinite" /> <stop offset="1" style="stop-color:#77D5C0" /> </linearGradient> <polygon class="wdgreyAnim" fill="url(#largeGradient)" points="49.498,91.095 73.592,188.992 101.322,188.992 115.607,135.212 129.191,188.994 150.898,188.994 177.931,110.705 195.294,167.986 162.38,167.986 155.238,188.994 230.591,188.994 199.076,91.095 158.711,91.211 141.919,136.94 132.27,91.095 103.699,91.095 91.522,142.325 79.75,91.095 " /> <defs> <linearGradient id="largeGradient" x2="100%"> <stop offset="0%" stop-color="#4c7eaf"></stop> <stop offset="25%" stop-color="#4a8eac"></stop> <stop offset="50%" stop-color="#46a5a7"></stop> <stop offset="75%" stop-color="#53bfac"></stop> <stop offset="100%" stop-color="#828282"></stop> <animate attributeName="x2" dur="5s" from="0%" to="100%" repeatCount="indefinite" /> </linearGradient> </defs> the animation is moving vertically but i want it be moved horizontally. I am not able to do this . someone please help me out My confusion is the gradient is like vertical. how can i set the stop tag with the offset for the different colors and animation. and also in animate tag. if i use freeze instead of repeatcount attribute that will take full single color but i want it to filled with the gradient i.e how it animates. Better if the animation come like the waves from the bottom to top.(liquid filling effect) JSfiddle Added the svg code for the final image i needed after the animation <?xml version="1.0" encoding="utf-8"?> js fiddle updated the animation movement to be from bottom to top and gradient color should be from left to right .and also i need that to be animated like the water waves
You mean like this? I've just used y2 instead of x2 <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="280.089px" height="280.089px" viewBox="0 0 280.089 280.089" enable-background="new 0 0 280.089 280.089" xml:space="preserve"> <polygon class="wdgreyAnim" fill="url(#largeGradient)" points="49.498,91.095 73.592,188.992 101.322,188.992 115.607,135.212 129.191,188.994 150.898,188.994 177.931,110.705 195.294,167.986 162.38,167.986 155.238,188.994 230.591,188.994 199.076,91.095 158.711,91.211 141.919,136.94 132.27,91.095 103.699,91.095 91.522,142.325 79.75,91.095 " /> <defs> <linearGradient id="largeGradient" x2="0" y2="100%"> <stop offset="0%" stop-color="#4c7eaf"></stop> <stop offset="25%" stop-color="#4a8eac"></stop> <stop offset="50%" stop-color="#46a5a7"></stop> <stop offset="75%" stop-color="#53bfac"></stop> <stop offset="100%" stop-color="#828282"></stop> <animate attributeName="y2" dur="5s" from="0%" to="100%" repeatCount="indefinite" /> </linearGradient> </defs> </svg>
Svg gradient animation
` <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="280.089px" height="280.089px" viewBox="0 0 280.089 280.089" enable-background="new 0 0 280.089 280.089" xml:space="preserve"> <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-229.002" y1="335.0444" x2="-47.9087" y2="335.0444" gradientTransform="matrix(1 0 0 -1 278.5 475.0889)"> <stop offset="0" style="stop-color:#4D75B1" /> <stop offset="0.1138" style="stop-color:#4C7BB0" /> <stop offset="0.2617" style="stop-color:#4A8BAD" /> <stop offset="0.4278" style="stop-color:#46A6A7" /> <stop offset="0.5117" style="stop-color:#44B6A4" /> <stop offset="0.9093" style="stop-color:#6DCFBA" /> <animate attributeName="offset" dur="20s" values="0;1;0" repeatCount="indefinite" /> <stop offset="1" style="stop-color:#77D5C0" /> </linearGradient> <polygon display"none" fill="url(#SVGID_1_)" points="49.498,91.095 79.75,91.095 91.515,142.356 103.699,91.095 132.27,91.095 141.934,136.894 158.742,91.095 199.076,91.095 230.591,188.994 155.238,188.994 162.38,167.986 195.294,167.986 177.931,110.704 150.898,188.994 129.191,188.994 115.607,135.212 101.322,188.992 73.592,188.992 " /> <polygon class="wdgreyAnim" fill="#828282" points="49.498,91.095 73.592,188.992 101.322,188.992 115.607,135.212 129.191,188.994 150.898,188.994 177.931,110.705 195.294,167.986 162.38,167.986 155.238,188.994 230.591,188.994 199.076,91.095 158.711,91.211 141.919,136.94 132.27,91.095 103.699,91.095 91.522,142.325 79.75,91.095 " /> </svg>` I have code like this through svg one polygon is grey and another one is colored. I need the effect like the colored gradient color should be animated so that it should feel like the water filling (waves) on the grey color logo. for the colored polygon i given attribute display none. Jsfiddle