Skip to content

Commit 494aa59

Browse files
author
Andreas Riepl
committed
feat(scroll-on-touch): use finger to scroll on canvas
1 parent fd07a3c commit 494aa59

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

src/Canvas/index.tsx

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useEffect } from "react";
12
import * as React from 'react';
23
import Paths, { SvgPath } from '../Paths';
34
import { CanvasPath, ExportImageType, Point } from '../types';
@@ -32,6 +33,7 @@ function getCanvasWithViewBox(canvas: HTMLDivElement) {
3233
export interface CanvasProps {
3334
paths: CanvasPath[];
3435
isDrawing: boolean;
36+
scrollOnTouch: boolean;
3537
onPointerDown: (point: Point) => void;
3638
onPointerMove: (point: Point) => void;
3739
onPointerUp: () => void;
@@ -57,6 +59,7 @@ export const Canvas = React.forwardRef<CanvasRef, CanvasProps>((props, ref) => {
5759
const {
5860
paths,
5961
isDrawing,
62+
scrollOnTouch,
6063
onPointerDown,
6164
onPointerMove,
6265
onPointerUp,
@@ -77,6 +80,7 @@ export const Canvas = React.forwardRef<CanvasRef, CanvasProps>((props, ref) => {
7780
} = props;
7881

7982
const canvasRef = React.useRef<HTMLDivElement>(null);
83+
const currentPointerType = React.useRef<"pen" | "mouse" | "touch" | null>(null);
8084

8185
// Converts mouse coordinates to relative coordinate based on the absolute position of svg
8286
const getCoordinates = (
@@ -104,8 +108,18 @@ export const Canvas = React.forwardRef<CanvasRef, CanvasProps>((props, ref) => {
104108
const handlePointerDown = (
105109
event: React.PointerEvent<HTMLDivElement>
106110
): void => {
107-
// Allow only chosen pointer type
111+
currentPointerType.current = event.pointerType;
108112

113+
if (scrollOnTouch && event.pointerType === "touch") {
114+
return;
115+
}
116+
117+
if (event.pointerType === 'pen') {
118+
event.preventDefault();
119+
event.stopPropagation();
120+
}
121+
122+
// Allow only chosen pointer type
109123
if (
110124
allowOnlyPointerType !== 'all' &&
111125
event.pointerType !== allowOnlyPointerType
@@ -125,6 +139,10 @@ export const Canvas = React.forwardRef<CanvasRef, CanvasProps>((props, ref) => {
125139
): void => {
126140
if (!isDrawing) return;
127141

142+
if (scrollOnTouch && event.pointerType === "touch") {
143+
return;
144+
}
145+
128146
// Allow only chosen pointer type
129147
if (
130148
allowOnlyPointerType !== 'all' &&
@@ -142,6 +160,9 @@ export const Canvas = React.forwardRef<CanvasRef, CanvasProps>((props, ref) => {
142160
event: React.PointerEvent<HTMLDivElement> | PointerEvent
143161
): void => {
144162
if (event.pointerType === 'mouse' && event.button !== 0) return;
163+
if (scrollOnTouch && event.pointerType === "touch") {
164+
return;
165+
}
145166

146167
// Allow only chosen pointer type
147168
if (
@@ -239,7 +260,7 @@ export const Canvas = React.forwardRef<CanvasRef, CanvasProps>((props, ref) => {
239260
}));
240261

241262
/* Add event listener to Mouse up and Touch up to
242-
release drawing even when point goes out of canvas */
263+
release drawing even when point goes out of canvas */
243264
React.useEffect(() => {
244265
document.addEventListener('pointerup', handlePointerUp);
245266
return () => {
@@ -267,18 +288,36 @@ release drawing even when point goes out of canvas */
267288
[[]]
268289
);
269290

291+
// avoid pen from scrolling if scrollOnTouch
292+
useEffect(() => {
293+
const listener = function(
294+
this: HTMLDivElement,
295+
event: TouchEvent
296+
): void {
297+
if (currentPointerType.current === "pen") {
298+
event.preventDefault();
299+
event.stopPropagation();
300+
}
301+
};
302+
303+
if (scrollOnTouch) {
304+
canvasRef.current?.addEventListener("touchstart", listener, { passive: false });
305+
}
306+
return () => canvasRef.current?.removeEventListener("touchstart", listener);
307+
}, []);
308+
270309
return (
271310
<div
272311
role="presentation"
273312
ref={canvasRef}
274313
className={className}
275314
style={{
276-
touchAction: 'none',
315+
touchAction: scrollOnTouch ? 'pan-y' : 'none',
277316
width,
278317
height,
279318
...style,
280319
}}
281-
touch-action="none"
320+
touch-action={scrollOnTouch ? 'pan-y' : 'none'}
282321
onPointerDown={handlePointerDown}
283322
onPointerMove={handlePointerMove}
284323
onPointerUp={handlePointerUp}

src/ReactSketchCanvas/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export interface ReactSketchCanvasProps {
2323
style?: React.CSSProperties;
2424
svgStyle?: React.CSSProperties;
2525
withTimestamp?: boolean;
26+
scrollOnTouch?: boolean;
2627
}
2728

2829
export interface ReactSketchCanvasRef {
@@ -63,6 +64,7 @@ export const ReactSketchCanvas = React.forwardRef<
6364
onChange = (_paths: CanvasPath[]): void => {},
6465
onStroke = (_path: CanvasPath, _isEraser: boolean): void => {},
6566
withTimestamp = false,
67+
scrollOnTouch = false,
6668
} = props;
6769

6870
const svgCanvas = React.createRef<CanvasRef>();
@@ -269,6 +271,7 @@ export const ReactSketchCanvas = React.forwardRef<
269271
svgStyle={svgStyle}
270272
paths={currentPaths}
271273
isDrawing={isDrawing}
274+
scrollOnTouch={scrollOnTouch}
272275
onPointerDown={handlePointerDown}
273276
onPointerMove={handlePointerMove}
274277
onPointerUp={handlePointerUp}

0 commit comments

Comments
 (0)