Skip to content

Commit

Permalink
Merge pull request #510 from rpearce/chore/swipe-to-unzoom-backfill
Browse files Browse the repository at this point in the history
chore: backfill docs and style for 2 new swipe to unzoom features
  • Loading branch information
rpearce authored Apr 6, 2024
2 parents 186b16b + 5b12819 commit cf340b0
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 10 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ export interface UncontrolledProps {
// Default: 'Expand image'
a11yNameButtonZoom?: string

// Allow swipe gesture to unzoom.
// Default: true
canSwipeToUnzoom?: boolean

// Your image (required).
children: ReactNode

Expand All @@ -88,6 +92,10 @@ export interface UncontrolledProps {
// Default: IEnlarge
IconZoom?: ElementType

// Swipe gesture threshold after which to unzoom.
// Default: 10
swipeToUnzoomThreshold?: number

// Specify what type of element should be used for
// internal component usage. This is useful if the
// image is inside a <p> or <button>, for example.
Expand Down
20 changes: 10 additions & 10 deletions source/Controlled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ const defaultBodyAttrs: BodyAttrs = {
export interface ControlledProps {
a11yNameButtonUnzoom?: string
a11yNameButtonZoom?: string
canSwipeToUnzoom?: boolean
children: React.ReactNode
classDialog?: string
IconUnzoom?: React.ElementType
IconZoom?: React.ElementType
isZoomed: boolean
onZoomChange?: (value: boolean) => void
canSwipeToUnzoom?: boolean
swipeToUnzoomThreshold?: number
wrapElement?: 'div' | 'span'
ZoomContent?: (data: {
Expand All @@ -82,9 +82,9 @@ interface ControlledDefaultProps {
a11yNameButtonUnzoom: string
a11yNameButtonZoom: string
canSwipeToUnzoom: boolean
swipeToUnzoomThreshold: number
IconUnzoom: React.ElementType
IconZoom: React.ElementType
swipeToUnzoomThreshold: number
wrapElement: 'div' | 'span'
zoomMargin: number
}
Expand All @@ -103,9 +103,9 @@ class ControlledBase extends React.Component<ControlledPropsWithDefaults, Contro
static defaultProps: ControlledDefaultProps = {
a11yNameButtonUnzoom: 'Minimize image',
a11yNameButtonZoom: 'Expand image',
canSwipeToUnzoom: true,
IconUnzoom: ICompress,
IconZoom: IEnlarge,
canSwipeToUnzoom: true,
swipeToUnzoomThreshold: 10,
wrapElement: 'div',
zoomMargin: 0,
Expand Down Expand Up @@ -549,21 +549,21 @@ class ControlledBase extends React.Component<ControlledPropsWithDefaults, Contro
* and unzoom if we detect a swipe
*/
handleTouchMove = (e: TouchEvent) => {
if (!this.props.canSwipeToUnzoom) {
return
}

const browserScale = window.visualViewport?.scale ?? 1

if (!this.isScaling && browserScale <= 1 && this.touchYStart != null && e.changedTouches[0]) {
if (
this.props.canSwipeToUnzoom &&
!this.isScaling &&
browserScale <= 1 && this.touchYStart != null &&
e.changedTouches[0]
) {
this.touchYEnd = e.changedTouches[0].screenY

const max = Math.max(this.touchYStart, this.touchYEnd)
const min = Math.min(this.touchYStart, this.touchYEnd)
const delta = Math.abs(max - min)
const { swipeToUnzoomThreshold } = this.props

if (delta > swipeToUnzoomThreshold) {
if (delta > this.props.swipeToUnzoomThreshold) {
this.touchYStart = undefined
this.touchYEnd = undefined
this.handleUnzoom()
Expand Down
52 changes: 52 additions & 0 deletions stories/Img.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,58 @@ export const InlineImage = (props) => (
</main>
)

// =============================================================================

export const SwipeToUnzoomDisabled = (props) => (
<main aria-label="Story">
<h1>Swipe to Unzoom Disabled</h1>
<p>
This example demonstrates preventing swipe gestures from
unzooming when an image is zoomed. This is best tested on
a touchscreen device!
</p>
<div>
<Zoom {...props} canSwipeToUnzoom={false}>
<img
alt={imgThatWanakaTree.alt}
src={imgThatWanakaTree.src}
decoding="async"
height="320"
loading="lazy"
/>
</Zoom>
</div>
</main>
)

export const SwipeToUnzoomThreshold = (props) => (
<main aria-label="Story">
<h1>Swipe to Unzoom Threshold</h1>
<p>
This example demonstrates increasing the threshold
required for a swipe gesture on a touchscreen device to
unzoom when an image is zoomed. This is best tested on
a touchscreen device!
</p>
<p>
The default is <code>10</code> (px), but this example
is set to <code>200</code> (px); that&apos;s how far
you&apos;ll have to move your finger across the screen.
</p>
<div>
<Zoom {...props} swipeToUnzoomThreshold={200}>
<img
alt={imgThatWanakaTree.alt}
src={imgThatWanakaTree.src}
decoding="async"
height="320"
loading="lazy"
/>
</Zoom>
</div>
</main>
)

// =============================================================================
// INTERACTIONS

Expand Down

0 comments on commit cf340b0

Please sign in to comment.