diff --git a/.gitignore b/client/.gitignore
similarity index 100%
rename from .gitignore
rename to client/.gitignore
diff --git a/bun.lockb b/client/bun.lockb
similarity index 100%
rename from bun.lockb
rename to client/bun.lockb
diff --git a/index.html b/client/index.html
similarity index 79%
rename from index.html
rename to client/index.html
index 3504586..faa4336 100644
--- a/index.html
+++ b/client/index.html
@@ -4,6 +4,7 @@
ripples | compost.party
+
diff --git a/package.json b/client/package.json
similarity index 100%
rename from package.json
rename to client/package.json
diff --git a/public/vite.svg b/client/public/vite.svg
similarity index 100%
rename from public/vite.svg
rename to client/public/vite.svg
diff --git a/src/main.ts b/client/src/main.ts
similarity index 55%
rename from src/main.ts
rename to client/src/main.ts
index ec0d437..f086056 100644
--- a/src/main.ts
+++ b/client/src/main.ts
@@ -1,20 +1,22 @@
-import './style.css'
-
const canvas = document.querySelector('#canvas')!
const ctx = canvas.getContext('2d')!
const MIN_RADIUS = 20
const MAX_RADIUS = 200
-const MAX_AGE = 5000 // in milliseconds
+const MAX_AGE = 1000 // in milliseconds
+
+type Point = [number, number]
type Particle = {
- position: [number, number],
+ position: Point
age: number
+ maxRadius: number
}
-const createParticle = (x: number, y: number): Particle => ({
- position: [x, y],
+const createParticle = (position: [number, number], maxRadius: number): Particle => ({
+ position,
+ maxRadius,
age: 0,
})
@@ -24,12 +26,35 @@ let state = {
type State = typeof state
-canvas.addEventListener('click', (e) => {
+canvas.addEventListener('mousedown', (e) => {
// TODO Normalize x and y coords
- const particle = createParticle(e.clientX, e.clientY)
+ const particle = createParticle([e.clientX, e.clientY], MAX_RADIUS)
state.particles.push(particle)
})
+function* minDist(dist: number) {
+ let prev: Point
+ while (true) {
+ yield (cur: Point) => {
+ if (prev == null || Math.sqrt(Math.pow(prev[0]-cur[0], 2) + Math.pow(prev[1]-cur[1], 2)) >= dist) {
+ prev = cur
+ return true
+ }
+ return false
+ }
+ }
+}
+
+const hasSpace = minDist(70)
+
+canvas.addEventListener('mousemove', (e) => {
+ const shouldSpawn = hasSpace.next().value!
+ if (shouldSpawn([e.clientX, e.clientY])) {
+ const particle = createParticle([e.clientX, e.clientY], MAX_RADIUS / 3*2)
+ state.particles.push(particle)
+ }
+})
+
const update = (state: State, deltaTime: number): State => ({
particles: state.particles
.map(p => ({
@@ -44,12 +69,12 @@ const render = (state: State, ctx: CanvasRenderingContext2D) => {
for (const particle of state.particles) {
const progress = (particle.age / MAX_AGE)
- const opacity = Math.min(1, (1-progress)*(1-progress))
+ const opacity = Math.min(1, Math.pow(1-progress, 3)) * (particle.maxRadius / MAX_RADIUS)
ctx.beginPath()
ctx.strokeStyle = `rgba(40, 40, 40, ${opacity})`
const [x, y] = particle.position
- const radius = (progress * (MAX_RADIUS - MIN_RADIUS)) + MIN_RADIUS
+ const radius = (progress * (particle.maxRadius - MIN_RADIUS)) + MIN_RADIUS
ctx.ellipse(x, y, radius, radius, 0, 0, Math.PI * 2)
ctx.stroke()
}
diff --git a/src/style.css b/client/src/style.css
similarity index 98%
rename from src/style.css
rename to client/src/style.css
index 92912df..38c53a1 100644
--- a/src/style.css
+++ b/client/src/style.css
@@ -7,5 +7,4 @@ body {
}
canvas {
-
}
diff --git a/src/vite-env.d.ts b/client/src/vite-env.d.ts
similarity index 100%
rename from src/vite-env.d.ts
rename to client/src/vite-env.d.ts
diff --git a/tsconfig.json b/client/tsconfig.json
similarity index 100%
rename from tsconfig.json
rename to client/tsconfig.json