Skip to content

Commit cb199ff

Browse files
committed
Use pointer capture to require painting starts within the scene
1 parent 892702d commit cb199ff

1 file changed

Lines changed: 31 additions & 18 deletions

File tree

src/Scene.js

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { ReactComponent as StartIndicator } from './svg/StartIndicator.svg';
2626

2727
const startIndicatorWidth = 0.45;
2828

29-
type MousePosition = {
29+
type PointerPosition = {
3030
x: number,
3131
y: number
3232
};
@@ -173,7 +173,7 @@ class Scene extends React.Component<SceneProps, {}> {
173173
}
174174

175175
/* istanbul ignore next */
176-
getPositionFromSceneSvgMouseEvent(e: any): MousePosition {
176+
getPositionFromSceneSvgPointerEvent(e: any): PointerPosition {
177177
// $FlowFixMe: DOMPoint
178178
const clientPoint = new DOMPoint(e.clientX, e.clientY);
179179
const svgElem = e.currentTarget;
@@ -185,23 +185,36 @@ class Scene extends React.Component<SceneProps, {}> {
185185
}
186186

187187
/* istanbul ignore next */
188-
handleMouseDownSceneSvg = (e: any) => {
189-
const pos: MousePosition = this.getPositionFromSceneSvgMouseEvent(e);
190-
this.lastPaintX = pos.x;
191-
this.lastPaintY = pos.y;
192-
this.props.onPaintScene(pos.x, pos.y);
188+
handlePointerDownSceneSvg = (e: any) => {
189+
if (e.button === 0) {
190+
e.currentTarget.onpointermove = this.handlePaintMove;
191+
192+
// Capture the pointer events so that we can handle the case when
193+
// the pointerup event happens outside of the scene svg
194+
e.currentTarget.setPointerCapture(e.pointerId);
195+
196+
const pos: PointerPosition = this.getPositionFromSceneSvgPointerEvent(e);
197+
this.lastPaintX = pos.x;
198+
this.lastPaintY = pos.y;
199+
this.props.onPaintScene(pos.x, pos.y);
200+
}
193201
}
194202

195203
/* istanbul ignore next */
196-
handleMouseMoveSceneSvg = (e: any) => {
197-
const primaryButtonPressed = ((e.buttons % 2) === 1);
198-
if (primaryButtonPressed) {
199-
const pos: MousePosition = this.getPositionFromSceneSvgMouseEvent(e);
200-
if (pos.x !== this.lastPaintX || pos.y !== this.lastPaintY) {
201-
this.lastPaintX = pos.x;
202-
this.lastPaintY = pos.y;
203-
this.props.onPaintScene(pos.x, pos.y);
204-
}
204+
handlePointerUpSceneSvg = (e: any) => {
205+
e.currentTarget.onpointermove = null;
206+
e.currentTarget.releasePointerCapture(e.pointerId);
207+
}
208+
209+
/* istanbul ignore next */
210+
handlePaintMove = (e: any) => {
211+
const pos: PointerPosition = this.getPositionFromSceneSvgPointerEvent(e);
212+
if (this.props.dimensions.isXInRange(pos.x)
213+
&& this.props.dimensions.isYInRange(pos.y)
214+
&& (pos.x !== this.lastPaintX || pos.y !== this.lastPaintY)) {
215+
this.lastPaintX = pos.x;
216+
this.lastPaintY = pos.y;
217+
this.props.onPaintScene(pos.x, pos.y);
205218
}
206219
}
207220

@@ -252,8 +265,8 @@ class Scene extends React.Component<SceneProps, {}> {
252265
viewBox={`${minX} ${minY} ${width} ${height}`}
253266
ref={this.sceneSvgRef}
254267
aria-hidden={true}
255-
onMouseDown={this.handleMouseDownSceneSvg}
256-
onMouseMove={this.handleMouseMoveSceneSvg}
268+
onPointerDown={this.handlePointerDownSceneSvg}
269+
onPointerUp={this.handlePointerUpSceneSvg}
257270
>
258271
<defs>
259272
<clipPath id='Scene-clippath'>

0 commit comments

Comments
 (0)