I wanted to create a graphics where there will be a rectangle node in the center and from each of it's corner edges, draw a cross line. That means 4 lines in 4 corner edge of the rectangle.
I could only show some lines in the top left edge of the rectangle. Can anyone guide me on how to show other three lines from that rectangle, please? I did not understand the line concept from the docs
Here is the demo
<svg width="800" height="600" viewbox="0 0 800 600" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 250 100)">
<rect width="200" height="60" rx="5" ry="5">
</rect>
<text x="100" y="30" font-size="14" text-anchor="middle" fill="white">
Root Node
</text>
<line x1="0" y1="0" x2="0" y2="90" stroke="black" stroke-width="3" transform="rotate(-220)"/>
<line x1="0" y1="0" x2="10" y2="90" stroke="black" stroke-width="3" transform="rotate(-220)"/>
<line x1="0" y1="0" x2="10" y2="90" stroke="black" stroke-width="3" transform="rotate(-220)"/>
<line x1="0" y1="0" x2="10" y2="90" stroke="black" stroke-width="3" transform="rotate(-220)"/>
</g>
</svg>
http://jsbin.com/jucosalice/edit?html,output
To draw cross lines at each corner without calculating coordinates, you can use rotate and translate properties:
<svg width="800" height="600" viewbox="0 0 800 600" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 250 100)">
<rect width="200" height="60" rx="5" ry="5">
</rect>
<text x="100" y="30" font-size="14" text-anchor="middle" fill="white">
Root Node
</text>
<line x1="0" y1="0" x2="100" y2="0" transform="rotate(-135)" stroke="black" stroke-width="3"/>
<line x1="0" y1="0" x2="100" y2="0" transform="translate(200 0) rotate(-45)" stroke="black" stroke-width="3"/>
<line x1="0" y1="0" x2="100" y2="0" transform="translate(0 60) rotate(135)" stroke="black" stroke-width="3"/>
<line x1="0" y1="0" x2="100" y2="0" transform="translate(200 60) rotate(45)" stroke="black" stroke-width="3"/>
</g>
</svg>
Explanation:
The X axis is from left to right, the Y axis is from top to bottom. The direction of rotation is clockwise. So, the code
<line x1="0" y1="0" x2="100" y2="0" transform="translate(200 0) rotate(-45)" stroke="black" stroke-width="3"/>
draws a line from (0,0) to (100,0), translate(shift) it by 200 unit in X direction towards right (as it is width of main rectangle), and then rotate it by -45 deg to get its slope.
See here for their documentation.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<svg width="800" height="600" viewbox="0 0 800 600" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 250 100)">
<rect width="200" height="60" rx="5" ry="5"></rect>
<text x="100" y="30" font-size="14" text-anchor="middle" fill="white">
Root Node
</text>
<line x1="0" y1="0" x2="-75" y2="-75" stroke="black" stroke-width="3"/>
<line x1="200" y1="60" x2="275" y2="135" stroke="black" stroke-width="3"/>
<line x1="200" y1="0" x2="275" y2="-75" stroke="black" stroke-width="3"/>
<line x1="0" y1="60" x2="-75" y2="135" stroke="black" stroke-width="3"/>
</g>
</svg>
</body>
</html>
Related
The SVG example currently visually looks perfect except I want to achieve the same result without padding.
The padding's purpose is to force the red/blue lines 40px to the right to make space for the axis whilst also stopping it from overflowing on the right side of the graph.
I'm trying to remove the padding, but then I need to find a new way to shift JUST the "lines" 40px to the right without using x="40px" width="calc(100% - 40px)" because this syntax also isn't compatible with Sharp, or older browsers.
Is there any way to remove the padding and shift the lines 40px right whilst also constraining it within the box model of the SVG?
(final note: I don't want to use 'responsive' units in any logic that moves the lines)
JSFiddle of line graph: https://jsfiddle.net/Lefsqo3j/14/
<div style="height:148px;width:300px;overflow:hidden;resize:both">
<svg overflow="visible" style="padding:24px 0px 24px 40px" height="100%" width="100%">
<svg role="img" viewBox="0 0 300 100" preserveAspectRatio="none">
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<line y1="0" y2="100" x1="0" x2="0" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="75" x2="75" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="150" x2="150" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="225" x2="225" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="300" x2="300" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="0" y2="0" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="25" y2="25" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="50" y2="50" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="75" y2="75" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="100" y2="100" stroke-width="0.2" stroke="black"></line>
</svg>
</svg>
<svg x="100%" overflow="visible">
<text text-anchor="end" dy="-8px">
<tspan fill="red"> ⬤</tspan>
Line A<tspan fill="blue"> ⬤</tspan>
Line B
</text>
</svg>
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<path
d="M 0 75 M 0 75 L 75 50 L 150 15 L 225 67 L 300 67 L 300 67"
stroke-width="3"
stroke="red"
fill="transparent"
vector-effect="non-scaling-stroke"
></path>
<path
d="M 0 92 M 0 92 L 75 72 L 150 80 L 225 50 L 300 50 L 300 50"
stroke-width="3"
stroke="blue"
fill="transparent"
></path>
</svg>
<svg overflow="visible">
<text x="0%" text-anchor="end" y="0%">
40
</text>
<text x="0%" text-anchor="end" y="25%">
30
</text>
<text x="0%" text-anchor="end" y="50%">
20
</text>
<text x="0%" text-anchor="end" y="75%">
10
</text>
<text x="0%" text-anchor="end" y="100%">
0
</text>
<g style="transform: translateX(0%);">
<text y="100%" dy="16px">
5
</text>
</g>
<g style="transform: translateX(25%);">
<text y="100%" dy="16px">
10
</text>
</g>
<g style="transform: translateX(50%); ">
<text y="100%" dy="16px">
15
</text>
</g>
<g style="transform: translateX(75%); ">
<text y="100%" dy="16px">
20
</text>
</g>
<g text-anchor="end" style="transform: translateX(100%);">
<text y="100%" dy="16px">
25
</text>
</g>
</svg>
</svg>
</div>
I've modified the SVG and brought the content inside the content box. Dimensions scale uniformly maintaining aspect ratio.
<div style="height:148px;
width:300px;
overflow:hidden;
resize:both;
background-color: wheat;
">
<svg class="chart" overflow="visible">
<style>
.chart {
width: 100%;
height: 100%;
font-size: 14px;
padding-bottom: 24px;
}
/* background color for entire chart */
.chart-background {
fill: rgb(230, 249, 255);
}
/* styling for only the graph part */
.graph {
background-color: transparent;
}
/* grid lines style */
.chart .grid>line {
stroke-width: 0.5;
stroke: green;
}
.legend {
background-color: wheat;
}
.labels {
background-color: transparent !important;
}
.back {
background-color: wheat;
}
</style>
<rect class="chart-background" height="100%" width="100%" />
<svg viewBox="0 0 340 140" x="40" y="24" preserveAspectRatio="none">
<g class="grid">
<line y1="0" y2="100" x1="0" x2="0"></line>
<line y1="0" y2="100" x1="75" x2="75"></line>
<line y1="0" y2="100" x1="150" x2="150"></line>
<line y1="0" y2="100" x1="225" x2="225"></line>
<line y1="0" y2="100" x1="300" x2="300"></line>
<line x1="0" x2="300" y1="0" y2="0"></line>
<line x1="0" x2="300" y1="25" y2="25"></line>
<line x1="0" x2="300" y1="50" y2="50"></line>
<line x1="0" x2="300" y1="75" y2="75"></line>
<line x1="0" x2="300" y1="100" y2="100"></line>
</g>
</svg>
<svg>
<g class="legend">
<text x="100%" text-anchor="end" dy="16">
<tspan fill="red"> ⬤</tspan>Line A<tspan fill="blue"> ⬤</tspan>Line B
</text>
</g>
</svg>
<svg overflow="visible" x="40" y="24" height="70%" width="88%" style="margin-bottom: 24px;">
<g class="labels" style="font-size: 12px;">
<text x="0%" text-anchor="end" y="0%">40</text>
<text x="0%" text-anchor="end" y="25%">30</text>
<text x="0%" text-anchor="end" y="50%">20</text>
<text x="0%" text-anchor="end" y="75%">10</text>
<text x="0%" text-anchor="end" y="100%">0</text>
<text y="100%" dy="16px">5</text>
<text y="100%" dy="16px" x="22%">10</text>
<text y="100%" dy="16px" x="48%">15</text>
<text y="100%" dy="16px" x="74%">20</text>
<text y="100%" dy="16px" dx="-20px" x="100%">25</text>
</g>
</svg>
<svg viewBox="0 0 340 140" x="40" y="24" preserveAspectRatio="none">
<g class="plot">
<path d="M 0 75 M 0 75 L 75 50 L 150 15 L 225 67 L 300 67 L 300 67" stroke-width="3" stroke="red"
fill="transparent" vector-effect="non-scaling-stroke"></path>
<path d="M 0 92 M 0 92 L 75 72 L 150 80 L 225 50 L 300 50 L 300 50" stroke-width="3" stroke="blue"
fill="transparent"></path>
</g>
</svg>
</svg>
</div>
Sharpjs:
const svgBuffer = Buffer.from(svgImage);
const image = await sharp(svgBuffer, {})
.resize({ width: 500, fit: sharp.fit.inside, position: 'centre' })
.toFile('e:/svg-image.png');
Old answer
We can wrap the original svg content in a new <svg> tag. And with custom styles the original svg can be positioned such that overflow will be visible:
const sharp = require('sharp');
async function svgToImage(svgImage) {
try {
const wrapped = `<svg id='wrapper' width="600" height="400">
<style>
#wrapper > svg{
transform: scale(.9) translate(25px, 25px) ;
}
</style>
${svgImage}
</svg>`;
const svgBuffer = Buffer.from(wrapped);
//const image = await sharp(svgBuffer, {}).resize(500).toFile('e:/svg-image.png');
const image = await sharp({
create: {
width: 600,
height: 400,
channels: 4,
background: { r: 220, g: 255, b: 220, alpha: 1 },
},
})
.composite([{ input: svgBuffer, top: 0, left: 0 }])
.png()
.toFile('e:/svg-image.png');
} catch (error) {
console.log(error);
}
}
const svgImage = `
<svg overflow="visible" style="padding:24px 0px 24px 40px">
<svg role="img" viewBox="0 0 300 100" preserveAspectRatio="none">
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<line y1="0" y2="100" x1="0" x2="0" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="75" x2="75" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="150" x2="150" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="225" x2="225" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="300" x2="300" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="0" y2="0" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="25" y2="25" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="50" y2="50" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="75" y2="75" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="100" y2="100" stroke-width="0.2" stroke="black"></line>
</svg>
</svg>
<svg x="100%" overflow="visible">
<text text-anchor="end" dy="-8px">
<tspan fill="red"> ⬤</tspan>
Line A<tspan fill="blue"> ⬤</tspan>
Line B
</text>
</svg>
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<path
d="M 0 75 M 0 75 L 75 50 L 150 15 L 225 67 L 300 67 L 300 67"
stroke-width="3"
stroke="red"
fill="transparent"
vector-effect="non-scaling-stroke"
></path>
<path
d="M 0 92 M 0 92 L 75 72 L 150 80 L 225 50 L 300 50 L 300 50"
stroke-width="3"
stroke="blue"
fill="transparent"
></path>
</svg>
<svg overflow="visible">
<text x="0%" text-anchor="end" y="0%">40</text>
<text x="0%" text-anchor="end" y="25%">30</text>
<text x="0%" text-anchor="end" y="50%">20</text>
<text x="0%" text-anchor="end" y="75%">10</text>
<text x="0%" text-anchor="end" y="100%">0</text>
<text y="100%" dy="16px">5</text>
<text y="100%" dy="16px" x="25%">10</text>
<text y="100%" dy="16px" x="50%">15</text>
<text y="100%" dy="16px" x="75%">20</text>
<text y="100%" dy="16px" x="100%">25</text>
</svg>
</svg>`;
svgToImage(svgImage);
Output:
On x axis the labels didn't behave because of bug and bug related to transform. So I had to modify the x label tags.
I am trying to achieve The following image:
How do I achieve this fill?
How do I end my circle at the edge of the outer circle? My attempt to adjust the position of the canvas is not to be working.
<svg width="173" height="172" xmlns="http://www.w3.org/2000/svg">
<g>
<title>background</title>
<rect fill="none" id="canvas_background" height="175" width="175" y="-1" x="-1"/>
<g display="none" overflow="visible" y="0" x="0" height="100%" width="100%" id="canvasGrid">
<rect fill="url(#gridpattern)" stroke-width="0" y="0" x="0" height="100%" width="100%"/>
</g>
</g>
<g>
<title>Layer 1</title>
<ellipse stroke="#000" ry="85" rx="85" id="svg_1" cy="86" cx="86" stroke-width="1.5" fill="#fff"/>
<ellipse stroke="#000" ry="88" rx="88" id="svg_5" cy="88" cx="15" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" fill="none"/>
<line stroke="#000" stroke-linecap="null" stroke-linejoin="null" id="svg_3" y2="170" x2="86" y1="2" x1="82" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" fill="none"/>
</g>
</svg>
The code above produces the following:
Here's how you should do it, explainatory comments attatched:
<svg width="173" height="172" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- clip path-->
<clipPath id="clip">
<ellipse id="circle" ry="85" rx="85" cy="86" cx="86" />
</clipPath>
<!-- gradient -->
<linearGradient id="gradient" x1="0" x2="0" y1="0" y2="1">
<stop offset="0%" stop-color="#000" />
<stop offset="100%" stop-color="#fff" />
</linearGradient>
</defs>
<g>
<title>background</title>
<rect fill="none" id="canvas_background" height="175" width="175" y="-1" x="-1" />
<g display="none" overflow="visible" y="0" x="0" height="100%" width="100%" id="canvasGrid">
<rect fill="url(#gridpattern)" stroke-width="0" y="0" x="0" height="100%" width="100%" />
</g>
</g>
<g>
<title>Layer 1</title>
<!-- same shape of the #circle in #clip, adding stroke and fill -->
<use xlink:href="#circle" stroke="#000" stroke-width="1.5" fill="#fff" />
<!-- using clip path, same shape of above -->
<ellipse clip-path="url(#clip)" stroke="#000" ry="88" rx="88" id="svg_5" cy="88" cx="15" stroke-width="1.5" fill="url(#gradient)" />
<line clip-path="url(#clip)" stroke="#000" stroke-linecap="null" stroke-linejoin="null" id="svg_3" y2="170" x2="86" y1="2" x1="82" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" fill="none" />
</g>
</svg>
use this, I created this with adobe Illustrator.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="165px"
height="165px" viewBox="0 0 165 165" style="enable-background:new 0 0 165 165;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;stroke:#000000;stroke-width:1.5;}
.st1{fill:url(#SVGID_1_);stroke:#000000;stroke-width:1.5;}
.st2{fill:none;stroke:#000000;stroke-width:1.5;}
.st3{fill:url(#SVGID_2_);stroke:#000000;stroke-width:1.5;}
</style>
<defs>
</defs>
<path class="st0" d="M164.3,82.5c0,45.1-36.6,81.8-81.8,81.8c-10.8,0-21.2-2.1-30.6-5.9c-30-12.1-51.1-41.5-51.1-75.8
S21.9,18.8,51.9,6.7c9.5-3.8,19.8-5.9,30.6-5.9C127.6,0.8,164.3,37.3,164.3,82.5z"/>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="51.875" y1="158.32" x2="51.875" y2="6.68">
<stop offset="0" style="stop-color:#FFFFFF"/>
<stop offset="1" style="stop-color:#000000"/>
</linearGradient>
<path class="st1" d="M103,82.5c0,20.8-7.7,39.7-20.5,54.1c-8.3,9.4-18.8,16.9-30.6,21.7c-30-12.1-51.1-41.5-51.1-75.8
S21.9,18.8,51.9,6.7C63.7,11.5,74.2,19,82.5,28.4C95.3,42.8,103,61.7,103,82.5z"/>
<line class="st2" x1="82.5" y1="0.8" x2="82.5" y2="164.3"/>
</svg>
<!-- Generator: Adobe Illustrator 24.0.1, SVG Export Plug-In -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="165px"
height="165px" viewBox="0 0 165 165" style="enable-background:new 0 0 165 165;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;stroke:#000000;stroke-width:1.5;}
.st1{fill:url(#SVGID_1_);stroke:#000000;stroke-width:1.5;}
.st2{fill:none;stroke:#000000;stroke-width:1.5;}
.st3{fill:url(#SVGID_2_);stroke:#000000;stroke-width:1.5;}
</style>
<defs>
</defs>
<path class="st0" d="M164.3,82.5c0,45.1-36.6,81.8-81.8,81.8c-10.8,0-21.2-2.1-30.6-5.9c-30-12.1-51.1-41.5-51.1-75.8
S21.9,18.8,51.9,6.7c9.5-3.8,19.8-5.9,30.6-5.9C127.6,0.8,164.3,37.3,164.3,82.5z"/>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="51.875" y1="158.32" x2="51.875" y2="6.68">
<stop offset="0" style="stop-color:#FFFFFF"/>
<stop offset="1" style="stop-color:#000000"/>
</linearGradient>
<path class="st1" d="M103,82.5c0,20.8-7.7,39.7-20.5,54.1c-8.3,9.4-18.8,16.9-30.6,21.7c-30-12.1-51.1-41.5-51.1-75.8
S21.9,18.8,51.9,6.7C63.7,11.5,74.2,19,82.5,28.4C95.3,42.8,103,61.7,103,82.5z"/>
<line class="st2" x1="82.5" y1="0.8" x2="82.5" y2="164.3"/>
</svg>
I need to pass an <svg></svg> element to backend as clear text using angular HTTP.
for example, I have an angular-html page with a <svg> element,
<div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 540 320">
<defs>
<path id="Triangle" d="M120 20 L 220 193.205 L 20 193.205 Z" stroke="red" fill="url(#radial)"/>
<path id="Maths" d="M250,50C380,50 350,150 480,150" stroke="green" fill="none"/>
<path id="Chemistry" transform="translate(-200,0) scale(1.5)" d="M250,50C380,50 350,150 480,150" stroke="blue" fill="none"/>
<path id="Path" d="M20,240 C40,280 60,280 200,230 A100 100 0 0 1 300,260 L 330,280 Q 400,320 500,200" stroke="orange" fill="none"/>
<linearGradient id="linear" x1="0" x2="1" gradientUnits="objectBoundingBox">
<stop stop-color="green" offset="0"/>
<stop stop-color="red" offset="1"/>
</linearGradient>
<radialGradient id="radial" cx="0.5" cy="0.6667" r="0.6" gradientUnits="objectBoundingBox">
<stop stop-color="orange" offset="0.2"/>
<stop stop-color="yellow" offset="1"/>
</radialGradient>
<pattern id="pattern" width="4" height="4" patternUnits="userSpaceOnUse">
<rect width="4" height="4"/>
<rect width="2" height="2" fill="red"/>
<rect x="2" y="2" width="2" height="2" fill="red"/>
</pattern>
</defs>
<rect x="2%" y="2%" width="96%" height="96%" fill="url(#linear)" fill-opacity="0.3" stroke="orange" stroke-width="2" stroke-dasharray="5 2 2 2 5 5"/>
<use xlink:href="#Triangle"/>
<use xlink:href="#Maths"/>
<use xlink:href="#Chemistry"/>
<use xlink:href="#Path"/>
<text textLength="600px" lengthAdjust="spacingAndGlyphs" fill="url(#pattern)">
<textPath xlink:href="#Triangle" font-size="20" font-family="serif" font-weight="bold" textLength="600px" lengthAdjust="spacingAndGlyphs">Text adjusted around a triangle</textPath>
</text>
<text font-family="sans-serif">
<textPath xlink:href="#Maths" font-size="30" fill="blue" text-anchor="middle" startOffset="50%">Maths x<tspan font-size="20" baseline-shift="super">2</tspan> + y<tspan font-size="20" baseline-shift="super">2</tspan> = z<tspan font-size="20" baseline-shift="super">2</tspan>!</textPath>
<textPath xlink:href="#Chemistry" font-size="30" fill="green" text-anchor="middle" startOffset="50%">Chemistry 2H<tspan font-size="20" baseline-shift="sub">2</tspan> + O<tspan font-size="20" baseline-shift="sub">2</tspan> -> 2H<tspan font-size="20" baseline-shift="sub">2</tspan>O</textPath>
<textPath xlink:href="#Path" font-size="30" fill="purple" dominant-baseline="middle" text-anchor="middle" startOffset="50%">Text centered on a complex path</textPath>
</text>
</svg>
</div>
Is it possible to pass the svg to backend with angular HTTP.
You can use ViewChild for selecting svg element and then by outerHTML access the HTML.
Demo
Set reference to svg in HTML,
<svg #svgElement ...
Get data from reference,
#ViewChild('svgElement', {static: true}) svgElement: ElementRef;
onClick() {
console.log(this.svgElement.nativeElement.outerHTML)
}
This is the heart I'm trying to draw:
Here's the code I've written:
<!DOCTYPE html/>
<html>
<head>
<title>SVG Paths</title>
</head>
<body>
<svg width="200px" height="200px">
<pattern id="rulerPattern" patternUnits="userSpaceOnUse"
x="0" y="0" width="10" height="10"
viewBox="0 0 10 10" >
<line x1="0" y1="0" x2="10" y2="0"
stroke="gray" fill="none" />
<line x1="0" y1="0" x2="0" y2="10"
stroke="gray" fill="none"/>
</pattern>
<rect x="0" y="0" width="100%" height="100%"
fill="url(#rulerPattern)" stroke="black" />
<path d="M 100 180 20 80 C20 80 60 -15 100 80"
stroke="black"
stroke-width="5"
fill="red" />
<path d="M 100 180 180 80 C180 80 140 -15 100 80"
stroke="black"
stroke-width="5"
fill="red" />
</svg>
</body>
</html>
What am I doing wrong? I want to get the exact shape of the heart shown on the first picture using paths.
The given svg specifies the semi-circles of the heart's top with the C subcommand of the path element. This subcommand creates a cubic spline which is ill-suited to the purpose since no segments of circles can be drawn with this family of curves (more about splines can be found here).
The following code rectifies the svg definition:
<!DOCTYPE html>
<html>
<head>
<title>SVG Paths</title>
</head>
<body>
<svg width="200px" height="200px">
<pattern id="rulerPattern" patternUnits="userSpaceOnUse"
x="0" y="0" width="10" height="10"
viewBox="0 0 10 10" >
<line x1="0" y1="0" x2="10" y2="0"
stroke="gray" fill="none" />
<line x1="0" y1="0" x2="0" y2="10"
stroke="gray" fill="none"/>
</pattern>
<rect x="0" y="0" width="100%" height="100%"
fill="url(#rulerPattern)" stroke="black"
/>
<path
d="M 180,80 L100,180 20,80 A 40,40 0,0,1 100,80 A 40,40 0,0,1 180,80"
stroke="black"
stroke-width="5"
fill="red"
/>
</svg>
</body>
</html>
The icon can be drawn with a single path. This path consists of a polyline to generate the lower portion of the heart and two adjacent semi-circles.
The syntax for the path definition is outlined in the svg specs at W3C. The complex part is the specification of the semi-circles which employ the elliptic arc command whose usage is detailed here.
NB: The DOCTYPE element is not an xml/html element, it closes without /.
SVG Line at this point isn't drawing line at this coordinates (x1="200" x2="0" y1="200" y2="200") . This problem happens only in Firefox. What mistake did I make?
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<line x1="0" x2="200" y1="0" y2="0" style="stroke:rgb(255,0,0);stroke-width:2"></line>
<line x1="200" x2="200" y1="0" y2="200" style="stroke:rgb(255,0,0);stroke-width:2"></line>
<line x1="0" x2="0" y1="0" y2="200" style="stroke:rgb(255,0,0);stroke-width:2"></line>
<line x1="200" x2="0" y1="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2"></line>
</svg>