Basic shapes
SVG and Canvas
SVG
- Resolution independent.
- Supports event handlers.
- Not suitable for game applications.
- SVG is an XML-based description of graphics.
- Most suitable for applications with large rendering areas, such as Google Maps.
- High complexity will slow down the rendering speed, and any application that overuses DOM will not be fast.
- Exists independently as a single file, with the suffix
.svg, which can be directly imported intohtml.
- SVG is based on XML, which means that every element in the SVG DOM is available and can attach JavaScript event handlers to a particular element.
- In SVG, each drawn graphic is treated as an object, and if the properties of the SVG object change, the browser can recreate the graphic on its own.
canvas
- Depend on resolution.
- Text rendering is weak.
- Does not support event handlers.
Canvasis rendered pixel by pixel.
Canvasis drawn withJavaScript.
- Can save the result graphics in
.pngor.jpgformat.
- Most suitable for image-intensive games, where many objects will be frequently redrawn.
- Once the graphics are drawn in
Canvas, they will no longer receive attention from the browser. If their position changes, the graphics need to be redrawn, including any objects that have been covered by the graphics.
Postion system in SVG
<text x=”20” y=”20%”>SVG Text</text>
Percentages are relative to the viewBox of the nearest <svg> or <symbol> element (or the actual width and height if no viewBox was given).
transform
<text transform="translate(10,64)">SVG Text</text>
it can only accepts use-unit values for translations, not the presentage
Sizing
<text transform="scale(4,1)">SVG Text</text>
Reuse part of the SVG shapes
Create SVG symbol objects and include them with SVG use. This way, we can define the SVG icon library in HTML and instantiate and customize it in React as needed.
<!-- Definition -->
<svg viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
<symbol id="myIcon" width="24" height="24" viewBox="0 0 24 24">
<!-- ... -->
</symbol>
<!-- ... -->
</svg>
<!-- Usage -->
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<use href="#myIcon" />
</svg><svg width="400" height="400"> <line x1="2" y1="2" x2="400" y2="400" stroke="green"></line> <rect height="150" width="150" y="100" x="100" fill="red" stroke="blue"></rect> </svg>

element.style {
width: 200px;
}
rect[Attributes Style] {
height: 150;
width: 150;
y: 100;
x: 100;
fill: red;
stroke: blue;
}The css style will overwrite the attributes styles
Tag Name | Description | Example |
<svg> | This tag is the root container for all SVG elements. | <svg width="500" height="500"></svg> |
<circle> | This tag is used to draw circles. | <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red"/> |
<ellipse> | This tag is used to draw ellipses. | <ellipse cx="200" cy="80" rx="100" ry="50" style="fill:yellow;stroke:purple;stroke-width:2"/> |
<line> | This tag is used to draw lines. | <line x1="0" y1="0" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2"/> |
<polygon> | This tag is used to create a graphic that contains at least three sides. | <polygon points="200,10 250,190 160,210" style="fill:lime;stroke:purple;stroke-width:1"/> |
<polyline> | This tag is used to create any shape that consists of straight lines. | <polyline points="20,20 40,25 60,40 80,120 120,140 200,180" style="fill:none;stroke:black;stroke-width:3"/> |
<rect> | This tag is used to draw rectangles. | <rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)"/> |
<text> | This tag is used to create text. | <text x="0" y="15" fill="black">This is SVG text</text> |
<path> | This tag is used to define a path. | <<svg height="400" width="400">
<!-- Cat face -->
<circle cx="200" cy="200" r="100" stroke="black" stroke-width="4" fill="lightgrey" />
<!-- Eyes -->
<circle cx="150" cy="180" r="20" stroke="black" stroke-width="2" fill="green" />
<circle cx="250" cy="180" r="20" stroke="black" stroke-width="2" fill="green" />
<!-- Nose -->
<polygon points="190,230 210,230 200,250" style="fill:pink;stroke:black;stroke-width:2" />
<!-- Mouth -->
<path d="M150 260 Q 200 290 250 260" stroke="black" fill="transparent"/>
<path d="M150 260 Q 200 280 200 260" stroke="black" fill="transparent"/>
<path d="M250 260 Q 200 280 200 260" stroke="black" fill="transparent"/>
<!-- Whiskers -->
<line x1="120" y1="270" x2="180" y2="270" style="stroke:black;stroke-width:2" />
<line x1="220" y1="270" x2="280" y2="270" style="stroke:black;stroke-width:2" />
<line x1="130" y1="290" x2="170" y2="280" style="stroke:black;stroke-width:2" />
<line x1="230" y1="280" x2="270" y2="290" style="stroke:black;stroke-width:2" />
</svg> d="M150 0 L75 200 L225 200 Z"/> |
<g> | This tag is used to group SVG shapes together. | <g fill="black"><circle cx="50" cy="50" r="30"/><circle cx="70" cy="70" r="30"/></g> |
<defs> | This tag is used to store graphical objects that will be used at a later point. These objects should be defined inside the <defs> element. | <defs><radialGradient id="grad1" cx="50%" cy="50%" r="50%" fx="50%" fy="50%"><stop offset="0%" style="stop-color:rgb(255,255,255); stop-opacity:0" /><stop offset="100%" style="stop-color:rgb(0,0,255); stop-opacity:1" /></radialGradient></defs> |
<marker> | This tag is used to define marker or arrowhead shapes that can be later used by a <path>, <line>, <polyline> or <polygon> element. | <marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L0,6 L9,3 z" fill="#f00" /></marker> |
<pattern> | This tag is used to define patterns that can be used to fill or stroke SVG shapes. | <pattern id="patt1" patternUnits="userSpaceOnUse" width="100" height="100"><image href="image.jpg" x="0" y="0" width="100" height="100" /></pattern> |
<mask> | This tag is used to define an alpha mask for compositing the current object into the background. | <mask id="m1" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox"><circle cx=".5" cy=".5" r=".4" fill="white" /></mask> |
<clipPath> | This tag is used to define a clipping path, to be used by the clip-path property. | <clipPath id="myClip"><circle cx="50" cy="50" r="50" /></clipPath> |
<image> | This tag allows an external graphic to be included in the SVG. | <image href="image.jpg" height="200" width="200"/> |
<a> | This tag is used to make a shape or text clickable, much like in HTML. | <a href="https://www.example.com"><text x="0" y="15" fill="black">Click me</text></a> |
<use> | This tag is used to reuse an element that is defined elsewhere in the SVG. | <use href="#myCircle" fill="blue"/> |
Path
Mmoves the pen to a new location without drawing a line. It requires two parameters for the x and y coordinates. In this case, it moves the pen to the coordinates (150, 0).
Ldraws a line from the current position to the new position. Again, two parameters are needed for the x and y coordinates. Here, it draws lines to the points (75, 200) and then (225, 200).
Zcloses the path by drawing a straight line back to the starting point.
Here is a more detailed tutorial about how to use the
<path> tag:- Move To - M/m
- The
Mcommand is used to move the pen (without drawing anything). It takes two numbers, or parameters: x and y. For example,M 10 10would move the pen to the point (10,10) on the grid. - If you use the lowercase
m, it will move the pen relative to the last point. If the pen was at (30,30), the commandm 10 10would move the pen to (40,40).
- Line To - L/l
- The
Lcommand is used to draw a line from the current point to a new point. It takes two parameters: x and y. For example, if the pen is currently at (10,10), the commandL 20 20would draw a line to the point (20,20). - If you use the lowercase
l, it will draw a line relative to the current point. If the pen was at (30,30), the commandl 10 10would draw a line to (40,40).
- Horizontal Line To - H/h and Vertical Line To - V/v
- The
HandVcommands are used to draw horizontal and vertical lines, respectively. Each takes one parameter. If the pen is currently at (10,10),H 20would draw a horizontal line to (20,10), andV 20would draw a vertical line to (10,20). - The lowercase
handvare used to draw lines relative to the current point.
- Cubic Bézier Curve - C/c and S/s
- The
Ccommand is used to draw a cubic Bézier curve. It takes six parameters: x1 y1, x2 y2, x y (control points and end point). For example,C 20 20, 40 20, 50 10would draw a curve from the current point to (50,10) using (20,20) and (40,20) as the control points. - The
Scommand is a shorthand command forC. It takes four parameters and the first control point is assumed to be a reflection of the second control point on the previous command relative to the current point. - The lowercase
candsdraw curves relative to the current point.
- Quadratic Bézier Curve - Q/q and T/t
- The
Qcommand is similar toC, but it draws a quadratic Bézier curve. It takes four parameters: x1 y1, x y (control point and end point). - The
Tcommand is a shorthand command forQ. It takes two parameters and the control point is assumed to be a reflection of the control point on the previous command relative to the current point. - The lowercase
qandtdraw curves relative to the current point.
- Close Path - Z/z
- The
Zcommand is used to close the path. It does not take any parameters. It draws a straight line from the current point to the start point.
Want the transformation to relate to the element itself rather than the entire SVG canvas.
In SVG,
transform-box and transform-origin are properties used to control the behavior of transformations such as scaling, rotation, and skewing.Here's a breakdown of each:
- transform-box: This property defines the layout box to which the
transformandtransform-originproperties relate. It takes the following values: view-box: The bounding box is equivalent to the SVG's view box. This is the initial value.fill-box: The bounding box is equivalent to the object's fill area.stroke-box: The bounding box is equivalent to the object's stroke area.
- transform-origin: This property sets the origin for an element's transformations. It takes two values that determine the x and y coordinates of the origin:
X% Y%: The origin of transformation is positioned at X% across, Y% down relative to the element.Xpx Ypx: The origin of transformation is positioned at X pixels across, Y pixels down relative to the element.
It can also accept keywords 'top', 'bottom', 'left', 'right', and 'center' for both X and Y positions.
SVG animations can be done in a few different ways. You can use CSS animations, JavaScript, or SMIL (Synchronized Multimedia Integration Language) which is a native SVG animation syntax.
Here is an example of each:
1. CSS Animations:
<svg width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="45" fill="blue" class="myCircle"/>
</svg>
<style>
.myCircle {
animation: pulse 1s infinite;
}
@keyframes pulse {
0% {
fill: blue;
}
50% {
fill: red;
}
100% {
fill: blue;
}
}
</style>This animation will make the circle continuously change its color from blue to red and back again, every second.
2. JavaScript:
<svg id="mySvg" width="100" height="100" viewBox="0 0 100 100">
<circle id="myCircle" cx="50" cy="50" r="45" fill="blue"/>
</svg>
<script>
let circle = document.getElementById('myCircle');
setInterval(() => {
if (circle.getAttribute('fill') === 'blue') {
circle.setAttribute('fill', 'red');
} else {
circle.setAttribute('fill', 'blue');
}
}, 1000);
</script>This JavaScript animation will achieve the same effect as the CSS animation above, but using a different method.
3. SMIL:
<svg width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="45">
<animate attributeName="fill" values="blue;red;blue" dur="1s" repeatCount="indefinite" />
</circle>
<rect x="50" y="50" width="100" height="100" fill="lime">
<animateTransform
attributeName="transform"
type="rotate"
from="0 100 100"
to="360 100 100"
dur="2s"
repeatCount="indefinite"/>
</rect>
</svg>SMIL allows you to animate SVG elements directly within the SVG syntax itself. This SMIL animation will produce the same effect as the previous two examples.
Please note that support for SMIL is not universal across all web browsers (it's not supported in IE, and its future support in Chrome has been uncertain). For this reason, many developers prefer using CSS or JavaScript for SVG animations.
<svg width="500" height="500" xmlns="http://www.w3.org/2000/svg">
<path
id="motionPath"
d="M 10 80 Q 52.5 10, 95 80 T 180 80"
fill="none"
stroke="lightgrey"
/>
<circle r="5" fill="red">
<animateMotion dur="4s" repeatCount="indefinite" rotate="auto">
<mpath href="#motionPath" />
</animateMotion>
</circle>
</svg>Example
Drag a ball on a curved path
<!DOCTYPE html>
<html>
<head>
<style>
/* Styling for the draggable ball and the motion path */
#ball {
cursor: pointer; /* Changes the cursor to a hand when hovering over the ball */
fill: red;
}
#motionPath {
fill: none;
stroke: lightgrey;
}
</style>
</head>
<body>
<svg id="svg" width="500" height="500">
<path id="motionPath" d="M 10 80 Q 52.5 10, 95 80 T 180 80" />
<!-- The path the ball will move along -->
<circle id="ball" r="5" />
<!-- The ball that will be dragged -->
</svg>
<script>
// Getting the path and ball elements from the SVG
const path = document.getElementById('motionPath');
const ball = document.getElementById('ball');
// Calculating the total length of the path
const pathLength = path.getTotalLength();
// Initializing the current and target positions along the path
let currentLength = 0;
let targetLength = 0;
// Function to set the position of the ball on the path
function setPosition(length) {
// Getting the point at a specified length along the path
const point = path.getPointAtLength(length);
// Setting the position of the ball to the point
ball.setAttribute('cx', point.x);
ball.setAttribute('cy', point.y);
}
// Function to smoothly animate the ball towards the target position
function animate() {
// If the current and target positions are not close
if (Math.abs(targetLength - currentLength) > 0.1) {
// Move the current position a bit closer to the target position
currentLength += (targetLength - currentLength) * 0.2;
// Update the position of the ball
setPosition(currentLength);
// Request the next frame of the animation
requestAnimationFrame(animate);
}
}
// Setting the initial position of the ball
setPosition(currentLength);
// When the ball is pressed
ball.addEventListener('mousedown', function(event) {
// Function to move the ball when the mouse is moved
function onMouseMove(event) {
// Getting the position of the SVG relative to the page
const rect = svg.getBoundingClientRect();
// Getting the position of the mouse relative to the SVG
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
// Initializing the shortest distance to Infinity
let minDist = Infinity;
// Looping over points along the path
for (let length = 0; length <= pathLength; length += pathLength / 1000) {
// Getting the point at the current length
const point = path.getPointAtLength(length);
// Calculating the distance from the mouse to the point
const dx = x - point.x;
const dy = y - point.y;
const dist = Math.sqrt(dx * dx + dy * dy);
// If the distance is shorter than the current shortest distance
if (dist < minDist) {
// Update the shortest distance and target position
minDist = dist;
targetLength = length;
}
}
// Start the animation towards the target position
animate();
}
// When the mouse is moved, move the ball
svg.addEventListener('mousemove', onMouseMove);
// When the mouse button is released
svg.addEventListener('mouseup', function() {
// Stop moving the ball
svg.removeEventListener('mousemove', onMouseMove);
}, {once: true});
});
</script>
</body>
</html>Text
All the text need to be put into the
<text> tag to be able to show it. The y="0" default value can position text above the SVG if using the default top-left origin.
Default font-size should be 16px (medium) on most browsers. But it is also safe to set a font size for text
In CSS-styled HTML, the
color property sets the color of the text letters. However, in SVG text, the color is controlled by the same fill property used to set the color of SVG shapes.
To set the font-size property in SVG, you can use either CSS rules with the same syntax as for HTML(The using method is same as css) or define the font-size presentation attribute. For font-size presentation attribute, we can also set unit value.
css properties used to style text
font-family,font-size,font-size-adjust,font-stretch,font-style,font-variant, andfont-weightfor selecting and scaling the font data
text-shadowfor blurring or adding an offset copy behind the main text
text-transformfor converting to uppercase, lowercase, or cap‐ italized words
text-decorationfor adding underlines, overlines, and strike- throughs
directionandunicode-bidito control multidirectional language
letter-spacingandword-spacingto adjust text spacing
- Use values such as keywords, hex colors (e.g. #080844 or #fab), or functions like rgb(20, 100, 128) or hsla(0,80%,75%,0.7) for fill and stroke or a
url()reference to theidof an SVG paint server (gradient or pattern element).
Text effects
<svg
width="4in"
height="0.8in"
viewBox="0 0 400 80"
>
<title>Filter Effects on SVG Text</title>
<style type="text/css">
text {
font: bold 64px Verdana, Geneva, sans-serif;
text-decoration: underline;
fill: darkBlue;
stroke: indigo;
filter: url(#shine);
}
</style>
<defs>
<filter id="shine">
<feGaussianBlur in="SourceGraphic" stdDeviation="2" result="blur" />
<feColorMatrix
values="1.5 0 0 0.5 0 0 1.5 0 0.5 0 0 0 1.5 0.5 0
0 0 0 1 -0.5"
/>
<feOffset dx="-2.5" dy="-1.5" />
<feComponentTransfer result="highlight">
<feFuncA type="linear" amplitude="2" />
</feComponentTransfer>
<feComposite
in="blur"
in2="highlight"
operator="arithmetic"
k1="0"
k2="1"
k3="1"
k4="0"
/>
<feComposite in2="SourceGraphic" operator="atop" />
</filter>
</defs>
<rect width="100%" height="100%" fill="lightYellow" />
<text x="10" y="80%">SVG Text</text>
</svg>
Painted Effects (similar to background-clip: text in html css)
<svg
xml:lang="en"
height="50px"
width="410px"
>
<title>Gradient-Filled Text</title>
<defs>
<linearGradient id="fade">
<stop stop-color="orange" stop-opacity="1" offset="0" />
<stop stop-color="orange" stop-opacity="0" offset="1" />
</linearGradient>
</defs>
<g
transform="translate(10,40)"
style="
font-family: Arial;
font-weight: bold;
font-size: 24pt;
fill: url('#fade');
"
>
<text>A Whiter Shade of Pale</text>
</g>
</svg>.png%3Ftable%3Dblock%26id%3D0f30a1ba-131d-4fc6-8003-81e57c7aafe7%26cache%3Dv2&w=1920&q=75)
Text segments
To apply different styles to part of the text
<tspan class="em" dy="-0.5cm" >One</tspan>
There are four positioning attributes for SVG text:
x, y, dx, and dy. The first two declare absolute positions within the coordinate system, while the latter two declare differences in position that should be added to the otherwise applicable position.Or
<text x="0 1.0in 1.6in 2.2in 3.0in 3.6in"
y="0.8in 0.4in 0.8in 0.4in 0.8in 0.4in"
>Wiggle</text>
which can specific multi words position
Aria label
<text xml:lang="la" role="heading" aria-level="2" x="190" y="480">Lilium montanum</text>
Color
linearGradient<linearGradieny x1="0" y1="0" x2="100%" y2="100%"> <stop stop-color="blue" offset="0" /> <stop stop-color="darkSeaGreen" offset="1" /> </linearGradient>
JS manuplate
create the element
const rect = document.createElementNS(
'http://www.w3.org/2000/svg',
'rect'
);Pitfall
The transform origin is relative to the parent SVG element's viewbox, not the element itself. Therefore, if we set transform-origin: center center, the transformation will use the center coordinates of the parent SVG, not the path element.
Setting a transform-box property to
fill-box.body {
animation: sparkle 0.15s 1s steps(2, jump-none) infinite alternate;
transform-box: fill-box;
transform-origin: center center;
}Tools
Reduce the SVG size
svgo
svg • Updated Mar 17, 2025



