2014-07-30 03:23:16 +08:00
|
|
|
MAX_PATHS_IN_SEQUENCE = 30
|
|
|
|
|
|
|
|
# A line in the whiteboard
|
|
|
|
# Note: is used to draw lines from the pencil tool and from the line tool, this is why some
|
|
|
|
# methods can receive different set of parameters.
|
|
|
|
# TODO: Maybe this should be split in WhiteboardPathModel for the pencil and
|
|
|
|
# WhiteboardLineModel for the line tool
|
|
|
|
class @WhiteboardLineModel extends WhiteboardToolModel
|
|
|
|
|
|
|
|
constructor: (@paper) ->
|
|
|
|
super @paper
|
|
|
|
|
|
|
|
# the defintion of this shape, kept so we can redraw the shape whenever needed
|
|
|
|
# format: svg path, stroke color, thickness
|
|
|
|
@definition = ["", "#000", "0px"]
|
|
|
|
|
|
|
|
# Creates a line in the paper
|
|
|
|
# @param {number} x the x value of the line start point as a percentage of the original width
|
|
|
|
# @param {number} y the y value of the line start point as a percentage of the original height
|
|
|
|
# @param {string} colour the colour of the shape to be drawn
|
|
|
|
# @param {number} thickness the thickness of the line to be drawn
|
|
|
|
make: (info) ->
|
2014-08-20 03:09:04 +08:00
|
|
|
|
2014-08-15 02:11:56 +08:00
|
|
|
if info?.points?
|
|
|
|
x = info.points[0]
|
|
|
|
y = info.points[1]
|
|
|
|
color = info.color
|
|
|
|
thickness = info.thickness
|
2014-08-01 23:01:44 +08:00
|
|
|
|
|
|
|
x1 = x * @gw + @xOffset
|
|
|
|
y1 = y * @gh + @yOffset
|
|
|
|
path = "M" + x1 + " " + y1 + " L" + x1 + " " + y1
|
|
|
|
pathPercent = "M" + x + " " + y + " L" + x + " " + y
|
|
|
|
@obj = @paper.path(path)
|
2014-08-22 06:31:32 +08:00
|
|
|
@obj.attr "stroke", formatColor(color)
|
2014-09-13 04:26:25 +08:00
|
|
|
@obj.attr "stroke-width", zoomStroke(formatThickness(thickness))
|
2014-08-01 23:01:44 +08:00
|
|
|
@obj.attr({"stroke-linejoin": "round"})
|
2014-09-05 02:31:47 +08:00
|
|
|
@obj.attr "stroke-linecap", "round"
|
2014-08-01 23:01:44 +08:00
|
|
|
|
2014-08-15 02:11:56 +08:00
|
|
|
@definition = [pathPercent, @obj.attrs["stroke"], @obj.attrs["stroke-width"]]
|
2014-07-30 03:23:16 +08:00
|
|
|
|
|
|
|
@obj
|
|
|
|
|
|
|
|
# Update the line dimensions
|
|
|
|
# @param {number} x1 1) the x of the first point
|
|
|
|
# 2) the next x point to be added to the line
|
|
|
|
# @param {number} y1 1) the y of the first point
|
|
|
|
# 2) the next y point to be added to the line
|
|
|
|
# @param {number,boolean} x2 1) the x of the second point
|
|
|
|
# 2) true if the line should be added to the current line,
|
|
|
|
# false if it should replace the last point
|
|
|
|
# @param {number} y2 1) the y of the second point
|
|
|
|
# 2) undefined
|
|
|
|
update: (info) ->
|
2014-08-20 03:09:04 +08:00
|
|
|
|
2014-08-15 02:11:56 +08:00
|
|
|
if info?.points?
|
|
|
|
x1 = info.points[0]
|
|
|
|
y1 = info.points[1]
|
|
|
|
x2 = info.points[2]
|
|
|
|
y2 = info.points[3]
|
2014-07-30 03:23:16 +08:00
|
|
|
|
2014-08-01 23:01:44 +08:00
|
|
|
if @obj?
|
2014-09-18 04:04:30 +08:00
|
|
|
path = @_buildPath(info.points)
|
2014-07-30 03:23:16 +08:00
|
|
|
|
2014-09-18 04:04:30 +08:00
|
|
|
@definition[0] = path
|
2014-07-30 03:23:16 +08:00
|
|
|
|
2014-09-18 04:04:30 +08:00
|
|
|
path = @_scaleLinePath(path, @gw, @gh, @xOffset, @yOffset)
|
|
|
|
@obj.attr path: path
|
2014-07-30 03:23:16 +08:00
|
|
|
|
|
|
|
# Draw a line on the paper
|
|
|
|
# @param {number,string} x1 1) the x value of the first point
|
|
|
|
# 2) the string path
|
|
|
|
# @param {number,string} y1 1) the y value of the first point
|
|
|
|
# 2) the colour
|
|
|
|
# @param {number} x2 1) the x value of the second point
|
|
|
|
# 2) the thickness
|
|
|
|
# @param {number} y2 1) the y value of the second point
|
|
|
|
# 2) undefined
|
|
|
|
# @param {string} colour 1) the colour of the shape to be drawn
|
|
|
|
# 2) undefined
|
|
|
|
# @param {number} thickness 1) the thickness of the line to be drawn
|
|
|
|
# 2) undefined
|
|
|
|
draw: (x1, y1, x2, y2, colour, thickness) ->
|
|
|
|
|
|
|
|
# if the drawing is from the pencil tool, it comes as a path first
|
2014-09-18 04:04:30 +08:00
|
|
|
# if _.isString(x1)
|
|
|
|
# colour = y1
|
|
|
|
# thickness = x2
|
|
|
|
# path = x1
|
2014-07-30 03:23:16 +08:00
|
|
|
|
2014-09-18 04:04:30 +08:00
|
|
|
# # if the drawing is from the line tool, it comes with two points
|
|
|
|
# else
|
|
|
|
# path = @_buildPath(points)
|
2014-07-30 03:23:16 +08:00
|
|
|
|
2014-09-18 04:04:30 +08:00
|
|
|
# line = @paper.path(@_scaleLinePath(path, @gw, @gh, @xOffset, @yOffset))
|
|
|
|
# line.attr Utils.strokeAndThickness(colour, thickness)
|
|
|
|
# line.attr({"stroke-linejoin": "round"})
|
|
|
|
# line
|
2014-07-30 03:23:16 +08:00
|
|
|
|
|
|
|
# When dragging for drawing lines starts
|
|
|
|
# @param {number} x the x value of the cursor
|
|
|
|
# @param {number} y the y value of the cursor
|
|
|
|
# TODO: moved here but not finished
|
|
|
|
dragOnStart: (x, y) ->
|
|
|
|
# # find the x and y values in relation to the whiteboard
|
|
|
|
# sx = (@paperWidth - @gw) / 2
|
|
|
|
# sy = (@paperHeight - @gh) / 2
|
|
|
|
# @lineX = x - @containerOffsetLeft - sx + @xOffset
|
|
|
|
# @lineY = y - @containerOffsetTop - sy + @yOffset
|
|
|
|
# values = [ @lineX / @paperWidth, @lineY / @paperHeight, @currentColour, @currentThickness ]
|
|
|
|
# globals.connection.emitMakeShape "line", values
|
|
|
|
|
|
|
|
# As line drawing drag continues
|
|
|
|
# @param {number} dx the difference between the x value from _lineDragStart and now
|
|
|
|
# @param {number} dy the difference between the y value from _lineDragStart and now
|
|
|
|
# @param {number} x the x value of the cursor
|
|
|
|
# @param {number} y the y value of the cursor
|
|
|
|
# TODO: moved here but not finished
|
|
|
|
dragOnMove: (dx, dy, x, y) ->
|
|
|
|
# sx = (@paperWidth - @gw) / 2
|
|
|
|
# sy = (@paperHeight - @gh) / 2
|
|
|
|
# [cx, cy] = @_currentSlideOffsets()
|
|
|
|
# # find the x and y values in relation to the whiteboard
|
|
|
|
# @cx2 = x - @containerOffsetLeft - sx + @xOffset
|
|
|
|
# @cy2 = y - @containerOffsetTop - sy + @yOffset
|
|
|
|
# if @shiftPressed
|
|
|
|
# globals.connection.emitUpdateShape "line", [ @cx2 / @paperWidth, @cy2 / @paperHeight, false ]
|
|
|
|
# else
|
|
|
|
# @currentPathCount++
|
|
|
|
# if @currentPathCount < MAX_PATHS_IN_SEQUENCE
|
|
|
|
# globals.connection.emitUpdateShape "line", [ @cx2 / @paperHeight, @cy2 / @paperHeight, true ]
|
|
|
|
# else if @obj?
|
|
|
|
# @currentPathCount = 0
|
|
|
|
# # save the last path of the line
|
|
|
|
# @obj.attrs.path.pop()
|
|
|
|
# path = @obj.attrs.path.join(" ")
|
|
|
|
# @obj.attr path: (path + "L" + @lineX + " " + @lineY)
|
|
|
|
|
|
|
|
# # scale the path appropriately before sending
|
|
|
|
# pathStr = @obj.attrs.path.join(",")
|
|
|
|
# globals.connection.emitPublishShape "path",
|
|
|
|
# [ @_scaleLinePath(pathStr, 1 / @gw, 1 / @gh),
|
|
|
|
# @currentColour, @currentThickness ]
|
|
|
|
# globals.connection.emitMakeShape "line",
|
|
|
|
# [ @lineX / @paperWidth, @lineY / @paperHeight, @currentColour, @currentThickness ]
|
|
|
|
# @lineX = @cx2
|
|
|
|
# @lineY = @cy2
|
|
|
|
|
|
|
|
# Drawing line has ended
|
|
|
|
# @param {Event} e the mouse event
|
|
|
|
# TODO: moved here but not finished
|
|
|
|
dragOnEnd: (e) ->
|
|
|
|
# if @obj?
|
|
|
|
# path = @obj.attrs.path
|
|
|
|
# @obj = null # any late updates will be blocked by this
|
|
|
|
# # scale the path appropriately before sending
|
|
|
|
# globals.connection.emitPublishShape "path",
|
|
|
|
# [ @_scaleLinePath(path.join(","), 1 / @gw, 1 / @gh),
|
|
|
|
# @currentColour, @currentThickness ]
|
|
|
|
|
2014-09-18 04:04:30 +08:00
|
|
|
_buildPath: (points) ->
|
|
|
|
path = ""
|
|
|
|
|
|
|
|
if points and points.length >= 2
|
|
|
|
path += "M #{points[0]} #{points[1]}"
|
|
|
|
i = 2
|
|
|
|
|
|
|
|
while i < points.length
|
|
|
|
path += "L#{points[i]} #{points[i + 1]}"
|
|
|
|
i += 2
|
|
|
|
|
|
|
|
path += "Z"
|
|
|
|
path
|
2014-07-30 03:23:16 +08:00
|
|
|
|
|
|
|
# Scales a path string to fit within a width and height of the new paper size
|
|
|
|
# @param {number} w width of the shape as a percentage of the original width
|
|
|
|
# @param {number} h height of the shape as a percentage of the original height
|
|
|
|
# @return {string} the path string after being manipulated to new paper size
|
|
|
|
_scaleLinePath: (string, w, h, xOffset=0, yOffset=0) ->
|
|
|
|
path = null
|
|
|
|
points = string.match(/(\d+[.]?\d*)/g)
|
|
|
|
len = points.length
|
|
|
|
j = 0
|
|
|
|
|
|
|
|
# go through each point and multiply it by the new height and width
|
|
|
|
while j < len
|
|
|
|
if j isnt 0
|
|
|
|
path += "L" + (points[j] * w + xOffset) + "," + (points[j + 1] * h + yOffset)
|
|
|
|
else
|
|
|
|
path = "M" + (points[j] * w + xOffset) + "," + (points[j + 1] * h + yOffset)
|
|
|
|
j += 2
|
|
|
|
path
|