Add presence info message

This commit is contained in:
arne 2024-01-27 12:30:37 +01:00
commit d5abc17760
3 changed files with 29 additions and 5 deletions

View file

@ -7,6 +7,7 @@
<link rel="stylesheet" href="/src/style.css" type="text/css" media="screen" /> <link rel="stylesheet" href="/src/style.css" type="text/css" media="screen" />
</head> </head>
<body> <body>
<div id="presence-info"></div>
<canvas id="canvas"></canvas> <canvas id="canvas"></canvas>
<script type="module" src="/src/main.ts"></script> <script type="module" src="/src/main.ts"></script>
</body> </body>

View file

@ -1,3 +1,4 @@
const presenceInfo = document.querySelector<HTMLDivElement>('#presence-info')!
const canvas = document.querySelector<HTMLCanvasElement>('#canvas')! const canvas = document.querySelector<HTMLCanvasElement>('#canvas')!
const socket = new WebSocket(`ws://${window.location.hostname}:3000`) const socket = new WebSocket(`ws://${window.location.hostname}:3000`)
@ -20,7 +21,8 @@ type Particle = {
} }
let state = { let state = {
particles: <Particle[]>[] particles: <Particle[]>[],
others: 0
} }
type State = typeof state type State = typeof state
@ -47,7 +49,10 @@ const makeRipple = (position: [number, number], radius: number): void => {
canvas.addEventListener('mousedown', (e) => { canvas.addEventListener('mousedown', (e) => {
// TODO Normalize x and y coords // TODO Normalize x and y coords
const radius = MAX_RADIUS const radius = MAX_RADIUS
makeRipple([e.clientX, e.clientY], radius) makeRipple([
e.clientX / document.body.offsetWidth,
e.clientY / document.body.offsetHeight
], radius)
}) })
// create a smaller ripple when moving over the screen // create a smaller ripple when moving over the screen
@ -70,7 +75,10 @@ canvas.addEventListener('mousemove', (e) => {
const shouldSpawn = hasSpace.next().value! const shouldSpawn = hasSpace.next().value!
if (shouldSpawn([e.clientX, e.clientY])) { if (shouldSpawn([e.clientX, e.clientY])) {
const radius = MAX_RADIUS / 3*2 const radius = MAX_RADIUS / 3*2
makeRipple([e.clientX, e.clientY], radius) makeRipple([
e.clientX / document.body.offsetWidth,
e.clientY / document.body.offsetHeight
], radius)
} }
}) })
@ -82,7 +90,13 @@ socket.addEventListener('message', (e) => {
const message = JSON.parse(e.data) const message = JSON.parse(e.data)
if (message?.type === 'presence-information') { if (message?.type === 'presence-information') {
const data = <Message & { type: 'presence-information' }>message const data = <Message & { type: 'presence-information' }>message
console.log(`i'm seeing ${data.others} others around the pond`) state.others = data.others
// TODO: Would be nicer to have this DOM update elsewhere
presenceInfo.innerText = 'You see a pond. ' + (state.others === 0
? 'You are currently alone here.'
: state.others === 1
? 'Somebody else is also here.'
: `There are ${state.others} others with you.`)
} else if (message?.type === 'ripple') { } else if (message?.type === 'ripple') {
const data = <Message & { type: 'ripple' }>message const data = <Message & { type: 'ripple' }>message
const particle = createParticle(data.position, data.maxRadius) const particle = createParticle(data.position, data.maxRadius)
@ -97,6 +111,7 @@ socket.addEventListener('message', (e) => {
// update the particles and remove them after a certain time // update the particles and remove them after a certain time
const update = (state: State, deltaTime: number): State => ({ const update = (state: State, deltaTime: number): State => ({
...state,
particles: state.particles particles: state.particles
.map(p => ({ .map(p => ({
...p, ...p,
@ -117,7 +132,7 @@ const render = (state: State, ctx: CanvasRenderingContext2D) => {
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 * (particle.maxRadius - 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 * document.body.offsetWidth, y * document.body.offsetHeight, radius, radius, 0, 0, Math.PI * 2)
ctx.stroke() ctx.stroke()
} }
} }

View file

@ -4,6 +4,14 @@ body {
min-height: 100vh; min-height: 100vh;
padding: 0; padding: 0;
margin: 0; margin: 0;
overflow: hidden;
}
#presence-info {
position: absolute;
top: 24px;
left: 24px;
pointer-events: none
} }
canvas { canvas {