Skip to content

Commit 2ce451b

Browse files
Added:SVG-Optimizer (#1666)
* Added whiteboard * added svg optimizer * ADded logs * Fix: Resolve ESLint errors and add NODE_OPTIONS for Netlify build * Fixed errors --------- Co-authored-by: Priyankar Pal <88102392+priyankarpal@users.noreply.github.com>
1 parent 3c30ee2 commit 2ce451b

File tree

8 files changed

+899
-0
lines changed

8 files changed

+899
-0
lines changed

netlify.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
command = "npm run build"
33
publish = "build"
44

5+
[build.environment]
6+
NODE_OPTIONS = "--max-old-space-size=4096"
7+
58
[[headers]]
69
for = "/*"
710
[headers.values]

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@
105105
"prettier --write"
106106
]
107107
},
108+
"pnpm": {
109+
"overrides": {
110+
"json-graphql-parser@0.1.9>axios": "^0.27.2"
111+
}
112+
},
108113
"reactSnap": {
109114
"puppeteerArgs": [
110115
"--no-sandbox",
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Cover Image Placeholder
2+
3+
Please add a `cover.png` file to this directory.
4+
5+
Recommended specifications:
6+
- Format: PNG
7+
- Dimensions: Approximately 800x600 pixels (or similar aspect ratio)
8+
- Content: A representative screenshot or icon for the SVG Optimizer play
9+
10+
You can use a screenshot of the SVG Optimizer interface or create a custom graphic that represents the tool's functionality.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import React from 'react';
2+
3+
function OptimizationPanel({ options, onChange }) {
4+
const handleToggle = (optionKey) => {
5+
onChange({
6+
...options,
7+
[optionKey]: !options[optionKey]
8+
});
9+
};
10+
11+
return (
12+
<div className="svg-optimization-panel">
13+
<h3>Optimization Options</h3>
14+
<div className="svg-options-grid">
15+
<label className="svg-option-item">
16+
<input
17+
checked={options.removeComments}
18+
type="checkbox"
19+
onChange={() => handleToggle('removeComments')}
20+
/>
21+
<span>Remove Comments</span>
22+
</label>
23+
24+
<label className="svg-option-item">
25+
<input
26+
checked={options.removeMetadata}
27+
type="checkbox"
28+
onChange={() => handleToggle('removeMetadata')}
29+
/>
30+
<span>Remove Metadata</span>
31+
</label>
32+
33+
<label className="svg-option-item">
34+
<input
35+
checked={options.removeHiddenElements}
36+
type="checkbox"
37+
onChange={() => handleToggle('removeHiddenElements')}
38+
/>
39+
<span>Remove Hidden Elements</span>
40+
</label>
41+
42+
<label className="svg-option-item">
43+
<input
44+
checked={options.removeEmptyAttributes}
45+
type="checkbox"
46+
onChange={() => handleToggle('removeEmptyAttributes')}
47+
/>
48+
<span>Remove Empty Attributes</span>
49+
</label>
50+
51+
<label className="svg-option-item">
52+
<input
53+
checked={options.minifyColors}
54+
type="checkbox"
55+
onChange={() => handleToggle('minifyColors')}
56+
/>
57+
<span>Minify Colors</span>
58+
</label>
59+
60+
<label className="svg-option-item">
61+
<input
62+
checked={options.removeDefaultAttributes}
63+
type="checkbox"
64+
onChange={() => handleToggle('removeDefaultAttributes')}
65+
/>
66+
<span>Remove Default Values</span>
67+
</label>
68+
69+
<label className="svg-option-item">
70+
<input
71+
checked={options.removeXMLNS}
72+
type="checkbox"
73+
onChange={() => handleToggle('removeXMLNS')}
74+
/>
75+
<span>Remove XMLNS</span>
76+
</label>
77+
78+
<label className="svg-option-item">
79+
<input
80+
checked={options.prettify}
81+
type="checkbox"
82+
onChange={() => handleToggle('prettify')}
83+
/>
84+
<span>Prettify Output</span>
85+
</label>
86+
</div>
87+
</div>
88+
);
89+
}
90+
91+
export default OptimizationPanel;
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import React, { useState } from 'react';
2+
3+
function PreviewPanel({ originalSvg, optimizedSvg }) {
4+
const [activePreview, setActivePreview] = useState('optimized');
5+
6+
const renderSVG = (svgString) => {
7+
if (!svgString) {
8+
return <div className="svg-preview-placeholder">No SVG to preview</div>;
9+
}
10+
11+
try {
12+
return <div dangerouslySetInnerHTML={{ __html: svgString }} />;
13+
} catch (error) {
14+
return <div className="svg-preview-error">Error rendering SVG preview</div>;
15+
}
16+
};
17+
18+
return (
19+
<div className="svg-preview-section">
20+
<div className="svg-preview-header">
21+
<h3>Visual Preview</h3>
22+
<div className="svg-preview-tabs">
23+
<button
24+
className={`svg-tab-btn ${activePreview === 'original' ? 'active' : ''}`}
25+
type="button"
26+
onClick={() => setActivePreview('original')}
27+
>
28+
Original
29+
</button>
30+
<button
31+
className={`svg-tab-btn ${activePreview === 'optimized' ? 'active' : ''}`}
32+
type="button"
33+
onClick={() => setActivePreview('optimized')}
34+
>
35+
Optimized
36+
</button>
37+
<button
38+
className={`svg-tab-btn ${activePreview === 'comparison' ? 'active' : ''}`}
39+
type="button"
40+
onClick={() => setActivePreview('comparison')}
41+
>
42+
Side by Side
43+
</button>
44+
</div>
45+
</div>
46+
47+
<div className="svg-preview-content">
48+
{activePreview === 'original' && (
49+
<div className="svg-preview-box">{renderSVG(originalSvg)}</div>
50+
)}
51+
52+
{activePreview === 'optimized' && (
53+
<div className="svg-preview-box">{renderSVG(optimizedSvg)}</div>
54+
)}
55+
56+
{activePreview === 'comparison' && (
57+
<div className="svg-preview-comparison">
58+
<div className="svg-preview-box">
59+
<h4>Original</h4>
60+
{renderSVG(originalSvg)}
61+
</div>
62+
<div className="svg-preview-box">
63+
<h4>Optimized</h4>
64+
{renderSVG(optimizedSvg)}
65+
</div>
66+
</div>
67+
)}
68+
</div>
69+
</div>
70+
);
71+
}
72+
73+
export default PreviewPanel;

src/plays/svg-optimizer/Readme.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# SVG Optimizer
2+
3+
A powerful React-based SVG optimizer that allows users to paste or upload SVG code and optimize it by removing unnecessary elements while preserving visual output. This tool helps reduce file sizes significantly without compromising quality.
4+
5+
## Play Demographic
6+
7+
- Language: js
8+
- Level: Intermediate
9+
10+
## Creator Information
11+
12+
- User: Abhrxdip
13+
- Github Link: https://github.com/Abhrxdip
14+
- Blog:
15+
- Video:
16+
17+
## Implementation Details
18+
19+
This SVG Optimizer is built using React.js with the following features and concepts:
20+
21+
### React Concepts Used:
22+
- **Functional Components**: All components are functional components using modern React syntax
23+
- **React Hooks**:
24+
- `useState` for managing component state (SVG input, optimization options, file sizes)
25+
- `useEffect` for automatically optimizing SVG when input or options change
26+
- **Controlled Inputs**: Text areas and checkboxes are fully controlled components
27+
- **Conditional Rendering**: Error messages, preview modes, and button states render conditionally
28+
- **Component Composition**: Reusable components (OptimizationPanel, PreviewPanel)
29+
30+
### Key Features:
31+
1. **Multiple Input Methods**:
32+
- Paste SVG code directly
33+
- Upload SVG files
34+
- Load sample SVG for testing
35+
36+
2. **Optimization Options**:
37+
- Remove comments
38+
- Remove metadata (title, desc, metadata tags)
39+
- Remove hidden elements
40+
- Remove empty attributes
41+
- Minify colors (hex shortening, named colors to hex)
42+
- Remove default attribute values
43+
- Optional XMLNS removal
44+
- Code prettification
45+
46+
3. **Real-time Processing**:
47+
- Automatic optimization on input change
48+
- Live file size calculation
49+
- Percentage reduction display
50+
51+
4. **Visual Preview**:
52+
- Original SVG preview
53+
- Optimized SVG preview
54+
- Side-by-side comparison view
55+
56+
5. **Export Options**:
57+
- Copy to clipboard
58+
- Download optimized SVG file
59+
60+
### Technical Implementation:
61+
- **Client-side Processing**: All optimization happens in the browser with no backend required
62+
- **File API**: Uses FileReader for handling file uploads
63+
- **Blob API**: Creates downloadable files without server interaction
64+
- **Clipboard API**: Enables one-click copying of optimized code
65+
- **Regular Expressions**: Pattern matching for removing unnecessary SVG elements
66+
67+
## Considerations
68+
69+
- This is a client-side optimizer and doesn't perform advanced path optimization or vector calculations
70+
- Very complex SVG files with thousands of elements may require additional processing time
71+
- Some optimization options might affect specific SVG features (test thoroughly before use)
72+
- The tool preserves the main visual output but may remove accessibility features (like title/desc tags) if selected
73+
74+
## Resources
75+
76+
- [MDN SVG Documentation](https://developer.mozilla.org/en-US/docs/Web/SVG)
77+
- [SVG Optimization Guidelines](https://www.w3.org/TR/SVG11/)
78+
- [SVGO - SVG Optimizer Library](https://github.com/svg/svgo) (for reference)

0 commit comments

Comments
 (0)