File size: 2,912 Bytes
645859a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import _extends from '@babel/runtime/helpers/esm/extends';
import * as React from 'react';
import { MathUtils } from 'three';
import { useThree } from '@react-three/fiber';
import { useSpring, a } from '@react-spring/three';
import { useGesture } from '@use-gesture/react';

function PresentationControls({
  enabled = true,
  snap,
  global,
  domElement,
  cursor = true,
  children,
  speed = 1,
  rotation = [0, 0, 0],
  zoom = 1,
  polar = [0, Math.PI / 2],
  azimuth = [-Infinity, Infinity],
  config = {
    mass: 1,
    tension: 170,
    friction: 26
  }
}) {
  const events = useThree(state => state.events);
  const gl = useThree(state => state.gl);
  const explDomElement = domElement || events.connected || gl.domElement;
  const {
    size
  } = useThree();
  const rPolar = React.useMemo(() => [rotation[0] + polar[0], rotation[0] + polar[1]], [rotation[0], polar[0], polar[1]]);
  const rAzimuth = React.useMemo(() => [rotation[1] + azimuth[0], rotation[1] + azimuth[1]], [rotation[1], azimuth[0], azimuth[1]]);
  const rInitial = React.useMemo(() => [MathUtils.clamp(rotation[0], ...rPolar), MathUtils.clamp(rotation[1], ...rAzimuth), rotation[2]], [rotation[0], rotation[1], rotation[2], rPolar, rAzimuth]);
  const [spring, api] = useSpring(() => ({
    scale: 1,
    rotation: rInitial,
    config
  }));
  React.useEffect(() => void api.start({
    scale: 1,
    rotation: rInitial,
    config
  }), [rInitial]);
  React.useEffect(() => {
    if (global && cursor && enabled) {
      explDomElement.style.cursor = 'grab';
      gl.domElement.style.cursor = '';
      return () => {
        explDomElement.style.cursor = 'default';
        gl.domElement.style.cursor = 'default';
      };
    }
  }, [global, cursor, explDomElement, enabled]);
  const bind = useGesture({
    onHover: ({
      last
    }) => {
      if (cursor && !global && enabled) explDomElement.style.cursor = last ? 'auto' : 'grab';
    },
    onDrag: ({
      down,
      delta: [x, y],
      memo: [oldY, oldX] = spring.rotation.animation.to || rInitial
    }) => {
      if (!enabled) return [y, x];
      if (cursor) explDomElement.style.cursor = down ? 'grabbing' : 'grab';
      x = MathUtils.clamp(oldX + x / size.width * Math.PI * speed, ...rAzimuth);
      y = MathUtils.clamp(oldY + y / size.height * Math.PI * speed, ...rPolar);
      const sConfig = snap && !down && typeof snap !== 'boolean' ? snap : config;
      api.start({
        scale: down && y > rPolar[1] / 2 ? zoom : 1,
        rotation: snap && !down ? rInitial : [y, x, 0],
        config: n => n === 'scale' ? {
          ...sConfig,
          friction: sConfig.friction * 3
        } : sConfig
      });
      return [y, x];
    }
  }, {
    target: global ? explDomElement : undefined
  });
  return /*#__PURE__*/React.createElement(a.group, _extends({}, bind == null ? void 0 : bind(), spring), children);
}

export { PresentationControls };