How To Use Canvas4Z Part2
Jimmy Shiau, Engineer, Potix Corporation
February 29, 2012
ZK 5, Canvas4Z 0.9.0
Introduction
Canvas4Z is an experimental component that leverages HTML 5 for free-style drawing. In the previous small talk How To Use Canvas4Z Simon showed us how to use Canvas4Z, this small talk will extend the previous small talk with some additional new features such as
- Adding an image as a background
- Drawing an arrow
- Selecting and moving objects
- Saving canvas objects with its background as an image
Demo
Make canvas paint board as a macro component
In the previous smalltalk, we handled drawing at the client side and when finish drawing, client side will send the shape data to the server side controller, where the controller will then add a new shape that you drew on the canvas component. In this demo we have packed the code that handles this drawing process into a macro component, so that you can use it in your application more easily.
Here are the steps to pack the macro component;
- Add Component Class and Client Widget
- Import javascript
- paintDiv.js adds a client widget for handling the canvas drawing at the client side and the sends the shape data back to the server.
- Declare Macro Component
- PaintDiv retrieves the shape date from client-side, then pack the shape info into a Drawable java object, then send the object to an event listener for manipulating the Drawable object.
- Use paintDiv Component in your zul file
Add PaintDiv.java to your class path, and add paintDiv.js to your WebContent folder.
Add the following javascript to your zul file.
<?script type="text/javascript" src="/zkpaint/scripts/paintDiv.js"?>
Declare paintDiv component in your zul file.
<?component name="paintDiv" class="org.zkoss.canvas.zkpaint2.PaintDiv"?>
The paintDiv component is now ready, and you can use it in your zul file. For example,
<?script type="text/javascript" src="/zkpaint/scripts/paintDiv.js"?>
<?component name="paintDiv" class="org.zkoss.canvas.zkpaint2.PaintDiv"?>
<?link rel="stylesheet" type="text/css" href="zkpaint/css/zkpaint.css"?>
<zk>
<window id="zkpaintWindow" apply="org.zkoss.canvas.zkpaint2.PaintController" ...>
......
<paintDiv id="paintDiv" width="800px" height="500px"/>
.......
Using paintDiv
The following section illustrates how you can use the paintDiv component to add a background image and edit your objects.
Add an image as a background
Add an Image object to paintDiv.
paintDiv.setContent((Image) media);
Then, listen the onImageReady
event to retrieve an ImageSnapshot
object when the image is loaded.
public void onImageReady$paintDiv(ForwardEvent event) {
Map data = (Map) event.getOrigin().getData();
paintDiv.addDrawable((ImageSnapshot) data.get("image"));
}
Set Shape Category to paintDiv
List<Shape> _shapes = new ArrayList<Shape>();
_shapes.add(new Rectangle(0, 0, 1000, 1000));
_shapes.add(new Path().moveTo(0, 0).lineTo(1000, 1000).closePath());
paintDiv.setShapeCategory(_shapes);
paintDiv.setShapeIndex(1);
paintDiv.startDrawShape();
After setting Shape Category to paintDiv, you can now use shapeIndex
to inform canvas what shape to draw. This makes it easier to plug in new shapes to the component.
Set Font Property
You can define the font type and size as you wish as illustrated in the following code snippet
paintDiv.setFont("30px serif");
paintDiv.startDrawText();
Set Arrow Property
You can define the arrow property by using setArrowAttributes
.
paintDiv.setArrowAttributes(5, 20, 25);//arrowWidth, tipWidth, tipLength
paintDiv.startDrawArrow();
onAddShape, onAddText and onAddArrow Event
You can listen to onAddShape
, onAddText
and onAddArrow
events, and retrieve a Drawable object from the event data, then add the object to paintDiv component.
public void onAddText$paintDiv(ForwardEvent event) {
Map data = (Map) event.getOrigin().getData();
paintDiv.addDrawable((Text) data.get("text"));
}
public void onAddShape$paintDiv(ForwardEvent event) {
Map data = (Map) event.getOrigin().getData();
paintDiv.addDrawable((Shape) data.get("shape"));
}
public void onAddArrow$paintDiv(ForwardEvent event) {
Map data = (Map) event.getOrigin().getData();
paintDiv.addDrawable((Shape) data.get("arrow"));
}
Select and Move
The actions of selecting and moving shapes are handled by PaintDiv.java, you do not have to handle it by yourself in your controller.
paintDiv.startSelect();
Saving edited images
Call paintDiv.exportPng() to save the canvas as an image. paintDiv.js will then export the canvas into a base64 string, and PaintDiv.java will receive the strings from the client-side. Then, we use Apache base64 to decode the strings into byte array format, then post an event with the byte data to the component.
Finally, you can retrieve the image that's in the form of a byte array in the event listener:
public void onExportPng$paintDiv(ForwardEvent event) {
Map data = (Map) event.getOrigin().getData();
byte[] byteData = (byte[]) data.get("byteData");
Filedownload.save(byteData , "png", "canvas.png");
}
Summary
In this HTML5 canvas demo, we have illustrated the capabilities of adding an image as a background, drawing an arrow, selecting and moving objects, and exporting edited images. It now works like a simple web painting tool! Also, we have moved all the drawing processes out of the controller and organized the server and client implementation as a macro component. With this change it is now much easier to use this canvas4z component and maintain your application.
Download
Comments
Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License. |