Skip to content

Commit

Permalink
smoother cursor movement with waapi
Browse files Browse the repository at this point in the history
patch for preactjs/preact #4635
  • Loading branch information
lilnasy committed Jan 22, 2025
1 parent 57d584b commit 3dd06a6
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 65 deletions.
3 changes: 1 addition & 2 deletions Caddyfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# docker run --rm -it --name caddy-builder golang:1.23.4-alpine3.21
## apk add git
## go install github.com/caddyserver/xcaddy/cmd/xcaddy@eb894be
## xcaddy build v2.9.1 --with github.com/abiosoft/caddy-exec@521d873
# docker cp caddy-builder:/go/caddy /usr/local/bin/caddy && docker stop caddy-builder
Expand Down Expand Up @@ -29,7 +28,7 @@ sillystring.party:443 {
exec @auth {
directory /app
command ash
args -c "curl --silent --location --header 'Authorization: token {env.GITHUB_PAT}' --output dist.zip https://api.github.com/repos/lilnasy/tic-tac-toe/actions/artifacts/{query.artifact_id}/zip && unzip -q -o -d dist dist.zip && rm dist.zip && service tictactoe restart"
args -c "curl --silent --location --header 'Authorization: token {env.GITHUB_PAT}' --output dist.zip https://api.github.com/repos/lilnasy/tic-tac-toe/actions/artifacts/{query.artifact_id}/zip && unzip -q -o -d dist dist.zip && rm dist.zip && service tictactoe restart --quiet"
}
}
reverse_proxy 127.0.0.1:4321
Expand Down
110 changes: 65 additions & 45 deletions components/Menus.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import cx from "clsx/lite"
import { css } from "astro:emotion"
import { throttle } from "vendor/sindresorhus/throttleit/index.ts"
import { signal } from "lib/signal-decorator.ts"
import { ClientWorld, type WorldData } from "game/world.client.ts"
import type { CursorSync, MessageRegistry, Messages } from "game/messages.d.ts"
import type { Receiver } from "game/channel.d.ts"
Expand Down Expand Up @@ -135,8 +134,10 @@ class TitleScreen extends Component<{
}

class Cursors extends Component implements Receiver {

current: HTMLTemplateElement | null = null

@signal accessor #cursors: CursorSync = []
#cursors = new Map<string, SVGSVGElement>()

#sendCursorMove = throttle((event: MouseEvent) => {
this.world.channel.send("CursorMove", [
Expand All @@ -151,56 +152,75 @@ class Cursors extends Component implements Receiver {
}

receive<Message extends Messages>(message: Message, data: MessageRegistry[Message]) {
if (message === "CursorSync") {
this.#cursors = data as CursorSync
if (message === "CursorSync" && this.current) {
const sync: CursorSync = data
for (const [id, x, y] of sync) {
let cursor = this.#cursors.get(id)
if (!cursor) {
const fragment = this.current!.content.cloneNode(true) as DocumentFragment
cursor = fragment.firstElementChild as SVGSVGElement
cursor.style.setProperty("--id", `#${id.slice(0, 6)}`)
document.body.appendChild(cursor)
this.#cursors.set(id, cursor)
}
cursor.animate([
{},
{ translate: `${x + window.innerWidth / 2}px ${y + window.innerHeight / 2}px` }
], {
duration: 100,
easing: "linear",
fill: "forwards"
})
}

// Remove cursors that are no longer in the lobby
for (const [ id, element ] of this.#cursors) {
if (!sync.some(([cursorId]) => cursorId === id)) {
element.remove()
this.#cursors.delete(id)
}
}
}
}

componentWillUnmount() {
removeEventListener("mousemove", this.#sendCursorMove)
this.world.channel.unsubscribe(this)
this.#cursors.forEach(element => element.remove())
this.#cursors.clear()
}

render() {
return <>{
this.#cursors.map(([ id, x, y ]) =>
<svg
key={id}
class={css`
position: absolute;
top: 0;
left: 0;
pointer-events: none;
height: 1rem;
fill: oklch(from var(--id) 0.7 0.15 h);
stroke: white;
stroke-width: 0.25rem;
filter: var(--drop-shadow-subtle);
will-change: translate;
transition: translate 50ms linear;
`}
style={{
// derive hue from id which is also a hexadecimal number
"--id": `#${id.slice(0, 6)}`,
translate: `${x + window.innerWidth / 2}px ${y + window.innerHeight / 2}px`
}}
viewBox="0 0 32 36"
xmlns="http://www.w3.org/2000/svg"
>
<path d="
M28.7422 20.6515
C30.6498 20.1539 31.0119 17.6029 29.3184 16.594
L5.51804 2.41502
C3.82888 1.40872 1.76147 2.93154 2.22168 4.84316
L8.80478 32.1883
C9.27967 34.161 11.9329 34.5163 12.9105 32.7388
L18.0202 23.4486
L28.7422 20.6515
Z
"/>
</svg>
)
}</>
return <template ref={this}>
<svg
class={css`
position: absolute;
inset: 0;
pointer-events: none;
height: 1.5rem;
fill: oklch(from var(--id) 0.7 0.15 h);
stroke: white;
stroke-width: 0.125rem;
filter: var(--drop-shadow-subtle);
will-change: translate;
:has(> &) {
overflow: hidden;
}
`}
viewBox="0 0 32 36"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M28.7422 20.6515
C30.6498 20.1539 31.0119 17.6029 29.3184 16.594
L5.51804 2.41502
C3.82888 1.40872 1.76147 2.93154 2.22168 4.84316
L8.80478 32.1883
C9.27967 34.161 11.9329 34.5163 12.9105 32.7388
L18.0202 23.4486
L28.7422 20.6515"
/>
</svg>
</template>
}
}

Expand Down Expand Up @@ -237,10 +257,10 @@ class WaitingForOpponentScreen extends Component<{
class?: string
world: WorldData["name"]
}> implements AnimatesOut {

#copy = () =>
navigator.clipboard.writeText(this.props.world.replace(" ", "-"))

#share = () =>
navigator.share({
title: "Tic Tac Toe",
Expand Down
15 changes: 14 additions & 1 deletion patches/preact.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
diff --git a/package.json b/package.json
index 166b927ce89d1ff7ecc259912cfc6ff26fbe5f13..27baf4ea22b3e84464ff4fb8749f1530ef3d5594 100644
index f92ca82cdddda3b7cd85166c53225db640329165..43bf43a55297054d05dd1965be97183a2189f228 100644
--- a/package.json
+++ b/package.json
@@ -20,56 +20,56 @@
Expand Down Expand Up @@ -67,3 +67,16 @@ index 166b927ce89d1ff7ecc259912cfc6ff26fbe5f13..27baf4ea22b3e84464ff4fb8749f1530
"umd": "./jsx-runtime/dist/jsxRuntime.umd.js",
"import": "./jsx-runtime/dist/jsxRuntime.mjs",
"require": "./jsx-runtime/dist/jsxRuntime.js"
diff --git a/src/diff/index.js b/src/diff/index.js
index a05c03cc9584ac2ebe30c7ceb132a5771b781469..6f631d6e7fc0e8271272d1de48c2af58677aa812 100644
--- a/src/diff/index.js
+++ b/src/diff/index.js
@@ -525,7 +525,7 @@ function diffElementNodes(
if (oldHtml) dom.innerHTML = '';

diffChildren(
- dom,
+ newVNode.type === 'template' ? dom.content : dom,
isArray(newChildren) ? newChildren : [newChildren],
newVNode,
oldVNode,
34 changes: 17 additions & 17 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3dd06a6

Please sign in to comment.