Author: kpreisser
Date: Thu Oct 10 22:20:03 2013
New Revision: 1531130
URL: http://svn.apache.org/r1531130
Log:
Allow to draw other forms like line, rectangle and circle/ellipse.
Modified:
tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawMessage.java
tomcat/trunk/webapps/examples/websocket/drawboard.xhtml
Modified:
tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawMessage.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawMessage.java?rev=1531130&r1=1531129&r2=1531130&view=diff
==============================================================================
---
tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawMessage.java
(original)
+++
tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/drawboard/DrawMessage.java
Thu Oct 10 22:20:03 2013
@@ -34,9 +34,14 @@ public final class DrawMessage {
private byte colorR, colorG, colorB, colorA;
private double thickness;
private int x1, y1, x2, y2;
+ private boolean lastInChain;
/**
- * The type. 1: Line.
+ * The type.<br>
+ * 1: Brush<br>
+ * 2: Line<br>
+ * 3: Rectangle<br>
+ * 4: Ellipse
*/
public int getType() {
return type;
@@ -102,10 +107,24 @@ public final class DrawMessage {
this.y2 = y2;
}
+ /**
+ * Specifies if this DrawMessage is the last one in a chain
+ * (e.g. a chain of brush paths).<br>
+ * Currently it is unused.
+ */
+ public boolean isLastInChain() {
+ return lastInChain;
+ }
+ public void setLastInChain(boolean lastInChain) {
+ this.lastInChain = lastInChain;
+ }
+
+
public DrawMessage(int type, byte colorR, byte colorG, byte colorB,
- byte colorA, double thickness, int x1, int x2, int y1, int y2) {
+ byte colorA, double thickness, int x1, int x2, int y1, int y2,
+ boolean lastInChain) {
this.type = type;
this.colorR = colorR;
@@ -117,6 +136,7 @@ public final class DrawMessage {
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
+ this.lastInChain = lastInChain;
}
@@ -125,15 +145,37 @@ public final class DrawMessage {
* @param g
*/
public void draw(Graphics2D g) {
- switch (type) {
- case 1:
+
+ g.setStroke(new BasicStroke((float) thickness,
+ BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER));
+ g.setColor(new Color(colorR & 0xFF, colorG & 0xFF, colorB & 0xFF,
+ colorA & 0xFF));
+
+ if (type == 1 || type == 2) {
// Draw a line.
- g.setStroke(new BasicStroke((float) thickness,
- BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER));
- g.setColor(new Color(colorR & 0xFF, colorG & 0xFF, colorB & 0xFF,
- colorA & 0xFF));
g.drawLine(x1, y1, x2, y2);
- break;
+
+ } else if (type == 3 || type == 4) {
+ int x1 = this.x1, x2 = this.x2,
+ y1 = this.y1, y2 = this.y2;
+ if (x1 > x2) {
+ x1 = this.x2;
+ x2 = this.x1;
+ }
+ if (y1 > y2) {
+ y1 = this.y2;
+ y2 = this.y1;
+ }
+
+ if (type == 3) {
+ // Draw a rectangle.
+ g.drawRect(x1, y1, x2 - x1, y2 - y1);
+
+ } else if (type == 4) {
+ // Draw an ellipse.
+ g.drawArc(x1, y1, x2 - x1, y2 - y1, 0, 360);
+
+ }
}
}
@@ -148,7 +190,8 @@ public final class DrawMessage {
return type + "," + (colorR & 0xFF) + "," + (colorG & 0xFF) + ","
+ (colorB & 0xFF) + "," + (colorA & 0xFF) + "," + thickness
- + "," + x1 + "," + y1 + "," + x2 + "," + y2;
+ + "," + x1 + "," + y1 + "," + x2 + "," + y2 + ","
+ + (lastInChain ? "1" : "0");
}
public static DrawMessage parseFromString(String str)
@@ -158,12 +201,13 @@ public final class DrawMessage {
byte[] colors = new byte[4];
double thickness;
int[] coords = new int[4];
+ boolean last;
try {
String[] elements = str.split(",");
type = Integer.parseInt(elements[0]);
- if (type != 1)
+ if (!(type >= 1 && type <= 4))
throw new ParseException("Invalid type: " + type);
for (int i = 0; i < colors.length; i++) {
@@ -181,6 +225,7 @@ public final class DrawMessage {
+ coords[i]);
}
+ last = !"0".equals(elements[10]);
} catch (RuntimeException ex) {
throw new ParseException(ex);
@@ -188,7 +233,7 @@ public final class DrawMessage {
DrawMessage m = new DrawMessage(type, colors[0], colors[1],
colors[2], colors[3], thickness, coords[0], coords[2],
- coords[1], coords[3]);
+ coords[1], coords[3], last);
return m;
}
@@ -206,4 +251,5 @@ public final class DrawMessage {
}
+
}
Modified: tomcat/trunk/webapps/examples/websocket/drawboard.xhtml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/websocket/drawboard.xhtml?rev=1531130&r1=1531129&r2=1531130&view=diff
==============================================================================
--- tomcat/trunk/webapps/examples/websocket/drawboard.xhtml (original)
+++ tomcat/trunk/webapps/examples/websocket/drawboard.xhtml Thu Oct 10 22:20:03
2013
@@ -64,7 +64,6 @@
#drawContainer, #console-container {
box-shadow: 0px 0px 8px 3px #bbb;
border: 1px solid #CCCCCC;
-
}
]]></style>
@@ -139,7 +138,7 @@
this.resumeProcessing = function() {
pauseProcessing = false;
- // Process all queued functions until some handler
calls
+ // Process all queued functions until some handler
calls
// pauseProcessing() again.
while (functionQueue.length > 0 && !pauseProcessing) {
var func = functionQueue.pop();
@@ -180,15 +179,26 @@
var mouseInWindow = false;
var mouseDown = false;
var currentMouseX = 0, currentMouseY = 0;
+ var currentPreviewPath = null;
var availableColors = [];
var currentColorIndex;
var colorContainers;
+ var previewTransparency = 0.65;
var availableThicknesses = [2, 3, 6, 10, 16, 28, 50];
var currentThicknessIndex;
var thicknessContainers;
+ var availableDrawTypes = [
+ { name: "Brush", id: 1, continuous: true },
+ { name: "Line", id: 2, continuous: false },
+ { name: "Rectangle", id: 3, continuous: false },
+ { name: "Ellipse", id: 4, continuous: false }
+ ];
+ var currentDrawTypeIndex;
+ var drawTypeContainers;
+
var labelContainer = document.getElementById("labelContainer");
var placeholder = document.createElement("div");
@@ -208,7 +218,7 @@
this.id = id;
}
- function Path(type, color, thickness, x1, y1, x2, y2) {
+ function Path(type, color, thickness, x1, y1, x2, y2,
lastInChain) {
this.type = type;
this.color = color;
this.thickness = thickness;
@@ -216,6 +226,26 @@
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
+ this.lastInChain = lastInChain;
+
+ function ellipse(ctx, x, y, w, h) {
+ /* Drawing a ellipse cannot be done directly in a
+ * CanvasRenderingContext2D - we need to use drawArc()
+ * in conjunction with scaling the context so that we
+ * get the needed proportion.
+ */
+ ctx.save();
+
+ // Translate and scale the context so that we can draw
+ // an arc at (0, 0) with a radius of 1.
+ ctx.translate(x + w / 2, y + h / 2);
+ ctx.scale(w / 2, h / 2);
+
+ ctx.beginPath();
+ ctx.arc(0, 0, 1, 0, Math.PI * 2, false);
+
+ ctx.restore();
+ }
this.draw = function(ctx) {
ctx.beginPath();
@@ -223,7 +253,7 @@
ctx.lineWidth = thickness;
var style = rgb(color);
ctx.strokeStyle = style;
-
+
if (x1 == x2 && y1 == y2) {
// Always draw as arc to meet the behavior
// in Java2D.
@@ -232,11 +262,26 @@
Math.PI * 2.0, false);
ctx.fill();
} else {
- if (type == 1) {
+ if (type == 1 || type == 2) {
// Draw a line.
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
+ } else if (type == 3) {
+ // Draw a rectangle.
+ if (x1 == x2 || y1 == y2) {
+ // Draw as line
+ ctx.moveTo(x1, y1);
+ ctx.lineTo(x2, y2);
+ ctx.stroke();
+ } else {
+ ctx.strokeRect(x1, y1, x2 - x1, y2 - y1);
+ }
+ } else if (type == 4) {
+ // Draw a ellipse.
+ ellipse(ctx, x1, y1, x2 - x1, y2 - y1);
+ ctx.closePath();
+ ctx.stroke();
}
}
};
@@ -327,7 +372,7 @@
var url =
URL.createObjectURL(blob);
- var img = new Image();
+ var img = new Image();
// We must wait until the onload
event is
// raised until we can draw the
image onto
@@ -401,7 +446,8 @@
parseInt(elements[7]),
parseInt(elements[8]),
parseInt(elements[9]),
- parseInt(elements[10]));
+ parseInt(elements[10]),
+ elements[11] != "0");
// Draw the path onto the last
canvas.
path.draw(canvasServerImageCtx);
@@ -414,7 +460,7 @@
// Now go through the pathsNotHandled
array and
// remove the paths that were already
handled by
// the server.
- while (pathsNotHandled.length > 0
+ while (pathsNotHandled.length > 0
&& pathsNotHandled[0].id <=
maxLastHandledId)
pathsNotHandled.shift();
@@ -425,7 +471,7 @@
}
refreshDisplayCanvas();
- }
+ }
}
}
}
@@ -446,22 +492,28 @@
function refreshDisplayCanvas() {
canvasDisplayCtx.drawImage(canvasBackground, 0, 0);
- if (mouseInWindow && !mouseDown) {
+ if (currentPreviewPath != null) {
+ // Draw the preview path.
+ currentPreviewPath.draw(canvasDisplayCtx);
+
+ } else if (mouseInWindow && !mouseDown) {
canvasDisplayCtx.beginPath();
var color =
availableColors[currentColorIndex].slice(0);
- color[3] = 0.5;
+ color[3] = previewTransparency;
canvasDisplayCtx.fillStyle = rgb(color);
-
- canvasDisplayCtx.arc(currentMouseX, currentMouseY,
availableThicknesses[currentThicknessIndex] / 2, 0, Math.PI * 2.0, true);
-
+
+ canvasDisplayCtx.arc(currentMouseX, currentMouseY,
+ availableThicknesses[currentThicknessIndex] /
2,
+ 0, Math.PI * 2.0, true);
canvasDisplayCtx.fill();
}
+
}
function startControls() {
labelContainer.removeChild(placeholder);
placeholder = undefined;
-
+
labelContainer.appendChild(
document.createTextNode("Number of Players: "));
labelContainer.appendChild(labelPlayerCount);
@@ -472,58 +524,89 @@
drawContainer.appendChild(optionContainer);
- canvasDisplay.onmousemove = function(e) {
- mouseInWindow = true;
- var oldMouseX = currentMouseX, oldMouseY =
currentMouseY;
- currentMouseX = e.pageX - canvasDisplay.offsetLeft;
- currentMouseY = e.pageY - canvasDisplay.offsetTop;
-
- if (mouseDown) {
- var path = new Path(1,
availableColors[currentColorIndex],
-
availableThicknesses[currentThicknessIndex],
- oldMouseX, oldMouseY, currentMouseX,
- currentMouseY);
- // Draw it on the background canvas.
- path.draw(canvasBackgroundCtx);
-
- // Send it to the sever.
- pushPath(path);
- }
-
- refreshDisplayCanvas();
- };
-
canvasDisplay.onmousedown = function(e) {
- currentMouseX = e.pageX - canvasDisplay.offsetLeft;
- currentMouseY = e.pageY - canvasDisplay.offsetTop;
-
if (e.button == 0) {
- mouseDown = true;
-
- var path = new Path(1,
availableColors[currentColorIndex],
-
availableThicknesses[currentThicknessIndex],
- currentMouseX, currentMouseY,
currentMouseX,
- currentMouseY);
- // Draw it on the background canvas.
- path.draw(canvasBackgroundCtx);
-
- // Send it to the sever.
- pushPath(path);
+ currentMouseX = e.pageX - canvasDisplay.offsetLeft;
+ currentMouseY = e.pageY - canvasDisplay.offsetTop;
- refreshDisplayCanvas();
+ mouseDown = true;
+ canvasMouseMove(e);
} else if (mouseDown) {
// Cancel drawing.
mouseDown = false;
+ currentPreviewPath = null;
refreshDisplayCanvas();
}
}
+ var canvasMouseMove = canvasDisplay.onmousemove =
function(e) {
+ mouseInWindow = true;
+ var mouseX = e.pageX - canvasDisplay.offsetLeft;
+ var mouseY = e.pageY - canvasDisplay.offsetTop;
+
+ if (mouseDown) {
+ var drawType =
availableDrawTypes[currentDrawTypeIndex];
+
+ if (drawType.continuous) {
+
+ var path = new Path(drawType.id,
+ availableColors[currentColorIndex],
+
availableThicknesses[currentThicknessIndex],
+ currentMouseX, currentMouseY, mouseX,
+ mouseY, false);
+ // Draw it on the background canvas.
+ path.draw(canvasBackgroundCtx);
+
+ // Send it to the sever.
+ pushPath(path);
+
+ // Refresh old coordinates
+ currentMouseX = mouseX;
+ currentMouseY = mouseY;
+
+ } else {
+ // Create a new preview path.
+ var color =
availableColors[currentColorIndex].slice(0);
+ color[3] = previewTransparency;
+ currentPreviewPath = new Path(drawType.id,
+ color,
+
availableThicknesses[currentThicknessIndex],
+ currentMouseX, currentMouseY, mouseX,
+ mouseY, false);
+ }
+ } else {
+ currentMouseX = mouseX;
+ currentMouseY = mouseY;
+ }
+
+ refreshDisplayCanvas();
+ };
+
canvasDisplay.onmouseup = function(e) {
if (e.button == 0) {
if (mouseDown) {
mouseDown = false;
+ currentPreviewPath = null;
+
+ var mouseX = e.pageX -
canvasDisplay.offsetLeft;
+ var mouseY = e.pageY - canvasDisplay.offsetTop;
+ var drawType =
availableDrawTypes[currentDrawTypeIndex];
+
+ var path = new Path(drawType.id,
availableColors[currentColorIndex],
+
availableThicknesses[currentThicknessIndex],
+ currentMouseX, currentMouseY, mouseX,
+ mouseY, true);
+ // Draw it on the background canvas.
+ path.draw(canvasBackgroundCtx);
+
+ // Send it to the sever.
+ pushPath(path);
+
+ // Refresh old coordinates
+ currentMouseX = mouseX;
+ currentMouseY = mouseY;
refreshDisplayCanvas();
}
@@ -542,16 +625,15 @@
"margin: 4px; border: 1px solid #bbb;
border-radius: 3px;");
optionContainer.appendChild(colorContainersBox);
-
colorContainers = new Array(3 * 3 * 3);
for (var i = 0; i < colorContainers.length; i++) {
var colorContainer = colorContainers[i] =
document.createElement("div");
- var color = availableColors[i] =
+ var color = availableColors[i] =
[
Math.floor((i % 3) * 255 / 2),
Math.floor((Math.floor(i / 3) % 3) * 255 / 2),
- Math.floor((Math.floor(i / (3 * 3)) % 3) * 255
/ 2),
+ Math.floor((Math.floor(i / (3 * 3)) % 3) * 255
/ 2),
1.0
];
colorContainer.setAttribute("style",
@@ -571,12 +653,37 @@
divClearLeft.setAttribute("style", "clear: left;");
colorContainersBox.appendChild(divClearLeft);
+
+ var drawTypeContainersBox = document.createElement("div");
+ drawTypeContainersBox.setAttribute("style",
+ "float: right; margin-right: 3px; margin-top:
1px;");
+ optionContainer.appendChild(drawTypeContainersBox);
+
+ drawTypeContainers = new Array(availableDrawTypes.length);
+ for (var i = 0; i < drawTypeContainers.length; i++) {
+ var drawTypeContainer = drawTypeContainers[i] =
+ document.createElement("div");
+ drawTypeContainer.setAttribute("style",
+ "text-align: center; margin: 3px; padding: 0
3px;"
+ + "height: 18px; float: left;");
+ drawTypeContainer.style.border = "2px solid #000";
+ drawTypeContainer.appendChild(document.createTextNode(
+ String(availableDrawTypes[i].name)));
+ drawTypeContainer.onmousedown = (function(ix) {
+ return function() {
+ setDrawType(ix);
+ };
+ })(i);
+
+ drawTypeContainersBox.appendChild(drawTypeContainer);
+ }
+
+
var thicknessContainersBox = document.createElement("div");
thicknessContainersBox.setAttribute("style",
"margin: 3px; border: 1px solid #bbb;
border-radius: 3px;");
optionContainer.appendChild(thicknessContainersBox);
-
thicknessContainers = new
Array(availableThicknesses.length);
for (var i = 0; i < thicknessContainers.length; i++) {
var thicknessContainer = thicknessContainers[i] =
@@ -596,6 +703,7 @@
thicknessContainersBox.appendChild(thicknessContainer);
}
+
divClearLeft = document.createElement("div");
divClearLeft.setAttribute("style", "clear: left;");
thicknessContainersBox.appendChild(divClearLeft);
@@ -603,6 +711,7 @@
setColor(0);
setThickness(0);
+ setDrawType(0);
}
@@ -624,9 +733,10 @@
+ path.color[0] + "," + path.color[1] + ","
+ path.color[2] + ","
+ Math.round(path.color[3] * 255.0) + ","
- + path.thickness + "," + path.x1 + ","
- + path.y1 + "," + path.x2 + "," + path.y2;
-
+ + path.thickness + "," + path.x1 + ","
+ + path.y1 + "," + path.x2 + "," + path.y2 + ","
+ + (path.lastInChain ? "1" : "0");
+
socket.send("1" + message);
}
@@ -638,7 +748,7 @@
thicknessContainers[currentThicknessIndex]
.style.borderColor = "#d08";
}
-
+
function setColor(colorIndex) {
if (typeof currentColorIndex !== "undefined")
colorContainers[currentColorIndex]
@@ -648,6 +758,15 @@
.style.borderColor = "#d08";
}
+ function setDrawType(drawTypeIndex) {
+ if (typeof currentDrawTypeIndex !== "undefined")
+ drawTypeContainers[currentDrawTypeIndex]
+ .style.borderColor = "#000";
+ currentDrawTypeIndex = drawTypeIndex;
+ drawTypeContainers[currentDrawTypeIndex]
+ .style.borderColor = "#d08";
+ }
+
connect();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]