nooshu - Matt Hobbs' Web Development Blog

Kneeling on the shoulders of giants

Category: JavaScript

All things JavaScript in its many forms, be it plain old JavaScript to a cutting edge Library abstraction.

Aloha Editor – Content editing the HTML5 way

The number of times I’ve built a website based on a CMS only to have the client utter the words “Oh I’m confused, it’d be so much quicker if you made the changes”. Right, so the CMS was a bit of a waste of time then! But fingers crossed thanks to Aloha Editor that may be a thing of the past. Often the problem clients have is actually finding the content that needs to be edited in the CMS; Aloha to the rescue!

What Aloha actually does is make the content editable right on the page; no need to jump into the CMS, find the page, make the changes then preview the result. Just click on the text you wish to edit and type away. Done! It’s hard to believe it actually works until you try it. Why not give it a go on their demo page. It incorporates a few HTML5 technologies which could cause issues with older IE versions, but the demo page seems to work (with a few quirks).

An example of Aloha Editor in action

Quickly and easily edit the demo webpage.

The core has been written to be very small and streamlined, with additional functionality being added by the way of user contributed plug-ins. There’s already an extensive API for developers to play with so I’m sure many of the missing features will be plugged very soon.

There are alternatives about such as TinyMCE and CKEditor, but they’re integrated directly into a CMS’ administration pages rather than as an inline editor like Aloha. Now before you get too excited there are a few cons:

  • It isn’t as simple as just dropping the scripts into a page, it needs to be integrated into a backend system for the changes to be saved.
  • Still in early development so could be quite buggy.
  • Doesn’t work with Opera Browser at the moment but this is being worked on.
  • Some features aren’t available yet, like image / media insertion. But I’m sure these will be developed as it matures.

So there are still a few issues to iron out but it all looks very promising! There were even murmurs on Twitter today about a WordPress plug-in and a Drupal v7 module (not 6 though I presume) in development. So it won’t be long before we’ll be able to try it out on a live site; hopefully it’s also simple enough for clients to use too!

JS1k: Original source

Unfortunately I haven’t been able to put together another JS1k demo as I’ve had lots of ‘real’ work going on at the moment (boo!); so I thought I’d post a fully commented version of the JavaScript code for anyone who is interested to look over.

Some of the entries have been breathtaking, making my poor little demo look a little simple! Never mind. I look forward to looking over the uncompressed source of the other entries. There are just so many things to learn from them!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/**
 * This uncompressed source is close to my entry submitted to JS1k.
 * The number of particles and colours are different, but the rest is
 * near enough the same. The code is structured in a much neater way.
 */

var animate = function(){
    //Grab our canvas object and context
    var canvas = document.getElementById('c');
    var c = canvas.getContext('2d');
   
    //Set the canvas width to the same as the browser
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
   
    //Make the body background black and hide the scroll bars
    document.body.style.background = "black";
    document.body.style.overflow = "hidden";
   
    //Grab the width / height of the canvas for later use
    var width = canvas.width,
    height = canvas.height;
   
    //Arrays used to store the position / speed / direction and radius of the particles
    var posY = [],
    posX = [],
    speedX = [],
    speedY = [],
    directionX = [],
    directionY = [],
    radius = [];
   
    return {
        //Our initialise function
        init: function(){
            //Look at the width and generate a number of particles
            for(i = 10; i < width; i += 30) {
               
                //For each ballplace it in a random location
                var generatedX = Math.floor(Math.random()*width);
                var generatedY = Math.floor(Math.random()*height);
               
                //Set the initial particle start positions
                posX[i] = generatedX;
                posY[i] = generatedY;
               
                //Each particle has a random x and y speed
                var generatedSpeedX = 1 + Math.ceil(Math.random()*8);
                var generatedSpeedY = 1 + Math.ceil(Math.random()*8);
               
                //Set the initial speeds
                speedX[i] = generatedSpeedX;
                speedY[i] = generatedSpeedY;
               
                //Set the x and y directions of each particle
                (Math.ceil(Math.random()*2) === 1) ? directionX[i] = 1 : directionX[i] = -1;
                (Math.ceil(Math.random()*2) === 1) ? directionY[i] = 1 : directionY[i] = -1;
               
                //Each particle has a different radius
                radius[i] = 10 + Math.ceil(Math.random()*5);
            }
           
            //Fire our draw function every 10ms
            setInterval(this.draw, 20);
        },
        //Fun this function to draw a frame
        draw: function(){
            //Clear the last frame by filling it black (clearRect caused issues in chrome)
            c.fillStyle = "black";
            c.fillRect(0,0,width,height);
               
                //Loop through each particle
                for(i=10;i<width;i+=30){
                   
                    //Change its x direction if it gets to the boundry
                    if(posX[i] > width || posX[i] < 0){
                        directionX[i] *= -1;
                    }
                    //Change its y direction if it gets to the boundry
                    if(posY[i] > height || posY[i] < 0){
                        directionY[i] *= -1;
                    }
                   
                    //Save the canvas settings before we modify anything (clip)
                    c.save();//Before path
                   
                        //For each particle begin a path around its position
                        c.beginPath();
                        c.arc(posX[i],posY[i],radius[i],0,Math.PI * 2,false);
                        //Clip the path ready to be filled later
                        c.clip();
                       
                        //Set the red radial gradient alpha to 1
                        c.globalAlpha = 1;
                       
                        //Create our red radial gradient up the top left corner
                        var radGradRed = c.createRadialGradient(width/4,height/4,100,width/4,height/4,width/4);
                        radGradRed.addColorStop(0, 'red');
                        radGradRed.addColorStop(1, 'black');
                        c.fillStyle = radGradRed;
                       
                        //Create a rectangle filled using the red radial
                        c.fillRect(0,0,width,height);
                       
                        //Set the global alpha to 0.6 for the next box (so the red shines through)
                        c.globalAlpha = 0.6;
                       
                        //Create our green radial gradient up the top right corner
                        var radGradGreen = c.createRadialGradient(3*width/4,height/4,100,3*width/4,height/4,width/4);
                        radGradGreen.addColorStop(0, 'green');
                        radGradGreen.addColorStop(1, 'black');
                        c.fillStyle = radGradGreen;
                       
                        //Create a rectangle filled using the green radial
                        c.fillRect(0,0, width, height);
           
                        //Set the global alpha to 0.4 for the next box (red / green shines through)
                        c.globalAlpha = 0.4;
                       
                        //Create our blue radial gradient at the bottom middle
                        var radGradBlue = c.createRadialGradient(width/2,3*height/4,100,width/2,3*height/4,width/4);
                        radGradBlue.addColorStop(0, 'blue');
                        radGradBlue.addColorStop(1, 'black');
                        c.fillStyle = radGradBlue;
                       
                        //Create a rectangle filled using the green radial
                        c.fillRect(0,0,width,height);
                   
                    //Restore the canvas to how it was before the clipping path
                    c.restore();
                   
                    //Set the new x and y position of the selected particle
                    posX[i] += directionX[i]*speedX[i];
                    posY[i] += directionY[i]*speedY[i];
                }
           
            //Set the new global alpha to 0.9 for the static particles
            c.globalAlpha = 0.9;
           
            //Create a red particle top left
            c.fillStyle = "red";
            c.beginPath();
            c.arc(width/4,height/4, 20, 0, Math.PI * 2, false);
            c.fill();
           
            //Create a green particle top right
            c.fillStyle = "green";
            c.beginPath();
            c.arc(3*width/4, height/4, 20, 0, Math.PI * 2, false);
            c.fill();
           
            //Create a blue particle middle bottom
            c.fillStyle = "blue";
            c.beginPath();
            c.arc(width/2, 3*height/4, 20, 0, Math.PI * 2, false);
            c.fill();
        }
    };
}();

//Call the init function and get the particles moving
animate.init();

Or for those of you who are a fans of jsFiddle I’ve pasted it here for you look at.

JS1k: JavaScript Optimisations

Following up on my post on JS1k I thought I’d put together a small list of optimisations you can use if you’re looking to minify your code before compressing it. When you only have 1024 bytes to play with every byte counts!

Very obvious, store your objects for later use. You may need to use the document / context later so store them in a single byte variable.

1
2
3
4
5
6
7
8
//From:
var canvas = document.getElementById('c')
var context = canvas.getContext('2d')

//To:
d=document
t=d.getElementById('c')
c=t.getContext('2d')

If you are using Math object / functions, don’t repeat ‘Math’ over and over. It may not look much at first but it will pay off and save you loads of bytes

1
2
3
4
5
6
7
8
//From:
var colour = Math.floor(Math.random()*255);

//To:
M=Math
R=M.random
L=M.floor
colour = L(R()*255)

I found myself using 2 Pi and false quite a lot in the arc method, so why not minify them too.

1
2
3
4
5
6
7
//From:
context.arc(posX, posY, radius, 0, Math.PI*2, false);

//To (uses Math example above too):
P=M.PI*2
f=false
context.arc(posX, posY, radius, 0, P, f);

For your ‘draw’ function use an anonymous function within setInterval(). This will save you around 5 bytes.

1
2
3
4
5
6
7
8
9
10
//From:
function d(){
    //Code goes here...
}
setInterval(d,9)

//To:
setInterval(function(){
    //Code goes here...
},9)

When it comes to the canvas API it is necessary to minimise it’s usage at times since the methods can’t be stored like we did with the Math object. For that I used a mixture of arrays and for while loops.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//From:
ctx.fillStyle = "red";
ctx.beginPath();
ctx.arc(50, 100, 10, 0, Math.PI*2, false);
ctx.closePath();
ctx.fill();

ctx.fillStyle = "blue";
ctx.beginPath();
ctx.arc(143, 230, 15, 0, Math.PI*2, false);
ctx.closePath();
ctx.fill();//Add more if needed...

//To:
A=["red",50,100,10,"blue",143,230,15];
i=2;while(i--){
    D=i*4;
    ctx.fillStyle = A[D];
    ctx.beginPath();
    ctx.arc(A[D+1], A[D+2], A[D+3], 0, P, f);//We stored 2Pi and false in a var above
    //removed closepath() as this is done when fill is called
    ctx.fill();
}

Another quite obvious one, use the ternary operator instead of an if else statement.

1
2
3
4
5
6
7
8
9
10
//From:
if(Math.ceil(Math.random()*2) == 1){
    var result = 1
} else {
    result = -1
}

//To:
Math.ceil(Math.random()*2) == 1 ? result = 1:result = -1
//Remember you can minify the Math functions

An excellent couple of tips from Ben Almans blog post.

1
2
3
4
5
6
7
8
9
10
11
12
13
/*Backwards iterating while loop*/
//From:
for(i=0;i<20;i++){} //19 bytes

//To:
i=20;while(i--){} //17 bytes

/*Use 'this' instead of 'window'*/
//From:
w=window

//To:
w=this

Hopefully you’ve found some of these JavaScript short-cuts useful. Have any more to add to the list? Leave a comment below!

JS1k: Smaller is Better!

Every once in a while something really grabs my interest. Since being introduced to Mr doob and remembering back to the amazing demos you used to get on various Amiga software (cough..); the demoscene has got me thinking about all the cool new possibilities for Web Developers. You can easily use JavaScript and the canvas tag and go visualisation crazy. Now when you mix in another factor: set a limit to the size of the code you can use; then it becomes really interesting!

Peter van der Zee has created a competition called JS1k, where the aim is to see what you can achieve using JavaScript and a canvas tag with a strict limit of 1024 bytes (1k). To put that in perspective, your average web page is 507K, so there isn’t a lot of room for manoeuvre! Saying that though, you will be surprised with what you can achieve with only 1024 bytes. Take a look at some of the accepted submissions and prepare to be amazed.

I’ve submitted my own entry which you can view here, it hasn’t been updated to the latest version yet but I’m sure it will be soon.

Particles changing colour depending on their proximity to different coloured circles.

My entry into JS1k. Looks simple but was a challenge to come under the 1k limit

Compared to some of the entries my demo looks a tad boring, but I really enjoyed putting it together. Condensing a script that was originally over 3.5k down to 1024 bytes was a real challenge. The last 20 bytes in particular were a pain in the backside! In version 0.2 I hit 1024 bytes exactly as I hadn’t realised you also have to style the demo page slightly if you use a black background. I think I may be able to shave a couple more bytes off, but I’m really coming close to the limit. The resulting code isn’t pretty and in no way readable, but it works! Take a look for yourself with a “view source” on the demo page.

According to Peter the competition is open until the 10th September, so I may just create a new demo and see how I get on. On a side note, JavaScript wizard p01 has dabbled with even smaller code limits of 512, 256 and 128 bytes. The results of which you can see here. Impressive stuff! I’m looking forward to seeing his entry into the competition.

Update: After a few optimisations and a run through the closure compiler I managed to get the demo down to 957 bytes.

Learning HTML5 Canvas

For a good while now I’ve been wanting to explore generating visualisations using JavaScript, and there really hasn’t been an easier time to do it with web technologies like Canvas and Processing (via processing.js). As with all things in life there’s never enough hours in the day to do everything. I’ve had the excellent book by Daniel Shiffman, ‘Learning Processing‘ which I’m about 4 chapters into; stareing back at me on my desk for 8 months now. It’s all bright and orange and full of cool stuff! But alas no time… until now. Time for me to pull my finger out and learn something new.

In terms of canvas I’ve already gone through quite a few tutorials on the API and how it works, so I’m not quite a complete beginner. If you are just starting out with canvas one set of tutorials I found particularly helpful is located at the Mozilla developer center (MDC). I must admit I’m struggling to find intermediate tutorials; lots of inspirational demonstrations but the code can make your head hurt due to its complexity.

I’ve compiled a list of canvas related demos and sites below, which I’ve been reading. I’m going to concentrate on canvas for the moment then come back to Processing at a later date.

html5 canvas with liquid particles

Liquid Particles demo by Daniel Puhe

Visualisations

  • Liquid Particles: Loving the simplicity and the bright colours. Try leaving the particles to collect into a tight ball then rip it apart!
  • JuicyDrop: If you ever tried Milkdrop for Winamp you will love this port to canvas. There are four examples of the thousands of Milkdrop visualisations available.
  • HTML 5 Audio Experiment: Another particle based visualisation, this time mixed with audio. I don’t think the particles react to the audio (correct me if I’m wrong!) as it seems to be a repeating pattern. But still very cool!
  • 3D landscape on HTML5 Canvas: Superb 3D visualisation by Seb Lee-Delisle. Canvas may only have a 2D context at the moment but with a little JavaScript magic you can create 3D visualisations.
canvas html5 video in 3d space

Blowing up a HTML5 Video in 3D space using canvas by Craftymind

Technical Demos

  • Blowing up HTML5 video: If the addition of plug-in less video wasn’t enough in HTML 5, check out this demo. Blow up a streaming video with a mouse click.
  • Cloth simulation: It may not sound that exciting but the demo is very clever. Pull and push the cloth with your mouse to see how the mesh changes. Maybe one day we will see Maya ported to HTML5 (it could take a while!)
  • Image Evolve: This has to be one of my favourite HTML5 canvas demos so far. Upload an image and watch how the computer generates the same image using overlapping polygons. The image improves over time; leave it a couple of days and a canvas based Mona Lisa can be yours!
  • Raycaster: If you’ve ever played Wolfenstein 3D this demo will look familiar. It may not look too pretty but it’s a great proof of concept.
retro asteroids in HTML5

HTML 5 Asteroids by Doug McInnes

Games

  • HTML 5 Asteroids: If you are into retro arcade games there are plenty to choose from built with HTML5. Here’s the classic ‘Astroids’ for your time wasting pleasure.
  • HTML5 Pacman: Another classic, this time Pacman. A of version of Pacman hit the news recently when Google replaced their logo with a playable version of Pacman and cost 4.2 million hours of productivity. Not bad people!
  • Experimenting With Textures: Much like the Raycaster technical demo above only a little more advanced. The game actually looks to use some of the original Wolfenstein 3D textures. Now where are the German soldiers?
  • Torus: Looking for a 3D version of Tetris? Look no further as Ben Joffe has done exactly that.
Fire by mr doob

One of many experiments by Mr doob, this one is called 'Fire'.

Compilation Sites & Experiments

  • Mr Doob: If you haven’t seen Mr Doobs site you’ve been missing out. Lots of HTML5 and Flash experiments for you to look at. You can learn lots by doing a quick view source!
  • Chrome Experiments: To promote their Chrome browser Google launched Chrome Experiments. The demos available really show off the speed of the V8 JavaScript engine.
  • Hakim.se: If you like particle visualisations you will love the site by Hakim El Hattab. The HTML5 – Keylight demo is superb.
  • Andrew Hoyer: I mentioned this site earlier with the cloth simulation; but Andrews other experiments are also worth looking at. If you like mathematics you will love these demos. On a side note I’m impressed with the site design too!

Wow there’s a lot to look at there, with more and more coming out every day. So little time! If only I didn’t have to sleep…

Currently on page 1 of 712345Last »