#image-rotator {
max-width: 950px;
margin: 20px auto;
padding: 22px;
background: #fff;
border: 1px solid #ddd;
border-radius: 12px;
font-family: Arial, sans-serif;
color: #222;
box-sizing: border-box;
}
#image-rotator * { box-sizing: border-box; }
#image-rotator h2 {
text-align: center;
margin: 0 0 20px;
color: #222;
}
#image-rotator .upload-area {
border: 2px dashed #777;
border-radius: 10px;
padding: 25px;
text-align: center;
background: #f8faff;
margin-bottom: 18px;
}
#image-rotator input[type=file] {
max-width: 100%;
margin-top: 12px;
}
#image-rotator .preview {
text-align: center;
margin: 20px 0;
min-height: 80px;
}
#image-rotator canvas {
max-width: 100%;
height: auto;
border: 1px solid #ddd;
border-radius: 8px;
background:
linear-gradient(45deg,#eee 25%,transparent 25%),
linear-gradient(-45deg,#eee 25%,transparent 25%),
linear-gradient(45deg,transparent 75%,#eee 75%),
linear-gradient(-45deg,transparent 75%,#eee 75%);
background-size: 20px 20px;
background-position: 0 0,0 10px,10px -10px,-10px 0;
}
#image-rotator .section-title {
margin: 22px 0 12px;
font-weight: bold;
font-size: 17px;
}
#image-rotator .button-grid {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(75px,1fr));
gap: 9px;
}
#image-rotator button {
border: 0;
padding: 11px 7px;
border-radius: 7px;
background: #1769d2;
color: white;
cursor: pointer;
font-size: 14px;
font-weight: 600;
}
#image-rotator button:hover {
background: #084da8;
}
#image-rotator button:disabled {
opacity: .45;
cursor: not-allowed;
}
#image-rotator .action-buttons {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
margin-top: 20px;
}
#image-rotator .action-buttons button {
padding: 12px 20px;
}
#image-rotator .download { background: #16833d; }
#image-rotator .reset { background: #555; }
#image-rotator .status {
text-align: center;
margin-top: 12px;
color: #444;
font-size: 14px;
}
#image-rotator .degree-buttons {
max-height: 260px;
overflow-y: auto;
padding: 3px;
}
#image-rotator .note {
font-size: 13px;
color: #666;
line-height: 1.5;
margin-top: 16px;
}
Image Rotator Tool
Upload Your Image
Select a JPG, PNG, WEBP or BMP image
Your image preview will appear here.
Quick Rotation
Rotate by Every Degree (1°–360°)
Please upload an image to begin.
Note: Images are exported as PNG to avoid additional JPG compression. Rotating by angles other than 90°, 180° and 270° requires resampling pixels, so some interpolation differences may occur.
(() => { const root = document.getElementById("image-rotator"); const fileInput = root.querySelector("#rotatorFile"); const canvas = root.querySelector("#rotatorCanvas"); const ctx = canvas.getContext("2d"); const placeholder = root.querySelector("#rotatorPlaceholder"); const status = root.querySelector("#rotatorStatus"); const downloadBtn = root.querySelector("#downloadRotation"); const resetBtn = root.querySelector("#resetRotation"); let originalImage = null; let currentAngle = 0; const degreeButtons = root.querySelector("#degreeButtons"); // Create a separate button for every degree from 1 to 360. for (let degree = 1; degree { btn.disabled = false; }); status.textContent = "Image uploaded successfully."; URL.revokeObjectURL(url); }; img.onerror = function() { status.textContent = "Could not load this image."; URL.revokeObjectURL(url); }; img.src = url; }); root.addEventListener("click", function(event) { const btn = event.target.closest(".rotate"); if (!btn || btn.disabled || !originalImage) return; // Each button rotates the original image to its selected angle. currentAngle = Number(btn.dataset.angle); drawImage(); }); resetBtn.addEventListener("click", function() { if (!originalImage) return; currentAngle = 0; drawImage(); status.textContent = "Image rotation reset to 0°."; }); downloadBtn.addEventListener("click", function() { if (!originalImage) return; canvas.toBlob(function(blob) { if (!blob) { status.textContent = "Unable to create PNG. Please try again."; return; } const link = document.createElement("a"); const url = URL.createObjectURL(blob); link.href = url; link.download = "rotated-image.png"; link.click(); setTimeout(() => URL.revokeObjectURL(url), 1000); status.textContent = "Your rotated PNG image is ready."; }, "image/png"); }); })();