Skip to content

Commit

Permalink
feat: dpr property for portal to control its resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
bbohlender committed Jun 5, 2024
1 parent f2380ba commit d53e47d
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 6 deletions.
2 changes: 1 addition & 1 deletion docs/getting-started/components-and-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ The default image doesn't use react's suspense but rather loads the image silent

## Portal

The `Portal` component uses the `Image` component under the hood to render its children into a render target, which is displayed on the surface of the `Portal` component. In contrast to the `Image` component, the `Portal` component doesn't have a default `aspectRatio` or an `src` property. The size of the portal is completly controlled through the flexbox properties.
The `Portal` component uses the `Image` component under the hood to render its children into a render target, which is displayed on the surface of the `Portal` component. In contrast to the `Image` component, the `Portal` component doesn't have a default `aspectRatio` or an `src` property. The size of the portal is completly controlled through the flexbox properties, the resolution of the portal is equal to the size multiplied by the `dpr` property, which defaults to the system `dpr`.

```jsx
<Root>
Expand Down
2 changes: 1 addition & 1 deletion examples/uikit/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export default function App() {
<Container flexShrink={0} flexDirection="row" height={500}>
{/* By default, the Portal should create it's own camera and thus
not be affected by the scene camera and orbit controls..*/}
<Portal borderRadius={30} width="33%">
<Portal dpr={0.5} borderRadius={30} width="33%">
<Box rotation-y={Math.PI / 4} args={[2, 2, 2]} />
<color attach="background" args={['red']} />
</Portal>
Expand Down
12 changes: 8 additions & 4 deletions packages/react/src/portal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ export type PortalProperties = {
frames?: number
renderPriority?: number
eventPriority?: number
resolution?: number
/**
* ratio between the size (in pixels) and the size of the render target (in pixels)
* higher dpr means higher resolution of the render target
*/
dpr?: number
children?: ReactNode
} & BasePortalProperties &
EventHandlers & {
Expand All @@ -70,10 +74,11 @@ export type PortalProperties = {
export const Portal: (
props: PortalProperties & RefAttributes<ComponentInternals<BasePortalProperties & EventHandlers>>,
) => ReactNode = forwardRef(
({ children, resolution = 1, frames = Infinity, renderPriority = 0, eventPriority = 0, ...props }, ref) => {
({ children, dpr, frames = Infinity, renderPriority = 0, eventPriority = 0, ...props }, ref) => {
const fbo = useMemo(() => new Signal<WebGLRenderTarget | undefined>(undefined), [])
const imageRef = useRef<ComponentInternals<ImageProperties>>(null)
const previousRoot = useStore()
dpr ??= previousRoot.getState().viewport.dpr
useImperativeHandle(ref, () => imageRef.current!, [])
const texture = useMemo(() => computed(() => fbo.value?.texture), [fbo])

Expand Down Expand Up @@ -161,7 +166,6 @@ export const Portal: (
return
}
const [width, height] = size.value
const dpr = previousRoot.getState().viewport.dpr
renderTarget.setSize(width * dpr, height * dpr)
usePortalStore.setState({
size: { width, height, top: 0, left: 0 },
Expand All @@ -172,7 +176,7 @@ export const Portal: (
unsubscribeSetSize()
renderTarget.dispose()
}
}, [fbo, previousRoot, usePortalStore])
}, [fbo, previousRoot, usePortalStore, dpr])

return (
<>
Expand Down

0 comments on commit d53e47d

Please sign in to comment.