2012-12-12 03:37:32 +08:00
|
|
|
define [
|
|
|
|
'jquery',
|
|
|
|
'underscore',
|
|
|
|
'backbone',
|
2012-12-13 10:04:43 +08:00
|
|
|
'raphael',
|
2012-12-12 03:37:32 +08:00
|
|
|
'globals',
|
|
|
|
'cs!models/whiteboard_paper',
|
2012-12-13 10:04:43 +08:00
|
|
|
'text!templates/preupload_image.html',
|
|
|
|
'colorwheel'
|
|
|
|
], ($, _, Backbone, Raphael, globals, WhiteboardPaperModel, preuploadImageTemplate) ->
|
2012-12-12 03:37:32 +08:00
|
|
|
|
2012-12-12 05:15:08 +08:00
|
|
|
# TODO: this is being used for presentation and whiteboard, maybe they could be separated
|
|
|
|
|
2012-12-12 03:37:32 +08:00
|
|
|
DEFAULT_COLOUR = "#FF0000"
|
|
|
|
DEFAULT_THICKNESS = 1
|
|
|
|
|
|
|
|
# The whiteboard components in a session
|
|
|
|
# The contents are rendered by SessionView, this class is Used to
|
|
|
|
# manage the events in the users.
|
|
|
|
SessionWhiteboardView = Backbone.View.extend
|
2012-12-12 10:15:14 +08:00
|
|
|
events:
|
2012-12-13 10:04:43 +08:00
|
|
|
"click #colour-view": "_toogleColorPicker"
|
2012-12-12 03:37:32 +08:00
|
|
|
|
|
|
|
initialize: ->
|
|
|
|
@paper = null
|
|
|
|
|
|
|
|
# Bind to the event triggered when the client connects to the server
|
|
|
|
globals.connection.bind "connection:connected",
|
2012-12-13 10:04:43 +08:00
|
|
|
@_registerConnectionEvents, @
|
|
|
|
|
|
|
|
# don't need to render anything, the rendering is done by SessionView.
|
|
|
|
render: ->
|
|
|
|
@colorView = @$("#colour-view")
|
|
|
|
@colourViewCtx = @colorView[0].getContext("2d")
|
|
|
|
@colourText = @$("#colour-text")
|
|
|
|
@thicknessControl = @$("#thickness-view")
|
|
|
|
@thicknessControlCtx = @thicknessControl[0].getContext("2d")
|
|
|
|
@_createColourPicker()
|
|
|
|
|
|
|
|
@_renderPaper()
|
|
|
|
|
|
|
|
@_drawThicknessView(DEFAULT_THICKNESS, DEFAULT_COLOUR)
|
|
|
|
@_drawColourView(DEFAULT_COLOUR)
|
|
|
|
|
|
|
|
_createColourPicker: ->
|
|
|
|
unless @colourPicker
|
|
|
|
@$("#colour-picker").hide()
|
|
|
|
@colourPicker = Raphael.colorwheel(@$("#colour-picker")[0], 75)
|
|
|
|
@colourPicker.input(@$("#colour-text")[0])
|
|
|
|
@colourPicker.onchange (color) =>
|
|
|
|
@_drawThicknessView(null, color.hex)
|
|
|
|
@_drawColourView(color.hex)
|
|
|
|
@colourPicker.color DEFAULT_COLOUR
|
2012-12-12 03:37:32 +08:00
|
|
|
|
|
|
|
# Registers listeners for events in the application socket.
|
2012-12-13 10:04:43 +08:00
|
|
|
_registerConnectionEvents: ->
|
2012-12-12 03:37:32 +08:00
|
|
|
socket = globals.connection.socket
|
|
|
|
|
|
|
|
# Received event to update all the slide images
|
|
|
|
# @param {Array} urls list of URLs to be added to the paper (after old images are removed)
|
|
|
|
socket.on "all_slides", (urls) =>
|
|
|
|
console.log "received all_slides", urls
|
2012-12-12 04:48:38 +08:00
|
|
|
# TODO $("#uploadStatus").text ""
|
|
|
|
@paper?.removeAllImagesFromPaper()
|
2012-12-12 03:37:32 +08:00
|
|
|
for url in urls
|
2012-12-12 04:48:38 +08:00
|
|
|
@paper?.addImageToPaper(url[0], url[1], url[2])
|
|
|
|
|
|
|
|
# Received event to clear the whiteboard shapes
|
|
|
|
socket.on "clrPaper", =>
|
|
|
|
console.log "received clrPaper"
|
|
|
|
@paper?.clear()
|
|
|
|
|
|
|
|
# Received event to update all the shapes in the whiteboard
|
|
|
|
# @param {Array} shapes Array of shapes to be drawn
|
|
|
|
socket.on "all_shapes", (shapes) =>
|
|
|
|
console.log "received all_shapes"
|
|
|
|
@paper?.clear()
|
|
|
|
@paper?.drawListOfShapes shapes
|
|
|
|
|
|
|
|
# Received event to update a shape being created
|
|
|
|
# @param {string} shape type of shape being updated
|
|
|
|
# @param {Array} data all information to update the shape
|
|
|
|
socket.on "updShape", (shape, data) =>
|
|
|
|
@paper?.updateShape shape, data
|
|
|
|
|
|
|
|
# Received event to create a shape on the whiteboard
|
|
|
|
# @param {string} shape type of shape being made
|
|
|
|
# @param {Array} data all information to make the shape
|
|
|
|
socket.on "makeShape", (shape, data) =>
|
|
|
|
@paper?.makeShape shape, data
|
2012-12-12 03:37:32 +08:00
|
|
|
|
2012-12-12 05:15:08 +08:00
|
|
|
# Received event to update the cursor coordinates
|
|
|
|
# @param {number} x x-coord of the cursor as a percentage of page width
|
|
|
|
# @param {number} y y-coord of the cursor as a percentage of page height
|
|
|
|
socket.on "mvCur", (x, y) =>
|
|
|
|
@paper?.moveCursor x, y
|
|
|
|
|
|
|
|
# Received event to update the slide image
|
|
|
|
# @param {string} url URL of image to show
|
|
|
|
socket.on "changeslide", (url) =>
|
|
|
|
console.log "received changeslide", url
|
|
|
|
@paper?.showImageFromPaper url
|
|
|
|
|
2012-12-12 10:15:14 +08:00
|
|
|
# Received event to update the viewBox value
|
|
|
|
# @param {string} xperc Percentage of x-offset from top left corner
|
|
|
|
# @param {string} yperc Percentage of y-offset from top left corner
|
|
|
|
# @param {string} wperc Percentage of full width of image to be displayed
|
|
|
|
# @param {string} hperc Percentage of full height of image to be displayed
|
|
|
|
# TODO: not tested yet
|
|
|
|
socket.on "viewBox", (xperc, yperc, wperc, hperc) =>
|
|
|
|
console.log "received viewBox", xperc, yperc, wperc, hperc
|
|
|
|
xperc = parseFloat(xperc, 10)
|
|
|
|
yperc = parseFloat(yperc, 10)
|
|
|
|
wperc = parseFloat(wperc, 10)
|
|
|
|
hperc = parseFloat(hperc, 10)
|
|
|
|
@paper?.updatePaperFromServer xperc, yperc, wperc, hperc
|
|
|
|
|
2012-12-13 09:02:35 +08:00
|
|
|
# Received event to update the whiteboard between fit to width and fit to page
|
|
|
|
# @param {boolean} value choice of fit: true for fit to page, false for fit to width
|
|
|
|
socket.on "fitToPage", (value) ->
|
|
|
|
@paper?.setFitToPage value
|
|
|
|
|
|
|
|
# Received event to update the zoom level of the whiteboard.
|
|
|
|
# @param {number} delta amount of change in scroll wheel
|
|
|
|
socket.on "zoom", (delta) ->
|
|
|
|
@paper?.setZoom delta
|
|
|
|
|
|
|
|
# Received event to update the whiteboard size and position
|
|
|
|
# @param {number} cx x-offset from top left corner as percentage of original width of paper
|
|
|
|
# @param {number} cy y-offset from top left corner as percentage of original height of paper
|
|
|
|
# @param {number} sw slide width as percentage of original width of paper
|
|
|
|
# @param {number} sh slide height as a percentage of original height of paper
|
|
|
|
socket.on "paper", (cx, cy, sw, sh) ->
|
|
|
|
@paper?.updatePaperFromServer cx, cy, sw, sh
|
|
|
|
|
|
|
|
# Received event when the panning action finishes
|
|
|
|
socket.on "panStop", ->
|
|
|
|
# TODO: implement
|
|
|
|
# @paper?.panDone()
|
|
|
|
|
2012-12-13 10:04:43 +08:00
|
|
|
# Toggles the visibility of the colour picker, which is hidden by
|
|
|
|
# default. The picker is a RaphaelJS object, so each node of the object
|
|
|
|
# must be shown/hidden individually.
|
|
|
|
_toogleColorPicker: ->
|
|
|
|
if @$("#colour-picker").is(":visible")
|
|
|
|
@$("#colour-picker").hide()
|
|
|
|
else
|
|
|
|
@$("#colour-picker").show()
|
2012-12-12 03:37:32 +08:00
|
|
|
|
2012-12-13 10:04:43 +08:00
|
|
|
# TODO: to use the event to test other things
|
|
|
|
# @paper.setZoom(1)
|
2012-12-12 03:37:32 +08:00
|
|
|
|
|
|
|
_renderPaper: ->
|
|
|
|
# have to create the paper here, in the initializer #slide doesn't exist yet
|
2012-12-13 09:02:35 +08:00
|
|
|
@paper ?= new WhiteboardPaperModel(@$("#slide")[0])
|
2012-12-12 03:37:32 +08:00
|
|
|
@paper.create()
|
|
|
|
|
|
|
|
# events triggered when an image is added or removed from the paper
|
2012-12-12 10:15:14 +08:00
|
|
|
@paper.bind "paper:image:added", @_addPreloadImage, this
|
|
|
|
@paper.bind "paper:image:removed", @_removePreloadImage, this
|
2012-12-12 03:37:32 +08:00
|
|
|
|
2012-12-12 10:15:14 +08:00
|
|
|
_addPreloadImage: (img) ->
|
2012-12-12 03:37:32 +08:00
|
|
|
customSrc = img.attr("src")
|
|
|
|
customSrc = customSrc.replace(":3000", "") # TODO: temporary
|
|
|
|
console.log "adding preload image", customSrc
|
|
|
|
data =
|
|
|
|
img:
|
|
|
|
id: img.id
|
|
|
|
url: customSrc
|
|
|
|
compiledTemplate = _.template(preuploadImageTemplate, data)
|
|
|
|
@$("#slide").append compiledTemplate
|
|
|
|
|
2012-12-12 10:15:14 +08:00
|
|
|
_removePreloadImage: (imgID) ->
|
2012-12-12 03:37:32 +08:00
|
|
|
console.log "removing preload image", imgID
|
|
|
|
$("#preload-" + imgID).remove()
|
|
|
|
|
|
|
|
# Drawing the thickness viewer for client feedback.
|
|
|
|
# No messages are sent to the server, it is completely
|
|
|
|
# local. Shows visual of thickness for drawing tools.
|
|
|
|
# @param {number} thickness the thickness value
|
|
|
|
# @param {string} colour the colour it should be displayed as
|
|
|
|
# @return {undefined}
|
|
|
|
_drawThicknessView: (thickness, colour) ->
|
2012-12-13 10:04:43 +08:00
|
|
|
@currentThickness = thickness if thickness?
|
2012-12-12 03:37:32 +08:00
|
|
|
@thicknessControlCtx.fillStyle = "#FFFFFF"
|
|
|
|
@thicknessControlCtx.fillRect 0, 0, 20, 20
|
2012-12-13 10:04:43 +08:00
|
|
|
center = Math.round((20 - @currentThickness + 1) / 2)
|
2012-12-12 03:37:32 +08:00
|
|
|
@thicknessControlCtx.fillStyle = colour
|
2012-12-13 10:04:43 +08:00
|
|
|
@thicknessControlCtx.fillRect center, center, @currentThickness + 1, @currentThickness + 1
|
2012-12-12 03:37:32 +08:00
|
|
|
|
|
|
|
# Drawing the colour viewer for client feedback.
|
|
|
|
# No messages are sent to the server, it is
|
|
|
|
# completely local. Shows colour visual for drawing tools.
|
|
|
|
# @param {string} colour the colour it should be displayed as
|
|
|
|
# @return {undefined}
|
|
|
|
_drawColourView: (colour) ->
|
|
|
|
@currentColour = colour
|
|
|
|
@colourViewCtx.fillStyle = colour
|
|
|
|
@colourText.value = colour
|
|
|
|
@colourViewCtx.fillRect 0, 0, 12, 12
|
|
|
|
|
|
|
|
SessionWhiteboardView
|