html5 – Parerga und Paralipomena http://www.michelepasin.org/blog At the core of all well-founded belief lies belief that is unfounded - Wittgenstein Wed, 08 Feb 2012 17:34:12 +0000 en-US hourly 1 https://wordpress.org/?v=5.2.11 13825966 HTML5 Canvas Cookbook http://www.michelepasin.org/blog/2012/02/08/html5-canvas-cookbook/ Wed, 08 Feb 2012 17:34:12 +0000 http://www.michelepasin.org/blog/?p=1815 HTML5 Canvas Cookbook is a new publication from Packt publishing that discusses in details the new drawing functionalities the html5 canvas element makes available; in the last weeks I’ve been looking at this book in more details and since it’s been a quite useful learning experience I wanted to mention it here too.

The book (which is available online here )is simple and well organized; it spends quite a bit of time on both introductory topics and more advanced ones, so it’ll probably fit both the beginner and the more experienced programmer.

Here’s a list of the chapters available:

CHAPTER 1: GETTING STARTED WITH PATHS AND TEXT
Introduction
Drawing a line
Drawing an arc
Drawing a Quadratic curve
Drawing a Bezier curve
Drawing a zigzag
Drawing a spiral
Working with text
Drawing 3D text with shadows
Unlocking the power of fractals: Drawing a haunted tree

CHAPTER 2: SHAPE DRAWING AND COMPOSITES
Introduction
Drawing a rectangle
Drawing a circle
Working with custom shapes and fill styles
Fun with Bezier curves: drawing a cloud
Drawing transparent shapes
Working with the context state stack to save and restore styles
Working with composite operations
Creating patterns with loops: drawing a gear
Randomizing shape properties: drawing a field of flowers
Creating custom shape functions: playing card suits
Putting it all together: drawing a jet

CHAPTER 3: WORKING WITH IMAGES AND VIDEOS
Introduction
Drawing an image
Cropping an image
Copying and pasting sections of the canvas
Working with video
Getting image data
Introduction to pixel manipulation: inverting image colors
Inverting video colors
Converting image colors to grayscale
Converting a canvas drawing into a data URL
Saving a canvas drawing as an image
Loading the canvas with a data URL
Creating a pixelated image focus

CHAPTER 4: MASTERING TRANSFORMATIONS
Introduction
Translating the canvas context
Rotating the canvas context
Scaling the canvas context
Creating a mirror transform
Creating a custom transform
Shearing the canvas context
Handling multiple transforms with the state stack
Transforming a circle into an oval
Rotating an image
Drawing a simple logo and randomizing its position, rotation, and scale

CHAPTER 5: BRINGING THE CANVAS TO LIFE WITH ANIMATION
Introduction
Creating an Animation class
Creating a linear motion
Creating acceleration
Creating oscillation
Oscillating a bubble
Swinging a pendulum
Animating mechanical gears
Animating a clock
Simulating particle physics
Creating microscopic life forms
Stressing the canvas and displaying the FPS

CHAPTER 6: INTERACTING WITH THE CANVAS: ATTACHING EVENT LISTENERS TO SHAPES AND REGIONS 
Introduction
Creating an Events Class
Working With Canvas Mouse Coordinates
Attaching Mouse Event Listeners to Regions
Attaching Touch Event Listeners to Regions on a Mobile Device
Attaching Event Listeners to Images
Dragging-And-Dropping Shapes
Dragging-And-Dropping Images
Creating an Image Magnifier
Creating a Drawing Application

CHAPTER 7: CREATING GRAPHS AND CHARTS
Introduction
Creating a pie chart
Creating a bar chart
Graphing equations
Plotting data points with a line chart

CHAPTER 8: SAVING THE WORLD WITH GAME DEVELOPMENT
Introduction
Creating sprite sheets for the heroes and enemies
Creating level images and boundary maps
Creating an Actor class for the hero and enemies
Creating a Level class
Creating a Health Bar class
Creating a Controller class
Creating a Model class
Creating a View class
Setting up the HTML document and starting the game

CHAPTER 9: INTRODUCING WEBGL
Introduction
Creating a WebGL wrapper to simplify the WebGL API
Creating a triangular plane
Rotating a triangular plane in 3D space
Creating a rotating cube
Adding textures and lighting
Creating a 3D world that you can explore

The last chapters about animations and game developments are probably the most interesting ones, especially they all include detailed walk-through of the techniques discussed. Here’s for example an example from Chapter 5, ‘Oscillating a bubble’:


[inline]

[script type=”text/javascript”]

var Animation = function(canvasId){
this.canvas = document.getElementById(canvasId);
this.context = this.canvas.getContext(“2d”);
this.t = 0;
this.timeInterval = 0;
this.startTime = 0;
this.lastTime = 0;
this.frame = 0;
this.animating = false;

// provided by Paul Irish
window.requestAnimFrame = (function(callback){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
};
})();
};

Animation.prototype.getContext = function(){
return this.context;
};

Animation.prototype.getCanvas = function(){
return this.canvas;
};

Animation.prototype.clear = function(){
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
};

Animation.prototype.setDrawStage = function(func){
this.drawStage = func;
};

Animation.prototype.isAnimating = function(){
return this.animating;
};

Animation.prototype.getFrame = function(){
return this.frame;
};

Animation.prototype.start = function(){
this.animating = true;
var date = new Date();
this.startTime = date.getTime();
this.lastTime = this.startTime;

if (this.drawStage !== undefined) {
this.drawStage();
}

this.animationLoop();
};

Animation.prototype.stop = function(){
this.animating = false;
};
Animation.prototype.getTimeInterval = function(){
return this.timeInterval;
};

Animation.prototype.getTime = function(){
return this.t;
};

Animation.prototype.getFps = function(){
return this.timeInterval > 0 ? 1000 / this.timeInterval : 0;
};

Animation.prototype.animationLoop = function(){
var that = this;

this.frame++;
var date = new Date();
var thisTime = date.getTime();
this.timeInterval = thisTime – this.lastTime;
this.t += this.timeInterval;
this.lastTime = thisTime;

if (this.drawStage !== undefined) {
this.drawStage();
}

if (this.animating) {
requestAnimFrame(function(){
that.animationLoop();
});
}
};

window.onload = function(){
// instantiate new animation object
var anim = new Animation(“myCanvas”);
var context = anim.getContext();
var canvas = anim.getCanvas();

anim.setDrawStage(function(){
// update
var widthScale = Math.sin(this.getTime() / 200) * 0.1 + 0.9;
var heightScale = -1 * Math.sin(this.getTime() / 200) * 0.1 + 0.9;

// clear
this.clear();

//draw
context.beginPath();
context.save();
context.translate(canvas.width / 2, canvas.height / 2);
context.scale(widthScale, heightScale);
context.arc(0, 0, 65, 0, 2 * Math.PI, false);
context.restore();
context.fillStyle = “#8ED6FF”;
context.fill();
context.lineWidth = 2;
context.strokeStyle = “#555”;
context.stroke();

context.beginPath();
context.save();
context.translate(canvas.width / 2, canvas.height / 2);
context.scale(widthScale, heightScale);
context.arc(-30, -30, 15, 0, 2 * Math.PI, false);
context.restore();
context.fillStyle = “white”;
context.fill();
});

anim.start();
};

[/script]

[/inline]

 

In a nutshell, this is what is going on (note that the ‘animation’ library is discussed in a previous chapter of the book):

 

<script src="animation.js"></script>
<script>
    window.onload = function(){
        // instantiate new animation object
        var anim = new Animation("myCanvas");
        var context = anim.getContext();
        var canvas = anim.getCanvas();
        
        anim.setDrawStage(function(){
            // update
            var widthScale = Math.sin(this.getTime() / 200) * 0.1 + 0.9;
            var heightScale = -1 * Math.sin(this.getTime() / 200) * 0.1 + 0.9;

            // clear
            this.clear();
            
            //draw
            context.beginPath();
            context.save();
            context.translate(canvas.width / 2, canvas.height / 2);
            context.scale(widthScale, heightScale);
            context.arc(0, 0, 65, 0, 2 * Math.PI, false);
            context.restore();
            context.fillStyle = "#8ED6FF";
            context.fill();
            context.lineWidth = 2;
            context.strokeStyle = "#555";
            context.stroke();
            
            context.beginPath();
            context.save();
            context.translate(canvas.width / 2, canvas.height / 2);
            context.scale(widthScale, heightScale);
            context.arc(-30, -30, 15, 0, 2 * Math.PI, false);
            context.restore();
            context.fillStyle = "white";
            context.fill();
        });
        
        anim.start();
    };
</script>

 

All in all, a book definitely worth reading!

 

]]>
1815
First steps with Canvas and HTML5 http://www.michelepasin.org/blog/2011/08/25/first-steps-with-canvas-and-html5/ Thu, 25 Aug 2011 14:47:35 +0000 http://www.michelepasin.org/blog/?p=1503 I’ve been postponing experimenting with HTML5 for quite a while, so today I finally set aside a few hours to play with it. This is a very simple example of the graphic effects you can create using javascript and the HTML5 canvas element..

Note that the examples below will work only on HTML5-compatible browsers, such as the latest versions of Chrome or Firefox..

1. Setting up a canvas and drawing some lines on it.

This is easily done using the moveTo and lineTo functions. So let’s create a simple symmetrical geometrical shape..


Your browser does not support the canvas element.

[inline]

[script type=”text/javascript”]

var c=document.getElementById(“myCanvas1”);
var cxt=c.getContext(“2d”);
var i=0;

for (i=1;i<=5;i++) { cxt.moveTo(0, 400); cxt.lineTo(100, i * 40); cxt.lineTo(300, i * 60); cxt.lineTo(400, i * 30); cxt.lineTo(500, i * 60); cxt.lineTo(700, i * 40); cxt.lineTo(800, 400); } cxt.stroke(); [/script] [/inline]

Here’s the source code:

<!DOCTYPE HTML>
<html>
<body>

<canvas id="myCanvas1" width="800" height="400" style="border:1px dashed #c3c3c3;">
Your browser does not support the canvas element.
</canvas>

<script type="text/javascript">

var c=document.getElementById("myCanvas1");
var cxt=c.getContext("2d");
var i=0;

for (i=1;i<=5;i++)
{
cxt.moveTo(0, 400);
cxt.lineTo(100, i * 40);
cxt.lineTo(300, i * 60);
cxt.lineTo(400, i * 30);
cxt.lineTo(500, i * 60);
cxt.lineTo(700, i * 40);
cxt.lineTo(800, 400);
}

cxt.stroke();

</script>

</body>
</html>

 

2. Creating a mirroring effect

Now we can increase the size of the canvas to 800 and replicate these lines at the bottom of the canvas so to achieve a ‘mirroring’ effect.. since we know the max Y value of the canvas (800), let’s just add another loop that draws the same lines but inverts the Y position. This is easily achieved by subtracting the constant-dependent parameter from the max value of Y.


Your browser does not support the canvas element.

[inline]

[script type=”text/javascript”]

var c=document.getElementById(“myCanvas2”);
var cxt=c.getContext(“2d”);
var i=0;

for (i=1;i<=5;i++) { cxt.moveTo(0, 400); cxt.lineTo(100, i * 40); cxt.lineTo(300, i * 60); cxt.lineTo(400, i * 30); cxt.lineTo(500, i * 60); cxt.lineTo(700, i * 40); cxt.lineTo(800, 400); } for (i=5;i>=1;i–)
{
cxt.moveTo(0, 400);
cxt.lineTo(100, 800 – (i * 40));
cxt.lineTo(300, 800 – (i * 60));
cxt.lineTo(400, 800 – (i * 30));
cxt.lineTo(500, 800 – (i * 60));
cxt.lineTo(700, 800 – (i * 40));
cxt.lineTo(800, 400);
}

cxt.stroke();

[/script]

[/inline]

This is how the new source code looks like:

<canvas id="myCanvas2" width="800" height="800" style="border:1px dashed #c3c3c3;">
Your browser does not support the canvas element.
</canvas>

<script type="text/javascript">

var c=document.getElementById("myCanvas2");
var cxt=c.getContext("2d");
var i=0;

for (i=1;i<=5;i++)
{
cxt.moveTo(0, 400);
cxt.lineTo(100, i * 40);
cxt.lineTo(300, i * 60);
cxt.lineTo(400, i * 30);
cxt.lineTo(500, i * 60);
cxt.lineTo(700, i * 40);
cxt.lineTo(800, 400);
}


for (i=5;i>=1;i--)
{
cxt.moveTo(0, 400);
cxt.lineTo(100, 800 - (i * 40));
cxt.lineTo(300, 800 - (i * 60));
cxt.lineTo(400, 800 - (i * 30));
cxt.lineTo(500, 800 - (i * 60));
cxt.lineTo(700, 800 - (i * 40));
cxt.lineTo(800, 400);
}

cxt.stroke();

</script>

 

3. Adding more graphical interest

Finally, let’s parametrize a bit more the construction of this geometrical pattern by including everything into another loop, and using this new counter to increment the points ordinate position. We’ll add a new variable y and use it to run the external loop 20 times. Here’s the result:


Your browser does not support the canvas element.

[inline]

[script type=”text/javascript”]

var c=document.getElementById(“myCanvas3”);
var cxt=c.getContext(“2d”);
var i=0;
var y=0;

for (y=1;y<=20;y++) { for (i=1;i<=5;i++) { cxt.moveTo(0, 400+y); cxt.lineTo(100, i * (40+y)); cxt.lineTo(300, i * (60+y)); cxt.lineTo(400, i * (30+y)); cxt.lineTo(500, i * (60+y)); cxt.lineTo(700, i * (40+y)); cxt.lineTo(800, 400+y); } for (i=5;i>=1;i–)
{
cxt.moveTo(0, 400);
cxt.lineTo(100, 800 – (i * (40+y)));
cxt.lineTo(300, 800 – (i * (60+y)));
cxt.lineTo(400, 800 – (i * (30+y)));
cxt.lineTo(500, 800 – (i * (60+y)));
cxt.lineTo(700, 800 – (i * (40+y)));
cxt.lineTo(800, 400+y);
}

}

cxt.stroke();

[/script]

[/inline]

Not too bad uh? This last modification to the code looks like this:

<canvas id="myCanvas3" width="800" height="800" style="border:1px dashed #c3c3c3;">
Your browser does not support the canvas element.
</canvas>

<script type="text/javascript">

var c=document.getElementById("myCanvas3");
var cxt=c.getContext("2d");
var i=0;
var y=0;

for (y=1;y<=20;y++)
{
    
    for (i=1;i<=5;i++)
    {
    cxt.moveTo(0, 400+y);
    cxt.lineTo(100, i * (40+y));
    cxt.lineTo(300, i * (60+y));
    cxt.lineTo(400, i * (30+y));
    cxt.lineTo(500, i * (60+y));
    cxt.lineTo(700, i * (40+y));
    cxt.lineTo(800, 400+y);
    }


    for (i=5;i>=1;i--)
    {
    cxt.moveTo(0, 400);
    cxt.lineTo(100, 800 - (i * (40+y)));
    cxt.lineTo(300, 800 - (i * (60+y)));
    cxt.lineTo(400, 800 - (i * (30+y)));
    cxt.lineTo(500, 800 - (i * (60+y)));
    cxt.lineTo(700, 800 - (i * (40+y)));
    cxt.lineTo(800, 400+y);
    }

}

cxt.stroke();

</script>

 

Cool! I’d like to know more..

Yes, I agree. This opens up a new world for web-based graphics.. and I just scratched the surface of it! In particular I’d like to see how this type of graphical components can be used to compose visualizations in the digital humanities – provided more interactivity is added to them.

Here are a couple if learning resources I found useful:

  • Learning the basics of HTML5 canvas on .Net magazine online
  • Canvas tutorial on Mozilla.org (more advanced)
  • Javascript Graphics and Effects Frameworks: useful document providing a list of the most common libraries for doing javascript-based graphics
  • Canvas and interactivity tutorial: a step by step discussion on how to create a ‘breakout’ game clone that you can play in your browser, using javascript and the canvas element
  • Creating an HTML 5 canvas painting application: nice tutorial that shows how to put together several canvas drawing techniques so to build a basic ‘painting’ application
  • 21 Ridiculously Impressive HTML5 Canvas Experiments: a collection of some state-of-the-art HTML5 canvas-based experiments that will make you say, “Wow!”
  •  

     

    ]]>
    1503
    Enabling web-audio in Chrome http://www.michelepasin.org/blog/2011/06/19/enabling-web-audio-in-chrome/ Sun, 19 Jun 2011 20:23:52 +0000 http://www.michelepasin.org/blog/?p=1028 I haven’t realized that Chrome has a whole bunch of invisible experimental settings that you can turn on just by going to “about:flags“.

     

    Chrome about:flags options view

     

    Some of them will open up the musical capabilities of html5, which are pretty cool. Example, once you switch on the ‘web-audio‘ setting on Chrome, if you use a suitable musical musical library you could play a note just by issuing these javascript commands:

    
    var n = Note.fromLatin('A4'); 
    
    var freq = n.frequency(); // returns 440 
    var name = n.latin(); // returns "A" 
    var octave = n.octave(); // returns 4

     

    The full example (with sound, if you’ve turned on the Web Audio setting as mentioned above) can be seen here: musicjs demo.

    More info about web audio and related stuff can be found on this blog post: http://pixelist.info/web-audio-it-is-finally-almost-here/

    ]]>
    1028
    Processing.js, iProcessing: javascript does everything for you! http://www.michelepasin.org/blog/2010/02/18/processing-js-iprocessing-javascript-does-everything-for-you/ Thu, 18 Feb 2010 15:26:09 +0000 http://magicrebirth.wordpress.com/?p=585 First off – check out how cool is the little game below. It’s been implemented with processing.js, a port of the famous processing library that works in your browser only through javascript (the original processing is java-based).

    What is processing?

    The Processing language was created by Ben Fry and Casey Reas. It evolved from ideas explored in the Aesthetics and Computation Group at the MIT Media Lab and was originally intended to be used in a Java run-time environment. In the Summer of 2008, John Resig ( inventor of jQuery ), ported the 2D context of Processing to Javascript for use in web pages.

    Mmm how about processing.js then?

    Processing.js is an open programming language for people who want to program images, animation, and interactions for the web without using Flash or Java applets. Processing.js uses Javascript to draw shapes and manipulate images on the HTML5 Canvas element. The code is light-weight, simple to learn and makes an ideal tool for visualizing data, creating user-interfaces and developing web-based games.

    Processing.js is explicitly developed for browsers that support the HTML5 <Canvas> element. Processing.js runs in FireFox, Safari, Opera and Chrome but will not be supported in Internet Explorer.

     

    There’s more: some people in London created iProcessing, which lets you develop iPhone apps without touching objC (at least, that’s what they say). Seems a bit of a revolution to me…

    iProcessing is an open programming framework to help people develop native iPhone applications using the Processing language. It is an integration of the Processing.js library and a Javascript application framework for iPhone. The iProcessing downloadconsists of a set of example XCode projects that demonstrate many of the Basic Examples from the Processing web site (originally written by Casey Reas and Ben Fry unless otherwise stated) as well a number that demonstrate the use of various iPhone features such as multitouch, accelerometer, orientation, location, sound play/record, app state saving and so on.

     

     

    ]]>
    585