Category Archives: javascript

Hotkeys for CKEditor format/styles

Sourced from
http://stackoverflow.com/a/14425430/9908

function bib_onKey(event){
            var styles = [], config = this.config,
                codex = { }, format_name = undefined;
            codex[CKEDITOR.ALT + 49] = "format_h1";
            codex[CKEDITOR.ALT + 50] = "format_h2";
            codex[CKEDITOR.ALT + 51] = "format_h3";

            format_name = codex[event.data.keyCode];

            if (format_name !== undefined) {
                this.fire("saveSnapshot"); #save state for undo
                //Format codes are not stored anywhere I could find
                // so build them.
                var style = new CKEDITOR.style(config[format_name]),
                    elementPath = this.elementPath();
                    #Honestly no idea but its needed to work
                    style._.enterMode = config.enterMode;
                #if format is live, kill it or vice versa
                this[style.checkActive( elementPath )
                    ? "removeStyle"
                    : "applyStyle"
                ]( style );
                #another hit on the undo logic.
                this.fire( 'saveSnapshot' );
            }
        }

put that in the call to CKEditor as a custom config parameter

CKEDITOR.inline("your tag name", { on:{key:bib_onKey}})

CraftJS; interesting potential

The other month/week I resumed some dabbling/hacking experiments in working with HTML5’s canvas. This go around, I decided to give CraftyJS a try.

The short version of my experiments, CraftyJS has a lot of potential if it can get it’s memory leaks under control, which might be a daunting task.

Here’s the example Pong game implementation that can be found on CraftyJS’s website:


Crafty.init(600,300);
Crafty.background("rgb(127,127,127)");

//Paddles
Crafty.e("Paddle, 2D, DOM, Color, Multiway")
    .color('rgb(255,0,0)')
    .attr({ x: 20, y: 100, w: 10, h: 100 })
    .multiway(4, { W: -90, S: 90 });

Crafty.e("Paddle, 2D, DOM, Color, Multiway")
    .color('rgb(0,255,0)')
    .attr({ x: 580, y: 100, w: 10, h: 100 })
    .multiway(4, { UP_ARROW: -90, DOWN_ARROW: 90 });

//Ball
Crafty.e("2D, DOM, Color, Collision")
    .color('rgb(0,0,255)')
    .attr({ x: 300, y: 150, w: 10, h: 10,
            dX: Crafty.math.randomInt(2, 5),
            dY: Crafty.math.randomInt(2, 5) })
    .bind('EnterFrame', function () {
        //hit floor or roof
        if (this.y <= 0 || this.y >= 290)
            this.dY *= -1;

        if (this.x > 600) {
            this.x = 300;
            Crafty("LeftPoints").each(function () {
                this.text(++this.points + " Points") });
        }
        if (this.x < 10) {
            this.x = 300;
            Crafty("RightPoints").each(function () {
                this.text(++this.points + " Points") });
        }

        this.x += this.dX;
        this.y += this.dY;
    })
    .onHit('Paddle', function () {
    this.dX *= -1;
})

//Score boards
Crafty.e("LeftPoints, DOM, 2D, Text")
    .attr({ x: 20, y: 20, w: 100, h: 20, points: 0 })
    .text("0 Points");
Crafty.e("RightPoints, DOM, 2D, Text")
    .attr({ x: 515, y: 20, w: 100, h: 20, points: 0 })
    .text("0 Points");

Now I will break this down.

Crafty.init(600,300);
Crafty.background("rgb(127,127,127)");

Relatively straight forward; this generates a HTML5 canvas element of 600x300 pixels, sets the color to a neutral color range.

Crafty.e("Paddle, 2D, DOM, Color, Multiway")
    .color('rgb(255,0,0)')
    .attr({ x: 20, y: 100, w: 10, h: 100 })
    .multiway(4, { W: -90, S: 90 });

Part of Crafty's cleverness is in it's component based entity system. The first line tells the Crafty library that you're defining a new entity called "Paddle" which is a 2D, DOM behavior like, color'd objected that reacts to multiple user inputs. Break down:

.color(...) defines the paddles color
.attr(...) defines the entities dimensions AND position.
.multiway(...) is a clear API method which states
the entities movement speed, and then which direction a triggered keyboard input will send the entitiy. So in the above case W is north, and S is south.

Skipping the other paddle, we come to the ball in a pong game.

Crafty.e("2D, DOM, Color, Collision")
    .color('rgb(0,0,255)')
    .attr({ x: 300, y: 150, w: 10, h: 10,
            dX: Crafty.math.randomInt(2, 5),
            dY: Crafty.math.randomInt(2, 5) })
    .bind('EnterFrame', function () {
        //hit floor or roof
        if (this.y <= 0 || this.y >= 290)
            this.dY *= -1;

        if (this.x > 600) {
            this.x = 300;
            Crafty("LeftPoints").each(function () {
                this.text(++this.points + " Points") });
        }
        if (this.x < 10) {
            this.x = 300;
            Crafty("RightPoints").each(function () {
                this.text(++this.points + " Points") });
        }

        this.x += this.dX;
        this.y += this.dY;
    })
    .onHit('Paddle', function () {
    this.dX *= -1;
})

Something I glossed over, Crafty's e(...) function is actually a Javascript prototype class generator. It's important to note that because of the interplay between .attr() and every other post e(...) method call.

In the above

.attr({ x: 300, y: 150, w: 10, h: 10,
            dX: Crafty.math.randomInt(2, 5),
            dY: Crafty.math.randomInt(2, 5) })

defines additional properties of the entity. x/y & w/h are already used by the 2D and DOM components to determine the entities position on but in the later .bind("EnterFrame") notice that the logic involved is referencing this attributes.

So inside the EnterFrame handler for the Ball are two crucial sections.

if (this.x > 600) {
            this.x = 300;
            Crafty("LeftPoints").each(function () {
                this.text(++this.points + " Points") });
        }
        if (this.x < 10) {
            this.x = 300;
            Crafty("RightPoints").each(function () {
                this.text(++this.points + " Points") });
        }

These two if clauses handle bounds check's and then depending on position award the appropriate side a point.

Notice the Crafty("") calls.  In this case Crafty("LeftPoints") calls up the appropriate entity or entities ( in this case there are only 1 per side ) and applies a closure to increment the winning side's this.points and body text.


The other crucial section is the 2 line closure 

.onHit('Paddle', function () {
    this.dX *= -1;
}

A fairly cool concept in Crafty is that collision detection between almost any entity is dealt with by Crafty, so to determine if the Ball hits a paddle, you just have to ask Crafty.

Summary

I was fairly impressed with CraftyJS, it is very much the spiritual relative of jQuery for a dirt simple and comfortably clever API. Unfortunately Crafty can blind side you with it's cleverness if you're not careful. What I mean is that in experimenting with CraftyJS I found it fairly easy to create non-obvious memory leaks and or abuse closures to much.

Still it's a fairly nice library and though this post is slightly long, I am only covering a thin scratch of the depth that is in CraftJS. This could be a fantastic building stage for making a slew of quick and dirty games.

Sencha Touch v2 with style

You wouldn’t write a HTML form like this:



So why the hell would you write a Sencha Touch form like

Ext.define("SoopaForm", {
   config: {
         style: "radius-border:12px; border: thin solid black; background-color: blue",
         items: [
             {
                xtype: 'textfield',
                name: 'username',
                label: 'Username',
                labelStyle: 'background: none !important; width: 45%',
                style: 'background-color: white !important; border: thin solid white !important'
             },
             {
                xtype: 'passwordfield',
                name: 'password',
                label: 'Password',
                labelStyle: 'background: none !important; width: 45%',
                style: 'background-color: white !important; border: thin solid white !important'
             },
             {
                  xtype: 'button',
                  text: 'Submit',
                  action: 'submit'
             }
             
         ]
   }
});

ExtJS 4 AND Sencha Touch 2 come with a feature complete Sass/Compass sencha-touch css package ( just need to ruby gem install sass & compass ). From there, you can easily style your ExtJS4/Touch UI with some housekeeping similar to compass watch ( background polling compile on detection system ). You’re business logic will be cleaner, you styling will be more consistent, and more importantly it will make you totally look like a badass when you restyle an entire mobile app in minutes instead of days.

HTML5 Canvas windowing proof of concept/prototype

Code is here ( https://gist.github.com/a17216d5b1db068ab41b )

Taking a break from a client project today and decided to try something real quick out. For one of my unpublished pet projects ( a near real time web based MUD ) I wanted a little map window to give visual feedback to the user on where exactly they were. Fortunately the Canvas API makes this stupid easy.

       var oX = this.player.x * (this.mMX / this.rMX);
    var oY = this.player.y * (this.mMX / this.rMY);
    
    var halfX = ( this.wMX / 2 );
    var halfY = ( this.wMY / 2 );
    
    var startX = Math.max(0, oX - halfX);
    var startY = Math.max(0, oY - halfY);
    
    var endX = Math.max(startX + this.wMX);
    var endY = Math.max(startY + this.wMY);
    
    var buffer = this.ctx.getImageData(startX, startY, endX, endY);
    this.window.putImageData(buffer, 0, 0);

First block takes the player or avatars position then scales up their grid position to the map canvas position.

Second block gets middle point of the window canvas, in this case if the window is 150×150, the origin is (75,75)

Now given the player’s position in the canvas map it finds the upper left and lower right corners of the map that is going to be copied from the map canvas into the window canvas. The Math.Max’s are there to prevent the upper left corner from being an impossible point (123, -50 ).

The end*’s use of Math.Max is actually crap on my part and isn’t needed.

Object oriented Javascript

Generally there is only two ways to make a “class” in Javascript. The first is the prototypical way


function Foo(){
      this.someProperty = "123";
}

Foo.prototype.bar = function(){
     console.log("howdy", this.someProperty);
}

var blah = new Foo();
Foo.someProperty = "Hello World!");
Foo.bar();
>>"Howdy", "Hello World"

or something like

   function Foo(){
       this.someProperty = 123;
       this.bar = function(){
              console.log("Howdy", this.someProperty);
       }
   }

It’s sometimes not trivial to choose one over the other. The prototypical path is a tad faster instantiating while the second can be easier to write, read, and maintain. Generally I chose the prototypical when I know I’ll be instantiating the desired object a lot ( thousands to tens or thousands of times ) while the second is preferred when I’m writing a more complicated object definition.

You’d think it would be slam dunk to always choose the closure ( 2nd variety ) but it has one major flaw, by itself, you cannot inherit a closure based class.

Fortunately its 2011 and at this point someone is guaranteed to have already run into the same problem. From my personnel experience, the first group that solved this problem was PrototypeJS and their class system, then I ran into ExtJS and their system. Great and all but what if I don’t want everything else that comes with these two frameworks?

No problem:
There’s the super diet solution offered by John Resig’s proof of concept Simple inheritence thing

and a much more advanced system called BaseJS by Dean Edwards ( http://code.google.com/p/base2/ ).

If I know a projects going to be somewhat involved I would go with investing in Base2JS but if not, John Regig’s script is good enough.

The magic JS console thing

Source here – https://github.com/devdave/DevDave-s-miscellanious-bucket/tree/master/jsConsole

Just wanted to see what would be involved in making a terminal like UI for the web. Honestly there’s a few REALLY annoying bits, but with a bit of hackery it was pretty straight forward. I’ve found splitting up the keyCode/which between key press and key down events was a lot simpler then making some sort of jury rigged code to character map when trying to compute shifted keys.

Also, I put in a brutally ugly left to right parser that does auto-complete / tab completion for good measure. It’s got a very limited vocabulary but I could easily snap it into an asyncronous Ajax handler to bridge it with a much more powerful server side module.

Like all of my short term projects, no warranty or guarantee that it works is provided or implied.

Javascript has arrived in force

A quick tally of prospective clients this season is showing that JS is very much in demand in everything from HTML5 mobile support, to Ajaxifying web applications, to more exotic stuff. I’m really glad I invested myself five years ago in developing my grasp of JS, this was one technology choice I appear to have made right.

A web-console implemented in nodeJS

Reading over this ( http://gonzalo123.wordpress.com/2011/05/16/web-console-with-node-js/ ) , I felt this was a pretty good and relatively real world example of nodeJS’s capabilities. I did find one line near the end very poignant and reflective of my own opinions at the end of the show & tell post

I don’t know if node.js is the future or is just another hype, but it’s easy. And cool. Really cool.

New language to the toolset: NodeJS

I’ve started self-teaching myself NodeJS and not surprisingly there was a recent popular reddit link pointing to a not very short introduction to nodejs here ( http://anders.janmyr.com/2011/05/not-very-short-introduction-to-nodejs.html ) . At this point I haven’t found any good books for reference lookup… but hopefully in a week or so I’ll have gotten spooled up enough to be able to report back.

In the meantime as I use Ubuntu for everything but games, this short article here ( http://www.codediesel.com/linux/installing-node-js-on-ubuntu-10-04/ ) was enough to get a working environment running though I recommend using a pristine virtual machine instance to keep things simple.

Last point, a reliable friend & peer of mine recommended I check out this MVC like framework for NodeJS ( http://expressjs.com/ ). Preliminary it feels like a hybrid between Twistd and CherryPy in Python or Limonade PHP as far as style… aiming more for simplicity over feature/complexity.