From a0989deff9a2403763a6d91c80bf336482289bf3 Mon Sep 17 00:00:00 2001
From: Kevin Lee <kevin@infinite-lee.com>
Date: Mon, 20 Aug 2018 18:36:22 -0700
Subject: [PATCH] add functionality to change pen radius

---
 src/components/tools/networked-drawing.js |  7 ++-
 src/components/tools/pen.js               | 37 ++++++++++------
 src/hub.html                              | 14 +++---
 src/input-mappings.js                     |  8 ++--
 src/network-schemas.js                    |  8 +++-
 src/utils/mouse-events-handler.js         | 52 +++++++++++++----------
 6 files changed, 75 insertions(+), 51 deletions(-)

diff --git a/src/components/tools/networked-drawing.js b/src/components/tools/networked-drawing.js
index a56dde927..cd31926dd 100644
--- a/src/components/tools/networked-drawing.js
+++ b/src/components/tools/networked-drawing.js
@@ -26,8 +26,7 @@ function copyData(fromArray, toArray, fromIndex, toIndex) {
 AFRAME.registerComponent("networked-drawing", {
   schema: {
     segments: { default: 8 }, //the number of "sides" the procedural tube should have
-    radius: { default: 0.02 }, //the radius of the procedural tube
-    color: { type: "color", default: "#FF0000" }, //default color
+    defaultRadius: { default: 0.01 }, //the radius of the procedural tube
     minDrawTimeout: { default: 5000 }, //the minimum time a drawn line will live
     maxDrawTimeout: { default: 600000 }, //the maximum time a drawn line will live
     maxLines: { default: 25 }, //how many lines can persist before lines older than minDrawTime are removed
@@ -46,8 +45,8 @@ AFRAME.registerComponent("networked-drawing", {
       vertexColors: THREE.VertexColors
     };
 
-    this.color = new THREE.Color(this.data.color);
-    this.radius = this.data.radius;
+    this.color = new THREE.Color();
+    this.radius = this.data.defaultRadius;
     this.segments = this.data.segments;
 
     const material = new THREE.MeshStandardMaterial(options);
diff --git a/src/components/tools/pen.js b/src/components/tools/pen.js
index a776071d7..8abf3a532 100644
--- a/src/components/tools/pen.js
+++ b/src/components/tools/pen.js
@@ -15,15 +15,18 @@ AFRAME.registerComponent("pen", {
     camera: { type: "selector" },
     drawing: { type: "string" },
     drawingManager: { type: "string" },
+    color: { type: "color", default: "#FF0033" },
     availableColors: {
       default: ["#FF0033", "#FFFF00", "#00FF33", "#0099FF", "#9900FF", "#FFFFFF", "#000000"]
-    }
+    },
+    radius: { default: 0.01 },
+    minRadius: { default: 0.005 },
+    maxRadius: { default: 0.05 }
   },
 
   init() {
     this.stateAdded = this.stateAdded.bind(this);
     this.stateRemoved = this.stateRemoved.bind(this);
-    this.onComponentChanged = this.onComponentChanged.bind(this);
 
     this.timeSinceLastDraw = 0;
 
@@ -49,13 +52,16 @@ AFRAME.registerComponent("pen", {
 
     this.el.parentNode.addEventListener("stateadded", this.stateAdded);
     this.el.parentNode.addEventListener("stateremoved", this.stateRemoved);
-    this.el.addEventListener("onComponentChanged", this.onComponentChanged);
   },
 
   pause() {
     this.el.parentNode.removeEventListener("stateadded", this.stateAdded);
     this.el.parentNode.removeEventListener("stateremoved", this.stateRemoved);
-    this.el.removeEventListener("onComponentChanged", this.onComponentChanged);
+  },
+
+  update(_prevData) {
+    this.el.setAttribute("color", this.data.color);
+    this.el.setAttribute("radius", this.data.radius);
   },
 
   tick(t, dt) {
@@ -95,7 +101,7 @@ AFRAME.registerComponent("pen", {
       this.el.object3D.getWorldPosition(this.worldPosition);
       this.getNormal(this.normal, this.worldPosition, this.direction);
 
-      this.currentDrawing.startDraw(this.worldPosition, this.direction, this.normal, this.el.getAttribute("color"));
+      this.currentDrawing.startDraw(this.worldPosition, this.direction, this.normal, this.data.color, this.data.radius);
     }
   },
 
@@ -112,8 +118,13 @@ AFRAME.registerComponent("pen", {
 
   changeColor(mod) {
     this.colorIndex = (this.colorIndex + mod + this.data.availableColors.length) % this.data.availableColors.length;
-    const color = this.data.availableColors[this.colorIndex];
-    this.el.setAttribute("color", color);
+    this.data.color = this.data.availableColors[this.colorIndex];
+    this.el.setAttribute("color", this.data.color);
+  },
+
+  changeRadius(mod) {
+    this.data.radius = Math.max(this.data.minRadius, Math.min(this.data.radius + mod, this.data.maxRadius));
+    this.el.setAttribute("radius", this.data.radius);
   },
 
   stateAdded(evt) {
@@ -127,6 +138,12 @@ AFRAME.registerComponent("pen", {
       case "colorPrev":
         this.changeColor(-1);
         break;
+      case "radiusUp":
+        this.changeRadius(this.data.minRadius);
+        break;
+      case "radiusDown":
+        this.changeRadius(-this.data.minRadius);
+        break;
       case "grabbed":
         this.grabbed = true;
         break;
@@ -147,11 +164,5 @@ AFRAME.registerComponent("pen", {
       default:
         break;
     }
-  },
-
-  onComponentChanged(evt) {
-    if (evt.detail.name === "color") {
-      this.changeColor(0);
-    }
   }
 });
diff --git a/src/hub.html b/src/hub.html
index 31af6917b..1664e2f7d 100644
--- a/src/hub.html
+++ b/src/hub.html
@@ -196,8 +196,10 @@
                     hoverable
                     activatable__draw-hand="buttonStartEvents: secondary_hand_grab; buttonEndEvents: secondary_hand_release;"
                     activatable__draw-cursor="buttonStartEvents: secondary-cursor-grab; buttonEndEvents: secondary-cursor-release;"
-                    activatable__color-next="buttonStartEvents: tertiary_action_north, scroll_up; buttonEndEvents: secondary_hand_release, scroll_release; activatedState: colorNext;"
-                    activatable__color-prev="buttonStartEvents: tertiary_action_south, scroll_down; buttonEndEvents: secondary_hand_release, scroll_release; activatedState: colorPrev;"
+                    activatable__color-next="buttonStartEvents: tertiary_action_north, scroll_up; buttonEndEvents: secondary_hand_release, vertical_scroll_release; activatedState: colorNext;"
+                    activatable__color-prev="buttonStartEvents: tertiary_action_south, scroll_down; buttonEndEvents: secondary_hand_release, vertical_scroll_release; activatedState: colorPrev;"
+                    activatable__increase-radius="buttonStartEvents: tertiary_action_east, scroll_left; buttonEndEvents: secondary_hand_release, horizontal_scroll_release; activatedState: radiusUp;"
+                    activatable__decrease-radius="buttonStartEvents: tertiary_action_west, scroll_right; buttonEndEvents: secondary_hand_release, horizontal_scroll_release; activatedState: radiusDown;"
                     scale="0.5 0.5 0.5"
                 >
                     <a-sphere 
@@ -262,8 +264,8 @@
                          stretchEndButtons: primary_hand_release, secondary_hand_release;
                          dragDropStartButtons: hand_grab, secondary_hand_grab; 
                          dragDropEndButtons: hand_release, secondary_hand_release;
-                         activateStartButtons: secondary_hand_grab, tertiary_action_north, tertiary_action_south, scroll_up, scroll_down; 
-                         activateEndButtons: secondary_hand_release, scroll_release;"
+                         activateStartButtons: secondary_hand_grab, tertiary_action_north, tertiary_action_south, tertiary_action_east, tertiary_action_west, scroll_up, scroll_down, scroll_left, scroll_right; 
+                         activateEndButtons: secondary_hand_release, vertical_scroll_release, horizontal_scroll_release;"
                      collision-filter="collisionForces: false"
                      physics-collider
             ></a-mixin>
@@ -302,8 +304,8 @@
                 stretchEndButtons: cursor-release, primary_hand_release, secondary_hand_release;
                 dragDropStartButtons: cursor-grab, primary_hand_grab, secondary_hand_grab;
                 dragDropEndButtons: cursor-release, primary_hand_release, secondary_hand_release;
-                activateStartButtons: secondary-cursor-grab, secondary_hand_grab, tertiary_action_north, tertiary_action_south, scroll_up, scroll_down; 
-                activateEndButtons: secondary-cursor-release, secondary_hand_release, scroll_release;"
+                activateStartButtons: secondary-cursor-grab, secondary_hand_grab, tertiary_action_north, tertiary_action_south, tertiary_action_east, tertiary_action_west, scroll_up, scroll_down, scroll_left, scroll_right; 
+                activateEndButtons: secondary-cursor-release, secondary_hand_release, vertical_scroll_release, horizontal_scroll_release;"
             segments-height="9"
             segments-width="9"
             event-repeater="events: raycaster-intersection, raycaster-intersection-cleared; eventSource: #cursor-controller"
diff --git a/src/input-mappings.js b/src/input-mappings.js
index 80e708d75..0c1cc24a5 100644
--- a/src/input-mappings.js
+++ b/src/input-mappings.js
@@ -49,8 +49,8 @@ const config = {
     default: {
       "vive-controls": {
         "trackpad.pressedmove": { left: "move" },
-        trackpad_dpad4_pressed_west_down: { right: "snap_rotate_left" },
-        trackpad_dpad4_pressed_east_down: { right: "snap_rotate_right" },
+        trackpad_dpad4_pressed_west_down: { left: "tertiary_action_west", right: "snap_rotate_left" },
+        trackpad_dpad4_pressed_east_down: { left: "tertiary_action_east", right: "snap_rotate_right" },
         trackpad_dpad4_pressed_center_down: { left: "action_primary_down", right: "action_primary_down" },
         trackpad_dpad4_pressed_north_down: { left: "tertiary_action_north", right: "tertiary_action_north" },
         trackpad_dpad4_pressed_south_down: { left: "tertiary_action_south", right: "tertiary_action_south" },
@@ -66,8 +66,8 @@ const config = {
         scroll: { right: "scroll_move" }
       },
       "oculus-touch-controls": {
-        joystick_dpad4_west: { right: "snap_rotate_left" },
-        joystick_dpad4_east: { right: "snap_rotate_right" },
+        joystick_dpad4_west: { left: "tertiary_action_west", right: "snap_rotate_left" },
+        joystick_dpad4_east: { left: "tertiary_action_east", right: "snap_rotate_right" },
         joystick_dpad4_north: { left: "tertiary_action_north", right: "tertiary_action_north" },
         joystick_dpad4_south: { left: "tertiary_action_south", right: "tertiary_action_south" },
         joystick_dpad4_center: { left: "action_primary_up", right: "action_primary_up" },
diff --git a/src/network-schemas.js b/src/network-schemas.js
index cd3c162df..e515203ef 100644
--- a/src/network-schemas.js
+++ b/src/network-schemas.js
@@ -146,7 +146,13 @@ function registerNetworkSchemas() {
       "media-loader",
       {
         selector: "#pen",
-        component: "color"
+        component: "pen",
+        property: "radius"
+      },
+      {
+        selector: "#pen",
+        component: "pen",
+        property: "color"
       }
     ]
   });
diff --git a/src/utils/mouse-events-handler.js b/src/utils/mouse-events-handler.js
index 5bf420f28..90492d5a4 100644
--- a/src/utils/mouse-events-handler.js
+++ b/src/utils/mouse-events-handler.js
@@ -1,7 +1,8 @@
 // TODO: Make look speed adjustable by the user
 const HORIZONTAL_LOOK_SPEED = 0.1;
 const VERTICAL_LOOK_SPEED = 0.06;
-const SCROLL_TIMEOUT = 250;
+const VERTICAL_SCROLL_TIMEOUT = 250;
+const HORIZONTAL_SCROLL_TIMEOUT = 250;
 
 export default class MouseEventsHandler {
   constructor(cursor, cameraController) {
@@ -20,7 +21,8 @@ export default class MouseEventsHandler {
 
     this.addEventListeners();
 
-    this.lastScrollTime = 0;
+    this.lastVerticalScrollTime = 0;
+    this.lastHorizontalScrollTime = 0;
   }
 
   tearDown() {
@@ -82,31 +84,35 @@ export default class MouseEventsHandler {
   }
 
   onMouseWheel(e) {
-    let mod = 0;
-    switch (e.deltaMode) {
-      case e.DOM_DELTA_PIXEL:
-        mod = e.deltaY / 500;
-        break;
-      case e.DOM_DELTA_LINE:
-        mod = e.deltaY / 10;
-        break;
-      case e.DOM_DELTA_PAGE:
-        mod = e.deltaY / 2;
-        break;
+    const direction = this.cursor.changeDistanceMod(this.getScrollMod(e.deltaY, e.deltaMode));
+    if (
+      direction !== 0 &&
+      (this.lastVerticalScrollTime === 0 || this.lastVerticalScrollTime + VERTICAL_SCROLL_TIMEOUT < Date.now())
+    ) {
+      this.superHand.el.emit(direction > 0 ? "scroll_up" : "scroll_down");
+      this.superHand.el.emit("vertical_scroll_release");
+      this.lastVerticalScrollTime = Date.now();
     }
 
-    const direction = this.cursor.changeDistanceMod(mod);
-    let event;
-    if (direction === 1) {
-      event = "scroll_up";
-    } else if (direction === -1) {
-      event = "scroll_down";
+    const mod = this.getScrollMod(e.deltaX, e.deltaMode);
+    if (
+      mod !== 0 &&
+      (this.lastHorizontalScrollTime === 0 || this.lastHorizontalScrollTime + HORIZONTAL_SCROLL_TIMEOUT < Date.now())
+    ) {
+      this.superHand.el.emit(mod < 0 ? "scroll_left" : "scroll_right");
+      this.superHand.el.emit("horizontal_scroll_release");
+      this.lastHorizontalScrollTime = Date.now();
     }
+  }
 
-    if (direction !== 0 && (this.lastScrollTime === 0 || this.lastScrollTime + SCROLL_TIMEOUT < Date.now())) {
-      this.superHand.el.emit(event);
-      this.superHand.el.emit("scroll_release");
-      this.lastScrollTime = Date.now();
+  getScrollMod(delta, deltaMode) {
+    switch (deltaMode) {
+      case WheelEvent.DOM_DELTA_PIXEL:
+        return delta / 500;
+      case WheelEvent.DOM_DELTA_LINE:
+        return delta / 10;
+      case WheelEvent.DOM_DELTA_PAGE:
+        return delta / 2;
     }
   }
 
-- 
GitLab