diff --git a/src/component/dataZoom/InsideZoomModel.ts b/src/component/dataZoom/InsideZoomModel.ts index ad417afc87..c5899dd7c2 100644 --- a/src/component/dataZoom/InsideZoomModel.ts +++ b/src/component/dataZoom/InsideZoomModel.ts @@ -20,6 +20,12 @@ import DataZoomModel, {DataZoomOption} from './DataZoomModel'; import { inheritDefaultOption } from '../../util/component'; +export interface NatureMoveOnMouseWheelOpt { + windowScrollSpeedFactor?: number + zoomFactor?: number + wheelZoomSpeed?: number +} + export interface InsideDataZoomOption extends DataZoomOption { /** @@ -38,6 +44,12 @@ export interface InsideDataZoomOption extends DataZoomOption { moveOnMouseWheel?: boolean | 'shift' | 'ctrl' | 'alt' + /** + * Whether enable touchpad, if open this, + * other options such as `zoomOnMouseWheel` `moveOnMouseMove` will be ignored. + */ + natureMoveOnMouseWheel?: boolean | NatureMoveOnMouseWheelOpt + preventDefaultMouseMove?: boolean /** diff --git a/src/component/dataZoom/roams.ts b/src/component/dataZoom/roams.ts index d33e1e287a..ef49cd4c76 100644 --- a/src/component/dataZoom/roams.ts +++ b/src/component/dataZoom/roams.ts @@ -28,7 +28,7 @@ import * as throttleUtil from '../../util/throttle'; import { makeInner } from '../../util/model'; import { Dictionary, ZRElementEvent } from '../../util/types'; import ExtensionAPI from '../../core/ExtensionAPI'; -import InsideZoomModel from './InsideZoomModel'; +import InsideZoomModel, { NatureMoveOnMouseWheelOpt } from './InsideZoomModel'; import { each, curry, Curry1, HashMap, createHashMap } from 'zrender/src/core/util'; import { DataZoomPayloadBatchItem, collectReferCoordSysModelInfo, @@ -126,7 +126,7 @@ function createCoordSysRecord(api: ExtensionAPI, coordSysModel: CoordinateSystem const batch: DataZoomPayloadBatchItem[] = []; coordSysRecord.dataZoomInfoMap.each(function (dzInfo) { - // Check whether the behaviors (zoomOnMouseWheel, moveOnMouseMove, + // Check whether the behaviors (zoomOnMouseWheel, moveOnMouseMove, // moveOnMouseWheel, ...) enabled. if (!event.isAvailableBehavior(dzInfo.model.option)) { return; @@ -191,9 +191,10 @@ function mergeControllerParams(dataZoomInfoMap: HashMap<{ model: InsideZoomModel 'type_undefined': -1 }; let preventDefaultMouseMove = true; - + let natureMoveOnMouseWheel: boolean | NatureMoveOnMouseWheelOpt = false; dataZoomInfoMap.each(function (dataZoomInfo) { const dataZoomModel = dataZoomInfo.model; + natureMoveOnMouseWheel = natureMoveOnMouseWheel || dataZoomModel.get('natureMoveOnMouseWheel'); const oneType = dataZoomModel.get('disabled', true) ? false : dataZoomModel.get('zoomLock', true) @@ -218,7 +219,8 @@ function mergeControllerParams(dataZoomInfoMap: HashMap<{ model: InsideZoomModel zoomOnMouseWheel: true, moveOnMouseMove: true, moveOnMouseWheel: true, - preventDefaultMouseMove: !!preventDefaultMouseMove + preventDefaultMouseMove: !!preventDefaultMouseMove, + natureMoveOnMouseWheel } }; } @@ -242,7 +244,6 @@ export function installDataZoomRoamProcessor(registers: EChartsExtensionInstallR { mainType: 'dataZoom', subType: 'inside' }, function (dataZoomModel: InsideZoomModel) { const dzReferCoordSysWrap = collectReferCoordSysModelInfo(dataZoomModel); - each(dzReferCoordSysWrap.infoList, function (dzCoordSysInfo) { const coordSysUid = dzCoordSysInfo.model.uid; @@ -279,7 +280,6 @@ export function installDataZoomRoamProcessor(registers: EChartsExtensionInstallR disposeCoordSysRecord(coordSysRecordMap, coordSysRecord); return; } - const controllerParams = mergeControllerParams(dataZoomInfoMap); controller.enable(controllerParams.controlType, controllerParams.opt); diff --git a/src/component/helper/RoamController.ts b/src/component/helper/RoamController.ts index 874865ebee..972c801cb5 100644 --- a/src/component/helper/RoamController.ts +++ b/src/component/helper/RoamController.ts @@ -24,6 +24,7 @@ import { ZRenderType } from 'zrender/src/zrender'; import { ZRElementEvent, RoamOptionMixin } from '../../util/types'; import { Bind3, isString, bind, defaults, clone } from 'zrender/src/core/util'; import Group from 'zrender/src/graphic/Group'; +import { NatureMoveOnMouseWheelOpt } from '../dataZoom/InsideZoomModel'; // Can be null/undefined or true/false // or 'pan/move' or 'zoom'/'scale' @@ -37,6 +38,12 @@ interface RoamOption { * If fixed the page when pan */ preventDefaultMouseMove?: boolean + + /** + * Whether enable touchpad, if open this, + * other options such as `zoomOnMouseWheel` `moveOnMouseMove` will be ignored. + */ + natureMoveOnMouseWheel?: boolean | NatureMoveOnMouseWheelOpt } type RoamEventType = keyof RoamEventParams; @@ -63,6 +70,8 @@ export interface RoamEventParams { dy: number oldX: number oldY: number + originX?: number + originY?: number newX: number newY: number @@ -120,7 +129,6 @@ class RoamController extends Eventful<{ * default mousewheel behaviour (scroll page) will be disabled. */ this.enable = function (controlType, opt) { - // Disable previous first this.disable(); @@ -129,7 +137,8 @@ class RoamController extends Eventful<{ moveOnMouseMove: true, // By default, wheel do not trigger move. moveOnMouseWheel: false, - preventDefaultMouseMove: true + preventDefaultMouseMove: true, + natureMoveOnMouseWheel: false }); if (controlType == null) { @@ -235,6 +244,7 @@ class RoamController extends Eventful<{ private _mousewheelHandler(e: ZRElementEvent) { const shouldZoom = isAvailableBehavior('zoomOnMouseWheel', e, this._opt); const shouldMove = isAvailableBehavior('moveOnMouseWheel', e, this._opt); + const natureMoveOnMouseWheel = this._opt.natureMoveOnMouseWheel; const wheelDelta = e.wheelDelta; const absWheelDeltaDelta = Math.abs(wheelDelta); const originX = e.offsetX; @@ -248,7 +258,49 @@ class RoamController extends Eventful<{ // If both `shouldZoom` and `shouldMove` is true, trigger // their event both, and the final behavior is determined // by event listener themselves. + if (natureMoveOnMouseWheel) { + let windowScrollSpeedFactor = 1; + let zoomFactor = 1.2; + let wheelZoomSpeed = 2 / 23; + if (typeof natureMoveOnMouseWheel === 'object') { + windowScrollSpeedFactor = natureMoveOnMouseWheel.windowScrollSpeedFactor || windowScrollSpeedFactor; + zoomFactor = natureMoveOnMouseWheel.zoomFactor || zoomFactor; + wheelZoomSpeed = natureMoveOnMouseWheel.wheelZoomSpeed || wheelZoomSpeed; + } + // FIXME zrender type error + const wheelEvent = e.event as unknown as WheelEvent; + if (wheelEvent.ctrlKey) { + shouldZoom && checkPointerAndTrigger(this, 'zoom', 'zoomOnMouseWheel', e, { + scale: 1 / Math.pow(zoomFactor, wheelEvent.deltaY * wheelZoomSpeed), + originX, + originY, + isAvailableBehavior: null + }); + } + else { + let offsetY = 0; + let offsetX = 0; + if (wheelEvent.deltaY) { + offsetY = Math.round(wheelEvent.deltaY * windowScrollSpeedFactor); + } + if (wheelEvent.deltaX) { + offsetX = Math.round(wheelEvent.deltaX * windowScrollSpeedFactor); + } + shouldMove && checkPointerAndTrigger(this, 'pan', 'moveOnMouseMove', e, { + originX, + originY, + oldX: originX, + oldY: originY, + dx: -offsetX, + dy: -offsetY, + newX: originX - offsetX, + newY: originY - offsetY, + isAvailableBehavior: null + } as RoamEventParams['pan']); + } + return; + } if (shouldZoom) { // Convenience: // Mac and VM Windows on Mac: scroll up: zoom out. @@ -289,7 +341,7 @@ class RoamController extends Eventful<{ } -function checkPointerAndTrigger( +function checkPointerAndTrigger( controller: RoamController, eventName: T, behaviorToCheck: RoamBehavior, diff --git a/test/gesture.html b/test/gesture.html new file mode 100644 index 0000000000..15464808a8 --- /dev/null +++ b/test/gesture.html @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + +
+ + + \ No newline at end of file