-
-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: don't clear canvas on mobile browsers' height change #66
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,9 @@ import React, { Component } from 'react' | |
import SignaturePad from 'signature_pad' | ||
import trimCanvas from 'trim-canvas' | ||
|
||
const userAgent = window.navigator.userAgent | ||
const isTouchDevice = userAgent.indexOf("iPhone") >= 0 || userAgent.indexOf("iPad") >= 0 || userAgent.indexOf("Android") >= 0 | ||
|
||
export default class SignatureCanvas extends Component { | ||
static propTypes = { | ||
// signature_pad's props | ||
|
@@ -26,6 +29,8 @@ export default class SignatureCanvas extends Component { | |
|
||
_sigPad = null | ||
|
||
_windowSize = { width: window.innerWidth, height: window.innerHeight } | ||
|
||
_excludeOurProps = () => { | ||
const { canvasProps, clearOnResize, ...sigPadProps } = this.props | ||
return sigPadProps | ||
|
@@ -67,11 +72,28 @@ export default class SignatureCanvas extends Component { | |
return this._sigPad | ||
} | ||
|
||
_checkClearOnResize = () => { | ||
if (!this.props.clearOnResize) { | ||
_handleResize = (callback) => { | ||
if (this._windowSize.width === window.innerWidth && | ||
/** | ||
* For touch devices, only compare width as the browser height | ||
* might constantly change as user scrolls/touches like on iOS Safari. | ||
*/ | ||
(this._windowSize.height === window.innerHeight || isTouchDevice) | ||
) { | ||
return | ||
} | ||
this._resizeCanvas() | ||
// Update window size | ||
this._windowSize = { width: window.innerWidth, height: window.innerHeight } | ||
callback() | ||
} | ||
|
||
_checkClearOnResize = () => { | ||
this._handleResize(() => { | ||
if (!this.props.clearOnResize) { | ||
return | ||
} | ||
this._resizeCanvas() | ||
}) | ||
Comment on lines
+91
to
+96
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These methods can get called very frequently during each frame of a resize (esp. as they're not throttled), so instead of creating anonymous closures each time, it's better to have another helper method for this. That optimization is also why the rest of the code is written as such |
||
} | ||
|
||
_resizeCanvas = () => { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is fully inclusive of all mobile browsers. This SO answer lists quite a bit more.
isMobile
is also probably better naming as laptops can have touchscreens too.But while I like the DX of auto-detection, I'm not sure this is foolproof enough to work consistently. A prop
isMobile
might make more sense... but the developer might use the same method to set that prop 😅There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
detect-it
can also be used to check device support for touch screen and if the touch screen is the primary input method (which should filter out laptop touchscreens I think? though I'm not sure the compatibility of both checks).There are still some edge cases not covered there, for instance, multi-tasking mode on mobile where you split the screen... 😕
Adding a
clearOnOrientationChange
prop may make things more clear for developers and be fully backward-compatible as well. Then they can decide whether to use that for their users, e.g.clearOnResize={false} clearOnOrientationChange
, and each developer should know their users best.That's probably the easiest solution, though I do prefer the DX of auto-detection