Archive for the 'JavaScript' category

Winding Rules in HTML’s Canvas

Feb 01 2013 Published by under JavaScript

Send to Kindle

This is another one that a lot of people should already know, but I’m still betting that a few will find useful. Winding refers to the direction a path is drawn in – clockwise or counterclockwise. In many cases, this makes no difference at all, but there are cases where this is very important and can become a very useful tool.

Just realized that most of the examples I’m showing here could have been done just using a fat stroke instead of fills. My fault for poor examples. I was just trying to show simple shapes. This is still a very valid technique and useful for more complex shapes, such as the last example.

The most common use for this is drawing a shape with a hole in it. Let’s say we wanted to draw a black triangle with an empty hole in the center. We can simply draw a black triangle with a smaller white triangle on top of it.

  context.beginPath();
  context.moveTo(300, 100);
  context.lineTo(500, 400);
  context.lineTo(100, 400);
  context.lineTo(300, 100);
  context.fill();
  
  context.fillStyle = "white";
  context.beginPath();
  context.moveTo(300, 150);
  context.lineTo(450, 370);
  context.lineTo(150, 370);
  context.lineTo(300, 150);
  context.fill();

If the background is also white, this looks just fine.

wind_01

But what if we first draw something in the background, like this red bar?

  context.fillStyle = "red";
  context.fillRect(10, 200, 580, 100);
  context.fillStyle = "black";
  
  context.beginPath();
  context.moveTo(300, 100);
  context.lineTo(500, 400);
  context.lineTo(100, 400);
  context.lineTo(300, 100);
  context.fill();
  
  context.fillStyle = "white";
  context.beginPath();
  context.moveTo(300, 150);
  context.lineTo(450, 370);
  context.lineTo(150, 370);
  context.lineTo(300, 150);
  context.fill();

wind_02

The illusion is shattered. I once tried to change the second fill style from “white” to fully transparent with “rgba(255, 255, 255, 0)” thinking that it would overlay the black with transparency, but no, that does not work. Even if it did, it would also wipe out the red underneath it, so forget that.

The trick is to draw the second triangle within the same beginPath() / fill() section, and draw it in the opposite winding direction. Like so:

  context.fillStyle = "red";
  context.fillRect(10, 200, 580, 100);
  context.fillStyle = "black";
  
  context.beginPath();
  
  // first triangle (clockwise)
  context.moveTo(300, 100);
  context.lineTo(500, 400);
  context.lineTo(100, 400);
  context.lineTo(300, 100);

  // second, smaller triangle (counterclockwise)
  context.moveTo(300, 150);
  context.lineTo(150, 370);
  context.lineTo(450, 370);
  context.lineTo(300, 150);

  context.fill();

Notice that in the second triangle I swapped the first two lineTo statements, so it draws the triangle from the top, to bottom left, bottom right, back to top. This is counterclockwise, while the first triangle is drawn in the opposite direction. Because of this, the second triangle cuts out or subtracts from the first. This gives you the following:

wind_03

This works well for drawing lines with shapes. What about rectangles? Well, it won’t work with fillRect, as fillRect does it’s own internal beginPath() and fill() as part of its operations, so each call to it will draw completely separately, as in the first example. So you have to use the rect method. By default, all rects are drawn with the same winding, but there is a way to reverse the winding – just reverse either the width or height. An example will help:

  context.fillStyle = "red";
  context.fillRect(10, 100, 580, 100);
  context.fillStyle = "black";

  context.beginPath();
  context.rect(50, 50, 200, 200);
  context.rect(75, 225, 150, -150);
  context.fill();

Normally, you’d draw the second rect at an x, y of 75, 75, with a width and height of 150. But this would have the same winding as the first. Reversing either the width or height to become a negative value reverses the winding. Reversing both will send it back to the original. Note that you have to change the position on the axis you reversed the size on. So a position of 75, 75 becomes 75, 225, with a size of 150, -150. This gives you the following:

wind_04

Of course, you might be able to use clearRect, but that would wipe out any background as well.

How about arcs? If you’ve used these, you’ve seen that last boolean parameter and probably just ignore it or use whatever value you’ve gotten used to. I always use false. But if you want to punch a circle from another circle, to make a ring, for example, just draw them with opposite values for that last param:

  context.fillStyle = "red";
  context.fillRect(10, 100, 580, 100);
  context.fillStyle = "black";

  context.beginPath();
  context.arc(150, 150, 100, 0, Math.PI * 2, true);
  context.arc(150, 150, 70, 0, Math.PI * 2, false);
  context.fill();

wind_05

And of course you can mix and match these different shapes, though it might take some trial and error to get the different windings going in the right directions. Here’s a triangle with a punched out circle:

  context.fillStyle = "red";
  context.fillRect(10, 200, 580, 100);
  context.fillStyle = "black";
  
  context.beginPath();
  
  context.moveTo(300, 100);
  context.lineTo(500, 400);
  context.lineTo(100, 400);
  context.lineTo(300, 100);

  context.arc(300, 300, 70, 0, Math.PI * 2, true);

  context.fill(); 

wind_06

Well, that’s the basics on winding. Once you get it down, it can be a pretty powerful way of composing complex shapes.

Send to Kindle

One response so far

Scaling in HTML’s Canvas

Jan 31 2013 Published by under JavaScript

Send to Kindle

I’m probably not dropping any huge knowledge bombs here on many of you, but there are a few neat things about scaling when drawing to an HTML5 Canvas that I didn’t realize until a few months ago. So there are probably one or two of you who might find the info handy too.

Let’s say we’re drawing a circle in a canvas. We do this:

  context.beginPath();
  context.arc(100, 100, 50, 0, Math.PI * 2, false);
  context.stroke();

And we get this:

scale_01

(I’m assuming in all of these examples that you have an HTML document with a canvas element, and you’ve grabbed a reference to its 2d context, stored in a variable named “context”. You laugh, but someone’s bound to paste the above code into a text editor somewhere and complain to me that it doesn’t work.)

You probably also know that you can scale the circle like so:

  context.save();
  context.scale(2, 2);
  context.beginPath();
  context.arc(100, 100, 50, 0, Math.PI * 2, false);
  context.stroke();
  context.restore();

This scales everything by a factor of 2, so we get a circle that’s twice as large:

scale_02

But what might not be immediately obvious is the fact that the size of the shape, and the size of the stroke can be scaled separately. In this case because we set the scale before doing anything and restored the transformation matrix after all was done, everything was doubled, the size, the position, the stroke’s width.

But let’s try moving the restore line up before the stroke:

  context.save();
  context.scale(2, 2);
  context.beginPath();
  context.arc(100, 100, 50, 0, Math.PI * 2, false);
  context.restore();
  context.stroke();

This set up gives us a double sized circle, but because we cancelled the transform before applying the stroke, it stays one pixel thick, the default:

scale_03

We can even do the opposite and draw the circle the normal size, then scale up, stroke it, and restore:

  context.beginPath();
  context.arc(100, 100, 50, 0, Math.PI * 2, false);
  context.save();
  context.scale(4, 4);
  context.stroke();
  context.restore();

scale_04

So how is this useful? At least one great way: drawing ellipses. There is no native way to draw an ellipse in canvas. You can of course use some trig and draw a bunch of line segments, but that can be problematic. How many segments to draw? Too few for a large ellipse and it looks choppy. As the size goes down, you need less segments, and drawing too many is a waste of resources. Another complex and inexact solution involves using bezier curves. The easiest way is to just draw a circle scaled differently on one axis than the other. Of course, if you’re using a stroke on the arc, you can wind up with something weird like this:

  context.save();
  context.scale(10, 2);
  context.beginPath();
  context.arc(20, 20, 10, 0, Math.PI * 2, false);
  context.stroke();
  context.restore();

scale_05

See how the stroke was also scaled more on the x axis than on the y, making it look more like an Oakley logo than anything else. To fix it, just do what we did in the second example, moving the restore to before the stroke:

  context.save();
  context.scale(10, 2);
  context.beginPath();
  context.arc(20, 20, 10, 0, Math.PI * 2, false);
  context.restore();
  context.stroke();

scale_06

With this, we can even make a neat little ellipse function like so:

  function ellipse(x, y, w, h) {
    context.save();
    context.translate(x + w / 2, y + h / 2);
    context.scale(w / 2, h / 2);
    context.beginPath();
    context.arc(0, 0, 1, 0, Math.PI * 2, false);
    context.restore();
    context.stroke();
  }
  
  ellipse(100, 100, 200, 80);

I’ll leave you to work through that on your own. Here’s what calling it gives you:

scale_07

Finally, you can go really funky on it, scaling the shape one way and the stroke the other way, like so:

  context.save();
  context.scale(1, 2);
  context.beginPath();
  context.arc(100, 100, 60, 0, Math.PI * 2, false);
  context.restore();
  
  context.save();
  context.scale(20, 1);
  context.stroke();
  context.restore();

With a bit of experimentation, you can wind up with something that’s a half decent fake perspective:

scale_08

Anyway, old news to some of you, new news to others (I hope). More stuff to play with.

Send to Kindle

No responses yet

Circle Layering

Jan 28 2013 Published by under General, JavaScript

Send to Kindle

If you were wondering where my last post was heading…

growth

growth2

growth3

growth4

Oops, gotta turn off the “capture cursor” on that screenshot program. :)

Anyway, this was an idea I first explored several years ago on my art from code site, but has been in the back of my mind as something I wanted to play with more. (see: http://www.artfromcode.com/?s=cells) In the end I ditched the whole idea of perfection I was going for in the last post, as the fact of the outer circles having some space at the end gives it a more organic feel. In fact, you can see that I even exaggerated the space in some of the examples. Well, just a quick follow up. Carry on.

Send to Kindle

4 responses so far

Working out a Math Problem

Jan 25 2013 Published by under JavaScript

Send to Kindle

So I had this idea the other day for a graphic effect. I thought it might be interesting to walk through how it went from concept to functional code. So here it is. The effect involved placing smaller circles around a larger circle. Here’s about what I was looking to do:

circle

Note that all the outer circles exactly touch the inner circle and all the outer circles exactly touch each other. There are no spaces and no overlapping. When I went about coding it and found there were a few different ways to do such a thing and it wasn’t as straightforward as I thought it’d be.

I first tried specifying the size of the inner circle and the size of the outer circles. You can then go around the perimeter of the inner circle placing as many outer circles as will fit. Rarely will you get an exact fit this way, which means that if you don’t overlap, you’ll have some space. You can either have one big space at the end, or try to precalculate how many circles will fit and space them out evenly. Not what I wanted.

Another option is to specify the size and number of the outer circles. You can then arrange them so they just touch each other, figure out how far from the center they are, which then lets you calculate the size of the inner circle. This was fairly easy, but not my use case. I wanted to draw circles around an existing circle of known size.

The final option was to specify the size of the inner circle and how many outer circles you want. You then just have to figure out how big to make those outer circles so they sit on the edge of the inner circle and just touch each other. This would work, but I didn’t know how to figure out how big to make the outer circles. Time for some math! And some sketchy sketches.

math01

 

I made the above sketches to get a clear idea of what I wanted to do. On the bottom left is the inner circle with a couple of the outer circles shown. I know the angle between them, as it’s just 2 * PI / number of circles. And I know the radius of the inner circle. All I need is the radius of the outer circles.

The drawing on the top right is a close up of the top triangle in the first one. Angle A is one half of the angle between each circle, or PI / number of circles. R is the radius of the inner circle and N is the radius of the outer circle. From this, I could come up with the equation shown:

sin A * (R + N) = N

In other words, the sine of angle, times the radius (R + N) equals the opposite side (N). Basic trig.

Now I just needed to solve for N. My algebra was a bit rusty, but after a few false starts I got it down:

math02

 

Bottom line: N = (sin A * R) / (1 – sin A)

So I put it down in code and amazingly, it worked. Here’s what I came up with. Be it known that this code has been worked over quite a bit. It was originally just the onload function with one long linear mess of statements and vars. Once I saw that it worked, I refactored it into some halfway decent functions and cleaned it up a bit. It could still use work to make it more reusable, but at least it’s readable enough to post now:

window.onload = function() {
  var canvas = document.getElementById("canvas"),
      context = canvas.getContext("2d"),
      width = canvas.width,
      height = canvas.height,
      circles,
      inner,
      count = 20;
  
  // create inner circle and draw it:
  inner = {
    x: width / 2,
    y: height / 2,
    radius: 100
  };
  drawCircle(inner);
  
  // get outer circles and draw them:
  circles = getOuterCircles(inner, count);
  for(var i = 0; i < circles.length; i += 1) {
    drawCircle(circles[i]);
  }
    
  
  
  function getOuterCircles(inner, count) {
    var circles = [],
        angle = Math.PI * 2 / count, // angle between circles
        outerRadius = getOuterRadius(count, inner.radius),
        r = inner.radius + outerRadius,
        currentAngle;
  
    for(var i = 0; i < count; i += 1) {
      currentAngle = i * angle;
      circles.push({
        x: inner.x + Math.cos(currentAngle) * r,
        y: inner.y + Math.sin(currentAngle) * r,
        radius: outerRadius
      });
    }
    return circles;
  }
  
  function getOuterRadius(count, innerRadius) {
    var s = Math.sin(Math.PI / count);
    return (s * innerRadius) / (1 - s);
  }
  
  function drawCircle(c) {
    context.beginPath();
    context.arc(c.x, c.y, c.radius, 0, Math.PI * 2, false);
    context.stroke();
  }
};

As you can see, a circle is just an object with x, y, and radius properties. Create the inner circle and draw it.

The getOuterCircles function creates an array of circle objects that are placed around the inner one. It needs the inner circle and the count of outer circles to create. This function uses the getOuterRadius function to get the size of the smaller circles. The var s represents sin A in the original equation. And (s * innerRadius) / (1 – s) is basically the (sin A * R) / (1 – sin A) that I originally came up with.

The rest should hopefully be pretty obvious.

To see it in action, check it out here: http://jsbin.com/icahul/1/edit

Send to Kindle

12 responses so far

Game in Progress: Infiltration

Jan 04 2013 Published by under JavaScript, Windows 8

Send to Kindle

I just wanted to share a little bit about the game I’m currently in the process of creating. It will be a Windows 8 game, called “Infiltration”. The game play, as well as the visual style, is very much a homage to the arcade classic Gravitar, but it is far from an exact copy. The concept is that you have to infiltrate this alien world, fly through various barriers and tunnels and capture one or more targets. I guess I’ll make up a story of what these targets represent – information, energy crystals, or whatever. Anyway, once you grab all the targets, while avoiding being shot, taking out the guns that are shooting you, and keeping track of your fuel, the exit will appear and you fly into it to complete the level. Here are a few screenshots of some of the levels:

  

The controls are basically what you would find in Gravitar or Asteroids: turn left/right, thrust, shoot, with some friction so if you are drifting left or right you will come to a stop fairly soon. The world of the game has basic one dimensional gravity, i.e. your ship is pulled down so you need to regularly use some upward thrust to keep from crashing. Thrusting of course uses fuel and when you run out of fuel, you’re gonna crash. Most of the levels have fuel pods you can pick up to replenish your reserves.

A Word about Gravitar

Gravitar is one of my favorite old school video games. This is not to say that it was my favorite back in the day. I remember it in the arcades, but I never played it that much. Why? Because it was freaking HARD! Now I play it on MAME, which doesn’t waste my hard-earned quarters (worth a lot more back in the early 80′s), but I’m still not even close to beating all the worlds in the first universe. If you want to see for yourself how tough it is, try the online version here: http://my.ign.com/atari/gravitar.

Beyond the visual style and basic game play (fly, shoot, fuel, get out), I did want to capture a bit of that difficulty in Infiltration. So most of the levels are pretty damn hard. I imagine some casual users might consider a few of them impossible. But 1. I will have completed every level personally, and 2. I still don’t think it’s as hard as Gravitar.

If you are interested in Gravitar, you need to check out Dan Coogan’s Gravitar site. Seriously, this is virtual shrine to the game. There you can find screenshots and walkthroughs of every level, interviews with the creators, scans of the original manuals, flyers, ads, etc. There is even 350+ scanned pages of the original Gravitar design binder – original sketches, plans, meeting minutes, office correspondence about the game, cabinet specs, etc. An amazing resource to see what went into making a game like that back in the day.

Designing Levels

It became obvious to me very early on that if I was going to be designing a bunch of levels, doing it by plugging numerical coordinates into some kind of text document, loading the level, seeing what it looked like, tweaking the values and checking again, etc. was going to be very painful. So I set about making a graphical level editor for the game. This was also done as a Windows 8 app and became a major side project for a few weeks. I can now draw out a full level, place, move, and delete any game items, all with a full undo/redo stack, and load and save levels as JSON. It’s got a grid you can toggle on/off as well at toggle snap-to-grid, and inputting of level metadata. I’m pretty proud of it. Here’s what it looks like in action:

The next pain point was after creating a level, I had to add that level to the game project and compile the game. And then recompile the game every time I made a change. So I added a feature in the game itself to be able to load custom external (not compiled in) levels from the file system. At this point, I don’t even need to have Visual Studio open anymore. I create the levels in the editor and test them in the live game. Tweak the level, save, reload the level in the game.

This has worked out so well that I’ve decided to leave the external level feature in the game itself, and release the editor as a public app as well. So, when this is finally all completed, people will be able to create their own levels, play them, share them with friends, etc. Maybe I could even get some kind of best level contest going.

Current Progress

As of this writing, I have 23 levels done. I plan to have 30 in total. The first few are pretty easy tutorial-type levels. It gets tough pretty quickly after that though. I think I’m going to check out the try/buy functionality for this game, releasing a trial version with a selection of levels, and a full version with all levels plus the ability to load custom levels. The editor would be free, but only useful if you have the full version of the game. The trial may have ads as well. Not looking to get rich here, but I never signed my vow of poverty either.

I’ve been working on this since the beginning of October. So it’s been a couple of months and I’m itching to be done with it. I think there is little, if any, coding left to be done, just level creation, which I hope to wrap up by this weekend. Then I’ll probably need to tweak and rearrange the levels a bit to make them flow. Hopefully you’ll see this in the store by the middle of the month, if all goes right.

Send to Kindle

4 responses so far

2012 in Review

Dec 31 2012 Published by under General, JavaScript, Technology, Windows 8

Send to Kindle

Following a tradition several years in the running, I bring you my personal retrospective into 2012 and a glimpse into the new year.

In fact, 2012 followed much the same pattern as 2011 – some interesting stuff in the start of the year, a long period of just kind of being bored with everything, and then finding something to be excited about as the year drew to a close.

As 2011 ended, I was starting to get more seriously into JavaScript and web development. In early 2012 I posted a few opinionated opinions on object creation in JavaScript, which sparked some good conversation. I followed these up with a couple of articles on the same subject on the Adobe Developer Center.

In April I went to Beyond Tellerand – Play, a creative/development conference in Cologne, Germany. I revived one of my most popular talks, Playing With Chaos, for this conference, redoing all the examples in JavaScript. It went over amazingly well. The talk is always really well received. After that, I had the idea to turn the talk into a self published book and got a good start on it. But that kind of fizzled out after a couple of months. Perhaps I’ll revive it some time in the new year. You can actually watch the whole talk at the BT Play site, along with the other sessions.

It turned out that BT Play was the only speaking gig I did all year – the least amount of speaking I’ve done since I’ve started. I did have a couple of other opportunities to speak, but have not been super interested in doing so, to be honest. There are few if any “Flash conferences” around anymore, and even if there were, I’m not really doing any Flash these days. I don’t feel expert enough to try to get into the JavaScript conference speaking circuit. I probably could do more stuff like the chaos talk, which would go over well in any kind of creative type situation, but the impetus just wasn’t there for some reason. I guess another part of it is that the Flash conferences had a certain group of people you knew were going to show up. A large part of the pull to speak at these was the hooking up with friends from around the world and hanging out with them. I do miss that.

In June, my coworker and friend, Todd Anderson, and I went down to Austin for the TXJS conference, as attendees. It was very odd not knowing anyone else at the conference, and I’ll admit it, not having people coming up to me saying they read my books, blog, used my components, etc. It was also around this time that I started to get a bit bored with JavaScript. This statement needs a lot of clarification. I don’t have any problem with the language itself or what it can do. And at first, I was pretty excited about all the stuff happening in the community – so many new libraries and frameworks coming out all the time. But this latter part is what eventually got me bored with it. Too many frameworks, too many opinions. and everyone in your face telling you the RIGHT way to do things. I guess I was a bit guilty of this myself earlier in the year with my object creation posts. But I just kind of got tired of all the king-of-the-hill playing that’s going on in web development this last year or so. I got too caught up in the “how to” part and wasn’t really MAKING anything.

So you might have noticed that from June to August of this year I went pretty dark. Honestly I wasn’t even doing anything blogworthy. A bit of a technology sabbatical, covered well enough in this post. Also mentioned in that post is that Windows 8 programming is what pulled me back into activity. I now have two apps in the Windows 8 Store and am very close to having my next one ready for submission.

If it’s not obvious already, I LOVE Windows 8 programming. Everything I’ve done so far has been with HTML/JavaScript, which is the one thing that has most excited me over the last couple of years. But there’s very little of the community chaos that you get in web development. You are essentially developing for IE 10. So all the self-righteous, holier-than-thou web dev hipsters aren’t going to talk to you anyway. :) I’m not a standards guru, but from what I know, IE 10 is pretty good. And even if it’s not 100% standards compliant, since you are only developing for the one platform for desktop Win8 apps, it’s kind of a standard itself.  There’s none of the cross-browser / cross-platform stuff to worry about. Basically, you can just ignore all the noise and MAKE stuff. And that’s what I’m doing. And loving it.

On the job front, I’m still at Infrared5 and that’s all going pretty well. Although nothing jumps out as being hugely exciting there for me in the last year, there were no huge problems either. I did one project in ActionScript / Flex / Desktop AIR, which was pretty unique in that it embeds a Red5 server in the app itself to do local recording of video. I have Paul Gregoire to thank for the Red5 help and in hacking together a stripped down version of the Red5 server that could be run on the low end hardware we were targeting. It was quite a technical challenge and worked out pretty well. Most of the rest of the year I’ve been doing iOS stuff for a client of the company that keeps hiring me back. Earlier in the year I helped build out a custom iOS library for the client, and in the latter half, I’ve been helping to build an app based on that library – truly eating my own dog food! It’s an interesting situation to be working with the black box of a closed library that you helped build but no longer have access to the source of. A bit frustrating at times, but quite an eye opener as well.

So what’s in store for 2013? More of the same. Specifically, my plan for the moment is to participate in this: http://onegameamonth.com/ The One Game A Month… er… project? It’s not a game jam, it’s not a contest, it’s just a couple thousand people who say they are going to try to make a game each month for 2013. Fantastic idea. I’ve spent way too long on the game I’m currently working on. That’s a common problem with any personal programming project. There’s no deadline, so you fiddle with it forever, trying to make it perfect, eventually get bored with it and start something else. This boxes out your time. One month. Get it done. Ship it. The game I’m working on now will wind up being my January game, and I have a great concept for February. I’m excited about this.

I also really do plan to do more blogging. I’m going to try to put something up 2-3 times a week. Probably a lot of it will be about the game I’m working on at that particular time. Any tricks or tips, problems or insight.

Also, as many of you know from my tweets, G+ posts, other comments, and occasional mentions on this blog, I’ve been heavily into running in the last few years. This past year I ran my first two marathons and am now in training for my first ultramarathon, a 50K (31 mile) trail race in April. I don’t like to put too much of that info on this blog, but if you are interested to hear more about that, here’s another year in review post from that viewpoint, on my personal blog.

Send to Kindle

2 responses so far

Playing With Chaos: The Book

Apr 29 2012 Published by under General, JavaScript, Kindle, Technology

Send to Kindle

Well, the title gives it away, so I just need to elaborate. I had so much fun and did so much research and wrote so much code for my Playing With Chaos presentation, and it went over so well and was very popular. But in the 45 minutes I had last week, or even in a full hour of talking, you can barely scratch the surface of the simplest bits of math or code and only show a few quick images or demos of each example. And there were lots of other examples that I didn’t even have time to touch on. I would love to be able to cover all the topics I had in mind, and go over each one fully enough, with well explained code. Thus, I’ve been thinking of writing a book based on the presentation.

The truth is that I’ve been thinking of writing this book for about a year. But doing the presentation at Beyond Tellerand – Play! solidified the idea. Here are some details about my plans:

1. I’m going to self-publish the book. I’ve been really interested in self-publishing for a while. This will be an experiment to see how well it works for me. The biggest thing I’m concerned about is the editing process. I’m sure I can dig up a technical reviewer or two, but the copy editing phase where someone at the publisher fixes all your spelling and grammar and unifies your tenses and persons and numbers, etc. is invaluable. I actually do understand grammar pretty well, but in a longer piece of writing I can lose track of the style I’m using and jump back and forth. It will take an extra reading or two with extra attention on this stuff to get it down. Or perhaps I’ll find someone willing to help me out on this point.

2. I’ll be going through the Amazon Kindle publishing service. I think this offers the best form of distribution, discoverability, protection, commerce, etc. In addition to being able to read the book on any existing Kindle, it can be read on any iOS, Android, Windows Phone 7 or Blackberry device and on any computer via standalone reader apps or the Kindle web app. This also allows me the option to publish through other services such as B&N Nook and Apple iBooks as well. In addition, there are services that will publish hard copies of your Kindle book on demand for those who want to kill trees. :)

3. I will not be doing a Kickstarter project for the book. I don’t believe most books require any kind of start up capital. Unless you need to do some kind of heavy research, travel, or buy some expensive equipment, or quit your day job and write full time, there is really no up front cost. You sit down and write the book. The only thing I might need to pay out for would be a technical reviewer and/or copy editor, and that would be later and something I’m sure I can work out. I’ve contributed to funding two books over the last couple of years on Kickstarter and neither one of them has yet seen the light of day. It leaves the author in an odd position of being responsible to many people, but with no single person invested so heavily that they are going to bug him daily to meet deadlines. I’m not even sure there is any penalty if you get funded and never release the thing you were funded to do. Do the contributors eventually get their money back if nothing happens?

4. The examples will be done in JavaScript with HTML5′s Canvas. This may or may not be your favorite platform, but I feel like it offers appeal to the widest potential audience. Even if you’ve never done any serious JavaScript, you can fire up a text editor and browser and be coding and running HTML/JS in minutes, for a total cost of $0.00. If you’ve done any programming in any other language, JS is a piece of cake to pick up, and generally easy enough to convert into the language of your choice. Few other languages require so little monetary investment, so little setup for a coding environment across the boards, and such a low learning curve for the language itself.

5. Right now, the TOC stands at 12 chapters, but that could change and rearrange. Right now I’m most of the way through the introduction chapter and have been working on developing a base package that all the examples can use to prevent massive duplication of code. The goal is to not rely on any major third party libraries just as jQuery, etc., and not to create something so complex that it becomes a heavy dependency. Basically, it’s just some boiler plate to grab the canvas, 2d context, some properties like width and height, and various utility functions for commonly used operations.

So watch this space for various updates over the next few months. Maybe even some teaser images or live demos. I haven’t really got a solid deadline in mind, but roughly hoping to be done by the end of the summer.

Send to Kindle

10 responses so far

JavaScript Object Creation: Learning to Live Without “new”

Feb 29 2012 Published by under JavaScript

Send to Kindle

I wrote yet another article on object creation in JavaScript. This time, for Adobe! I’m really glad to see that they are reaching out to publish articles like this. I hope to see a lot more on similar subjects. And I hope that means that they may have additional tooling and products in the works that will support high end web development.

Here’s the article link:

http://www.adobe.com/devnet/html5/articles/javascript-object-creation.html

It touches on many of the same principles of my last couple of JS object posts here, but supplies some non-trivial, real world code to demonstrate the principles.

Send to Kindle

One response so far

Thoughts on Private in JS

Feb 18 2012 Published by under JavaScript

Send to Kindle

When you get into a bit higher end JavaScript patterns, one thing you’ll read very early on is this concept: that although JavaScript does not have private members or access modifiers, it is possible to achieve this behavior with closures. This is often done through an IIFE and is the simplest implementation of the module pattern. Like so:

var mod = (function() {
    var privateVar = "foo";
    return {
        getPrivateVar: function() {
            return privateVar;
        },
        setPrivateVar: function(value) {
            privateVar = value;
        }
    };
}());


console.log(mod.getPrivateVar());
mod.setPrivateVar("buzz");
console.log(mod.getPrivateVar());

The IIFE executes, returning an object with a couple of methods. These methods have access to the original privateVar, which is not accessible anywhere else. Private var, right? All good and well, but I’ve noticed one aspect of this that almost nobody ever talks about…

Modules are singletons.

OK, they are not really singletons in the full sense of the singleton pattern with a static getInstance method and a guard against creating multiple instances. But they are objects that are created a single time and unless you were to copy and paste the code that creates them, there’s no real way to create an additional instance of one of them.

I’m not going off into a “singletons are evil” rant or anything, but it should be pointed out that modules created in this way only have a single instance. This is pretty obvious, since the module is created by an IIFE, which runs once when it is defined, and that’s it. For most things that you would define as “modules” this is probably exactly what you want, which I guess is why nobody talks about it. A module is often a library, like underscore or jquery, etc. Something you generally would not want multiple copies of floating around in the first place.

But say you want some kind of object that it would make sense to have multiple copies of. Say a game with players. If you defined a player object like above, you could only have a single player. So you need to change things somehow to allow for multiple instances.

The first idea is just to remove the IIFE and just have a function that you can call multiple times to create individual objects:

function playerMaker(pname) {
    var name = pname;
    return {
        getName: function() {
            return name;
        },
        setName: function(value) {
            name = value;
        }
    };
}

var player1 = playerMaker("Fred");
console.log(player1.getName());
var player2 = playerMaker("Barney");
console.log(player2.getName());

This works just fine, but do you see the issue here? that return object is created anew every single time you create a new instance. Not a big deal in a trivial example like this, but say you had an object with dozens of properties and methods and you were creating scores of these things. All those methods and properties would be created as brand new methods and properties on every object, cranking up your memory consumption and creation time. Probably not a good idea in most cases.

We could then turn to something like the revealing module pattern, which defines the functions a single time in the module, and then returns an object that references these. In this case, we still want playerMaker to be a function, so we return a function that returns an object that references the single instances of the methods:

var playerMaker = (function() {
    var name = "";
    
    function getName() {
        return name;
    }
    
    function setName(value) {
        name = value;
    }
    
    return function() {
        return {
            getName: getName,
            setName: setName
        };
    };
}());

var player1 = playerMaker();
player1.setName("Fred");
var player2 = playerMaker();
player2.setName("Barney");
console.log(player1.getName());
console.log(player2.getName());​

Only this doesn’t work at all, because the “private” var name is defined only once in the original IIFE and is like a static var amongst all instances. If you tried to move it into the return function at line 12, it wouldn’t work, because then it would not be in the scope that the getName and setName functions would have access to.

The long and the short of it is that for private properties to work, they rely on a closure, and for multiple instances to each have their own accessors and private properties, each one needs to have its own closures. A shared closure can only access a shared property. So we can’t really escape the second example.

Perhaps there is some way to do this, but I suspect that the complexity involved would probably outweigh the benefits.

In my original draft of this post, I went into a minor rant about how you shouldn’t worry about private vars in JavaScript, as it doesn’t have them and it doesn’t make sense to over-engineer all kinds of complexity to simulate them. But I’m not feeling very ranty at the moment, so I deleted all that.

This isn’t to say that the module pattern as commonly used, with its private vars and methods is bad. It’s actually quite simple and elegant as long as you only need a single instance of that module, and I back it up as a great pattern 100%. But if you are trying to extend it to objects with multiple instances, I think you are best to leave privacy behind.

Interestingly, between the time of writing this post and publishing it (a couple of days) I listened to the latest JavaScript Jabber podcast http://javascriptjabber.com/005-jsj-javascript-objects/ on “JavaScript Objects”. A great listen, and some of these very points were brought up. Check that one out. It’s a great new podcast as a whole, and with only 5 episodes so far, well worth going back to the start and checking out all of them.

Send to Kindle

23 responses so far

CSS Roadblock

Jan 16 2012 Published by under JavaScript, Uncategorized

Send to Kindle

Generally I like to use my blog for dispensing knowledge, advice, opinions, thoughts, musings, and of course, FACTS. But occasionally I get stuck on a point and all my research leads me to a dead end, and I’ll write a post that asks for help. I figure the answers just might help someone else down the line anyway, so it’s not purely selfish.

OK, so I’ve learned to stop worrying and love JavaScript. HTML I can tolerate. But CSS is gonna kick my ass.

Here’s what I want:

Two divs, floated side by side, varying amounts of text in them, but that text needs to be bottom aligned. Here’s what I came up with after a few Google searches:

<style type="text/css">
	.header { 
		position: relative; 
		float: left;
		width: 200px;
		margin: 10px;
		height: 100px;
		background-color: #ffcccc;
	}
	.header-content { 
		position: absolute; 
		bottom: 0; 
		left: 0; 
		width: 100%;
	}
</style>
<div class="header">
	<div class="header-content">Some content that will wrap lorem ipsum and all that crap just to make a long lon long div</div>
</div>
<div class="header">
	<div class="header-content">other stuff</div>
</div>

And here’s what it looks like:

But I have one more need. I’m hard coding the height of the header class to be 100px. I want it to be the exact height of the tallest content. So that it looks like this:

The thing is, that because the header-content div is absolute positioned, then the header div’s height will be 0 unless explicitly set. So the bottom of header is the same as the top of header and header-content goes off the top of the page.

The only way I’ve managed to do this is via JavaScript something like this:

var contents = document.getElementsByClassName( "header-content" );
var h = 0;
for( var i = 0; i < contents.length; i++ ) {
	var content = contents[ i ];
	h = Math.max( h, content.offsetHeight );
}
var headers = document.getElementsByClassName( "header" );
for( var i = 0; i < headers.length; i++ ) {
	var header = headers[ i ];
	header.style.height = h + "px";
}

This loops through the header-content divs, finding the tallest one. Then with that value, sets the height of both header divs. Works just fine.

In Flash, I'd have no problem using code for layout. But I'd love to know if there is some pure CSS way to accomplish this.

Send to Kindle

20 responses so far

Older posts »