By default, SVG wraps text around a path in an anti-clockwise manner. The ceiling of the text sticks the path. How to change the direction to clockwise so that the floor of the text sticks to the circumference instead of the ceiling?
.textspace
{
letter-spacing: 5px;
font-family: fantasy;
font-size: 50px;
writing-mode: tb;
}
.curved-text
{
font-family: fantasy;
font-size: 20px;
letter-spacing: 5px;
word-spacing: 10px;
}
<svg height="400" width="400">
<defs>
<path d="M60,60
A50,50
0
1,0
61,60"
stroke="black"
stroke-width="2"
fill="none"
id="tracker-path"/>
</defs>
<text x="50" y="50" class="curved-text">
<textPath xlink:href="#tracker-path">
Tracking succesful.
</textPath>
</text>
</svg>
I managed to solve this. All you need to do is set the value of sweep-flag from 0 to 1. That will flip the direction of path
.textspace
{
letter-spacing: 5px;
font-family: fantasy;
font-size: 50px;
writing-mode: tb;
}
.curved-text
{
font-family: fantasy;
font-size: 20px;
letter-spacing: 5px;
word-spacing: 10px;
}
<svg height="400" width="400">
<defs>
<path d="M80,160
A50,50
0
1,1
81,160"
stroke="black"
stroke-width="2"
fill="none"
id="tracker-path"/>
</defs>
<text x="50" y="50" class="curved-text">
<textPath xlink:href="#tracker-path">
Tracking succesful.
</textPath>
</text>
</svg>
Related
I'm tring to have an effect on a picture in my website, the effect is "Image revealing from text on hover
" from this website.
I made a CSS file with this code:
body, html {
height: 100%;
margin: 0;
padding: 0;
background: #E3DFD2
}
effecrforthelogo {
background: url('http://www.uploads.co.il/uploads/images/607163485.png');
background-size: cover;
width: 40vmin;
height: auto;
display: block;
margin: 30vmin auto;
}
text {
font-size: 10px;
transition: font-size .4s ease-out;
font-weight: 900;
font-family: arial;
}
effectforthelogo:hover text {
transition: font-size .4s ease-in;
font-size: 300px;
}
and in my aspx file of the page in my wesite I wrote this HTML code:
<efectforthelogo viewbox="0 0 50 50" width="50" height="50">
<defs>
<mask id="mask" x="0" y="0" width="100" height="49">
<rect x="0.5" y="0.5" width="49" height="49" fill="#fff"/>
<text x="20" text-anchor="middle" y="50" dy="0">S</text>
<text x="25" id="ltrV" text-anchor="middle" y="50" dy="0">V</text>
<text x="30" text-anchor="middle" y="50" dy="0">G</text>
</mask>
</defs>
<rect x="0.5" y="0.5" width="49" height="49" mask="url(#mask)" fill-opacity="1" fill="#E3DFD2"/>
</efectforthelogo>
All it shows is "SVG" on the top of the page, without the picture/the effect.
Please help!
I wanted to see the picture woth the effect, but it only showd the text.
I'm creating a small stacked bar graph, with 3 bar items (rendered with a coloured <rect> item). This is all done in a React component (I build these up depending on some of the inputs I get). The render function for the component looks something like this:
<React.Fragment>
<g key={this.props.id}>
<rect
width={`${
this.props.value === 0 ? 2 : this.calculatePercentage(this.props.value)
}%`}
height={`15px`}
x={`${this.getPosition()}%`}
style={{ fill: this.props.color }}
className={Styles.bar}
/>
<text
y={25}
x={`${this.getPosition()}%`}
transform={`translate(${this.getTextPosition()}, 0)`}
>
<a
onClick={this.onClick}
className={
this.props.value === 0
? Styles.noResults
: this.props.isSelected
? Styles.selectedText
: Styles.filterText
}
>
{this.props.label}
</a>
</text>
</g>
<text
id={"percentage"}
className={Styles.barText}
x={`${this.getPosition() + 1}%`}
y={11}
transform={`translate(${0}, 0)`}
>
{this.calculatePercentage(this.props.value)}%
</text>
<use xlinkHref="#percentage" />
</React.Fragment>
Ultimately, for a result-set I have, the output from this component looks like this:
.container {
display: flex;
flex-direction: column;
}
.bar {
overflow: visible;
}
.barText {
fill: #000;
color: #000;
font-size: 10px;
overflow: visible;
}
.noResults {
fill: #bcbcbc;
font-size: 10px;
}
.noResults:hover {
cursor: default;
}
.selectedText {
fill: #0078d7;
font-size: 10px;
text-decoration: underline !important;
text-decoration-color: #0078d7;
text-decoration-thickness: 1px;
font-weight: bold;
}
.filterText {
fill: #0078d7;
font-size: 10px;
text-decoration: none;
}
.filterText:hover {
cursor: pointer;
text-decoration: underline !important;
text-decoration-color: #0078d7;
text-decoration-thickness: 1px;
}
<svg xmlns="http://www.w3.org/2000/svg" class="container">
<g>
<rect class="bar" style="fill: #2a7c4f;" x="0%" width="2%" height="15px" />
<text transform="translate(0)" x="0%" y="25"><a class="noResults">Complete: 0</a></text>
</g>
<text id="percentage" class="barText" transform="translate(0)" x="1%" y="11">0%</text>
<g>
<rect class="bar" style="fill: #fec42e;" x="2%" width="2%" height="15px" />
<text transform="translate(53.91)" x="2%" y="25"><a class="noResults">Draft: 0</a></text>
</g>
<text id="percentage" class="barText" transform="translate(0)" x="7%" y="11">48%</text>
<g>
<rect class="bar" style="fill: #D3D3D3;" x="4%" width="100%" height="15px" />
<text transform="translate(253.91)" x="2%" y="25"><a class="noResults">Empty: 0</a></text>
</g>
<text id="percentage" class="barText" transform="translate(0)" x="91%" y="11">50%</text>
<use xlink:href="#percentage"/>
</svg>
Now as you can see, the second 0% isn't visible, what I want is for all the % value fields to be visible on top of the bar itself. Is there any way to go about this? It obviously works if the particular section of the bar has a larger width, but I want it to work regardless of the width of the rect.
I have an issue with font size on SVG as us can see in svg the font-size:16px different from paragraph font-size but the they have the same value 16px. I would like to have font size in svg such on paragraph.
The second issue, it's how to center <tspan text-anchor="middle" class="tc-label-value">85</tspan> when I delete <tspan class="label-text" text-anchor="middle" x="0" y="50" dy="15">Text in SVG</tspan>
I mean the is a case when I have Text in svg and have not
https://codepen.io/palaniichukdmytro/pen/BaaKbze
SVG text, & span font-size and center solution
body {
margin: 0;
}
.wr {
width: 180px;
margin: 0 auto;
}
.label-text {
font-size: 12px;
text-align: center;
}
.tc-label-value {
font-size: 12px;
text-align: center;
}
.par {
font-size: 16px;
text-align: center;
}
<div class='wr'>
<svg viewBox="0 0 100 100" width="100%" height="100%" style="display: block;">
<path d="M 95.5 50 A 45.5 45.5 0 1 1 11.315120324302569 26.047336589080288" stroke-width="9" stroke-dasharray="168.16760675098308" stroke-dashoffset="2.842170943040401e-14" stroke="#a3bfff" stroke-linecap="round" fill="none" style="transition: stroke-dashoffset 500ms ease-out 0s;"></path>
<path d="M 11.315120324302569 26.047336589080288 A 45.5 45.5 0 0 1 95.5 49.999999999999986" stroke-width="9" stroke-dasharray="117.71732472568812" stroke-dashoffset="0" stroke="#66bb6a" stroke-linecap="round" fill="none" style="transition: stroke-dashoffset 500ms ease-out 0s;"></path>
<text transform="translate(50)" x="0" y="50">
<tspan text-anchor="middle" class="tc-label-value">85</tspan>
<tspan class="label-text" text-anchor="middle" x="0" y="50" dy="15">Text in SVG</tspan>
</text>
</svg>
<p class='par'>Text Paragraph</p>
</div>
The font size for the svg element should be 8.88px. Why? Because the svg's width is 100 units or px ( viewBox="0 0 100 100" ) and is scaled up to 180px ( .wr{width: 180px;} ). Since you need the font size inside the svg to look like 16px, the real font size should be 16 * 100 / 180 = 8.88
.wr {
width: 180px;
}
.par{
font-size: 16px;
}
svg{font-size: 8.88px;}
<div class='wr'>
<svg viewBox="0 0 100 100" style="display: block;">
<path d="M 95.5 50 A 45.5 45.5 0 1 1 11.315120324302569 26.047336589080288" stroke-width="9" stroke-dasharray="168.16760675098308" stroke-dashoffset="2.842170943040401e-14" stroke="#a3bfff" stroke-linecap="round" fill="none" style="transition: stroke-dashoffset 500ms ease-out 0s;"></path>
<path d="M 11.315120324302569 26.047336589080288 A 45.5 45.5 0 0 1 95.5 49.999999999999986" stroke-width="9" stroke-dasharray="117.71732472568812" stroke-dashoffset="0" stroke="#66bb6a" stroke-linecap="round" fill="none" style="transition: stroke-dashoffset 500ms ease-out 0s;"></path>
<text transform="translate(50)" x="0" y="50">
<tspan text-anchor="middle" class="tc-label-value">85</tspan>
<tspan class="label-text" text-anchor="middle" x="0" y="50" dy="15">Text in SVG</tspan>
</text>
</svg>
<p class='par'>Text Paragraph</p>
</div>
So I'm pretty new to SVG but I started playing with a graph. The graph is from here. I've been searching for hours and did only find a half solution to my problem. As you see from the code snippet, if you hover on the graph it "glows". But I want that only the circles and the "joints" would glow when I'm hovering on them.
What I tried:
Using regular CSS shadowing
Using the code that makes "glow" the graph, but only on g elements.
Creating a separate SVG both: a) in the main SVG b) separately, and
mixing them with position: absolute. (after this the positioning
worked weirdly)
What should I do to make only the circles and the joints "glow"?
*{
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body{
height: 100%;
width: 100%;
}
#import url('https://fonts.googleapis.com/css?family=Roboto+Mono:400,500&display=swap');
body {
font-family: 'Roboto Mono', monospace;
}
.graph .labels.x-labels {
text-anchor: middle;
}
.graph .labels.y-labels {
text-anchor: end;
}
.graph {
height: 500px;
width: 800px;
}
.graph .grid {
stroke: #ccc;
stroke-dasharray: 0;
stroke-width: 3;
}
.labels {
font-size: 17px;
font-weight: 400;
}
.label-title {
font-weight: 500;
text-transform: uppercase;
font-size: 15px;
fill: black;
}
.data {
fill: #f86d36;
stroke-width: 1;
}
.graph .dot-joints {
stroke: #f86d36;
stroke-dasharray: 0;
stroke-width: 3;
}
svg:hover {
-webkit-filter: drop-shadow(0px 0px 4px #f86d36e8);
filter: drop-shadow(0px 0px 4px #f86d36e8);
}
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="graph"
aria-labelledby="title" role="img">
<g class="grid x-grid" id="xGrid">
<line x1="90" x2="90" y1="5" y2="371"></line>
</g>
<g class="grid x-grid" id="xGrid">
<line x1="90" x2="705" y1="370" y2="370"></line>
</g>
<g class="labels x-labels"><text x="100" y="400">2008</text><text x="246" y="400">2009</text><text x="392"
y="400">2010</text><text x="538" y="400">2011</text><text x="694" y="400">2012</text><text x="400" y="440"
class="label-title">Year</text></g>
<g class="labels x-labels"><text x="70" y="15">15</text><text x="70" y="131">10</text><text x="70"
y="248">5</text><text x="70" y="373">0</text><text x="35" y="200" class="label-title">Price</text></g>
<g class="data" data-setname="Our first data set">
<circle cx="95" cy="192" data-value="7.2" r="5"></circle>
<circle cx="240" cy="141" data-value="8.1" r="5"></circle>
<circle cx="388" cy="179" data-value="7.7" r="5"></circle>
<circle cx="531" cy="200" data-value="6.8" r="5"></circle>
<circle cx="677" cy="104" data-value="6.7" r="5"></circle>
</g>
<g class="dot-joints x-grid">
<line x1="95" x2="240" y1="192" y2="141"></line>
<line x1="240" x2="388" y1="141" y2="179"></line>
<line x1="388" x2="531" y1="179" y2="200"></line>
<line x1="531" x2="677" y1="200" y2="104"></line>
</g>
</svg>
I hope this is what you need: I'm using an svg filter for the shadow.
To your code I've added .data circle:hover{filter:url(#f)}for the individual circles and .dot-joints.x-grid:hover{filter:url(#f)} for the group of lines:
*{
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body{
height: 100%;
width: 100%;
}
#import url('https://fonts.googleapis.com/css?family=Roboto+Mono:400,500&display=swap');
body {
font-family: 'Roboto Mono', monospace;
}
.graph .labels.x-labels {
text-anchor: middle;
}
.graph .labels.y-labels {
text-anchor: end;
}
.graph {
height: 500px;
width: 800px;
}
.graph .grid {
stroke: #ccc;
stroke-dasharray: 0;
stroke-width: 3;
}
.labels {
font-size: 17px;
font-weight: 400;
}
.label-title {
font-weight: 500;
text-transform: uppercase;
font-size: 15px;
fill: black;
}
.data {
fill: #f86d36;
stroke-width: 1;
}
.data circle:hover{filter:url(#f)}
.graph .dot-joints {
stroke: #f86d36;
stroke-dasharray: 0;
stroke-width: 3;
}
.dot-joints.x-grid:hover{filter:url(#f)}
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="graph"
aria-labelledby="title" role="img">
<defs>
<filter id="f" filterUnits="userSpaceOnUse" id="shadow" x="-10" y="-150" width="120%" height="120%">
<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur"></feGaussianBlur>
<feOffset in="blur" dx="3" dy="1" result="shadow"></feOffset>
<feFlood flood-color="rgba(0,0,0,.52)" result="color" />
<feComposite in ="color" in2="shadow" operator="in" />
<feComposite in="SourceGraphic"/>
</filter>
</defs>
<g class="grid x-grid" id="xGrid">
<line x1="90" x2="90" y1="5" y2="371"></line>
</g>
<g class="grid x-grid" id="xGrid">
<line x1="90" x2="705" y1="370" y2="370"></line>
</g>
<g class="labels x-labels"><text x="100" y="400">2008</text><text x="246" y="400">2009</text><text x="392"
y="400">2010</text><text x="538" y="400">2011</text><text x="694" y="400">2012</text><text x="400" y="440"
class="label-title">Year</text></g>
<g class="labels x-labels"><text x="70" y="15">15</text><text x="70" y="131">10</text><text x="70"
y="248">5</text><text x="70" y="373">0</text><text x="35" y="200" class="label-title">Price</text></g>
<g class="data" data-setname="Our first data set">
<circle cx="95" cy="192" data-value="7.2" r="5"></circle>
<circle cx="240" cy="141" data-value="8.1" r="5"></circle>
<circle cx="388" cy="179" data-value="7.7" r="5"></circle>
<circle cx="531" cy="200" data-value="6.8" r="5"></circle>
<circle cx="677" cy="104" data-value="6.7" r="5"></circle>
</g>
<g class="dot-joints x-grid" >
<line x1="95" x2="240" y1="192" y2="141"></line>
<line x1="240" x2="388" y1="141" y2="179"></line>
<line x1="388" x2="531" y1="179" y2="200"></line>
<line x1="531" x2="677" y1="200" y2="104"></line>
</g>
</svg>
Alternatively you may want this instead:
svg:hover .data,
svg:hover .dot-joints.x-grid{filter:url(#f)}
When hovering the svg element apply shadow to the lines and circles.
*{
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body{
height: 100%;
width: 100%;
}
#import url('https://fonts.googleapis.com/css?family=Roboto+Mono:400,500&display=swap');
body {
font-family: 'Roboto Mono', monospace;
}
.graph .labels.x-labels {
text-anchor: middle;
}
.graph .labels.y-labels {
text-anchor: end;
}
.graph {
height: 500px;
width: 800px;
}
.graph .grid {
stroke: #ccc;
stroke-dasharray: 0;
stroke-width: 3;
}
.labels {
font-size: 17px;
font-weight: 400;
}
.label-title {
font-weight: 500;
text-transform: uppercase;
font-size: 15px;
fill: black;
}
.data {
fill: #f86d36;
stroke-width: 1;
}
.graph .dot-joints {
stroke: #f86d36;
stroke-dasharray: 0;
stroke-width: 3;
}
svg:hover .data,
svg:hover .dot-joints.x-grid{filter:url(#f)}
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="graph"
aria-labelledby="title" role="img">
<defs>
<filter id="f" filterUnits="userSpaceOnUse" id="shadow" x="-10" y="-150" width="120%" height="120%">
<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur"></feGaussianBlur>
<feOffset in="blur" dx="3" dy="1" result="shadow"></feOffset>
<feFlood flood-color="rgba(0,0,0,.52)" result="color" />
<feComposite in ="color" in2="shadow" operator="in" />
<feComposite in="SourceGraphic"/>
</filter>
</defs>
<g class="grid x-grid" id="xGrid">
<line x1="90" x2="90" y1="5" y2="371"></line>
</g>
<g class="grid x-grid" id="xGrid">
<line x1="90" x2="705" y1="370" y2="370"></line>
</g>
<g class="labels x-labels"><text x="100" y="400">2008</text><text x="246" y="400">2009</text><text x="392"
y="400">2010</text><text x="538" y="400">2011</text><text x="694" y="400">2012</text><text x="400" y="440"
class="label-title">Year</text></g>
<g class="labels x-labels"><text x="70" y="15">15</text><text x="70" y="131">10</text><text x="70"
y="248">5</text><text x="70" y="373">0</text><text x="35" y="200" class="label-title">Price</text></g>
<g class="data" data-setname="Our first data set">
<circle cx="95" cy="192" data-value="7.2" r="5"></circle>
<circle cx="240" cy="141" data-value="8.1" r="5"></circle>
<circle cx="388" cy="179" data-value="7.7" r="5"></circle>
<circle cx="531" cy="200" data-value="6.8" r="5"></circle>
<circle cx="677" cy="104" data-value="6.7" r="5"></circle>
</g>
<g class="dot-joints x-grid" >
<line x1="95" x2="240" y1="192" y2="141"></line>
<line x1="240" x2="388" y1="141" y2="179"></line>
<line x1="388" x2="531" y1="179" y2="200"></line>
<line x1="531" x2="677" y1="200" y2="104"></line>
</g>
</svg>
UPDATE
The OP is commenting:
Can you explain it in a little more details
In the <defs> I've added an svg filter. This filter first is creating a blur feGaussianBlur. You may need to change the stdDeviation in order to change the aspect of the shadow.
Next is offsetting the the previously created blur feOffset: You may need to change the dx="3"and dy="1" attributes in order to move the shadow.
Then feFlood and feComposite are used to add a color to the shadow. In this case I'm using a semitransparent black, but you can use the color you want.
I'm using this filter to apply the shadow only to those elements you want: filter:url(#f) - where f is the filter's id
I want to place a text in a shape. I have: font, textWidth, textHeight, margin of the text. the text is placed into a shape which has its coordinates x and y :
so what i'm getting is this :
this is the svg that i generate :
<g class='nodeGroup' transform='translate(43,-66)' style='-webkit-user-select: none; -webkit-user-drag: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); touch-action: none;'>
<rect stroke='lightgray' fill='#FEFEF5' x='0' y='0' width='260' height='618' padding='0,0,0,0' marginBottom='0' marginLeft='0' marginRight='0' marginTop='0'/>
<text fill='black' x='98' y='8' width='64' height='14' padding='0,0,0,0' cursor='default' angle='0' font='14px Calibri Bold' horizontalAlignment='center' marginBottom='8' marginLeft='0' marginRight='0' marginTop='8' textHeight='14' textWidth='60' verticalAlignment='top'>
processtest</text>
<line stroke='lightgray' fill='none' x='0' y='30' x1='0' y1='30' x2='260' y2='30' width='260' height='0' padding='0,0,0,0' marginBottom='0' marginLeft='0' marginRight='0' marginTop='0'/>
</g>
<g class='nodeGroup' transform='translate(43,-36)' style='-webkit-user-select: none; -webkit-user-drag: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); touch-action: none;'>
<rect stroke='lightgray' fill='#FEFEF5' x='0' y='0' width='260' height='588' padding='0,0,0,0' marginBottom='0' marginLeft='0' marginRight='0' marginTop='0'/>
<text fill='black' x='113' y='8' width='34' height='14' padding='0,0,0,0' cursor='default' angle='0' font='14px Calibri Bold' horizontalAlignment='center' marginBottom='8' marginLeft='0' marginRight='0' marginTop='8' textHeight='14' textWidth='30' verticalAlignment='top'>lane0</text>
</g>
And i'm trying to place the text in the right position compared with the rectangle shape coordinates, what i want to get :
and this is the svg that i want to get :
<g class="nodeGroup" transform="translate(43,-66)" style="-webkit-user-select: none; -webkit-user-drag: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); touch-action: none;">
<rect stroke="#2e3d54" stroke-width="2" fill="#FEFEF5" x="0" y="0" width="260" height="618" />
<text fill="black" cursor="default" x="100" y="19" style="font:14px Calibri Bold;">processtest</text>
<line stroke="#2e3d54" stroke-width="1" fill="none" x1="0" y1="30" x2="260" y2="30" />
</g>
<g class="nodeGroup" transform="translate(43,-36)" style="-webkit-user-select: none; -webkit-user-drag: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); touch-action: none;">
<rect stroke="#2e3d54" stroke-width="2" fill="#FEFEF5" x="0" y="0" width="260" height="588" />
<text fill="black" cursor="default" x="115" y="19" style="font:14px Calibri Bold;">lane0</text>
</g>
Using javascript, how can i place the text and calculate its x and y ?
Er... Are you looking for something like this?
* {font-family: 'Consolas', 'Courier New', monospace; line-height: 1;}
.classDgm {border: 1px solid #666; text-align: center; width: 175px;}
.classDgm .head {border-bottom: 1px solid #666; padding: 5px;}
.classDgm .body {min-height: 100px; padding: 5px;}
<div class="classDgm">
<div class="head">processTest</div>
<div class="body">lane0</div>
</div>
Preview:
You might play around with the line-height, min-height. I have given a min-height, just in case to align all the other similar diagrams with it.
Without code it’s hard to tell.
If it is in a table try using CSS:
text-align: center;
vertical-align: middle;
else the padding-top: 10px; should work with positioning.
There is no need for JavaScript when CSS can get it all done.