My first Chrome extension

tumblr

My tumblr, visualized

After doing some data visualizations on reddit over the weekend based on using text to create ‘ASCII/word circles’ that show how each letter is connected to another I made my first Chrome extension. It is basically a visualization of Markov chains.

You can get the Chrome extension from the Chrome Web Store now. Simply click the button in your toolbar to view the visualization for any web page.

N-sided shapes

You’ll probably know that the formula for calculating the interior angle of a regular polygon is 180(n – 2) / n where n is the number of sides:

Angle formula

So if we put 4 (i.e. a square) into the formula we 90 degrees, if we stick in 5 (pentagon) we get 108 degrees. Simple. In fact, lets create a JavaScript function to draw these shapes if we enter a starting coordinate, side length and number of sides:

 function drawShape(c, startX, startY, sideLength, sideCount)
 {
  var interiorAngleDegrees = (180 * (sideCount - 2)) / sideCount;
  var interiorAngle = Math.PI - Math.PI * interiorAngleDegrees / 180; //Convert to radians
  c.save();
  c.beginPath();
  c.translate(startX, startY);
  c.moveTo(0,0);
  for (var i = 0; i < sideCount; i++)
  {
    c.lineTo(sideLength,0);
    c.translate(sideLength,0);
    c.rotate(interiorAngle);
  }
  c.stroke();
  c.restore();
}
Example of a square

Example of a square drawn with function

Now, if what happens if we take our original formula and stick in something that isn’t an integer. If we put in 2.5 we get out 54 degrees. What does a 2.5 sided shape look like with the above function?

A '2.5' sided shape.

A ‘2.5’ sided shape.

Clearly this isn’t a full polygon, so perhaps it is better to think of 2.5 as 5/2. Let’s adapt the function a little:

function drawShape(c, startX, startY, sideLength, sideCountNumerator, sideCountDenominator)
 {
   var sideCount = sideCountNumerator * sideCountDenominator;
   var decimalSides = sideCountNumerator / sideCountDenominator;
   var interiorAngleDegrees = (180 * (decimalSides - 2)) / decimalSides;
   var interiorAngle = Math.PI - Math.PI * interiorAngleDegrees / 180; //Convert to radians
   c.save();
   c.beginPath();
   c.translate(startX, startY);
   c.moveTo(0,0);
   for (var i = 0; i < sideCount; i++)
   {
     c.lineTo(sideLength,0);
     c.translate(sideLength,0);
     c.rotate(interiorAngle);
   }
   c.stroke();
   c.restore();
 }

Now the function can draw 5 / 2 shapes:

A 5 / 2 sided regular polygon.

A 5 / 2 sided regular polygon.

If you want to check out a full source code example, you can see it here.

HTML5 apps on the App Store

There are many HTML5 apps on the App Store but they are not first class citizens on iOS, unlike on other platforms. They have to be executed by UIWebView, a component allowing the presentation of web pages using WebKit but with the major disadvantage that the JavaScript performance is massively throttled compared to performance in Safari (because Safari uses the Nitro engine). This was expressed dramatically by the old Facebook app, and continues to be shown by many other apps.

Apple could quite easily allow developers to produce iOS apps with HTML5 and package them in Xcode for the App Store. Rather than being executed by a UIWebView they could instead be executed by the full Safari engine with its faster JavaScript performance. A similar feature exists in Safari already that allows you to ‘pin’ websites to the Home Screen and opening them executes them like an app, but being run by Safari without the navigation bar.

This would be incredibly advantageous for web developers because it would allow them to charge for their web apps on mobile platforms and lock down the source code if they were distributed via the App Store. It would also make porting between devices a lot easier, although this wouldn’t be as advantageous for Apple.

There are a few main problems with this, of course. The first is In App Purchases. Currently they account for a huge proportion of App Store revenue, however JavaScript has no way of accessing them unless Apple allowed for the transaction to launch the App Store app, which could prove effective.

Another disadvantage is appearance. Should Apple allow web developers to produce regular HTML markup or should it extend the standard to contain UIViews? The advantage of the former is it would make apps easier to design because existing tools and frameworks could be used. The disadvantage is that it would ruin the current design standards that Apple runs on. Interestingly, Intel announced a UIKit toolkit for JavaScript earlier this month.

Native APIs are also a disadvantage. How does an HTML5 app send notifications (Chrome does have an API for this)? How does an HTML5 app access the camera (again, W3 has some drafts on this)? How does an HTML5 app access photos or contacts? Either Apple doesn’t let them and places them at a disadvantage against native apps or it ports the Foundation framework to JavaScript, but that would ruin JavaScript standards if we started relying on NS* rather than JavaScript standards.

Unfortunately there really isn’t much in it for Apple because it either involves a huge port of their libraries of a huge loss of design I’m apps. The bare minimum is to allow current (major?) apps that rely on UIWebView for the majority of their content to access Nitro, ensuring faster performance.

Ultimately I don’t think that Apple will make HTML5 apps first class citizens on the App Store any time soon, but accessing Nitro could provide a major boost to mobile web apps.

Drawing stars with HTML5 Canvas

Update: I’ve since written a slightly different version that can draw n-sided polygons.


I was searching around for some decent HTML5 demos earlier and I noticed that there weren’t any particularly good tutorials or functions for drawing regular stars. Obviously Canvas is fine for drawing polygons and so I was able to produce this very simple function that uses the rotate() function to position the points:

function star(ctx, x, y, r, p, m)
{
    ctx.save();
    ctx.beginPath();
    ctx.translate(x, y);
    ctx.moveTo(0,0-r);
    for (var i = 0; i < p; i++)
    {
        ctx.rotate(Math.PI / p);
        ctx.lineTo(0, 0 - (r*m));
        ctx.rotate(Math.PI / p);
        ctx.lineTo(0, 0 - r);
    }
    ctx.fill();
    ctx.restore();
}

You call the function by using star(canvas, x of center, y of center, radius, number of points, fraction of radius for inset). Here are some examples. To create a five point star, therefore, you call star(ctx, 100, 100, 90, 5, 0.5). Here is an example of what that looks like:

Obviously because the function doesn’t actually set styles or shadows but this isn’t too difficult to implement. Here is a live demo of the star being drawn.