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.
Canvas
is rendered pixel by pixel.
Canvas
is drawn withJavaScript
.
- Can save the result graphics in
.png
or.jpg
format.
- 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
M
moves 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).
L
draws 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).
Z
closes 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
M
command is used to move the pen (without drawing anything). It takes two numbers, or parameters: x and y. For example,M 10 10
would 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 10
would move the pen to (40,40).
- Line To - L/l
- The
L
command 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 20
would 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 10
would draw a line to (40,40).
- Horizontal Line To - H/h and Vertical Line To - V/v
- The
H
andV
commands are used to draw horizontal and vertical lines, respectively. Each takes one parameter. If the pen is currently at (10,10),H 20
would draw a horizontal line to (20,10), andV 20
would draw a vertical line to (10,20). - The lowercase
h
andv
are used to draw lines relative to the current point.
- Cubic Bézier Curve - C/c and S/s
- The
C
command 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 10
would draw a curve from the current point to (50,10) using (20,20) and (40,20) as the control points. - The
S
command 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
c
ands
draw curves relative to the current point.
- Quadratic Bézier Curve - Q/q and T/t
- The
Q
command 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
T
command 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
q
andt
draw curves relative to the current point.
- Close Path - Z/z
- The
Z
command 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
transform
andtransform-origin
properties 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-weight
for selecting and scaling the font data
text-shadow
for blurring or adding an offset copy behind the main text
text-transform
for converting to uppercase, lowercase, or cap‐ italized words
text-decoration
for adding underlines, overlines, and strike- throughs
direction
andunicode-bidi
to control multidirectional language
letter-spacing
andword-spacing
to 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 theid
of 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 Oct 18, 2024