Skip to content

Commit

Permalink
Changed scroll wheel behavior
Browse files Browse the repository at this point in the history
Vertical wheel now zooms. Horizontal wheel pans. (Vertical wheel with shift zooms.)

Wheel events of any kind clear the current tooltip as well.
  • Loading branch information
Brian Vaughn committed Jul 30, 2021
1 parent 216f4cd commit b7e66ec
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 64 deletions.
33 changes: 33 additions & 0 deletions packages/react-devtools-scheduling-profiler/src/CanvasPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,39 @@ function AutoSizedCanvas({data, height, width}: AutoSizedCanvasProps) {
return;
}

// Wheel events should always hide the current toolltip.
switch (interaction.type) {
case 'wheel-control':
case 'wheel-meta':
case 'wheel-plain':
case 'wheel-shift':
setHoveredEvent(prevHoverEvent => {
if (prevHoverEvent === null) {
return prevHoverEvent;
} else if (
prevHoverEvent.flamechartStackFrame !== null ||
prevHoverEvent.measure !== null ||
prevHoverEvent.nativeEvent !== null ||
prevHoverEvent.schedulingEvent !== null ||
prevHoverEvent.suspenseEvent !== null ||
prevHoverEvent.userTimingMark !== null
) {
return {
data: prevHoverEvent.data,
flamechartStackFrame: null,
measure: null,
nativeEvent: null,
schedulingEvent: null,
suspenseEvent: null,
userTimingMark: null,
};
} else {
return prevHoverEvent;
}
});
break;
}

const surface = surfaceRef.current;
surface.handleInteraction(interaction);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import type {
MouseUpInteraction,
WheelPlainInteraction,
WheelWithShiftInteraction,
WheelWithControlInteraction,
WheelWithMetaInteraction,
} from './useCanvasInteraction';
import type {Rect} from './geometry';
import type {ScrollState} from './utils/scrollState';
Expand Down Expand Up @@ -202,7 +200,7 @@ export class HorizontalPanAndZoomView extends View {
}
}

_handleWheelPlain(interaction: WheelPlainInteraction) {
_handleWheel(interaction: WheelPlainInteraction | WheelWithShiftInteraction) {
const {
location,
delta: {deltaX, deltaY},
Expand All @@ -214,51 +212,41 @@ export class HorizontalPanAndZoomView extends View {

const absDeltaX = Math.abs(deltaX);
const absDeltaY = Math.abs(deltaY);
if (absDeltaY > absDeltaX) {
return; // Scrolling vertically
}
if (absDeltaX < MOVE_WHEEL_DELTA_THRESHOLD) {
return;
}

const newState = translateState({
state: this._scrollState,
delta: -deltaX,
containerLength: this.frame.size.width,
});
this._setStateAndInformCallbacksIfChanged(newState);
}

_handleWheelZoom(
interaction:
| WheelWithShiftInteraction
| WheelWithControlInteraction
| WheelWithMetaInteraction,
) {
const {
location,
delta: {deltaY},
} = interaction.payload;

if (!rectContainsPoint(location, this.frame)) {
return; // Not scrolling on view
}

const absDeltaY = Math.abs(deltaY);
if (absDeltaY < MOVE_WHEEL_DELTA_THRESHOLD) {
return;
// Vertical scrolling zooms in and out (unless the SHIFT modifier is used).
// Horizontal scrolling pans.
if (absDeltaY > absDeltaX) {
if (absDeltaY < MOVE_WHEEL_DELTA_THRESHOLD) {
return;
}

if (interaction.type === 'wheel-shift') {
// Shift modifier is for scrolling, not zooming.
return;
}

const newState = zoomState({
state: this._scrollState,
multiplier: 1 + 0.005 * -deltaY,
fixedPoint: location.x - this._scrollState.offset,

minContentLength: this._intrinsicContentWidth * MIN_ZOOM_LEVEL,
maxContentLength: this._intrinsicContentWidth * MAX_ZOOM_LEVEL,
containerLength: this.frame.size.width,
});
this._setStateAndInformCallbacksIfChanged(newState);
} else {
if (absDeltaX < MOVE_WHEEL_DELTA_THRESHOLD) {
return;
}

const newState = translateState({
state: this._scrollState,
delta: -deltaX,
containerLength: this.frame.size.width,
});
this._setStateAndInformCallbacksIfChanged(newState);
}

const newState = zoomState({
state: this._scrollState,
multiplier: 1 + 0.005 * -deltaY,
fixedPoint: location.x - this._scrollState.offset,

minContentLength: this._intrinsicContentWidth * MIN_ZOOM_LEVEL,
maxContentLength: this._intrinsicContentWidth * MAX_ZOOM_LEVEL,
containerLength: this.frame.size.width,
});
this._setStateAndInformCallbacksIfChanged(newState);
}

handleInteraction(interaction: Interaction, viewRefs: ViewRefs) {
Expand All @@ -273,12 +261,8 @@ export class HorizontalPanAndZoomView extends View {
this._handleMouseUp(interaction, viewRefs);
break;
case 'wheel-plain':
this._handleWheelPlain(interaction);
break;
case 'wheel-shift':
case 'wheel-control':
case 'wheel-meta':
this._handleWheelZoom(interaction);
this._handleWheel(interaction);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@ class ResizeBar extends View {

export class ResizableView extends View {
_canvasRef: {current: HTMLCanvasElement | null};
_didDrag: boolean = false;
_layoutState: LayoutState;
_resizeBar: ResizeBar;
_resizingState: ResizingState | null = null;
Expand Down Expand Up @@ -327,11 +326,6 @@ export class ResizableView extends View {
}

_handleClick(interaction: ClickInteraction) {
if (this._didDrag) {
// Ignore click events that come after drag-to-resize.
return;
}

const cursorInView = rectContainsPoint(
interaction.payload.location,
this.frame,
Expand Down Expand Up @@ -364,7 +358,6 @@ export class ResizableView extends View {
const cursorLocation = interaction.payload.location;
const resizeBarFrame = this._resizeBar.frame;
if (rectContainsPoint(cursorLocation, resizeBarFrame)) {
this._didDrag = false;
const mouseY = cursorLocation.y;
this._resizingState = {
cursorOffsetInBarFrame: mouseY - resizeBarFrame.origin.y,
Expand All @@ -376,7 +369,6 @@ export class ResizableView extends View {
_handleMouseMove(interaction: MouseMoveInteraction) {
const {_resizingState} = this;
if (_resizingState) {
this._didDrag = true;
this._resizingState = {
..._resizingState,
mouseY: interaction.payload.location.y,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type {
MouseDownInteraction,
MouseMoveInteraction,
MouseUpInteraction,
WheelPlainInteraction,
WheelWithShiftInteraction,
} from './useCanvasInteraction';
import type {Rect} from './geometry';
import type {ScrollState} from './utils/scrollState';
Expand Down Expand Up @@ -157,7 +157,7 @@ export class VerticalScrollView extends View {
}
}

_handleWheelPlain(interaction: WheelPlainInteraction) {
_handleWheelShift(interaction: WheelWithShiftInteraction) {
const {
location,
delta: {deltaX, deltaY},
Expand Down Expand Up @@ -195,8 +195,8 @@ export class VerticalScrollView extends View {
case 'mouseup':
this._handleMouseUp(interaction);
break;
case 'wheel-plain':
this._handleWheelPlain(interaction);
case 'wheel-shift':
this._handleWheelShift(interaction);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import type {NormalizedWheelDelta} from './utils/normalizeWheel';
import type {Point} from './geometry';

import {useEffect} from 'react';
import {useEffect, useRef} from 'react';
import {normalizeWheel} from './utils/normalizeWheel';

export type ClickInteraction = {|
Expand Down Expand Up @@ -115,6 +115,9 @@ export function useCanvasInteraction(
canvasRef: {|current: HTMLCanvasElement | null|},
interactor: (interaction: Interaction) => void,
) {
const isMouseDownRef = useRef<boolean>(false);
const didMouseMoveWhileDownRef = useRef<boolean>(false);

useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) {
Expand All @@ -130,6 +133,10 @@ export function useCanvasInteraction(
}

const onCanvasClick: MouseEventHandler = event => {
if (didMouseMoveWhileDownRef.current) {
return;
}

interactor({
type: 'click',
payload: {
Expand All @@ -140,6 +147,10 @@ export function useCanvasInteraction(
};

const onCanvasDoubleClick: MouseEventHandler = event => {
if (didMouseMoveWhileDownRef.current) {
return;
}

interactor({
type: 'double-click',
payload: {
Expand All @@ -150,6 +161,9 @@ export function useCanvasInteraction(
};

const onCanvasMouseDown: MouseEventHandler = event => {
didMouseMoveWhileDownRef.current = false;
isMouseDownRef.current = true;

interactor({
type: 'mousedown',
payload: {
Expand All @@ -160,6 +174,10 @@ export function useCanvasInteraction(
};

const onDocumentMouseMove: MouseEventHandler = event => {
if (isMouseDownRef.current) {
didMouseMoveWhileDownRef.current = true;
}

interactor({
type: 'mousemove',
payload: {
Expand All @@ -170,6 +188,8 @@ export function useCanvasInteraction(
};

const onDocumentMouseUp: MouseEventHandler = event => {
isMouseDownRef.current = false;

interactor({
type: 'mouseup',
payload: {
Expand Down

0 comments on commit b7e66ec

Please sign in to comment.