diff --git a/src/engine/runtime.js b/src/engine/runtime.js
index bf7969a0c..bf3a6adc2 100644
--- a/src/engine/runtime.js
+++ b/src/engine/runtime.js
@@ -14,6 +14,7 @@ const Clock = require('../io/clock');
 const DeviceManager = require('../io/deviceManager');
 const Keyboard = require('../io/keyboard');
 const Mouse = require('../io/mouse');
+const MouseWheel = require('../io/mouseWheel');
 
 const defaultBlockPackages = {
     scratch3_control: require('../blocks/scratch3_control'),
@@ -258,7 +259,8 @@ class Runtime extends EventEmitter {
             clock: new Clock(),
             deviceManager: new DeviceManager(),
             keyboard: new Keyboard(this),
-            mouse: new Mouse(this)
+            mouse: new Mouse(this),
+            mouseWheel: new MouseWheel(this)
         };
 
         /**
diff --git a/src/io/mouseWheel.js b/src/io/mouseWheel.js
new file mode 100644
index 000000000..3394f9411
--- /dev/null
+++ b/src/io/mouseWheel.js
@@ -0,0 +1,28 @@
+class MouseWheel {
+    constructor (runtime) {
+        /**
+         * Reference to the owning Runtime.
+         * @type{!Runtime}
+         */
+        this.runtime = runtime;
+    }
+
+    /**
+     * Mouse wheel DOM event handler.
+     * @param  {object} data Data from DOM event.
+     */
+    postData (data) {
+        const matchFields = {};
+        if (data.deltaY < 0) {
+            matchFields.KEY_OPTION = 'up arrow';
+        } else if (data.deltaY > 0) {
+            matchFields.KEY_OPTION = 'down arrow';
+        } else {
+            return;
+        }
+
+        this.runtime.startHats('event_whenkeypressed', matchFields);
+    }
+}
+
+module.exports = MouseWheel;
diff --git a/test/unit/io_mousewheel.js b/test/unit/io_mousewheel.js
new file mode 100644
index 000000000..f54d47cc7
--- /dev/null
+++ b/test/unit/io_mousewheel.js
@@ -0,0 +1,44 @@
+const test = require('tap').test;
+const MouseWheel = require('../../src/io/mouseWheel');
+const Runtime = require('../../src/engine/runtime');
+
+test('spec', t => {
+    const rt = new Runtime();
+    const mw = new MouseWheel(rt);
+
+    t.type(mw, 'object');
+    t.type(mw.postData, 'function');
+    t.end();
+});
+
+test('blocks activated by scrolling', t => {
+    let _startHatsArgs;
+    const rt = {
+        startHats: (...args) => {
+            _startHatsArgs = args;
+        }
+    };
+    const mw = new MouseWheel(rt);
+
+    _startHatsArgs = null;
+    mw.postData({
+        deltaY: -1
+    });
+    t.strictEquals(_startHatsArgs[0], 'event_whenkeypressed');
+    t.strictEquals(_startHatsArgs[1].KEY_OPTION, 'up arrow');
+
+    _startHatsArgs = null;
+    mw.postData({
+        deltaY: +1
+    });
+    t.strictEquals(_startHatsArgs[0], 'event_whenkeypressed');
+    t.strictEquals(_startHatsArgs[1].KEY_OPTION, 'down arrow');
+
+    _startHatsArgs = null;
+    mw.postData({
+        deltaY: 0
+    });
+    t.strictEquals(_startHatsArgs, null);
+
+    t.end();
+});