Multiple lines of curved text in SVG - google-chrome

Is there a way in SVG of drawing multiple lines of text within a single <text> element that follow the same path contour? Here is the closest I have been able to get:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<path id="text_0_path" d="M 100 150 A 100 100 0 1 1 300 150"/>
</defs>
<use xlink:href="#text_0_path" stroke="blue" fill="none"/>
<text font-family="Arial" font-size="18px" text-anchor="middle">
<textPath xlink:href="#text_0_path" startOffset="50%">
<!-- 157.075 is the center of the length of an arc of radius 100 -->
<tspan x="157.075">Here is a line</tspan>
<tspan x="157.075" dy="20">Here is a line</tspan>
<tspan x="157.075" dy="20">Here is a line</tspan>
</textPath>
</text>
</svg>
Here is the output (in Chrome):
This is almost what I want. The problems:
I would like each line of text centered at the top of the arc, not to start the text there. It seems like the text-anchor attribute is being forgotten when the x value is specified in a tspan along a path. (This is not the case with straight text; the text-anchor attribute is remembered.)
Each successive line of text is crunched, as if following a concentric path. I would like each line of text to follow the same contour, as if the path were simply translated in the y direction by the height of the font.
I know I could just create three separate <path> elements and associate them with three separate <text> (or <textPath>) elements, but it would be really nice to keep all the text logically together using <tspan> elements for later applications.
Or is this supposed to work but there is a rendering bug in Chrome? (unlikely, IMO)

I can't tell if you want the text rendered on concentric circles or if you simply want it translated. If the former, then you may want to experiment with letter-spaccing attributes on your t-span elements. This will add tracking to your characters pushing them further apart. I tried the following, but alignment between lines is lost for some reason:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<path id="text_0_path" d="M 100 150 A 100 100 0 1 1 300 150"/>
</defs>
<use xlink:href="#text_0_path" stroke="blue" fill="none"/>
<text font-family="Arial" font-size="18px" text-anchor="middle">
<textPath xlink:href="#text_0_path" startOffset="50%">
<!-- 157.075 is the center of the length of an arc of radius 100 -->
<tspan x="157.075">Here is a line</tspan>
<tspan x="157.075" dy="20" letter-spacing="2">Here is a line</tspan>
<tspan x="157.075" dy="20" letter-spacing="4">Here is a line</tspan>
</textPath>
</text>
</svg>
However, if you want the latter (concentric circles), this appears to work in Safari and Chrome on the Mac:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<path id="text_0_path" d="M 100 150 A 100 100 0 1 1 300 150"/>
</defs>
<use xlink:href="#text_0_path" stroke="blue" fill="none"/>
<g font-family="Arial" font-size="18px">
<text text-anchor="middle">
<textPath xlink:href="#text_0_path" startOffset="50%">Here is a line</textPath>
</text>
<text text-anchor="middle" transform="translate(0, 20)">
<textPath xlink:href="#text_0_path" startOffset="50%">Here is a line</textPath>
</text>
<text text-anchor="middle" transform="translate(0, 40)">
<textPath xlink:href="#text_0_path" startOffset="50%">Here is a line</textPath>
</text>
</g>
</svg>
I know you were shooting for tspans only, but as you said, it seemed to reset the startOffset values.
HTH,
Kevin

Related

Very simple SVG is different between Firefox and Chrome

I have a very simple SVG which gets rendered differently between Firefox and Chrome and I have no idea why. Any suggestions? I would not want to use any CSS to specially style things to get them in sync but have a simple stand-alone SVG.
<?xml version="1.0" encoding="utf-8" ?>
<svg baseProfile="tiny" height="400.0" version="1.2" width="400.0" xmlns="http://www.w3.org/2000/svg">
<rect fill="#fff" fill-opacity="0" stroke="#000" height="90.0" rx="5.0" ry="5.0" stroke-width="3" width="350.0" x="0" y="0"/>
<text font-size="18.0" stroke="#000" text-anchor="start" x="5.0" y="51.0">func: foo_bar_longer</text>
<text font-size="18.0" stroke="#000" text-anchor="end" x="345.0" y="51.0">class: bar_foo_longer</text>
</svg>
Firefox 67 on Linux:
Chromium 75.0.3770.90:
It seems setting font_family="Arial,Helvetica,sans-serif" on all text elements solved the problem. Browsers do not have the same default font.

How can I update several text values inside an SVG Group?

I have an SVG element that is composed of a shape and text. This element is replicated several times inside the SVG file and I wanted to take advantage of the symbol and use tags.
But I need to be able to pass values to update the text nodes inside the symbol as each symbol will have it's own value.
Is there a way to do this without Javascript?
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 800 800">
<defs>
<g id="Initials">
<circle id="bgColor" cx="200" cy="200" r="80" class="cls-9"/>
<text id="label" fill="white" font-size="50" transform="translate(170, 220)">
10
</text>
</g>
</defs>
<use href="#Initials" />
<use href="#Initials" x="200" y="0" />
</svg>

local svg image not found when web page loaded

I have been trying to add an svg image to my django website for awhile now. However, I keep getting this error:
GET http://localhost:8000/images/enter.svg 404 (Not Found)
This is what I wrote
<img src='/images/enter.svg'>
and my folder structure is as such
index.html
- images
-- enter.svg
I've been googling around but I can't find a solution. I hear people copying and pasting the 'data' of the svg instead, but I haven't been able to find an example. Just in case it's actually useful, here's the data of the svg image I'm trying to attach to my page:
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>
<svg fill-opacity="1" xmlns:xlink="http://www.w3.org/1999/xlink" color-rendering="auto" color-interpolation="auto" text-rendering="auto" stroke="black" stroke-linecap="square" stroke-miterlimit="10" shape-rendering="auto" stroke-opacity="1" fill="black" stroke-dasharray="none" font-weight="normal" stroke-width="1" xmlns="http://www.w3.org/2000/svg" font-family="&apos;Dialog&apos;" font-style="normal" stroke-linejoin="miter" font-size="12" stroke-dashoffset="0" image-rendering="auto">
<!--Unicode Character 'DOWNWARDS ARROW WITH CORNER LEFTWARDS' (U+21B5)-->
<defs id="genericDefs" />
<g>
<g>
<path d="M159.3281 330.8906 L76.6406 330.8906 Q92.5312 348.75 99.4219 368.8594 L89.2969 368.8594 Q69.6094 340.1719 34.5938 327.375 L34.5938 320.4844 Q69.6094 307.6875 89.2969 279 L99.4219 279 Q92.5312 299.25 76.6406 317.1094 L145.4062 317.1094 L145.4062 215.7188 L159.3281 215.7188 L159.3281 330.8906 Z" stroke="none" />
</g>
</g>
</svg>
Hi your svg code didnt seem to work so i think if you put this piece of code in wherever you want you svg placed it should work:
<svg width="124.73px" height="153.14px" viewBox="0 0 124.73 153.14">
<g>
<g>
<path d="M124.73,115.17H42.05c10.59,11.91,18.19,24.56,22.78,37.97H54.7C41.58,134.02,23.34,120.19,0,111.66v-6.89
c23.34-8.53,41.58-22.36,54.7-41.48h10.12c-4.59,13.5-12.19,26.2-22.78,38.11h68.77V0h13.92V115.17z"/>
</g>
</g>
</svg>
It ofcourse can be turned into an svg file and then linked into your code as you were trying. But you could also just put the code above into your code. example:
<html>
<body>
<h1> some content or whatever </h1>
<svg width="124.73px" height="153.14px" viewBox="0 0 124.73 153.14">
<g>
<g>
<path d="M124.73,115.17H42.05c10.59,11.91,18.19,24.56,22.78,37.97H54.7C41.58,134.02,23.34,120.19,0,111.66v-6.89
c23.34-8.53,41.58-22.36,54.7-41.48h10.12c-4.59,13.5-12.19,26.2-22.78,38.11h68.77V0h13.92V115.17z"/>
</g>
</g>
</svg>
</body>
</html>
like this it should show up on your page without having the linking problem. You can style your svg like this aswell now by giving your path an id.
https://css-tricks.com/lodge/svg/ there are plenty tutorials on this page that helped me a lot with svg.
Hope this works!

Starting a SVG animation with keyframes using "begin" property

I'm actually learning SVG in order to import a vector animation I did in Flash inside a website, then integrate some "interactivity" (with the SVG property begin="mouseover").
So first, here is a very simple example of SVG animation I made with the help of the Flash plugin called "Flash2SVG" : https://codepen.io/Rojiraan/pen/owboXr
(StackOverflow want some code when using a Codepen.io link, the problem is that my SVG is way too long, so I did an ultra conversion of my HTML code)
<div class="svg-container">
<svg version="1.1" class="svg-content" viewBox="0 0 550 400" preserveAspectRatio="xMinYMin meet">
<g id="SEQUENCE_No1" overflow="visible">
<g id="THE_RED_RECTANGLE" transform="translate(71 68.05)">
<g>
<g id="Layer11_0_FILL">
<path fill="#F30" stroke="none" d="M408 263.95L408 0 0 0 0 263.95 408 263.95Z"/>
</g>
</g>
</g>
<g display="none">
<g>
<g id="Layer10_0_FILL">
<path fill="#6CF" stroke="none" d="some numbers..."/>
</g>
</g>
<animate attributeName="display" repeatCount="indefinite" dur="3.333s" keyTimes="0;.9;1" values="none;inline;inline"/>
</g>
<g display="none">
<g>
<g id="Layer9_0_FILL">
<path fill="#6CF" stroke="none" d="some numbers..."/>
</g>
</g>
<animate attributeName="display" repeatCount="indefinite" dur="3.333s" keyTimes="0;.8;.9;1" values="none;inline;none;none"/>
</g>
<!-- Et cetera... -->
</svg>
</div>
What I want to do is to start the animation (with the little blue points) when I'm hovering the red rectangle. The thing is I don't really know where to put my "begin" property, I tried various thing without success.
Thanks a lot for reading & for the help !

SVG "use" doesn't show

I have and SVG icon I need to use in a several toolbars on a page.
If I add the SVG code to the location in the toolbar, it works. However, since I need to use it many times I'm trying to define it one at the bottom of the page and then with "use" having it displayed in several places.
So I define it:
<svg>
<defs>
<g id="svgHelp" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none">
<path d="M1 12c0-6.075 4.925-11 11-11s11 4.925 11 11-4.925 11-11 11-11-4.925-11-11z"/>
<path d="M11.792 14v-1c1.609 0 3-1.391 3-3s-1.391-3-3-3c-1.194 0-2.342.893-2.792 1.921"/>
<path d="M12 17v1"/>
</g>
</defs>
</svg>
And then try to use it:
<use xlink:href="#svgHelp" x="0" y="0" />
But it does not display. What am I missing here?
I believe <use> must be wrapped by <svg>
<svg>
<use xlink:href="#svgHelp" x="0" y="0" />
</svg>