Skip to content


Weppy Updates: Opera, Chrome and Firefox support and simpler usage

With help from @Frenzie and @paul_irish, the latest not-yet-versioned release of Weppy, my Javascript WebP to WebM conversion library, or something of a polyfill for a format that is yet to be part of any specification (HTML5 seems to specifically reference the image src attribute are examples such as PNG, GIF, JPEG, APNG, PDF, XML, SVG, SMIL, and MNG). The new release brings some awesome new features that really don’t change much and shouldn’t really be used in the real world because most browsers in the world still aren’t Firefox, Chrome or Opera – that is, a large portion of the browser market includes browsers like Safari and IE, either suffering from antiquity (IE6! aah!) or just liking h264 (IE9 + Safari).

The new release supports Opera. I never bothered debugging Opera, I figured it was another huge issue that would demand a rewrite (as supporting Firefox had needed, because the order of the object keys isn’t preserved and breaks the EBML result, or at least for Firefox’s parser which seems to be somewhat stricter than Chrome’s, is that ffmpeg?). And after premature optimization (stripping “unnecessary” EBML tags), my code didn’t work in chrome, so I had to revert to an earlier revision. All my testing code was based on file drag-drop stuff, and Opera doesn’t support that. Until I saw this mozillazine topic, I didn’t care, but it was a lot easier to fix than I feared.

Part of the solution was getting rid of the canvas stage. Admittedly, the canvas stage was pretty useless once the toDataURL() stage was removed before the first public release, but I didn’t feel like deleting code, so it stayed there. Also, I noticed that the global variable that gets introduced was accidentally named “WebM”, which is wrong, it should be “WebP”, but because of the uncreative format naming and similarities, I didn’t notice. Not sure, but it seems to be more stable now.

Chrome probably will add WebP soon, and it needs to be future proof, detecting whether or not a browser supports the WebP format. To do that, it creates an Image, sets the src to a data url of a 4×4 webp image and listens to the onload and onerror events, checking if the size is correct and there were no errors loading it. The routine is expected to error and totally untested as there aren’t any browsers that support the feature yet for me to try.

Another change, is that by default, it will automatically load all the same-origin (because of the limitations of XHR) webp images (from <img> tags), on the DOMContentLoaded event, so the library is practically drop-in now. In any web page, you can pretty much add <script src=”http://antimatter15.github.com/weppy/weppy.js“></script> and on the supported browsers, it should automatically load and replace all WebP images, though not something I would really recommended.

The demo is the same place it always was: http://antimatter15.github.com/weppy/demo.html

There is also this nifty hack that uses <canvas> to add an alpha channel to the WebP image (adapted from the original JPEG one): http://antimatter15.github.com/weppy/alpha/alpha.html

Also, please follow me on twitter.

Posted in Weppy.

Tagged with , , , , , , , , , , , , , , , , , , , , , , , .


Weppy: Javascript Shim for WebP on Chrome 6 and Firefox 4.0

WebP http://code.google.com/speed/webp/

Recently, Google announced a new lossy image compression codec, named WebP, intended to supersede JPEG. It is based on VP8′s intraframe compression algorithm. It’s not natively supported in any browsers yet. Weppy is a compatibility layer that changes WebP files into WebM files that can be loaded on several modern browsers.

How does it work?

WebP is actually a lightweight container for a single VP8 frame (whereas WebM is a container based off Matroska meant for video). WebM support exists already in Chrome, Firefox and Opera, so all that’s needed to render it is to do a little magic to convert the RIFF encoded WebP image into a EBML/Matroska encoded single frame WebM video, loading it in a , using drawImage() on a and replacing the .webp image with the data URL extracted from the using toDataURL().
Issues

  • Chrome (on linux anyway) tends to crash a lot.
  • Firefox throws a security exception when doing toDataURL() on a canvas after drawImage() of a video loaded from a data url. The hack being used it to replace the image node with the actual canvas instance.
  • Opera doesn’t work. I don’t really have the time to investigate.

What Browsers?

Chrome 7.0 and Firefox 4.0 were both tested. Opera doesn’t work for reasons that I’m not sure about. I would appreciate it if someone fixes it and submits a patch :)

Demo

http://antimatter15.github.com/weppy/demo.html

Posted in Weppy.

Tagged with , , , , .


drag2up – Drag files onto any site

Drag2Up, is an app named horribly, as I suck at naming things. It’s very simple in terms of capabilities – no buttons, no interface, which is pretty much the ideal type of user experience, something that’s intuitive and lends focus to content, not chrome. Really, this post isn’t useful in any way. What you should do, is install it and try it out for yourself (Chrome only, It would be possible to make a firefox version, but I have no experience with Firefox extensions, and the new Jetpack isn’t quite out yet, though you can probably adapt the code relatively easily. Maybe a greasemonkey script by using GM_XHR). https://chrome.google.com/extensions/detail/bjgjolhpdlgebodaapdafhdnikagbfll

Drag and drop is probably one of the greatest forms of interaction ever, it’s intuitive and exemplifies the usefulness of a GUI. Recently, browsers have implemented drag and drop APIs (actually a feature of IE5.5+ but then codified into part of HTML5). Some browsers, namely Chrome and Firefox implement a dataTransfer property of the drop events that allow one to access files dragged from the user’s desktop (or file browser) onto a web application. The application can read the file through the File API, and do whatever it chooses. Probably most notably is Gmail’s utilization of the feature that allows dragging and dropping files from the desktop onto a message to upload it as an attachment. When it was announced, some people remarked how excited everyone was of a feature that was present in desktop clients for several decades already.

I stole this icon from the Tango Desktop project. Mua ha ha ha. I'm so evil.

Browser vendors have the role of enabling developers to do cool stuff. It’s up to a web developer or service to maintain an application, to update it and add new features. Undoubtedly, many do, living on the bleeding edge of innovation, but most don’t, and stay locked in a certain state for years if not longer. Extension developers have no obligation to be entirely objective in terms of how it deals with websites, and many are site-specific, adding features to sites that lack them, integrated into the interface, utilizing product-specific APIs, or document structure. Browser vendors enable innovation, site developers integrate standards and browser extensions add features to sites, because the developer is unwilling or because of restrictions on the functionality of web apps (x-domain, persistence, etc).

Uploading images is a fairly common task, and the standard go-to-file-host-site, click-the-attach-button, browse-button-hitting, navigation-through-folders and waiting-for-page-to-reload-after-uploading, link-copying, tab-switching and pasting. Some applications like CloudApp look promising in alleviating this needlessly tedious process, but only reduce the interaction steps a little. The ideal would be making that third-party file upload service integrate seamlessly into all web applications, with a level of integration akin to Gmail, drag and drop.

As awesome as it sounds, it’s not as easy to implement as one might like. The basic idea was to detect when a drag event started, and to iterate all the elements, adding an absolutely positioned, semitransparent mask to indicate that it’s a drop target. A few issues occur with that, I have a little writeup on those issues.

A lot of WYSIWYG editors use iframes, and creating content scripts with all_frames: true doesn’t necessarily mean it runs on all frames (for some very odd reason). And also for some reason, there’s no way to access frames from window.frames in content scripts. So I have this hack where if there are frames, it injects some javascript into the real page executed in the page’s context to run it within the iframe (if it’s the same domain, as it always is in wysiwyg editors). Then events get propagated from the sub-frame into the parent window, through postMessage that is subsequently handled by the content script, forwarded to a background page using chrome.extensions.sendRequest, and it all happens in reverse once the server gives a response. As such, it’s a really bad idea to use this for large files since it needs to be passed around several times over several pages, and apparently V8 isn’t the best with big strings.

Aside from that, uploading to imgur for some odd reason takes a long time. I don’t like sites that don’t have simple JSON POST APIs, and there really aren’t many that fit that criterion. So with the initial release, images are uploaded with imgur and text files are all uploaded to a github gist.

Posted in Chrome Extensions, drag2up.

Tagged with , , , , , , , , .


Gmail Style HTML5 Drag/Drop

I’m making a (really awesome) chrome extension that involves dragging and dropping files. MDC, as usual, has great information on the topic. Gmail does it almost perfectly, with the green file drop target. But all other implementations of this feature suffer from two issues, and Gmail’s code is far too obfuscated for any mere mortal to interpret (no doubt thanks to closure). When implementing the file drop target, two fairly important user experience issues occur. I don’t know what way Gmail does it, and I just used whatever solution worked.

Firstly, is that you only want to trigger the drop target once a file is being dragged onto the web app. You don’t want a file drop target to appear once someone starts dragging text (fairly simple, check that e.dataTransfer.types includes File). Even trickier (even Gmail doesn’t get this right) is dragging links also triggers the file drop target for some reason (it’s tricky because then e.dataTransfer.types also includes the File type for some odd reason). There’s no way to access file data as it’s being dragged (getData always returns undefined). One thing that I still have no idea about is inter-browser-window data transfers.

Secondly, is how to get the dialog to dismiss itself once the dragged image is dragged out of the viewport. It’s pretty tricky because of how the events bubble and don’t always go through <body>. The solution I eventually arrived at was to add a timer on the dragleave and see if within fifty milliseconds (a random amount of time, zero works too, but fifty feels safer), another drag event is fired.

Hopefully, people will find this useful :)

Posted in drag2up.

Tagged with , , , , .


Readability iframe Extension

I was inspired by chris messina‘s idea of integrating Readability into a twitter client. Sadly, I don’t have newtwitter yet, so I can’t actually do that. But since I do have the ultrahackable Streamie client, I’ve updated my fork of streamie with that functionality. It relies on a chrome extension that sort of makes an exception to the cross domain policy that makes all frames with a URL that includes #readStyle automatically load the readability bookmarklet.

Inspired by this

Posted in Chrome Extensions.

Tagged with , , , , , , , .


3D Sculpting Tool

So for the  past few days, I discovered this neat app called Sculptris. It’s this amazing digital sculpting app where your canvas is basically a blob of virtual clay that can be molded into any shape with any level of detail. It’s windows-only, and I thought it would be neat to have something like it that works in the browser. First I thought of using WebGL, but trying to start chromium with webgl always ends up with a GLXFBConfig error, and on Firefox, it’s stuck with using libosmesa which gives absolutely terrible framerates (IDK why but Fx4 *crawls* on my computer. Panorama is so slow it lags from simple dragging). Eventually, I ended up basing it off my js1k function plotter, because it’s a fairly simple 3d renderer.

The pictures on the top of the page are of the death star and alderaan, respectively, mostly because planets (and moons that aren’t moons) are mostly spherical and explosions and light rays are pretty much the only things that this app is suitable for at these stages.

So how does it work? It’s actually really simple, and probably too simple. At ~300 LOC  of pretty trivial JS, it’s not much at all (though it is hideous, I must warn you). It is based on my js1k entry, and I considered making this a 1k submission, but I gave up and said I couldn’t. It starts off simple enough, do lots of freaky trigonometric loops to generate a set of points that lie on a sphere. Then loop through every 50 milliseconds, apply a 3d transformation, get points that lie within a radius of the mouse position and reference them in the selected array. Then you segregate the selected array into the foreground and background, find the arithmetic mean of the fg and bg, respectively and find the difference. Then I convert it to spherical coordinates and get rid of the ratio to ignore the magnitude of the vector and add it to the position of foreground points. Then loop through all the points and wherever there’s a long distance, insert a new dot at the midpoint.

For no apparent reason I decided not to put many words on it. I was actually reluctant to add “points” and “undo”, but it’s fine print in faded color that doesn’t help the user at all.

  • Middle Click + Drag to rotate (in 3d)
  • Right Drag to deflate the shape
  • Left Drag to inflate the shape
  • Middle Scroll to zoom in/out
  • The slider bar is for controlling the size of the selection.
  • The checkbox enables/disables Undo/Redo (via CtrlZ/CtrlY or CtrlZ/Ctrl+Shift+Z).

App: http://antimatter15.github.com/3d-sculpt/3d.html

Mirrored Version: http://antimatter15.github.com/3d-sculpt/mirror.html

(Not as in the other meaning for mirror, but it actually reflects the X axis so that it’s symmetrical, which is a neat feature in sculptris)

Github: http://github.com/antimatter15/3d-sculpt

Posted in 3D, Digital Sculpting.

Tagged with , , , , , , , , , , , , .


zQuery

The name comes from the fact that of letters which can prefix the word “Query”, the letter z appears to have the least results, and its avoidance of resemblance to jQuery to some extent really underlies what it is: (yet another) lightweight jQuery clone.

This project uses defineGetter/Object.defineProperty to make a jQuery-style (but more like the DOM) API in under 1k (minified).

Example:

$(‘#magic a’).className += ‘ link’;
$(‘body’).find(‘a’).innerHTML
$(‘body’).textContent += ‘blah’ //works on firefox too!

BTW:
This library is totally untested

Posted in vX JS.


Why my Streamie fork is better than everyone else’s

So the future is here and everyone is forking running websites. The rate of development is pretty insane and I’ve already disabled Chromed Bird and I’m switching to having Streamie as a pinned tab, which also leads inevitably to the question “Why is a pinned application tab aesthetically different from a Browser Action?” . But back to the point, this post will detail every little feature that is utterly insignificant in the grand scheme of things that I felt like improving on in the streamie client.

Retweeters show a little icon

This is a feature that was in Chromed Bird and Tweetie and was pretty easy so why not implement it.

Short links are automatically expanded

This feature is accomplished using Dion Almaer’s endpoint resolver.

Better link detection

My fork uses John Gruber’s improved liberal, accurate Regex pattern for matching URLs. This allows cases like the above to be properly ended at the parenthesis while still allowing wikipedia links that include parentheses.

What client was used to post it.

Mine displays what client the poster is using.

You can try it out on http://antimatter15.streamie.org/ But seriously, all the forking of streamie is probably great for the project, and my role is very insignificant, and it would be great if some of the features got into the master branch :)

Posted in Streamie.

Tagged with , , .


Sort-of working Linux-friendly Apple Event Playlist

http://antimatter15.com/misc/playlist.xspf

Posted in Uncategorized.

Tagged with , , , , , , .


HTTP based federated protocol for real time hierarchical message manipulation

In other words. It’s like google wave, but simpler in every possible way.

This protocol uses two servers. The federation server and the storage server. The latter is incredably simple. In fact, the reference implementation is only about 200 lines of JS (Node.JS FTW). Thats because a storage server accomplishes just about three things. It receives message deltas. It applies them. And it pushes the delta to all subscribers. The subscribers are the federation servers, they act on the behalf of multiple clients, keeping track of users, their inboxes, etc.

Anyway, the big part about the design is that there is only one unit of information, and that is the message. There’s no such thing as waves, wavelets, conversations, private replies, threads (sort of lying here), blips and other information. It’s just messages. Messages are stored on storage servers, and are filled with HTML and a tree of information.

Messages can have other messages inside them. It’s just some xml-ish stuff. <thread></thread> is a thread and <message name=”http://blahblahblah.com/blahblahblah”></message> is a message that goes inside the thread. You can stick it anywhere. In the middle (inline replies!) or at the end (normal replies!).

Messages don’t even have to have text. Gadgets are just messages that are slightly different.

http://github.com/antimatter15/awesomeness

There’s a lot that it doesn’t do because I’m too lazy to do it. And I can’t give you a live demo because I don’t have a node-enabled server.

Posted in Google Wave.

Tagged with , , , , , , , , , , .