Skip to content

Commit

Permalink
fix bug: bars in dashbord sometimes clipped away
Browse files Browse the repository at this point in the history
improved: dashboard example
  • Loading branch information
bbohlender committed Feb 23, 2024
1 parent 6942e5e commit e8784a0
Show file tree
Hide file tree
Showing 49 changed files with 2,630 additions and 239 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ Build performant 3D user interfaces for Three.js using @react-three/fiber and yo

TODO Release

- fix bug: 3 draw calls for TabsDemo
- fix bug: interaction panel disappear unmount and mount
- add shadcn components
- cli for kits
Expand Down
8 changes: 4 additions & 4 deletions examples/dashboard/date-range-picker.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Button } from "@/button.js";
import { Calendar } from "@react-three/uikit-lucide";
import { Text } from "@react-three/uikit";
import { Button } from '@/button.js'
import { Calendar } from '@react-three/uikit-lucide'
import { Text } from '@react-three/uikit'

export function CalendarDateRangePicker() {
return (
<Button variant="outline" width={260} justifyContent="flex-start">
<Calendar marginRight={8} width={16} height={16} />
<Text fontWeight="normal">Jan 20, 2023 - Feb 09, 2023</Text>
</Button>
);
)
}
171 changes: 109 additions & 62 deletions examples/dashboard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { StrictMode } from 'react'
import { Canvas } from '@react-three/fiber'
import { StrictMode, Suspense, useEffect, useRef, useState } from 'react'
import { Canvas, useFrame } from '@react-three/fiber'
import { createRoot } from 'react-dom/client'
import { Container, Fullscreen, Root, Text } from '@react-three/uikit'
import { Container, CustomContainer, Root, Text } from '@react-three/uikit'
import { DefaultColors, colors } from '@/defaults.js'
import { Button } from '@/button.js'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/card.js'
Expand All @@ -13,8 +13,11 @@ import { RecentSales } from './recent-sales.js'
import { TeamSwitcher } from './team-switcher.js'
import { UserNav } from './user-nav.js'
import { Activity, CreditCard, DollarSign, Users } from '@react-three/uikit-lucide'
import { Environment, OrbitControls } from '@react-three/drei'
import { Perf } from 'r3f-perf'
import { ContactShadows, Environment, MeshTransmissionMaterial, useGLTF, useTexture } from '@react-three/drei'
import { Group, MathUtils, RepeatWrapping } from 'three'
import { DialogAnchor } from '@/dialog.js'
//@ts-ignore
import { EffectComposer, DepthOfField, Vignette } from '@react-three/postprocessing'

createRoot(document.getElementById('root')!).render(
<StrictMode>
Expand All @@ -23,70 +26,114 @@ createRoot(document.getElementById('root')!).render(
)

function App() {
const [open, setOpen] = useState(false)
return (
<Canvas style={{ height: '100dvh', touchAction: 'none' }} gl={{ localClippingEnabled: true }}>
<Perf />
<color attach="background" args={['black']} />
<ambientLight intensity={0.5} />
<directionalLight intensity={0} position={[5, 1, 10]} />
<OrbitControls />
<Environment preset="city" background />
<group rotation-y={Math.PI / 4} position-x={-1.5}>
<Root
hover={{ transformTranslateZ: 500 }}
anchorX="right"
pixelSize={0.002}
sizeX={1.5}
backgroundColor="white"
backgroundOpacity={0.9}
borderRadius={16}
>
<DefaultColors>
<DashboardPage />
</DefaultColors>
</Root>
</group>
<Root
pixelSize={0.002}
sizeX={2.25}
hover={{ transformTranslateZ: 500 }}
backgroundColor="white"
backgroundOpacity={0.9}
borderRadius={16}
>
<DefaultColors>
<DashboardPage />
</DefaultColors>
</Root>
<Canvas
camera={{ position: [0, 0, -18], fov: 35 }}
style={{ height: '100dvh', touchAction: 'none' }}
gl={{ localClippingEnabled: true }}
>
<pointLight position={[8, 0, -10]} intensity={1500} color={'#d25578'} />
<pointLight position={[-10, 10, -10]} intensity={1500} color={'blue'} />
<Suspense fallback={null}>
<group rotation={[0, Math.PI, 0]} position-y={-0.5}>
<Model open={open} setOpen={setOpen} hinge={-0.425} />
</group>
<Environment background blur={0.2} preset="city" />
</Suspense>
<ContactShadows position={[0, -4.5, 0]} opacity={0.4} scale={20} blur={1.75} far={4.5} />

<group rotation-y={-Math.PI / 4} position-x={1.5}>
<Root
hover={{ transformTranslateZ: 500 }}
anchorX="left"
pixelSize={0.002}
sizeX={3.5}
backgroundColor="white"
backgroundOpacity={0.9}
borderRadius={16}
>
<DefaultColors>
<DashboardPage />
</DefaultColors>
</Root>
</group>
<EffectComposer>
<DepthOfField focusDistance={open ? 0.016 : 0.018} focalLength={0.005} bokehScale={6} />
<Vignette eskil={false} offset={0.1} darkness={1.1} />
</EffectComposer>
</Canvas>
)
}

export function DashboardPage() {
function Model({ hinge, open, setOpen, ...props }: any) {
const group = useRef<Group>(null)
const normalMap = useTexture('/scratches.jpg')
useEffect(() => {
normalMap.repeat.setScalar(2)
normalMap.wrapS = RepeatWrapping
normalMap.wrapT = RepeatWrapping
normalMap.needsUpdate = true
}, [normalMap])
// Load model
const { nodes, materials } = useGLTF('/mac-draco.glb')
// Take care of cursor state on hover
// Make it float in the air when it's opened
useFrame((state) => {
const t = state.clock.getElapsedTime()
if (group.current == null) {
return
}
group.current.rotation.x = MathUtils.lerp(group.current.rotation.x, Math.cos(t / 10) / 10 + 0.25, 0.1)
group.current.rotation.y = MathUtils.lerp(group.current.rotation.y, Math.sin(t / 10) / 4, 0.1)
group.current.rotation.z = MathUtils.lerp(group.current.rotation.z, Math.sin(t / 10) / 10, 0.1)
group.current.position.y = MathUtils.lerp(group.current.position.y, (-2 + Math.sin(t)) / 3, 0.1)
})
// The view was auto-generated by: https://github.com/pmndrs/gltfjsx
// Events and spring animations were added afterwards
return (
<group ref={group} {...props} dispose={null}>
<group rotation-x={hinge} position={[0, -0.04, 0.41]}>
<group position={[0, 2.96, -0.13]} rotation={[Math.PI / 2, 0, 0]}>
<mesh material={materials.aluminium} geometry={nodes['Cube008'].geometry} />
<mesh material={materials['matte.001']} geometry={nodes['Cube008_1'].geometry} />
<group rotation-x={-Math.PI / 2}>
<Root backgroundColor={0xffffff} sizeX={8.34} sizeY={5.58} pixelSize={0.01}>
<CustomContainer transformTranslateZ={-1} positionType="absolute" inset={0}>
<meshBasicMaterial colorWrite={false} />
</CustomContainer>
<CustomContainer zIndexOffset={50} transformTranslateZ={1} positionType="absolute" inset={0}>
<MeshTransmissionMaterial
normalMap={normalMap}
normalMapType={1}
clearcoatNormalMap={normalMap}
distortionScale={0}
temporalDistortion={0}
transmission={1}
metalness={0.6}
roughness={0.1}
clearcoat={0.1}
opacity={0.4}
transparent
envMapIntensity={0.5}
color={0xffffff}
/>
</CustomContainer>
<DefaultColors>
<DialogAnchor>
<Container width="100%" height="100%" overflow="scroll">
<DashboardPage open={open} setOpen={setOpen} />
</Container>
</DialogAnchor>
</DefaultColors>
</Root>
</group>
</group>
</group>
<mesh material={materials.keys} geometry={nodes.keyboard.geometry} position={[1.79, 0, 3.45]} />
<group position={[0, -0.1, 3.39]}>
<mesh material={materials.aluminium} geometry={nodes['Cube002'].geometry} />
<mesh material={materials.trackpad} geometry={nodes['Cube002_1'].geometry} />
</group>
<mesh material={materials.touchbar} geometry={nodes.touchbar.geometry} position={[0, -0.03, 1.2]} />
</group>
)
}

export function DashboardPage({ open, setOpen }: { open: boolean; setOpen: (open: boolean) => void }) {
return (
<Container flexDirection="column">
<Container borderBottom={1}>
<Container height={64} alignItems="center" flexDirection="row" paddingX={16}>
<TeamSwitcher />
<MainNav marginX={24} />
<Container marginLeft="auto" flexDirection="row" alignItems="center" gap={16}>
<UserNav />
<UserNav open={open} setOpen={setOpen} />
</Container>
</Container>
</Container>
Expand Down Expand Up @@ -120,7 +167,7 @@ export function DashboardPage() {
<TabsContent value="overview" gap={16}>
<Container gap={16} lg={{ flexDirection: 'row' }}>
<Container flexGrow={1} gap={16} flexDirection="row">
<Card backgroundOpacity={0.8} flexBasis={0} flexGrow={1}>
<Card flexBasis={0} flexGrow={1}>
<CardHeader flexDirection="row" alignItems="center" justifyContent="space-between" paddingBottom={8}>
<CardTitle>
<Text fontSize={14} lineHeight={1.43}>
Expand All @@ -138,7 +185,7 @@ export function DashboardPage() {
</Text>
</CardContent>
</Card>
<Card backgroundOpacity={0.8} flexBasis={0} flexGrow={1}>
<Card flexBasis={0} flexGrow={1}>
<CardHeader
flexDirection="row"
alignItems="center"
Expand All @@ -164,7 +211,7 @@ export function DashboardPage() {
</Card>
</Container>
<Container flexGrow={1} gap={16} flexDirection="row">
<Card backgroundOpacity={0.8} flexBasis={0} flexGrow={1}>
<Card flexBasis={0} flexGrow={1}>
<CardHeader
flexDirection="row"
alignItems="center"
Expand All @@ -188,7 +235,7 @@ export function DashboardPage() {
</Text>
</CardContent>
</Card>
<Card backgroundOpacity={0.8} flexBasis={0} flexGrow={1}>
<Card flexBasis={0} flexGrow={1}>
<CardHeader
flexDirection="row"
alignItems="center"
Expand All @@ -215,7 +262,7 @@ export function DashboardPage() {
</Container>
</Container>
<Container lg={{ flexDirection: 'row' }} flexDirection="column" gap={16}>
<Card backgroundOpacity={0.8} lg={{ flexGrow: 4 }}>
<Card lg={{ flexGrow: 4 }}>
<CardHeader>
<CardTitle>
<Text>Overview</Text>
Expand All @@ -225,7 +272,7 @@ export function DashboardPage() {
<Overview />
</CardContent>
</Card>
<Card backgroundOpacity={0.8} lg={{ flexGrow: 3 }}>
<Card lg={{ flexGrow: 3 }}>
<CardHeader>
<CardTitle>
<Text>Recent Sales</Text>
Expand Down
10 changes: 5 additions & 5 deletions examples/dashboard/main-nav.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { colors } from "@/defaults.js";
import { Container, Text } from "@react-three/uikit";
import { ComponentPropsWithoutRef } from "react";
import { colors } from '@/defaults.js'
import { Container, Text } from '@react-three/uikit'
import { ComponentPropsWithoutRef } from 'react'

export function MainNav(props: Omit<ComponentPropsWithoutRef<typeof Container>, "children">) {
export function MainNav(props: Omit<ComponentPropsWithoutRef<typeof Container>, 'children'>) {
return (
<Container alignItems="center" flexDirection="row" gap={16} lg={{ gap: 24 }} {...props}>
<Text fontSize={14} lineHeight={1.43} fontWeight="medium" hover={{ color: colors.primary }}>
Expand All @@ -18,5 +18,5 @@ export function MainNav(props: Omit<ComponentPropsWithoutRef<typeof Container>,
Settings
</Text>
</Container>
);
)
}
45 changes: 25 additions & 20 deletions examples/dashboard/overview.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,70 @@
import { colors } from "@/defaults.js";
import { Container, Text } from "@react-three/uikit";
import { colors } from '@/defaults.js'
import { Container, Text } from '@react-three/uikit'

const data = [
{
name: "Jan",
name: 'Jan',
total: Math.floor(Math.random() * 5000) + 1000,
},
{
name: "Feb",
name: 'Feb',
total: Math.floor(Math.random() * 5000) + 1000,
},
{
name: "Mar",
name: 'Mar',
total: Math.floor(Math.random() * 5000) + 1000,
},
{
name: "Apr",
name: 'Apr',
total: Math.floor(Math.random() * 5000) + 1000,
},
{
name: "May",
name: 'May',
total: Math.floor(Math.random() * 5000) + 1000,
},
{
name: "Jun",
name: 'Jun',
total: Math.floor(Math.random() * 5000) + 1000,
},
{
name: "Jul",
name: 'Jul',
total: Math.floor(Math.random() * 5000) + 1000,
},
{
name: "Aug",
name: 'Aug',
total: Math.floor(Math.random() * 5000) + 1000,
},
{
name: "Sep",
name: 'Sep',
total: Math.floor(Math.random() * 5000) + 1000,
},
{
name: "Oct",
name: 'Oct',
total: Math.floor(Math.random() * 5000) + 1000,
},
{
name: "Nov",
name: 'Nov',
total: Math.floor(Math.random() * 5000) + 1000,
},
{
name: "Dec",
name: 'Dec',
total: Math.floor(Math.random() * 5000) + 1000,
},
];
]

const max = 6000;
const max = 6000

const yAxisLabels = ["$6000", "$4500", "$3000", "$1500", "$0"];
const yAxisLabels = ['$6000', '$4500', '$3000', '$1500', '$0']

export function Overview() {
return (
<Container paddingX={16} gap={16} width="100%" height={350} flexDirection="row">
<Container paddingBottom={12 * 1.333 + 8} flexDirection="column" alignItems="flex-end" justifyContent="space-between">
<Container
paddingBottom={12 * 1.333 + 8}
flexDirection="column"
alignItems="flex-end"
justifyContent="space-between"
>
{yAxisLabels.map((label) => (
<Text color={colors.mutedForeground} fontSize={12} lineHeight={1.3333} key={label}>
{label}
Expand All @@ -72,7 +77,7 @@ export function Overview() {
<Container flexGrow={1} flexShrink={1} justifyContent="flex-end" width="100%">
<Container
borderRadiusTop={4}
height={`${Math.min(1, (total / max)) * 100}%`}
height={`${Math.min(1, total / max) * 100}%`}
backgroundColor={colors.primary}
width="100%"
/>
Expand All @@ -84,5 +89,5 @@ export function Overview() {
))}
</Container>
</Container>
);
)
}
Loading

0 comments on commit e8784a0

Please sign in to comment.