Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Saturday, November 13, 2010

Experiments in HTML5: canvas

With HTML5 quickly becoming all the rage, and rightfully so, I think it was very important to learn what seems to be one of the more groundbreaking innovations, the canvas.

I started by searching through my Google Reader (RSS reader which I've become a fan of) since I know I had starred a few articles on HTML5 and the canvas element in particular. Here is what I came up with, sixrevisions.comAWESOME examples from tutsplus.combouncing ball from sixrevisions.com, again, I'm sold, this stuff is WAY too call to ignore!

After a quck 5 minute browsing of some tutorials and samples, it seems pretty similar in use to a typical graphics api. I've had some minor exposure to these in the form of OpenGL, DirectX, and XNA, but it was very limited and I quickly lost interest as it was dealing with what I consider the dying native app. I still have the desire to make a game and perhaps now I have the technology to reach the audience and potential I was looking for.

Here is the recommended canvas template:

<html>
<head>
<title>Canvas</title>
<script type="text/javascript">
// When the window has loaded, DOM is ready. Run the draw() function.
window.onload = draw;   

function draw(){
  var canvas = document.getElementById('myCanvas');
  if (canvas.getContext){
    var context = canvas.getContext('2d');
    // Put canvas drawing stuff here, e.g. context.fillStyle
  }
  else{
    // Put code to execute if browser doesn't have canvas support here
  }
}
</script>

<style type="text/css">
  canvas { border: 1px solid black; }</style>
</head>
<body>
  <canvas id="myCanvas" width="200" height="200"></canvas>
</body>
</html>

Since I already have a page set up, I'm just taking the necessary pieces and placing them where they belong according to this template. I started with a 500 x 500 canvas, this is rather arbitrary, but I have found the most limiting size on regular web pages is facebook profiles at 520px. I styled the canvas to be center aligned by display: block, margin: 0px auto, and border so I know where it is! I put the javascript on the html page, but will remove this once initial development is done.

Ok not too bad to get set up. Now lets get to the fun stuff! I used a great tutorial from Mozilla to get these intial startups going.

The first set of instructions are about drawing shapes, pretty simple stuff really. The only pre-defined shape is a rectangle, but there are several "path" functions. These are similar to drawing freehand. You can draw lines, arcs, and curves using a typical coordinate system in which (0,0) is the top left of the canvas and (width, height) is the bottom right of the canvas. All of this is unfortunately familiar to me. I only say unfortunately because drawing with geometry can be a painful experience at times. First successful canvas javascript api will make someone really rich and/or really famous for shaping internet gaming forever (hint, hint).

The images section reads much like a chapter on sprites in my opinion. I barely read this section since the methods are rather self explanatory. Something that is very important to note on this page though is how images are "loaded". You can use any image already on the page or within the canvas by selecting it by id or tag name, or you can also use document.images, though I personally am unfamiliar with this method. But it seems the preferred method in this tutorial is to load the image using a javascript Image object:

var img = new Image();   // Create new Image object  
img.src = 'myImage.png'; // Set source path  

You can then position, scale, and crop this image and draw it to the canvas with drawImage functions. The rest of the article is still very good, but I ran out of patience and wanted "something". I was somewhat familiar with the remaining topics, and since they are somewhat "heady" I didn't feel like absorbing all that knowledge (probably again) right now. If all of this sounds crazy to you, take it slower, and experiment a lot as the gap between code and visuals is too big to bridge just in your head. So I figured I'll make a small canvas with a "sprite" of some kind, or perhaps a drawn image, that will move around according to key presses. Lets start.

First things first, I am using this as my groundwork.



Nice work by this guy and just wanted to give credit even though I plan on doing some things a little differently. Lets get our shape on there, for simplicity I'm going to create a small 20x20 gray square in a paint tool and draw it to the canvas in the top left:

var img = new Image();
 // When the window has loaded, DOM is ready. Run the init() function.
 window.onload = init;

 function init() { 
  ctx = document.getElementById("mycanvas").getContext("2d");
  img.src = "/images/dev/gray_box.png";
  img.onload = function() {
   ctx.drawImage(img,0,0); 
  }
 }

Now lets add some logic to make it move on a key press:

function keyDown(evt) {
 // so a key was pressed, only react to the keys below
 // left = 37, up = 38, right = 39, down = 40
 // movement workflow: get key, check if at edge, if not move, 
 // if moved off edge then set it to edge, draw at new location
 // if you drew a new square then prevent default key action
 if(evt.keyCode == 37) {
  if(imgObj.x > 0) {
   imgObj.x -= 20;
   if(imgObj.x<0) { imgObj.x=0; } 
   draw();
   evt.preventDefault();
  }
 }
 if(evt.keyCode == 39) {
  if(imgObj.x + imgObj.w < 500) {
   imgObj.x += 20;
   if(imgObj.x + imgObj.w > 500) {imgObj.x=500-imgObj.w; }
   draw();
   evt.preventDefault();
  }
 }

 if(evt.keyCode == 38) {
  if(imgObj.y > 0) {
   imgObj.y -= 20;
   if(imgObj.y<0) { imgObj.y = 0; }
   draw();
   evt.preventDefault();
  }
 }
 if(evt.keyCode == 40) {
  if(imgObj.y + imgObj.h < 500) {
   imgObj.y += 20;
   if(imgObj.y + imgObj.h > 500){imgObj.y = 500 - imgObj.h; }
   draw();
   evt.preventDefault();
  }
 }
 return false;
}

I tried to document the process as concisely as possible. And finally our new draw function:


function draw(){
 // we get the context again (needs efficiency improvement for that)
 var ctx = document.getElementById("mycanvas").getContext("2d");
 // clear the entire canvas, should have a built in function like ctx.clear();
 ctx.clearRect(0,0,500,500);
 // save context (not needed here but a best practice for future)
 ctx.save();
 // draw square in new location
 ctx.drawImage(img,imgObj.x,imgObj.y);
 // restore the context (again not needed but a best practice)
 ctx.restore();
}

Here you can find the complete javascript file.
And a working demo.

This was all done in an hour or two (including the initial research). This is proof that this is a great entry way for web developers to get a taste of game development without such a steep learning curve. A lot of this code isn't anywhere near optimized and was simply more to get a working example and get my feet wet.

I plan to clean this code up, comment more fully, then add functionality, and finally some polish. Hopefully by the end I'll have a fully functional, yet rudimentary html5 canvas game!

UPDATE: Check out the same demo page above for a version of pong.

Friday, November 12, 2010

Quick thoughts

Every week I listen to a google focused podcast and a "neutral" though more apple leaning podcast (at least that is the impression I get from the host). And one thing that I have noticed with the hosts and guests of both shows are that the google folks are usually much more rounded in their technology knowledge. This isn't really a shocker, but I think it's interesting to note as I closely follow google v apple.

So I wanted to use javascript in a cool way, well this guy puts it to shame in some early demos. Yes, its a gameboy emulator taking shape in javascript. It's up on github for anyone who fancies (under MIT and Apache too, ya know so that it has a real chance to grow). This whole thing tells me to scrap the css and jump into the canvas.

The markets were down for the week. No real shocker as it was time to take some profits and everyone had to come down off that caffeine high of last week. Now we have to deal with Chinese currency issues and their effect on commodity prices. And next week should be quite active for US markets at least. Lots of earnings reports and GM IPO. Should be interesting, but I'm thinking it'll be another up week! Here is a better preview of the week to come.

Just installed some chrome extensions for fun: Yoono a social networking "mashup", MeasureIt a quick tool to measure the screen in pixels, and Xmarks a bookmark synchronizer (passwords too if you wish).

Happy weekend, enjoy!

Wednesday, November 3, 2010

Facebook...WTF!?

Ok so this already has rant written all over it right? And if you've worked with me over the past few days, you probably know most of what I'm about to say. But I need to air it out more and maybe get some other opinions on the issue.

For starters lets talk about facebook's "non-event" today. So you are planning to integrate more tightly with mobile devices? Thanks for the incite you progressive minded "genius". I would like to announce that I plan to eat food over the coming months. I do agree though that the iPad is not a mobile platform and I loved Zuck's apparent delivery of the line, "It's a computer. Sorry". Does someone have a favorite mobile OS? Maybe Zuck and I could get along after all ha!

I got most of my information from Engadget's coverage and general google searches. For a real analysis of the event I'd recommend you do the same because I definitely won't do it justice.

Overall its a reasonable roadmap for facebook that was laid out today. In my opinion there really wasn't anything worthy of an event announced today. Though this excellent write up says otherwise. In short, iPhone gets updated app with Groups, Deals, and enhanced Places. Android get additions as well. Deals sounds a little too "market-y" for my liking. And maybe its just me, but I really am not comfortable with telling the world where I am all the time? It's all a little big brother-like to me.

Now you'll see that throughout the event (and the above blog) how much they plug how much the developers "love" it and how its so "easy" to use. I'd also like to point out that they had an Android and an iPhone crash during the demo. And we reach the ranting:

Now I don't claim to be a programming god (still just working on guru status) but I have picked up a few programming languages, APIs, frameworks, CMSs, etc, over the past few years. And of course there were bumps in the road, but overall the experience was progressive and mostly painless. I have been using (attempting to) the facebook apis for the past two weeks and its been painful.

I want to be the first to admit that I am not the most adept facebook user in the world (where the hell is logout you sneaky bastards!) but the whole concept of pages, tabs, and applications makes my eyes glaze over. Yes, there are times when the distinction is clear as day. But other times applications are on tabs on a page. And other times an application isn't a page at all (apps.facebook.com domain). Oh and applications actually have pages of their own, but the page doesn't actually have the application on it. Or wait are those pages or profiles, because you know they are different.

This instantly puts me at a disadvantage, and I would normally take the blame for this, but give a read through their documentation sometime. Essentially every api page starts with: "Use this new api rather than this old api. Oh, unless you're on a page then you have to use the old api. But keep in mind that we're retiring this api in the next month." Holy crap! Think I'm exagerating? Directly from their documentation:
Note: We do not recommend FBML for new developers. If you aren't already using FBML, you should instead implement your application within an iframe, using the JavaScript SDK and social plugins for client-side integration with Facebook services. The one exception: if you absolutely must create an application that appears as a tab on a Facebook Page, you will need to use FBML for now; tabs do not currently support iframes directly. We will be transitioning tabs to iframes later this year -- please see the developer roadmap for more details.
Now can I start to put some of the blame on them instead of myself? Perhaps the most telling thing is that in 50% of the examples they give you, a direct copy and paste will not run. Ok, so the documentation sucks, not like their the first ones to suffer from that. This admission gives me hope, and there have been several updates on the facebook developer blog as well.

I won't be all negative though. Their PHP SDK worked pretty well, though I had a bit of a hiccup with hosting using PHP 5.1 and the SDK requiring JSON (I put most of the blame on hosting for that). And it was a bit tough to get a work around in CodeIgniter, again not really a facebook issue. In their defense it seems they are in transition right now and will perhaps come out much cleaner in 2011, but until then I'm not a big fan.

The main culprit for all of this is the god forsaken FBML and FBJS. These are essentially languages that take their normal counter parts (HTML and Javascript), strip most of their usefulness, then add a bunch of custom tags that are completely uncustomizable and have no significant tutorials. In addition to this the whole "view source" trick to get ideas doesn't work because of their bloated markup.

There, I'm done. I'm sure in a few days I will have that "a ha!" moment and zip through it (fingers crossed) but until then, wtf facebook?

UPDATE: I was finally able to accomplish my task, AJAX and all. I wasn't able to bind events the way I would have liked, but I guess that cake wasn't for eating. But a HUGE thanks goes out to these guys and their blog article. All the examples worked and he responded to his comments, what a novel idea!! I will follow up with more details for any who are interested.

Saturday, October 30, 2010

Why a new UI?

When using my computer, if it requires more than one or two clicks to get what I want, I get frustrated. So my overall goal for my "newi" project (name still in development ha) is to put all of your files/applications/web pages just one click away (or if absolutely necessary two clicks). Of course you could do this right now by moving all of your applications to your desktop, but lets be real no one wants to do that. And in comes my idea for the first cycle of newi.

Without going into too many details, I was picturing a typical "windowed" browsing system but removing the need to click to open a new folder and click to go back a folder. I felt that a user's mouse movement should be enough to tell you what or where they are actually interested in going. By emphasizing this area, the user will be informed of what the newi intends to do. At this point the user can continue the movement to execute or continue the action, or change the movement to suggest a new action.

The action will vary from object to object (and should be customizable by file type). For example, by hovering over a folder it will zoom the folder and expose the folders/files inside. To move back they would move to a small frame that will remain visible. By hovering over an application for x amount of time the application would launch (file browsing within the application would work the same). And by hovering over a file (text document for example) it would launch the appropriate application and open the document.

So this all sounds great, but there are plenty of concerns. Could this create a "too instant" experience? Would users be in and out of folders multiple times because of newi jumping the gun? Of course it would require a lot of tweaking of the sensitivity, but there is bound to be a limit to that.

With my very initial prototypes (and I mean very initial) I already discovered that the operations will be quite math intensive. I didn't experience any issues in Javascript, though I was running Chrome the supposed king of Javascript, though it was with only one window. I imagine multiplying this by at least dozens would have an impact on performance. I also think a compiled application will give better performance.

I'd love to hear any thoughts or suggestions. And check up on my progress here: 2bdev. Time to try out some psuedo-object oriented Javascript!