From 494aa599826b3b16a199ca5c472d6976aac03a1d Mon Sep 17 00:00:00 2001 From: Andreas Riepl Date: Fri, 23 Dec 2022 08:57:44 +0100 Subject: [PATCH 1/3] feat(scroll-on-touch): use finger to scroll on canvas --- src/Canvas/index.tsx | 47 ++++++++++++++++++++++++++++++--- src/ReactSketchCanvas/index.tsx | 3 +++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/Canvas/index.tsx b/src/Canvas/index.tsx index ad1abd8..07f636d 100644 --- a/src/Canvas/index.tsx +++ b/src/Canvas/index.tsx @@ -1,3 +1,4 @@ +import { useEffect } from "react"; import * as React from 'react'; import Paths, { SvgPath } from '../Paths'; import { CanvasPath, ExportImageType, Point } from '../types'; @@ -32,6 +33,7 @@ function getCanvasWithViewBox(canvas: HTMLDivElement) { export interface CanvasProps { paths: CanvasPath[]; isDrawing: boolean; + scrollOnTouch: boolean; onPointerDown: (point: Point) => void; onPointerMove: (point: Point) => void; onPointerUp: () => void; @@ -57,6 +59,7 @@ export const Canvas = React.forwardRef((props, ref) => { const { paths, isDrawing, + scrollOnTouch, onPointerDown, onPointerMove, onPointerUp, @@ -77,6 +80,7 @@ export const Canvas = React.forwardRef((props, ref) => { } = props; const canvasRef = React.useRef(null); + const currentPointerType = React.useRef<"pen" | "mouse" | "touch" | null>(null); // Converts mouse coordinates to relative coordinate based on the absolute position of svg const getCoordinates = ( @@ -104,8 +108,18 @@ export const Canvas = React.forwardRef((props, ref) => { const handlePointerDown = ( event: React.PointerEvent ): void => { - // Allow only chosen pointer type + currentPointerType.current = event.pointerType; + if (scrollOnTouch && event.pointerType === "touch") { + return; + } + + if (event.pointerType === 'pen') { + event.preventDefault(); + event.stopPropagation(); + } + + // Allow only chosen pointer type if ( allowOnlyPointerType !== 'all' && event.pointerType !== allowOnlyPointerType @@ -125,6 +139,10 @@ export const Canvas = React.forwardRef((props, ref) => { ): void => { if (!isDrawing) return; + if (scrollOnTouch && event.pointerType === "touch") { + return; + } + // Allow only chosen pointer type if ( allowOnlyPointerType !== 'all' && @@ -142,6 +160,9 @@ export const Canvas = React.forwardRef((props, ref) => { event: React.PointerEvent | PointerEvent ): void => { if (event.pointerType === 'mouse' && event.button !== 0) return; + if (scrollOnTouch && event.pointerType === "touch") { + return; + } // Allow only chosen pointer type if ( @@ -239,7 +260,7 @@ export const Canvas = React.forwardRef((props, ref) => { })); /* Add event listener to Mouse up and Touch up to -release drawing even when point goes out of canvas */ + release drawing even when point goes out of canvas */ React.useEffect(() => { document.addEventListener('pointerup', handlePointerUp); return () => { @@ -267,18 +288,36 @@ release drawing even when point goes out of canvas */ [[]] ); + // avoid pen from scrolling if scrollOnTouch + useEffect(() => { + const listener = function( + this: HTMLDivElement, + event: TouchEvent + ): void { + if (currentPointerType.current === "pen") { + event.preventDefault(); + event.stopPropagation(); + } + }; + + if (scrollOnTouch) { + canvasRef.current?.addEventListener("touchstart", listener, { passive: false }); + } + return () => canvasRef.current?.removeEventListener("touchstart", listener); + }, []); + return (
{}, onStroke = (_path: CanvasPath, _isEraser: boolean): void => {}, withTimestamp = false, + scrollOnTouch = false, } = props; const svgCanvas = React.createRef(); @@ -269,6 +271,7 @@ export const ReactSketchCanvas = React.forwardRef< svgStyle={svgStyle} paths={currentPaths} isDrawing={isDrawing} + scrollOnTouch={scrollOnTouch} onPointerDown={handlePointerDown} onPointerMove={handlePointerMove} onPointerUp={handlePointerUp} From 74ddf26b5f38f2638d4ef7070ff5e6f532715cf0 Mon Sep 17 00:00:00 2001 From: Andreas Riepl Date: Fri, 23 Dec 2022 09:47:28 +0100 Subject: [PATCH 2/3] feat(scroll-on-touch): adds docu --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5d9f718..7cefd4f 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ const Canvas = class extends React.Component { ## List of Props | Props | Expected datatype | Default value | Description | -| ---------------------------------- | ----------------- | --------------------- | --------------------------------------------------------------------------------------------------- | +|------------------------------------|-------------------| --------------------- |-----------------------------------------------------------------------------------------------------| | width | PropTypes.string | 100% | canvas width (em/rem/px) | | height | PropTypes.string | 100% | canvas width (em/rem/px) | | id | PropTypes.string | "react-sketch-canvas" | ID field to uniquely identify a SVG canvas (Supports multiple canvases in a single page) | @@ -136,6 +136,7 @@ const Canvas = class extends React.Component { | allowOnlyPointerType | PropTypes.string | all | allow pointer type ("all"/"mouse"/"pen"/"touch") | | onChange | PropTypes.func | | Returns the current sketch path in `CanvasPath` type on every path change | | onStroke | PropTypes.func | | Returns the the last stroke path and whether it is an eraser stroke on every pointer up event | +| scrollOnTouch | PropTypes.bool | false | Scroll overflowing component instead of sketching if pointerType === touch | | style | PropTypes.object | false | Add CSS styling as CSS-in-JS object | | svgStyle | PropTypes.object | {} | Add CSS styling as CSS-in-JS object for the SVG | | withTimestamp | PropTypes.bool | false | Add timestamp to individual strokes for measuring sketching time | From 4c7f3815f83980f6addd19a929b03007403a7cea Mon Sep 17 00:00:00 2001 From: Andreas Riepl Date: Mon, 30 Jan 2023 09:41:20 +0100 Subject: [PATCH 3/3] feat(scroll-on-touch): adds gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a38ecb1..190a6ce 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .DS_Store node_modules .cache +.idea dist # Cypress cypress/screenshots/