Archive for the ‘Open Source’ Category

console.log helper function

Thursday, April 4th, 2013

I have often found it tricky to get a ‘just-right’ console.log wrapper in JavaScript. I would prefer to just type log, but writing a wrapper function is a little trickier than at first glance. A variation of this used to exist in the HTML5 Boilerplate plugin.js but is now missing.

I have two versions – one is bigger, and is intended for an application – it stubs out console methods when they don’t exist, and exposes a log function to the window. The second is portable – it is meant for use inside of plugins.

The neat thing about this technique is that this preserves the original line of code inside of the console.log statement, rather than the line in which the log function is declared.


The code is in a gist, which is also embedded below:

Devtools Colorpicker Palette

Saturday, February 2nd, 2013

I’m still trying to figure out how to get a list of all the colors in use on a page from within devtools, but I’ve been hacking together a little demo with a custom Web Inspector frontend that loads a color palette on the side.

When you click one of the swatches, it sets the current color of the element. The idea is that it would include all the colors in your page, maybe ordered by most used. Possibly could even get more advanced and suggest a set of complementary or analagous colors based on your current selection.

A prototype implementation of a palette using color swatches within devtools

A prototype implementation of a palette using color swatches within devtools

jQuery UI 1.9 Boilerplate

Wednesday, October 17th, 2012

jsbin has made having to remember some of these links less important. However, with jQuery UI 1.9 coming out, there are some CDN links that aren’t working. Here is the updated boilerplate I use to quickly test out a jQuery UI project. If all goes well, you should have a dialog that you can drag around and resize.

<!doctype html>
<html>
<head>
  <title></title>
 
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
 
  <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.js"></script>
  <script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.9.0/jquery-ui.js" type="text/javascript"></script>
 
  <style type="text/css">
    #modal {
	 background: orange;
    }
  </style>
 
  <script type='text/javascript'>
    $(function() {
        $("#modal").dialog({ title: "It works" })
    });
  </script>
</head>
 
<body>
<div id='modal'>jQuery UI!</div>
</body>
 
</html>

As a bonus, here is the markup in jsbin.

TinyColor On npm

Wednesday, September 12th, 2012

I have published my TinyColor package to the npm repository – https://npmjs.org/package/tinycolor2. Unfortunately it is called tinycolor2 since tinycolor was already taken.

After running

npm install tinycolor2

You can use tinycolor like so:

var tinycolor = require("./tinycolor");
console.log(tinycolor("red").toHex());

See the project homepage or the README for more info.

Devtools Colorpicker

Monday, July 2nd, 2012

It is great that so many important platforms that we use on the web are open source, and open to contributions from anyone.

It took a lot of work, but it was worth it. I’ve been doing some web design work recently, and love how much easier it is to play with different colors in a design.

Now I’m thinking of different ways that design work could be further improved with the colorpicker. A couple of ideas right now: (a) an eyedropper to select a color from the screen and (b) a color palette consisting of currently used and recommended colors.

FileReaderSync

Friday, June 1st, 2012

I have been working on updating the FileReader.js JavaScript file reading library lately to help out with a few different projects. This library has provided a quick way to get started with reading files on a few different projects, like mothereffinganimatedgif.com and Instant Sprite.

One thing I noticed was that there is a FileReaderSync API, meant for loading files synchronously.

You might wonder why on earth would you want to load a file synchronously in your browser – that seems like it could block the entire UI until the file is loaded! It turns out you can’t, at least not in the normal window context. FileReaderSync only exists inside of the context of a WebWorker:

Implementation

View a A working JS Fiddle using FileReaderSync.

I also wrote about how to load web workers without a JavaScript file, but this technique works just fine using a normal external reference.

markup

<input type='file' id='files' multiple onchange='handleFileSelect()' />

page javascript

function processFiles(files, cb) {
    var syncWorker = new Worker('worker.js');
    syncWorker.onmessage = function(e) {
        cb(e.data.result);
    };
 
    Array.prototype.forEach.call(files, function(file) {
        syncWorker.postMessage(file);
    });
}
 
function handleFileSelect() {
    var files = document.getElementById('files').files;
    processFiles(files, function(src) {
        var img = new Image();
        img.src = src;
        document.body.appendChild(img);
    });
}

worker.js

self.addEventListener('message', function(e) { 
    var data=e.data; 
    try { 
        var reader = new FileReaderSync(); 
        postMessage({ 
            result: reader.readAsDataURL(data)
        });
   } catch(e){ 
        postMessage({ 
            result:'error'
        }); 
   } 
}, false);

The jsFiddle demo is a little more complicated than this, since it handles checking for support and an inline worker.

Gotchas

Something that was a little weird is that since you can’t detect support from the main window, I need to spawn off a worker to post the message of whether it supports FileReaderSync. See a jsFiddle to detect FileReaderSync support. There may be a better way to do this, but I don’t know of it.

This can be pretty complicated, but I have been tying it all into the filereader.js plugin, to make reading with FileReaderSync just an option along with the standard FileReader

Performance

It’s hard for me to accurately measure the performance. On one hand, the FileReaderSync seems to load the images in a slower time per image (measured in milliseconds). I assume that this is due to the overhead and message passing with the worker, or possibly because it is a newer implementation.

However, on large images and videos, it definitely feels like the UI does not lock up as much when processing the files.

Purpose

I feel like maybe part of the point of this API is when you want to some heavy lifting with the file after it is loaded but still inside the worker, which isn’t currently supported in FileReader.js. I could imagine ways this use case could be supported though (maybe by passing in a process() function as a string that the worker could call?

Check out the FileReader.js demo and see if you can tell a difference! I’d love to get any kinks worked out and get some feedback – I have been thinking of setting up a js-file-boilerplate project on Github to tie together a bunch of this functionality in a sample project.

Load Web Workers Without A JavaScript File

Friday, May 25th, 2012

Ever want to load a JavaScript Web Worker without specifying an external JavaScript file? There are a couple of different ways to do this by creating a blog and object URL – I wrapped this functionality up into a little plugin to share.

Here is the code. Or checkout out a working jsfiddle demo

 
var WorkerHelper = (function() {
 
    var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
    var URL = window.URL || window.webkitURL;
 
    function getURL (script) {
        if (window.Worker && BlobBuilder && URL) {
            var bb = new BlobBuilder();
            bb.append(script);
            return URL.createObjectURL(bb.getBlob());
        }
 
        return null;
    };
 
    function getWorker (script, onmessage) {
        var url = getURL(script);
        if (url) {
            var worker = new Worker(url);
            worker.onmessage = onmessage;
            return worker;
        }
 
        return null;
    };
 
    return {
        getURL: getURL,
        getWorker: getWorker     
    }
 
})();
 
<div id='log'></div>
 
<script type='text/worker' id='worker-script'>
    self.addEventListener('message', function(e) { 
        postMessage(e.data / 2); 
    },false);
</script>​
 
<script type='text/javascript'>
 
// Load a worker from a string, and manually initialize the worker
var inlineWorkerURL = WorkerHelper.getURL(
    "self.addEventListener('message', function(e) { postMessage(e.data * 2); } ,false);"
);
var inlineWorker = new Worker(inlineWorkerURL);
inlineWorker.onmessage = function(e) {
    document.getElementById('log').innerHTML += '<br />Inline: ' + e.data;
};
 
 
// Load a worker from a script of type=text/worker, and use the getWorker helper
var scriptTagWorker = WorkerHelper.getWorker(
    document.getElementById('worker-script').textContent,
    function(e) {
        document.getElementById('log').innerHTML += '<br />Script Tag: ' + e.data;
    }
);
 
inlineWorker.postMessage(1);
inlineWorker.postMessage(2);
inlineWorker.postMessage(100);
scriptTagWorker.postMessage(1);
scriptTagWorker.postMessage(2);
scriptTagWorker.postMessage(100);
 
</script>

Drag Out Images and Canvas With Filenames

Thursday, May 10th, 2012

It can be annoying that when you drag out images of a browser window, they are named png.png (or something equally useless). I was playing around with fixing this – it is a little inconvenience in my CSS Sprite Generator that would be nice to have working (naming the file based on their input). Here is what I came up with (no library dependancies):

function dragoutImages() {
 
    if (!document.addEventListener) {
        return;
    }
 
    document.addEventListener("dragstart", function(e) {
        var element = e.target;
        var src;
 
        if (element.tagName === "IMG" && element.src.indexOf("data:") === 0) {
            src = element.src;
        }
 
        if (element.tagName === "CANVAS") {
            try {
                src = element.toDataURL();
            }
            catch(e) {  }
        }
 
        if (src) {
            var name = element.getAttribute("alt") || "download";
            var mime = src.split(";")[0].split("data:")[1];
            var ext = mime.split("/")[1] || "png";
            var download = mime + ":" + name + "." + ext + ":" + src;
 
            e.dataTransfer.setData("DownloadURL", download);   
        }
    }, false);
}

You just need to specify the alt attribute on the image or canvas to specify your name (along with the draggable attribute on canvas elements) and the script should handle the rest.

Browser Support

I am not 100% sure on browser support. This used to be Chrome only according to this HTML5rocks article, but maybe other browsers have picked it up by now. It is a neat little addition when available though.

Demos

See the full demo: drag out images with custom file name. This shows the ability to drag out both image and canvas tags.

On this page, you should be able to drag out the following colorpicker screenshot, which will be called spectrum.png.

spectrum

Astar Graph Search – Variable Costs

Tuesday, May 8th, 2012

I’ve been working on updating my A* Graph Search Algorithm (A* on Github) and toying with the idea of adding variable costs to the grid, also known as weighted paths.

I opened an issue to add weighting to graph nodes a while ago, but am a little stuck on the implementation details. My initial thought was to change the semantics of the graph. Right now, here is a sample graph:

 
var GraphNodeType = { 
    OPEN: 0, 
    WALL: 1 
};
 
// 0 represents an open node, 1 represents a wall 
var graph = new Graph([
    [0,0,0,0],
    [1,0,0,1],
    [1,1,0,0]
]);

My initial plan for adding weighting was something like this:

 
var GraphNodeType = { 
    WALL: 0,
};
 
// Anything > 0 represents the cost to travel to that node, 0 represents a wall
var graph = new Graph([
    [2,1,3,4],
    [0,1,1,0],
    [0,0,3,10]
]);

One major issue with that is that it breaks backwards compatibility with the plugin. A user, spellfork, on the Github issue came up with a neat solution, basically passing in two separate arrays to the graph function, where one represents the “obstacle map” (walls), and the second represents the “terrain map” (costs).

 
// First array: 0 represents an open node, 1 represents a wall 
// Second array: movement costs are represented by numeric value 
var graph = new Graph([
    [0,0,0,0],
    [1,0,0,1],
    [1,1,0,0]
],[
    [2,1,3,4],
    [0,1,1,0],
    [0,0,3,10]
]);

This is nice because the terrain map is optional, but not as nice if you need to do a lot of work to generate the two separate maps.

Maybe there is a better solution that I am not thinking of? Any ideas about the best way to implement this? Drop a comment here or over in the Github issue to help get this implemented!

Expanding Textareas jQuery Plugin

Thursday, April 19th, 2012

Ever want a textarea to expand based on the size of the input that someone types? I made a jQuery plugin to handle expanding textareas! The basic technique is based off of a cool article called Expanding Text Areas Made Elegant. Check out the Expanding Textareas Demo and play with the Expanding Textareas Source Code.

I think it’s a pretty cool plugin that is a lot nicer than using the standard hacks for keeping textarea heights up to date. And it works really well with proportional widths, custom fonts, and min/max heights!

Here is a screenshot (which also links to the demo):


Expanding Textareas jQuery plugin