-
Notifications
You must be signed in to change notification settings - Fork 2
/
atom.xml
704 lines (599 loc) · 67.9 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[cgack]]></title>
<link href="http://cgack.github.com/atom.xml" rel="self"/>
<link href="http://cgack.github.com/"/>
<updated>2012-01-27T18:35:27-05:00</updated>
<id>http://cgack.github.com/</id>
<author>
<name><![CDATA[Cory Gackenheimer]]></name>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[DeviceOrientation Events]]></title>
<link href="http://cgack.github.com/blog/2012/01/27/deviceorientation-events/"/>
<updated>2012-01-27T18:04:00-05:00</updated>
<id>http://cgack.github.com/blog/2012/01/27/deviceorientation-events</id>
<content type="html"><![CDATA[<p>The Mozilla Dev Derby is a pretty cool thing. Developers from around the world can openly add any demo to the site, and if their demo lines up with the prescribed derby for the month, they are automatically entered to win a prize (t-shirt, cool bag, android device). I decided I would enter again for the January 2012 derby based on Orientation. I made two demos.</p>
<h3>catch</h3>
<p>The first one called “Catch” which you are attempting to catch a randomly generated ball in the shortest amount of time possible. I have personally found it incredibly addicting to get the perfect game, or at least my best attempt at it and I even wrote the source code. What I learned in developing this app was a couple of things. One, there isn’t a ton of documentation on the web about the DeviceOrientationEvent. Two, its pretty straightforward to detect the orientation and utilize it to move an object. Here is the basic of my app:</p>
<pre><code> /*orientation stuffs*/
var initOrientation = function() {
var count = 0, gam = 0, bet = 0;
if (window.DeviceOrientationEvent) {
window.addEventListener("deviceorientation", function(e) {
//gamma = left to right
//beta = front back
//alpha = compass dir
count = count + 1;
gam += e.gamma;
bet += e.beta;
if (count === 0 || count % 10 === 0) {
orientationYo(gam, bet);
gam = 0;
bet = 0;
}
}, false);
}
};
//handle orientation
var orientationYo = function(ltr, ftb) {
coor.x = coor.x + ltr;
coor.y = coor.y + ftb;
if (!gameState.victory && gameState.playing) {
tgt.move(coor);
}
};
</code></pre>
<p>so that handles the detection of the orientation event, next I simply added the move call to my target (tgt) which looks like this:</p>
<pre><code>var tgt = {
isDrawing: false,
collided: false,
start: function(coordinates) {
this.drawIt(coordinates);
this.isDrawing = true;
},
drawIt: function (coordinates) {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.fillStyle = b2_color;
ctx.beginPath();
ctx.arc(coordinates.x, coordinates.y, 25, 0, Math.PI * 2, true);
ctx.fill();
},
move: function(coordinates) {
if (this.isDrawing) {
this.checkBounds(coordinates);
this.drawIt(coordinates);
}
},
finish: function(coordinates) {
this.isDrawing = false;
ctx.lineTo(coordinates.x, coordinates.y);
ctx.stroke();
ctx.closePath();
},
checkBounds: function(coordinates) {
if (coordinates.y > bound.y2) {
coordinates.y = bound.y2;
} else if (coordinates.y < bound.y1) {
coordinates.y = bound.y1;
} else if (coordinates.x > bound.x2) {
coordinates.x = bound.x2;
} else if (coordinates.x < bound.x1) {
coordinates.x = bound.x1;
}
}
};
</code></pre>
<p>collision detection is handled by my randomly placed bouncing ball, which detects when the target ball moves into its path:</p>
<pre><code>checkObjectCollisions: function() {
var imgData = ctx.getImageData(this.position.x + this.velocity.x1, this.position.y + this.velocity.x2, r, r),
pix = imgData.data;
for (i = 0, n = pix.length; i < n; i += 4) {
if (pix[i] !== 0) {
this.collided = true;
if (Math.abs(this.velocity.x1) > Math.abs(this.velocity.x2)){
this.velocity.x1 = -this.velocity.x1 * drag;
} else {
this.velocity.x2 = -this.velocity.x2 * drag;
}
break;
} else {
this.collided = false;
}
}
}
</code></pre>
<p>I am pretty happy with the game, its clean and works nicely. You can check it out <a href="https://developer.mozilla.org/en-US/demos/detail/catch">here</a></p>
<h3>compass</h3>
<p>The other is a simple web compass where I utilize the DeviceOrientationEvent to get the <a href="https://developer.mozilla.org/en-US/demos/detail/simple-compass">cardinal direction your phone or device is facing</a>. There are two cool (in my opinion) things that happened here. One is that to me it seems the device orientation event as defined states that the DeviceOrientationEvent.alpha ranges from 0 to 360 which to me is a 361 degree circle. The second is that I was able to utilize the offline caching capabilities of the modern web to make the compass available to a device event when not connected to the internet. This is done in minimal lines of code. The HTML and JavaScript are as follows:</p>
<pre><code><!-- This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this file,
You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html>
<html manifest="compass.appcache">
<head>
<meta charset=utf-8 />
<title>Cardinal Direction Compass</title>
<style>
.pointer {
height: 0;
width: 0;
border-left: 3em solid transparent;
border-right: 3em solid transparent;
border-bottom: 12em solid black;
margin: -10px 0 0 -40px;
top: 40%;
left: 50%;
position: absolute;
}
.n {
top: 20%;
left:50%;
position:absolute;
font:8em Helvetica;
margin: 0 0 0 -40px;
}
</style>
<script src="js/jquery.js"></script>
</head>
<body>
<div class="n">N<br><br><br><br>S</div>
<div class="pointer"></div>
<script>
$(document).ready(function() {
var rotate = function (deg) {
$(".n").css({ "-moz-transform": "rotate(0deg)"});
$(".n").css({ "-moz-transform": "rotate(" + deg + "deg)"});
$(".n").css({ "-o-transform": "rotate(0deg)"});
$(".n").css({ "-o-transform": "rotate(" + deg + "deg)"});
$(".n").css({ "-ms-transform": "rotate(0deg)"});
$(".n").css({ "-ms-transform": "rotate(" + deg + "deg)"});
$(".n").css({ "-webkit-transform": "rotate(0deg)"});
$(".n").css({ "-webkit-transform": "rotate(" + deg + "deg)"});
$(".n").css({ "transform": "rotate(0deg)"});
$(".n").css({ "transform": "rotate(" + deg + "deg)"});
};
if (window.DeviceOrientationEvent) {
window.addEventListener("deviceorientation", function (e) {
rotate(360 - e.alpha);
}, false);
}
});
</script>
</body>
</html>
</code></pre>
<p>The final point I’d like to make is that due to what I thought was minimal documentation, I participated in a Mozilla Doc Sprint last weekend to update the Documentation surrounding the DeviceOrientationEvent. Doing my part in the web development community was both rewarding and a learning experience. I encourage anyone to try it out as well.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Widget]]></title>
<link href="http://cgack.github.com/blog/2012/01/07/widget/"/>
<updated>2012-01-07T21:20:00-05:00</updated>
<id>http://cgack.github.com/blog/2012/01/07/widget</id>
<content type="html"><![CDATA[<p>I have lately been looking to become more involed with open source projects and for starters I have been looking at jQuery UI and jQuery Mobile. Both are amazing projects and share many of the same characteristics in their code. This is because in both cases, the majority of the functionality is inherited from the jQuery UI widget factory. If I’m going to become involved in this project
I should understand how this works, so the following is my breakdown of the code as I understand it.</p>
<p>The widget factory looks like the following:</p>
<pre><code>$.widget = function( name, base, prototype ) {
var namespace = name.split( "." )[ 0 ],
fullName;
name = name.split( "." )[ 1 ];
fullName = namespace + "-" + name;
if ( !prototype ) {
prototype = base;
base = $.Widget;
}
// create selector for plugin
$.expr[ ":" ][ fullName ] = function( elem ) {
return !!$.data( elem, name );
};
/* OTHER STUFF */
}
</code></pre>
<p>I’ll get to the stuff in a second, but lets see what we’ve already learned here. First I see that widget can take up to three arguments (name, base, prototype), and example might be something like</p>
<pre><code>$.widget("cg.awesomewidget, "ui.button", { /*...*/})
</code></pre>
<p>here name or “cg.awesomewidget” becomes the namespace and fullname so in my example I have namespaced it to “cg” with a fullname of “cg-awesomewidget”. I also see that we check if prototype is provided, if it is not we assume that we are not inheriting from a named widget, set the base parameter to prototype and set the base to the main $.Widget base object. Okay that sounds more messy than it is. Lets try to rephrase. The base is an optional parameter telling the widget factory we want to inherit from a known widget. In my example above its “ui.button”. If that parameter is not provided it simply pulls from the base $.Widget. So we know that <strong>any</strong> widget will carry the prototype base of
$.Widget for starters. Now, what about this prototype? This is the base object literal
that the widget makes its prototype. Sweet right? The next fun fact is that our widget gets its
very own shiny new custom selector $(“:cg-awesomewidget”).</p>
<p>Next the object is constructed via the jQuery.extend() method as follows:</p>
<pre><code>$[ namespace ] = $[ namespace ] || {};
// create the constructor using $.extend() so we can carry over any
// static properties stored on the existing constructor (if there is one)
$[ namespace ][ name ] = $.extend( function( options, element ) {
// allow instantiation without "new" keyword
if ( !this._createWidget ) {
return new $[ namespace ][ name ]( options, element );
}
// allow instantiation without initializing for simple inheritance
// must use "new" keyword (the code above always passes args)
if ( arguments.length ) {
this._createWidget( options, element );
}
}, $[ namespace ][ name ], { version: prototype.version } );
</code></pre>
<p>here the $[ namespace ][ name ] object is merged together with the prototype.version into the
existing constructor as described in the comments. Then the options are passed along to the
base. Again this is done via jQuery extend.</p>
<pre><code>var basePrototype = new base();
// we need to make the options hash a property directly on the new instance
// otherwise we'll modify the options hash on the prototype that we're
// inheriting from
basePrototype.options = $.widget.extend( {}, basePrototype.options );
</code></pre>
<p>This is followed up with a call to $.each() that checks all the functions of the base and applies
those to our new widget.</p>
<pre><code>$.each( prototype, function( prop, value ) {
if ( $.isFunction( value ) ) {
prototype[ prop ] = (function() {
var _super = function() {
return base.prototype[ prop ].apply( this, arguments );
};
var _superApply = function( args ) {
return base.prototype[ prop ].apply( this, args );
};
return function() {
var __super = this._super,
__superApply = this._superApply,
returnValue;
this._super = _super;
this._superApply = _superApply;
returnValue = value.apply( this, arguments );
this._super = __super;
this._superApply = __superApply;
return returnValue;
};
}());
}
});
</code></pre>
<p>After all of this its time to put it all together. The widget prototype is now set via extend where
we extend our basePrototype (widget) merging in the new widget and prototype. The last thing needed is a call to $.widget.bridge() which creates an instance of the object.</p>
<pre><code>$[ namespace ][ name ].prototype = $.widget.extend( basePrototype, {
namespace: namespace,
widgetName: name,
widgetEventPrefix: name,
widgetBaseClass: fullName
}, prototype );
$.widget.bridge( name, $[ namespace ][ name ] );
</code></pre>
<p>That concludes our walkthrough of the jQuery UI widget factory. Fairly amazing when you look at how simple it is to create a widget based on this. A simple example is a look at jquery.ui.tooltip.js</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Collision Detection on Canvas]]></title>
<link href="http://cgack.github.com/blog/2011/12/28/collision-detection-on-canvas/"/>
<updated>2011-12-28T16:59:00-05:00</updated>
<id>http://cgack.github.com/blog/2011/12/28/collision-detection-on-canvas</id>
<content type="html"><![CDATA[<p>I was toying around with a bouncing ball on an HTML canvas the other day when I wanted to find an easy way to detect collisions. One thing that is easy is validating against the bounds of the canvas. This is done with a simple check on the bounds of the canvas as follows:</p>
<pre><code>//this is a Ball object
if (this.position.y > bound.y2) {
this.velocity.x2 = -this.velocity.x2 * drag;
this.position.y = bound.y2;
} else if (this.position.y < bound.y1) {
this.velocity.x2 = -this.velocity.x2 * drag;
this.position.y = bound.y1;
}
if (this.position.x < bound.x1) {
this.velocity.x1 = -this.velocity.x1 * drag;
this.position.x = bound.x1;
} else {
if (this.position.x > bound.x2) {
this.velocity.x1 = -this.velocity.x1 * drag;
this.position.x = bound.x2;
}
}
</code></pre>
<p>You’ll see that if we get the Ball beyond the bounds of either axis we reverse the velocity vector (and for my example) I augment that vector with some drag. Then I start the Ball off (headed the other direction now) from the start of the boundary. This is straight forward and not too difficult to come up with. The same can be done for other shapes on the canvas which we do not wish for the ball to pass through. These again can be simple if we know the layout and the position of the target walls (think floating boxes). Where this gets to a point where the shapes are not at right angles or the boundaries have become more arbitrary, I no longer want to calculate each possible collision point. I also do not wish to wrap the object into a larger boundary box to utilize for detection. So a more elegant solution can be found. If we, just before moving the ball, simulate the move and have another means for detection we can then change the trajectory of the object and send it sailing away. Here’s what we need. we need a ball sized snapshot of the canvas where we plan to put the ball on the next move. We then iterate through those pixels on the image and find ones that arent the color of our background (in my case non-white). To do this without also seeing the ball as a collided upon object, I’ll clear the canvas of the ball first. Here is the code:</p>
<pre><code>//clear canvas, add shape
context.clearRect(0, 0, canvasWidth, canvasHeight);
context.fillStyle = "rgb(150,150,150)"; //not white
context.beginPath();
context.moveTo(200, 100);
context.lineTo(300, 125);
context.lineTo(250, 175);
context.lineTo(200, 200);
context.lineTo(200, 100);
context.fill();
context.closePath();
//now we check our next move for collision
var imgData = context.getImageData(this.position.x + this.velocity.x1, this.position.y + this.velocity.x2, r, r);
var pix = imgData.data;
for (var i = 0; n = pix.length, i < n; i += 4) {
//check if we're not on a white pixel
if (pix[i] != 0) {
this.collided = true;
//bounce away
if (Math.abs(this.velocity.x1) > Math.abs(this.velocity.x2)){
this.velocity.x1 = -this.velocity.x1 * drag;
} else {
this.velocity.x2 = -this.velocity.x2 * drag;
}
break;
} else {
this.collided = false;
}
}
</code></pre>
<p>Thats it! Now we can throw our ball at a target. The demo I have is located at <a href="http://jsfiddle.net/cgack/mwsBY/">this jsFiddle</a>.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Book Review: The Tangled Web]]></title>
<link href="http://cgack.github.com/blog/2011/12/23/book-review-the-tangled-web/"/>
<updated>2011-12-23T07:39:00-05:00</updated>
<id>http://cgack.github.com/blog/2011/12/23/book-review-the-tangled-web</id>
<content type="html"><![CDATA[<p>Browsers are not secure. They won’t ever be invincible to malicious attacks. Browser A does not serve the same set of security mechanisms as Browser B. These points are highlighted in Michal Zalewski’s book “The Tangled Web: A Guide to Securing Modern Web Applications”, but Zalewski, an expert in browser security and author of <a href="http://code.google.com/p/browsersec/">Google’s Browser Security Handbook</a>, discusses in detail common and known vulnerabilities, providing hints and tips to keep web applications as secure as possible along the way.</p>
<p>The book starts with a relatively exhaustive dissection of the “Anatomy of the Web”, highlighting the history of the web, from HTTP up to Plug-ins such as Flash and Silverlight all while noting some of the varying browser implementations of many common web functionalities. For example when discussing the Content-Disposition Header, Zalewski notes that these headers “are truncated at NUL by Internet Explorer, Firefox, and Chrome but not by Opera or Safari”,</p>
<p>In parts Two and Three of the book, the meat of browser security features are discussed in depth. Highlights include a detailed look at the Same Origin Policy for all aspects of the modern web, including Scripts, XHR, Cookies, and Plugins. Another intriguing look into browser inner workings was the sections on special psuedo urls such as about:, javascript:, and data: and how these can lead to interesting handlings of the origination of the requests across browser implementations. For example about:blank can be navigated to from an Existing non-same-origin page and have its origin inherited from the caller in Firefox, Webkit, and Opera while gaining a unique origin in Internet Explorer.</p>
<p>Perhaps one the most valuable parts of “The Tangled Web” is how Zalewski adds a handy “Security Engineering Cheat Sheet” to the end of each chapter. Having these quick tips at ones fingertips is a remarkable asset and great addition to the book. I could continue to outline the great parts of this book, and tout the security expertise that jumps from the pages, but the most important parts in the book are what each reader takes away. Whether its a small attack vector that a reader picks up on to close a vulnerability in their own web application, or an interesting fact about browser inconsistencies, each reader should gain something from this book. For me, the take away is that as a developer there is no magic bullet and we will always uncover new security holes in our web applications, either from poor programming, or new features of a browser’s implementation. And that our expectations should not be that we have a perfectly impenetrable web, or are capable of producing one. Zalewski puts it like this, “As the complexity of our online interactions approaches that of real life, the odds of designing perfectly secure software are rapidly diminishing”</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Canvas, History, LocalStorage and More]]></title>
<link href="http://cgack.github.com/blog/2011/12/19/canvas/"/>
<updated>2011-12-19T18:17:00-05:00</updated>
<id>http://cgack.github.com/blog/2011/12/19/canvas</id>
<content type="html"><![CDATA[<p>A few months ago I entered the <a href="https://developer.mozilla.org/en-US/demos/devderby/2011/august/">August Mozilla Dev Derby</a>, which focused on the History API. I have seen some of the amazing things that the new changes to this interface have been able to make from folks like <a href="https://www.facebook.com/note.php?note_id=438532093919">Facebook</a> and <a href="https://github.com/blog/760-the-tree-slider">GitHub</a> but I wanted to try something a little different. I had been hacking on a simple drawing canvas and decided that I could leverage the History API to create a more application like experience. Since winning the Derby, I’ve seen my code improved and extended in a <a href="https://developer.mozilla.org/en-US/demos/detail/paint-search">later Dev Derby Entry</a>, and I turned it into a sample <a href="https://apps-preview.mozilla.org/en-US/apps/app/draw/?src=cb-dl-free">application</a> for <a href="https://apps-preview.mozilla.org/en-US/apps/">Mozilla’s new App experience</a>. Here’s a peek into the process of creating a drawing demo like the one I created.</p>
<h2>Basic Setup</h2>
<p>Firstly, we’re going to need to create a canvas. This is pretty straightforward for those who have done this sort of thing before, but for a reminder that can look like the following</p>
<pre><code> <!DOCTYPE html>
<html>
<body>
<div id="content">
<canvas id="canvas" height="500" width="500"></canvas>
</div>
</body>
</html>
</code></pre>
<p>Now that we have our canvas we can start to initialize it and get ready to roll with the fun features we’d like to demonstrate.</p>
<pre><code>var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
img, //more about this later
blankCanvas = true; //this too
</code></pre>
<p>We now need to set it up to allow for drawing. This is done by adding a event listeners to the mouse events we’d like to watch.</p>
<pre><code>window.addEventListener("mousedown", setupDraw, false);
window.addEventListener("mousemove", setupDraw, false);
window.addEventListener("mouseup", setupDraw, false);
</code></pre>
<p>You’ll notice the setupDraw function is called on all of these events. This function will grab the coordinates of our pointer (less the offset of our lovely #content div and send those to our draw object.</p>
<pre><code>function setupDraw(event) {
var cnt = document.getElementById("content"),
coordinates = {
x: event.pageX - cnt.offsetLeft,
y: event.pageY - cnt.offsetTop
};
draw[event.type](coordinates);
};
</code></pre>
<p>Now time for the drawing I’ll go ahead and let you peek at the source so you can follow along.</p>
<pre><code>var draw = {
isDrawing: false,
mousedown: function(coordinates) {
ctx.beginPath();
ctx.moveTo(coordinates.x, coordinates.y);
this.isDrawing = true;
},
mousemove: function(coordinates) {
if (this.isDrawing) {
ctx.lineTo(coordinates.x, coordinates.y);
ctx.stroke();
}
},
mouseup: function(coordinates) {
this.isDrawing = false;
ctx.lineTo(coordinates.x, coordinates.y);
ctx.stroke();
ctx.closePath();
}
};
</code></pre>
<p>You’ll see this object directs to an event type specific function and handles the coordinates parameters which are passed into the object. Following some basic canvas drawing steps for ctx.beginPath() -> ctx.moveTo(x,y) -> ctx.lineTo(x,y) -> ctx.stroke() -> ctx.closePath() we now have the ability to draw with our mouse. The “isDrawing” property is there to let us know to continue our strokes on mousemove. Now that we have an example that allows us to draw, we’ll move forward to make it more interesting by utilizing the History API and LocalStorage.</p>
<h2>About the History API</h2>
<p>One of the new features in HTML5 (an subject of the Dev Derby) is the additional features of the History API. These are history.pushState(data,title [,url]) and history.replaceState(data, title [,url] ) which are utilized to directly push (or replace) data in the session history. For the purposes of this demo we’ll be using pushState to add data, specifically the image data from the canvas, to the current URL. Now this alone is not enough we will also need to know when the current state changes, which is made accessible to us via the window.onpopstate event. This event fires when the browser gets a new history event. We can inspect the event to see if it contains a state and then load the data (hopefully our image) into the canvas. So to get things wired up correctly, its time to add a function to store the history.</p>
<pre><code>var storeHistory = function () {
img = canvas.toDataURL("image/png");
history.pushState({ imageData: img }, "", window.location.href);
};
</code></pre>
<p>This grabs the data from the canvas in the form of a “data:image/png…” url. Then we create a new history state by pushing an imageData attribute for later retrieval. Now, before we add the calls to storeHistory to our drawing application, we need to do a bit of preventative maintenance. If we store this data and navigate backward without a reinitialization of the canvas, we will just draw the stored imageData onto the existing image. To us this will look like it isn’t working so we need to add an initialization function to reset our canvas.</p>
<pre><code>var initializeCvs = function () {
ctx.lineCap = "round";
ctx.save();
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.restore();
}
</code></pre>
<p>Now we can go about the business of storing our history states. The code that follows will store history in two places. The first place it stores is if the canvas is blank it stores that before drawing anything. The second is on the mouseup event after the line is completed. Now our draw object looks like this:</p>
<pre><code>var draw = {
isDrawing: false,
mousedown: function(coordinates) {
if (blankCanvas) { storeHistory(); blankCanvas = false; }
ctx.beginPath();
ctx.moveTo(coordinates.x, coordinates.y);
this.isDrawing = true;
},
mousemove: function(coordinates) {
if (this.isDrawing) {
ctx.lineTo(coordinates.x, coordinates.y);
ctx.stroke();
}
},
mouseup: function(coordinates) {
this.isDrawing = false;
ctx.lineTo(coordinates.x, coordinates.y);
ctx.stroke();
ctx.closePath();
storeHistory();
}
};
</code></pre>
<p>Awesome, now we have started storing history on the page with each completed line. Now we need to be able to see the results of this work when the history state changes. As I mentioned earlier this is done via the window.onpopstate event. We will examine the imageData of the state (if it exists) and place that image on the canvas as follows:</p>
<pre><code> window.onpopstate = function (event) {
if (event.state !== null) {
img = new Image();
img.onload =function () {
ctx.drawImage(img, 0, 0);
};
img.src = event.state.imageData;
}
};
</code></pre>
<p>Splendid, we now have a drawing tool that stores history so we can undo and redo drawings. But wait! What happens if I’m in the middle of a canvas masterpiece and my browser crashes? Lets handle that with localStorage. With localStorage we can store a named item locally independent of our session, so in the event of leaving the page, we can retrieve data from our previous encounter. In this demo I did a simple test of the window.localStorage object to see if we can store data, and then I store the latest image so upon return you’ll at least be able to recover that data. Here are the initializeCanvas and storeHistory functions with this additional feature added:</p>
<pre><code>var initializeCvs = function () {
ctx.lineCap = "round";
ctx.save();
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.restore();
if (window.localStorage) {
img = new Image();
img.onload = function () {
ctx.drawImage(img, 0, 0);
};
if (localStorage.curImg) {
img.src = localStorage.curImg;
blankCanvas = false;
}
}
}
var storeHistory = function () {
img = canvas.toDataURL("image/png");
history.pushState({ imageData: img }, "", window.location.href);
if (window.localStorage) { localStorage.curImg = img; }
};
</code></pre>
<p> You can see the full working demo in <a href="http://jsfiddle.net/cgack/JHr2P/">this jsFiddle</a>.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Moving to Octopress]]></title>
<link href="http://cgack.github.com/blog/2011/11/08/moving-to-octopress/"/>
<updated>2011-11-08T22:14:00-05:00</updated>
<id>http://cgack.github.com/blog/2011/11/08/moving-to-octopress</id>
<content type="html"><![CDATA[<p>I have been toying with the idea to move away from blogger to another blogging engine. Since I’ve been doing most of my hacking via Github I have decided to move to <a href="http://octopress.org">Octopress</a>. I have imported most my old posts and hopefully the conversion hasn’t caused too much trouble. The original posts can still be found on my <a href="http://blog.cgack.com">blogger blog</a></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Snakes in the Cloud]]></title>
<link href="http://cgack.github.com/blog/2011/10/22/snakes-in-the-cloud/"/>
<updated>2011-10-22T17:38:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/10/22/snakes-in-the-cloud</id>
<content type="html"><![CDATA[<div class="separator" style="clear: both; text-align: center;">
<br /></div>
I used to think that building web applications in Python for Google’s app engine was reserved for a desktop development environment. I had hacked a bit on an app or two and used the command line tools to test and publish to the app engine. Then I discovered <a href="https://coderbuddy1.appspot.com/">CoderBuddy</a>. CoderBuddy is a one stop shop for building python apps for the app engine. Once signed in you can create a blank project, or get a head start with one of six template apps. One template is of course a “hello world” app, but there are a few other samples including 3 that come with some <a href="https://www.djangoproject.com/">Django</a> (arguably the go to MVC framework for python web applications). I tested a couple of the template apps and found them to be quite useful. The “Adrian Remembers Me” template creates an app that allows users to become members and sign in. Here is a look at the editor with the main.py file opened for this project:<a href="http://2.bp.blogspot.com/-ES_BL0gUWTM/TqLjtn668qI/AAAAAAAAApU/-SwPW-jQsw8/s1600/cgack2-coderbuddy+-+CoderBuddy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="256" src="http://2.bp.blogspot.com/-ES_BL0gUWTM/TqLjtn668qI/AAAAAAAAApU/-SwPW-jQsw8/s400/cgack2-coderbuddy+-+CoderBuddy.png" width="400" /></a><br />
<br />
<br />
Each of these templates could be either a good launching point or reference for a new developer looking to quickly create a Python app. Deploying to the App Engine is just a few clicks away with CoderBuddy. So I “created” my Adrian Remembers Me app in one click and about two minutes later had my site running on the app engine at <a href="http://cgack2-coderbuddy.appspot.com/">http://cgack2-coderbuddy.appspot.com/</a>. The ease of deploy along with the ability to upload files and download the project as a .zip I will definitely look to CoderBuddy for part if not all of my next project.
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Cloud 9 adds Heroku Support]]></title>
<link href="http://cgack.github.com/blog/2011/09/02/cloud-9-adds-heroku-support/"/>
<updated>2011-09-02T00:00:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/09/02/cloud-9-adds-heroku-support</id>
<content type="html"><![CDATA[One of my favorite online IDEs has added support for Heroku. This is great news as I have enjoyed developing node.js applications in <a href="http://c9.io/">Cloud9</a> but felt that the main thing it lacked was a method to deploy directly to the cloud. So I took it for a test run. I signed in to Cloud 9 and created a simple hello world app, make sure you use the process.env.PORT to listen on so Heroku can deploy it properly.<br /><br />Commit your changes via the Cloud 9 git interface.Then all you have to do is click the Deploy button in Cloud 9, sign in to Heroku, create your new instance, and deploy. If you haven’t created a package.json or Procfile (needed for Heroku deploy), Cloud 9 will create those for you. My hello world is at <a href="http://cheese.herokuapp.com/">http://cheese.herokuapp.com/</a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7333770831047956364-6512242240963047422?l=go-cloud-go.blogspot.com' alt='' /></div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[github goes ace (and demos)]]></title>
<link href="http://cgack.github.com/blog/2011/08/25/github-goes-ace-and-demos/"/>
<updated>2011-08-25T00:00:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/08/25/github-goes-ace-and-demos</id>
<content type="html"><![CDATA[A week ago <a href="http://github.com/">GitHub</a> <a href="https://github.com/blog/905-edit-like-an-ace">announced</a> they were incorporating the Ace editor (which powers the <a href="http://c9.io/">Cloud9 IDE</a>). Since I am a fan of both Cloud9 and GitHub, I gave it a whirl on my <a href="http://cgack.github.com/">GitHub Pages site</a> and was not disappointed. As advertised one can easily open a file for editing, preview the diff of your changes and commit. I think it will likely become useful to edit posts when (if) I finally decide to move my blog from here at Blogger to <a href="http://octopress.org/">Octopress</a> (just because it looks fun). For me, this is particularly useful for simple changes like those I have made to my demos and experiments. Speaking of demos, I had created a simple drawing app using HTML5 canvas for my preschooler which evolved into a demo of the HTML5 History API thanks to a tweet by Christian Heilmann and subsequent read of his <a href="http://hacks.mozilla.org/2011/08/making-history-with-the-august-dev-derby/">blog post</a>. I decided to use this History API to create the undo/redo functionality that I rely on heavily if i’m trying to draw something in a painting tool. As a bonus I added a localStorage call that will recreate your last drawing if your browser closes or you are forced to leave the site for a while. What does that look like:<br />
<br /> I entered the demo in the <a href="https://developer.mozilla.org/en-US/demos/devderby">DevDerby</a>, you can find it <a href="https://developer.mozilla.org/en-US/demos/detail/html5-drawings">here</a>. I hope you ’like’ it too. (note: I’ve only really tested my demo on firefox 5, 6, 7, and 8 as well as chrome 13 & 14, so your results may vary if you use a different browser)<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7333770831047956364-6571414986215912499?l=go-cloud-go.blogspot.com' alt='' /></div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Chrome Dev Tools as an IDE]]></title>
<link href="http://cgack.github.com/blog/2011/07/08/chrome-dev-tools-as-an-ide/"/>
<updated>2011-07-08T00:00:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/07/08/chrome-dev-tools-as-an-ide</id>
<content type="html"><![CDATA[I’ve spent a lot of time trying to find the best development method in Chrome OS. Recently I decided I wanted to create a chrome extension using Chrome OS. My first stop was CodeRun IDE which has a sample Chrome Extension project so I thought it would be great for a starter. The development is pretty mess free, but the problem comes once its downloaded. It comes downloaded and zipped. When loading an unpackaged Chrome Extension you can point Chrome to a directory, but not a zipped directory. So I had to unzip the files…which was pretty easy to do once I found <a href="http://wobzip.org/">wobzip</a>.<br /><br />Now that I had a skeleton Chrome Extension up and running, I could start to make it my own. I decided on a simple calculator for starters, plus I thought it might be useful. I have to admit it had been a while since I’d used the user ‘chronos’ in Developer mode, but once I got it there I found that Chrome OS had a new default text editor (thankfully) in ‘vi’. This is where it got really fun. I edited my popup.html file to have a stylesheet and JavaScript file and loaded the html directly in Chrome. Enter the best web app ever… Chrome Dev Tools.<br /><br />With Dev tools I am able to make changes to my stylesheets through the inspector to get the style just how I want, then save the modified .css file to the extension directory. <br /> Similarly, I can edit and save versions of my JavaScript file directly from Dev tools. The only issue with this is when I overlooked some invalid code which prevented Chrome from loading the JavaScript file. This was not much of an issue the one time it happened to me, as I was able to enter vi and quickly rectify the rogue curly brace and was back to Dev Tools in no time. So If you ask me what my choice is for rapid JavaScript development, I’ll say Chrome Dev Tools.<br /><br /> The result from blank files to:<br /><br /><br />and <br /><br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7333770831047956364-1069319577707889253?l=go-cloud-go.blogspot.com' alt='' /></div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[I Cloud]]></title>
<link href="http://cgack.github.com/blog/2011/06/07/i-cloud/"/>
<updated>2011-06-07T00:00:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/06/07/i-cloud</id>
<content type="html"><![CDATA[Earlier today Apple announced a revolutionary set of services called <a href="http://www.apple.com/icloud/">iCloud</a>. I must say it sounds incredible to be able to edit a <a href="http://docs.google.com/">document</a>, sync <a href="http://mail.google.com/">contacts</a>, view my <a href="http://www.google.com/calendar">calendar</a>, listen to <a href="http://music.google.com/">music</a>, read my electronic <a href="http://books.google.com/">books</a>, view my <a href="http://www.google.com/picasa">photos</a>, and access my <a href="http://mail.google.com/">email</a> from any internet enabled device. , It does seem like a great advantage to not have to upload to a cloud music service like the Amazon Cloud Player or Google Music, which iCloud offers via iTunes “scan and match” and I’m certain it will be another service I try in my attempt to find the best cloud experience. I’ve been happily clouding for some time now, and hope that Apple does good things in the space. Happy clouding.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7333770831047956364-747140899803548158?l=go-cloud-go.blogspot.com' alt='' /></div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Chromebook first dibs]]></title>
<link href="http://cgack.github.com/blog/2011/06/02/chromebook-first-dibs/"/>
<updated>2011-06-02T00:00:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/06/02/chromebook-first-dibs</id>
<content type="html"><![CDATA[Being a test pilot has some perks. The latest of which is a special invitation to early released Chromebooks via the Gilt Groupe. Below is the email I received earlier today inviting me to Gilt’s privileged offering of the newest Chromebook.<br /><br /><blockquote><span class="Apple-style-span" style="font-family:arial, sans-serif;font-size:13px;"></span><br /><table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="20" style="font-family:arial, sans-serif;font-size:13px;width:400px;"><tbody><tr><td colspan="2" style="font-family:arial, sans-serif;margin:0;"></td></tr><tr><td height="60" style="font-family:arial, sans-serif;margin:0;" valign="top" width="50%"><div style="margin:0;"><img border="0" src="http://www.google.com/chromebook/static/images/email/chrome-173x63.png" /></div></td><td align="right" height="60" style="font-family:arial, sans-serif;margin:0;" valign="top" width="50%"><div style="margin:0;"><img border="0" src="http://www.google.com/chromebook/static/images/email/giltgroupe-110x63.png" /></div></td></tr><tr><td colspan="2" height="30" style="font-family:arial, sans-serif;margin:0;" valign="top"><div style="margin:0;"><span style="font-family:Arial, sans;font-size:x-large;"><strong>Be the first to get a Chromebook.</strong></span></div></td></tr><tr><td colspan="2" style="font-family:arial, sans-serif;margin:0;"><div style="margin:0;"><span style="font-family:Arial, sans;font-size:x-small;">Since we announced the Chrome Notebook Pilot Program back in December, we’ve been humbled by the amount of interest that we’ve received from users like you.</span></div><div style="margin:0;"><span style="font-family:Arial, sans;font-size:x-small;">We’re excited about the brand-new Samsung Chromebook that goes on sale on June 15. Fortunately, we’ve managed to get our hands on a few machines a little earlier, and we’d like to make these available to you, our biggest enthusiasts.</span></div><div style="margin:0;"><span style="font-family:Arial, sans;font-size:x-small;">When you buy your Chromebook, you’ll also be getting a limited edition, custom-fit Chrome sleeve designed by Rickshaw so you can carry your new Chromebook in style.</span></div><div style="margin:0;"><span style="font-family:Arial, sans;font-size:x-small;">Our good friends over at Gilt, the premier invitation-only shopping site, have agreed to put these Chromebooks up for sale – but only for a very limited time.</span></div><div style="margin:0;"><img alt="Samsung Series 5 Chromebook" src="http://www.google.com/chromebook/static/images/email/samsung-series5-300x246.png" /></div><div></div></td></tr></tbody></table></blockquote><div class="blogger-post-footer"><img width='1' height='1' src='' alt='' /></div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Duostack acquired by dotCloud]]></title>
<link href="http://cgack.github.com/blog/2011/05/25/duostack-acquired-by-dotcloud/"/>
<updated>2011-05-25T00:00:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/05/25/duostack-acquired-by-dotcloud</id>
<content type="html"><![CDATA[A few weeks ago I wrote about utilizing the Duostack platform as a service to host a Node.js application on the cloud. Today Duostack announced they were joining forces with dotCloud, another platform as a service provider. Here is the announcement as I received it:<br /><br /><blockquote><table border="0" cellpadding="0" cellspacing="0" style="background-color:#3b5998;border-bottom:5px solid rgb(59,89,152);width:500px;"><tbody><tr><td style="color:#96a6c5;font-family:Arial;font-size:24px;font-weight:bold;line-height:100%;text-align:center;vertical-align:middle;padding:0;"> Duostack Announcement - May 24, 2011<br /><br /></td> </tr><tr> <td> </td> </tr></tbody></table><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> We are pleased to announce that Duostack is joining forces with DotCloud.</div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> </div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> DotCloud is a Platform as a Service that provides unsurpassed flexibility. Developers have the freedom to assemble their own deployment environment by selecting stack components on DotCloud, instead of being restricted to a limited stack configuration typical of cloud platforms. Supported components include PHP, Ruby, Python, Perl, Java, Node.js, MySQL, Redis, RabbitMQ, Solr, PostgreSQL, and now MongoDB.</div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> </div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> As part of DotCloud, we will continue to raise the bar for cloud platforms and further our commitment as the best place to deploy apps.</div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> </div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> See the full acquisition announcement here:</div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> <a href="http://duostack.us2.list-manage2.com/track/click?u=54f3e2020e67b0ac9e68cd450&id=06ed5b37c4&e=f3943c1bc8" style="color:#3b5998;font-weight:normal;text-decoration:underline;" target="_blank">DotCloud Acquires Duostack, Expands Footprint in PaaS Market to Further “One Platform, Any Stack” Vision</a></div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> </div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> <strong>What does this mean for apps hosted on Duostack?</strong></div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> Current Duostack developers will receive immediate access to DotCloud. Invite codes will be delivered by email.</div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> </div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> Apps currently hosted on Duostack will remain online through the end of June 2011. We will provide assistance for migrating apps to DotCloud. More information about the transition will be available this week.</div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> </div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> The Duostack name will be phased out. However, the best parts of the Duostack platform and the feedback from our beta program will be incorporated into DotCloud. This starts today as DotCloud launches support for MongoDB, and there is plenty more to come.</div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> </div><div style="color:#505050;font-family:Arial;font-size:14px;line-height:150%;text-align:left;"> We are very happy to welcome you to DotCloud.</div></blockquote><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7333770831047956364-6112486245904442994?l=go-cloud-go.blogspot.com' alt='' /></div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Chromebooks!]]></title>
<link href="http://cgack.github.com/blog/2011/05/12/chromebooks/"/>
<updated>2011-05-12T00:00:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/05/12/chromebooks</id>
<content type="html"><![CDATA[Yesterday, at Day 2 of Google I/O, it was officially announced that <a href="http://www.google.com/chromebook/#">Chromebooks</a> will be available in retail locations worldwide starting June 15th. Perhaps even more exciting news was the mention that for Educational institutions (and businesses) these would be available at $20/month/user ($28/mo/user for business) which could be a huge savings (70% over traditional PCs according to the graphic <a href="http://www.google.com/chromebook/#business-education">here</a>). <br /><br />Here is the Keynote from Google I/O day two for those who missed it:<br />[youtube http://www.youtube.com/watch?v=MiYND_zvIc0]<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7333770831047956364-771895672650425206?l=go-cloud-go.blogspot.com' alt='' /></div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Duostack: Cloud Platform as a Service]]></title>
<link href="http://cgack.github.com/blog/2011/05/02/duostack-cloud-platform-as-a-service/"/>
<updated>2011-05-02T00:00:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/05/02/duostack-cloud-platform-as-a-service</id>
<content type="html"><![CDATA[I have been using and trying many of the all-in-one solutions for web-based development on my Cr-48, but what happens when your favorite editor does not deploy directly to where you want your app to live (<a href="http://c9.io/">cloud9</a>)? I tried this recently with a <a href="http://nodejs.org/">NodeJS</a> app and a cloud platform (currently in beta) called <a href="https://www.duostack.com/">Duostack</a>. For my NodeJS app, just as everyone else toying with Node, I <strike>reinvented</strike> reworked the wheel and used Ryan Dahl’s (creator of NodeJS) basic chat application. All I did was partition the client to act like it had multiple rooms rather than one group room as in <a href="http://chat.nodejs.org/">the original</a>. That is not what this post is about. This post is about how easy it is to get a node instance up and running on Duostack.<br /><div><br /></div><div>Duostack is a super easy to use cloud platform as a service for Node and Ruby apps. Databases that are available by default are MySQL, MongoDB, and Redis (the documentation states external DBs are welcome). The deployments live on the Amazon EC2 by default, but there is ‘cross-cloud reliability’ that will allow for fail over to the Proactive Cloud in case of a <i>possible</i> Amazon outage. Deployment is as simple as it could get with a cloud platform (well it could get simpler, but its super easy as you can read below). </div><div><br /></div><div>To setup Duostack I had to move away from Chrome OS and into Ubuntu on my Cr-48. I followed the <a href="http://docs.duostack.com/node/command-line-client#setup">simple steps</a> to get the command line interface installed. I used the curl method versus the node package manager install and had my Duostack instance configured shortly thereafter. So now to create a Duostack app. This is even easier then setup of the command line client, simply type ‘duostack create ’ and you have it. Duostack uses Git to control deployment so deploying is also a snap, just feed the command ‘git push duostack master’ from your git repository, wait a few seconds while Duostack works the deployment magic, and you have your Duostack application deployed. Mine lives <a href="http://noderooms.duostack.net/">here</a>. So far I am more than pleased with my Duostack beta access and invite anyone with interest in deploying a Node or Ruby app to a cloud platform to <a href="https://www.duostack.com/signups/new">signup</a> and give it a try. I have a few other betas for platform as a service solutions to check out, but Duostack got first dibs by granting me beta access before the others.</div><div><br /></div><div><br /></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7333770831047956364-6022969820459559969?l=go-cloud-go.blogspot.com' alt='' /></div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[changing old habits]]></title>
<link href="http://cgack.github.com/blog/2011/04/27/changing-old-habits/"/>
<updated>2011-04-27T00:00:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/04/27/changing-old-habits</id>
<content type="html"><![CDATA[I have been doing a lot of development on my Cr-48 lately. And as I sit here coding away I wanted to note how useful chrome is to me as a developer. As I have written about previously there is a <a href="http://www.youtube.com/watch?v=_QI8nj6PSPI">plethora</a> of web-based IDEs to develop with in Chrome OS. So what I have been finding particularly useful regardless of the development environment is something any chrome user (I’m talking browser now, not OS) can utilize…the <a href="http://code.google.com/chrome/devtools/docs/overview.html">Chrome Developer Tools</a>. Before I received my Cr-48, the majority of my browser based debug sessions lived in Firefox with the amazing and powerful tool <a href="http://getfirebug.com/">Firebug</a>, but thanks to Google I was forced to try something new. I thought nothing else compared to Firebug (I am not going to speak out against Firefox or Firebug as both are spectacular), but as I have familiarized myself with the Chrome tools I find they are just as powerful and robust. I love how easy it is to inspect an element on the page and edit CSS and JavaScript, check network events, record a timeline, or just drill through local variables in the console. So if you are like I was, before you move from chrome to some other tool just to step through your JavaScript in the console, stop and give the Chrome Developer Tools a try, you might decide to stay.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7333770831047956364-5974311961422618634?l=go-cloud-go.blogspot.com' alt='' /></div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Chrome OS Everyday]]></title>
<link href="http://cgack.github.com/blog/2011/04/16/chrome-os-everyday/"/>
<updated>2011-04-16T00:00:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/04/16/chrome-os-everyday</id>
<content type="html"><![CDATA[Writing code in the browser with Chrome OS is an important item for me as a developer and there are a growing number of apps available to get your geek on in the cloud, but what else is awesome on Chrome OS? Tons of things. I have been <i>almost</i> exclusively utilizing my Cr-48 since early February at home, with the exception of my taxes (chrome beta/dev wasn’t supported), some photo management, the time when the developer build rendered the OS impossible to use (hooray for being a test pilot), and the occasional connection to my remote work computer. So it is promising that I am able to find a replacement for everything I do on a computer in Chrome OS with limited exceptions. What else?<br /><div><br /></div><div>I recently have been running some rigorous durability tests on my Cr-48, or I guess I should say Preschooler compatibility tests. I realized this was needed when I arrived at my son’s daycare to see a dozen preschoolers huddled around a computer clicking things and learning their letters, numbers, and sequences. At home my son enjoys the stock windows Paint… a bunch. What could I use on the Cr-48? <a href="http://muro.deviantart.com/">deviantArt muro</a> is a cool choice although it took us a bit to get used to the track pad. Of course the Chrome web store has many options like <a href="https://chrome.google.com/webstore/detail/mcbkbpnkkkipelfledbfocopglifcfmi">Poppit</a>, a balloon popping game which really tests the durability of the track pad. But one of my favorite apps is <a href="https://chrome.google.com/webstore/detail/jhfhmaajajcjoijfaceafiembkmhcddc">MeeGenius! Children’s Books</a>, which reads classic children’s books out loud and highlights the words as it reads. Our favorite kid friendly site is and has been the <a href="http://pbskids.org/">PBS kids site</a> which as an avid PBS kids family is full of friendly educational games from our most familiar characters. <br /><br />For me, I have recently been utilizing my Cr-48 to read books on <a href="http://books.google.com/">Google Books</a>. It may not read super easy in direct sunlight, but I can read at night without a light. There are tons of books, “over 3 million”, which is enough to keep any reader busy for a while. So there is plenty for everyone on Chrome OS, especially for everyday computer needs.</div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7333770831047956364-4704811775203935933?l=go-cloud-go.blogspot.com' alt='' /></div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[ShiftEdit web-based IDE]]></title>
<link href="http://cgack.github.com/blog/2011/04/09/shiftedit-web-based-ide/"/>
<updated>2011-04-09T00:00:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/04/09/shiftedit-web-based-ide</id>
<content type="html"><![CDATA[<span class="Apple-style-span" style="font-family:inherit;">I have come to the conclusion that there is plenty of selection for online application development using a web-based development environment. After trying out several online IDE’s over the last few months I was asked by a reader to check out <a href="http://shiftedit.net/">ShiftEdit</a>. I had read that this was an editor of choice for many on some of the Chrome OS forums where the question of what is used to develop on the Cr-48 usually shows up. So I decided I would try out another IDE to get a feel for how it compares to others I have tried.</span><br /><span class="Apple-style-span" style="font-family:inherit;"><br /></span><br /><span class="Apple-style-span" style="font-family:inherit;">First off, bonus points for allowing Google (or Facebook) login. After authentication, this feels like a desktop IDE similar to what I feel like in <a href="http://www.coderun.com/ide/">CodeRun</a>, <a href="http://c9.io/">Cloud9</a>, or <a href="http://www.akshell.com/ide/">Akshell</a> (I usually test this by going full screen on my Cr-48 and say its good if it isn’t obvious I am in a web browser). Selection of file formats is diverse and allows for PHP, HTML, JavaScript, CSS, Perl, Python, Ruby, Java, or Text with built-in FTP support, which is nice for those who enjoy diverse development. I tried to create a trivial web page and was pleased with the HTML editor with the exception of when I tried the split view (HTML and Design viewed at the same time) I found it hard to keep the focus on the HTML screen and ended up navigating away from the editor when hitting backspace to delete a <div>. This is not a huge deal as I would likely not develop full time in split view. </span><br /><span class="Apple-style-span" style="font-family:inherit;"><br /></span><br /><span class="Apple-style-span" style="font-family:inherit;">JavaScript editing is almost too full featured for my taste by default. There is an auto complete feature that will auto close brackets in your code as you type. I found that I was creating double closing brackets so I turned that feature off which was easy enough in the Edit -> Preferences menu. However, JSLint is a wonderful addition to any JavaScript Editor, and is fully configurable in the Preferences section (so if you don’t like to be forced to use === instead of == you can allow that).</span><br /><span class="Apple-style-span" style="font-family:inherit;"><br /></span><br /><span class="Apple-style-span" style="font-family:inherit;">A feature that I’ve recently learned is important to me in an online IDE is allowing for multiple tabs to be opened at once. ShiftEdit does this well. (I have been working a lot in Akshell for some recent development and the lack of tab support is nearly a deal breaker…along with the times when I log in and all the open files disappear and I have to select the current project again to restore the view). There are many other features that I have yet to try in ShiftEdit which could be handy, though I’m not sure I’ll try them out anytime soon. Perhaps I will never need to utilize them. </span><br /><span class="Apple-style-span" style="font-family:inherit;"><br /></span><br /><span class="Apple-style-span" style="font-family:inherit;">I have found I’m no longer sure what I’ll be using as my web-based development environment (most likely a combination of many, just as I develop in a desktop environment). I am fairly certain I have seen enough for now <span class="Apple-style-span" style="font-size:x-small;">(of course if you have found “the best” one, let me know, I’ll check it out)</span> that I will be able to find the one (or two, or three) that suits my needs best. Recently I’ve been trying all these IDE’s out and sticking with the current flavor of the week only to later find out certain limitations or something that I preferred in a different editor. This is no different than using a full featured text editor outside of Visual Studio for example to edit JavaScript or XML files because I don’t particularly care for the way these appear in Visual Studio. What I really need or want in a cloud-based IDE is still being defined as each one’s limitations or offerings reveal themselves through repeated use.</span><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7333770831047956364-9186502508601723025?l=go-cloud-go.blogspot.com' alt='' /></div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Cloud9 revisited]]></title>
<link href="http://cgack.github.com/blog/2011/04/03/cloud9-revisited/"/>
<updated>2011-04-03T00:00:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/04/03/cloud9-revisited</id>
<content type="html"><![CDATA[A while ago I <a href="http://go-cloud-go.blogspot.com/2011/03/coding-in-cloud-part.html">tried to use Cloud9 IDE</a> to code in the cloud on my Cr-48 and it was too buggy to even try to accomplish anything in it. It now appears that the issues have been resolved. I have been interested in learning some of the awesome that is <a href="http://nodejs.org/">node.js</a>. I could easily move to my Ubuntu partition, install and build node, and try it there. However, I really like Chrome OS and I’ve really been enjoying my other Google V8 JavaScript engine based development with <a href="http://www.akshell.com/">Akshell</a> so why not try Node.js in the cloud too. Cloud9 is the perfect place for this.<br /><br />First let me say the the github integration with Cloud9 is super smooth. To start editing a github based project just enter the github url and click “start editing”. So I created a new github repository and started a simple web server with node to see how it would go. I checked out one of Ryan Dahl’s (the creator of node.js) introductory videos to get a simple server created in my server JavaScript file. Then I setup the server configuration in Cloud9 which only required me to tell it which JavaScript file to use and what command line arguments to send it (i.e. “node server.js”) to get it running. Cloud9 does not let you specify a port number like one would in a desktop environment, but they add a helpful hint when running a server “Important: in your scripts, use ‘process.env.C9_PORT’ as port and ‘0.0.0.0’ as host.” So I modified the server file with the tip, clicked run and sure enough I created a node.js server.<br /><br />I think using node.js on Cloud9 is up to par with any other web-based IDE. One thing it lacks versus something like Akshell or Kodingen is the ability to deploy to a subdomain directly. I can however build my app up (if I continue to use Cloud9 versus Akshell) and then deploy to a node.js hosting platform like <a href="https://www.duostack.com/">duostack</a>. For now I plan on using Cloud9 to learn some node.js and see what things I can make with that.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7333770831047956364-764076792241002278?l=go-cloud-go.blogspot.com' alt='' /></div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[A Better Web-Based IDE]]></title>
<link href="http://cgack.github.com/blog/2011/03/26/a-better-web-based-ide/"/>
<updated>2011-03-26T00:00:00-04:00</updated>
<id>http://cgack.github.com/blog/2011/03/26/a-better-web-based-ide</id>
<content type="html"><![CDATA[After a few days this week without Chrome OS due to <a href="https://groups.google.com/forum/#!msg/chrome-notebook-pilot/biRRijQapdc/FDs_l-29szQJ">a fun error</a> in the Dev build (though its never bad to be able to revert to Ubuntu), I am able to be a Cr-48 nerd again. The other day one of the three readers of this blog tipped me off on <a href="http://www.akshell.com/">Akshell</a>, another online development environment, which I quickly dove into in order to compare it against some of my other favorites which I have checked out previously <a href="http://go-cloud-go.blogspot.com/2011/02/coding-in-cloud.html">here</a>, <a href="http://go-cloud-go.blogspot.com/2011/02/coding-in-cloud-part-ii.html">here</a>, and <a href="http://go-cloud-go.blogspot.com/2011/03/coding-in-cloud-part.html">here</a>. By far my favorite has been <a href="http://kodingen.com/">Kodingen</a>, I still go to it to code around and generally geek it up. This all may change.<br /><br />Akshell is a brilliant development environment that utilizes JavaScript for not only the client-side programming, but also the Server-side. There are many cool features to how apps are developed and integrated in Akshell, which can be found in <a href="http://www.akshell.com/docs/0.3/">their documentation here</a>. I have found the environment to be amazing to use utilizing the default “ak” library and their Model-View-Controller framework. For my first test I tried to remake (and improve) the test site I created on Kodingen with Akshell. I found it was super fast to build with the Akshell environment and enabled me to test and preview just as smoothly as Kodingen though I think the interface with Akshell is much easier to navigate (perhaps because most of the features in Kodingen are still disabled in its current Beta state). I must admit that I did utilize <a href="http://jsfiddle.net/">jsFiddle</a> to quickly enhance my HTML5 canvas that I had created in Kodingen and then simply copied the JavaScript to Akshell. So what does a quick Akshell site look like? <a href="http://gocloudgo.akshell.com/">See mine here.</a><br /><br />One of the promising things about Akshell that I’ll be getting into soon, is their relational database (PostgreSQL) that is accessible with their “Simple JavaScript API”. From the documentation and the quick test I did with their relation variables I have to agree it is simple to use. I hope to get some time to get an app going that utilizes this database functionality soon. <br /><br />I don’t know if I like Akshell an better than Kodingen as far as functionality and features (they both let you code, use a database, and deploy directly within their apps) but I can say that Akshell seems to be a more elegant solution to the online coding environment so I will definitely be using it for my next online coding endeavor.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7333770831047956364-884156941911087161?l=go-cloud-go.blogspot.com' alt='' /></div>
]]></content>
</entry>
</feed>