added mode support

main
Antonio De Lucreziis 2 years ago
parent 1dd1c47903
commit 56096644a0

@ -2,6 +2,7 @@ import { useEffect, useRef, useState } from 'preact/hooks'
import { enforceDistance } from '../../lib/math/constraint.js' import { enforceDistance } from '../../lib/math/constraint.js'
import { resampleCurve } from '../../lib/math/curves.js' import { resampleCurve } from '../../lib/math/curves.js'
import { Vec2, Vec3 } from '../../lib/math/math.js' import { Vec2, Vec3 } from '../../lib/math/math.js'
import { MODE_DRAW, MODE_FLIP, MODE_DRAG } from '../pages.jsx'
function mod(i, modulus) { function mod(i, modulus) {
const r = i % modulus const r = i % modulus
@ -58,22 +59,26 @@ class KnotSimulation {
this.mousePosition = [x, y] this.mousePosition = [x, y]
if (buttons === 1) { if (buttons === 1) {
this.ghostPath = [] switch (this.modeRef.current) {
} case MODE_DRAW:
if (buttons === 2) { this.ghostPath = []
const [i] = Vec2.findNearest( break;
this.particleSimulation.positions.map(([x, y]) => [x, y]), case MODE_FLIP:
this.mousePosition const { positions } = this.particleSimulation
)
this.draggingIndex = i for (let i = 0; i < positions.length; i++) {
} if (Vec2.distance2([x, y], positions[i]) < INVERT_CROSSING_RADIUS) {
if (buttons === 4) { positions[i][2] *= -1
const { positions } = this.particleSimulation }
}
for (let i = 0; i < positions.length; i++) { break;
if (Vec2.distance2([x, y], positions[i]) < INVERT_CROSSING_RADIUS) { case MODE_DRAG:
positions[i][2] *= -1 const [i] = Vec2.findNearest(
} this.particleSimulation.positions.map(([x, y]) => [x, y]),
this.mousePosition
)
this.draggingIndex = i
break;
} }
} }
} }
@ -318,9 +323,9 @@ class KnotSimulation {
} }
} }
export const KnotLayer = ({ knotRef }) => { export const KnotLayer = ({ knotRef, modeRef }) => {
const canvasRef = useRef(null) const canvasRef = useRef(null)
const [knotSim] = useState(() => new KnotSimulation(knotRef)) const [knotSim] = useState(() => new KnotSimulation(knotRef, modeRef))
useEffect(() => { useEffect(() => {
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
@ -353,17 +358,17 @@ export const KnotLayer = ({ knotRef }) => {
return ( return (
<canvas <canvas
ref={canvasRef} ref={canvasRef}
onMouseDown={e => { onPointerDown={e => {
knotSim.onMouseDown(e.offsetX, e.offsetY, e.buttons) knotSim.onMouseDown(e.offsetX, e.offsetY, e.buttons)
}} }}
onMouseMove={e => { onPointerMove={e => {
if (canvasRef.current && e.buttons > 0) { if (canvasRef.current && e.buttons > 0) {
knotSim.onMouseDrag(e.offsetX, e.offsetY, e.buttons) knotSim.onMouseDrag(e.offsetX, e.offsetY, e.buttons)
requestAnimationFrame(() => knotSim.render(canvasRef.current.graphicsContext)) requestAnimationFrame(() => knotSim.render(canvasRef.current.graphicsContext))
} }
}} }}
onContextMenu={e => e.preventDefault()} onContextMenu={e => e.preventDefault()}
onMouseUp={e => { onPointerUp={e => {
if (canvasRef.current) { if (canvasRef.current) {
knotSim.onMouseUp() knotSim.onMouseUp()
requestAnimationFrame(() => knotSim.render(canvasRef.current.graphicsContext)) requestAnimationFrame(() => knotSim.render(canvasRef.current.graphicsContext))

@ -1,4 +1,4 @@
import { useRef } from 'preact/hooks' import { useRef, useState } from 'preact/hooks'
import { KnotLayer } from './components/KnotLayer.jsx' import { KnotLayer } from './components/KnotLayer.jsx'
export const PageHomepage = ({}) => { export const PageHomepage = ({}) => {
@ -9,10 +9,20 @@ export const PageHomepage = ({}) => {
) )
} }
function filterClasses(...classes) {
return classes.filter(Boolean).join(' ')
}
export const MODE_DRAW = 'draw'
export const MODE_FLIP = 'flip'
export const MODE_DRAG = 'drag'
export const PageKnotEditor = ({}) => { export const PageKnotEditor = ({}) => {
const knot1 = useRef({ const knot1 = useRef({ points: [] })
points: [], const [mode, setMode] = useState(MODE_DRAW)
})
const modeRef = useRef(mode)
modeRef.current = mode
return ( return (
<main> <main>
@ -26,13 +36,13 @@ export const PageKnotEditor = ({}) => {
<div class="label">Tools</div> <div class="label">Tools</div>
<div class="content"> <div class="content">
<div class="compound-select"> <div class="compound-select">
<button class="icon selected"> <button class={filterClasses("icon", mode === MODE_DRAW && 'selected')} onClick={() => setMode(MODE_DRAW)}>
<span class="material-symbols-outlined">gesture</span> <span class="material-symbols-outlined">gesture</span>
</button> </button>
<button class="icon"> <button class={filterClasses("icon", mode === MODE_FLIP && 'selected')} onClick={() => setMode(MODE_FLIP)}>
<span class="material-symbols-outlined">swap_vert</span> <span class="material-symbols-outlined">swap_vert</span>
</button> </button>
<button class="icon"> <button class={filterClasses("icon", mode === MODE_DRAG && 'selected')} onClick={() => setMode(MODE_DRAG)}>
<span class="material-symbols-outlined">pinch</span> <span class="material-symbols-outlined">pinch</span>
</button> </button>
</div> </div>
@ -86,7 +96,7 @@ export const PageKnotEditor = ({}) => {
</div> </div>
</div> </div>
<div class="work-area"> <div class="work-area">
<KnotLayer knotRef={knot1} /> <KnotLayer knotRef={knot1} modeRef={modeRef} />
</div> </div>
</main> </main>
) )

Loading…
Cancel
Save