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
55 changes: 53 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,53 @@
# CAPTCHA-Validator
This project demonstrates how you can implement CAPTCHA Validation in your website using HTML, CSS and JavaScript.
# CAPTCHA Validator 🔐

A lightweight and responsive CAPTCHA validation project built with **HTML**, **CSS**, and **JavaScript**. This project generates a random CAPTCHA string, validates user input, and provides real-time feedback — helping protect your forms from bots.

---

## ✨ Features

- 🎨 Custom CAPTCHA canvas rendering
- 🔁 CAPTCHA refresh functionality
- 🧠 Real-time input validation (on button click or Enter key)
- 📱 Fully responsive design (mobile/tablet/desktop)
- 🎯 Clean and modern UI with Roboto fonts
- ✅ Clear feedback for correct/incorrect inputs
---

## 🚀 How to Run

1. **Clone the Repository**

git clone https://github.com/your-username/captcha-validator.git
cd captcha-validator
Open in Browser

Just open index.html in any modern browser.

🧩 Project Structure

📁 captcha-validator/
├── index.html # Main HTML page
├── styles.css # Styling with responsive media queries
├── script.js # CAPTCHA logic and interaction
└── README.md # Project documentation

📱 Responsive Design
Mobile-first approach
Fluid resizing for tablets and desktops
Buttons and input boxes adjust automatically

💡 Use Cases
Login or Sign-Up forms
Contact pages
Basic form submissions

🛠️ Tech Stack
HTML5
CSS3
JavaScript

🙌 Author
Abhinash Rao
GitHub | LinkedIn
31 changes: 21 additions & 10 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
<!DOCTYPE html>
<html>
<html lang="en">

<head>
<link rel="stylesheet" type="text/css" href="styles.css">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CAPTCHA Validator</title>
<link rel="stylesheet" href="styles.css" />
</head>

<body>
<div class="center">
<h1 id="captchaHeading">Captcha Validator Using HTML, CSS and JavaScript</h1>
<div id="captchaBackground">
<canvas id="captcha">captcha text</canvas>
<input id="textBox" type="text" name="text">
<div id="buttons">
<input id="submitButton" type="submit">
<button id="refreshButton" type="submit">Refresh</button>

<form id="captchaForm" onsubmit="return false;">
<div id="captchaBackground" role="region" aria-labelledby="captchaHeading">
<canvas id="captcha" aria-label="Generated CAPTCHA image">captcha text</canvas>

<label for="textBox" style="color:white; margin-top: 10px;">Enter the CAPTCHA</label>
<input id="textBox" type="text" name="text" aria-label="Enter CAPTCHA" autocomplete="off" autofocus />

<div id="buttons">
<input id="submitButton" type="submit" value="Submit" aria-label="Submit CAPTCHA" />
<button id="refreshButton" type="button" aria-label="Refresh CAPTCHA">Refresh</button>
</div>

<span id="output" aria-live="polite"></span>
</div>
<span id="output"></span>
</div>
</form>
</div>

<script src="script.js"></script>
</body>

Expand Down
135 changes: 83 additions & 52 deletions script.js
Original file line number Diff line number Diff line change
@@ -1,76 +1,107 @@

// document.querySelector() is used to select an element from the document using its ID
let captchaText = document.getElementById('captcha');
var ctx = captchaText.getContext("2d");
let ctx = captchaText.getContext("2d");
ctx.font = "30px Roboto";
ctx.fillStyle = "#08e5ff";


let userText = document.getElementById('textBox');
let submitButton = document.getElementById('submitButton');
let output = document.getElementById('output');
let refreshButton = document.getElementById('refreshButton');

let alphaNums = [
'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9'
];

let c = "";

function generateCaptcha() {
userText.value = "";
output.innerHTML = "";
ctx.clearRect(0, 0, captchaText.width, captchaText.height);

let captchaArray = [];
for (let i = 0; i < 7; i++) {
captchaArray.push(alphaNums[Math.floor(Math.random() * alphaNums.length)]);
}

// alphaNums contains the characters with which you want to create the CAPTCHA
let alphaNums = ['A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9'];
c = captchaArray.join('');
ctx.fillText(c, captchaText.width / 4, captchaText.height / 2);

// Add random lines
for (let i = 0; i < 5; i++) {
ctx.beginPath();
ctx.moveTo(Math.random() * captchaText.width, Math.random() * captchaText.height);
ctx.lineTo(Math.random() * captchaText.width, Math.random() * captchaText.height);
ctx.strokeStyle = getRandomColor();
ctx.lineWidth = 1;
ctx.stroke();
}

// This loop generates a random string of 7 characters using alphaNums
// Further this string is displayed as a CAPTCHA
let emptyArr = [];
for (let i = 1; i <= 7; i++) {
emptyArr.push(alphaNums[Math.floor(Math.random() * alphaNums.length)]);
// Add random dots
for (let i = 0; i < 30; i++) {
ctx.beginPath();
ctx.arc(Math.random() * captchaText.width, Math.random() * captchaText.height, 1.5, 0, 2 * Math.PI);
ctx.fillStyle = getRandomColor();
ctx.fill();
}
}

function getRandomColor() {
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
var c = emptyArr.join('');
ctx.fillText(emptyArr.join(''), captchaText.width/4, captchaText.height/2);

// This event listener is stimulated whenever the user press the "Enter" button
// "Correct!" or "Incorrect, please try again!" message is
// displayed after validating the input text with CAPTCHA
userText.addEventListener('keyup', function(e) {
// Initial CAPTCHA render
generateCaptcha();

// Event: Press Enter
userText.addEventListener('keyup', function (e) {
if (e.key === 'Enter') {
if (userText.value === c) {
output.classList.add("correctCaptcha");
output.innerHTML = "Correct!";
} else {
output.classList.add("incorrectCaptcha");
output.innerHTML = "Incorrect, please try again!";
}
checkCaptcha();
}
});

// This event listener is stimulated whenever the user clicks the "Submit" button
// "Correct!" or "Incorrect, please try again!" message is
// displayed after validating the input text with CAPTCHA
submitButton.addEventListener('click', function() {
// Event: Submit
submitButton.addEventListener('click', function () {
checkCaptcha();
});

// Event: Refresh
refreshButton.addEventListener('click', function () {
generateCaptcha();
});

// Function to validate CAPTCHA
function checkCaptcha() {
if (userText.value === c) {
output.classList.remove("incorrectCaptcha");
output.classList.add("correctCaptcha");
output.innerHTML = "Correct!";
output.innerHTML = "✅ Correct!";

userText.disabled = true;
submitButton.disabled = true;
refreshButton.disabled = true;

setTimeout(() => {
alert("CAPTCHA verified! Proceeding...");
// window.location.href = "success.html"; // Uncomment to redirect
}, 2000);
} else {
output.classList.remove("correctCaptcha");
output.classList.add("incorrectCaptcha");
output.innerHTML = "Incorrect, please try again!";
output.innerHTML = "Incorrect, please try again!";
}
});
}

// This event listener is stimulated whenever the user press the "Refresh" button
// A new random CAPTCHA is generated and displayed after the user clicks the "Refresh" button
refreshButton.addEventListener('click', function() {
userText.value = "";
let refreshArr = [];
for (let j = 1; j <= 7; j++) {
refreshArr.push(alphaNums[Math.floor(Math.random() * alphaNums.length)]);
}
ctx.clearRect(0, 0, captchaText.width, captchaText.height);
c = refreshArr.join('');
ctx.fillText(refreshArr.join(''),captchaText.width/4, captchaText.height/2);
output.innerHTML = "";
});
59 changes: 57 additions & 2 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ body {
align-items: center;
justify-content: center;
flex-direction: column;
padding: 1rem;
gap: 1rem;
border-radius: 10px;
}

#captchaHeading {
color: white;
text-align: center;
margin: 1em;
}

#captcha {
Expand All @@ -35,27 +40,77 @@ body {
}

#submitButton {
margin-top: 2em;
margin-bottom: 2em;
background-color: #08e5ff;
border: 0px;
font-weight: bold;
padding: 0.5em 1em;
cursor: pointer;
border-radius: 5px;
}

#refreshButton {
background-color: #08e5ff;
border: 0px;
font-weight: bold;
padding: 0.5em 1em;
cursor: pointer;
border-radius: 5px;
margin-left: 0.5em;
}

#textBox {
height: 25px;
width: 80%;
padding: 0.3em;
border-radius: 5px;
border: 1px solid #ccc;
}

.incorrectCaptcha {
color: #FF0000;
font-weight: bold;
margin-top: 0.5em;
}

.correctCaptcha {
color: #7FFF00;
font-weight: bold;
margin-top: 0.5em;
}

#buttons {
display: flex;
gap: 0.5em;
margin-top: 1em;
}

/* 📱 Responsive Design for Mobile */
@media screen and (max-width: 480px) {
#captchaBackground {
width: 90%;
height: auto;
padding: 1rem;
}

#captcha {
width: 100%;
height: 60px;
}

#textBox {
width: 90%;
margin: 1em 0;
}

#submitButton,
#refreshButton {
width: 90%;
padding: 0.5em;
margin-bottom: 1em;
}

#buttons {
flex-direction: column;
align-items: center;
}
}