Nodepen is a web client for Grasshopper. This monorepo is for the main @nodepen/nodes
React app library and its supporting packages.
This project is under active development towards a 2.0 release that will:
- Publish useful bits of the previous release as javascript and React modules
- Integrate with Speckle for backend processes and frontend geometry
- Compose, execute, and view results from your Grasshopper graphs in the browser
- Or, upload an existing script and continue working on the web
- Easily pin any number of parameters for a quick configurator-like experience
- Open the same graph in multiple browser windows for the "two screen" UX we've come to love with Rhino and Grasshopper
- Download your current graph to continue work in Grasshopper offline
Minimal
import type * as NodePen from '@nodepen/core'
import { NodesApp, DocumentView, SpeckleModelView } from '@nodepen/nodes'
const MyApp = () => {
const document: NodePen.Document = { ...yourData }
const streamId = "your-speckle-stream-id"
return (
<NodesApp document={document}>
<DocumentView />
<SpeckleModelView streamId={streamId} />
</NodesApp>
)
}
Not minimal:
import { useState, useCallback } from 'react'
import type * as NodePen from '@nodepen/core'
import { NodesApp, DocumentView, SpeckleModelView } from '@nodepen/nodes'
import type { NodesAppState, NodesAppCallbacks } from '@nodepen/nodes'
type MyAppProps = {
templates: NodePen.NodeTemplate[]
}
const MyApp = ({ templates }: MyAppProps) => {
const [document, setDocument] = useState<NodePen.Document>()
const [solution, setSolution] = useState<NodePen.SolutionData>()
const handleDocumentChange = useCallback((state: NodesAppState) => {
const { document } = state
// React to document changes
}, [])
const handleExpireSolution = useCallback((state: NodesAppState) => {
const { document, solution } = state
// React to new solution requests
const fetchSolution = async (): Promise<NodePen.SolutionData> => {
const response = await fetch('your-endpoint', { method: 'POST', body: { id: solution.id, document }})
const data = await response.json()
// Do work with solution data
return data
}
fetchSolution().then((solutionData) => setSolution(solutionData))
}, [])
const callbacks: NodesAppCallbacks = {
handleDocumentChange,
handleExpireSolution
}
return (
<NodesApp document={document} templates={templates} solution={solution} {...callbacks}>
<DocumentView editable />
<SpeckleModelView streamId={streamId} />
</NodesApp>
)
}
WIP
WIP
Rhinoceros and Grasshopper are registered trademarks of Robert McNeel & Associates.
All 3D visuals are powered by the Speckle Viewer.
Previous drafts of NodePen included the "RestHopper" headless Grasshopper prototype developed at the 2018 AEC Tech Hackathon.