Skip to content

Commit

Permalink
feat(Resize): new component (#1420)
Browse files Browse the repository at this point in the history
  • Loading branch information
abernier authored Apr 25, 2023
1 parent 1b0a2df commit c918df0
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 0 deletions.
45 changes: 45 additions & 0 deletions .storybook/stories/Resize.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import * as THREE from 'three'
import * as React from 'react'
import { withKnobs } from '@storybook/addon-knobs'

import { Setup } from '../Setup'

import { Box, Resize, ResizeProps } from '../../src'

export default {
title: 'Staging/Resize',
component: Resize,
decorators: [
withKnobs,
(storyFn) => (
<Setup camera={{ position: [1, 1, 1], zoom: 150 }} orthographic>
{storyFn()}
</Setup>
),
],
}

export const ResizeSt = ({ width, height, depth }: ResizeProps) => (
<>
<axesHelper />

<Resize width={width} height={height} depth={depth}>
<Box args={[70, 40, 20]}>
<meshBasicMaterial wireframe />
</Box>
</Resize>
</>
)
ResizeSt.args = {
width: undefined,
height: undefined,
depth: undefined,
}

ResizeSt.argTypes = {
width: { control: { type: 'boolean' } },
height: { control: { type: 'boolean' } },
depth: { control: { type: 'boolean' } },
}

ResizeSt.storyName = 'Default'
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3122,6 +3122,41 @@ function ScaledModel() {
</Center>
```

#### Resize

[![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.pmnd.rs/?path=/story/staging-resize)

Calculates a boundary box and scales its children so the highest dimension is constrained by 1. NB: proportions are preserved.

```tsx
export type ResizeProps = JSX.IntrinsicElements['group'] & {
/** constrained by width dimension (x axis), undefined */
width?: boolean
/** constrained by height dimension (y axis), undefined */
height?: boolean
/** constrained by depth dimension (z axis), undefined */
depth?: boolean
/** You can optionally pass the Box3, otherwise will be computed, undefined */
box3?: THREE.Box3
/** See https://threejs.org/docs/index.html?q=box3#api/en/math/Box3.setFromObject */
precise?: boolean
}
```

```jsx
<Resize>
<mesh />
</Resize>
```

You can also specify the dimension to be constrained by:

```jsx
<Resize height>
<Box args={[70, 40, 20]}>
</Resize>
```

#### BBAnchor

[![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/misc-bbanchor--bb-anchor-with-html)
Expand Down
49 changes: 49 additions & 0 deletions src/core/Resize.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as THREE from 'three'
import * as React from 'react'

export type ResizeProps = JSX.IntrinsicElements['group'] & {
/** Whether to fit into width (x axis), undefined */
width?: boolean
/** Whether to fit into height (y axis), undefined */
height?: boolean
/** Whether to fit into depth (z axis), undefined */
depth?: boolean
/** You can optionally pass the Box3, otherwise will be computed, undefined */
box3?: THREE.Box3
/** See https://threejs.org/docs/index.html?q=box3#api/en/math/Box3.setFromObject */
precise?: boolean
}

export const Resize = React.forwardRef<THREE.Group, ResizeProps>(
({ children, width, height, depth, box3, precise = true, ...props }, fRef) => {
const ref = React.useRef<THREE.Group>(null!)
const outer = React.useRef<THREE.Group>(null!)
const inner = React.useRef<THREE.Group>(null!)

React.useLayoutEffect(() => {
outer.current.matrixWorld.identity()

box3 ||= new THREE.Box3().setFromObject(inner.current, precise)
const w = box3.max.x - box3.min.x
const h = box3.max.y - box3.min.y
const d = box3.max.z - box3.min.z

let dimension = Math.max(w, h, d)
if (width) dimension = w
if (height) dimension = h
if (depth) dimension = d

outer.current.scale.setScalar(1 / dimension)
}, [width, height, depth, box3, precise])

React.useImperativeHandle(fRef, () => ref.current, [])

return (
<group ref={ref} {...props}>
<group ref={outer}>
<group ref={inner}>{children}</group>
</group>
</group>
)
}
)
1 change: 1 addition & 0 deletions src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export * from './ScreenQuad'

// Staging/Prototyping
export * from './Center'
export * from './Resize'
export * from './Bounds'
export * from './CameraShake'
export * from './Float'
Expand Down

1 comment on commit c918df0

@vercel
Copy link

@vercel vercel bot commented on c918df0 Apr 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.