Draw ripples on mousemove as well
This commit is contained in:
parent
50b88dec67
commit
398aa43338
9 changed files with 36 additions and 11 deletions
0
.gitignore → client/.gitignore
vendored
0
.gitignore → client/.gitignore
vendored
|
|
@ -4,6 +4,7 @@
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>ripples | compost.party</title>
|
<title>ripples | compost.party</title>
|
||||||
|
<link rel="stylesheet" href="/src/style.css" type="text/css" media="screen" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<canvas id="canvas"></canvas>
|
<canvas id="canvas"></canvas>
|
||||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
|
@ -1,20 +1,22 @@
|
||||||
import './style.css'
|
|
||||||
|
|
||||||
const canvas = document.querySelector<HTMLCanvasElement>('#canvas')!
|
const canvas = document.querySelector<HTMLCanvasElement>('#canvas')!
|
||||||
|
|
||||||
const ctx = canvas.getContext('2d')!
|
const ctx = canvas.getContext('2d')!
|
||||||
|
|
||||||
const MIN_RADIUS = 20
|
const MIN_RADIUS = 20
|
||||||
const MAX_RADIUS = 200
|
const MAX_RADIUS = 200
|
||||||
const MAX_AGE = 5000 // in milliseconds
|
const MAX_AGE = 1000 // in milliseconds
|
||||||
|
|
||||||
|
type Point = [number, number]
|
||||||
|
|
||||||
type Particle = {
|
type Particle = {
|
||||||
position: [number, number],
|
position: Point
|
||||||
age: number
|
age: number
|
||||||
|
maxRadius: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const createParticle = (x: number, y: number): Particle => ({
|
const createParticle = (position: [number, number], maxRadius: number): Particle => ({
|
||||||
position: [x, y],
|
position,
|
||||||
|
maxRadius,
|
||||||
age: 0,
|
age: 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -24,12 +26,35 @@ let state = {
|
||||||
|
|
||||||
type State = typeof state
|
type State = typeof state
|
||||||
|
|
||||||
canvas.addEventListener('click', (e) => {
|
canvas.addEventListener('mousedown', (e) => {
|
||||||
// TODO Normalize x and y coords
|
// 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)
|
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 => ({
|
const update = (state: State, deltaTime: number): State => ({
|
||||||
particles: state.particles
|
particles: state.particles
|
||||||
.map(p => ({
|
.map(p => ({
|
||||||
|
|
@ -44,12 +69,12 @@ const render = (state: State, ctx: CanvasRenderingContext2D) => {
|
||||||
|
|
||||||
for (const particle of state.particles) {
|
for (const particle of state.particles) {
|
||||||
const progress = (particle.age / MAX_AGE)
|
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.beginPath()
|
||||||
ctx.strokeStyle = `rgba(40, 40, 40, ${opacity})`
|
ctx.strokeStyle = `rgba(40, 40, 40, ${opacity})`
|
||||||
const [x, y] = particle.position
|
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.ellipse(x, y, radius, radius, 0, 0, Math.PI * 2)
|
||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
}
|
}
|
||||||
|
|
@ -7,5 +7,4 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas {
|
canvas {
|
||||||
|
|
||||||
}
|
}
|
||||||
0
src/vite-env.d.ts → client/src/vite-env.d.ts
vendored
0
src/vite-env.d.ts → client/src/vite-env.d.ts
vendored
Loading…
Add table
Add a link
Reference in a new issue