|
GWTCanvas
Provides cross Browser Vector Graphics support in the spirit of the Javascript canvas element API.
This code is now deprecated. Canvas support is now included in the GWT mainline. IntroductionVector graphics have made their way to the GWT Incubator. The GWTCanvas Widget exposes an API for drawing and transforming shapes and images, as well as for defining paths to create custom shapes. GWTCanvas currently supports:
See the live demo: http://google-web-toolkit-incubator.googlecode.com/svn/trunk/demo/GWTCanvasDemo/GWTCanvasDemo.html Setup InstructionsJust add the following line to your module.gwt.xml file: <inherits name='com.google.gwt.widgetideas.GWTCanvas'/> You can specify your own stylesheet to further customize the look and feel of GWTCanvas. Using ImagesIn order for GWTCanvas to draw images, they must first be loaded by the browser. We provide an ImageLoader class in the same package as GWTCanvas to take care of this for you. Please refer to the Sample Code below for examples on how to use ImageLoader. Sample CodePlease refer to the source code of the live demo (which can be found in the incubator trunk) for more detailed examples. Drawing a rectangle using paths.
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.widgetideas.graphics.client.Color;
import com.google.gwt.widgetideas.graphics.client.GWTCanvas;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class MyEntryPoint implements EntryPoint {
public void onModuleLoad() {
// Make a new canvas 400x400 pixels
GWTCanvas canvas = new GWTCanvas(400,400);
canvas.setLineWidth(1);
canvas.setStrokeStyle(Color.GREEN);
canvas.beginPath();
canvas.moveTo(1,1);
canvas.lineTo(1,50);
canvas.lineTo(50,50);
canvas.lineTo(50, 1);
canvas.closePath();
canvas.stroke();
RootPanel.get().add(canvas);
}
}
Drawing an image (Scaling THEN translating before drawing). Please note that you must put all drawing code involving the image in the supplied callback. Drawing order for images and paths is guaranteed only within the callback method when working with images (since they have to be loaded first, and it can not be known ahead of time how long that will take). import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.widgetideas.graphics.client.GWTCanvas;
import com.google.gwt.widgetideas.graphics.client.ImageHandle;
import com.google.gwt.widgetideas.graphics.client.ImageLoader;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class MyEntryPoint implements EntryPoint {
public void onModuleLoad() {
// Make a new canvas 400x400 pixels
final GWTCanvas canvas = new GWTCanvas(400,400);
String[] urls = new String[] {"gwt_logo.jpg"};
ImageLoader.loadImages(urls, new ImageLoader.CallBack() {
public void onImagesLoaded(ImageHandle[] imageHandles) {
ImageHandle img = imageHandles[0];
canvas.translate(40, 40);
canvas.scale(0.5f, 0.5f);
canvas.drawImage(img, 0, 0);
}
});
RootPanel.get().add(canvas);
}
}
Drawing two rectangles, with different colors, in different locations.
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.widgetideas.graphics.client.Color;
import com.google.gwt.widgetideas.graphics.client.GWTCanvas;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class MyEntryPoint implements EntryPoint {
public void onModuleLoad() {
// Make a new canvas 400x400 pixels
GWTCanvas canvas = new GWTCanvas(400,400);
canvas.setLineWidth(1);
canvas.setStrokeStyle(Color.GREEN);
canvas.saveContext();
canvas.setLineWidth(1);
canvas.setStrokeStyle(Color.RED);
canvas.translate(100, 100);
canvas.strokeRect(0, 0, 100, 100);
canvas.restoreContext();
canvas.strokeRect(1, 1, 80, 80);
RootPanel.get().add(canvas);
}
}
Important Caveats
|
Would it be possible to add setGlobalCompositeOperation like
I think this is not possible or easy for IE, but for other browsers it would be great. I use a different implementation for IE anyway. My problem is just, I have no way to set this for Firefox other than to patch GWTCanvas. If the implementation for IE just does nothing, that would be enough.
For me the IE implementation doesn't look right (at least for this demo - haven't seen the source), blurry squares, strokes too thin, etc...
I've done something similar, take a look at http://code.google.com/p/gwt-canvas/
It is not complete, however it looks almost pixel-perfect on IE for me. So please feel free to merge it into GWTCanvas (or the other way around) if it helps ;)
I've downloaded the latest version of the incubator to try the GWTCanvas out, but:
doesn't seem to appear anymore? Where is the canvas class located now?
Thanks
I' like to ask the same question as markww. It doesn't look to be anywhere. And It looks an amazing job!
thanks, Dirso
dirsow, it's not in the compiled jar they have up on the site. I had to build the whole incubator myself, it's in the trunk of the repository!
So this is dependent on the canvas element support being present correct? This will not work in hosted mode on the linux platform because GWT currently uses the antiquated mozilla 1.7 for its rendering (correct me if i'm wrong).
@dolcraith
You are correct. We are working on addressing that though :). For now, if you have access to a Mac, you should be able to develop in hosted mode just fine. Otherwise (and I realize that this is non-optimal) you will have to debug in web mode.
I want draw line on a piece of image, how did i do?
Is it possible for a GWTCanvas to receive any events, such as mouse or click events?
@eroberts00
I extended the GWTCanvas class to implement mouse listening events:
public final class Canvas extends GWTCanvas { private MouseListener listener; public Canvas() { super(620, 620); sinkEvents(Event.MOUSEEVENTS); } @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); if (listener != null) { int x = event.getClientX() - getAbsoluteLeft(); int y = event.getClientY() - getAbsoluteTop(); switch (event.getTypeInt()) { case Event.ONMOUSEDOWN: listener.onMouseDown(this, x, y); break; case Event.ONMOUSEMOVE: listener.onMouseMove(this, x, y); break; case Event.ONMOUSEUP: listener.onMouseUp(this, x, y); break; } } } public void setListener(MouseListener listener) { this.listener = listener; } }@nvaneijck
Thanks, that worked great.
How do you render/draw Text using GWTCanvas?
I have added click events and multiple listeners to nvaneijck's contribution:
import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.ClickListener; import com.google.gwt.user.client.ui.ClickListenerCollection; import com.google.gwt.user.client.ui.MouseListener; import com.google.gwt.user.client.ui.MouseListenerCollection; import com.google.gwt.widgetideas.graphics.client.GWTCanvas; public class Canvas extends GWTCanvas { private MouseListenerCollection mouseListeners; private ClickListenerCollection clickListeners; public Canvas() { super(); } public Canvas(int coordX, int coordY) { super(coordX, coordY); } public Canvas(int coordX, int coordY, int pixelX, int pixelY) { super(coordX, coordY, pixelX, pixelY); } @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); if ((clickListeners != null && clickListeners.size() > 0) || (mouseListeners != null && mouseListeners.size() > 0)) { int x = event.getClientX() - getAbsoluteLeft(); int y = event.getClientY() - getAbsoluteTop(); switch (event.getTypeInt()) { case Event.ONCLICK: if (clickListeners != null) { clickListeners.fireClick(this); } break; case Event.ONMOUSEDOWN: if (mouseListeners != null) { mouseListeners.fireMouseDown(this, x, y); } break; case Event.ONMOUSEMOVE: if (mouseListeners != null) { mouseListeners.fireMouseMove(this, x, y); } break; case Event.ONMOUSEUP: if (mouseListeners != null) { mouseListeners.fireMouseUp(this, x, y); } break; } } } public void addClickListener(ClickListener listener) { if (clickListeners == null) { clickListeners = new ClickListenerCollection(); sinkEvents(Event.ONCLICK); } clickListeners.add(listener); } public void addMouseListener(MouseListener listener) { if (mouseListeners == null) { mouseListeners = new MouseListenerCollection(); sinkEvents(Event.MOUSEEVENTS); } mouseListeners.add(listener); } public void removeClickListener(ClickListener listener) { if (clickListeners != null) { clickListeners.remove(listener); } } public void removeMouseListener(MouseListener listener) { if (mouseListeners != null) { mouseListeners.remove(listener); } } }Rendering on canvas is fast on firefox/chrome, but on IE it is extremely slow. I found that GWTCanvas's vml implementation on IE is the cause: passing the string to browser every time you want to render something. I suggest GWTCanvas can have some "compile list" function as OpenGL, so that we can manipulate the attribute of some compile element rather than pass string to browser every time. I think some dojo code may inspire GWTCanvas developer:
var node = document.createElement("div"); document.body.appendChild(node); var surfaceWidth = 120; var surfaceHeight = 220; var surface = dojo.gfx.createSurface(node,surfaceWidth, surfaceHeight); var rect = { x: 100, y: 0, width: 100, height: 100 }; var circle = { cx: 150, cy: 160, r: 50 }; var group = surface.createGroup(); var blueRect = group.createRect(rect) .setFill([0, 0, 255, 0.5]) .applyTransform(dojo.gfx.matrix.identity); var greenCircle = group.createCircle(circle) .setFill([0, 255, 0, 1.0]) .setStroke({color: "black", width: 4, cap: "butt", join: 4}) .applyTransform(dojo.gfx.matrix.identity);this piece of code is copy from: http://www.thinkvitamin.com/features/design/create-cross-browser-vector-graphics
Is this likely to go into 1.5, or will we have to wait for 1.6?
I would like to congratulate nvaneijck, for the mouse listner implementation, and srfarley for improving it. It helped me a lot in a college project. Thanks!
Hi - I have the same question/need as stated above: can I somehow render text on the gwtcanvas? Thanks a lot! Axel
In GWT 1.6, the classes srfarley uses are deprecated. The new event system is a lot cleaner. Here's an example for mouse down events:
import com.google.gwt.event.dom.client.HasMouseDownHandlers; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.widgetideas.graphics.client.GWTCanvas; public class Canvas extends GWTCanvas implements HasMouseDownHandlers { public Canvas() { super(); } public Canvas(int coordX, int coordY) { super(coordX, coordY); } public Canvas(int coordX, int coordY, int pixelX, int pixelY) { super(coordX, coordY, pixelX, pixelY); } public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) { return addDomHandler(handler, MouseDownEvent.getType()); } }Then you can add an extended handler class and it'll get fired by GWT for you. In the callback functions, use getAbsoluteLeft() and getAbsoluteTop() as in nvaneijck's original to convert from screen coordinates to canvas coordinates.
Hi all,
Check out my application using gwt canvas : its http://gwt-mind-mapping.appspot.com/
Its only a alpha prototype version.
Thx
Hi, How can I make a canvas transparent to a lower level canvas? I mean two or more canvases one upon another. Thx
If anybody is interested in drawing text in GWTCanvas take a look at the Google code project swtbcanvasfont
Hi,
Does anyone know if the library has been distributed to a maven repo?
Many thx
I have recently created a project gwt-g2d (http://code.google.com/p/gwt-g2d/) that branches off from gwt-canvas and provide some newer features for canvas, such as text drawing, shadow, and pixel manipulation. The IE implementation uses excanvas and is working reasonably well (text drawing and linear gradient are working). It works best on Firefox 3.5 and Safari, but also pretty decently on Chrome and to some extent Opera. You can see the demo here (http://gwt-g2d.appspot.com/)
Hi everyone,
I have a problem with key events over GWTCanvas on Web mode. I add KeyPress? and KeyDown? events to canvas and they work fine in Hosted Mode, but when I compile to WebMode? KeyEvents? just don't work.
The MouseEvents? works fine in both Hosted and WebMode?... Can anyone help me?
I've done a simple app to demonstrate that... You can download it from http://dl.getdropbox.com/u/1353013/GWT_Canvas_Demo.rar
You just have to right setup the gxt and gwt-incubator on the app built-path. I hope someone can help me.
Thanks, Cheers.
Hi ,
Is it possible to render the drawings on a gwtcanvas to a png image format or a pdf format?
Thx
Is it possible to draw text? I like to draw a rectangle - and on top of the rectagle draw a text such as 'OK' or 'Cancel'.
As suggested above, I am using code like
y = event.getClientY() - getAbsoluteTop();
to get the canvas-relative coordinates. This works fine unless the browser window is scrolled. I'd appreciate any help on how to handle this.
Has anybody successfully tried gwtcanvas with the newly released gwt 2.0?
Yes, it works with GWT 2.0
I would like to add text also to the canvas, so that I can have a chart with axis-values. Or maybe, have a text converted to an image and add that to the canvas. Another addition would be to have a canvas with widgets, so I have a chart containing textboxes for input...
Great stuff, working on a WWII style boardgame based on this widget, its at: http://www.logicwell.com:8080/bigboard/BigBoard.html - excuse the utter lack of completeness right now, its an older build and I'm busy on another project atm ;) .. login as guest/guest and to scroll the map hold down RMB and drag in a direction.
Quick and dirty way to add text to a panel.
- Define an AbsolutePanel? panel.
- Add GWTCanvas to the AbsolutePanel?.
- Add html like:
panel.add(html, scrnX, scrnY);Demo: http://lower-bound.appspot.com/ (other links included)
If anyone is struggling with getting coordinates on the canvas. Try this:
I put the below in my subclassed GWTCanvas' constructor.
addDomHandler(new ClickHandler?() {
This appears to still work even when the window is scrolled.
Hi,
I have a problem with compiling the GWTCanvasDemo in a such way that it works on IE7. I have downloaded the "gwt-incubator drop for gwt 2.0.1 (revision 1747)" and GWT 2.0.1. Then I have checked out the source code of GWTCanvasDemo and just compiled it into an webapp. The result however doesn't work in IE 7.
http://google-web-toolkit-incubator.googlecode.com/svn/trunk/demo/GWTCanvasDemo/GWTCanvasDemo.html <- this compilation does work inIE7, however my compilation doesn't: http://shahbazian.nl/GWTCanvasDemo/
Also, http://collectionofdemos.appspot.com/demo/index.html gives a blank page in IE7. Anyone any idea how to fix this?
Thanks!
added a few mouse events to matt d.hillard example
public class Canvas extends GWTCanvas { public Canvas() { super(); } public Canvas(int coordX, int coordY) { super(coordX, coordY); } public Canvas(int coordX, int coordY, int pixelX, int pixelY) { super(coordX, coordY, pixelX, pixelY); } public HandlerRegistration addMouseHandler(MouseDownHandler handler) { return addDomHandler(handler, MouseDownEvent.getType()); } public HandlerRegistration addMouseHandler(MouseUpHandler handler) { return addDomHandler(handler, MouseUpEvent.getType()); } public HandlerRegistration addMouseHandler(MouseWheelHandler handler) { return addDomHandler(handler, MouseWheelEvent.getType()); } public HandlerRegistration addMouseHandler(MouseMoveHandler handler) { return addDomHandler(handler, MouseMoveEvent.getType()); } }I'm using GWTCanvas to draw images. In my case the images are created by setting the src attribute with a data URI in which I have a base64 encoded PNG. Everything works great in FF and Chrome but in IE8 when I try to draw the image in the canvas it only draws something that looks like a placeholder for a missing object. I know IE6 and 7 does not support data URI but at least I would like to make this work in IE8. The reason is that I have many small images (hundreds) to load and I want to avoid so many requests. I also tried to create a small test case using pure javascript and excanvas library that simulates canvas object in IE8. The result was similar with GWTCanvas. My question is, does anybody knows if this an IE issue or it's something that can be fixed in GWTCanvas? Thank, Daniel
I can't get the latest gwt-incubator drop jar working for IE. Works fine in Chrome and Firefox. I am running GWT 2.0.3 and also tried GWT 2.0.1 with no luck.
I'm using GWTCanvas, and i found out that clear function should include parameters. Because in case you use the translate function to move the origin of coordinates, and you draw anything in the non positive area of any x or y. The clear function just clears the positive quadrant, the remaining quadrants did not clear. Can somebody check this is correct??
Is this project being worked on? I have found out about gwt-graphics (@code.google.com)? How does it compare with GWTCanvas?
I'm having trouble in chrome no canvas graphics appear, Firefox works fine. Has anyone else see this?
How is it best to combine ImageResource? with ImageLoader? Just send it the URL, or maybe is there something to be done to make it faster/better? Maybe GWTCanvas can support images loaded using ClientBundles? as well?
I am having trouble getting KeyDownEvent?'s working. I have the mouse events working fine. I noticed in the source that GWTCanvas extends from widget. Would it be better extending from FocusWidget? to get key events?
I have a scenario like that: I'm trying to load an image from a url (say from X), if it fails i'm trying to load the image from another url (say Y). I couldn't use ImageLoader because i couldn't find its onError method. I also tried to load the image with Image class and attaching it to a handler. The debugger never entered onError and onLoad methods.
Also why and when the pixel manipulation is added to GWT Canvas? Or which canvas project is most recent? Should I try a different one?
I need to be able to set individual pixel colors. I trying to make fractals. I don't see this functionality here. Though it is easy enough with straight javascript: http://beej.us/blog/2010/02/html5s-canvas-part-ii-pixel-manipulation/
Sorry for the noob question -- but where can I find the demo source code? Thanks!
You can see the source online at: http://code.google.com/p/google-web-toolkit-incubator/source/browse/trunk/src/com/google/gwt/demos/gwtcanvas/client/SuiteDemo.java
(if you go down a level to client you can also see each individual demo that is displayed on the demo page at: http://google-web-toolkit-incubator.googlecode.com/svn/trunk/demo/GWTCanvasDemo/GWTCanvasDemo.html)
Or check out the code and actually see it all in eclipse. svn/trunk/src/com/google/gwt/demos/gwtcanvas/client/SuiteDemo?.java
cheers, daniel
It is working great on mac too. I tested it on mac os x 10.6 in safari as well as google chrome. It is working fine.
About the keyboard event not working for GWTCanvas, somebody points out that, GWTCanvas extends from Widget instead of "FocusWidget?". If there is not focus on the Canvas component, how does the browser know where to dispatch the key event?
Anybody has a work around for this issue by modifying their library code?
How about drawString....
I had built my app and left the label things behind.... Now my app is done and I come back to complete the labels... just to realize that GWTCanvas does not support drawString...
Is there any suggestion? Should I render my string into an image then draw it??? Please help me... T_T
I fixed it :-) So happy now _
I want to make a vector editor (a simplified SVG editor with some additional internal logic to constrain what can be drawn). Ideally I want to code this in java, and use gwt to convert it to html 5 to run natively in the browser.
I've just found gwtcanvas, which looks way cool. Does it support the ability to interact with a mouse with objects in the canvas? (And could I theoretically interact with a touch device, such as an ipad?).
Hi, I would like to know that can we create automata's using GWT CANVAS. Like Refer http://think.ajsands.com/.
Can we create something like this using GWT and GWTCanvas