Installation
npm i three @react-three/fiber react-mol
Quick started
git clone https://github.com/tseijp/react-mol
- Now you can go to our demo, and try its usage.
Recipes
<td>
<strong><a href="#recipes-of-atom">Atom</a></strong>
<ul>
<li><a href="#Recipes-of-mol">Mol</a></li>
<li><a href="#Recipes-of-flow">Flow</a></li>
<li><a href="#Recipes-of-tile">Tile</a></li>
<li><a href="#Recipes-of-spring">Spring</a></li>
</ul>
</td>
<td>
<strong><a href="#recipes-of-mol">Mol</a></strong>
<ul>
<li><a href="#Methyl alcohol">Methyl alcohol</a></li>
<li><a href="#Polyethylene">Polyethylene</a></li>
<li><a href="#Acetil-acid">Acetil Acid</a></li>
</ul>
</td>
<td>
<strong><a href="#recipes-of-flow">Flow</a></strong>
<ul>
<li><a href="#Points">Points</a></li>
<li><a href="#Boxes">Boxes</a></li>
<li><a href="#Spheres">Spheres</a></li>
<li><a href="#Dodecas">Dodecas</a></li>
</ul>
</td>
<td>
<strong><a href="#recipes-of-tile">Tile</a></strong>
<ul>
<li><a href="#Basic">Basic</a></li>
</ul>
</td>
<td>
<strong><a href="#recipes-of-spring">Spring</a></strong>
<ul>
<li><a href="#Pieces">Pieces</a></li>
<li><a href="#Bounds">Bounds</a></li>
<li><a href="#Pipes">Pipes</a></li>
</ul>
</td>
Recipes of Atom
š”<Mol/> is a molecular chemistry based simulation component
that covers most cases of organic molecule simulation.
(More Recipes)
View Code
```tsx
import React from 'react'
import { Atom } from 'react-mol'
export const Mol = React.forwardRef((props, ref) => {
const {index: i, angle: a, double:d} = props
const state = React.useMemo(() => {
const position = calcMolPos(i, a, d)
const rotation = eulerVec3(position, [0,1,0])
return {position, rotation}
}, i, a, d)
const children = React.useMemo(() =>
React.Children.map(props.children, (child, index) =>
React.cloneElement(child, {index})
), [props.children])
return {...state} children={children}/>
})
```
|
|
š<Flow/>
(More Recipes)
View Code
```tsx
import React from 'react'
import { Atom } from 'react-mol'
import { useFrame } from ""
export const Flow = React.forwardRef((props, forwardRef) => {
const now = React.useRef(0)
const ref = React.useRef(null)
const fun = (value) => typeof value==="function"
useFrame((, delta) => {
if (!ref.current) return
now.current += delta
const { position: p, scale: s, args: a,
rotation: r, color: c } = props
const args = fun(a)
? a(now.current,...ref.current.position.toArray())
: [ now.current,...(a || []) ]
p && ref.current.position.set(...(fun(p)? p(...args): p))
r && ref.current.rotation.set(...(fun(r)? r(...args): r))
s && ref.current.scale.set(...(fun(s)? s(...args): s))
c && ref.current.color.set(fun(c)? c(...args): c)
})
return
})
```
|
|
What does it look like?
).
<a href="https://tsei.jp/rmol/Basic/Basic"><img
src="" /></a>
|
```tsx
import React from 'react'
import ReactDOM from 'react-dom'
import { Atom } from 'react-mol'
import { Canvas, useFrame } from ''
function Basic () {
// This reference will give us direct access to the last instance
const ref = React.useRef(null)
// Rotate instance every frame, this is outside of React without overhead
useFrame(() => {
ref.current.rotation.x =
ref.current.rotation.y =
ref.current.rotation.z += 0.025
})
return (
<Instanced>
<boxBufferGeometry attach="geometry" />
<meshPhongMaterial attach="material" />
<Atom color="red" position={[1, -2, -5]} rotation={[0, 0, Math.PI/3]}>
<Atom color="green" position={[2, 0, 1]} rotation={[0, 0, Math.PI/3]}>
<Atom color="green" position={[2, 0, 1]} rotation={[0, 0, Math.PI/3]}>
<Atom color="green" position={[2, 0, 1]} rotation={[0, 0, Math.PI/3]}>
<Atom color="green" position={[2, 0, 1]} rotation={[0, 0, Math.PI/3]}>
<Atom color="green" position={[2, 0, 1]} rotation={[0, 0, Math.PI/3]}>
<Atom color="blue" position={[2, 0, 0]} ref={ref}/>
</Atom>
</Atom>
</Atom>
</Atom>
</Atom>
</Atom>
</Instanced>
)
}
ReactDOM.render(
<pointLight />
<ambientLight />
<Basic />
,
document.getElementById('root')
)
```
Show Recursion Example
```tsx
import React from 'react'
import ReactDOM from 'react-dom'
import { Atom } from 'react-mol'
import { Canvas, useFrame } from ''
function Basic () {
// This reference will give us direct access to the last instance
const ref = React.useRef(null)
// Rotate instance every frame, this is outside of React without overhead
useFrame(() => {
ref.current.rotation.x =
ref.current.rotation.y =
ref.current.rotation.z += 0.025
})
return (
<Instanced>
<Recursion>
<boxBufferGeometry/>
<meshPhongMaterial/>
<Atom color="red" position={[1, -2, -5]} rotation={[0, 0, Math.PI/3]}/>
{[...Array(5)].map((_, i) =>
<Atom color="green" position={[2, 0, 1]} rotation={[0, 0, Math.PI/3]} key={i}/>
)}
<Atom color="blue" position={[2, 0, 0]} ref={ref}/>
</Recursion>
</Instanced>
)
}
ReactDOM.render(
<pointLight/>
<ambientLight/>
<Basic/>
,
document.getElementById('root')
)
```
Recipes of Mol
|
|
|
|
Methyl alcohol
|
```tsx
```
|
```tsx
```
|
|
Acetil acid
|
```tsx
```
|
```tsx
```
|
|
Poly ethylene
|
```tsx
{next =>
<CH2>
<CH2>
{next||<H/>}
</CH2>
</CH2>
}
```
|
```tsx
{Array(200)
.fill(0)
.map((,i) =>
<C key={i}>
<H/>
<H/>
</C>
)}
```
|
|
Recipes of Flow
|
|
|
Points
|
```tsx
-12.5,0,-25} count={2500}>
{...Array(2500).map((,i) =>
<Flow key={i} color={colors[i]}
args={(t,x,_,z) => [
sin((x+t)/3)+sin((z+t)/2)]}
position={r => [i%c,r,i/c%c]}
scale={r => [r/3,r/3,r/3]} />
)}
```
|
|
Boxes
|
```tsx
3}>
{...Array(1000).map((,i) =>
<Flow key={i} color={colors[i]}
args={(t,x,y,z) => [
sin(x/4+t)+sin(y/4+t)+sin(z/4+t) ]}
position={[i%10-5,i/10%10-5,i/100-5]}
rotation={r => [0,r*2,r*3]}
scale={r => [r/4,r/4,r/4]}/>
)}
```
|
|
Spheres
|
```tsx
1,32,32}/>
{...Array(1000).map((, i) =>
<Flow key={i} color={colors[i]}
args={[...Array(4)].map(() => rand())}
position={(t,s,x,y,z) => [
x*40-20 + cos(t*s*6) + sin(t*s*2),
y*40-20 + sin(t*s*4) + cos(t*s*4),
z*40-20 + cos(t*s*2) + sin(t*s*6),]}
scale={(t,s) => Array(3).fill(
max(.3, cos((t+s*10)*s))*s)}/>
)}
```
|
|
Dodecas
|
```tsx
1,0}/>
{...Array(1000).map((,i) =>
<Flow key={i} color={colors[i]}
args={[...Array(4)].map(() => rand())}
position={(t,s,x,y,z) => [
((x-.5)-cos(t*s+x)-sin(t*s/1))*x*100,
((y-.5)-sin(t*s+y)-cos(t*s/3))*y*100,
((z-.5)-cos(t*s+z)-sin(t*s/5))*z*100,]}
rotation={(t,s)=>Array(3).fill(cos(t*s))}
scale={(t,s)=>Array(3).fill(cos(t*s))}/>
)}
```
|
|
Recipes of Spring
Recipes of Tile
Recipes of Plant
TODO
Koch Curve
```tsx
90,90}>
```
|
Meandering Snake
```tsx
LR={[90,90]}>
```
|
Urban Charting
```tsx
LR={[90,90]}>
```
|