From 39337816ad1e221b120f5475736c420cf6a469a7 Mon Sep 17 00:00:00 2001 From: Erik Demaine Date: Thu, 27 Aug 2020 19:34:18 -0400 Subject: [PATCH] Fill color support for rect, ellipse (fix #83) (#35) --- client/lib/icons.coffee | 5 +++ client/main.coffee | 71 ++++++++++++++++++++++++++++++----------- client/main.pug | 3 ++ lib/objects.coffee | 1 + 4 files changed, 61 insertions(+), 19 deletions(-) diff --git a/client/lib/icons.coffee b/client/lib/icons.coffee index 6745283..86175c2 100644 --- a/client/lib/icons.coffee +++ b/client/lib/icons.coffee @@ -42,6 +42,8 @@ icons = '' spinner: '' + tint: + '' undo: '' @@ -68,6 +70,9 @@ icons = '' text: # combination of font and i-cursor (with 16px offset subtracted) '' + 'tint-slash': # modification to tilt-slash to fit in 512x512, + # with 45-degree slash taken from fill icon + '' export viewSize = 512 diff --git a/client/main.coffee b/client/main.coffee index c2a15d6..13341a4 100644 --- a/client/main.coffee +++ b/client/main.coffee @@ -228,16 +228,17 @@ tools = down: (e) -> return if pointers[e.pointerId] origin = eventToPoint e + object = + room: currentRoom + page: currentPage + type: 'rect' + pts: [origin, origin] + color: currentColor + width: currentWidth + object.fill = currentFill if currentFillOn pointers[e.pointerId] = origin: origin - id: Meteor.apply 'objectNew', [ - room: currentRoom - page: currentPage - type: 'rect' - pts: [origin, origin] - color: currentColor - width: currentWidth - ], returnStubValue: true + id: Meteor.apply 'objectNew', [object], returnStubValue: true up: (e) -> return unless pointers[e.pointerId] undoableOp @@ -268,16 +269,17 @@ tools = down: (e) -> return if pointers[e.pointerId] origin = eventToPoint e + object = + room: currentRoom + page: currentPage + type: 'ellipse' + pts: [origin, origin] + color: currentColor + width: currentWidth + object.fill = currentFill if currentFillOn pointers[e.pointerId] = origin: origin - id: Meteor.apply 'objectNew', [ - room: currentRoom - page: currentPage - type: 'ellipse' - pts: [origin, origin] - color: currentColor - width: currentWidth - ], returnStubValue: true + id: Meteor.apply 'objectNew', [object], returnStubValue: true up: (e) -> return unless pointers[e.pointerId] undoableOp @@ -722,6 +724,8 @@ colors = [ '#eced00' # custom yellow ] currentColor = 'black' +currentFill = 'white' +currentFillOn = false widths = [ 1 @@ -1131,7 +1135,7 @@ class Render stroke: obj.color 'stroke-width': obj.width 'stroke-linejoin': 'round' - fill: 'none' + fill: obj.fill or 'none' rect renderEllipse: (obj) -> id = @id obj @@ -1149,7 +1153,7 @@ class Render ry: (yMax - yMin) / 2 stroke: obj.color 'stroke-width': obj.width - fill: 'none' + fill: obj.fill or 'none' ellipse renderText: (obj, options) -> id = @id obj @@ -1764,6 +1768,23 @@ selectDrawingTool = -> unless currentTool of drawingTools selectTool lastDrawingTool +paletteFill = -> + document.getElementById('fillOn').innerHTML = + icons.svgIcon icons.modIcon 'tint', fill: 'currentColor' + document.getElementById('fillOff').innerHTML = + icons.svgIcon icons.modIcon 'tint-slash', fill: 'currentColor' + dom.listen document.getElementById('fillTool'), + click: (e) -> + currentFillOn = not currentFillOn + updateFill() + updateFill() +updateFill = -> + document.getElementById('fillOn').style.display = + if currentFillOn then 'block' else 'none' + document.getElementById('fillOff').style.display = + if currentFillOn then 'none' else 'block' + document.getElementById('fillTool').style.color = currentFill + paletteColors = -> colorsDiv = document.getElementById 'colors' for color in colors @@ -1772,7 +1793,9 @@ paletteColors = -> style: backgroundColor: color dataset: color: color , - click: (e) -> selectColor e.currentTarget.dataset.color + click: (e) -> + (if e.shiftKey then selectFill else selectColor) \ + e.currentTarget.dataset.color widthSize = 22 paletteWidths = -> @@ -1854,6 +1877,15 @@ selectColor = (color, keepTool) -> if currentTool == 'pen' icons.setCursor board.svg, penIcon(currentColor), ...tools[currentTool].hotspot +selectFill = (color) -> + currentFill = color + currentFillOn = true + updateFill() + if selection.nonempty() + selection.edit 'fill', currentFill + keepTool = true + selectDrawingTool() unless keepTool + selectWidth = (width, keepTool) -> currentWidth = parseFloat width if width? if selection.nonempty() @@ -1896,6 +1928,7 @@ Meteor.startup -> paletteTools() paletteWidths() paletteFontSizes() + paletteFill() paletteColors() selectTool() selectColor null, true diff --git a/client/main.pug b/client/main.pug index 24fc1be..0253cc7 100644 --- a/client/main.pug +++ b/client/main.pug @@ -25,6 +25,9 @@ body #attribs.bottom.horizontal.palette.historyHide #widths.subpalette.textHide #fontSizes.subpalette.textShow + #fillTool.subpalette + #fillOn.attrib.active + #fillOff.attrib #colors.subpalette #history.bottom.horizontal.palette.historyShow input#historyRange.history(type="range", min="0", max="0", title="Drag to time travel through history") diff --git a/lib/objects.coffee b/lib/objects.coffee index 4c66640..6654c8b 100644 --- a/lib/objects.coffee +++ b/lib/objects.coffee @@ -47,6 +47,7 @@ Meteor.methods check pts, [xyType] pts.length == 2 color: String + fill: Match.Optional String width: Number when 'text' Object.assign pattern,