My blog has been moved to ariya.ofilabs.com.
Showing posts with label sencha. Show all posts
Showing posts with label sencha. Show all posts

Thursday, June 30, 2011

quaternion multiplication: two years later

Sometime back I wrote (fun fact: it's Google first hit for faster quaternion multiplication) about my favorite commit I did exactly two years ago to Qt :

git show cbc22908
commit cbc229081a9df67a577b4bea61ad6aac52d470cb
Author: Ariya Hidayat 
Date:   Tue Jun 30 11:18:03 2009 +0200

    Faster quaternion multiplications.
    
    Use the known factorization trick to speed-up quaternion multiplication.
    Now we need only 9 floating-point multiplications, instead of 16 (but
    at the cost of extra additions and subtractions).

Ages ago, during my Ph.D research, when I worked with a certain hardware platform (hint: it's not generalized CPU), minimizing the needed number of hardware multipliers with a very little impact in the computation speed makes a huge different. With today's advanced processor architecture armed with vectorized instructions and a really smart optimizing compiler, there is often no need to use the factorized version of the multiplication.

Side note: if you want to like quaternion, see this simple rotatation quiz which can be solved quite easily once you know quaternion.

I try to apply the same trick to PhiloGL, an excellent WebGL framework from Nicolas. Recently, to my delight, he added quaternion support to the accompanying math library in PhiloGL. I think this is a nice chance to try the old trick, as I had the expectation that reducing the number of multiplications from 16 to just 9 could give some slight performance advantage.

It turns out that it is not the case, at least based on the benchmark tests running on modern browsers with very capable JavaScript engine. You can try the test yourself at jsperf.com/quaternion-multiplication. I have no idea whether this is due to JSPerf (very unlikely) or it's simply because the longer construct of the factorized version does not really speed-up anything. If any, seems that the amount of executed instruction matters more than whether addition is much faster than multiplication. And of course, we're talking about modern CPU, the difference is then becoming more subtle.

With the help of Nicolas, I tried various other tricks to help the JavaScript engine, mainly around different ways to prepare the persistent temporary variables: using normal properties, using Array, using Float32Array (at the cost of precision). Nothing leads to any significant improvement.

Of course if you have other tricks in your sleeve, I welcome you to try it with the benchmark. Meanwhile, let's hope that someday some JavaScript engine will run the factorized version faster. It's just a much cooler way to multiply quaternions!

Saturday, March 12, 2011

SenchaCon 2010

At the last successful, sold-out Sencha Conference 2010, I did two introductory talks about JavaScript and WebKit, mainly targeted for web application developers. Since a few weeks ago, the videos for these talks have been available for you to watch.

JavaScript Engines: Under the Hood is 10,000-foot overview on how a typical JavaScript engine works. Watch it below or at vimeo.com/18783283, with the accompanying slides at http://slidesha.re/gGx9aA.

The other talk Compiling and Optimizing Your Own Browser with WebKit (vimeo.com/18780399 for the video, http://slidesha.re/fPSvXX for the slide deck), mostly showing few tricks you can leverage to understand how your web applications work. For example, by using QtWebKit and capturing all the drawing commands and the corresponding timestamp, it is very easy to have a slow-motion rendering of your web page. As I showed it in the talk, it is even possible to go back in time, i.e. rendering your web page backwards.

Many other videos from SenchaCon 2010 have been published as well. Make sure you check them out.

Enjoy!

Friday, March 11, 2011

PhantomJS meets CoffeeScript

I did something related to CoffeeScript before, namely simple command-line compiler. For those who are not aware of CoffeeScript, it's basically (from Wikipedia) JavaScript with "syntactic sugar inspired by Ruby and Python".

On the hand, surprisingly PhantomJS generates more interest than I ever imagined before (with over 240 watching its repository), prompting me not to abandon it too soon :) In fact, I decided to dump my tought on its roadmap since more and more people are willing to help.

My secret feature, which is not secret anymore, for the upcoming 1.1 release is to incorporate the CoffeeScript compiler so that PhantomJS scripts can be written in CoffeeScript. Since the intention of PhantomJS is for various scripting purpose utilizing headless QtWebKit, this is a perfect match.

Gone are the curly braces...

Monday, February 21, 2011

color wheel on Canvas

While I played with HSV pie and color wheel before, usually I just use the excellent Qt graphics stack to try out various things. This days, I lean towards using web technologies and for that purpose, HTML Canvas suits me just fine. With PhantomJS, I even got the result rendered as PNG image.

The new example I added to PhantomJS is colorwheel.js which produces the above screenshot. The entire script code is as follows (if some parts look cryptic, read about HSL and HSV color space):

if (phantom.state.length === 0) {
    phantom.state = 1;
    phantom.viewportSize = { width: 400, height : 400 };
    phantom.content = '<html><body><canvas id="surface">' +
        '</canvas></body></html>';
} else {
    var el = document.getElementById('surface'),
        context = el.getContext('2d'),
        width = window.innerWidth,
        height = window.innerHeight,
        cx = width / 2,
        cy = height / 2,
        radius = width  / 2.3,
        imageData,
        pixels,
        hue, sat, value,
        i = 0, x, y, rx, ry, d,
        f, g, p, u, v, w, rgb;

    el.width = width;
    el.height = height;
    imageData = context.createImageData(width, height);
    pixels = imageData.data;

    for (y = 0; y < height; y = y + 1) {
        for (x = 0; x < width; x = x + 1, i = i + 4) {
            rx = x - cx;
            ry = y - cy;
            d = rx * rx + ry * ry;
            if (d < radius * radius) {
                hue = 6 * (Math.atan2(ry, rx) + Math.PI) / (2 * Math.PI);
                sat = Math.sqrt(d) / radius;
                g = Math.floor(hue);
                f = hue - g;
                u = 255 * (1 - sat);
                v = 255 * (1 - sat * f);
                w = 255 * (1 - sat * (1 - f));
                pixels[i] = [255, v, u, u, w, 255, 255][g];
                pixels[i + 1] = [w, 255, 255, v, u, u, w][g];
                pixels[i + 2] = [u, u, w, 255, 255, v, u][g];
                pixels[i + 3] = 255;
            }
        }
    }

    context.putImageData(imageData, 0, 0);
    document.body.style.backgroundColor = 'white';
    document.body.style.margin = '0px';

    phantom.render('colorwheel.png');
    phantom.exit();
}

Beside the above example, there are few other things which you'll get in the upcoming PhantomJS 1.1 release, among others support for Unix shebang, file upload for form submission, disable/enable images loading and plugins, as well as support for QUnit integration.

Sunday, January 23, 2011

PhantomJS: minimalistic headless WebKit-based JavaScript-driven tool

PhantomJS is a headless WebKit packaged as a JavaScript-driven tool. It can be used in command-line utilities which requires web stack, or even as the basis for testing rich web application. It uses WebKit in a headless mode, so you get access to the real native and fast implementation (not a simulated environment) of various standards such as DOM, CSS selector, Canvas, SVG, and many others.

The project page contains a bunch of examples, from easy ones to some more complicated uses. Feel free to contribute more examples!

Let's look at one of the examples, the page rasterizer (yes, it's only 16 lines!):

if (phantom.state.length === 0) {
    if (phantom.args.length !== 2) {
        console.log('Usage: rasterize.js URL filename');
        phantom.exit();
    } else {
        var address = phantom.args[0];
        phantom.state = 'rasterize';
        phantom.viewportSize = { width: 600, height: 600 };
        phantom.open(address);
    }
} else {
    var output = phantom.args[1];
    phantom.sleep(200);
    phantom.render(output);
    phantom.exit();
}

If I want to have the famous PostScript tiger from its SVG source, all I have to do is to run:

phantomjs rasterize.js http://ariya.github.com/svg/tiger.svg tiger.png

But static vector graphic is boring. Replacing the above with

phantomjs rasterize.js http://raphaeljs.com/polar-clock.html clock.png

gives me Polar Clock, one notable example from RaphaelJS.

Should you need to deal with JSONP, process XML, and integrate with YQL, that's all easily done. Again, refer to the various service integration examples. Let me show one example, which is actually my favorite:

if (phantom.state.length === 0) {
    var origin, dest;
    if (phantom.args.length < 2) {
        console.log('Usage: direction.js origin destination');
        console.log('Example: direction.js "San Diego" "Palo Alto"');
        phantom.exit(1);
    }
    origin = phantom.args[0];
    dest = phantom.args[1];
    phantom.state = origin + ' to ' + dest;
    phantom.open(encodeURI('http://maps.googleapis.com/maps/api/directions/xml?origin='
        + origin +  '&destination=' + dest + 
        '&units=imperial&mode=driving&sensor=false'));
} else {
    if (phantom.loadStatus === 'fail') {
        console.log('Unable to access network');
    } else {
        var steps;
        steps = phantom.content.match(/<html_instructions>(.*)<\/html_instructions>/ig);
        if (steps == null) {
            console.log('No data available for ' + phantom.state);
        } else {
            steps.forEach(function (ins) {
                ins = ins.replace(/\&lt;/ig, '<').replace(/\&gt;/ig, '>');
                ins = ins.replace(/\<div/ig, '\n<div');
                ins = ins.replace(/<.*?>/g, '');
                console.log(ins);
            });
        }
    }
    phantom.exit();
}

If I run it like the following:

phantomjs direction.js 'Redwood City' 'Sunnyvale'

what I got is the complete driving direction:

Head east on Broadway toward El Camino Real
Take the 1st left onto El Camino Real
Turn right at Whipple Ave
Slight right to merge onto US-101 S toward San Jose
Take exit 398B to merge onto CA-85 S toward Santa Cruz/Cupertino
Take exit 22A to merge onto CA-82 S/E El Camino Real toward Sunnyvale
Destination will be on the right

Map data ©2011 Google

Make sure you check out other examples, such as getting weather forecast conditions, finding pizza in New York, looking up approximate location based on IP address, pulling the list of seasonal food, displaying tweets, and many others.

Headless execution of any web content also enables fast unit testing. Obviously, the goal is not to replace comprehensive, cross-browser framework such as Selenium or Squish for Web. Rather, it serves a quick sanity check just before you check in some changes.

Since this can happen automatically and does not need to launch any browser, even better, you can hook the test so that it executes right before a commit and actually prevents the commit if any of the test fails. It is easily done using git via its hook support. This is something I have written at Sencha blog. It demonstrated precommit hook with Jasmine, but technically it can work with any test framework.

I have been working on and off on PhantomJS for the past few years. You may be already familiar with some of its inspiration (also involving headless WebKit): SVG rasterizer, page capture, visual Google, etc. Finally I managed to overcome my laziness, cleaned up the code, and published it for your pleasure. Obviously it's not a surprise if you find out that PhantomJS uses QtWebKit.

I got a few tasks for next PhantomJS version 1.1. You are encouraged to file bugs and feature requests in the said issue tracker.

Get it while it is hot!

Saturday, January 01, 2011

X2 from Ofi Labs: wrap-up 2010

X2It got started when I needed a new home for my examples. It has even a nice logo.

sensor

accelerometer viewer for Maemo 5 (Nokia N900).

bouncing ball, where the gravity affects the movement of the ball.

box of marbles, where the gravity affects a bunch of colored marbles.

combining accelerometer and network to do inter-device marbles transfer.

motion and orientation for web applications.

web-based version of marble box.

widgets

morphing clock, where the transition between the digital and analog version is a kind of morphing effect.

qpalette viewer so you know which color is which one.

graphics

fast approximation of Gaussian blur to create a blurry drop shadow.

command-line capture tool to save maps from OpenStreetMap, MapQuest and Ovi Maps.

simple tool to list all chunks inside a PNG image.

webkit & javascript

file processing, including using jslint, in command-line using JavaScript.

play Canvas-based game as normal desktop app.

offline, command line beautifier for JavaScript code, utilizing Qt Script.

another variant of the beautifier, this time using V8.

minimalistic editing widget for JavaScript code, with custom syntax highlighting.

white background is boring? just try some color inverted web pages.

detect the closest link to ease following it on a touch device.

Canvas pixel manipulation for plasma effect.

network

simple proxy server for HTTP, in 100 lines.

tracenet: trap all network requests+replies to show them with Speed Tracer.

filterproxy: another variant of the proxy server with added URL filtering feature.

Thursday, December 16, 2010

motion vs orientation

I already showed the use of device orientation in a fun game called Box of Marbles. Based on my experience trying out this API implementation, often it is easy to get confused by device motion vs device orientation. Thus, I created two web-based applications (using on Sencha Touch): Device Motion and Device Orientation. Each basically just visualizes the values of the data in a bunch of sliders:

You can find the code in the usual X2 repository, under the subdirectory javascript/devicemotion and javascript/deviceorientation, respectively. Obviously, the rest of Sencha Touch library is needed before you can deploy and run the examples. For the lazy, just run the live demo for Device Motion and Device Orientation (they support offline mode).

While right now only iOS 4.2 on iPhone/iPad/iPod Touch implements this API, I have a strong hope that Android (post Gingerbread) and Nokia (thanks to QtWebKit and Qt Mobility) will support this cool API in the near future. Well, at least I do plan to revive my Symbian setup to custom compile QtWebKit and test it on Nokia N8.

Side note: from my limited understanding, seems that both accelerometer and gyroscope are needed in order to supply the accurate data, much like in an inertial navigation system ("Inertial Phone", anyone?).

Wednesday, November 10, 2010

V8 + jslint + vim

Usually, you would want to use scripting solution, e.g. Perl/Python/whatever, to manipulate file contents. Somehow, it's also fun to use JavaScript instead. After I did the V8-based jsbeautify, I was doing V8-based jslint as well. Then I realized, let's just extend it to be generic. With API loosely modelled after CommonJS, filejs was born. Find it in the usual X2 repository under the javascript/filejs. There are two examples so far, ROT-13 and line counter. If you write more examples, feel free to pass them to me!

Of course, the twist is: use filejs to drive a command-line jslint. This is one way to do it. First build filejs (follow the instructions in the included README), then place the executable in your PATH. Create a simple shell script, which contains one line filejs /path/to/filejs/jslint.js $1 and make it executable. That's it! If you also store this shell script in your PATH, then you just need to run:

jslint source-code.js

If you use vim, jslint can be combined with Quickfix. First of all, associate *.js with the tool by putting this line in your personal .vimrc:

au FileType javascript set makeprg=jslint\ %

Now open a JavaScript file and run :make (or whatever shortcut you map this into), which will launch jslint with the current file. After a while, use :cope to open the quickfix little window, move up and down, and press Enter to bring you back to the main editor and set the cursor at the specified problem. Use standard window navigation, e.g. Ctrl+W W to switch to quickfix pane again. Check the quickfix documentation for details. All in all, you may want to map mostly used commands to some shortcuts for faster access.

Note that since this is dynamic JavaScript, rather than matching errorformat, technically I just tweaked the tool to spit something similar to what a C/C++ compiler would do. Also, if you need different jslint options, simply edit the invocation to suit your needs.

It's been a while since I blogged about vim. The last one was about the project plugin, which is surprisingly still quite popular. Hopefully this one also teaches you a trick or two, especially if you work a lot with JavaScript code.

Note 1: It does not work on Windows yet. No idea if I would have the time to do it, patch is welcomed.

Note 2: This is not a replacement for NodeJS, nor would it grow to include more functions.

Note 3: For the sake of completeness, let me mention that there are already other countless solutions for command-line jslint (using Rhino, SpiderMonkey, JSC, etc), even with vim integration.

Friday, November 05, 2010

the fun of remote JavaScript debugging

Remote feature of Web Inspector, whereby you use an instance of WebKit and debug another one in different machine, is one important feature (that is being worked on) of WebKit I can't wait to start using. Till that day, remote debugging is always a challenge. There are of course assorted workarounds out there. At Sencha we decide to have and share with you a little tool that helps JavaScript remote debugging. It is available in two flavors: GUI-based (using Qt obviously) and Python-based for scripts and automation. Right now, the target is Android WebKit but there is no reason why we should not march to other platforms as well (e.g. QtWebKit on Symbian and MeeGo). Get it while it's hot!

Wednesday, October 27, 2010

Look ma, no JavaScript!

Take a look at the following CSS 3 demo. No Flash. No JavaScript. No image.

Hungry for more? Enjoy some other demos created using Sencha Animator.

Monday, October 18, 2010

Qt Developer Days, Bay Area Mobile meetup

We heard that Munich Qt Developer Days was an awesome event, which is why I look forward to the San Francisco Qt Developer Days, which will be held November 1-3.

Now, if you are from outside US, drop me an email in case you fancy some quality tea/coffee time. Even better, on the next day (November 4), Sencha will host the first Meet the Sencha Team, the first Bay Area Mobile meetup. Our team will give an overview of Sencha and the mobile technologies we are developing. RSVP and drop by!

Thursday, October 14, 2010

sencha touch hackathon

Are you in the Bay Area? Don't miss our Sencha Touch Hackathon this Saturday (Oct 16) in our Palo Alto Office, 1pm to 5pm. There will be food and drinks as well.

Drop by and upgrade your Sencha Touch kungfu!

yet another command-line JavaScript beautifier (based on V8)

While we're still on the topic of JavaScript, I took the afternoon break to create a command-line runner for jsbeautifier.org . In case you miss it, I did the similar thing using Qt Script module. This time however, the command-line tool uses and exploits Google V8 instead.

If you update your clone of js-beautify repository, check out the fresh v8 subdirectory. I also mirror the code in the usual X2 repository, under the javascript/jsbeautify8 subdirectory. Also, grok the included README.txt first.

Update: I added --overwrite option which (surprise!) will overwrite the original source file (and thus, use it with care). This is useful if you invoke the beautifier tool from your text editor. Nicolas also implemented various settings support so you can specify the indentation level, braces placement, etc.

This is probably the last thing the world needs now, but hey, it was a fun break.

Friday, September 24, 2010

invade & destroy

Developing games using HTML5 Canvas and JavaScript is simply the future. Something classic like Egor Balishev's RGB Invader, an entry in the 10K Apart, is usually my favorite.

If for some reasons (which I would not elaborate in this post) you need to deploy the game as a desktop or a mobile application, using Canvas and JavaScript gives another advantage: just package it with WebKit, for example QtWebKit if you do not mind using Qt.

However, since usually it is just about Canvas, often it is enough to run the game logic with a JavaScript interpreter and use some Canvas implementation for the display. This was something that I demonstrated before, i.e. running the Monster Evolution demo via JavaScriptCore and V8. Applying the same technique, and adjusting the shim so that it layers whatever RGB Invader requires, gives the following:

Basically it is using Qt Script (also in attempt to popularize it even more) along with a mix of C++/QObject and JavaScript machinery to fool the game code to think it's running in a browser environment. It was a nice afternoon fun project.

The code is in the X2 repository, find it under the javascript/invader directory. Get it while it's hot, and save our Earth!

Monday, September 20, 2010

offline, command-line beautifier for JavaScript code

There are many different ways to autoformat JavaScript code, my favorite is always jsbeautifier.org. Apparently, you can also use it locally without a web browser since it supports running it with Rhino.

It took me just few minutes to reimplement the same functionality, but using Qt Script, the fantastic ECMAScript support built into Qt.

The code is in the usual X2 repository, under the javascript/jsbeautify. Note that this is just a convenient mirror as Einar's js-beautify repository already includes this Qt Script driver.

With the rise of server-side JavaScript and desktop-esque JavaScript tools, I hope Qt Script will become more popular. It is sadly still "underrated" right now.

Saturday, September 11, 2010

minimalistic JavaScript editing widget

In the spirit of clean-up-and-publish, here is another code example of X2: a subclass of QPlainTextEdit which acts as a nice and minimalistic JavaScript editor. Basically it just adds a sidebar for the line number and a syntax highlighter. Thanks to QPlainTextEdit and QSyntaxHighlighter, this editing widget is quite performant. At just about 500 lines, think about it as another example on how to use these two classes.

It does support specifying different colors so you can have funky color scheme if you want:

The widget is BSD licensed. Find it out in the X2 repository under the javascript/jsedit subdirectory.

It does not have fancy features such as code folding or autocomplete (not sure I would have time to add them, so patches are welcomed!), but if you want feature packed editor, use QScintilla, KDE's Kate, Qt Creator's editor, or grab something else or even write your own.

Wednesday, September 08, 2010

Sencha Touch and N900

Being part of the awesome Sencha Team, I did shoot a quick attempt to run Sencha Touch, more precisely its Kitchen Sink demo, on Maemo-powered Nokia N900. Since Sencha Touch targets WebKit but Maemo default browser is Gecko/Firefox-based, I crafted a mini launcher which wraps Sencha Touch in QtWebKit. The screenshots below serve as the proof:

Most of the stuff works just fine. There are some minor issues and performance problems, but I worry not. With the amazing amount of optimizations Qt+Nokia put in place for Qt 4.7 and QtWebKit 2.x, writing applications for Maemo/MeeGo will be fun (again).

Wednesday, August 11, 2010

adventure to the land of green tea

Now I work for Sencha, the company behind the leading JavaScript frameworks such as Sencha Touch, Ext JS, Ext GWT, Ext Designer, jQTouch, Raphaƫl, Connect, which empower developers to create, deploy and optimize application using web-standard technologies (HTML5, CSS, JavaScript). Beside, it's a hot startup to work for.

Monday, June 21, 2010

spring-to-summer: photo blog

Since I've not been blogging for a while, let me do a post on some pictures (plus the stories) instead.

On a weekend, Balboa Park is a very nice attraction. Rather than explaining it in details, I suggest to just drop the park a visit. Beside a lot of different types of museum, there is also this Japanese Friendship Garden. A small cafe there, the Tea Pavillion, is a very nice place to relax and enjoy the surrounding. They serve sencha and other types of tea. Hungry? Get a rice bowl:

rice bowl

If you are more a beach person instead, then there is a plenty of choices, for example Silver Strand Beach. It is rather small, but it is always a nice spot to enjoy the sunset.

silhouette @ sunset

When I was at Google IO, I took some pictures of the large overhang banners because I wanted to test the 8 megapixel camera of HTC EVO 4G that Google gave away (see more in the complete set):

api

Getting a fantastic gift for the Father's day? Thinking of something for the next Mother's Day? What about a beautiful pendant (get one from LuShae Jewelry) like what my other better half elegantly captured below?

pendant