Detecting a jQuery Collision – Part I

The requirements of those running online stores are very diverse. As regards product settings, usually the majority of Magento built-in features can meet expectations of a typical webstore administrator. However, sometimes it is necessary to implement additional functionalities that deviate a little from the standard ones.

One example may be the option of configuring the product's look by a user. Such situation occurs most frequently when selling T-shirts or mugs with applied graphic or materials with prints that can be modified by the user, on the assumption that we offer ready-made templates or provide an option of uploading images. In order to have an original product, buyers often want to be able to set the layout of the print’s content manually. For this purpose it’s necessary to create a functionality enabling the potential buyer to introduce desired changes.

In order for the user to have a free choice, we should implement/add a simple product configurator that can be operated either using a mouse (and a tablet) or using a keypad. If we choose the second solution (i.e. the keypad), which is for various reasons often more attractive to ‘desktop’ users, sooner or later the developer will face the issue of a collision on a surface.

Optimal handling of collisions of 2D objects using JavaScript is an issue not as complex as it may seem. Knowing the basics of HTML5, jQuery and CSS3, we are able to detect collisions of moving objects (namely block elements of, for example, a

type) easily and quite quickly, as well as to implement events required at the moment of their occurrence.

As you will soon see, detecting collisions is not complicated, since it generally boils down to dynamically checking coordinates of subsequent

s on a 2D surface in successive iterations of the main control loop. The real trick is finding the most effective method, one that will not overload the processor and memory excessively while enabling smoothness of animation. This in turn will result in reduction of power use (which is particularly important in case of mobile devices).

The aim of this article is creating a small application enabling the user to control a block moving within a selected field that will contain static objects that block the motion. The pack with all the files can be found here:

collisions.zip

Optimization

The best way to optimize image rendering via a web browser is using hardware acceleration. In practice, this task boils down to offloading CPU and submitting part of calculations to a graphics processing unit (GPU) of the graphics card. However, how to ‘force’ the browser to offload the CPU, since CSS and JavaScript do not refer to GPU by default?

At the moment hardware acceleration is launched, among others, by:

Canvas Drawing,
WebGL 3D Drawing,
CSS3 transitions,
CSS3 3D transforms.

For our purposes, we will adapt the CSS3 3D transforms mechanism. Additionally, we will make use of HTML5 and jQuery (even though jQuery is not one of the fastest libraries, we will use it due to the fact that it is most common among web developers).

Step I – HTML5

Application responsible for detecting collisions will consist of four files:

index.html
styles.css
jquery.min.js (current version of jQuery)
scripts.js

The index.html content is presented below:

html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 <!doctype html> <html> <head> <meta charset="UTF-8"> <title>Collisions</title> <!-- Our Stylesheet --> <link rel="stylesheet" href="./styles.css"> <!-- Nice font : ) --> <link href='http://fonts.googleapis.com/css?family=Open+Sans|Open+Sans+Condensed:300' rel='stylesheet' type='text/css'> <!-- Current version of jQuery --> <script src="./jquery.min.js"></script> <!-- Our JS scripts --> <script src="./scripts.js"></script> </head> <body> <!-- Container --> <div class="container"> <!-- Header --> <header> <h1>How to detect collisions using jQuery and CSS3?</h1> </header> <!-- /Header --> <!-- Collisions Area --> <section class="collisions-area-wrapper"> <!-- Object which you can move --> <div class="obj obj-in-motion"></div> <!-- Object 1 --> <div class="obj static obj-1"></div> <!-- Object 2 --> <div class="obj static obj-2"></div> <!-- Object 3 --> <div class="obj static obj-3"></div> <!-- Object 4 --> <div class="obj static obj-4"></div> <!-- Object 5 --> <div class="obj static obj-5"></div> </section> <!-- /Collisions Area --> </div> <!-- /Container --> </body> </html>

We will skip information on the HTML5 alone, since it falls outside of the scope of our considerations.

For us, the most interesting fragment of the HTML document is the section with ‘collisions-area-wrapper’ class where all activities will take place, that is motion and collisions:

html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <!-- Collisions Area --> <section class="collisions-area-wrapper"> <!-- Object which you can move --> <div class="obj obj-in-motion"></div> <!-- Object 1 --> <div class="obj static obj-1"></div> <!-- Object 2 --> <div class="obj static obj-2"></div> <!-- Object 3 --> <div class="obj static obj-3"></div> <!-- Object 4 --> <div class="obj static obj-4"></div> <!-- Object 5 --> <div class="obj static obj-5"></div> </section> <!-- /Collisions Area -->

The ‘Collisions-area-wrapper’ section is a container storing all objects (

s) that take part in a collision – both static and the ones (soon to be) in motion.

Description of particular classes of block elements is provided below:

obj – every object within the section ‘collisions-area-wrapper’ and taking part in collisions,
obj-in-motion – movable object that can be moved using keypad cursors,
static – immovable objects (in general),
elements from obj-1 to obj-5 – subsequent immovable

s (see above).

Step II – CSS

You can find the content of the styles.css file below:

html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 body { font-family: 'Open Sans Condensed', sans-serif; } h1 { font-weight: normal; text-align: center; } .container { margin: 0 auto; width: 960px; } .collisions-area-wrapper { position: relative; border: 1px solid #000; height: 480px; overflow: hidden; } .obj { position: absolute; z-index: 1; background-color: #000; width: 80px; height: 80px; -ms-transform-origin: origin; /* IE 9 */ -webkit-transform-origin: origin; /* Chrome, Safari, Opera */ transform-origin: origin; /* General */ } .obj-in-motion { background-color: #A1A6AD; z-index: 2; }

Actually, there isn’t a lot to discuss here – if you’re interested in the subject of collisions, CSS is surely not a mystery to you. You only need to pay attention to selectors with the following classes: ‘collisions-area-wrapper’, ‘obj’ and ‘obj-in-motion’. We gave a relative position to the .collisions-area-wrapper section so that all divs with ‘obj’ class could be positioned absolutely. Thus the elements contained in the .collisions-area-wrapper section that have position: absolute will be positioned in relation to its [section’s] edge instead of the edge of another superior covering container (by default it is the browser’s window).

At this moment, the following question should arise in your head: why do we need position: absolute and position: relative, since our aim is to use 3D transformation instead of the attributes top, bottom, left, right…? Well, the answer is simple: transform3d refers to its own element’s coordinate system and therefore in case of using only transform3d we wouldn’t have any common reference point for our .obj objects, which in turn would result in a mess in the coordinates. We need a global system linking all

s with the beginning of the reference system in a point with coordinates (0,0). This is the task that is implemented by the position: relative and position: absolute, thanks to which all markers with .obj class are given top: 0 and left: 0, and thus they ‘start’ from one place.

We’ll discuss other methods of detecting collisions in the next part of this article, so stay tuned.