amXor

Blogging about our lives online.

7.15.2010

Thought Experiment: JavaScript POSIX Shell

0 comments

Okay, this one is a bit of an odd idea. My thinking is that you build a shell that will work in a browser window. The 'filesystem' is created in the browser's localStorage. Only the basic IO system and OS facilities are hardwired, the rest is implemented through executable 'files' in the filesystem.

The general idea is to make a lightweight shell that is programmable and could do some really cool stuff.

echo "Hey, I'm in a browser terminal!" | twitter

I've already hacked together a demo just to see how all the parts would work. Here are my findings.

User Interface

A text area is editable or not, whereas a terminal window is only editable at the cursor point. I puzzled over this one for a bit, wondering how to mimic this behavior in a browser, and then I dropped it and just did what was convenient: one editable textarea for commands, one for output. This is what that looks like:


At first I thought this was kind of a lame hack, but as I use it a bit more it feels quite intuitive. It's like posting on Twitter; you type on top and the command gets pushed onto the stack. But, you might ask, what about programs that take over the full terminal window? Well, in this case you just pass the lower window to the program and keep the upper for commands to the program. In the Vim editor, and most others, you always have a status/command line used for issuing commands anyway, so why not keep it on top?

Calling Convention

This is the one place that I wanted to stay very UNIXy. The commands are called with arguments and have access to stdin, out and err and everything is a 'file', meaning everything is a key/value pair in localStorage.

Files

In my first draft, the files are just key/value pairs with the file name being the key and the text being the value. There are a few problems with this.

First, file permissions/types are not implemented, which is mostly a problem because there needs to be a mechanism to determine what are executable files. Remember: everything is a file; all the commands 'echo, emacs (!)' will be JavaScript strings stored in the browser. Any user can make their own executables.

Second, a file heirarchy would be nice. Timestamps would be nice.

I think the best solution is to format the 'name' string with all the metadata, which would get stripped when accessed by the Terminal. So a file like /bin/echo would become < name='echo' path='/bin/echo' mode='-r-x' > if we want to use XMLish formatting.

Summary

I really like this idea. When I first got it up and running I was a bit giddy. It is browser based, but I also want to make it very Internet based. I would like to make it possible to wire in any site that has a public API; Social Networking, Mail, RSS, the works.

Skratch Development Update

0 comments
"Make one to throw away"

I forget who said this, but it has been good advice for my little web-based sketching app called Skratch. After the first version was up and running I took a step back and had a hard look at the overall structure.

Overall it wasn't too bad. It has been a work in progress to figure out how to modularize and encapsulate. In the alpha stages it was a bunch of global functions and variables going every which way. By version 0.1, I had realized that I needed to introduce some structure and so I grouped the drawing code into objects with attributes. Most of the event handling code was still in global functions. At this point I took a break and did some reading.

First I read Douglas Crockford's JavaScript: The Good Parts, and none of it really sunk in. It's an excellent book for the theory of how to use the language functions and how to avoid bad practices, but it doesn't really give the reader a sense of how they should write JavaScript. All of the examples are very short and specific to a certain language feature.

Then I read the jQuery source code and realized that I hadn't got it at all. It took me a while to really grasp what was going on here, and most of that time was spent trying to figure out what it was that I didn't understand. The thing that I didn't understand was simple but elusive: closure.

I have heard of closures as a programming concept a number of times but I never really grasped why they would be practically useful or how I would recognize one when I saw one. Reading the jQuery source, it took me a while to realize that this was a ~6000 line closure staring me right in the face. So I started coding to see how I could use an anonymous function to my benefit.

It's really quite simple: any vars, functions or objects declared inside a function are only accessible within that function. So if an anonymous function invokes itself, it's totally possible to not add to the global namespace at all. Nothing within that function is accessible unless it is attached somehow to the global namespace. But those functions that ARE attached to the global namespace can make use of all the private variables and state within the anonymous function.

This is the little testing function that I hacked together to prove this to myself:
(function () {
    var obj = {}, 
        privateData = 42,
        privateMethod = function (arg) {
            return "Private method: called with "+ arg + 
                    "\n" + "The holy grail: " + privateData + "  sees:" + obj.globalData;
        };
    
    //Priveledged: public methods which rely on private members.
    obj.protectedMethod = function (arg) {
        return "Priveledged method: called with " + arg + "\n" +
                    privateMethod("really " + arg);
    };
    
    // Public: members that are publicly accessible, rewritable, etc...
    obj.globalData = "I am the viewable data of the globalobject.";
    
    obj.generateString = function () {
        return "Global method: " + obj.globalData + "\n" +
                obj.protectedMethod("do this");
    };
    genericObj = obj;
})();

Only in the last line do I "publish" the object I've created, anything else is encapsulated in the closure and remains private.

Once I grasped this concept, it was immediately apparrent how it would be useful to my drawing app. I created an object, called "skratch" and attached only the functions and data that need to be accessible from outside to it; basically just the UI controls and a .setupCanvas method. The drawing engine and event handlers are now completely wrapped inside the closure.

This way of programming seemed kind of ugly to me until I looked at the DOM tree for my app. There was only one global object called "skratch" with a couple methods for triggering UI events and that was it.

So, I now know what closure is and what it can do for me and I think my scripts will be better for it.

Oh, and FYI, after reading the jQuery source, I couldn't help but include it in my app, even though all it does right now is make the toolbar go swoosh! Totally worth it!

6.09.2010

Skratch - HTML5 Version

0 comments

I've rewrote my drawing engine to run entirely in javascript and render to an HTML canvas. Since all the control logic was already sketched out and working in Quartz Composer, I simply had to translate that into javascript equivalents.

Instead of drawing with a colored image, this version draws individual pixels for every point along the path with a random scattering algorithm. It does this by computing a random angle and a random distance from the drawing position.

The controls are fairly rough at the moment. I think I'll probably scrap all the HTML inputs and integrate the controls into the drawing surface itself; but this works for testing purposes.

The background is drawn using tips from this great tutorial.

The code is in one HTML file, which you can download and run locally. Get it here, In the folder "Web Development" > Pencil_Drawing.html.

6.03.2010

Skratch Rendering Engine

0 comments

Abstract

Skratch is a Quartz Composer based rendering engine for painting and drawing applications. The primary design considerations are speed, smooth dynamics, a simple interface and extensibility.

Features

  • Quadratic Input Smoothing
  • 3 Mode, Fullscreen Color Chooser
  • Pressure Sensitive Brush
  • Selectable Brush Types and Repeat Rate
  • Transparent Drawing Layer
  • Modular Design

Design

Skratch is designed to be highly modular in order to make modification, automation and extensibility simple.

Smoothing Functions

One of the primary design obstacles was the relatively slow sampling rate of the mouse or tablet (approx. 16.7 ms). This results in jagged lines at even moderate brush speeds. To overcome this limitation I have implemented a smoothing algorithm using a quadratic Bézier curve in Javascript. The function takes three sampling points input(3) from the mouse. It then calculates three control points, one halfway between in0 and in1, one at in1, and one halfway between in1 and in_2. The Bézier curve is then calculated based on these points and the number of intermediate points is determined by the "Granularity" input. The smoothing function looks like this:

(((1-t)*(1-t)) * p0) + ((2 * (1-t)) * t * p1) + ((t*t) * p2)

Where t is the point to produce in the range 0.0 - 1.0 and p0, p1 and p2 are the control points. http://en.wikipedia.org/wiki/Bézier_curve

On top of this rapid smoothing, there is also the option of low-speed interpolation which makes it much easier to draw smooth curves and lines by hand. This makes it easy to switch between quick sketching / hatching and smooth deliberate strokes.

Modularity

The original goal was to develop a simple sketching program, but due to it's modular nature, it has been quite simple to connect it to function generators and produce auto-drawings with interesting results. This modularity should make it quite simple to extend it beyond Quartz Composer in XCode and produce various types of drawing programs.

Color Chooser

The color chooser that I've implemented is somewhat different than most. When you press the 'c' key you are presented with a full-screen CMYK palette to pick a color from. If you use the right arrow key, it will change the palette to a number of alternate palettes. There's also an RGB palette as well as an option to pick the color right from the current drawing (in a slightly pixellated version). Further images or palettes could be added with minimal effort.

Transparency

The drawing layer is transparent, allowing full color drawing and erasing and the potential of stacking layers with blending. The background is opaque.

Further Directions

  • Canvas Sizing (Zoom & Pan)
  • Custom Brushes & Brush Selector
  • HUD of all drawing state info

Noodling.

Guided Auto-Drawing.

5.11.2010

Copy From iPod - Mini App

0 comments

I packaged the previous post into an app. All you have to do is select your iPod folder and iPod Copy will copy it all to a folder on your desktop.

Heres the link:

iPod Copy

It's a pretty trivial Automator script, but it got me thinking about interaction. In the previous post there was about 10 lines of navigation/folder creation and one payoff line. To my friend that had never used a terminal the 10 lines were mystic voodoo, but they are really basic stuff if you've used the command line at all. And then I thought, "Whatever happened to Midnight Commander?"

Midnight Commander To The iPad

Midnight Commander enabled you to navigate visually in side-by-side views and run commands of your own or from a dropdown menu. All that painful navigation cured, but the command line was still one keystroke away. The problem was, as soon as we had visual interaction there was no going back. The average user cannot shift modes between the padded walls and unlimited undo of GUI's to the underground streetfighting of CLI's.

The announcement of the iPad is one more step into the walled garden of safe and fun computing for the masses, but it worries me that the average user knows less and less about how the technology actually functions. Even developers are becoming much more insulated from the workings of the machine. Like the Galactic Empire in Asimov's Foundation series, if we don't have knowledgable people working at every level our systems will grow unmanageable and unmaintainable.

4.22.2010

Copy From iPod

0 comments
I've had a number of requests about how to copy music from an iPod back to your computer. It's fairly straightforward if you know how to get around in Terminal, if you don't here's a walkthrough, if you do you might just want to skip ahead to the copy command, it's the only one doing anything special.
1. Open Terminal (Applications/Utilities/Terminal/)
2. Navigate to /Volumes/Your iPod/iPod_Control/Music/
 cd /Volumes/
 ls
 >>> Andrew Vanee’s iPod    BOOTCAMP    Backup    My Public Folder

 cd "Andrew Vanee’s iPod"/
 ls
 >>> Calendars Contacts  Desktop DB Desktop DF Notes    iPod_Control

 cd iPod_Control/
 ls
 >>> Artwork  Device  Music  iPodPrefs iTunes

 cd Music/
 ls
 >>> F00 F03 F06 F09 F12 F15 F18 F21 F24 F27 F30 F33 F36 F39 F42 F45 F48
 F01 F04 F07 F10 F13 F16 F19 F22 F25 F28 F31 F34 F37 F40 F43 F46 F49
 F02 F05 F08 F11 F14 F17 F20 F23 F26 F29 F32 F35 F38 F41 F44 F47

3. Make a folder on the desktop to copy to:
 mkdir ~/Desktop/ipod

4. Copy all files in folders, without Mac resource forks (-rX options)
 cp -rX ./* ~/Desktop/ipod/

5. Wait for a while. Terminal just sits there blankly, but you can go to the folder
in Finder and see the copying happening. Once you get a command prompt in 
Terminal, you're done.
Gotchas: Any folder name with spaces or weird characters needs to be surrounded by double-quotes. (eg. "Andrew Vanee's iPod"/) To do: on the fly file renaming. mdls -name kMDItemName will display the actual song name.. Not sure what to do with that.

Twitter

Labels

Followers

andyvanee.com

Files