From 45c3af9c67b86de8e47806562d964a99d152d51b Mon Sep 17 00:00:00 2001 From: "A.Olokhtonov" Date: Sun, 16 Apr 2023 20:31:57 +0300 Subject: [PATCH] Brush width control. Phone "zen mode" button --- client/default.css | 118 +++++++++++++++++++++++++++++++++-- client/icons/cheeseburga.svg | 59 ++++++++++++++++++ client/index.html | 46 ++++++++------ client/tools.js | 9 +++ client/webgl.js | 2 - client/webgl_geometry.js | 3 +- client/webgl_listeners.js | 10 ++- 7 files changed, 220 insertions(+), 27 deletions(-) create mode 100644 client/icons/cheeseburga.svg diff --git a/client/default.css b/client/default.css index d4ffad9..99b5e29 100644 --- a/client/default.css +++ b/client/default.css @@ -4,6 +4,7 @@ --radius: 5px; --hgap: 5px; --gap: 10px; + --transform-amimate: transform .1s ease-in-out; } html, body { @@ -40,7 +41,8 @@ canvas.movemode.moving { pointer-events: none; } -.pallete-wrapper { +.pallete-wrapper, +.sizer-wrapper { position: fixed; top: 0; left: 0; @@ -49,6 +51,13 @@ canvas.movemode.moving { display: flex; flex-direction: column; justify-content: center; + transition: var(--transform-amimate); +} + +.sizer-wrapper { + height: unset; + width: 100%; + flex-direction: row; } .pallete { @@ -64,11 +73,19 @@ canvas.movemode.moving { padding-bottom: var(--gap); } +.pallete-wrapper.hidden { + transform: translateX(-125%); /* to account for a selected color, which is also offset to the right */ +} + +.sizer-wrapper.hidden { + transform: translateY(-125%); +} + .pallete .color { padding: var(--gap); cursor: pointer; background: var(--dark-blue); - transition: transform .1s ease-in-out; + transition: var(--transform-amimate); } .pallete .color:hover { @@ -92,7 +109,8 @@ canvas.movemode.moving { border-radius: var(--radius); } -.tools { +.tools, +.sizer { pointer-events: all; display: flex; align-items: center; @@ -106,6 +124,12 @@ canvas.movemode.moving { padding-right: var(--gap); } +.sizer { + border-radius: 0; + border-bottom-right-radius: var(--radius); + border-bottom-left-radius: var(--radius); +} + .tool { cursor: pointer; padding-left: var(--gap); @@ -114,7 +138,7 @@ canvas.movemode.moving { display: flex; align-items: center; background: var(--dark-blue); - transition: transform .1s ease-in-out; + transition: var(--transform-amimate); user-select: none; } @@ -133,4 +157,90 @@ canvas.movemode.moving { height: 24px; width: 24px; filter: invert(100%); +} + +input[type=range] { + -webkit-appearance: none; + width: 200px; + background: transparent; +} + +input[type=range]:focus { + outline: none; +} + +input[type=range]::-webkit-slider-thumb { + -webkit-appearance: none; + border: none; + background: white; + height: 20px; + width: 20px; + border-radius: 50%; + cursor: pointer; + border: 2px solid var(--dark-blue); + margin-top: -6px; /* You need to specify a margin in Chrome, but in Firefox and IE it is automatic */ +} + +input[type=range]::-moz-range-thumb { + border: none; + background: white; + height: 16px; + width: 16px; + border-radius: 50%; + cursor: pointer; + border: 2px solid var(--dark-blue); +} + +input[type=range]::-webkit-slider-runnable-track { + width: 100%; + height: 8px; + cursor: pointer; + background: white; + border-radius: 2px; + border: none; +} + +input[type=range]:focus::-webkit-slider-runnable-track { + width: 100%; + height: 8px; + cursor: pointer; + background: white; + border-radius: 2px; + border: none; +} + +input[type=range]::-moz-range-track { + width: 100%; + height: 8px; + cursor: pointer; + background: white; + border-radius: 2px; + border: none; +} + +.phone-extra-controls { + display: none; + cursor: pointer; /* for click events on mobile */ + pointer-events: all; + position: absolute; + right: 0; + background: var(--dark-blue); + height: 42px; + justify-content: center; + align-items: center; + padding-left: var(--gap); + padding-right: var(--gap); + border-top-left-radius: var(--radius); +} + +.phone-extra-controls img { + height: 24px; + width: 24px; + filter: invert(100%); +} + +@media (hover: none) and (pointer: coarse) { + .phone-extra-controls { + display: flex; + } } \ No newline at end of file diff --git a/client/icons/cheeseburga.svg b/client/icons/cheeseburga.svg new file mode 100644 index 0000000..5003fe3 --- /dev/null +++ b/client/icons/cheeseburga.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + diff --git a/client/index.html b/client/index.html index 9dcaac6..33f0951 100644 --- a/client/index.html +++ b/client/index.html @@ -6,33 +6,39 @@ - + - - - - - - - + + + + + + + - - - + + + +
+
+ +
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -44,6 +50,10 @@
+ +
+ +
\ No newline at end of file diff --git a/client/tools.js b/client/tools.js index adedbac..8546110 100644 --- a/client/tools.js +++ b/client/tools.js @@ -22,6 +22,11 @@ function switch_color(state, item) { state.colors.active_element.classList.add('active'); } +function switch_stroke_width(e, state) { + const value = e.target.value; + state.stroke_width = value; +} + function init_tools(state) { const tools = document.querySelectorAll('.tools .tool'); const colors = document.querySelectorAll('.pallete .color'); @@ -32,4 +37,8 @@ function init_tools(state) { // TODO: from localstorage switch_tool(state, document.querySelector('.tool[data-tool="pencil"]')); switch_color(state, document.querySelector('.color[data-color="000000"]')); + + document.querySelector('#stroke-width').value = state.stroke_width; + document.querySelector('#stroke-width').addEventListener('input', (e) => switch_stroke_width(e, state)); + document.querySelector('.phone-extra-controls').addEventListener('click', zenmode); } \ No newline at end of file diff --git a/client/webgl.js b/client/webgl.js index 5524884..2bef762 100644 --- a/client/webgl.js +++ b/client/webgl.js @@ -180,8 +180,6 @@ function main() { 'drawing': false, 'spacedown': false, - 'stroke_width': 8, - 'current_strokes': {}, 'queue': [], diff --git a/client/webgl_geometry.js b/client/webgl_geometry.js index 0b573e7..6bf06a5 100644 --- a/client/webgl_geometry.js +++ b/client/webgl_geometry.js @@ -169,7 +169,7 @@ function update_dynamic_stroke(state, context, player_id, point) { if (!(player_id in state.current_strokes)) { state.current_strokes[player_id] = { 'points': [], - 'width': 8, // TODO + 'width': state.stroke_width, 'color': state.colors.active, }; @@ -191,6 +191,7 @@ function clear_dynamic_stroke(state, context, player_id) { if (player_id in state.current_strokes) { state.current_strokes[player_id].points.length = 0; state.current_strokes[player_id].color = state.colors.active; + state.current_strokes[player_id].width = state.stroke_width; context.dynamic_positions[player_id].length = 0; recompute_dynamic_data(state, context); } diff --git a/client/webgl_listeners.js b/client/webgl_listeners.js index 7e78fbb..9f9b259 100644 --- a/client/webgl_listeners.js +++ b/client/webgl_listeners.js @@ -22,12 +22,18 @@ function cancel(e) { return false; } +function zenmode() { + document.querySelector('.pallete-wrapper').classList.toggle('hidden'); + document.querySelector('.sizer-wrapper').classList.toggle('hidden'); +} + function keydown(e, state, context) { if (e.code === 'Space' && !state.drawing) { state.spacedown = true; context.canvas.classList.add('movemode'); - } else if (e.code === 'KeyD') { - + } else if (e.code === 'Tab') { + e.preventDefault(); + zenmode(); } }