h3mm3's blog

Stories from behind the keyboard

  • RSS
  • Twitter
Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

After experimenting the Mandelbrot algorithm inside a Razor web application, I decided to port my code to a standalone Javascript+HTML5 page (i.e. the one you are just reading now).

As far as I'm concerned, the most interesting part about this post is loading this page with different browsers and comparing how fast are the various javascript engine implementations. For instance, on my PC, generating the first picture of the Mandelbrot set (i.e. the one you're gonna see after clicking the GO button) takes:

  • about half a second (511ms) on Chrome 10.0.648.204,
  • one third of a second (312ms) on Firefox 4.0
  • ... and more than eleven (!!) seconds on Internet Explorer 9.0.

It'll be fine if you comment this post and write how much time your browser takes to generate the very first picture (zooming times are not comparable since they depends on how much «inner» fractal points are computated).

Enough chatting... Just click the GO button and enjoy the beauty of the Mandelbrot set... If you can’t see any fractal, either your browser doesn’t support HTML5, or my code is buggy enough not to run on you client (LOL).

Update: now you can click the picture to zoom into the fractal.


Happy programming!

After I stumbled upon this post about how to draw a Koch curve using turtle graphics, I decided to implement some turtle commands in Javascript and test them inside a <canvas/>.

The application

Set the width and the number of recursions of the Koch algorithm, and watch a classic Koch fractal!

Koch curve parameters:


The implementation

The hearth of the application is the fracturtle object. It implements some turtle graphics commands and the algorithm of the Koch curve (may the SRP god forgive me!). The turtle commands implemented here are:

  • right(): turns the turtle (i.e. the drawing brush) clockwise
  • left(): turns the turtle counter-clockwise
  • forward(): moves the turtle ahead

The whole process starts with the init() function, but the real drawing happens after the fracturtle has received all the commands:

  • begin(): sets the starting position of the turtle
  • koch(): tells the turtle how to move in order to obtain a Koch curve
  • end(): terminates the moving phase and draws the geometric path
<script>
var fracturtle = {
 x0: 0,
 y0: 0,
 w2: 150,
 h2: 150,
 x1: 0,
 y1: 0,
 direction360: 0,
 ctx: undefined,
 canvas: undefined,

 init: function(canvasid, width, height) {
  this.canvas = $("#"+canvasid)[0];
  this.canvas.width = width;
  this.canvas.height = height;
  this.ctx = this.canvas.getContext('2d');
  this.ctx.beginPath();
  this.x0 = w2 = width / 2;
  this.y0 = h2 = height / 2;
 },

 begin: function(x,y) {
  this.ctx.beginPath();
  this.ctx.moveTo(this.x0=x, this.y0=y);
 },

 end: function() {
  this.ctx.closePath();
  this.ctx.fill();
  this.ctx.strokeStyle = "red";
  this.ctx.lineWidth="1px";
  this.ctx.stroke();
 },

 from360: function(angle360) {
  return Math.PI * angle360 / 180;
 },

 forward: function(length) {
  this.x1 = this.x0 + length * Math.cos(this.from360(this.direction360));
  this.y1 = this.y0 + length * Math.sin(this.from360(this.direction360));
  this.ctx.lineTo(this.x0=this.x1,this.y0=this.y1);
 },

 right: function(angle360) {
  this.direction360 -= angle360;
 },

 left: function(angle360) {
  this.direction360 += angle360;
 },

 koch: function(length, depth) {
  if (depth === 0) {
   this.forward(length);
  } else {
   this.koch(length / 3, depth - 1);
   this.right(60);
   this.koch(length / 3, depth - 1);
   this.left(120);
   this.koch(length / 3, depth - 1);
   this.right(60);
   this.koch(length / 3, depth - 1);
  }
 }
};

The algorithm is fired when the user interacts with either dropdown, thanks to this vanilla jQuery code:

$("select").change(function(){ 
 var w = $("#fracturtle_w").val();
 var r = $("#fracturtle_r").val();
                
 if (w==0 || r==0) return;

 fracturtle.init("fracturtle_c",w,w/3);
 fracturtle.begin(0,w/3-1);
 fracturtle.koch(w,r);
 fracturtle.end();
});

Happy programming!

Well, this is sort of an implicit tutorial about HTML5 and the <canvas/> tag. If your browser supports HTML5 (*) you'll see an animated starfield: just click and move your mouse (sort of... read the asterisk *) to enjoy a romantic.. er... a classic animation. The javascript code is neither minified nor obfuscated, soo feel free to invastigate the source code of this page.

Happy programming!

(Yes... I told I would continue my previous post about fractals and razor... I promise I will do it, soon.)

Sorry, your browser is too old to support canvas!

(*) …and if you are not using Mozilla, which fires a subtle NS_ERROR_DOM_SYNTAX_ERR. As of now FireFox is in troubles if someone (i.e. some code) wants to draw something outside the boundary of a canvas. The roundtrip described here by rogerh requires you to create a temporary canvas, do all the operations in this canvas and write back to the original one. I decided not to implement this roundtrip in this demo, so the viewport rotation and the mouse interactivity are only available to Internet Explorer and Chrome.