Our SVG viewer will have the following features:
- An editor that allows us to write, paste, and edit SVG code
- A validation mechanism that checks if the SVG Code is valid
- A preview area where we’ll see the SVG in real-time
- An export feature that will allow us to export the SVG
So, by the end of this tutorial, we’ll have something like this:
The SVG editor will have a text area to add, edit, or paste the SVG code.
1 |
<div class="editor"> |
2 |
<div class="editor-header">SVG Code Editor</div> |
3 |
<textarea
|
4 |
id="svgInput" |
5 |
placeholder="Paste your SVG code here and watch the magic happen..." |
6 |
></textarea>
|
7 |
</div>
|
The preview area will have a preview container where the current SVG code will be injected for preview.
1 |
<div class="preview"> |
2 |
<div class="preview-header">SVG Preview</div> |
3 |
<div class="preview-content"> |
4 |
<div id="previewContainer" class="preview-container"></div> |
5 |
</div>
|
6 |
</div>
|
HTML Markup
Okay, let’s start with the building blocks. The HTML markup will look like this:
1 |
<div class="main"> |
2 |
<header>
|
3 |
<h1>SVG Preview Tool</h1> |
4 |
<p>Edit, preview, and export clean, scalable vector art</p> |
5 |
</header>
|
6 |
<div class="container"> |
7 |
<div class="editor"> |
8 |
<div class="editor-header">SVG Code Editor</div> |
9 |
|
10 |
<textarea
|
11 |
id="svgInput" |
12 |
placeholder="Paste your SVG code here and watch the magic happen..." |
13 |
></textarea>
|
14 |
|
15 |
</div>
|
16 |
<div class="preview"> |
17 |
<div class="preview-header">SVG Preview</div> |
18 |
<div class="preview-content"> |
19 |
<div id="previewContainer" class="preview-container"></div> |
20 |
</div>
|
21 |
</div>
|
22 |
</div>
|
23 |
|
24 |
<button id="exportBtn">Export SVG</button> |
25 |
</div>
|
Styling with CSS
As you saw from the final demo, we want the editor and the preview to appear side by side on large screens and stack vertically on small devices. We’ll achieve this layout using Flexbox and media queries.
Let’s begin by applying some basic styles to the <body>
and <header>
elements as shown below.
1 |
@import url("https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap"); |
2 |
|
3 |
* { |
4 |
margin: 0; |
5 |
padding: 0; |
6 |
box-sizing: border-box; |
7 |
}
|
8 |
|
9 |
body { |
10 |
display: flex; |
11 |
min-height: 100vh; |
12 |
justify-content: center; |
13 |
padding: 20px; |
14 |
font-family: "DM Mono", monospace; |
15 |
}
|
16 |
|
17 |
header { |
18 |
max-width: 420px; |
19 |
text-align: center; |
20 |
margin-bottom: 40px; |
21 |
}
|
22 |
|
23 |
h1 { |
24 |
font-size: 30px; |
25 |
font-weight: 700; |
26 |
margin-bottom: 8px; |
27 |
}
|
28 |
|
29 |
header p { |
30 |
font-size: 18px; |
31 |
}
|
We’ll apply the following styles to ensure all elements are stacked vertically.
1 |
.main { |
2 |
display: flex; |
3 |
flex-direction: column; |
4 |
align-items: center; |
5 |
gap: 24px; |
6 |
width: 100%; |
7 |
max-width: 1000px; |
8 |
height: 90vh; |
9 |
min-height: 700px; |
10 |
margin-top: 50px; |
11 |
}
|
12 |
.container { |
13 |
display: flex; |
14 |
height: calc(100% - 84px); |
15 |
gap: 20px; |
16 |
width: 100%; |
17 |
}
|
We also want the text editor and the preview container to fill the available height of their parent containers.
1 |
.editor { |
2 |
border: 1px solid #7287f2; |
3 |
}
|
4 |
|
5 |
.editor, |
6 |
.preview { |
7 |
width: 50%; |
8 |
display: flex; |
9 |
flex-direction: column; |
10 |
border-radius: 16px; |
11 |
overflow: hidden; |
12 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
13 |
}
|
14 |
|
15 |
.editor-header, |
16 |
.preview-header { |
17 |
padding: 12px 20px; |
18 |
font-weight: 600; |
19 |
font-size: 14px; |
20 |
text-align: center; |
21 |
width: 100%; |
22 |
color: white; |
23 |
|
24 |
}
|
25 |
|
26 |
textarea { |
27 |
/* width: 100%; */
|
28 |
height: 100%; |
29 |
border: none; |
30 |
padding: 20px; |
31 |
font-size: 13px; |
32 |
resize: none; |
33 |
background: #2e3138; |
34 |
color: white; |
35 |
overflow-y: auto; |
36 |
}
|
37 |
|
38 |
textarea:focus { |
39 |
outline: none; |
40 |
}
|
41 |
|
42 |
.preview-container { |
43 |
width: 100%; |
44 |
height: 100%; |
45 |
border-radius: 16px; |
46 |
background-color: #f9fafb; |
47 |
overflow-y: auto; |
48 |
}
|
49 |
|
50 |
.preview-content { |
51 |
flex: 1; |
52 |
padding: 16px; |
53 |
overflow: hidden; |
54 |
}
|
55 |
|
56 |
.svg-container { |
57 |
display: flex; |
58 |
justify-content: center; |
59 |
overflow: hidden; |
60 |
}
|
Finally, let’s style the export button, add styles for displaying error messages, and apply media queries for responsiveness.
1 |
.error-message { |
2 |
color: #dc2626; |
3 |
background: #fef2f2; |
4 |
border: 1px solid #fca5a5; |
5 |
padding: 16px; |
6 |
margin: 20px; |
7 |
border-radius: 6px; |
8 |
font-size: 13px; |
9 |
}
|
10 |
|
11 |
button { |
12 |
margin-top: 40px; |
13 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
14 |
color: white; |
15 |
padding: 12px 30px; |
16 |
border: none; |
17 |
border-radius: 8px; |
18 |
cursor: pointer; |
19 |
width: 150px; |
20 |
}
|
21 |
|
22 |
@media (max-width: 768px) { |
23 |
body { |
24 |
padding: 20px; |
25 |
}
|
26 |
|
27 |
.main { |
28 |
width: 100%; |
29 |
height: 100vh; |
30 |
}
|
31 |
|
32 |
.container { |
33 |
flex-direction: column; |
34 |
height: 100%; |
35 |
}
|
36 |
|
37 |
.editor, |
38 |
.preview { |
39 |
width: 100%; |
40 |
height: 50%; |
41 |
}
|
42 |
}
|
Now the SVG tool interface looks like this:


JavaScript functionality
In this section, we’ll perform some SVG code validation to ensure that any SVG code added to the editor is parsed before being displayed.
We’ll also add a sample SVG code in the editor and display it in the preview area by default.
Let’s start by getting the elements from the DOM and assigning them to variables for easy access.
1 |
const svgInput = document.getElementById("svgInput"); |
2 |
const previewContainer = document.getElementById("previewContainer"); |
3 |
const exportBtn = document.getElementById("exportBtn"); |
SVG Code Validation
The next step is to ensure that the SVG code is valid before adding it for preview. Create a function called loadSVG()
that takes an SVG string as an argument.
Inside this function, we will first check if the SVG string is empty. If its empty, we’ll display an error message.
1 |
function loadSVG(svgCode) { |
2 |
previewContainer.innerHTML = ""; |
3 |
if (!svgCode.trim()) { |
4 |
showErrorMessage("Enter SVG code to see preview"); |
5 |
return; |
6 |
}}
|
The second form of validation will be done using the DOMParser
to ensure the SVG Code is well formatted XML code.
DOMParser
is an inbuilt interface in JavaScript that allows us to convert XML or HTML strings into a DOM Document object. Once the string is parsed into a DOM, you can query it using standard DOM methods like querySelector, etc.
To parse the XML, first create an instance of the DOMParser
API. Then, parse the SVG string using the ParseFromString()
method and set “image/svg+xml” as the MIME type.
1 |
const parser = new DOMParser(); |
2 |
const doc = parser.parseFromString(svgCode, "image/svg+xml"); |
Check for errors by querying the <parserror>
element. If there are no errors, we will extract the <svg>
element and inject it into the preview.
1 |
function loadSVG(svgCode) { |
2 |
previewContainer.innerHTML = ""; |
3 |
if (!svgCode.trim()) { |
4 |
showErrorMessage("Enter SVG code to see preview"); |
5 |
return; |
6 |
}
|
7 |
|
8 |
try { |
9 |
const parser = new DOMParser(); |
10 |
const doc = parser.parseFromString(svgCode, "image/svg+xml"); |
11 |
const parserError = doc.querySelector("parsererror"); |
12 |
if (parserError) |
13 |
throw new Error("XML parsing error: " + parserError.textContent); |
14 |
const svgElement = doc.querySelector("svg"); |
15 |
if (!svgElement) throw new Error("No valid SVG element found"); |
16 |
|
17 |
const container = document.createElement("div"); |
18 |
container.className = "svg-container"; |
19 |
container.innerHTML = svgCode; |
20 |
previewContainer.appendChild(container); |
21 |
} catch (error) { |
22 |
|
23 |
showErrorMessage("Invalid SVG code: " + error.message); |
24 |
}
|
25 |
}
|
Add event listeners
We now have a function that validates and displays the SVG code, so the next step is to ensure it runs before the SVG code in the input changes.
Add two event listeners to the textarea element as shown below:
1 |
svgInput.addEventListener("input", function () { |
2 |
loadSVG(this.value); |
3 |
});
|
4 |
svgInput.addEventListener("paste", function () { |
5 |
loadSVG(this.value); |
6 |
});
|
The input event will be triggered whenever you type, delete, or change the contents of the text area, while the paste event will be triggered when you paste the content to the text area.
Load sample SVG and export SVG
The final step is to ensure that we have a default SVG when the tool opens. This is great to ensure the user sees how the tool works.
Create a function called loadDefaultSVG()
which looks like this:
1 |
function loadDefaultSVG() { |
2 |
const sampleSvg = `<svg xmlns="https://www.w3.org/2000/svg" width="160" height="190" viewBox="0 0 60 60"><defs><style>.cls-1{fill:#87e64b;}</style></defs><circle class="cls-1" cx="25.56" cy="61.15" r="2.86"/><path class="cls-1" d="M42,41.65l-16.13,1.73c-.3.03-.45-.34-.21-.53l15.78-12.29c1.02-.84,1.68-2.14,1.4-3.54-.28-2.14-2.05-3.54-4.29-3.26l-17.15,2.51c-.3.04-.46-.34-.22-.53l17-12.98c3.35-2.61,3.63-7.73.56-10.71-2.79-2.79-7.27-2.7-10.06.09L1.29,30.01c-1.02,1.12-1.49,2.61-1.21,4.19.47,2.52,2.98,4.19,5.5,3.73l14.77-3.01c.32-.07.49.36.22.54l-16.38,10.49c-2.05,1.3-2.98,3.63-2.33,5.96.65,3.07,3.73,4.84,6.71,4.1l24.49-6.03c.28-.07.48.25.3.47l-3.82,4.72c-1.02,1.3.65,3.07,2.05,2.05l12.58-10.34c2.24-1.86.75-5.5-2.14-5.22h-.03Z"/></svg>`; |
3 |
|
4 |
svgInput.value = sampleSvg; |
5 |
loadSVG(sampleSvg); |
6 |
}
|
7 |
|
8 |
window.addEventListener("load", loadDefaultSVG); |
In the code above, we set a default SVG string as the value of the editor (in the textarea), then we call the loadSVG()
function which in turn renders the SVG in the preview area.
I’ve used the Envato “creative spark” for this example, but you can choose any default SVG you like
Export SVG
To export the SVG, we’ll package it as an SVG file and trigger a download when the export button is clicked.
1 |
function exportSVG() { |
2 |
const blob = new Blob([svgInput.value], { |
3 |
type: "image/svg+xml" |
4 |
});
|
5 |
const url = URL.createObjectURL(blob); |
6 |
const a = document.createElement("a"); |
7 |
a.href = url; |
8 |
a.download = "svg-viewer.svg"; |
9 |
document.body.appendChild(a); |
10 |
a.click(); |
11 |
document.body.removeChild(a); |
12 |
URL.revokeObjectURL(url); |
13 |
}
|
14 |
exportBtn.addEventListener("click", exportSVG); |
Final demo
And we’re done! Here’s a reminder of the final codepen demo:
We built a fully functional SVG viewer using HTML, CSS, and JavaScript. This simple, yet powerful tool will allow you to preview and export your SVG graphics for use in your projects.
- Kiambu Web Design Services
- Kiambu SEO Services
- Kiambu Digital Marketing Services
- Kiambu Social Media Marketing Services
- Kiambu Lipa Pole Pole Phones
- Nyali Web Design Services
- Nyali SEO Services
- Nyali Lipa Pole Pole Phones
- Mombasa Lipa Pole Pole Phones
- Meru Web Design Services
- Meru SEO Services
- Meru Digital Marketing Services
- Meru Social Media Marketing Services
- CBD Nairobi Web Design Services
- Westlands Web Design Services
- Outer Ring Road Web Design Services
- Outer Ring Road SEO Services
- Thika Road Web Design Services
- Thika Road SEO Services
- Thika Road Digital Marketing Services
- Thika Road Lipa Pole Pole Phones
- Langata Web Design Services
- Langata SEO Services
- Langata Lipa Pole Pole Phones
- Mombasa Road Web Design Services
- Mombasa Road SEO Services
- Mombasa Road Lipa Pole Pole Phones
- Mombasa Road Digital Marketing Services
- Mombasa Road Social Media Marketing Services
- Karen Web Design Services
- Karen SEO Services
- Karen Digital Marketing Services
- Garden City Web Design Services
- Thika Road Mall Web Design Services
- Thika Road Mall SEO Services
- Thika Road Mall Lipa Pole Pole Phones
- Eastlands Web Design Services
- Eastlands SEO Services
- Eastlands Lipa Pole Pole Phones
- Donholm Web Design Services
- Donholm SEO Services
- Donholm Lipa Pole Pole Phones
- Ruai Web Design Services
- Ruai SEO Services
- Ruai Lipa Pole Phones
from Artificial Intelligence – Techyrack Hub https://ift.tt/qumabSc
via IFTTT
0 Comments