Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit aba5c8da96e16d197ad6a6eb1e0837615863ab69 @Daniel15 committed Jan 15, 2012
@@ -0,0 +1 @@
+node_modules
@@ -0,0 +1,3 @@
+[submodule "public/javascripts/framework"]
+ path = public/javascripts/framework
+ url = git://github.com/Daniel15/JSFramework.git
83 app.js
@@ -0,0 +1,83 @@
+/**
+ * Module dependencies.
+ */
+
+var express = require('express'),
+ routes = require('./routes'),
+ now = require('now');
+
+var app = module.exports = express.createServer(),
+ everyone = now.initialize(app);
+
+// Configuration
+app.configure(function()
+{
+ app.set('views', __dirname + '/views');
+ app.set('view engine', 'ejs');
+ app.use(express.bodyParser());
+ app.use(express.methodOverride());
+ app.use(app.router);
+ app.use(express.static(__dirname + '/public'));
+});
+
+app.configure('development', function()
+{
+ app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
+});
+
+app.configure('production', function()
+{
+ app.use(express.errorHandler());
+});
+
+// Routes
+//app.get('/', routes.index);
+app.get('/', function(req, res)
+{
+ res.render('index',
+ {
+ title: 'Whiteboard',
+ pageId: 'index'
+ })
+});
+
+
+// -------------------------------------------
+// Now.js functions
+// TODO: Move this all to a separate file
+var shapes = {};
+everyone.connected(function()
+{
+ console.log('%s connected', this.user.clientId);
+ // Send all the current shapes
+ this.now.initShapes(shapes);
+});
+
+/**
+ * Add a new shape to the drawing. Adds the shape to the shape cache and then broadcasts it to
+ * every user.
+ * @param String Client's shape ID - Starts at 1 and increments for each new shape
+ * @param Object Shape data
+ */
+everyone.now.newShape = function(clientShapeId, shape)
+{
+ var shapeId = this.user.clientId + '_' + clientShapeId;
+ console.log('Adding shape %s', shapeId);
+ shapes[shapeId] = shape;
+
+ everyone.now.shapeAdded(this.user.clientId, shapeId, shape);
+};
+
+/**
+ * Clear the drawing.
+ */
+everyone.now.clear = function()
+{
+ console.log('%s cleared the drawing', this.user.clientId)
+ shapes = {};
+ everyone.now.cleared();
+}
+// -------------------------------------------
+
+app.listen(3000);
+console.log('Express server listening on port %d in %s mode', app.address().port, app.settings.env);
@@ -0,0 +1,9 @@
+{
+ "name": "Whiteboard",
+ "version": "0.0.1",
+ "private": true,
+ "dependencies": {
+ "express": "2.5.5",
+ "ejs": ">= 0.0.1"
+ }
+}
Submodule framework added at e170fb

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -0,0 +1,134 @@
+var Whiteboard =
+{
+ shapes: {},
+ maxShapeId: 0,
+
+ init: function()
+ {
+ // Elements
+ this.drawingEl = $('drawing');
+ this.drawingElPos = this.drawingEl.getPosition();
+ this.clearButtonEl = $('clear');
+
+ // Events
+ this.drawingEl.addEvent('mousedown', this.mouseDown.bind(this));
+ this.drawingEl.addEvent('mousemove', this.mouseMove.bind(this));
+ this.drawingEl.addEvent('mouseup', this.mouseUp.bind(this));
+ this.clearButtonEl.addEvent('click', this.clear.bind(this));
+
+ // Now.js
+ now.shapeAdded = this.shapeAdded.bind(this);
+ now.initShapes = this.initShapes.bind(this);
+ now.cleared = this.cleared.bind(this);
+ },
+ initShapes: function(shapes)
+ {
+ // Initialize Raphael
+ this.paper = new Raphael(this.drawingEl.element, 600, 600);
+ // Remove loading indicator
+ $('loading').remove();
+
+ for (var i in shapes)
+ {
+ if (shapes.hasOwnProperty(i))
+ {
+ this.shapeAdded(null, i, shapes[i]);
+ }
+ }
+ },
+ createShapeTool: function(x, y, colour)
+ {
+ var tool = null;
+ if ($('rectangle').get('checked'))
+ tool = 'Rectangle';
+ else if ($('ellipse').get('checked'))
+ tool = 'Ellipse';
+
+ if (!tool)
+ return null;
+
+ return new Tools.Shape[tool](this.paper, x, y, colour);
+ },
+ mouseDown: function(e)
+ {
+ this.isDrawing = true;
+
+ var x = this.drawingStartX = e.pageX - this.drawingElPos.x,
+ y = this.drawingStartY = e.pageY - this.drawingElPos.y;
+
+ // TODO: Support more than just rect
+ //this.drawingTool = new Tools.Shape.Rectangle(this.paper, x, y);
+ this.drawingTool = this.createShapeTool(x, y, $('colour').get('value'));
+ },
+ mouseMove: function(e)
+ {
+ // We don't care about the mouse if the user is not drawing
+ if (!this.isDrawing)
+ return;
+
+ // Size = mouse position - starting position
+ var mouseX = e.pageX - this.drawingElPos.x,
+ mouseY = e.pageY - this.drawingElPos.y,
+ width = mouseX - this.drawingStartX,
+ height = mouseY - this.drawingStartY;
+
+ this.drawingTool.mouseMove(width, height, mouseX, mouseY);
+ },
+ mouseUp: function(e)
+ {
+ this.isDrawing = false;
+
+ // Ignore the shape if it ended up less than 5 pixels wide
+ // TODO
+ /*if (this.drawingShape.attr('width') < 5 && this.drawingShape.attr('height') < 5)
+ {
+ this.drawingShape = null;
+ return;
+ }*/
+
+ var shapeId = this.maxShapeId++,
+ shapeData = this.drawingTool.finish();
+
+ // Add this shape right away
+ this.shapeAdded(now.core.clientId, now.core.clientId + '_' + shapeId, shapeData);
+
+ // Send this shape to the server
+ now.newShape(shapeId, shapeData);
+ },
+
+ /**
+ * Called from server - shape was added
+ */
+ shapeAdded: function(clientId, shapeId, data)
+ {
+ // If this shape was already added, ignore it
+ if (this.shapes[shapeId])
+ return;
+
+ // Create the shape
+ var shape = this.shapes[shapeId] = this.paper.add([data])[0];
+ /*shape.dblclick(function()
+ {
+ shape.remove();
+ // TODO: Send to server
+ });*/
+
+ //console.log(clientId, shapeId, data);
+ },
+ clear: function()
+ {
+ now.clear();
+ this.cleared();
+
+ },
+ cleared: function()
+ {
+ this.paper.clear();
+ }
+};
+
+// If on the body, initialise when Now.js is ready
+if (document.body.id == 'index')
+{
+ Whiteboard.init();
+}
@@ -0,0 +1,73 @@
+/**
+ * Constructor for Ellipse.
+ * @param Object Raphael paper for the drawing
+ * @param int Starting X position
+ * @param int Starting Y position
+ */
+Tools.Shape.Ellipse = function(paper, startX, startY, colour)
+{
+ this.paper = paper;
+ this.startX = startX;
+ this.startY = startY;
+ this.shape = this.paper.ellipse(startX, startY, 0, 0);
+ this.shape.attr({
+ fill: colour,
+ opacity: 0.4,
+ stroke: 'black',
+ 'stroke-width': 1
+ });
+}
+
+Tools.Shape.Ellipse.prototype =
+{
+ /**
+ * Called when the mouse is moved.
+ * @param int Width of the shape
+ * @param int Height of the shape
+ * @param int X position of the mouse
+ * @param int Y position of the mouse
+ */
+ mouseMove: function(width, height, mouseX, mouseY)
+ {
+ // The centre is half-way
+ var centreX = this.startX + (width / 2),
+ centreY = this.startY + (height / 2);
+
+ this.shape.attr({
+ cx: centreX,
+ cy: centreY,
+ rx: width,
+ ry: height
+ });
+ },
+
+ /**
+ * Get information about the shape in its current form.
+ * @return Hash Data about the shape
+ */
+ getShape: function()
+ {
+ return {
+ type: 'ellipse',
+ cx: this.shape.attr('cx'),
+ cy: this.shape.attr('cy'),
+ rx: this.shape.attr('rx'),
+ ry: this.shape.attr('ry'),
+ fill: this.shape.attr('fill'),
+ stroke: this.shape.attr('stroke'),
+ 'stroke-width': this.shape.attr('stroke-width')
+ };
+ },
+
+ /**
+ * Finish drawing this shape - Remove the temporary version from the drawing, and return its
+ * data.
+ */
+ finish: function()
+ {
+ var shape = this.getShape();
+ this.shape.remove();
+ this.shape = null;
+ return shape;
+ }
+};
@@ -0,0 +1,67 @@
+/**
+ * Constructor for Rectangle.
+ * @param Object Raphael paper for the drawing
+ * @param int Starting X position
+ * @param int Starting Y position
+ */
+Tools.Shape.Rectangle = function(paper, startX, startY, colour)
+{
+ this.paper = paper;
+ this.startX = startX;
+ this.startY = startY;
+ this.shape = this.paper.rect(startX, startY, 0, 0);
+ this.shape.attr({
+ fill: colour,
+ opacity: 0.4,
+ stroke: 'black',
+ 'stroke-width': 1
+ });
+}
+
+Tools.Shape.Rectangle.prototype =
+{
+ /**
+ * Called when the mouse is moved.
+ * @param int Width of the shape
+ * @param int Height of the shape
+ * @param int X position of the mouse
+ * @param int Y position of the mouse
+ */
+ mouseMove: function(width, height, mouseX, mouseY)
+ {
+ this.shape.attr({
+ width: width,
+ height: height
+ });
+ },
+
+ /**
+ * Get information about the shape in its current form.
+ * @return Hash Data about the shape
+ */
+ getShape: function()
+ {
+ return {
+ type: 'rect',
+ x: this.shape.attr('x'),
+ y: this.shape.attr('y'),
+ width: this.shape.attr('width'),
+ height: this.shape.attr('height'),
+ fill: this.shape.attr('fill'),
+ stroke: this.shape.attr('stroke'),
+ 'stroke-width': this.shape.attr('stroke-width')
+ };
+ },
+
+ /**
+ * Finish drawing this shape - Remove the temporary version from the drawing, and return its
+ * data.
+ */
+ finish: function()
+ {
+ var shape = this.getShape();
+ this.shape.remove();
+ this.shape = null;
+ return shape;
+ }
+};
Oops, something went wrong.

0 comments on commit aba5c8d

Please sign in to comment.