Repository: chartjs/chartjs-plugin-zoom
Pull request #507 (2021-05-12 08:21:14)

Add the ability to enable both wheel and drag modes at the same time
Hi,

Here is a PR thats adds the ability to enable both wheel and drag modes at the same time, as suggested in #239. I propose to split the wheel/drag configurations like this:

```js
zoom: {
      wheel: {
        enabled: true,
        speed: 0.1,
        modifierKey: null
      },
      drag: {
        enabled: true,
        backgroundColor: 'yellow',
        borderColor: 'black',
        borderWidth: 1,
        threshold: 1
      },
      mode: 'xy',
}
```

`speed`, `threshold`, `wheelModifierKey` (now `wheel.modifierKey`) are moved to their respective configurations, I think that makes clearer that a given option refers to a given mode.

kurkle: Nice!
How about `pinch` zoom? I think its still checking for `zoom.enabled`. Maybe it should be possible to disable that separately? Own scope for it?
jledentu: Oh you're right, I admit that I often forget to check touch behaviors. Do I add `pinch.enabled`? I guess that it will often be aligned with `wheel.enabled`  as I don't know if it makes sense to explicitly enable zoom by mouse and disable zoom on touch devices. But at least we allow more flexibility.
kurkle: I think `pinch.enabled` would be good. Maybe fall back from each scope to `zoom.enabled`, to make the "break" of the change smaller and maybe easier to find.
jledentu: @kurkle I added `pinch.enabled` + a warning on `zoom.enabled ` as suggested (I think it's better to remove this option in order to keep the code clean and make the configuration more explicit?).

Patch:
diff --git a/docs/guide/options.md b/docs/guide/options.md
index d61f03b..5f293c6 100644
--- a/docs/guide/options.md
+++ b/docs/guide/options.md
@@ -53,21 +53,35 @@ const chart = new Chart('id', {
 
 | Name | Type | Default | Description
 | ---- | ---- | ------- | ----------
-| `enabled` | `boolean` | `false` | Enable zooming
-| `drag` | `boolean`\|[`DragEffectOptions`](#drag-effect-options) | `undefined` | Enable drag-to-zoom behavior (disables zooming by wheel)
+| `wheel` | [`WheelOptions`](#wheel-options) | `undefined` | Options of the mouse wheel behavior
+| `drag` | [`DragOptions`](#drag-options) | `undefined` | Options of the drag-to-zoom behavior
+| `pinch` | [`PinchOptions`](#pinch-options) | `undefined` | Options of the pinch behavior
 | `mode` | `'x'`\|`'y'`\|`'xy'` | `'xy'` | Allowed zoom directions
 | `overScaleMode` | `'x'`\|`'y'`\|`'xy'` | `undefined` | Which of the enabled zooming directions should only be available when the mouse cursor is over a scale for that axis
-| `speed` | `number` | `0.1` | Factor of zoom speed via mouse wheel.
-| `threshold` | `number` | `0` | Mimimal zoom distance required before actually applying zoom
-| `wheelModifierKey` | `'ctrl'`\|`'alt'`\|`'shift'`\|`'meta'` | `null` |  Modifier key required for zooming with mouse
 
-#### Drag effect options
+#### Wheel options
 
-| Name | Type | Description
-| ---- | -----| -----------
-| `backgroundColor` | `Color` | Fill color
-| `borderColor` | `Color` | Stroke color
-| `borderWidth` | `number` | Stroke width
+| Name | Type | Default | Description
+| ---- | -----| ------- | -----------
+| `enabled` | `boolean` | `false` | Enable zooming via mouse wheel
+| `speed` | `number` | `0.1` | Factor of zoom speed via mouse wheel
+| `modifierKey` | `'ctrl'`\|`'alt'`\|`'shift'`\|`'meta'` | `null` |  Modifier key required for zooming with mouse
+
+#### Drag options
+
+| Name | Type | Default | Description
+| ---- | -----| ------- | -----------
+| `enabled` | `boolean` | `false` | Enable drag-to-zoom
+| `backgroundColor` | `Color` | `'rgba(225,225,225,0.3)'` | Fill color
+| `borderColor` | `Color` | `'rgba(225,225,225)'` | Stroke color
+| `borderWidth` | `number` | `0` | Stroke width
+| `threshold` | `number` | `0` | Minimal zoom distance required before actually applying zoom
+
+#### Pinch options
+
+| Name | Type | Default | Description
+| ---- | -----| ------- | -----------
+| `enabled` | `boolean` | `false` | Enable zooming via pinch
 
 ### Zoom Events
 
diff --git a/docs/guide/usage.md b/docs/guide/usage.md
index 8fde347..75c56bd 100644
--- a/docs/guide/usage.md
+++ b/docs/guide/usage.md
@@ -20,7 +20,12 @@ const config = {
     plugins: {
       zoom: {
         zoom: {
-          enabled: true,
+          wheel: {
+            enabled: true,
+          },
+          pinch: {
+            enabled: true
+          },
           mode: 'xy',
         }
       }
diff --git a/docs/samples/basic.md b/docs/samples/basic.md
index 622fbee..f2b076e 100644
--- a/docs/samples/basic.md
+++ b/docs/samples/basic.md
@@ -61,14 +61,19 @@ const zoomOptions = {
     mode: 'xy',
   },
   zoom: {
-    enabled: true,
+    wheel: {
+      enabled: true,
+    },
+    pinch: {
+      enabled: true
+    },
     mode: 'xy',
   }
 };
 // </block:zoom>
 
 const panStatus = () => zoomOptions.pan.enabled ? 'enabled' : 'disabled';
-const zoomStatus = () => zoomOptions.zoom.enabled ? 'enabled' : 'disabled';
+const zoomStatus = () => zoomOptions.zoom.wheel.enabled ? 'enabled' : 'disabled';
 
 // <block:config:1>
 const config = {
@@ -95,7 +100,8 @@ const actions = [
   {
     name: 'Toggle zoom',
     handler(chart) {
-      zoomOptions.zoom.enabled = !zoomOptions.zoom.enabled;
+      zoomOptions.zoom.wheel.enabled = !zoomOptions.zoom.wheel.enabled;
+      zoomOptions.zoom.pinch.enabled = !zoomOptions.zoom.pinch.enabled;
       chart.update();
     }
   }, {
diff --git a/docs/samples/drag/category.md b/docs/samples/drag/category.md
index fe0388d..ab8f60f 100644
--- a/docs/samples/drag/category.md
+++ b/docs/samples/drag/category.md
@@ -67,8 +67,9 @@ const config = {
           modifierKey: 'ctrl',
         },
         zoom: {
-          enabled: true,
-          drag: true,
+          drag: {
+            enabled: true
+          },
           mode: 'x',
         },
       }
diff --git a/docs/samples/drag/linear.md b/docs/samples/drag/linear.md
index 3e0d245..3c40f76 100644
--- a/docs/samples/drag/linear.md
+++ b/docs/samples/drag/linear.md
@@ -61,9 +61,9 @@ const zoomOptions = {
     modifierKey: 'ctrl',
   },
   zoom: {
-    enabled: true,
     mode: 'xy',
     drag: {
+      enabled: true,
       borderColor: 'rgb(54, 162, 235)',
       borderWidth: 1,
       backgroundColor: 'rgba(54, 162, 235, 0.3)'
@@ -72,7 +72,7 @@ const zoomOptions = {
 };
 // </block:zoom>
 
-const zoomStatus = () => zoomOptions.zoom.enabled ? 'enabled' : 'disabled';
+const zoomStatus = () => zoomOptions.zoom.drag.enabled ? 'enabled' : 'disabled';
 
 // <block:config:1>
 const config = {
@@ -96,7 +96,7 @@ const actions = [
   {
     name: 'Toggle zoom',
     handler(chart) {
-      zoomOptions.zoom.enabled = !zoomOptions.zoom.enabled;
+      zoomOptions.zoom.drag.enabled = !zoomOptions.zoom.drag.enabled;
       chart.update();
     }
   }, {
diff --git a/docs/samples/drag/log.md b/docs/samples/drag/log.md
index 0a02b8a..0459059 100644
--- a/docs/samples/drag/log.md
+++ b/docs/samples/drag/log.md
@@ -146,8 +146,9 @@ const config = {
           modifierKey: 'ctrl',
         },
         zoom: {
-          enabled: true,
-          drag: true,
+          drag: {
+            enabled: true
+          },
           mode: 'xy',
         },
       }
diff --git a/docs/samples/drag/time.md b/docs/samples/drag/time.md
index 0714faf..ce4bf86 100644
--- a/docs/samples/drag/time.md
+++ b/docs/samples/drag/time.md
@@ -60,15 +60,16 @@ const zoomOptions = {
     modifierKey: 'ctrl',
   },
   zoom: {
-    enabled: true,
-    drag: true,
+    drag: {
+      enabled: true
+    },
     mode: 'xy',
   },
 };
 // </block>
 
 const panStatus = () => zoomOptions.pan.enabled ? 'enabled' : 'disabled';
-const zoomStatus = () => zoomOptions.zoom.enabled ? 'enabled' : 'disabled';
+const zoomStatus = () => zoomOptions.zoom.drag.enabled ? 'enabled' : 'disabled';
 
 // <block:config:1>
 const config = {
@@ -92,7 +93,7 @@ const actions = [
   {
     name: 'Toggle zoom',
     handler(chart) {
-      zoomOptions.zoom.enabled = !zoomOptions.zoom.enabled;
+      zoomOptions.zoom.drag.enabled = !zoomOptions.zoom.drag.enabled;
       chart.update();
     }
   }, {
diff --git a/docs/samples/drag/timeseries.md b/docs/samples/drag/timeseries.md
index 43b1766..bf660ff 100644
--- a/docs/samples/drag/timeseries.md
+++ b/docs/samples/drag/timeseries.md
@@ -63,15 +63,16 @@ const zoomOptions = {
     modifierKey: 'ctrl',
   },
   zoom: {
-    enabled: true,
-    drag: true,
+    drag: {
+      enabled: true,
+    },
     mode: 'xy',
   },
 };
 // </block>
 
 const panStatus = () => zoomOptions.pan.enabled ? 'enabled' : 'disabled';
-const zoomStatus = () => zoomOptions.zoom.enabled ? 'enabled' : 'disabled';
+const zoomStatus = () => zoomOptions.zoom.drag.enabled ? 'enabled' : 'disabled';
 
 // <block:config:1>
 const config = {
@@ -95,7 +96,7 @@ const actions = [
   {
     name: 'Toggle zoom',
     handler(chart) {
-      zoomOptions.zoom.enabled = !zoomOptions.zoom.enabled;
+      zoomOptions.zoom.drag.enabled = !zoomOptions.zoom.drag.enabled;
       chart.update();
     }
   }, {
diff --git a/docs/samples/pan-region.md b/docs/samples/pan-region.md
index e4a5814..93a69d3 100644
--- a/docs/samples/pan-region.md
+++ b/docs/samples/pan-region.md
@@ -71,7 +71,12 @@ const zoomOptions = {
     mode: 'xy',
   },
   zoom: {
-    enabled: false,
+    wheel: {
+      enabled: false,
+    },
+    pinch: {
+      enabled: true
+    },
   }
 };
 // </block:zoom>
diff --git a/docs/samples/wheel/category.md b/docs/samples/wheel/category.md
index c6e10f5..fd7e92a 100644
--- a/docs/samples/wheel/category.md
+++ b/docs/samples/wheel/category.md
@@ -63,7 +63,12 @@ const config = {
           threshold: 5,
         },
         zoom: {
-          enabled: true,
+          wheel: {
+            enabled: true
+          },
+          pinch: {
+            enabled: true
+          },
           mode: 'xy',
         },
       }
diff --git a/docs/samples/wheel/click-zoom.md b/docs/samples/wheel/click-zoom.md
index 5f1c9a5..512e3de 100644
--- a/docs/samples/wheel/click-zoom.md
+++ b/docs/samples/wheel/click-zoom.md
@@ -57,7 +57,12 @@ const zoomOptions = {
     mode: 'xy',
   },
   zoom: {
-    enabled: false,
+    wheel: {
+      enabled: false,
+    },
+    pinch: {
+      enabled: false
+    },
     mode: 'xy',
   }
 };
@@ -97,7 +102,8 @@ const config = {
     },
     onClick(e) {
       const chart = e.chart;
-      chart.options.plugins.zoom.zoom.enabled = !chart.options.plugins.zoom.zoom.enabled;
+      chart.options.plugins.zoom.zoom.wheel.enabled = !chart.options.plugins.zoom.zoom.wheel.enabled;
+      chart.options.plugins.zoom.zoom.pinch.enabled = !chart.options.plugins.zoom.zoom.pinch.enabled;
       chart.update();
     }
   },
@@ -117,7 +123,7 @@ const actions = [
   }, {
     name: 'Toggle zoom',
     handler(chart) {
-      zoomOptions.zoom.enabled = !zoomOptions.zoom.enabled;
+      zoomOptions.zoom.wheel.enabled = !zoomOptions.zoom.wheel.enabled;
       chart.update();
     }
   }, {
diff --git a/docs/samples/wheel/log.md b/docs/samples/wheel/log.md
index b295716..9e9af4e 100644
--- a/docs/samples/wheel/log.md
+++ b/docs/samples/wheel/log.md
@@ -147,7 +147,12 @@ const config = {
           mode: 'xy',
         },
         zoom: {
-          enabled: true,
+          wheel: {
+            enabled: true
+          },
+          pinch: {
+            enabled: true,
+          },
           mode: 'xy',
         },
       }
diff --git a/docs/samples/wheel/over-scale-mode.md b/docs/samples/wheel/over-scale-mode.md
index 9623a7b..d3b707d 100644
--- a/docs/samples/wheel/over-scale-mode.md
+++ b/docs/samples/wheel/over-scale-mode.md
@@ -55,7 +55,12 @@ Object.keys(scales).forEach(scale => Object.assign(scales[scale], scaleOpts));
 // <block:zoom:0>
 const zoomOptions = {
   zoom: {
-    enabled: true,
+    wheel: {
+      enabled: true,
+    },
+    pinch: {
+      enabled: true,
+    },
     mode: 'xy',
     overScaleMode: 'xy',
   },
@@ -68,7 +73,7 @@ const zoomOptions = {
 // </block>
 
 const panStatus = () => zoomOptions.pan.enabled ? 'enabled' : 'disabled';
-const zoomStatus = () => zoomOptions.zoom.enabled ? 'enabled' : 'disabled';
+const zoomStatus = () => zoomOptions.zoom.wheel.enabled ? 'enabled' : 'disabled';
 
 // <block:config:1>
 const config = {
@@ -92,7 +97,8 @@ const actions = [
   {
     name: 'Toggle zoom',
     handler(chart) {
-      zoomOptions.zoom.enabled = !zoomOptions.zoom.enabled;
+      zoomOptions.zoom.wheel.enabled = !zoomOptions.zoom.wheel.enabled;
+      zoomOptions.zoom.pinch.enabled = !zoomOptions.zoom.pinch.enabled;
       chart.update();
     }
   }, {
diff --git a/docs/samples/wheel/time.md b/docs/samples/wheel/time.md
index 3e55113..5636554 100644
--- a/docs/samples/wheel/time.md
+++ b/docs/samples/wheel/time.md
@@ -54,7 +54,12 @@ const scales = {
 // <block:zoom:0>
 const zoomOptions = {
   zoom: {
-    enabled: true,
+    wheel: {
+      enabled: true,
+    },
+    pinch: {
+      enabled: true,
+    },
     mode: 'xy',
   },
   pan: {
@@ -65,7 +70,7 @@ const zoomOptions = {
 // </block>
 
 const panStatus = () => zoomOptions.pan.enabled ? 'enabled' : 'disabled';
-const zoomStatus = () => zoomOptions.zoom.enabled ? 'enabled' : 'disabled';
+const zoomStatus = () => zoomOptions.zoom.wheel.enabled ? 'enabled' : 'disabled';
 
 // <block:config:1>
 const config = {
@@ -92,7 +97,8 @@ const actions = [
   {
     name: 'Toggle zoom',
     handler(chart) {
-      zoomOptions.zoom.enabled = !zoomOptions.zoom.enabled;
+      zoomOptions.zoom.wheel.enabled = !zoomOptions.zoom.wheel.enabled;
+      zoomOptions.zoom.pinch.enabled = !zoomOptions.zoom.pinch.enabled;
       chart.update();
     }
   }, {
diff --git a/samples/zoom-separately.html b/samples/zoom-separately.html
index d83257b..84e2ca0 100644
--- a/samples/zoom-separately.html
+++ b/samples/zoom-separately.html
@@ -104,7 +104,12 @@
 								overScaleMode: 'y'
 							},
 							zoom: {
-								enabled: true,
+								wheel: {
+									enabled: true,
+								},
+								pinch: {
+									enabled: true,
+								},
 								mode: 'xy',
 								overScaleMode: 'y'
 							}
diff --git a/src/hammer.js b/src/hammer.js
index 78f223c..004bf4c 100644
--- a/src/hammer.js
+++ b/src/hammer.js
@@ -67,7 +67,7 @@ function handlePinch(chart, state, e) {
 }
 
 function startPinch(chart, state) {
-  if (state.options.zoom.enabled) {
+  if (state.options.zoom.pinch.enabled) {
     state.scale = 1;
   }
 }
@@ -125,7 +125,7 @@ export function startHammer(chart, options) {
   const {pan: panOptions, zoom: zoomOptions} = options;
 
   const mc = new Hammer.Manager(canvas);
-  if (zoomOptions && zoomOptions.enabled) {
+  if (zoomOptions && zoomOptions.pinch.enabled) {
     mc.add(new Hammer.Pinch());
     mc.on('pinchstart', () => startPinch(chart, state));
     mc.on('pinch', (e) => handlePinch(chart, state, e));
diff --git a/src/handlers.js b/src/handlers.js
index 37440e5..e960234 100644
--- a/src/handlers.js
+++ b/src/handlers.js
@@ -103,7 +103,7 @@ export function mouseUp(chart, event) {
   // Remove drag start and end before chart update to stop drawing selected area
   state.dragStart = state.dragEnd = null;
 
-  const zoomThreshold = zoomOptions.threshold || 0;
+  const zoomThreshold = zoomOptions.drag.threshold || 0;
   if (dragDistanceX <= zoomThreshold && dragDistanceY <= zoomThreshold) {
     return;
   }
@@ -115,9 +115,9 @@ export function mouseUp(chart, event) {
 }
 
 function wheelPreconditions(chart, event, zoomOptions) {
-  const {wheelModifierKey, onZoomRejected} = zoomOptions;
+  const {wheel: wheelOptions, onZoomRejected} = zoomOptions;
   // Before preventDefault, check if the modifier key required and pressed
-  if (wheelModifierKey && !event[wheelModifierKey + 'Key']) {
+  if (wheelOptions.modifierKey && !event[wheelOptions.modifierKey + 'Key']) {
     call(onZoomRejected, [{chart, event}]);
     return;
   }
@@ -147,7 +147,7 @@ export function wheel(chart, event) {
   }
 
   const rect = event.target.getBoundingClientRect();
-  const speed = 1 + (event.deltaY >= 0 ? -zoomOptions.speed : zoomOptions.speed);
+  const speed = 1 + (event.deltaY >= 0 ? -zoomOptions.wheel.speed : zoomOptions.wheel.speed);
   const amount = {
     x: speed,
     y: speed,
@@ -172,18 +172,18 @@ function addDebouncedHandler(chart, name, handler, delay) {
 
 export function addListeners(chart, options) {
   const canvas = chart.canvas;
-  const {enabled: zoomEnabled, drag: dragEnabled, onZoomComplete} = options.zoom;
+  const {wheel: wheelOptions, drag: dragOptions, onZoomComplete} = options.zoom;
 
   // Install listeners. Do this dynamically based on options so that we can turn zoom on and off
   // We also want to make sure listeners aren't always on. E.g. if you're scrolling down a page
   // and the mouse goes over a chart you don't want it intercepted unless the plugin is enabled
-  if (zoomEnabled && !dragEnabled) {
+  if (wheelOptions.enabled) {
     addHandler(chart, canvas, 'wheel', wheel);
     addDebouncedHandler(chart, 'onZoomComplete', onZoomComplete, 250);
   } else {
     removeHandler(chart, canvas, 'wheel');
   }
-  if (zoomEnabled && dragEnabled) {
+  if (dragOptions.enabled) {
     addHandler(chart, canvas, 'mousedown', mouseDown);
     addHandler(chart, canvas.ownerDocument, 'mouseup', mouseUp);
   } else {
diff --git a/src/plugin.js b/src/plugin.js
index 6895f04..bbabfbb 100644
--- a/src/plugin.js
+++ b/src/plugin.js
@@ -19,10 +19,18 @@ export default {
       modifierKey: null,
     },
     zoom: {
-      enabled: false,
+      wheel: {
+        enabled: false,
+        speed: 0.1,
+        modifierKey: null
+      },
+      drag: {
+        enabled: false
+      },
+      pinch: {
+        enabled: false
+      },
       mode: 'xy',
-      speed: 0.1,
-      wheelModifierKey: null
     }
   },
 
@@ -30,6 +38,10 @@ export default {
     const state = getState(chart);
     state.options = options;
 
+    if (Object.prototype.hasOwnProperty.call(options.zoom, 'enabled')) {
+      console.warn('The option `zoom.enabled` is no longer supported. Please use `zoom.wheel.enabled`, `zoom.drag.enabled`, or `zoom.pinch.enabled`.');
+    }
+
     if (Hammer) {
       startHammer(chart, options);
     }
diff --git a/types/options.d.ts b/types/options.d.ts
index 1ecac96..e25ef80 100644
--- a/types/options.d.ts
+++ b/types/options.d.ts
@@ -4,27 +4,62 @@ import { Chart, Color, Point } from 'chart.js';
 type Mode = 'x' | 'y' | 'xy';
 type Key = 'ctrl' | 'alt' | 'shift' | 'meta';
 
-export interface DragEffectOptions {
-  borderColor?: Color;
-  borderWidth?: number;
-  backgroundColor?: Color;
+export interface WheelOptions {
+  /**
+   * Enable the zoom via mouse wheel
+   */
+  enabled?: boolean;
+
+  /**
+   * Speed of zoom via mouse wheel
+   * (percentage of zoom on a wheel event)
+   */
+  speed?: number;
+
+  /**
+   * Modifier key required for zooming with mouse
+   */
+  modifierKey?: Key;
 }
 
-/**
- * Container for zoop options
- */
-export interface ZoomOptions {
+export interface DragOptions {
   /**
-   * Boolean to enable zooming
+   * Enable the zoom via drag
    */
   enabled?: boolean;
 
   /**
-   * Enable drag-to-zoom behavior
-   **/
-  drag?: boolean | DragEffectOptions;
+   * Minimal zoom distance required before actually applying zoom
+   */
+  threshold?: number;
 
+  /**
+   * Border color of the drag area
+   */
+  borderColor?: Color;
 
+  /**
+   * Border width of the drag area
+   */
+  borderWidth?: number;
+
+  /**
+   * Background color of the drag area
+   */
+  backgroundColor?: Color;
+}
+
+export interface PinchOptions {
+  /**
+   * Enable the zoom via pinch
+   */
+  enabled?: boolean;
+}
+
+/**
+ * Container for zoop options
+ */
+export interface ZoomOptions {
   /**
    * Zooming directions. Remove the appropriate direction to disable
    * Eg. 'y' would only allow zooming in the y direction
@@ -34,25 +69,24 @@ export interface ZoomOptions {
    *      return 'xy';
    *    },
    */
-  mode?: Mode | { (char: Chart): Mode };
-
-  overScaleMode?: Mode | { (char: Chart): Mode };
+  mode?: Mode | { (chart: Chart): Mode };
 
   /**
-   * Speed of zoom via mouse wheel
-   * (percentage of zoom on a wheel event)
+   * Options of the mouse wheel mode
    */
-  speed?: number;
+  wheel?: WheelOptions;
 
   /**
-   * Minimal zoom distance required before actually applying zoom
+   * Options of the drag-to-zoom mode
    */
-  threshold?: number;
+  drag?: DragOptions;
 
   /**
-   * Modifier key required for zooming with mouse
+   * Options of the pinch mode
    */
-  wheelModifierKey?: Key;
+  pinch?: PinchOptions;
+
+  overScaleMode?: Mode | { (chart: Chart): Mode };
 
   /**
    * Function called while the user is zooming


Test patch:
diff --git a/test/fixtures/zoom/category-x.js b/test/fixtures/zoom/category-x.js
index 91777b4..221527f 100644
--- a/test/fixtures/zoom/category-x.js
+++ b/test/fixtures/zoom/category-x.js
@@ -31,7 +31,9 @@ module.exports = {
         legend: false,
         zoom: {
           zoom: {
-            enabled: true,
+            wheel: {
+              enabled: true,
+            },
             mode: 'x',
           }
         }
diff --git a/test/fixtures/zoom/drag.js b/test/fixtures/zoom/drag.js
index cf384c0..cad22e0 100644
--- a/test/fixtures/zoom/drag.js
+++ b/test/fixtures/zoom/drag.js
@@ -22,8 +22,8 @@ module.exports = {
         legend: false,
         zoom: {
           zoom: {
-            enabled: true,
             drag: {
+              enabled: true,
               backgroundColor: 'yellow',
               borderColor: 'black',
               borderWidth: 1
diff --git a/test/fixtures/zoom/zoom-reset.js b/test/fixtures/zoom/zoom-reset.js
index f69ac48..2da5b8f 100644
--- a/test/fixtures/zoom/zoom-reset.js
+++ b/test/fixtures/zoom/zoom-reset.js
@@ -31,7 +31,9 @@ module.exports = {
         legend: false,
         zoom: {
           zoom: {
-            enabled: true,
+            wheel: {
+              enabled: true
+            },
             mode: 'x',
           }
         }
diff --git a/test/specs/defaults.spec.js b/test/specs/defaults.spec.js
index cce2ca2..066f387 100644
--- a/test/specs/defaults.spec.js
+++ b/test/specs/defaults.spec.js
@@ -7,10 +7,18 @@ describe('defaults', function() {
       modifierKey: null,
     },
     zoom: {
-      enabled: false,
-      mode: 'xy',
-      speed: 0.1,
-      wheelModifierKey: null
+      wheel: {
+        enabled: false,
+        speed: 0.1,
+        modifierKey: null
+      },
+      drag: {
+        enabled: false
+      },
+      pinch: {
+        enabled: false
+      },
+      mode: 'xy'
     }
   };
 
diff --git a/test/specs/zoom.spec.js b/test/specs/zoom.spec.js
index cabe6d0..f8c58ba 100644
--- a/test/specs/zoom.spec.js
+++ b/test/specs/zoom.spec.js
@@ -38,8 +38,9 @@ describe('zoom', function() {
             plugins: {
               zoom: {
                 zoom: {
-                  enabled: true,
-                  drag: true,
+                  drag: {
+                    enabled: true
+                  },
                   mode: 'x'
                 }
               }
@@ -83,8 +84,9 @@ describe('zoom', function() {
             plugins: {
               zoom: {
                 zoom: {
-                  enabled: true,
-                  drag: true,
+                  drag: {
+                    enabled: true
+                  },
                   mode: function() {
                     return 'x';
                   }
@@ -130,8 +132,9 @@ describe('zoom', function() {
             plugins: {
               zoom: {
                 zoom: {
-                  enabled: true,
-                  drag: true,
+                  drag: {
+                    enabled: true
+                  },
                   mode: 'y'
                 }
               }
@@ -175,8 +178,9 @@ describe('zoom', function() {
             plugins: {
               zoom: {
                 zoom: {
-                  enabled: true,
-                  drag: true,
+                  drag: {
+                    enabled: true
+                  },
                   mode: function() {
                     return 'y';
                   }
@@ -222,8 +226,9 @@ describe('zoom', function() {
             plugins: {
               zoom: {
                 zoom: {
-                  enabled: true,
-                  drag: true,
+                  drag: {
+                    enabled: true
+                  },
                   mode: 'xy'
                 }
               }
@@ -251,7 +256,7 @@ describe('zoom', function() {
     });
   });
 
-  describe('with wheelModifierKey', function() {
+  describe('with modifierKey', function() {
     for (const key of ['ctrl', 'alt', 'shift', 'meta']) {
       for (const pressed of [true, false]) {
         let chart, scaleX, scaleY;
@@ -274,9 +279,11 @@ describe('zoom', function() {
               plugins: {
                 zoom: {
                   zoom: {
-                    enabled: true,
+                    wheel: {
+                      enabled: true,
+                      modifierKey: key,
+                    },
                     mode: 'x',
-                    wheelModifierKey: key,
                     onZoomRejected: rejectedSpy
                   }
                 }
@@ -342,8 +349,9 @@ describe('zoom', function() {
                     modifierKey: key,
                   },
                   zoom: {
-                    enabled: true,
-                    drag: true,
+                    drag: {
+                      enabled: true,
+                    },
                     mode: 'x',
                     onZoomRejected: rejectedSpy
                   }
@@ -406,7 +414,9 @@ describe('zoom', function() {
         plugins: {
           zoom: {
             zoom: {
-              enabled: true,
+              wheel: {
+                enabled: true,
+              },
               mode: 'xy',
               overScaleMode: 'y'
             }
@@ -481,8 +491,9 @@ describe('zoom', function() {
             plugins: {
               zoom: {
                 zoom: {
-                  enabled: true,
-                  drag: false,
+                  wheel: {
+                    enabled: true,
+                  },
                   mode: 'xy',
                   onZoomStart: startSpy
                 }
@@ -509,8 +520,9 @@ describe('zoom', function() {
             plugins: {
               zoom: {
                 zoom: {
-                  enabled: true,
-                  drag: false,
+                  wheel: {
+                    enabled: true,
+                  },
                   mode: 'xy',
                   onZoomStart: () => false,
                   onZoomRejected: rejectSpy
@@ -537,7 +549,9 @@ describe('zoom', function() {
             plugins: {
               zoom: {
                 zoom: {
-                  enabled: true,
+                  wheel: {
+                    enabled: true,
+                  },
                   mode: 'xy',
                   onZoomComplete(ctx) {
                     expect(ctx.chart.scales.x.min).not.toBe(1);
@@ -568,8 +582,9 @@ describe('zoom', function() {
             plugins: {
               zoom: {
                 zoom: {
-                  enabled: true,
-                  drag: true,
+                  drag: {
+                    enabled: true,
+                  },
                   mode: 'xy',
                   onZoomStart: startSpy,
                   onZoom: zoomSpy,
@@ -605,8 +620,9 @@ describe('zoom', function() {
             plugins: {
               zoom: {
                 zoom: {
-                  enabled: true,
-                  drag: true,
+                  drag: {
+                    enabled: true,
+                  },
                   mode: 'xy',
                   onZoomStart: () => false,
                   onZoom: zoomSpy,
@@ -655,7 +671,9 @@ describe('zoom', function() {
           plugins: {
             zoom: {
               zoom: {
-                enabled: true
+                wheel: {
+                  enabled: true,
+                },
               }
             }
           }
@@ -704,7 +722,9 @@ describe('zoom', function() {
                 }
               },
               zoom: {
-                enabled: true,
+                wheel: {
+                  enabled: true,
+                },
                 mode: 'y'
               }
             }
diff --git a/types/tests/exports.ts b/types/tests/exports.ts
index ce92307..567ab69 100644
--- a/types/tests/exports.ts
+++ b/types/tests/exports.ts
@@ -32,9 +32,10 @@ const chart = new Chart('id', {
           mode: 'x'
         },
         zoom: {
-          enabled: true,
+          wheel: {
+            enabled: true
+          },
           mode: 'x',
-
         }
       },
     }