46

GitHub - drcmda/react-with-gesture: ?Bread n butter utility for component-tied m...

 5 years ago
source link: https://github.com/drcmda/react-with-gesture
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

README.md

68747470733a2f2f692e696d6775722e636f6d2f7467316d4e31462e676966 68747470733a2f2f692e696d6775722e636f6d2f696664434276472e676966

npm install react-with-gesture

import { useGesture, withGesture, Gesture } from 'react-with-gesture'

Ever thought about doing that sidebar pull-out, or a view pager, some slider, any gesture on the web basically, and dropped the idea because it's way too hard? In that case, this is your lib. The attempt was to gather the right amount of data needed to make even complex interaction possible without ending up either in complex math-, or implicit magic-hell.

React-with-gesture is a small utility that lets you bind richer mouse and touch events to any component or view. It calculates initial position, deltas, velocity, direction, distance, etc. With this data it becomes trivial to set up gesture controls, and often takes no more than a few lines of code.

You can use it stand-alone, but to make the most of it you should combine it with a animation library, preferrably react-spring (nothing complements gestures better than physics-based springs).

Demos

Viewpager/carousel: https://codesandbox.io/embed/n9vo1my91p

Draggable list: https://codesandbox.io/embed/r5qmj8m6lq

Slider: https://codesandbox.io/embed/zrj66y8714

Api

The api is straight forward. You can use React hooks, render-props or higher-order-components. You bind handlers to your view (done automatically for you if you use render-props or hoc's), and you will receive events when the user is clicking/dragging/pulling/releasing them.

// Full config with event handler
const bind = useGesture({ onAction: event => eventHandler, ...config })
return <div {...bind(optionalArgs)} />

// Short cut with event handler (becomes onAction + default config)
const bind = useGesture(event => eventHandler)
return <div {...bind(optionalArgs)} />

// No event handler (will re-render the component on event changes with fresh props)
const [bind, props] = useGesture()
return <div {...bind(optionalArgs)} />

// Render props
<Gesture {...config}>
  {event => <div />}
</Gesture>

// HOC with decorator
@withGesture(config)
class extends React.Component {
  render() {
    const event = this.props.event
    return <div />
  }
}

// Plain standard HOC
withGesture(config)(Component)

Config

{ 
  touch: true,                  // accept mouse input
  mouse: true,                  // accept touch input
  passive: { passive: true },   // event handler 3rd argument input, passive by default
  onAction: undefined           // event => eventHandler, respond to events outside Reacts render cycle
}

Event data

{
  event,                        // source event
  target,                       // dom node
  time,                         // time tag
  initial,                      // click coordinates (vec2)
  xy,                           // page coordinates (vec2)
  previous,                     // previous page coordinates (vec2)
  delta,                        // delta offset (xy - initial) (vec2)
  direction,                    // direction normal (vec2)
  local,                        // delta with book-keeping (vec2)
  velocity,                     // drag momentuum / speed
  distance,                     // delta distance
  down,                         // mouse / touch down
  first,                        // marks first event (mouse / touch down)
  args,                         // arguments optionally passed to bind(a,b,c,d,..)
  temp,                         // arguments optionally returned by onActions eventHandler
}

Examples

React hooks (basic drag/n/drop)

68747470733a2f2f692e696d6775722e636f6d2f6f6f4e75336a7a2e676966

Demo: https://codesandbox.io/embed/l2wy87l28l

const [bind, { local: [x, y] }] = useGesture()
return <div {...bind()} style={{ transform: `translate3d(${x}px,${y}px,0)` }} />

React hooks with onAction (and react-spring) (basic pull & release)

68747470733a2f2f692e696d6775722e636f6d2f4b44654a4271702e676966

Demo: https://codesandbox.io/embed/r24mzvo3q

const [{ xy }, set] = useSpring(() => ({ xy: [0, 0] }))
const bind = useGesture(({ down, delta }) => set({ xy: down ? delta : [0, 0] }))
return (
  <animated.div
    {...bind()}
    style={{ transform: xy.interpolate((x, y) => `translate3d(${x}px,${y}px,0)`) }}
  />
)

React hooks with onAction (and react-spring) (decay)

68747470733a2f2f692e696d6775722e636f6d2f4a7965517345492e676966

Demo: https://codesandbox.io/embed/zq19y1xr9m

const [{ xy }, set] = useSpring(() => ({ xy: [0, 0] }))
const bind = useGesture(({ down, delta, velocity, direction, temp = xy.getValue() }) => {
  set({ 
    xy: add(delta, temp),
    immediate: down,
    config: { velocity: scale(direction, velocity), decay: true }
  })
  return temp
})
return (
  <animated.div
    {...bind()}
    style={{ transform: xy.interpolate((x, y) => `translate3d(${x}px,${y}px,0)`) }}
  />
)

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK