Skip to content
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

feat: add enabled prop to PresentationControls #1096

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 33 additions & 0 deletions .storybook/stories/PresentationControls.stories.tsx
@@ -0,0 +1,33 @@
import * as React from 'react'

import { Setup } from '../Setup'

import { Box, PresentationControlProps, PresentationControls } from '../../src'

export function PresentationControlStory({ enabled, ...rest }: PresentationControlProps) {
return (
<PresentationControls global snap enabled={enabled} {...rest}>
<Box args={[1, 1, 1]}>
<meshBasicMaterial wireframe />
<axesHelper args={[100]} />
</Box>
</PresentationControls>
)
}

PresentationControlStory.storyName = 'Default'
PresentationControlStory.args = {
enabled: true,
}

export default {
title: 'Controls/PresentationControls',
component: PresentationControls,
decorators: [
(storyFn) => (
<Setup camera={{ near: 1, far: 1100, fov: 75 }} controls={false}>
{storyFn()}
</Setup>
),
],
}
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -372,6 +372,7 @@ Semi-OrbitControls with spring-physics, polar zoom and snap-back, for presentati

```jsx
<PresentationControls
enabled={true} // the controls can be disabled by setting this to false
global={false} // Spin globally or by dragging the model
cursor={true} // Whether to toggle cursor style on drag
snap={false} // Snap-back to center (can also be a spring config)
Expand Down
15 changes: 10 additions & 5 deletions src/web/PresentationControls.tsx
Expand Up @@ -5,7 +5,7 @@ import { a, useSpring } from '@react-spring/three'
import { useGesture } from '@use-gesture/react'
import { SpringConfig } from '@react-spring/core'

type Props = {
export type PresentationControlProps = {
snap?: Boolean | SpringConfig
global?: boolean
cursor?: boolean
Expand All @@ -15,10 +15,12 @@ type Props = {
polar?: [number, number]
azimuth?: [number, number]
config?: any
enabled?: boolean
children?: React.ReactNode
}

export function PresentationControls({
enabled = true,
snap,
global,
cursor = true,
Expand All @@ -29,7 +31,7 @@ export function PresentationControls({
polar = [0, Math.PI / 2],
azimuth = [-Infinity, Infinity],
config = { mass: 1, tension: 170, friction: 26 },
}: Props) {
}: PresentationControlProps) {
const { size, gl } = useThree()
const rPolar = React.useMemo(
() => [rotation[0] + polar[0], rotation[0] + polar[1]],
Expand All @@ -46,14 +48,17 @@ export function PresentationControls({
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) gl.domElement.style.cursor = 'grab'
}, [global, cursor, gl.domElement])
if (global && cursor && enabled) gl.domElement.style.cursor = 'grab'
joshuaellis marked this conversation as resolved.
Show resolved Hide resolved

return () => void (gl.domElement.style.cursor = 'default')
}, [global, cursor, gl.domElement, enabled])
const bind = useGesture(
{
onHover: ({ last }) => {
if (cursor && !global) gl.domElement.style.cursor = last ? 'auto' : 'grab'
if (cursor && !global && enabled) gl.domElement.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) gl.domElement.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)
Expand Down