d3.js label inside path deformed - d3.js

i added a label inside a path successfully but when i try to center this label by changing manually x and dy attributes. the label deforms in the center.
here is some picture and its corresponding code.
before changing the x attributes its value 135:
<svg width="1306" height="628">
<g>
<path name="cf40" d="M590.3383838385344,295.20151514932513L756.3916666656733,317.13308080658317L878.5818181820214,279.5361111164093L822.186363636516,527.0494949556887L728.1939393933862,555.2472222223878Z" id="polygon2" style="fill: steelblue;"></path>
</g>
<text x="135" dy="105"><textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#polygon2">CF40</textPath></text>
</svg>
after changing the x attributes new value is 145:
<svg width="1306" height="628">
<g>
<path name="cf40" d="M590.3383838385344,295.20151514932513L756.3916666656733,317.13308080658317L878.5818181820214,279.5361111164093L822.186363636516,527.0494949556887L728.1939393933862,555.2472222223878Z" id="polygon2" style="fill: steelblue;"></path>
</g>
<text x="145" dy="105"><textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#polygon2">CF40</textPath></text>
</svg>

There is nothing "deformed" here. That's the expected behaviour: you're using a textPath to position the text, and the path you're referencing changes orientation at the first L command.
You can clearly see that there is nothing wrong when we draw some (red) lines, showing this "bend":
<svg width="400" height="300">
<g>
<path name="cf40" d="M590.3383838385344,295.20151514932513L756.3916666656733,317.13308080658317L878.5818181820214,279.5361111164093L822.186363636516,527.0494949556887L728.1939393933862,555.2472222223878Z" id="polygon2" style="fill: steelblue;" transform="translate(-500,-260)"></path>
</g>
<text x="145" dy="105"><textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#polygon2">CF40</textPath></text>
<line x1="756.3916666656733" y1="317.133080" x2="728.1939393933862"
y2="555.2472222223878" stroke="red" transform="translate(-500,-260)"
></line>
<line x1="756.3916666656733" y1="317.133080" x2="822.186363636516"
y2="527.049" stroke="red" transform="translate(-500,-260)"
></line>
</svg>
And you can see that even better if we create several texts, increasing the dy up to your value (105):
<svg width="400" height="300">
<g>
<path name="cf40" d="M590.3383838385344,295.20151514932513L756.3916666656733,317.13308080658317L878.5818181820214,279.5361111164093L822.186363636516,527.0494949556887L728.1939393933862,555.2472222223878Z" id="polygon2" style="fill: steelblue;" transform="translate(-500,-260)"></path>
</g>
<text x="145" dy="15"><textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#polygon2">CF40</textPath></text>
<text x="145" dy="40"><textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#polygon2">CF40</textPath></text>
<text x="145" dy="60"><textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#polygon2">CF40</textPath></text>
<text x="145" dy="80"><textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#polygon2">CF40</textPath></text>
<text x="145" dy="105"><textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#polygon2">CF40</textPath></text>
<line x1="756.3916666656733" y1="317.133080" x2="728.1939393933862"
y2="555.2472222223878" stroke="red" transform="translate(-500,-260)"
></line>
<line x1="756.3916666656733" y1="317.133080" x2="822.186363636516"
y2="527.049" stroke="red" transform="translate(-500,-260)"
></line>
</svg>
Possible solution: alternatively, you can draw a curve. That way, the text will follow the path without breaks:
<svg width="400" height="300">
<g>
<path name="cf40" d="M590.3383838385344,295.20151514932513 C 756 327,756 327, 878.5818181820214,279.5361111164093L822.186363636516,527.0494949556887L728.1939393933862,555.2472222223878Z" id="polygon2" style="fill: steelblue;" transform="translate(-500,-260)"></path>
</g>
<text x="145" dy="105"><textPath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#polygon2">CF40</textPath></text>
</svg>

Related

SVG image does not show up in browsers

I have this SVG image, made in Inkscape which shows the following in Inkscape:
However, when I open the SVG in a browser (Chrome, Firefox), nothing appears. I have tried adding "simple" lines and objects to the image, and they DO appear, so it seems to be something with this specific object. What could it be? And how to fix it?
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="65.834572mm"
height="70.733879mm"
viewBox="0 0 65.834572 70.733879"
version="1.1"
id="svg13961"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)"
sodipodi:docname="test.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview13963"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.63874158"
inkscape:cx="161.25457"
inkscape:cy="270.06227"
inkscape:window-width="529"
inkscape:window-height="862"
inkscape:window-x="534"
inkscape:window-y="18"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs13958">
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath16097">
<g
id="g16109">
<g
id="g16107"
transform="translate(162.0894,-8.96869)">
<g
id="g16105">
<g
id="g16103">
<g
id="g16101">
<path
d="M 0,595.2 H 841.7 V 0 H 0 Z"
id="path16099" />
</g>
</g>
</g>
</g>
</g>
</clipPath>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-61.940456,-78.545196)">
<path
d="m 384.899,184.03111 c 40.89063,-0.26977 82.65532,5.96811 119.21947,25.15083 23.45592,12.13347 47.3093,25.37475 74.13169,27.82215 6.70195,0.79044 13.4529,1.13004 20.19984,1.13002"
style="display:inline;opacity:1;fill:none;stroke:#000000;stroke-width:127.501;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path60"
clip-path="url(#clipPath16097)"
transform="matrix(0.00761114,0.32814968,0.35268292,-0.00818017,16.590019,-45.732392)" />
</g>
</svg>

SVG text animate font styles

I want to make an animation that looks like a google search box
I have a text path where the word appears in a 'bold' font.
I would like the word to animate so that the first letter appears 'regular', then the first and second, then the first second and third etc.
Is this possible to do with an svg animation?
<svg width="100%" height="100%" viewBox="30 -50 600 500" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<path id="path1">
<animate attributeName="d" from="m100,50 h0" to="m100,50 h1100" dur="5s" begin="0s" repeatCount="indefinite" />
</path>
// this text "types"
<text font-size="90" font-family="Montserrat" fill='black'>
<textPath xlink:href="#path1">Google is</textPath>
</text>
// I want this text to animate the "font-style"
<text font-size="90" font-family="Montserrat" fill='black' x="100" y="200">
Google is gold
<animate attributeType="CSS" .... />
</text>
You'd need to put the letters in separate tags within the textPath so you can target them individually with animations.
I've just done the first letter but you could extend this to all the letters if you wished.
<svg width="100%" height="100%" viewBox="30 -50 600 500" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<path id="path1">
<animate attributeName="d" from="m100,50 h0" to="m100,50 h1100" dur="5s" begin="0s" repeatCount="indefinite" />
</path>
// this text "types"
<text font-size="90" font-family="Montserrat" fill='black'>
<textPath xlink:href="#path1">Google is</textPath>
</text>
// I want this text to animate the "font-style"
<text font-size="90" font-family="Montserrat" fill='black' x="100" y="200">
<tspan>G<animate attributeType="CSS" attributeName="font-weight" from="700" to="100" dur="1s" begin="0s" repeatCount="indefinite"/></tspan>oogle is gold
</text>

using d3.js, how to append <textpath> to some already existing <paths> of svg?

Initial html is as follows
<svg>
<g id="groupOfPaths">
<path id="foo_1" d="M 80,40 Q 200,85 245,205" stroke="red" stroke-width="2"/>
<path id="foo_2" d="M 150,40 Q 200,85 245,205" stroke="red" stroke-width="2" />
</g></svg>
using d3 how can i append textpath to all the existing path tags such that output is as follows
<svg>
<g id="groupOfPaths">
<path id="foo_1" d="M 80,40 Q 200,85 245,205" stroke="red" stroke-width="2"/>
<path id="foo_2" d="M 150,40 Q 200,85 245,205" stroke="red" stroke-width="2" />
<!--extra added tags-->
<text fill="red">
<textPath xlink:href="foo_1">1 path text follow</textPath>
</text>
<text fill="red">
<textPath xlink:href="foo_2">101 path text follow</textPath>
</text>
</g></svg>
Edited the question to incorportate Id for each path

SVG animation scaling while keeping the group from moving on one end

I am trying to use svg animation to get a dragonfly to flap its wings.
I am doing this by scaling the left and right wing on the x axis. the problem is when I scale it the wing moves. I want the left or right edge of the wing to stay in one spot when it scales.
here is the code for one wing
<g id="wing_left">
<g>
<path fill="#88C9CE" d="M254.8,132.1c-66.2,6.7-130.7,21.1-193.3,47.2c-7.4,3.1-58.6,24.1-44.8,37.4
c15.2,14.8,88.3,17.3,109.3,11.3C162.6,217.8,279.4,129.7,254.8,132.1z"/>
<path fill="#92D9DE" d="M237.3,113.7c-16.1,3.6-245.9-31.8-250-22.3c-11.5,26.7,38.3,51.9,56.1,58.2
c88.5,31.4,185.6,6.2,202.5-11.3C251.7,132.4,247.9,111.3,237.3,113.7z"/>
<path fill="#FFFFFF" d="M-1.2,97.7c9.1-4.5,84.8,7.2,83.7,7.1c-16.4-1.7-49.9-3.3-56.9-3.5c-32.2-1.2-24,7.4-22.5,11.8
C5,118.4-7.2,100.6-1.2,97.7z"/>
<path fill="#76B0B3" d="M249.3,145.5c-2.9,3-8,7.3-11.5,10.2c-21.1,17.5-102.1,8.9-102.1,8.9s54.5-2.2,86-13.4
c13.2-4.7,21-10.2,23.2-12c0,0,1.1,1.4,2.1,2.5c1,1.1,2.3,1.8,2.3,1.8S249.3,145.5,249.3,145.5z"/>
</g>
<animateTransform id="wlFlapDown" attributeName="transform"
type="scale"
from="1 1" to="0.5 1"
begin="0s;wlFlapUp.end" dur="160ms"
repeatCount="indefinite"
fill="freeze"
/>
<animateTransform id="wlFlapUp" attributeName="transform"
type="scale"
from="0.5 1" to="1 1"
begin="wlFlapDown.end" dur="160ms"
repeatCount="indefinite"
fill="freeze"
/>
</g>
Here is the whole svg code or you can see it in codepen
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="-14.4 7.7 550.5 426.8" enable-background="new -14.4 7.7 550.5 426.8" xml:space="preserve">
<g id="wing_left">
<g>
<path fill="#88C9CE" d="M254.8,132.1c-66.2,6.7-130.7,21.1-193.3,47.2c-7.4,3.1-58.6,24.1-44.8,37.4
c15.2,14.8,88.3,17.3,109.3,11.3C162.6,217.8,279.4,129.7,254.8,132.1z"/>
<path fill="#92D9DE" d="M237.3,113.7c-16.1,3.6-245.9-31.8-250-22.3c-11.5,26.7,38.3,51.9,56.1,58.2
c88.5,31.4,185.6,6.2,202.5-11.3C251.7,132.4,247.9,111.3,237.3,113.7z"/>
<path fill="#FFFFFF" d="M-1.2,97.7c9.1-4.5,84.8,7.2,83.7,7.1c-16.4-1.7-49.9-3.3-56.9-3.5c-32.2-1.2-24,7.4-22.5,11.8
C5,118.4-7.2,100.6-1.2,97.7z"/>
<path fill="#76B0B3" d="M249.3,145.5c-2.9,3-8,7.3-11.5,10.2c-21.1,17.5-102.1,8.9-102.1,8.9s54.5-2.2,86-13.4
c13.2-4.7,21-10.2,23.2-12c0,0,1.1,1.4,2.1,2.5c1,1.1,2.3,1.8,2.3,1.8S249.3,145.5,249.3,145.5z"/>
</g>
<animateTransform id="wlFlapDown" attributeName="transform"
type="scale"
from="1 1" to="0.5 1"
begin="0s;wlFlapUp.end" dur="160ms"
repeatCount="indefinite"
fill="freeze"
/>
<animateTransform id="wlFlapUp" attributeName="transform"
type="scale"
from="0.5 1" to="1 1"
begin="wlFlapDown.end" dur="160ms"
repeatCount="indefinite"
fill="freeze"
/>
</g>
<g id="wing_right">
<g>
<path fill="#88C9CE" d="M275.9,134c66.4,4.7,131.2,17.1,194.6,41.4c7.5,2.9,59.3,22.3,45.9,36.1c-14.8,15.2-87.7,19.9-109,14.6
C370.6,216.9,251.2,132.2,275.9,134z"/>
<path fill="#92D9DE" d="M285,113c16.2,3.1,244.8-39.1,249.2-29.7c12.3,26.3-36.8,53-54.4,59.8c-87.6,34-185.4,11.7-202.8-5.2
C271.1,132.1,274.2,110.9,285,113z"/>
<path fill="#FFFFFF" d="M451.2,98.5c25.6-4.3,28.9-4.8,58.9-8.8c1.9-0.3,16.3-1.3,15.6,4.3c-0.2,1.4-6.5,17.8-6,13.2
c0.1-0.8,0.9-9.8-1.3-12.5C513.9,88.7,445.7,99.5,451.2,98.5z"/>
<path fill="#76B0B3" d="M291.3,155.4c21.9,16.6,99.9,5.4,99.9,5.4s-54.7-0.2-86.7-9.9c-13.4-4.1-22.5-9.1-24.1-10.3
c0,0-0.8,0.9-1.8,1.6c0,0,0.1,2.2,0.1,2.2S287.6,152.7,291.3,155.4z"/>
</g>
<animateTransform id="wrFlapDown" attributeName="transform"
type="scale"
from="1 1" to="0.5 1"
begin="0s; wrFlapUp.end" dur="160ms"
repeatCount="indefinite"
fill="freeze"
/>
<animateTransform id="wrFlapDown" attributeName="transform"
type="scale"
from="0.5 1" to="1 1"
begin="wrFlapDown.end" dur="160ms"
repeatCount="indefinite"
fill="freeze"
/>
</g>
<g id="body" xmlns:inkpad="http://taptrix.com/inkpad/svg_extensions">
<g id="Layer_2" inkpad:layerName="body">
<path fill="#D9AC32" d="M253.8,83.2c-4.5-29.5-6.4-53.2-16-74.7c-0.8-1.9-4.3,1-3.4,1.6c0.4,0.2,12.6,13.5,17.3,73.2
C252.2,88.9,254.5,87.3,253.8,83.2z"/>
<path fill="#D9AC32" d="M272.2,82.6c5.2-29.3,7.8-53,17.9-74.3c0.9-1.9,4.3,1.1,3.3,1.7c-0.4,0.2-12.9,13.2-19.1,72.7
C273.7,88.2,271.5,86.6,272.2,82.6z"/>
<path fill="#FFE008" d="M249.8,128.8l28.2-0.4c0,0,10.4,208,2.7,260.4c-10.3,71.1-18.9,49.7-27.9,0.4
C243.4,337.1,249.8,128.8,249.8,128.8z"/>
<path fill="#FFE008" d="M242.5,130.2c-0.2-12,9-21.8,20.6-22c11.5-0.2,21.1,9.4,21.2,21.4c0.2,12-9.7,17-21.2,17.2
C251.5,146.9,242.7,142.2,242.5,130.2z"/>
<path fill="#FFE008" d="M236.8,110.7c-0.3-18.4,12-32.8,26.5-33c14.5-0.2,25.8,13.9,26.1,32.2c0.3,18.4-11.7,25.1-26.3,25.3
C248.6,135.4,237.1,129,236.8,110.7z"/>
</g>
<g id="Layer_3" inkpad:layerName="eyes">
<g>
<path fill="#F5F2E1" d="M227.8,95.9c-0.1-8.3,7.2-15.1,16.4-15.3c9.2-0.1,16.7,6.5,16.8,14.8c0.1,8.3-7.2,15.1-16.4,15.3
C235.4,110.9,227.9,104.2,227.8,95.9z"/>
<path d="M255.1,92c-0.6,1.6-7.3-5.5-19.7,3.7c-2.4,1.8-1.8-4.6-0.1-6C244.1,82.6,255.8,90.4,255.1,92z"/>
<path fill="#D8E6C3" d="M228,96.2c-0.1-5.4,2.1,9.9,15.5,11.1c8.1,0.7,14.5-2.9,14.2-2.5c-3.9,4.4-9,5.5-10.5,5.7
C236.8,111.8,228.2,106.5,228,96.2z"/>
</g>
<g>
<path fill="#F5F2E1" d="M295.8,94.9c-0.1-8.3-7.7-14.9-16.8-14.8c-9.2,0.1-16.5,7-16.4,15.3c0.1,8.3,7.7,14.9,16.8,14.8
C288.6,110.1,295.9,103.2,295.8,94.9z"/>
<path d="M268.3,91.8c0.7,1.6,7.1-5.7,19.8,3.1c2.5,1.7,1.7-4.7-0.1-6C279.1,82.1,267.6,90.3,268.3,91.8z"/>
<path fill="#D8E6C3" d="M295.5,95.2c-0.1-5.4-1.8,9.9-15.2,11.5c-8.1,1-14.6-2.5-14.3-2.1c4,4.3,9.2,5.2,10.7,5.4
C287.2,111,295.7,105.5,295.5,95.2z"/>
</g>
</g>
<path fill="#E5C907" d="M242.6,127.9c0-0.1,4.8,8.1,22.5,7.2c13.6-0.7,19-8.1,19-8.1c-0.4,4.9-11.3,11.2-18.3,11.6
C260.3,139,247.3,137.3,242.6,127.9z"/>
<path fill="#E5C907" d="M249.3,143.6c0,0,6,3.9,15,3.2c10.4-0.8,14.4-4.7,14.4-4.6c0.2,4.1,0.5,8.3,0.4,8.6
c-3.5,7.1-20.6,9.4-29.8,2C249,152.5,249.3,147.1,249.3,143.6z"/>
</g>
</svg>
The problem here is that the origin for all scale transforms is at (0,0) which is at the top left of the SVG. So your scale animations are centred on the left side of the SVG (x=0).
Basically you need to move the coordinate space for the wings, so that when the scale is applied, the wings are centred on x=0.
So the steps would be:
Use a translate transform to move your wings so they are centred at x=0
apply your scale animation in this coordinate space
surround that with a group with a transform that moves them back to their original position
For example:
<g id="wings" transform="translate(270,0)">
<g>
<g transform="translate(-270,0)">
<g "left wing">
<g "right wing">
</g>
<animateTransform .../>
</g>
</g>
Demo here

Why don't the circles show up?

I built some SVG with d3.js but nothing is displayed. Why? Here is part of code:
<svg width="863" height="863" id="svgId">
<g transform="translate(431.5,431.5)">
<g class="asdf" r="421.5">
<circle transform="translate(0,0)" style="fill: rgb(255, 0, 0);"></circle>
</g>
<g class="asdf" r="127.6354829132969">
<circle transform="translate(-118.50486492278469,167.13470131539657)" style="fill: rgb(255, 0, 0);"></circle>
</g>
</g>
You've set the radius (r attribute) on the <g> element where it does nothing and not on the <circle> element where it's required. What you need is this...
<svg width="863" height="863" id="svgId">
<g transform="translate(431.5,431.5)">
<g class="asdf">
<circle r="421.5" transform="translate(0,0)" style="fill: rgb(255, 0, 0);"></circle>
</g>
<g class="asdf">
<circle r="127.6354829132969" transform="translate(-118.50486492278469,167.13470131539657)" style="fill: rgb(255, 0, 0);"></circle>
</g>
</g>
</svg>

Resources