diff --git a/src/behaviours/trackpad-scrolling.js b/src/behaviours/trackpad-scrolling.js
new file mode 100644
index 0000000000000000000000000000000000000000..e6fd297e5bb09a46ae1ff706eda3451e74b26b63
--- /dev/null
+++ b/src/behaviours/trackpad-scrolling.js
@@ -0,0 +1,52 @@
+function trackpad_scrolling(el) {
+  this.el = el;
+  this.start = "trackpadtouchstart";
+  this.move = "axismove";
+  this.end = "trackpadtouchend";
+  this.isScrolling = false;
+  this.x = 0;
+  this.y = 0;
+  this.axis = [0, 0];
+  this.emittedEventDetail = { axis: this.axis };
+
+  this.onStart = this.onStart.bind(this);
+  this.onMove = this.onMove.bind(this);
+  this.onEnd = this.onEnd.bind(this);
+}
+
+trackpad_scrolling.prototype = {
+  addEventListeners: function() {
+    this.el.addEventListener(this.start, this.onStart);
+    this.el.addEventListener(this.move, this.onMove);
+    this.el.addEventListener(this.end, this.onEnd);
+  },
+  removeEventListeners: function() {
+    this.el.removeEventListener(this.start, this.onStart);
+    this.el.removeEventListener(this.move, this.onMove);
+    this.el.removeEventListener(this.end, this.onEnd);
+  },
+  onStart: function(e) {
+    this.x = e.detail.axis[0];
+    this.y = e.detail.axis[1];
+    this.isScrolling = true;
+  },
+
+  onMove: function(e) {
+    if (!this.isScrolling) return;
+    const x = e.detail.axis[0];
+    const y = e.detail.axis[1];
+
+    this.axis[0] = x - this.x;
+    this.axis[1] = y - this.y;
+    this.emittedEventDetail.axis = this.axis;
+    e.target.emit("scroll", this.emittedEventDetail);
+    this.x = x;
+    this.y = y;
+  },
+
+  onEnd: function(e) {
+    this.isScrolling = false;
+  }
+};
+
+export default trackpad_scrolling;
diff --git a/src/hub.js b/src/hub.js
index 76b202b3d3fa535334d699fe44d8e62e5ba80f44..f69848e1b6987f818af88ba9cb77e5aaeef23a35 100644
--- a/src/hub.js
+++ b/src/hub.js
@@ -20,6 +20,7 @@ import "aframe-motion-capture-components";
 import "./utils/audio-context-fix";
 
 import trackpad_dpad4 from "./behaviours/trackpad-dpad4";
+import trackpad_scrolling from "./behaviours/trackpad-scrolling";
 import joystick_dpad4 from "./behaviours/joystick-dpad4";
 import msft_mr_axis_with_deadzone from "./behaviours/msft-mr-axis-with-deadzone";
 import { PressedMove } from "./activators/pressedmove";
@@ -143,6 +144,7 @@ if (!isBotMode && !isTelemetryDisabled) {
 disableiOSZoom();
 
 AFRAME.registerInputBehaviour("trackpad_dpad4", trackpad_dpad4);
+AFRAME.registerInputBehaviour("trackpad_scrolling", trackpad_scrolling);
 AFRAME.registerInputBehaviour("joystick_dpad4", joystick_dpad4);
 AFRAME.registerInputBehaviour("msft_mr_axis_with_deadzone", msft_mr_axis_with_deadzone);
 AFRAME.registerInputActivator("pressedmove", PressedMove);
diff --git a/src/input-mappings.js b/src/input-mappings.js
index a4c0f8ea827996018d4f822c3ee81f68c31612df..386df13d1e2f17129214a130b62c212e9c7f4a17 100644
--- a/src/input-mappings.js
+++ b/src/input-mappings.js
@@ -24,7 +24,8 @@ const config = {
         joystick: "joystick_dpad4"
       },
       "vive-controls": {
-        trackpad: "trackpad_dpad4"
+        trackpad: "trackpad_dpad4",
+        trackpad_scrolling: "trackpad_scrolling"
       },
       "windows-motion-controls": {
         joystick: "joystick_dpad4",
@@ -59,7 +60,7 @@ const config = {
         trackpadtouchend: "thumb_up",
         triggerdown: ["action_grab", "index_down"],
         triggerup: ["action_release", "index_up"],
-        axismove: { right: "move_duck" }
+        scroll: { right: "move_duck" }
       },
       "oculus-touch-controls": {
         joystick_dpad4_west: {