Last active
January 17, 2021 22:06
-
-
Save wonglok/cdb7cf080f6263872b4042eeaae6f1ca to your computer and use it in GitHub Desktop.
EffectNode.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let isFunction = function(obj) { | |
return typeof obj === 'function' || false; | |
} | |
class EventEmitter { | |
// https://gist.github.com/datchley/37353d6a2cb629687eb9 | |
constructor() { | |
this.listeners = new Map(); | |
} | |
on(label, callback) { | |
this.listeners.has(label) || this.listeners.set(label, []); | |
this.listeners.get(label).push(callback); | |
return () => { | |
this.off(label, callback) | |
} | |
} | |
off(label, callback) { | |
let listeners = this.listeners.get(label), | |
index; | |
if (listeners && listeners.length) { | |
index = listeners.reduce((i, listener, index) => { | |
return (isFunction(listener) && listener === callback) ? | |
i = index : | |
i; | |
}, -1); | |
if (index > -1) { | |
listeners.splice(index, 1); | |
this.listeners.set(label, listeners); | |
return true; | |
} | |
} | |
return false; | |
} | |
emit (label, ...args) { | |
let listeners = this.listeners.get(label); | |
if (listeners && listeners.length) { | |
listeners.forEach((listener) => { | |
listener(...args); | |
}); | |
return true; | |
} | |
return false; | |
} | |
} | |
class Wire extends EventEmitter { | |
constructor () { | |
super() | |
} | |
} | |
export class AutoWire { | |
constructor () { | |
let map = new Map() | |
let proxy = new Proxy({}, { | |
get: (object, key) => { | |
if (map.has(key)) { | |
return map.get(key) | |
} else { | |
let wire = new Wire() | |
map.set(key, wire) | |
return wire | |
} | |
}, | |
set: (object, key, val) => { | |
console.log('enWire is read only') | |
return true | |
} | |
}) | |
return proxy | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState, useRef, useEffect, useMemo } from "react" | |
import { Canvas } from "react-three-fiber" | |
import { ACESFilmicToneMapping, sRGBEncoding } from "three" | |
import { AutoWire } from "./effectnode" | |
// let getID = () => `_${(Math.random() * 100000000).toFixed(0)}` | |
function useInput (input, event, fnc, memo = []) { | |
useEffect(() => { | |
let off = input.on(event, fnc) | |
return () => { | |
off() | |
} | |
}, memo) | |
} | |
export function BoxClicker ({ output, ...props }) { | |
let onClick = () => { output.emit('data', { rand: Math.random() }) } | |
let Html = require('drei').Html | |
return <mesh | |
{...props} | |
onClick={onClick} | |
> | |
<Html | |
center | |
> | |
<div onClick={onClick} className="w-32">Click Me</div> | |
</Html> | |
<boxBufferGeometry args={[1,1,1]}></boxBufferGeometry> | |
<meshStandardMaterial color={'#bababa'}></meshStandardMaterial> | |
</mesh> | |
} | |
export function BoxColor ({ input, ...props }) { | |
const [color, setColor] = useState(0xffffff) | |
let onClick = () => { props.output.emit('data', { rand: Math.random() }) } | |
useInput(input, 'data', ({ rand }) => { | |
setColor(0xffffff * rand) | |
}) | |
return <mesh | |
{...props} | |
onClick={() => { onClick() }} | |
> | |
<boxBufferGeometry args={[1,1,1]}></boxBufferGeometry> | |
<meshStandardMaterial color={color}></meshStandardMaterial> | |
</mesh> | |
} | |
export function MyCanvasScene () { | |
let wire = useMemo(() => { | |
// Singleton + Lazy Instantiatoin | |
return new AutoWire() | |
}, []) | |
return <scene> | |
<BoxClicker position={[-1,0,0]} output={wire.lok}></BoxClicker> | |
<BoxColor position={[1,0,0]} input={wire.lok}></BoxColor> | |
<BoxColor position={[1,1.1,0]} input={wire.lok}></BoxColor> | |
<BoxColor position={[1,-1.1,0]} input={wire.lok}></BoxColor> | |
</scene> | |
} | |
export default function EffectNode () { | |
const mouse = useRef({ x: 0, y: 0 }) | |
return <Canvas | |
shadowMap | |
pixelRatio={[1.2, 2.0]} | |
// onPointerMove={(e) => ( mouse.current = getMousePos(e)) }} | |
// onTouchMove={(e) => { mouse.current = getFirstTouchPos(e); }} | |
// onTouchStart={(e) => { mouse.current = getFirstTouchPos(e); }} | |
onCreated={({ gl }) => { | |
gl.toneMapping = ACESFilmicToneMapping | |
gl.outputEncoding = sRGBEncoding | |
mouse.current.x = gl.domElement.width / 2 | |
mouse.current.y = gl.domElement.height / 2 | |
}} | |
> | |
<ambientLight intensity={1}></ambientLight> | |
<MyCanvasScene dispose={null} mouse={mouse}></MyCanvasScene> | |
</Canvas> | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment