Improve three scene performance and add JSCAD

- smoothed follow mouse animation
- made mobile friendlier down to about 330px ish
- added default social image
- used smaller hero asset
This commit is contained in:
Kurt Hutten
2021-09-12 10:24:39 +10:00
parent 750d10c01d
commit e526fa812e
17 changed files with 6735 additions and 34917 deletions

View File

@@ -4,23 +4,16 @@ import { useLoader, useThree, useFrame } from '@react-three/fiber'
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'
import { useEdgeSplit } from 'src/helpers/hooks/useEdgeSplit'
import texture from 'src/components/IdeViewer/dullFrontLitMetal.png'
import {
useTexture,
Environment,
MeshDistortMaterial,
Sphere,
} from '@react-three/drei'
import { useTexture, MeshDistortMaterial, Sphere } from '@react-three/drei'
const thresholdAngle = 10
export default function AssetWithGooey({
assetUrl,
offset,
preset,
scale,
}: {
assetUrl: string
offset: number[]
preset?: string
scale: number
}) {
const geo = useLoader(STLLoader, assetUrl)
@@ -32,27 +25,31 @@ export default function AssetWithGooey({
const position = [offset[0], offset[1], 5]
const scaleArr = Array.from({ length: 3 }).map(() => scale)
const { mouse } = useThree()
const [rEuler, rQuaternion] = useMemo(
() => [new THREE.Euler(), new THREE.Quaternion()],
[]
)
useFrame((state, delta) => {
if (edgeRef.current) {
edgeRef.current.rotation.y += 0.01
coffeeRef.current.rotation.x = (-mouse.y * Math.PI) / 6
coffeeRef.current.rotation.y = (mouse.x * Math.PI) / 6
}
if (coffeeRef.current) {
rEuler.set((-mouse.y * Math.PI) / 4, (mouse.x * Math.PI) / 2, 0)
coffeeRef.current.quaternion.slerp(rQuaternion.setFromEuler(rEuler), 0.1)
}
})
return (
<group dispose={null} ref={edgeRef} position={position}>
<group ref={coffeeRef}>
<Environment preset={preset || 'warehouse'} />
<mesh ref={mesh} scale={scaleArr} geometry={geo}>
<meshPhysicalMaterial
envMapIntensity={2}
color="#F472B6"
map={colorMap}
clearcoat={0.2}
clearcoat={0.5}
clearcoatRoughness={0.01}
roughness={1}
metalness={0.9}
roughness={0}
metalness={0.7}
smoothShading
/>
</mesh>
@@ -60,12 +57,7 @@ export default function AssetWithGooey({
<lineBasicMaterial color="#aaaaff" />
</lineSegments>
</group>
<pointLight
position={[-1000, -1000, 1000]}
color="#5555FF"
intensity={1}
/>
<ambientLight intensity={0.3} />
<ambientLight intensity={2} />
<Gooey />
</group>
)
@@ -77,7 +69,7 @@ function randomSign(num: number): number {
function Gooey() {
const blobsData = useMemo(() => {
const firstSet = Array.from({ length: 10 }).map((_, index) => {
const firstSet = Array.from({ length: 5 }).map((_, index) => {
const dist = Math.random() * 3 + 2.5
const x = randomSign(Math.random() * dist)
const y = randomSign(Math.sqrt(dist * dist - x * x))
@@ -88,7 +80,7 @@ function Gooey() {
const speed = (Math.random() * 0.8) / size / size + 0.1
return { position, size, distort, speed }
})
const secondSet = Array.from({ length: 10 }).map((_, index) => {
const secondSet = Array.from({ length: 5 }).map((_, index) => {
const dist = Math.random() * 3 + 1.5
const x = randomSign(Math.random() * dist)
const y = randomSign(Math.sqrt(dist * dist - x * x))
@@ -106,11 +98,11 @@ function Gooey() {
{blobsData.map(({ position, size, distort, speed }, index) => (
<Sphere key={index} visible position={position} args={[size, 16, 200]}>
<MeshDistortMaterial
color="#5098F1"
color="#173E6F"
attach="material"
distort={distort} // Strength, 0 disables the effect (default=1)
speed={speed} // Speed (default=1)
roughness={0}
roughness={0.2}
opacity={0.6}
transparent
/>

View File

@@ -1,10 +1,11 @@
import { Canvas, useLoader, useFrame } from '@react-three/fiber'
import { Suspense } from 'react'
import { Html } from '@react-three/drei'
import { Html, Stats } from '@react-three/drei'
import CadPackage, {
CadPackageType,
} from 'src/components/CadPackage/CadPackage'
import { navigate, routes } from '@redwoodjs/router'
import { navigate, routes, Link } from '@redwoodjs/router'
import { useInView } from 'react-intersection-observer'
import Svg, { SvgNames } from 'src/components/Svg/Svg'
import Gravatar from 'src/components/Gravatar/Gravatar'
@@ -45,25 +46,32 @@ export const Hero = () => {
<ModelSection assetUrl="/coffee-lid.stl" offset={heroOffset} scale={0.06}>
<div className="grid lg:grid-cols-2 py-32">
<div className="flex items-end justify-center row-start-2 lg:row-start-1 pt-96 lg:pt-0 pr-12 pl-6">
<div className="grid grid-flow-col gap-4 items-center bg-ch-gray-760 bg-opacity-95 text-ch-gray-300 rounded-md p-2 font-fira-sans relative z-10 shadow-ch">
<div className="pl-4">
<Gravatar
image="CadHub/xvrnxvarkv8tdzo4n65u"
className="w-12 h-12 mr-4"
size={60}
/>
<Link
to={routes.project({
userName: 'irevdev',
projectTitle: 'coffee-lid',
})}
>
<div className="grid grid-flow-col gap-2 sm:gap-4 items-center bg-ch-gray-760 bg-opacity-95 text-ch-gray-300 rounded-md p-2 font-fira-sans relative z-10 shadow-ch">
<div className="pl-1 sm:pl-4">
<Gravatar
image="CadHub/xvrnxvarkv8tdzo4n65u"
className="w-12 h-12 mr-4"
size={60}
/>
</div>
<div>
<div className="text-xl sm:text-3xl">Coffee Lid</div>
<div>IrevDev</div>
</div>
<div className="flex self-start">
<CadPackage
cadPackage="cadquery"
className="px-3 py-1 sm:text-xl rounded transform translate-x-4 sm:translate-x-10"
/>
</div>
</div>
<div>
<div className="text-3xl">Coffee Lid</div>
<div>IrevDev</div>
</div>
<div className="flex self-start">
<CadPackage
cadPackage="cadquery"
className="px-3 py-1 text-xl rounded transform translate-x-10"
/>
</div>
</div>
</Link>
</div>
<div className="col-start-1 lg:col-start-2 px-4">
@@ -100,12 +108,7 @@ export const Hero = () => {
</ModelSection>
<ChooseYourCharacter />
<Community />
<ModelSection
assetUrl="/hinge.stl"
offset={tutOffset}
scale={0.12}
preset="lobby"
>
<ModelSection assetUrl="/hinge.stl" offset={tutOffset} scale={0.12}>
<div className="max-w-7xl mx-auto grid py-16 overflow-hidden">
<div className="py-0 pb-32 lg:py-32 ml-4 col-start-1 lg:col-start-1 pr-12 pl-6">
<div className="text-4xl mb-6 text-ch-gray-300">Learn Code-CAD</div>
@@ -126,25 +129,34 @@ export const Hero = () => {
</div>
<div className="flex items-end justify-center row-start-2 lg:row-start-1 lg:col-start-2 pt-96 lg:pt-0 lg:pr-10">
<div className="grid grid-flow-col gap-2 items-center bg-ch-gray-760 bg-opacity-95 text-ch-gray-300 rounded-md p-2 font-fira-sans relative z-10 shadow-ch">
<div className="pl-4">
<Gravatar
image="CadHub/xvrnxvarkv8tdzo4n65u"
className="w-12 h-12 mr-4"
size={60}
/>
<Link
to={routes.project({
userName: 'irevdev',
projectTitle: 'tutorial-hinge',
})}
>
<div className="grid grid-flow-col sm:gap-2 items-center bg-ch-gray-760 bg-opacity-95 text-ch-gray-300 rounded-md py-2 pl-2 font-fira-sans relative z-10 shadow-ch">
<div className="pl-1 sm:pl-4">
<Gravatar
image="CadHub/xvrnxvarkv8tdzo4n65u"
className="w-12 h-12 mr-4"
size={60}
/>
</div>
<div>
<div className="text-lg sm:text-2xl w-28 sm:w-auto">
Print in Place Hinge
</div>
<div>IrevDev</div>
</div>
<div className="flex self-start">
<CadPackage
cadPackage="openscad"
className="px-3 py-1 sm:text-xl rounded transform translate-x-4 sm:translate-x-10"
/>
</div>
</div>
<div>
<div className="text-2xl">Print in Place Hinge</div>
<div>IrevDev</div>
</div>
<div className="flex self-start">
<CadPackage
cadPackage="openscad"
className="px-3 py-1 text-xl rounded transform translate-x-10"
/>
</div>
</div>
</Link>
</div>
</div>
</ModelSection>
@@ -155,39 +167,47 @@ export const Hero = () => {
)
}
const DisableRender = () => useFrame(() => null, 1000)
function ModelSection({
assetUrl,
offset,
children,
preset,
scale,
}: {
assetUrl: string
offset: number[]
children: React.ReactNode
preset?: string
scale: number
}) {
const { ref, inView } = useInView()
return (
<div className="relative">
{children}
<div className="absolute inset-0">
<div className="absolute inset-0" ref={ref}>
<Canvas
linear
dpr={[1, 2]}
orthographic
camera={{ zoom: 75, position: [0, 0, 500] }}
>
{!inView && <DisableRender />}
<pointLight position={[2, 3, 5]} color="#FFFFFF" intensity={2} />
<pointLight position={[2, 3, -5]} color="#FFFFFF" intensity={2} />
<pointLight position={[-6, 3, -5]} color="#FFFFFF" intensity={2} />
<pointLight position={[-6, 3, 5]} color="#FFFFFF" intensity={2} />
<pointLight position={[2, 1.5, 0]} color="#0000FF" intensity={2} />
<pointLight position={[2, 1.5, 0]} color="#FF0000" intensity={2} />
<Suspense
fallback={<Html center className="loading" children="Loading..." />}
>
<Coffee
assetUrl={assetUrl}
offset={offset}
preset={preset}
scale={scale}
/>
<Coffee assetUrl={assetUrl} offset={offset} scale={scale} />
</Suspense>
{/* uncomment for framerate and render time */}
{/* <Stats showPanel={0} className="three-debug-panel-1" /> */}
{/* <Stats showPanel={1} className="three-debug-panel-2" /> */}
</Canvas>
</div>
</div>
@@ -229,7 +249,7 @@ function ChooseYourCharacter() {
desc: string
}) => (
<li key={cadPackage} className="flex items-center">
<div className="mr-12">
<div className="mr-4 sm:mr-12">
<button
onClick={() => navigate(routes.draftProject({ cadPackage }))}
className="flex-shrink-0 cursor-pointer"
@@ -464,9 +484,12 @@ function Footer() {
</p>
</div>
<div className="grid grid-cols-4 gap-4 flex-grow pl-20 row-start-2 lg:col-start-2 lg:row-start-1 mt-20 lg:mt-0">
<div className="grid sm:grid-cols-4 gap-4 flex-grow pl-20 row-start-2 lg:col-start-2 lg:row-start-1 mt-20 lg:mt-0">
{section.map(({ header, links }) => (
<ul className="text-ch-gray-300 font-fira-sans" key={header}>
<ul
className="text-ch-gray-300 font-fira-sans pt-8 sm:pt-0"
key={header}
>
<li className="text-xl font-bold">{header}</li>
{links.map(({ name, url }) => (
<li className="text-lg mt-6 font-light" key={url}>

View File

@@ -63,7 +63,8 @@ const LoginModal = ({ open, onClose, shouldStartWithSignup = false }) => {
style: {
backgroundColor: 'transparent',
},
}}>
}}
>
<div className="bg-ch-gray-700 max-w-2xl rounded-lg shadow-lg text-ch-gray-300">
<Tabs
value={tab}
@@ -190,7 +191,10 @@ const SignUpForm = ({ onSubmitSignUp, checkBox, setCheckBox, onClose }) => (
checked={checkBox}
onChange={() => setCheckBox(!checkBox)}
/>{' '}
<label htmlFor="signup-toc" className="text-ch-gray-400 text-sm mt-4 cursor-pointer">
<label
htmlFor="signup-toc"
className="text-ch-gray-400 text-sm mt-4 cursor-pointer"
>
Stay up-to-date with CadHub's progress with the founder's (
<OutBound className="underline" to="https://twitter.com/IrevDev">
Kurt's

View File

@@ -1,9 +1,7 @@
import { Link, routes } from '@redwoodjs/router'
import Svg from 'src/components/Svg/Svg'
import { Popover } from '@headlessui/react'
import CadPackage, {
CadPackageType,
} from 'src/components/CadPackage/CadPackage'
import { CadPackageType } from 'src/components/CadPackage/CadPackage'
const menuOptions: {
name: string
@@ -24,9 +22,15 @@ const menuOptions: {
sub: 'beta',
bgClasses: 'bg-ch-blue-700',
dotClasses: 'bg-blue-800',
ideType: 'cadquery'
ideType: 'cadquery',
},
{
name: 'JSCAD',
sub: 'beta',
bgClasses: 'bg-ch-purple-500',
dotClasses: 'bg-yellow-300',
ideType: 'jscad',
},
// { name: 'JSCAD', sub: 'alpha', ideType: 'jscad' }, // TODO #422, add jscad to db schema when were ready to enable saving of jscad projects
]
const NavPlusButton: React.FC = () => {
@@ -42,9 +46,12 @@ const NavPlusButton: React.FC = () => {
{menuOptions.map(({ name, sub, ideType, bgClasses, dotClasses }) => (
<li
key={name}
className={bgClasses+" px-4 py-1 my-4 bg-opacity-30 hover:bg-opacity-70 grid grid-flow-col-dense items-center gap-2"}
className={
bgClasses +
' px-4 py-1 my-4 bg-opacity-30 hover:bg-opacity-70 grid grid-flow-col-dense items-center gap-2'
}
>
<div className={dotClasses + " w-5 h-5 rounded-full"}></div>
<div className={dotClasses + ' w-5 h-5 rounded-full'}></div>
<Link to={routes.draftProject({ cadPackage: ideType })}>
<div>{name}</div>
<div className="text-xs text-ch-gray-400 font-light">{sub}</div>