Skip to content

Commit

Permalink
Ellipse drawing (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
edemaine committed Jul 6, 2020
1 parent 0bf5c7e commit 9e0da26
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 10 deletions.
Empty file modified client/lib/.iconsrc/clipboard-link.svg
100755 → 100644
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions client/lib/.iconsrc/ellipse.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions client/lib/dom.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export svgTags =
polyline: true
rect: true
circle: true
ellipse: true
text: true

export create = (tag, attrs, props, events, children) ->
Expand Down
2 changes: 2 additions & 0 deletions client/lib/icons.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ icons =
'<path d="M407,64h-87c0-35.3-28.7-64-64-64s-64,28.7-64,64h-87c-26.5,0-48,21.5-48,48v352c0,26.5,21.5,48,48,48h302c26.5,0,48-21.5,48-48V112C455,85.5,433.5,64,407,64z M256,40c13.3,0,24,10.7,24,24s-10.7,24-24,24c-13.3,0-24-10.7-24-24S242.7,40,256,40z M407,458c0,3.3-2.7,6-6,6H110c-3.3,0-5-2.7-5-6V118c0-3.3,1.7-6,5-6h50v36c0,6.6,5.4,12,12,12h168c6.6,0,12-5.4,12-12v-36h49c3.3,0,6,2.7,6,6V458z M291.3,279.2c29.9,29.9,29.5,77.8,0.2,107.3c-0.1,0.1-0.1,0.1-0.2,0.2l-33.6,33.6c-29.6,29.6-77.8,29.6-107.5,0c-29.6-29.6-29.6-77.9,0-107.5l18.6-18.6c4.9-4.9,13.4-1.6,13.6,5.3c0.3,8.9,1.9,17.8,4.8,26.4c1,2.9,0.3,6.1-1.9,8.3l-6.5,6.5c-14,14-14.5,36.8-0.6,51c14,14.3,37,14.4,51.2,0.3l33.6-33.6c14.1-14.1,14-36.9,0-50.9c-1.9-1.8-3.7-3.3-5.2-4.3c-2.1-1.4-3.4-3.8-3.5-6.3c-0.2-5.3,1.7-10.7,5.8-14.9l10.5-10.5c2.8-2.8,7.1-3.1,10.3-0.9C284.7,273.2,288.1,276,291.3,279.2L291.3,279.2z M361.8,208.7c-29.6-29.6-77.8-29.6-107.5,0l-33.6,33.6c-0.1,0.1-0.1,0.1-0.2,0.2c-29.3,29.4-29.7,77.4,0.2,107.3c3.2,3.2,6.6,6,10.3,8.6c3.2,2.2,7.5,1.9,10.3-0.9l10.5-10.5c4.2-4.2,6-9.6,5.8-14.9c-0.1-2.5-1.4-4.9-3.5-6.3c-1.5-1-3.3-2.4-5.2-4.3c-14-14-14.1-36.8,0-50.9l33.6-33.6c14.1-14.1,37.2-14,51.2,0.3c13.9,14.2,13.4,37-0.6,51l-6.5,6.5c-2.2,2.2-2.9,5.4-1.9,8.3c2.9,8.6,4.5,17.5,4.8,26.4c0.3,7,8.7,10.2,13.6,5.3l18.6-18.6C391.4,286.6,391.4,238.4,361.8,208.7L361.8,208.7z"/>'
'download-svg': # heavily edited file-download-solid plus "SVG" in Impact font
'<path d="M424,0h-97.9H320h-32H88C74.7,0,64,10.7,64,24v159v305c0,13.3,10.7,24,24,24h336c13.3,0,24-10.7,24-24V183v-23v-32v-6.1V24 C448,10.7,437.3,0,424,0z M364.5,377.4L268,473.1c-6.7,6.6-17.4,6.6-24,0l-96.4-95.7c-10.2-10.1-3-27.4,11.3-27.4H224v-80 c0-8.8,7.2-16,16-16h32c8.8,0,16,7.2,16,16v80h65.2C367.5,350,374.6,367.3,364.5,377.4z M192,101h-38.3V88.2c0-6-0.5-9.8-1.5-11.4 c-1-1.6-2.6-2.5-4.9-2.5c-2.5,0-4.4,1.1-5.6,3.3c-1.3,2.2-1.9,5.6-1.9,10.1c0,5.8,0.7,10.1,2.1,13.1c1.4,2.9,5.2,6.5,11.6,10.6 c18.3,11.9,29.9,21.7,34.7,29.3c4.8,7.6,7.1,19.9,7.1,36.9c0,12.3-1.3,21.4-4,27.3c-2.6,5.8-7.7,10.7-15.3,14.7 c-7.6,4-16.4,5.9-26.4,5.9c-11,0-20.4-2.3-28.2-6.8c-7.8-4.6-12.9-10.4-15.3-17.4c-2.4-7.1-3.6-17.1-3.6-30v-11.3h38.3v21.1 c0,6.5,0.5,10.7,1.6,12.5c1.1,1.9,3,2.8,5.7,2.8c2.7,0,4.8-1.2,6.1-3.5c1.3-2.4,2-5.8,2-10.5c0-10.2-1.3-16.9-3.8-20 c-2.6-3.1-9-8.4-19.3-15.7c-10.2-7.4-17-12.8-20.4-16.1c-3.3-3.4-6.1-8-8.3-13.9c-2.2-5.9-3.3-13.5-3.3-22.7c0-13.3,1.5-23,4.6-29.1 c3.1-6.1,8.1-10.9,15-14.4c6.9-3.5,15.3-5.2,25.1-5.2c10.7,0,19.8,1.9,27.4,5.7c7.5,3.8,12.5,8.5,15,14.3c2.4,5.7,3.7,15.5,3.7,29.2 V101z M306.3,48.6l-21,173.1h-62.6L198.9,48.6h43.5c5.1,47.7,8.7,88,10.8,121c2.1-33.4,4.4-63,6.8-88.9l2.9-32.2H306.3z M407.8,112.3h-41.2V96.6c0-9.9-0.4-16.1-1.2-18.6c-0.8-2.5-2.6-3.7-5.6-3.7c-2.5,0-4.3,1.1-5.2,3.2c-0.9,2.1-1.4,7.6-1.4,16.5V177 c0,7.8,0.5,12.9,1.4,15.3c0.9,2.5,2.7,3.7,5.5,3.7c3,0,5-1.4,6.1-4.2c1.1-2.8,1.6-8.2,1.6-16.3v-20.5h-8.3v-26.3h48.3v92.9h-25.9 l-3.8-12.4c-2.8,5.3-6.4,9.4-10.6,12c-4.3,2.7-9.3,4-15.1,4c-6.9,0-13.4-1.8-19.4-5.5c-6-3.7-10.6-8.2-13.8-13.6 c-3.1-5.4-5.1-11.1-5.9-17.1c-0.8-6-1.2-14.9-1.2-26.8v-51.4c0-16.5,0.8-28.5,2.4-36c1.6-7.5,6.3-14.3,14-20.6 c7.7-6.2,17.7-9.4,30-9.4c12.1,0,22.1,2.7,30,8.1c8,5.4,13.1,11.9,15.6,19.3c2.4,7.4,3.6,18.3,3.6,32.5V112.3z"/>'
ellipse: # edited rect below
'<path d="M256,468c-67.1,0-130.5-21.2-178.4-59.8c-24-19.3-42.9-41.9-56.3-67.3C7.2,314.1,0,285.5,0,256s7.2-58.1,21.3-85 c13.3-25.3,32.3-48,56.3-67.3C125.5,65.2,188.9,44,256,44c67.1,0,130.5,21.2,178.4,59.8c24,19.3,42.9,41.9,56.3,67.3 c14.1,26.8,21.3,55.4,21.3,85s-7.2,58.1-21.3,85c-13.3,25.3-32.3,48-56.3,67.3C386.5,446.8,323.1,468,256,468z M256,108 c-52.6,0-101.7,16.2-138.3,45.7C83.1,181.5,64,217.8,64,256s19.1,74.5,53.7,102.3C154.3,387.8,203.4,404,256,404 c52.6,0,101.7-16.2,138.3-45.7C428.9,330.5,448,294.2,448,256s-19.1-74.5-53.7-102.3C357.7,124.2,308.6,108,256,108z"/>'
grid: # edited border-all to extend (more) beyond square
'<rect x="52" width="64" height="512"/><rect x="224" width="64" height="512"/><rect x="396" width="64" height="512"/><rect y="52" width="512" height="64"/><rect y="224" width="512" height="64"/><rect y="396" width="512" height="64"/>'
rect: # edited square to have wider aspect ratio and as thick as segment
Expand Down
77 changes: 68 additions & 9 deletions client/main.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,34 @@ tools =
pointers.throttle
id: pointers[e.pointerId]
pts: 1: eventToPoint e
ellipse:
icon: 'ellipse'
hotspot: [0.201888, 0.75728]
help: 'Draw axis-aligned ellipsis inside rectangle between endpoints (drag)'
start: ->
pointers.throttle = throttle.method 'objectEdit'
down: (e) ->
return if pointers[e.pointerId]
pt = eventToPoint e
pointers[e.pointerId] = Meteor.apply 'objectNew', [
room: currentRoom
type: 'ellipse'
pts: [pt, pt]
color: currentColor
width: currentWidth
], returnStubValue: true
console.log 'yo', eventToPoint e
up: (e) ->
return unless pointers[e.pointerId]
undoableOp
type: 'new'
obj: Objects.findOne pointers[e.pointerId]
delete pointers[e.pointerId]
move: (e) ->
return unless pointers[e.pointerId]
pointers.throttle
id: pointers[e.pointerId]
pts: 1: eventToPoint e
eraser:
icon: 'eraser'
hotspot: [0.4, 0.9]
Expand Down Expand Up @@ -316,7 +344,7 @@ tools =
count++
break if count > target
switch diff.type
when 'pen', 'poly', 'rect'
when 'pen', 'poly', 'rect', 'ellipse'
obj = diff
historyObjects[obj.id] = obj
historyRender.render obj
Expand Down Expand Up @@ -367,7 +395,7 @@ tools =
help: 'Download/export entire drawing as an SVG file'
once: ->
## Compute bounding box, assuming spanned by <circle> (from pen groups),
## <polyline>, and <rect> elements
## <polyline>, <rect>, and <ellipse> elements
min =
x: Infinity
y: Infinity
Expand Down Expand Up @@ -402,6 +430,16 @@ tools =
max.x = Math.max max.x, x + width + stroke
min.y = Math.min min.y, y - stroke
max.y = Math.max max.y, y + height + stroke
for ellipse in currentBoard().querySelectorAll 'ellipse'
cx = parseFloat ellipse.getAttribute 'x'
cy = parseFloat ellipse.getAttribute 'y'
rx = parseFloat ellipse.getAttribute 'rx'
ry = parseFloat ellipse.getAttribute 'ry'
stroke = (parseFloat ellipse.getAttribute('stroke-width') ? 0) / 2
min.x = Math.min min.x, cx - rx - stroke
max.x = Math.max max.x, cx + rx + stroke
min.y = Math.min min.y, cy - ry - stroke
max.y = Math.max max.y, cy + ry + stroke
if min.x == Infinity
min.x = min.y = max.x = max.y = 0
## Temporarily make grid space entire drawing
Expand Down Expand Up @@ -434,6 +472,7 @@ drawingTools =
pen: true
segment: true
rect: true
ellipse: true
lastDrawingTool = 'pen'

currentBoard = ->
Expand Down Expand Up @@ -533,8 +572,8 @@ pointerEvents = ->

class Highlighter
constructor: ->
@target = null # <g/polyline/rect> that @highlighted is based on
@highlighted = null # <g/polyline/rect class="highlight">
@target = null # <g/polyline/rect/ellipse> that @highlighted based on
@highlighted = null # <g/polyline/rect/ellipse class="highlight">
@id = null # highlighted object ID
findGroup: (e) ->
## Pen and touch devices don't always seem to set `e.target` correctly;
Expand All @@ -545,7 +584,7 @@ class Highlighter
while target? and (tag = target.tagName.toLowerCase()) in ['circle', 'line']
target = target.parentNode
return unless target?
return unless tag in ['g', 'polyline', 'rect']
return unless tag in ['g', 'polyline', 'rect', 'ellipse']
return unless target.dataset.id?
#return if target == @highlighted
## Shouldn't get pointer events on highlighted or selected overlays thanks
Expand Down Expand Up @@ -759,14 +798,14 @@ class Render
poly
renderRect: (obj) ->
id = @id obj
unless (poly = @dom[id])?
@root.appendChild @dom[id] = poly =
unless (rect = @dom[id])?
@root.appendChild @dom[id] = rect =
dom.create 'rect', null, dataset: id: id
xMin = Math.min obj.pts[0].x, obj.pts[1].x
xMax = Math.max obj.pts[0].x, obj.pts[1].x
yMin = Math.min obj.pts[0].y, obj.pts[1].y
yMax = Math.max obj.pts[0].y, obj.pts[1].y
dom.attr poly,
dom.attr rect,
x: xMin
y: yMin
width: xMax - xMin
Expand All @@ -775,7 +814,25 @@ class Render
'stroke-width': obj.width
'stroke-linejoin': 'round'
fill: 'none'
poly
rect
renderEllipse: (obj) ->
id = @id obj
unless (ellipse = @dom[id])?
@root.appendChild @dom[id] = ellipse =
dom.create 'ellipse', null, dataset: id: id
xMin = Math.min obj.pts[0].x, obj.pts[1].x
xMax = Math.max obj.pts[0].x, obj.pts[1].x
yMin = Math.min obj.pts[0].y, obj.pts[1].y
yMax = Math.max obj.pts[0].y, obj.pts[1].y
dom.attr ellipse,
cx: (xMin + xMax) / 2
cy: (yMin + yMax) / 2
rx: (xMax - xMin) / 2
ry: (yMax - yMin) / 2
stroke: obj.color
'stroke-width': obj.width
fill: 'none'
ellipse
render: (obj, options = {}) ->
elt =
switch obj.type
Expand All @@ -785,6 +842,8 @@ class Render
@renderPoly obj, options
when 'rect'
@renderRect obj, options
when 'ellipse'
@renderEllipse obj, options
else
console.warn "No renderer for object of type #{obj.type}"
if options.translate != false
Expand Down
2 changes: 1 addition & 1 deletion lib/objects.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Meteor.methods
pts: [xyType]
color: String
width: Number
when 'rect'
when 'rect', 'ellipse'
Object.assign pattern,
pts: Match.Where (pts) ->
check pts, [xyType]
Expand Down

0 comments on commit 9e0da26

Please sign in to comment.