Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML5

Easy to Use AntiBot

4.43/5 (4 votes)
28 Sep 2011CPOL2 min read 24K   266  
AntiBot control using HTML5 rotating feature

Introduction

This is just a tip for those who are sick and tired of struggling with the "string-like" Anti-Bots and who don't want users of their Web pages to experience the same feelings.

Background

The idea of using a kind of a slider control to rotate an image (in order to prove you are human) is not new. I got it from one of my students in 2008 and he had found it somewhere in the net.

But the implementation was based on jQuery or some other JavaScript library. Hmmm, learning jQuery requires some effort. I don't like wonders taken out of black box, so I stopped thinking of the trick.

Now, that HTML5 gives us new possibilities, I thought I should implement the idea in a form of a control. Later, I plan to make a real ASP.NET Custom Control with embedded JavaScript. So far, the code is pure HTML and JavaScript, but it does the job.

Using the Code

The most difficult part of solution is:

  • How to scale an arbitrary image and place it at the desired location of a canvas
  • How to rotate image at the desired angle
  • How to track this angle value, and use it as result of a test

The following fragment solves a part of the problem:

JavaScript
hdc.clearRect(0, 0, canvasWidth, canvasHeight);
hdc.save();
hdc.translate(cx, cy);
hdc.rotate(-angle);
hdc.translate(-cx, -cy);
hdc.drawImage(img, posX, posY, img.width, img.height);
hdc.restore();

The hdc variable is a device context of a canvas-element. It is declared at the global scope and created in onload event handler, as recommended by the HTML5 tutorials.

JavaScript
var canvasImg = document.getElementById("canvasImg");
hdc = canvasImg.getContext("2d");

The important details of the context manipulations are:

  • Saving current state of the context
  • Translating (shifting) the context at the desired location (cx, cy) within the canvas.
  • Rotating is trivial, but the sign of the angle should be negative (if you want the rotation direction to coincide with the Math counter-clockwise-positive-rule)
  • Translating the context back (-cx, -cy)
  • Drawing the image at the position (posX, posY) that must be properly calculated beforehand
  • Restoring the context to its initial state

Scaling the image and position calculation is done once (after image load is finished). The left-top corner of the image should be biased relative to the center of the canvas. The value of this shift must be half the size of the image.

JavaScript
posX = cx - img.width / 2;
posY = cy - img.height / 2;

The following function shows all the details of scaling and positioning calculations. This function is called in response to the image onload event (img.onload = Scale;).

JavaScript
function Scale()
{
  canvasWidth = canvasImg.width;
  canvasHeight = canvasImg.height;
            
  var 
    dx = img.width - canvasWidth,
    dy = img.height - canvasHeight;
         
  if (dx >= 0 || dy >= 0)
  {
    var d = 0.75 * (dx > dy ? canvasWidth / img.width : canvasHeight / img.height);
    img.width *= d;
    img.height *= d; 
  }
  cx = canvasWidth / 2;
  cy = canvasHeight / 2;
  posX = cx - img.width / 2;
  posY = cy - img.height / 2;
  factor = 2 * Math.abs(startAngle) / slider.offsetWidth;
  Draw();
} 

Points of Interest

I did not know that HTML5 has a control with a slider functionality, so a hand-made slider is created here. If you find the whole control useful, then maybe it's worth replacing the slider with a standard one.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)