<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>simonsarris.com</title>
	<atom:link href="http://simonsarris.com/feed" rel="self" type="application/rss+xml" />
	<link>http://simonsarris.com</link>
	<description></description>
	<lastBuildDate>Tue, 24 Aug 2010 01:17:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Making and Moving Selectable Shapes on an HTML5 Canvas: A Simple Example</title>
		<link>http://simonsarris.com/blog/140-canvas-moving-selectable-shapes</link>
		<comments>http://simonsarris.com/blog/140-canvas-moving-selectable-shapes#comments</comments>
		<pubDate>Mon, 23 Aug 2010 01:54:13 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://simonsarris.com/?p=140</guid>
		<description><![CDATA[This tutorial will show you how to create a simple data structure for shapes on an HTML5 canvas and how to have them be selectable. The finished canvas will look like this: This text is displayed if your browser does not support HTML5 Canvas. Click to drag boxes. Double click to add new boxes. init(); [...]]]></description>
			<content:encoded><![CDATA[<p>This tutorial will show you how to create a simple data structure for shapes on an HTML5 canvas and how to have them be selectable. The finished canvas will look like this:</p>
<div id="container">
    <canvas id="canvas" width="400" height="300" style="border: 1px solid #000;"><br />
    This text is displayed if your browser does not support HTML5 Canvas.<br />
    </canvas>
</div>
<p><i>Click to drag boxes. Double click to add new boxes.</i></p>
<pre><script type="text/javascript" src="http://simonsarris.com/project/canvasdemo/boxes.js"></script>
<script>init();</script></pre>
<p>This article&#8217;s code is written primarily to be easy to understand. It isn&#8217;t optimized for performance, though a little bit of the drawing is set up so that more complex shapes can easily be added in the future.</p>
<p>We&#8217;ll be going over a few things that are also essential to game-development (drawing loop, hit testing), and in later tutorials I will probably turn this example into a small game.</p>
<h3>The HTML5 Canvas</h3>
<p>A Canvas is made by using the &lt;canvas&gt; tag in HTML:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;">   <span style="color: #009900;">&lt;canvas <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;canvas&quot;</span> <span style="color: #000066;">width</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;400&quot;</span> <span style="color: #000066;">height</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;300&quot;</span>&gt;</span>
    This text is displayed if your browser does not support HTML5 Canvas.
   <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span>canvas&gt;</span></pre></div></div>

<p>A canvas isn&#8217;t smart: it&#8217;s just a place for drawing pixels. If you ask it to draw something it will do so and then immediately forget everything about what you have just done. Because of this we have to keep track ourselves of all the things we want to draw (and re-draw) each frame.</p>
<p>So we&#8217;ll need to add:</p>
<ol>
<li>Code for keeping track of objects</li>
<li>Code for initialization</li>
<li>Code for drawing the objects as they are made and move around</li>
<li>Code for mouse events</li>
</ol>
<h3>Keeping track of what we draw</h3>
<p>To keep things simple for this example we will just make a rectangular object called Box. We&#8217;ll also make a method for creating Boxes a little easier.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// holds all our rectangles</span>
<span style="color: #003366; font-weight: bold;">var</span> boxes <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> 
&nbsp;
<span style="color: #006600; font-style: italic;">//Box object to hold data for all drawn rects</span>
<span style="color: #003366; font-weight: bold;">function</span> Box<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">x</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">y</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">w</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// default width and height?</span>
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">h</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">fill</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'#444444'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//Initialize a new Box, add it, and invalidate the canvas</span>
<span style="color: #003366; font-weight: bold;">function</span> addRect<span style="color: #009900;">&#40;</span>x<span style="color: #339933;">,</span> y<span style="color: #339933;">,</span> w<span style="color: #339933;">,</span> h<span style="color: #339933;">,</span> fill<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> rect <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Box<span style="color: #339933;">;</span>
  rect.<span style="color: #660066;">x</span> <span style="color: #339933;">=</span> x<span style="color: #339933;">;</span>
  rect.<span style="color: #660066;">y</span> <span style="color: #339933;">=</span> y<span style="color: #339933;">;</span>
  rect.<span style="color: #660066;">w</span> <span style="color: #339933;">=</span> w
  rect.<span style="color: #660066;">h</span> <span style="color: #339933;">=</span> h<span style="color: #339933;">;</span>
  rect.<span style="color: #660066;">fill</span> <span style="color: #339933;">=</span> fill<span style="color: #339933;">;</span>
  boxes.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>rect<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  invalidate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>Initialization</h3>
<p>I&#8217;m going to add a bunch of variables for keeping track of the drawing and mouse state. I already added boxes[] to keep track of each object, but we&#8217;ll also need a var for the canvas, the canvas&#8217; 2d context (where wall drawing is done), whether the mouse is dragging, width/height of the canvas, and so on. We&#8217;ll also want to make a <i>second</i> canvas, for selection purposes, but I&#8217;ll talk about that later.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> canvas<span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> ctx<span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> WIDTH<span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> HEIGHT<span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> INTERVAL <span style="color: #339933;">=</span> <span style="color: #CC0000;">20</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// how often, in milliseconds, we check to see if a redraw is needed</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> isDrag <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> mx<span style="color: #339933;">,</span> my<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// mouse coordinates</span>
&nbsp;
 <span style="color: #006600; font-style: italic;">// when set to true, the canvas will redraw everything</span>
 <span style="color: #006600; font-style: italic;">// invalidate() just sets this to false right now</span>
 <span style="color: #006600; font-style: italic;">// we want to call invalidate() whenever we make a change</span>
<span style="color: #003366; font-weight: bold;">var</span> canvasValid <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// The node (if any) being selected.</span>
<span style="color: #006600; font-style: italic;">// If in the future we want to select multiple objects, this will get turned into an array</span>
<span style="color: #003366; font-weight: bold;">var</span> mySel<span style="color: #339933;">;</span> 
&nbsp;
<span style="color: #006600; font-style: italic;">// The selection color and width. Right now we have a red selection with a small width</span>
<span style="color: #003366; font-weight: bold;">var</span> mySelColor <span style="color: #339933;">=</span> <span style="color: #3366CC;">'#CC0000'</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> mySelWidth <span style="color: #339933;">=</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// we use a fake canvas to draw individual shapes for selection testing</span>
<span style="color: #003366; font-weight: bold;">var</span> ghostcanvas<span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> gctx<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// fake canvas context</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// since we can drag from anywhere in a node</span>
<span style="color: #006600; font-style: italic;">// instead of just its x/y corner, we need to save</span>
<span style="color: #006600; font-style: italic;">// the offset of the mouse when we start dragging.</span>
<span style="color: #003366; font-weight: bold;">var</span> offsetx<span style="color: #339933;">,</span> offsety<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Padding and border style widths for mouse offsets</span>
<span style="color: #003366; font-weight: bold;">var</span> stylePaddingLeft<span style="color: #339933;">,</span> stylePaddingTop<span style="color: #339933;">,</span> styleBorderLeft<span style="color: #339933;">,</span> styleBorderTop<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// initialize our canvas, add a ghost canvas, set draw loop</span>
<span style="color: #006600; font-style: italic;">// then add everything we want to intially exist on the canvas</span>
<span style="color: #003366; font-weight: bold;">function</span> init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  canvas <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'canvas'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  HEIGHT <span style="color: #339933;">=</span> canvas.<span style="color: #660066;">height</span><span style="color: #339933;">;</span>
  WIDTH <span style="color: #339933;">=</span> canvas.<span style="color: #660066;">width</span><span style="color: #339933;">;</span>
  ctx <span style="color: #339933;">=</span> canvas.<span style="color: #660066;">getContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'2d'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  ghostcanvas <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'canvas'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  ghostcanvas.<span style="color: #660066;">height</span> <span style="color: #339933;">=</span> HEIGHT<span style="color: #339933;">;</span>
  ghostcanvas.<span style="color: #660066;">width</span> <span style="color: #339933;">=</span> WIDTH<span style="color: #339933;">;</span>
  gctx <span style="color: #339933;">=</span> ghostcanvas.<span style="color: #660066;">getContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'2d'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">//fixes a problem where double clicking causes text to get selected on the canvas</span>
  canvas.<span style="color: #660066;">onselectstart</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// fixes mouse co-ordinate problems when there's a border or padding</span>
  <span style="color: #006600; font-style: italic;">// see getMouse for more detail</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">defaultView</span> <span style="color: #339933;">&amp;&amp;</span> document.<span style="color: #660066;">defaultView</span>.<span style="color: #660066;">getComputedStyle</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    stylePaddingLeft <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">defaultView</span>.<span style="color: #660066;">getComputedStyle</span><span style="color: #009900;">&#40;</span>canvas<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'paddingLeft'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span>      <span style="color: #339933;">||</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
    stylePaddingTop  <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">defaultView</span>.<span style="color: #660066;">getComputedStyle</span><span style="color: #009900;">&#40;</span>canvas<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'paddingTop'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span>       <span style="color: #339933;">||</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
    styleBorderLeft  <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">defaultView</span>.<span style="color: #660066;">getComputedStyle</span><span style="color: #009900;">&#40;</span>canvas<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'borderLeftWidth'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span>  <span style="color: #339933;">||</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
    styleBorderTop   <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">defaultView</span>.<span style="color: #660066;">getComputedStyle</span><span style="color: #009900;">&#40;</span>canvas<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'borderTopWidth'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span>   <span style="color: #339933;">||</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// make draw() fire every INTERVAL milliseconds.</span>
  setInterval<span style="color: #009900;">&#40;</span>draw<span style="color: #339933;">,</span> INTERVAL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// add our events. Up and down are for dragging,</span>
  <span style="color: #006600; font-style: italic;">// double click is for making new boxes</span>
  canvas.<span style="color: #660066;">onmousedown</span> <span style="color: #339933;">=</span> myDown<span style="color: #339933;">;</span>
  canvas.<span style="color: #660066;">onmouseup</span> <span style="color: #339933;">=</span> myUp<span style="color: #339933;">;</span>
  canvas.<span style="color: #660066;">ondblclick</span> <span style="color: #339933;">=</span> myDblClick<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// add custom initialization here:</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// add an orange rectangle</span>
  addRect<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">200</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">200</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">40</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">40</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'#FFC02B'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// add a smaller blue rectangle</span>
  addRect<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">25</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">90</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">25</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">25</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'#2BB8FF'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>Drawing</h3>
<p>Since our canvas is animated (boxes move over time), we have to set up a draw loop as I did in the init() function.</p>
<p>We have to draw at a frame rate, maybe every 20 milliseconds or so. However, redrawing doesn&#8217;t just mean drawing the shapes over and over; we also have to clear the canvas before every redraw. If we don&#8217;t clear it, dragging will look like the box is making a solid line because none of the old box-positions will go away.</p>
<p>Because of this, we clear the entire canvas before each Draw frame. This can get expensive, and we only want to draw if something has actually changed within our framework, so we will consider the canvas to be either valid or invalid.</p>
<p>If everything just got drawn, the canvas is valid and there&#8217;s no need to draw again. However, if we do something like add a new Box or try to move a box by dragging it, the canvas will get invalidated and draw() will do a clear-redraw-validate.</p>
<p>This isn&#8217;t the only way to optimize drawing, after all clearing and redrawing the <i>entire</i> canvas when one little box moves is excessive, but canvas invalidation is the only optimization we&#8217;re going to use for now.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// While draw is called as often as the INTERVAL variable demands,</span>
<span style="color: #006600; font-style: italic;">// It only ever does something if the canvas gets invalidated by our code</span>
<span style="color: #003366; font-weight: bold;">function</span> draw<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>canvasValid <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    clear<span style="color: #009900;">&#40;</span>ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Add stuff you want drawn in the background all the time here</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// draw all boxes</span>
    <span style="color: #003366; font-weight: bold;">var</span> l <span style="color: #339933;">=</span> boxes.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> l<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        drawshape<span style="color: #009900;">&#40;</span>ctx<span style="color: #339933;">,</span> boxes<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> boxes<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">fill</span><span style="color: #339933;">,</span> boxes<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">fill</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// draw selection</span>
    <span style="color: #006600; font-style: italic;">// right now this is just a stroke along the edge of the selected box</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>mySel <span style="color: #339933;">!=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      ctx.<span style="color: #660066;">strokeStyle</span> <span style="color: #339933;">=</span> mySelColor<span style="color: #339933;">;</span>
      ctx.<span style="color: #660066;">lineWidth</span> <span style="color: #339933;">=</span> mySelWidth<span style="color: #339933;">;</span>
      ctx.<span style="color: #660066;">strokeRect</span><span style="color: #009900;">&#40;</span>mySel.<span style="color: #660066;">x</span><span style="color: #339933;">,</span>mySel.<span style="color: #660066;">y</span><span style="color: #339933;">,</span>mySel.<span style="color: #660066;">w</span><span style="color: #339933;">,</span>mySel.<span style="color: #660066;">h</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Add stuff you want drawn on top all the time here</span>
&nbsp;
&nbsp;
    canvasValid <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>As you can see, we go through all of boxes[] and draw each one, in order from first to last. This will give the nice appearance of later boxes looking as if they are on top of earlier boxes. After all the boxes are drawn, a selection handle (if there&#8217;s a selection) gets drawn around the box that mySel references.</p>
<p>If you wanted a background (like a city) or a foreground (like clouds), one way to add them is to put them before or after the main two drawing bits. There are better ways though, like using multiple canvases, but we won&#8217;t go over that here.</p>
<h3>Mouse events</h3>
<p>Now we have objects, initialization, and a loop that will constantly re-draw when needed. All thats left is to make the mouse do things upon pressing, releasing, and double clicking.</p>
<p>With our MouseDown event we need to see if there are any objects we could have clicked on. And we don&#8217;t want just any object; selections make the most sense when we only grab the top-most object.</p>
<p>Now we could do something very easy and just check the bounds of each of our boxes &#8211; see if the mouse co-ordinates lie within the boxes width and height range &#8211; but that isn&#8217;t as extendable as I&#8217;d like. After all, What if later we want to select lines instead of boxes? Or select triangles? Or select text?</p>
<p>So we&#8217;re going to do selection in a more general way: We will draw each shape, one at a time, onto a &#8220;ghost&#8221; canvas, and see if the mouse co-ordinates lie on a drawn pixel or not.</p>
<p>A ghost canvas (or fake canvas, or temporary canvas) is a second canvas that we created in the same size and shape as our normal one. Only nothing from it will ever get seen, because we only created it in code and never added it to the page. Go back and look at ghostcanvas and its context (gctx) in the init() function to see how it was made.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Happens when the mouse is clicked in the canvas</span>
<span style="color: #003366; font-weight: bold;">function</span> myDown<span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  getMouse<span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  clear<span style="color: #009900;">&#40;</span>gctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// clear the ghost canvas from its last use</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// run through all the boxes</span>
  <span style="color: #003366; font-weight: bold;">var</span> l <span style="color: #339933;">=</span> boxes.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> l<span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&gt;=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">--</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// draw shape onto ghost context</span>
    drawshape<span style="color: #009900;">&#40;</span>gctx<span style="color: #339933;">,</span> boxes<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'black'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'black'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// get image data at the mouse x,y pixel</span>
    <span style="color: #003366; font-weight: bold;">var</span> imageData <span style="color: #339933;">=</span> gctx.<span style="color: #660066;">getImageData</span><span style="color: #009900;">&#40;</span>mx<span style="color: #339933;">,</span> my<span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> index <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>mx <span style="color: #339933;">+</span> my <span style="color: #339933;">*</span> imageData.<span style="color: #660066;">width</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// if the mouse pixel exists, select and break</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>imageData.<span style="color: #660066;">data</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      mySel <span style="color: #339933;">=</span> boxes<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
      offsetx <span style="color: #339933;">=</span> mx <span style="color: #339933;">-</span> mySel.<span style="color: #660066;">x</span><span style="color: #339933;">;</span>
      offsety <span style="color: #339933;">=</span> my <span style="color: #339933;">-</span> mySel.<span style="color: #660066;">y</span><span style="color: #339933;">;</span>
      mySel.<span style="color: #660066;">x</span> <span style="color: #339933;">=</span> mx <span style="color: #339933;">-</span> offsetx<span style="color: #339933;">;</span>
      mySel.<span style="color: #660066;">y</span> <span style="color: #339933;">=</span> my <span style="color: #339933;">-</span> offsety<span style="color: #339933;">;</span>
      isDrag <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
      canvas.<span style="color: #660066;">onmousemove</span> <span style="color: #339933;">=</span> myMove<span style="color: #339933;">;</span>
      invalidate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      clear<span style="color: #009900;">&#40;</span>gctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009900;">&#125;</span>
  <span style="color: #006600; font-style: italic;">// havent returned means we have selected nothing</span>
  mySel <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
  <span style="color: #006600; font-style: italic;">// clear the ghost canvas for next time</span>
  clear<span style="color: #009900;">&#40;</span>gctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #006600; font-style: italic;">// invalidate because we might need the selection border to disappear</span>
  invalidate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>myMove and myUp are pretty self explanatory. the var isDrag becomes true if myDown found something to select, and it becomes false again when the mouse is released (myUp).</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Happens when the mouse is moving inside the canvas</span>
<span style="color: #003366; font-weight: bold;">function</span> myMove<span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isDrag<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    getMouse<span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    mySel.<span style="color: #660066;">x</span> <span style="color: #339933;">=</span> mx <span style="color: #339933;">-</span> offsetx<span style="color: #339933;">;</span>
    mySel.<span style="color: #660066;">y</span> <span style="color: #339933;">=</span> my <span style="color: #339933;">-</span> offsety<span style="color: #339933;">;</span>   
&nbsp;
    <span style="color: #006600; font-style: italic;">// something is changing position so we better invalidate the canvas!</span>
    invalidate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> myUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  isDrag <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  canvas.<span style="color: #660066;">onmousemove</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>There are a few little methods I added that are not shown, such as one to correctly get the mouse position in a canvas. You can see and download the full demo source <a href="http://simonsarris.com/project/canvasdemo/demo1.html">here</a>.</p>
<p>Now that we have a basic structure down, it is easy to write code that handles more complex shapes, like paths or images or video. Rotation and scaling these things takes a bit more work, but is quite doable with the Canvas and our selection method is already set up to deal with them.</p>
<p>If you would like to see this code enhanced in future posts (or have any fixes), let me know how in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonsarris.com/blog/140-canvas-moving-selectable-shapes/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>A Nanopitter?</title>
		<link>http://simonsarris.com/blog/102-nanopitters</link>
		<comments>http://simonsarris.com/blog/102-nanopitters#comments</comments>
		<pubDate>Sun, 18 Jul 2010 02:16:50 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://simonsarris.com/?p=102</guid>
		<description><![CDATA[While reading a story regarding nanopillars I kept thinking of a sort of minuscule caterpillar. I wondered if anyone else had thought the same so (somehow) ended up searching for the word nanopitter on Google. I think this was the first time in a long time that such a short query yielded zero results! So [...]]]></description>
			<content:encoded><![CDATA[<p>While reading a story regarding <a href="http://www.technologyreview.com/energy/25817/">nanopillars</a> I kept thinking of a sort of minuscule caterpillar. I wondered if anyone else had thought the same so (somehow) ended up searching for the word nanopitter on Google. I think this was the first time in a long time that such a short query yielded zero results!</p>
<p>So now I must wonder how long it will take before this page appears on Google as the sole result.</p>
<p><b>Edit:</b> Apparently, <a href="http://www.google.com/search?hl=en&#038;q=Nanopitter">about a day.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://simonsarris.com/blog/102-nanopitters/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Easily monitor the Oil Spill &#8211; All the live feeds on one page</title>
		<link>http://simonsarris.com/blog/34-easily-monitor-oil-spill</link>
		<comments>http://simonsarris.com/blog/34-easily-monitor-oil-spill#comments</comments>
		<pubDate>Wed, 23 Jun 2010 22:41:03 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bp]]></category>
		<category><![CDATA[oil spill]]></category>

		<guid isPermaLink="false">http://simonsarris.com/?p=34</guid>
		<description><![CDATA[Want to watch all of BP&#8217;s ROV feeds at once? I have created a simple page here that contains the embedded feed of all 12 ROVs from BP&#8217;s website. Let me know if you have any additions or modifications to make the page better.]]></description>
			<content:encoded><![CDATA[<p>Want to watch all of BP&#8217;s ROV feeds at once?</p>
<p>I have created a simple page <a href="http://simonsarris.com/project/oilspill.html">here</a> that contains the embedded feed of all 12 ROVs from BP&#8217;s website.</p>
<p>Let me know if you have any additions or modifications to make the page better.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonsarris.com/blog/34-easily-monitor-oil-spill/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Customizing the HP Envy Quick Launch keys</title>
		<link>http://simonsarris.com/blog/24-envy-keyboard</link>
		<comments>http://simonsarris.com/blog/24-envy-keyboard#comments</comments>
		<pubDate>Sun, 13 Jun 2010 01:37:19 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[envy]]></category>
		<category><![CDATA[hp]]></category>
		<category><![CDATA[laptop]]></category>

		<guid isPermaLink="false">http://simonsarris.com/?p=24</guid>
		<description><![CDATA[I bought an envy about a month ago and have been working through the usual new laptop quirks. There are plenty of hard-to-notice-until-bought pros and cons that I might pour over some time, but right now I&#8217;d just like to mention my findings with respect to the Envy Quick Launch keys that are located on [...]]]></description>
			<content:encoded><![CDATA[<p>I bought an envy about a month ago and have been working through the usual new laptop quirks. There are plenty of hard-to-notice-until-bought pros and cons that I might pour over some time, but right now I&#8217;d just like to mention my findings with respect to the Envy Quick Launch keys that are located on the left of the keyboard.</p>
<p>By default these keys open up a mail program, HP&#8217;s MediaSmart SmartMenu, a web browser, printing, and the Windows calculator program. You can see them on the left side of the keyboard, with labels I&#8217;ll explain in a moment:<br />
<center><br />
<img src="http://www.simonsarris.com/images/envy-keyboard.jpg" /><br />
</center><br />
There&#8217;s no way in the HP software to customize the buttons, so I did a little bit of fishing around and found some useful information.</p>
<p>My original intent was to make a small program that would sit in the system tray and simply have a menu to enable/disable all the buttons at will. The buttons are nice, but they aren&#8217;t the most useful thing to have enabled when one is trying to play a full-screen game. I&#8217;d keep getting sent back to the desktop because I accidentally opened a calculator instead of pressing Ctrl. Similar problems abound with Photoshop, or any program that demands constant use of Tab and Ctrl.</p>
<p>Making a small key-capture program I found out that the first odd-one out was the Print key, which literally just sends the key press for LeftCtrl and P. The second odd one is the wave- looking key, the SmartMenu button, which I&#8217;ll address later.</p>
<p>The others had strange key names: BrowserHome, calc.exe, and LaunchMail. At that point I decided to look for those names in the registry and came upon some interesting values:</p>
<p>There are 5 entries in a registry folder corresponding to some of the Quick Launch keys as well as mysterious nonexistant keys. First I&#8217;ll mention what the real keys do and how to change them.<br />
<br/><br/><br />
<b>Editing the keys</b></p>
<p>Go to the start bar in Windows 7, type &#8220;regedit&#8221; and press enter. If you&#8217;re unfamiliar with the Windows registry then please be careful, messing with values here can cause a lot of errors.</p>
<p>Navigate to the registry folder:</p>
<p>Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AppKey</p>
<p>In the folder you&#8217;ll see more folders, the three we care about are:</p>
<ul>
<li>15 calls for the Assocation of &#8216;mailto&#8217;</li>
<li>18 calls for a ShellExecute of &#8216;calc.exe&#8217;</li>
<li>7 calls for the Assocation of &#8216;http&#8217; (opens the browser or program associated with http)</li>
</ul>
<p>These are the mail, calculator, and internet buttons respectively. If you want to change them, simply modify the values inside each folder. Associations will open the program that is tied to the protocol or file type. For these two buttons, the &#8216;mailto&#8217; association opens Windows Live Mail (by default), and the &#8216;http&#8217; association opens whatever browser is your default. ShellExecute on the other hand is the same as typing something into Run and pressing enter.</p>
<p><b>An example:</b> Let&#8217;s say you want the mail button to open Notepad: Go into the folder named 15, rename &#8220;Association&#8221; to &#8220;ShellExecute&#8221;, double click ShellExecute to modify the key&#8217;s data and enter &#8220;notepad.exe&#8221;, replacing &#8220;mailto.&#8221;</p>
<p>Want to disable a button? Just clear out the ShellExecute or Association data. For the mail button you would double click the Association and replace &#8220;mailto&#8221; with nothing.</p>
<p><br/><br/><br />
<b>What about the wave key?</b></p>
<p>The wave-looking key actually opens a program called &#8216;HP MediaSmart SmartMenu.&#8217; You can uninstall this from Programs and Features in the Control Panel if you wish. I haven&#8217;t yet found a way to do anything else with it.<br />
<br/><br/><br />
<b>What were those other registry entries?</b></p>
<ul>
<li>16 calls for the Assocation of .cda, this seems to be a nonexistant key that was intended to be media-centric</li>
<li>17 calls a ShellExecute on ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}, which is the ParsingName for &#8220;My Computer&#8221; in Folder Descriptions, so I suppose it was a My Computer button</li>
</ul>
<p>These keys were probably programmed for but never implemented in the final Envy design.</p>
<p>None of this gives us an easy way to disable the keys temporarily, though, so I guess I&#8217;ll have to release a small program later to let people temporarily disable and re-enable them on the fly.</p>
<p>Also, if anyone has any information about the Wireless On/Off key above the &#8220;+&#8221; key, please let me know. I&#8217;d <i>really</i> like to find a way to temporarily disable that, or better yet only make it work when &#8220;fn&#8221; is pressed, but so far haven&#8217;t found anything useful on the key.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonsarris.com/blog/24-envy-keyboard/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>A solution to the ATI Hammer Text Corruption Problem</title>
		<link>http://simonsarris.com/blog/17-a-solution-to-the-ati-hammer-text-corruption-problem</link>
		<comments>http://simonsarris.com/blog/17-a-solution-to-the-ati-hammer-text-corruption-problem#comments</comments>
		<pubDate>Sun, 13 Jun 2010 01:29:09 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ati]]></category>
		<category><![CDATA[hammer]]></category>
		<category><![CDATA[text corruption]]></category>

		<guid isPermaLink="false">http://simonsarris.com/?p=17</guid>
		<description><![CDATA[Many people with newer ATI cards have been having trouble using Valve&#8217;s Hammer, the Source SDK&#8217;s level editor. Specifically, the text that tells you what the dimensions of an object are has become unreadable. This topic has been discussed in threads like this one. I did a great deal of digging, most of it ending [...]]]></description>
			<content:encoded><![CDATA[<p>Many people with newer ATI cards have been having trouble using Valve&#8217;s Hammer, the Source SDK&#8217;s level editor. Specifically, the text that tells you what the dimensions of an object are has become unreadable.</p>
<p>This topic has been discussed in threads like <a href="http://forums.steampowered.com/forums/showthread.php?t=865783">this one.</a></p>
<p>I did a great deal of digging, most of it ending in other users complaining about how neither Valve or ATI seem to care about this issue &#8211; and indeed I emailed Valve and they emailed me back saying that they don&#8217;t support the SDK. Alas, I have found a solution to the Text corruption many of us have seen in Hammer!</p>
<p>The solution:</p>
<p>1. Download a program known as <a href="http://www.softpedia.com/progDownload/ATI-Tray-Tools-Download-9040.html">ATI Tray Tools.</a> I had to use the Beta since I&#8217;m running Windows 7.</p>
<p>2. Right click its icon, Go to</p>
<pre>3D >
Additional Options >
and check the box for <b>Alternate Pixel Center</b></pre>
<p>This will fix the error.</p>
<p>Happy level making!</p>
<p><font color="red">EDIT:</font><br />
Apparently, while this tweak fixes Hammer, it breaks all the Source games in a similar text-garbled manner. You&#8217;ll have to turn it off again to play Source games.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonsarris.com/blog/17-a-solution-to-the-ati-hammer-text-corruption-problem/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to play Age of Empires II on Windows Vista and Windows 7</title>
		<link>http://simonsarris.com/blog/6-how-to-play-age-of-empires-ii-on-windows-vista-and-windows-7</link>
		<comments>http://simonsarris.com/blog/6-how-to-play-age-of-empires-ii-on-windows-vista-and-windows-7#comments</comments>
		<pubDate>Sat, 12 Jun 2010 18:02:27 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[age of empires]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[windows 7]]></category>

		<guid isPermaLink="false">http://simonsarris.com/?p=6</guid>
		<description><![CDATA[I love Age of Empires II. I love all real-time strategy games, but Age of Empires II must be among the finest I’ve ever played, especially as a multiplayer game. Unfortunately, getting Age of Empires to work in this modern day is a bit of a pain. The game was built on network technology known [...]]]></description>
			<content:encoded><![CDATA[<p>I love Age of Empires II. I love all real-time strategy games, but Age of Empires II must be among the finest I’ve ever played, especially as a multiplayer game.</p>
<p>Unfortunately, getting Age of Empires to work in this modern day is a bit of a pain. The game was built on network technology known as IPX that has since gone the way of the dinosaurs. So far gone, in fact, that Microsoft decided not to include it in Vista and Windows 7. All of my computers are using Windows 7 now, so getting the game to play over LAN proved to be difficult.</p>
<p>I didn’t want to deal with trying to hodge-podge together an IPX installation, so I decided to look for ways for the TCP/IP method of gameplay to work. This method rarely worked for me, and when it did it only worked on some computers and not others.</p>
<p><strong>Apparently, all I needed to do was assign <span style="text-decoration: underline;">all</span> the computers that were playing in the game to have static IP addresses.</strong> If you don’t know what that is, there’s a link to a guide at the bottom of this article. Set static IPs on every computer that will be playing, not just the host.</p>
<p>Then, on the computer hosting, select <strong>Internet TCP/IP Connection for DirectPlay</strong> and NOT the LAN option. For some reason, selecting the LAN option caused issues. However, all the computers that will be joining can just select the LAN option.</p>
<p>Assuming there are no firewall issues, you should be good to go. I tested this with Windows 7 only machines, and only over LAN. If anyone has tried this as described and couldn’t get it to work, I’d like to hear from you.</p>
<p>Have fun playing!</p>
<p><em>Here’s a wonderful guide from PortForward.com on <a href="http://portforward.com/networking/staticip.htm">setting up a static IP.</a></em></p>
]]></content:encoded>
			<wfw:commentRss>http://simonsarris.com/blog/6-how-to-play-age-of-empires-ii-on-windows-vista-and-windows-7/feed</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Quite possibly the best time to buy a MacBook Pro?</title>
		<link>http://simonsarris.com/blog/22-mac-envy-2</link>
		<comments>http://simonsarris.com/blog/22-mac-envy-2#comments</comments>
		<pubDate>Wed, 14 Apr 2010 01:35:19 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[envy]]></category>
		<category><![CDATA[hp]]></category>
		<category><![CDATA[laptop]]></category>
		<category><![CDATA[mac]]></category>

		<guid isPermaLink="false">http://simonsarris.com/?p=22</guid>
		<description><![CDATA[The fruit-themed computer manufacturer has finally made an effort to bring the MacBook Pro into the modern era. Boasting new Core i5 and i7 series processors and an updated (albeit last generation) graphics card, the new MacBook Pro sells at a curiously similar price to the MacBook Pro of last week. Take a look at [...]]]></description>
			<content:encoded><![CDATA[<p>The fruit-themed computer manufacturer has finally made an effort to bring the MacBook Pro into the modern era. Boasting new Core i5 and i7 series processors and an updated (albeit last generation) graphics card, the new MacBook Pro sells at a curiously similar price to the MacBook Pro of last week.</p>
<p>Take a look at what&#8217;s changed. I left the HP Envy 15 in for a comparison to a modern laptop with non-Apple brand pricing.</p>
<p><img src="http://www.simonsarris.com/images/macbook-envy2.jpg"/></p>
<p><font face="Sans-Serif"></p>
<table border="2" cellspacing="0" cellpadding="7">
<tr>
<th>Part</th>
<th>MacBook Pro 15<br/>(1 week ago)</th>
<th>MacBook Pro 15<br/>(Today)</th>
<th>HP Envy 15</th>
</tr>
<tr>
<td>Processor</td>
<td bgcolor=#FF888>Intel Core2 Duo T9600 @ 2.80GHz<br/>(Passmark score: 1995)<br/>(2 cores)</td>
<td bgcolor=#FFFACD>Intel Core i7 M 620 @ 2.60GHz<br/>(Passmark score: 2871)<br/>(2 cores)</td>
<td bgcolor=#88FF88>Intel Core i7 720QM @ 1.60GHz<br/>(Passmark score: 3296)<br/>(4 cores)</td>
</tr>
<tr>
<td>RAM</td>
<td bgcolor=#FFFACD>4GB DDR3</td>
<td bgcolor=#FFFACD>4GB DDR3</td>
<td bgcolor=#FFFACD>4GB DDR3</td>
</tr>
<tr>
<td>Video</td>
<td bgcolor=#FF888>NVIDIA GeForce 9600M GT<br/>512MB of GDDR3<br/>120 gigaFLOPs<br/>OpenGL 2.1</td>
<td bgcolor=#FFFACD>NVIDIA GeForce GT 330M<br/>512MB of GDDR3<br/>182 gigaFLOPs<br/>OpenGL 2.1 </td>
<td bgcolor=#88FF88>Mobility Radeon HD 5830<br/>1GB of GDDR3<br/>800 gigaFLOPs<br/>OpenGL 3.2</td>
</tr>
<tr>
<td>Screen</td>
<td bgcolor=#FF888>15.4&#8243;<br/>1440&#215;900</td>
<td bgcolor=#FFFACD>15.4&#8243;<br/>1680&#215;1050</td>
<td bgcolor=#88FF88>15.6&#8243;<br/>1920&#215;1080</td>
</tr>
<tr>
<td>HDD</td>
<td bgcolor=#FFFACD>500GB SATA<br/>@ 7200 rpm</td>
<td bgcolor=#FFFACD>500GB SATA<br/>@ 7200 rpm</td>
<td bgcolor=#FFFACD>500GB SATA<br/>@ 7200 rpm</td>
</tr>
<tr>
<td>Price:</td>
<td bgcolor=#FFFACD>$2,399.00</td>
<td bgcolor=#FFFACD>$2,399.00</td>
<td bgcolor=#88FF88>$1,749.99</td>
</tr>
</table>
<p></font></p>
<p>Little else has changed on the Pro aside from the processor, video card, and max screen resolution. The supported DirectX and OpenGL are still still 10.1 and 2.1 respectively, and the laptop&#8217;s price remains unchanged*.</p>
<p>The updated video card is NVIDIA&#8217;s GeForce GT 330M, which is an over-clocked GT 240M, which itself is just an over-clocked GT 230M (June 2009), which explains the aging DirectX and OpenGL versions.</p>
<p>Nonetheless, thanks to Apple&#8217;s staunch refusal to discount hardware that was already two years old, it is a significantly better time to buy a MacBook Pro than it was just one week ago, be it new or used. Every other laptop manufacturer has had to reduce prices on aged models or introduce newer models in order to stay competitive, but it seems that Apple is immune to Father Time, perhaps because its consumer base practices an isolationism unseen since the days of <a href="http://en.wikipedia.org/wiki/Hai_jin">Hai jin.</a></p>
<p>This is of course not a bad thing in itself. If you&#8217;re running an all-Mac shop then right now is quite possibly the best time to buy a MacBook Pro. Yesterday, however, was quite possibly the worst.<br />
<br/><br/><br/></p>
<p><i>* As configured above. I believe the minimum price for a base 15-inch MacBook Pro is slightly less than it was previous.</i></p>
]]></content:encoded>
			<wfw:commentRss>http://simonsarris.com/blog/22-mac-envy-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quite possibly the worst time to buy a MacBook Pro</title>
		<link>http://simonsarris.com/blog/19-mac-envy</link>
		<comments>http://simonsarris.com/blog/19-mac-envy#comments</comments>
		<pubDate>Mon, 08 Feb 2010 01:32:56 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[envy]]></category>
		<category><![CDATA[hp]]></category>
		<category><![CDATA[laptop]]></category>
		<category><![CDATA[mac]]></category>

		<guid isPermaLink="false">http://simonsarris.com/?p=19</guid>
		<description><![CDATA[I&#8217;ve been looking for a new laptop since January, so far being generally unimpressed due to the slow adoption of the mobile i7 processors. I ended up with just a few, the best of which seems to be the HP Envy. Dell and Lenovo have contending i5 and i7-based systems out, but all the models [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been looking for a new laptop since January, so far being generally unimpressed due to the slow adoption of the mobile i7 processors. I ended up with just a few, the best of which seems to be the HP Envy. Dell and Lenovo have contending i5 and i7-based systems out, but all the models except the Envy seemed to have one or two unforgivable drawbacks, such as only two dimm slots, only one hdd slot, poor screen resoloution, or a new processor coupled with a miserably dated graphics card (I&#8217;m looking at you, Lenovo).</p>
<p>Every time I mention that I&#8217;m looking for a new laptop I have gotten no good suggestions other than one recommendation for the HP Envy and a handful of people advocating the MacBook Pro. I don&#8217;t plan on running OSX but I recall back in late 2007 an article <a href="http://www.pcworld.com/article/136649-3/in_pictures_the_most_notable_notebooks_of_2007.html">mentioning the Mac being the fastest Vista notebook</a>, so I figured I&#8217;d at least take a look. Comparing it to the Envy though, the results were pretty stark.</p>
<p><img src="http://www.simonsarris.com/images/macbook-envy.jpg"/></p>
<p><font face="Sans-Serif"></p>
<table border="2" cellspacing="0" cellpadding="7">
<tr>
<th>Part</th>
<th>MacBook Pro 15</th>
<th>HP Envy 15</th>
</tr>
<tr>
<td>Processor</td>
<td>Intel Core2 Duo T9600 @ 2.80GHz<br />
(Passmark score: 1995)</td>
<td bgcolor=#88FF88>Intel Core i7 720QM @ 1.60GHz<br />
(Passmark score: 3296)</td>
</tr>
<tr>
<td>RAM</td>
<td>4GB DDR3</td>
<td bgcolor=#FFFACD>4GB DDR3</td>
</tr>
<tr>
<td>Video</td>
<td>NVIDIA GeForce 9600M GT<br />
512MB of GDDR3<br />
120 gigaFLOPs<br />
OpenGL 2.1</td>
<td bgcolor=#88FF88>Mobility Radeon HD 5830<br />
1GB of GDDR3<br />
800 gigaFLOPs<br />
OpenGL 3.2</td>
</tr>
<tr>
<td>Screen</td>
<td>15.4&#8243; 1440&#215;900</td>
<td bgcolor=#88FF88>15.6&#8243; 1920&#215;1080</td>
</tr>
<tr>
<td>HDD</td>
<td>500GB SATA<br />
@ 7200 rpm</td>
<td bgcolor=#FFFACD>500GB SATA<br />
@ 7200 rpm</td>
</tr>
<tr>
<td>Price:</td>
<td>$2,399.00</td>
<td bgcolor=#88FF88>$1,749.99</td>
</tr>
</table>
<p></font></p>
<p><a href="http://www.primatelabs.ca/geekbench/">Geekbench</a> generally rates the two laptops on the whole with a score average of around 3700 for the Mac vs 5000 for the HP Envy, making the performance-per-price <i>enormously</i> in favor of the Envy.</p>
<p>The Mac&#8217;s poor marks largely stem from its age. This is the newest 15&#8243; laptop, according to Apple&#8217;s own store, yet it is using a processor and video card that were released in July 2008 and June 2008, respectively. On the other hand, the Envy has a video card from last month and a processor from September of 2009.</p>
<p>So why the price discrepancy? $650 <i>more</i> than the up-to-date Envy is an enormous sum to pay for a laptop that was largely produced a year and a half ago. It doesn&#8217;t help matters to be reminded that this is the performance line of laptop, nearly Apple&#8217;s highest attainable 15&#8243; without going deeper in to terrible price-per-performance territory. (see below)</p>
<p>I don&#8217;t mean to say the MacBook Pro will <i>never</i> be worth its cost. It is expected that Apple will be refreshing its product line in the very near future, but in the interim it seems almost cruel to Mac fans to charge so much for pathetically dated technology. Right now is quite possibly the worst time to buy a MacBook Pro.</p>
<p>I guess people who consider MacBook Pros are only comparing them to other (past) MacBook Pros, and in solely that light they&#8217;re clearly well-endowed. The only reason to buy a MacBook Pro at this point in time would be an enormous desire for OSX over any other operating system coupled with a belligerent ignorance of computer hardware timelines. What&#8217;s more absurd than the price is be that <a href="http://www.9to5mac.com/macbook_sales_are_exploding">Apple still seems to be selling the things.</a></p>
<p>I&#8217;m sure others have made this observation in the past, but I get the feeling that Apple actually holds their users hostage. If Apple opened up OSX to be installable on non-Mac platforms it would almost surely kill the MacBook Pro of today, or maybe just force them into using hardware that isn&#8217;t trash. Hardware <i>this</i> old for <i>that</i> much just seems gimmicky, or even dishonest.</p>
<p>Other upgrades not added to my table don&#8217;t help the Mac much:<br />
The MacBook Pro has an optional Intel Core2 Duo T9900 @ 3.06GHz, which came out in April 2009, (passmark 2328) +$300 for 333 more passmark points<br />
The Envy has an optional Intel Core i7 820QM @ 1.73GHz, brand new, (passmark 3708) +$400 for 412 more passmark points</p>
<p>The Mac can be upgraded to 8GB for $600 more while the Envy can be upgraded to 8GB for $300 more. The HP has a large advantage even with after-market upgrades due to it having 4 RAM slots instead of 2.</p>
<p>As an aside, there are a few other aspects of the laptops that could be compared that I didn&#8217;t factor in to the above because they are hardly worth mentioning once the processor and video card age are apparent, but I&#8217;ll list them here for those interested. The HP wins on the battery side of things (life is debatable, being able to swap out batteries is not. Like I said above the Envy also has more RAM upgrade options as well as two HDD slots. I didn&#8217;t look much at sound, but I&#8217;m going to guess that the MacBook Pro&#8217;s speakers produce better sound than the Envy. The Envy also has no optical drive inside of itself (remember the second HDD slot), so I added the HP external USB optical option to my configuration, which added (surprisingly only) $50 to its price.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonsarris.com/blog/19-mac-envy/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
