Using the Google Web Toolkit (GWT) to create an HTML5 Canvas that uses (almost) all available space

Post to Twitter

A few weeks ago I had written an article in regards to getting the HTML5 Canvas to take up the entire browser available area and to take into consideration scrollbars as well as mobile devices. The code works pretty decent but any feedback is appreciated in the comments section. Keep in mind I have a Droid X so that is the only mobile device I’ve tested my code on thus far – see here for a live demo.

I wanted to take the code I had written and modify it to work with the Google Web Toolkit or GWT as most people call it. Today I’ll show you the code I came up with. I can’t say this is the way to do it because this code was the result of some trial and error so improvements most likely are needed but its at least a stepping stone.


Article Updated March 7, 2011 – Thanks to John Munsch.

Here are the steps I did to make this example.

Create a new Google Web Application Project (using the Google plug-in for Eclipse). I called my project: GWTCanvasResize

Remove the Servlets XML from the web.xml file as we won’t need any of that.

Here is what my web.xml looks like after removing the XML:





  
  


Remove/delete the following files from the project:

  • GreetingService.java
  • GreetingServiceAsync.java
  • GreetingServiceImpl.java
  • FieldVerifier.java

In the GWTCanvasResize.html file remove all the code between the closing noscript and closing body tag so your file looks like this:









  
    

    
    
    
    

    
    
    
    Web Application Starter Project
    
    
    
    
    
    
    
  

  
  
  
  
  
  

    
    
    
    
    
  

Add the following to the GWTCanvasResize.css file:

.mainCanvas {
   background-color: #000;
   border: solid 3px #0F0;
}
 
.body {
   background: #000;
   overflow-y: hidden;
   overflow-x: hidden;
}
 
.contentHolder {
   width: 100%;
   height: 100%;
   margin: auto;
}

The last thing is to modify the GWTCanvasResize.java file:

package com.giantflyingsaucer.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Label;


public class GWTCanvasResize implements EntryPoint
{
	Canvas canvas;
    Context2d context;
    HTMLPanel panel;
    static final String id = "contentholder";
    
	public void onModuleLoad()
	{
		// Cheesy way to add a DIV but it works for this demo
		panel = new HTMLPanel("
"); panel.setStyleName("contentHolder"); Window.addResizeHandler(new ResizeHandler() { @Override public void onResize(ResizeEvent event) { resizeCanvas(event.getWidth(), event.getHeight()); } }); // Call the resize event for the first time resizeCanvas(Window.getClientWidth(), Window.getClientHeight()); RootPanel.get().setStyleName("body"); RootPanel.get().add(panel); } private void resizeCanvas(int width, int height) { // Adjust the width and height by 6 to fit into the viewable area (tested in FireFox and Chrome only) width = width - 6; height = height - 6; // Remove the old Canvas panel.clear(); canvas = null; canvas = Canvas.createIfSupported(); if (canvas == null) { RootPanel.get().add(new Label("Sorry, your browser doesn't support the HTML5 Canvas element")); return; } context = canvas.getContext2d(); canvas.setStyleName("mainCanvas"); // Add the new Canvas back inside the DIV panel.add(canvas, id); canvas.setWidth(width + "px"); canvas.setCoordinateSpaceWidth(width); canvas.setHeight(height + "px"); canvas.setCoordinateSpaceHeight(height); // Don't need to erase first since this is always on a new canvas context.setFont("20pt serif"); context.setFillStyle("#0f0"); context.fillText("Width: " + width + " Height: " + height, 25, 100); } }

Not a lot of magic in there. The trick I’ve found that works best for me is when the browser is resized (which I catch with the Window.addResizeHandler) I simply remove the current Canvas and replace it with a new one. This way I’ve been able to avoid some of the redrawing/scaling issues I found with redrawing on the existing but resized Canvas. It ended up just being easier to add the new properly resized Canvas and redraw on that. As you resize your browser the code writes out the dimensions on the Canvas.

I’ve only tested this out on Chrome and Firefox so far.

Here are the results in Chrome and Firefox:

Note: Keep in mind that as of GWT 2.2 the Canvas support is experimental, this code might change in the future as the API changes.

Post to Twitter

This entry was posted in GWT, HTML5. Bookmark the permalink.

4 Responses to Using the Google Web Toolkit (GWT) to create an HTML5 Canvas that uses (almost) all available space

  1. John Munsch says:

    You mention that you avoid making the canvas too large to avoid the scrollbars showing up. I think you could just use the overflow-x and overflow-y CSS properties to make both scrollbars hidden and just crank the size up to the full browser viewable area.

    With those set to hidden the browser is just supposed to clip its contents.

  2. Chad Lung says:

    @John,

    Thanks for the tip. I’ve put the overflow x and y in some test code but the right hand side and then the bottom borders were extending beyond the browser’s viewable area. So I set the container to take up 100% of the space and then took off 6 pixels from the height and width of the canvas, its really close to using all the available space now.

    I’m updating the article with these enhancements.

    Thanks,

    Chad

  3. Jayachandran says:

    hi,
    I am new to GWT i need to draw a image in canvas. I draw image in canvas code is,
    public class TestCanvas implements EntryPoint{

    Canvas canvasScreen;
    Context2d contextScreen;
    static final int canvasHeight = 500;
    static final int canvasWidth = 500;

    public void onModuleLoad() {
    canvasScreen = Canvas.createIfSupported();

    if(canvasScreen == null) {
    RootPanel.get().add(new Label(“Sorry, your browser doesn’t support the HTML5 Canvas element”));
    }
    canvasScreen.setHeight(canvasHeight+”px”);
    canvasScreen.setWidth(canvasWidth+”px”);
    canvasScreen.setCoordinateSpaceHeight(canvasHeight);
    canvasScreen.setCoordinateSpaceWidth(canvasWidth);
    RootPanel.get().add(canvasScreen);
    contextScreen = canvasScreen.getContext2d();
    loadImage();
    }

    private void loadImage() {
    Image img = new Image(/home/jayachandran/Desktop/vss.jpg);

    ImageElement imageElement = ImageElement.as(img.getElement());
    contextScreen.drawImage(imageElement, 110,110, imageElement.getWidth(), imageElement.getHeight());
    }

    }

    if i execute this, only canvas is shown but not image drawn in side the canvas.
    But after refreshing the browser second time the image show on browser in mozilla firefox.

    i need to show on browser on first time itself.

  4. Pingback: Developer Sharing June Edition « GWT Buzz

Comments are closed.