How to Flip and Mirror an Image in JavaScript with CSS Transforms and HTML5 Canvas
Sometimes, we may need to flip a media element in a web app. For example, we may need to flip a video element streaming from a camera to match what we actually see or correct scanned document images that are flipped.
What you’ll build: A browser-based tool that flips or mirrors images horizontally and vertically using three methods — CSS transforms, HTML5 Canvas 2D context, and the Dynamic Web TWAIN SDK for batch document processing.
Key Takeaways
- JavaScript can flip images visually with
CSS scaleX(-1)/scaleY(-1)transforms, or permanently with the HTML5 Canvastranslateandscalemethods. - CSS transforms only change the display — use Canvas
drawImagefollowed bytoDataURLto produce an actual flipped image file you can download or upload. - Dynamic Web TWAIN provides native
Flip(vertical) andMirror(horizontal) methods that can batch-process large volumes of scanned documents in the browser. - Horizontal flipping (mirroring) is the most common use case — correcting selfie-camera previews and fixing scanner orientation errors.
Common Developer Questions
- How do I horizontally flip an image in JavaScript using HTML5 Canvas?
- What is the difference between CSS transform flip and Canvas flip for images?
- How can I batch flip or mirror scanned document images in a web application?
In this article, we are going to talk about three ways to flip an image with JavaScript.
- CSS
- Canvas
- Dynamic Web TWAIN, a document-scanning SDK
Prerequisites
- A modern browser (Chrome, Firefox, or Edge) with HTML5 Canvas support
- Basic knowledge of JavaScript, HTML, and CSS
- Get a 30-day free trial license for Dynamic Web TWAIN if you want to use the SDK-based batch flip method
Set Up an HTML5 Page for Image Flipping
Create a new HTML5 page with the following template and then let’s add the image flipping function to it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flip an Image with JavaScript</title>
<style>
</style>
</head>
<body>
<div class="home">
<h2>Flip an Image</h2>
<button id="flipButton">Flip</button>
</div>
<script>
</script>
</body>
</html>
Add a Direction Selector for Horizontal or Vertical Flip
We can flip an image in two directions: horizontal and vertical. We can add a select element to select which direction to use.
<label>
Direction:
<select id="directionSelect">
<option>Horizontal</option>
<option>Vertical</option>
</select>
</label>
Load an Image File into the Page
Add an input element for selecting files and use a button element to trigger it. The image file will be loaded into an image element.
HTML:
<button id="loadFileButton">Load a File</button>
<input style="display:none;" type="file" id="file" onchange="loadImageFromFile();" accept=".jpg,.jpeg,.png,.bmp" />
<div class="imageContainer">
<img id="image"/>
</div>
<style>
.imageContainer {
overflow: auto;
}
#image {
max-width: 50%;
}
</style>
JavaScript:
function loadImageFromFile(){
let fileInput = document.getElementById("file");
let files = fileInput.files;
if (files.length == 0) {
return;
}
let file = files[0];
fileReader = new FileReader();
fileReader.onload = function(e){
document.getElementById("image").src = e.target.result;
};
fileReader.onerror = function () {
console.warn('oops, something went wrong.');
};
fileReader.readAsDataURL(file);
}
Flip an Image Horizontally or Vertically Using CSS Transforms
We can use the CSS property transform to flip an HTML element like the following:
img.style.transform = "scaleY(-1)"; //flip vertically
img.style.transform = "scaleX(-1)"; //flip horizontally
img.style.transform = "scaleX(-1) scaleY(-1)"; //flip both vertically and horizontally
Here is the code we use in the page to flip the image, which remembers the previous flipping status.
function flipImageWithCSS(){
let img = document.getElementById("image");
if (document.getElementById("directionSelect").selectedIndex == 0) {
if (img.style.transform.indexOf("scaleX") != -1) {
img.style.transform = img.style.transform.replace("scaleX(-1)","");
}else{
img.style.transform = img.style.transform+" scaleX(-1)";
}
}else{
if (img.style.transform.indexOf("scaleY") != -1) {
img.style.transform = img.style.transform.replace("scaleY(-1)","");
}else{
img.style.transform = img.style.transform+" scaleY(-1)";
}
}
}
Flip and Mirror an Image Using HTML5 Canvas 2D Context
HTML5 provides a canvas element which provides a way to manipulate image data. Unlike CSS which only changes the visual effect, we can use it to actually get a flipped image.
-
Add a hidden
canvaselement to the page.<canvas id="canvasHidden"></canvas> <style> #canvasHidden { display: none; } </style> -
Add a
selectelement to select which flipping method to use.<label> Method: <select id="methodSelect"> <option>CSS</option> <option>Canvas</option> </select> </label> -
Flip an image with
canvaswhen the selected method is “Canvas”.let method = document.getElementById("methodSelect").selectedIndex; if (method == 0) { flipImageWithCSS(); }else if (method == 1){ document.getElementById("image").style.transform = ""; flipImageWithCanvas(); }
Details of flipping an image with canvas.
-
Set the canvas’s size to match the image’s size.
const image = document.getElementById("image"); const canvas = document.getElementById("canvasHidden"); canvas.width = image.naturalWidth; canvas.height = image.naturalHeight; -
Get the context of the canvas to perform actions.
const context = canvas.getContext("2d"); -
Translate the
(0,0)to(width,0)and then scale the image using a scaling factor of -1 in the horizontal direction to flip the image horizontally. We can use a similar logic to flip the image vertically.if (document.getElementById("directionSelect").selectedIndex == 0) { context.translate(width, 0); context.scale(-1, 1); }else{ context.translate(0, height); context.scale(1, -1); } -
Use
drawImageto draw the image content.context.drawImage(image, 0, 0); -
Display the flipped image.
document.getElementById("image").src = canvas.toDataURL();
Batch Flip Document Images with Dynamic Web TWAIN
Dynamic Web TWAIN is a document scanning SDK making it possible to scan documents in the browser. It provides various image processing methods. We can use its Flip and Mirror methods to flip an image.
The advantage of using it is that it can be used to batch process a large volume of images as the processing is done using a native process.
Here are the steps to use it:
-
Include Dynamic Web TWAIN in the page.
<script src="https://unpkg.com/dwt@18.4.2/dist/dynamsoft.webtwain.min.js"></script> -
Initialize an instance of Web TWAIN and use it to flip the image. You can apply for its license here.
let DWObject; Dynamsoft.DWT.AutoLoad = false; Dynamsoft.DWT.ProductKey = "LICENSE-KEY"; Dynamsoft.DWT.ResourcesPath = "https://unpkg.com/dwt@18.4.2/dist"; async function flipImageWithWebTWAIN(){ if (!DWObject) { await initDWT(); } DWObject.RemoveAllImages(); let response = await fetch(document.getElementById("image").src); let buffer = await response.arrayBuffer(); DWObject.LoadImageFromBinary(buffer, function(){ if (document.getElementById("directionSelect").selectedIndex == 0) { DWObject.Mirror(0, function(){ //success document.getElementById("image").src = DWObject.GetImageURL(0); }, function(errorCode, errorString){ //fail console.log(errorString); }); }else{ DWObject.Flip(0, function(){ //success document.getElementById("image").src = DWObject.GetImageURL(0); }, function(errorCode, errorString){ //fail console.log(errorString); }); } }, function(errorCode, errorString){ console.log(errorString); }) } function initDWT(){ return new Promise((resolve, reject) => { const title = document.querySelector("h2").innerText; document.querySelector("h2").innerText = "Loading Dynamic Web TWAIN..."; Dynamsoft.DWT.CreateDWTObjectEx( { WebTwainId: 'dwtcontrol' }, function(obj) { DWObject = obj; document.querySelector("h2").innerText = title; resolve(); }, function(err) { console.log(err); document.querySelector("h2").innerText = "Failed to load Dynamic Web TWAIN"; reject(err); } ); }) }
Common Issues and Edge Cases
- Flipped image appears blank or distorted: Ensure the canvas dimensions match
image.naturalWidthandimage.naturalHeight, not the CSS display size. Usingimage.widthreturns the rendered size, which may be scaled down. - CORS errors when calling
canvas.toDataURL(): If the image is loaded from a cross-origin URL, the canvas becomes “tainted” andtoDataURL()throws a security error. Serve images from the same origin or set thecrossOriginattribute on the<img>element before loading. - CSS flip does not persist after download: CSS
transformonly changes the visual rendering. If users need to save or upload the flipped result, use the Canvas method to produce actual pixel data viatoDataURL()ortoBlob().
Source Code
You can find all the code and an online demo in the following repo: