Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/plays/svg-optimizer/COVER_IMAGE_NOTE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Cover Image Placeholder

Please add a `cover.png` file to this directory.

Recommended specifications:
- Format: PNG
- Dimensions: Approximately 800x600 pixels (or similar aspect ratio)
- Content: A representative screenshot or icon for the SVG Optimizer play

You can use a screenshot of the SVG Optimizer interface or create a custom graphic that represents the tool's functionality.
91 changes: 91 additions & 0 deletions src/plays/svg-optimizer/OptimizationPanel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import React from 'react';

function OptimizationPanel({ options, onChange }) {
const handleToggle = (optionKey) => {
onChange({
...options,
[optionKey]: !options[optionKey]
});
};

return (
<div className="svg-optimization-panel">
<h3>Optimization Options</h3>
<div className="svg-options-grid">
<label className="svg-option-item">
<input
checked={options.removeComments}
onChange={() => handleToggle('removeComments')}
type="checkbox"
/>
<span>Remove Comments</span>
</label>

<label className="svg-option-item">
<input
checked={options.removeMetadata}
onChange={() => handleToggle('removeMetadata')}
type="checkbox"
/>
<span>Remove Metadata</span>
</label>

<label className="svg-option-item">
<input
checked={options.removeHiddenElements}
onChange={() => handleToggle('removeHiddenElements')}
type="checkbox"
/>
<span>Remove Hidden Elements</span>
</label>

<label className="svg-option-item">
<input
checked={options.removeEmptyAttributes}
onChange={() => handleToggle('removeEmptyAttributes')}
type="checkbox"
/>
<span>Remove Empty Attributes</span>
</label>

<label className="svg-option-item">
<input
checked={options.minifyColors}
onChange={() => handleToggle('minifyColors')}
type="checkbox"
/>
<span>Minify Colors</span>
</label>

<label className="svg-option-item">
<input
checked={options.removeDefaultAttributes}
onChange={() => handleToggle('removeDefaultAttributes')}
type="checkbox"
/>
<span>Remove Default Values</span>
</label>

<label className="svg-option-item">
<input
checked={options.removeXMLNS}
onChange={() => handleToggle('removeXMLNS')}
type="checkbox"
/>
<span>Remove XMLNS</span>
</label>

<label className="svg-option-item">
<input
checked={options.prettify}
onChange={() => handleToggle('prettify')}
type="checkbox"
/>
<span>Prettify Output</span>
</label>
</div>
</div>
);
}

export default OptimizationPanel;
73 changes: 73 additions & 0 deletions src/plays/svg-optimizer/PreviewPanel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React, { useState } from 'react';

function PreviewPanel({ originalSvg, optimizedSvg }) {
const [activePreview, setActivePreview] = useState('optimized');

const renderSVG = (svgString) => {
if (!svgString) {
return <div className="svg-preview-placeholder">No SVG to preview</div>;
}

try {
return <div dangerouslySetInnerHTML={{ __html: svgString }} />;
} catch (error) {
return <div className="svg-preview-error">Error rendering SVG preview</div>;
}
};

return (
<div className="svg-preview-section">
<div className="svg-preview-header">
<h3>Visual Preview</h3>
<div className="svg-preview-tabs">
<button
className={`svg-tab-btn ${activePreview === 'original' ? 'active' : ''}`}
onClick={() => setActivePreview('original')}
type="button"
>
Original
</button>
<button
className={`svg-tab-btn ${activePreview === 'optimized' ? 'active' : ''}`}
onClick={() => setActivePreview('optimized')}
type="button"
>
Optimized
</button>
<button
className={`svg-tab-btn ${activePreview === 'comparison' ? 'active' : ''}`}
onClick={() => setActivePreview('comparison')}
type="button"
>
Side by Side
</button>
</div>
</div>

<div className="svg-preview-content">
{activePreview === 'original' && (
<div className="svg-preview-box">{renderSVG(originalSvg)}</div>
)}

{activePreview === 'optimized' && (
<div className="svg-preview-box">{renderSVG(optimizedSvg)}</div>
)}

{activePreview === 'comparison' && (
<div className="svg-preview-comparison">
<div className="svg-preview-box">
<h4>Original</h4>
{renderSVG(originalSvg)}
</div>
<div className="svg-preview-box">
<h4>Optimized</h4>
{renderSVG(optimizedSvg)}
</div>
</div>
)}
</div>
</div>
);
}

export default PreviewPanel;
78 changes: 78 additions & 0 deletions src/plays/svg-optimizer/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# SVG Optimizer

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.

## Play Demographic

- Language: js
- Level: Intermediate

## Creator Information

- User: Abhrxdip
- Github Link: https://github.com/Abhrxdip
- Blog:
- Video:

## Implementation Details

This SVG Optimizer is built using React.js with the following features and concepts:

### React Concepts Used:
- **Functional Components**: All components are functional components using modern React syntax
- **React Hooks**:
- `useState` for managing component state (SVG input, optimization options, file sizes)
- `useEffect` for automatically optimizing SVG when input or options change
- **Controlled Inputs**: Text areas and checkboxes are fully controlled components
- **Conditional Rendering**: Error messages, preview modes, and button states render conditionally
- **Component Composition**: Reusable components (OptimizationPanel, PreviewPanel)

### Key Features:
1. **Multiple Input Methods**:
- Paste SVG code directly
- Upload SVG files
- Load sample SVG for testing

2. **Optimization Options**:
- Remove comments
- Remove metadata (title, desc, metadata tags)
- Remove hidden elements
- Remove empty attributes
- Minify colors (hex shortening, named colors to hex)
- Remove default attribute values
- Optional XMLNS removal
- Code prettification

3. **Real-time Processing**:
- Automatic optimization on input change
- Live file size calculation
- Percentage reduction display

4. **Visual Preview**:
- Original SVG preview
- Optimized SVG preview
- Side-by-side comparison view

5. **Export Options**:
- Copy to clipboard
- Download optimized SVG file

### Technical Implementation:
- **Client-side Processing**: All optimization happens in the browser with no backend required
- **File API**: Uses FileReader for handling file uploads
- **Blob API**: Creates downloadable files without server interaction
- **Clipboard API**: Enables one-click copying of optimized code
- **Regular Expressions**: Pattern matching for removing unnecessary SVG elements

## Considerations

- This is a client-side optimizer and doesn't perform advanced path optimization or vector calculations
- Very complex SVG files with thousands of elements may require additional processing time
- Some optimization options might affect specific SVG features (test thoroughly before use)
- The tool preserves the main visual output but may remove accessibility features (like title/desc tags) if selected

## Resources

- [MDN SVG Documentation](https://developer.mozilla.org/en-US/docs/Web/SVG)
- [SVG Optimization Guidelines](https://www.w3.org/TR/SVG11/)
- [SVGO - SVG Optimizer Library](https://github.com/svg/svgo) (for reference)
Loading
Loading