CreateJS_resizetutorial

CreateJS and HTML5 Canvas: resize, fullscreen and liquid layouts

How to handle the resizing of an application built with CreateJS and HTML5 Canvas.
This tecnique can be used to create cross-platform applications that works fine on every resolution and HTML5 browser, desktop or  mobile.




In this demo we’ll handle three different situations:
1) A logo always positioned on top-right of the screen
2) A fullscreen background
3) A centered content

View demo

HOW TO HANDLE THE RESIZE EVENT

First, as with any other EaselJS project, we create an HTML canvas element and then we call the init() function when the page has been completely loaded using the onload event.
The width and height canvas properties are not very important now because they will be updated in the resize() function to be fullscreen. So you can write what you want.


< body onLoad="init();">
	<canvas id="demoCanvas" width="300" height="100"  >
		alternate content
	</canvas>
</body>

Download the tutorial “EaselJS: Getting Started” to get more info about it.

Now lets add the init(), the tick() and the resize() functions.


< script>
	var stage;
	
	window.addEventListener('resize', resize, false);
	
	function init() {
		stage = new createjs.Stage("demoCanvas");
		createjs.Ticker.addListener(this);
		resize();
		
	}

	function tick() {
		stage.update();
	}	


	function resize() {	
		stage.canvas.width = window.innerWidth;
		stage.canvas.height = window.innerHeight;	    
	}

</script>

The ‘resize’ event is called every time the browser is resized or a mobile device is rotated.
So the same function can be used to handle resize and orientation events.

The init() method creates a new Stage property and adds the Ticker listener.

Finally we call the resize() function to update the canvas width/height properties.
The resize() event is not fired until the browser is resized and for this reason we need to manually call it.

ADD ELEMENTS TO THE STAGE
Lets call three new methods in the init() function:

function init() {

	stage = new createjs.Stage(&quot;demoCanvas&quot;);

	createBackground();
	createLogo();
	createContent();

	createjs.Ticker.addListener(this);

	resize();
}

THE FULLSCREEN BACKGROUND (fullscreen)
In the createBackground() we create a new Shape that will draw a fullscreen background using the Graphics class.
But we don’t draw anything inside it until the resize() function is called.

function createBackground() {

	bg = new createjs.Shape();
	stage.addChild(bg);

}

THE LOGO (top-right)

In the createLogo() we simply display an Image using the Bitmap class, setting its Y position (that will never change)
The X position will be updated in the resize() function

function createLogo() {

	logo = new createjs.Bitmap("logo.png");
	logo.y = 10;
	stage.addChild(logo);

}

The resize() function is so updated to handle these new elements:

function resize() {
			
	// Resize the canvas element
	stage.canvas.width = window.innerWidth;
	stage.canvas.height = window.innerHeight;	    	

	// Logo: top-right position (canvasWidth - image width - 10 px padding)
	logo.x = stage.canvas.width - logo.image.width - 120 - 10;

	// Background: full screen redraw 
	bg.graphics.clear()
	bg.graphics.beginFill("#222").drawRect(0,0,stage.canvas.width,stage.canvas.height);

}

1) we draw the fullscreen background using the Graphics Class and the stage.canvas width and height properties to always fit the current screen resolution.

2) we set the X position of the logo: since we didn’t preload the image we can’t be sure the logo has been completely loaded when we call the resize() function so we must manually subtract 120 px (the size of the image) + 10 px of padding to be sure it will be positioned on the right side of the screen.
Although this way can be used and it works fine it’s not so elegant and often it’s very hard to mantain if your assets changes for some reasons. The best way to avoid this issue is using PreloadJS, so your assets will be preloaded and you can easily get their width/height properties. Another way to get the image width is shown in the createContent() function, described below.


THE CONTENT (centered)

The createContent() is a bit more complex.
This method creates a new Container that contains an Image (monalisa) and it will be horizontally and vertically aligned to center.
The easiest way to accomplish this task is setting the regX and regY properties of the Container in order to align it to center simply using these two lines of code in the resize() method.

function resize() {
	...
	content.x = stage.canvas.width / 2;
	content.y = stage.canvas.height / 2;
}

The main problem to use this technique is that (at least in this scenario) the size of the content is unknown until the image is loaded.
So the regX and regY properties can be setted only after the image is loaded.


function createContent() {

	content = new createjs.Container();
	stage.addChild(content);
	
	// Load the Monalisa Image
	// (You may also use PreloadJS to avoid the onload listener)
	monalisa = new Image();
	monalisa.src = "mona.jpg";
	monalisa.onload = handleImageLoad;
}

function handleImageLoad() {

	// Create a CreateJS bitmap from the loaded image
	var bmpMonaLisa = new createjs.Bitmap(monalisa);

	// Add the bitmap to the Container
	content.addChild(bmpMonaLisa);

	// Set the registration point of the Container
	content.regX = bmpMonaLisa.image.width/2
	content.regY = bmpMonaLisa.image.height/2

	// Set the scale of the content.
	// It's not necessary but it might be useful to properly handle different mobile resolutions resizing the content.
	content.scaleX = 0.5;
	content.scaleY = 0.5;

}

Here, the final resize() function:


function resize() {

	// Resize the canvas element
	stage.canvas.width = window.innerWidth;
	stage.canvas.height = window.innerHeight;

	// Logo: top-right position (canvasWidth - image width - 10 px padding)
	logo.x = stage.canvas.width - logo.image.width - 120 - 10;

	// Background: full screen redraw
	bg.graphics.clear();
	bg.graphics.beginFill(&quot;#222&quot;).drawRect(0,0,stage.canvas.width,stage.canvas.height);

	// Content: centered
	content.x = stage.canvas.width / 2;
	content.y = stage.canvas.height / 2;
}

SOME DEMOS THAT USE THIS CONCEPT:

Watch the last three videos of this article to see it in actions

HTML TIPS:
In the source code of the demo you may have noticed other two interesting stuff:


< html>
<head>
<meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">

<title>EaselJS demo: Resize</title>	

< style type="text/css">

	/* Remove margins and HTML scrollbars */
	BODY, HTML  {
		margin: 0;
		padding: 0;
		overflow: hidden;
	}
</style>


1) We have used a viewport metatag to prevent users from scaling the html page using pinchIn/out gestures, especially useful on mobile devices. It’s related to the type of your project and maybe you won’t need to it.
For example, it could not be necessary if your canvas is used in an existing HTML website optimized for mobile devices and must be scaled following its rules.

2) Using CSS we removed margins, paddings and we set the overflow property to hidden to prevent the display of scrollbars.

Here, the complete source code:


<!DOCTYPE html>
< html>
<head>
	<!-- Using this metatag users can't scale the page using pinchIn/out gestures on mobile devices -->
	<meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">

	<title>EaselJS demo: Resize</title>	

	< style type="text/css">

		/* Remove margins and HTML scrollbars */
		BODY, HTML  {
			margin: 0;
			padding: 0;
			overflow: hidden;
		}
	</style>

	<script src="../../lib/easeljs-NEXT.min.js"></script>

	< script>

		var stage;
		var bg, logo;		
		var content, monalisa;

		// Resize event listener
		window.addEventListener('resize', resize, false);

		/**
		 * Init handler
		 */
		function init() {

			stage = new createjs.Stage("demoCanvas");
			
			createBackground();
			createLogo();
			createContent();
			
			createjs.Ticker.addListener(this);

			resize();
		}
		
		/**
		 * create and display the background (fullscreen)
		 */
		function createBackground() {
			
			bg = new createjs.Shape();		
			stage.addChild(bg);

		}

		/**
		 * create and display logo (top-right)
		 */
		function createLogo() {

			logo = new createjs.Bitmap("logo.png");
			logo.y = 10;
			stage.addChild(logo);

		}
		
		 
		/**
		 * create content (centered)
		 */
		function createContent() {


			content = new createjs.Container();
			stage.addChild(content);

			// Load the Monalisa Image
			// (You should also use PreloadJS to avoid the onload listener)
			monalisa = new Image();
			monalisa.src = "mona.jpg";
			monalisa.onload = handleImageLoad;
			

		}
		
		function handleImageLoad() {

			// Create a CreateJS bitmap from the loaded image
			var bmpMonaLisa = new createjs.Bitmap(monalisa);

			// Add the bitmap to the Container
			content.addChild(bmpMonaLisa);
			
			// Set the registration point of the content Container to center
			content.regX = bmpMonaLisa.image.width/2
			content.regY = bmpMonaLisa.image.height/2

			// Set the scale value
			// It could be useful to properly handle different mobile resolutions
			content.scaleX = 0.5;
			content.scaleY = 0.5;

			
		}


		/**
		 * Tick Handler
		 */
		function tick() {
			
			stage.update();
		}	


		/**
		 * Resize event handler
		 */
		function resize() {

			// Resize the canvas element
		  	stage.canvas.width = window.innerWidth;
	    	stage.canvas.height = window.innerHeight;	    	

	    	// Logo: top-right position (canvasWidth - image width - 10 px padding)
	    	logo.x = stage.canvas.width - 120 - 10

	    	// Background: full screen redraw 
	    	bg.graphics.clear()
	    	bg.graphics.beginFill("#222").drawRect(0,0,stage.canvas.width,stage.canvas.height);
	    	
	        // Content: centered
	        content.x = stage.canvas.width / 2;
	        content.y = stage.canvas.height / 2;
	    }


	</script>
</head>
<body onLoad="init();">
	<canvas id="demoCanvas" width="300" height="100"  >
		alternate content
	</canvas>
</body>
</html>

Download the source code (you need to manually download the “NEXT” version of CreateJS library)

Comments (5)

  1. nikolas (reply)

    January 27, 2013 at 9:49 am

    are you crazy?! you can do everything in here WITHOUT using javascript! Please don’t put readers into the wrong direction

  2. Fabio Biondi (reply)

    February 21, 2013 at 4:38 pm

    Hi Nikolas,
    sure, you can do it using CSS.

    But i’m talking about CreateJS. It’s another story and use a different approach:)

  3. Artur (reply)

    March 25, 2013 at 2:38 pm

    Hi Fabio,

    I was interested by your window configurator (have found it on youtube). Could you please send to me a link to try it?

    Thanks
    Artur

    1. Fabio Biondi (reply)

      March 25, 2013 at 3:06 pm

      Hi Artur,
      please send me a pvt email and I’ll send you all the links : )
      Fabio

  4. Momen Nemrat (reply)

    April 10, 2014 at 3:06 am

    thank you , I’am a flash developer and this helped me a lot :)

Leave a Reply

Your email address will not be published. Required fields are marked *

Published on: 20 August 2012
Posted by:
Discussion: 5 Comments