I'm currently in the preparatory stage of a new project which basically consists in creating an online PDF editor. The tricky part on the client-side is to exactly get the coordinates of HTML boxes in the preview page. Basically, a user can move text boxes and images along a grid. This grid must have necessarily proportional dimensions which should be calculated by starting from various PDF page formats. Ironically, converting centimeters and millimeters into pixels is not that difficult. The heavy-lifting will be made by a PHP library on the server-side, but to make it work properly you should pass exact values to the PHP script via AJAX. So the very first step is to get the exact coordinates of a box that can be dragged inside a canvas.

We'll start with the following markup:

<div id="canvas">
	<div id="box"></div>

<div id="results"></div>​

The important elements here are the first two. The third element is just a console where to output our coordinates. To position our box, we'll use contextual positioning. This is a crucial aspect of our test. Due to the inner nature of jQuery's positioning methods, the best thing we can do is to explicitly declare our parent element as the context for the child box:

#canvas {
    width: 500px;
    height: 400px;
    background: #ccc;
    position: relative;
    margin: 2em auto;

#box {
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    height: 100px;
    background: green;
    cursor: move;

Element's dimensions will be replaced with the proper dimensions when I'll start the testing phase. For now we can use arbitrary dimensions.

We're going to use the draggable object of the jQuery UI library. This object has two important methods:

  1. start() – a user starts dragging the object around
  2. stop() – a users stops dragging the object around

We can get our coordinates both when the user starts dragging and when he stops dragging. Here's the code:

var coordinates = function(element) {
    element = $(element);
    var top = element.position().top;
    var left = element.position().left;
    $('#results').text('X: ' + left + ' ' + 'Y: ' + top);

    start: function() {
    stop: function() {

position() works relatively to the parent's boundaries, whereas offset() starts from the whole document. Since we've used CSS contextual positioning, this is the perfect use case for the first method.

You can see the demo below.


Live demo