Image Styles Tool
Drag & drop images here or click to browse
No images uploaded yet
Upload up to 4 images to start editing
Image Editor
Tools
Export
<!DOCTYPE html><html lang="en">
<head> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Styles Tool | Multi Tool Spot</title>
<style>
:root {
--primary-color: #6c5ce7;
--secondary-color: #a29bfe;
--dark-bg: #2d3436;
--darker-bg: #1e272e;
--light-text: #f5f6fa;
--muted-text: #dfe6e9;
--error-color: #ff7675;
--success-color: #55efc4;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background-color: var(--dark-bg);
color: var(--light-text);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
h1 {
text-align: center;
margin-bottom: 30px;
color: var(--secondary-color);
}
.tool-container {
background-color: var(--darker-bg);
border-radius: 10px;
padding: 20px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
}
.upload-section {
border: 2px dashed var(--secondary-color);
border-radius: 8px;
padding: 30px;
text-align: center;
margin-bottom: 20px;
transition: all 0.3s;
}
.upload-section:hover {
background-color: rgba(162, 155, 254, 0.1);
}
.upload-section.drag-over {
background-color: rgba(162, 155, 254, 0.2);
border-color: var(--primary-color);
}
.upload-icon {
font-size: 48px;
color: var(--secondary-color);
margin-bottom: 15px;
}
.upload-text {
margin-bottom: 20px;
}
.upload-btn {
background-color: var(--primary-color);
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
transition: background-color 0.3s;
}
.upload-btn:hover {
background-color: #5649d1;
}
#file-input {
display: none;
}
.image-preview-container {
display: flex;
flex-wrap: wrap;
gap: 15px;
margin-bottom: 20px;
}
.image-preview-item {
position: relative;
width: calc(25% - 15px);
border-radius: 8px;
overflow: hidden;
background-color: rgba(255, 255, 255, 0.05);
}
@media (max-width: 900px) {
.image-preview-item {
width: calc(33.33% - 15px);
}
}
@media (max-width: 600px) {
.image-preview-item {
width: calc(50% - 15px);
}
}
.preview-image {
width: 100%;
height: 150px;
object-fit: cover;
display: block;
}
.preview-actions {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
padding: 8px;
display: flex;
justify-content: space-between;
}
.preview-btn {
background: none;
border: none;
color: white;
cursor: pointer;
font-size: 14px;
padding: 5px;
}
.preview-btn:hover {
color: var(--secondary-color);
}
.editor-container {
display: none;
margin-top: 30px;
}
.editor-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.editor-title {
font-size: 20px;
color: var(--secondary-color);
}
.editor-close {
background: none;
border: none;
color: var(--light-text);
font-size: 24px;
cursor: pointer;
}
.editor-main {
display: flex;
flex-direction: column;
gap: 20px;
}
@media (min-width: 768px) {
.editor-main {
flex-direction: row;
}
}
.canvas-container {
flex: 1;
position: relative;
border: 2px solid var(--darker-bg);
border-radius: 8px;
overflow: hidden;
min-height: 300px;
background-color: var(--dark-bg);
}
#editor-canvas {
max-width: 100%;
display: block;
margin: 0 auto;
}
.toolbox {
width: 100%;
max-width: 300px;
background-color: var(--darker-bg);
border-radius: 8px;
padding: 15px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
}
@media (min-width: 768px) {
.toolbox {
width: 300px;
}
}
.tool-section {
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.tool-section:last-child {
border-bottom: none;
margin-bottom: 0;
padding-bottom: 0;
}
.tool-title {
font-size: 16px;
margin-bottom: 10px;
color: var(--secondary-color);
}
.tool-options {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.tool-btn {
background-color: var(--dark-bg);
border: 1px solid var(--secondary-color);
color: var(--light-text);
padding: 8px 12px;
border-radius: 5px;
cursor: pointer;
transition: all 0.3s;
}
.tool-btn:hover {
background-color: var(--primary-color);
}
.tool-btn.active {
background-color: var(--primary-color);
border-color: var(--primary-color);
}
.emoji-picker {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.emoji-option {
font-size: 20px;
cursor: pointer;
transition: transform 0.2s;
}
.emoji-option:hover {
transform: scale(1.2);
}
.form-group {
margin-bottom: 15px;
}
.form-label {
display: block;
margin-bottom: 5px;
font-size: 14px;
}
.form-control {
width: 100%;
padding: 8px 12px;
background-color: var(--dark-bg);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 5px;
color: var(--light-text);
}
.color-picker {
width: 100%;
height: 40px;
border: none;
cursor: pointer;
background: transparent;
}
.range-control {
width: 100%;
}
.download-btn {
background-color: var(--success-color);
color: var(--darker-bg);
border: none;
padding: 12px 20px;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
width: 100%;
transition: background-color 0.3s;
}
.download-btn:hover {
background-color: #00b894;
}
.error-message {
color: var(--error-color);
margin-top: 5px;
font-size: 13px;
display: none;
}
.active-element {
position: absolute;
border: 2px dashed var(--primary-color);
resize: both;
overflow: hidden;
cursor: move;
}
.active-element .element-content {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.active-element .resize-handle {
position: absolute;
width: 10px;
height: 10px;
background-color: var(--primary-color);
right: 0;
bottom: 0;
cursor: nwse-resize;
}
.empty-state {
text-align: center;
padding: 40px 20px;
color: var(--muted-text);
}
.empty-icon {
font-size: 60px;
margin-bottom: 20px;
opacity: 0.5;
}
</style>
</head><body>
<div class="container">
<h1>Image Styles Tool</h1>
<div class="tool-container">
<div class="upload-section" id="drop-area">
<div class="upload-icon">📁</div>
<p class="upload-text">Drag & drop images here or click to browse</p>
<button class="upload-btn" id="upload-btn">Select Images</button>
<input type="file" id="file-input" accept="image/*" multiple>
<p class="error-message" id="file-error">Please select up to 4 images (JPG, PNG, GIF)</p>
</div>
<div class="image-preview-container" id="preview-container">
<div class="empty-state" id="empty-state">
<div class="empty-icon">🖼️</div>
<p>No images uploaded yet</p>
<p>Upload up to 4 images to start editing</p>
</div>
</div>
<div class="editor-container" id="editor-container">
<div class="editor-header">
<h2 class="editor-title">Image Editor</h2>
<button class="editor-close" id="editor-close">×</button>
</div>
<div class="editor-main">
<div class="canvas-container" id="canvas-container">
<canvas id="editor-canvas"></canvas>
</div>
<div class="toolbox">
<div class="tool-section">
<h3 class="tool-title">Tools</h3>
<div class="tool-options">
<button class="tool-btn" id="move-btn">Move</button>
<button class="tool-btn" id="crop-btn">Crop</button>
<button class="tool-btn" id="text-btn">Text</button>
<button class="tool-btn" id="emoji-btn">Emoji</button>
</div>
</div>
<div class="tool-section" id="text-tool-section" style="display: none;">
<h3 class="tool-title">Text Options</h3>
<div class="form-group">
<label class="form-label" for="text-input">Text Content</label>
<input type="text" id="text-input" class="form-control" placeholder="Enter your text">
</div>
<div class="form-group">
<label class="form-label" for="font-size">Font Size</label>
<input type="range" id="font-size" class="range-control" min="10" max="72" value="24">
<span id="font-size-value">24px</span>
</div>
<div class="form-group">
<label class="form-label" for="text-color">Text Color</label>
<input type="color" id="text-color" class="color-picker" value="#ffffff">
</div>
<button class="tool-btn" id="add-text-btn">Add Text</button>
</div>
<div class="tool-section" id="emoji-tool-section" style="display: none;">
<h3 class="tool-title">Emoji Options</h3>
<div class="emoji-picker">
<span class="emoji-option">😀</span>
<span class="emoji-option">😂</span>
<span class="emoji-option">😍</span>
<span class="emoji-option">🤔</span>
<span class="emoji-option">😎</span>
<span class="emoji-option">🥳</span>
<span class="emoji-option">😊</span>
<span class="emoji-option">🙄</span>
<span class="emoji-option">🤯</span>
<span class="emoji-option">🥺</span>
<span class="emoji-option">❤️</span>
<span class="emoji-option">👍</span>
<span class="emoji-option">👎</span>
<span class="emoji-option">✨</span>
<span class="emoji-option">🔥</span>
<span class="emoji-option">🎉</span>
<span class="emoji-option">💯</span>
<span class="emoji-option">👀</span>
<span class="emoji-option">🤷</span>
<span class="emoji-option">🍕</span>
</div>
<div class="form-group">
<label class="form-label" for="emoji-size">Emoji Size</label>
<input type="range" id="emoji-size" class="range-control" min="20" max="100" value="40">
<span id="emoji-size-value">40px</span>
</div>
</div>
<div class="tool-section" id="crop-tool-section" style="display: none;">
<h3 class="tool-title">Crop Options</h3>
<div class="form-group">
<label class="form-label" for="crop-width">Width</label>
<input type="number" id="crop-width" class="form-control" placeholder="Width in px">
</div>
<div class="form-group">
<label class="form-label" for="crop-height">Height</label>
<input type="number" id="crop-height" class="form-control" placeholder="Height in px">
</div>
<button class="tool-btn" id="apply-crop-btn">Apply Crop</button>
</div>
<div class="tool-section">
<h3 class="tool-title">Export</h3>
<button class="download-btn" id="download-btn">Download Image</button>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// DOM Elements
const fileInput = document.getElementById('file-input');
const uploadBtn = document.getElementById('upload-btn');
const dropArea = document.getElementById('drop-area');
const previewContainer = document.getElementById('preview-container');
const emptyState = document.getElementById('empty-state');
const editorContainer = document.getElementById('editor-container');
const editorClose = document.getElementById('editor-close');
const canvas = document.getElementById('editor-canvas');
const ctx = canvas.getContext('2d');
const fileError = document.getElementById('file-error');
// Tool buttons
const moveBtn = document.getElementById('move-btn');
const cropBtn = document.getElementById('crop-btn');
const textBtn = document.getElementById('text-btn');
const emojiBtn = document.getElementById('emoji-btn');
// Tool sections
const textToolSection = document.getElementById('text-tool-section');
const emojiToolSection = document.getElementById('emoji-tool-section');
const cropToolSection = document.getElementById('crop-tool-section');
// Text tool elements
const textInput = document.getElementById('text-input');
const fontSize = document.getElementById('font-size');
const fontSizeValue = document.getElementById('font-size-value');
const textColor = document.getElementById('text-color');
const addTextBtn = document.getElementById('add-text-btn');
// Emoji tool elements
const emojiOptions = document.querySelectorAll('.emoji-option');
const emojiSize = document.getElementById('emoji-size');
const emojiSizeValue = document.getElementById('emoji-size-value');
// Crop tool elements
const cropWidth = document.getElementById('crop-width');
const cropHeight = document.getElementById('crop-height');
const applyCropBtn = document.getElementById('apply-crop-btn');
// Download button
const downloadBtn = document.getElementById('download-btn');
// State variables
let uploadedImages = [];
let currentImageIndex = -1;
let activeTool = 'move';
let activeElement = null;
let isDragging = false;
let startX, startY;
let startWidth, startHeight;
let startElementX, startElementY;
// Initialize
setupEventListeners();
function setupEventListeners() {
// File upload
uploadBtn.addEventListener('click', () => fileInput.click());
fileInput.addEventListener('change', handleFileSelect);
// Drag and drop
dropArea.addEventListener('dragover', handleDragOver);
dropArea.addEventListener('dragleave', handleDragLeave);
dropArea.addEventListener('drop', handleDrop);
// Editor controls
editorClose.addEventListener('click', closeEditor);
// Tool buttons
moveBtn.addEventListener('click', () => setActiveTool('move'));
cropBtn.addEventListener('click', () => setActiveTool('crop'));
textBtn.addEventListener('click', () => setActiveTool('text'));
emojiBtn.addEventListener('click', () => setActiveTool('emoji'));
// Text tool
fontSize.addEventListener('input', () => {
fontSizeValue.textContent = `${fontSize.value}px`;
});
addTextBtn.addEventListener('click', addTextToCanvas);
// Emoji tool
emojiSize.addEventListener('input', () => {
emojiSizeValue.textContent = `${emojiSize.value}px`;
});
emojiOptions.forEach(emoji => {
emoji.addEventListener('click', () => addEmojiToCanvas(emoji.textContent));
});
// Crop tool
applyCropBtn.addEventListener('click', applyCrop);
// Download
downloadBtn.addEventListener('click', downloadImage);
// Canvas interactions
canvas.addEventListener('mousedown', startDrag);
canvas.addEventListener('mousemove', handleDrag);
canvas.addEventListener('mouseup', endDrag);
canvas.addEventListener('mouseleave', endDrag);
}
function handleFileSelect(e) {
const files = e.target.files || (e.dataTransfer ? e.dataTransfer.files : []);
handleFiles(files);
}
function handleDragOver(e) {
e.preventDefault();
e.stopPropagation();
dropArea.classList.add('drag-over');
}
function handleDragLeave(e) {
e.preventDefault();
e.stopPropagation();
dropArea.classList.remove('drag-over');
}
function handleDrop(e) {
e.preventDefault();
e.stopPropagation();
dropArea.classList.remove('drag-over');
handleFiles(e.dataTransfer.files);
}
function handleFiles(files) {
fileError.style.display = 'none';
if (files.length === 0) return;
// Filter and limit to 4 images
const imageFiles = Array.from(files)
.filter(file => file.type.match('image.*'))
.slice(0, 4 - uploadedImages.length);
if (imageFiles.length === 0) {
fileError.style.display = 'block';
return;
}
// Process each image
imageFiles.forEach(file => {
const reader = new FileReader();
reader.onload = function(e) {
const img = new Image();
img.onload = function() {
uploadedImages.push({
file: file,
element: img,
url: e.target.result
});
updatePreview();
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
});
}
function updatePreview() {
if (uploadedImages.length === 0) {
emptyState.style.display = 'block';
return;
}
emptyState.style.display = 'none';
previewContainer.innerHTML = '';
uploadedImages.forEach((image, index) => {
const previewItem = document.createElement('div');
previewItem.className = 'image-preview-item';
const img = document.createElement('img');
img.className = 'preview-image';
img.src = image.url;
img.alt = `Preview ${index + 1}`;
const previewActions = document.createElement('div');
previewActions.className = 'preview-actions';
const editBtn = document.createElement('button');
editBtn.className = 'preview-btn';
editBtn.innerHTML = '✏️ Edit';
editBtn.addEventListener('click', () => openEditor(index));
const deleteBtn = document.createElement('button');
deleteBtn.className = 'preview-btn';
deleteBtn.innerHTML = '🗑️ Delete';
deleteBtn.addEventListener('click', () => deleteImage(index));
previewActions.appendChild(editBtn);
previewActions.appendChild(deleteBtn);
previewItem.appendChild(img);
previewItem.appendChild(previewActions);
previewContainer.appendChild(previewItem);
});
}
function deleteImage(index) {
uploadedImages.splice(index, 1);
updatePreview();
if (currentImageIndex === index) {
closeEditor();
} else if (currentImageIndex > index) {
currentImageIndex--;
}
}
function openEditor(index) {
currentImageIndex = index;
editorContainer.style.display = 'block';
// Initialize canvas with the selected image
const img = uploadedImages[index].element;
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
// Reset tools
setActiveTool('move');
}
function closeEditor() {
editorContainer.style.display = 'none';
currentImageIndex = -1;
// Clear any active elements
if (activeElement) {
activeElement.remove();
activeElement = null;
}
}
function setActiveTool(tool) {
activeTool = tool;
// Update button states
moveBtn.classList.remove('active');
cropBtn.classList.remove('active');
textBtn.classList.remove('active');
emojiBtn.classList.remove('active');
// Hide all tool sections
textToolSection.style.display = 'none';
emojiToolSection.style.display = 'none';
cropToolSection.style.display = 'none';
// Activate selected tool
switch (tool) {
case 'move':
moveBtn.classList.add('active');
break;
case 'crop':
cropBtn.classList.add('active');
cropToolSection.style.display = 'block';
break;
case 'text':
textBtn.classList.add('active');
textToolSection.style.display = 'block';
break;
case 'emoji':
emojiBtn.classList.add('active');
emojiToolSection.style.display = 'block';
break;
}
}
function addTextToCanvas() {
const text = textInput.value.trim();
if (!text) return;
const element = document.createElement('div');
element.className = 'active-element';
element.style.width = '200px';
element.style.height = '50px';
element.style.left = '50px';
element.style.top = '50px';
const content = document.createElement('div');
content.className = 'element-content';
content.textContent = text;
content.style.color = textColor.value;
content.style.fontSize = `${fontSize.value}px`;
const resizeHandle = document.createElement('div');
resizeHandle.className = 'resize-handle';
element.appendChild(content);
element.appendChild(resizeHandle);
document.getElementById('canvas-container').appendChild(element);
// Make draggable and resizable
setupElementInteractions(element);
// Clear input
textInput.value = '';
}
function addEmojiToCanvas(emoji) {
const element = document.createElement('div');
element.className = 'active-element';
element.style.width = `${emojiSize.value}px`;
element.style.height = `${emojiSize.value}px`;
element.style.left = '50px';
element.style.top = '50px';
const content = document.createElement('div');
content.className = 'element-content';
content.textContent = emoji;
content.style.fontSize = `${emojiSize.value}px`;
const resizeHandle = document.createElement('div');
resizeHandle.className = 'resize-handle';
element.appendChild(content);
element.appendChild(resizeHandle);
document.getElementById('canvas-container').appendChild(element);
// Make draggable and resizable
setupElementInteractions(element);
}
function setupElementInteractions(element) {
// Clear previous active element
if (activeElement) {
activeElement.classList.remove('active-element');
}
// Set new active element
activeElement = element;
element.classList.add('active-element');
// Focus the element
element.focus();
}
function startDrag(e) {
if (!activeElement || activeTool !== 'move') return;
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// Check if we're clicking on the active element
const elementRect = activeElement.getBoundingClientRect();
if (
x >= elementRect.left - rect.left &&
x <= elementRect.right - rect.left &&
y >= elementRect.top - rect.top &&
y <= elementRect.bottom - rect.top
) {
isDragging = true;
startX = x;
startY = y;
startElementX = parseInt(activeElement.style.left) || 0;
startElementY = parseInt(activeElement.style.top) || 0;
}
}
function handleDrag(e) {
if (!isDragging || !activeElement) return;
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const dx = x - startX;
const dy = y - startY;
activeElement.style.left = `${startElementX + dx}px`;
activeElement.style.top = `${startElementY + dy}px`;
}
function endDrag() {
isDragging = false;
}
function applyCrop() {
const width = parseInt(cropWidth.value);
const height = parseInt(cropHeight.value);
if (!width || !height || width <= 0 || height <= 0) return;
// Create a temporary canvas for cropping
const tempCanvas = document.createElement('canvas');
tempCanvas.width = width;
tempCanvas.height = height;
const tempCtx = tempCanvas.getContext('2d');
// Draw the cropped portion
tempCtx.drawImage(
canvas,
0, 0, width, height,
0, 0, width, height
);
// Resize the main canvas
canvas.width = width;
canvas.height = height;
ctx.drawImage(tempCanvas, 0, 0);
// Clear crop inputs
cropWidth.value = '';
cropHeight.value = '';
}
function downloadImage() {
if (currentImageIndex === -1) return;
// Create a temporary canvas to compose all elements
const tempCanvas = document.createElement('canvas');
tempCanvas.width = canvas.width;
tempCanvas.height = canvas.height;
const tempCtx = tempCanvas.getContext('2d');
// Draw the base image
tempCtx.drawImage(canvas, 0, 0);
// Draw any active elements (text, emoji)
if (activeElement) {
const content = activeElement.querySelector('.element-content');
if (content) {
tempCtx.font = `${content.style.fontSize} sans-serif`;
tempCtx.fillStyle = content.style.color || '#ffffff';
const rect = activeElement.getBoundingClientRect();
const canvasRect = canvas.getBoundingClientRect();
const x = rect.left - canvasRect.left;
const y = rect.top - canvasRect.top;
tempCtx.fillText(content.textContent, x, y + parseInt(content.style.fontSize));
}
}
// Create download link
const link = document.createElement('a');
link.download = `edited-${uploadedImages[currentImageIndex].file.name}`;
link.href = tempCanvas.toDataURL('image/png');
link.click();
}
});
</script>
</body>
</html>