more performant cursor
This commit is contained in:
parent
5be099c61c
commit
4b7741cf46
7 changed files with 37 additions and 20 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
build/public/assets/index.f7304069.css
Normal file
1
build/public/assets/index.f7304069.css
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -4,9 +4,9 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
|
||||||
<title>🧩 jigsaw.hyottoko.club</title>
|
<title>🧩 jigsaw.hyottoko.club</title>
|
||||||
<script type="module" crossorigin src="/assets/index.3b46c827.js"></script>
|
<script type="module" crossorigin src="/assets/index.47e2ba43.js"></script>
|
||||||
<link rel="modulepreload" href="/assets/vendor.b622ee49.js">
|
<link rel="modulepreload" href="/assets/vendor.b622ee49.js">
|
||||||
<link rel="stylesheet" href="/assets/index.f09d7623.css">
|
<link rel="stylesheet" href="/assets/index.f7304069.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,11 @@ async function resizeBitmap (
|
||||||
return await createImageBitmap(c)
|
return await createImageBitmap(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function colorize(
|
function colorizedCanvas(
|
||||||
bitmap: ImageBitmap,
|
bitmap: ImageBitmap,
|
||||||
mask: ImageBitmap,
|
mask: ImageBitmap,
|
||||||
color: string
|
color: string,
|
||||||
): Promise<ImageBitmap> {
|
): HTMLCanvasElement {
|
||||||
const c = createCanvas(bitmap.width, bitmap.height)
|
const c = createCanvas(bitmap.width, bitmap.height)
|
||||||
const ctx = c.getContext('2d') as CanvasRenderingContext2D
|
const ctx = c.getContext('2d') as CanvasRenderingContext2D
|
||||||
ctx.save()
|
ctx.save()
|
||||||
|
|
@ -45,12 +45,12 @@ async function colorize(
|
||||||
ctx.globalCompositeOperation = "destination-over"
|
ctx.globalCompositeOperation = "destination-over"
|
||||||
ctx.drawImage(bitmap, 0, 0)
|
ctx.drawImage(bitmap, 0, 0)
|
||||||
ctx.restore()
|
ctx.restore()
|
||||||
return await createImageBitmap(c)
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
createCanvas,
|
createCanvas,
|
||||||
loadImageToBitmap,
|
loadImageToBitmap,
|
||||||
resizeBitmap,
|
resizeBitmap,
|
||||||
colorize,
|
colorizedCanvas,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ export async function main(
|
||||||
) {
|
) {
|
||||||
if (typeof window.DEBUG === 'undefined') window.DEBUG = false
|
if (typeof window.DEBUG === 'undefined') window.DEBUG = false
|
||||||
|
|
||||||
const shouldDrawPlayerText = (player: Player) => {
|
const shouldDrawPlayer = (player: Player) => {
|
||||||
return MODE === MODE_REPLAY || player.id !== clientId
|
return MODE === MODE_REPLAY || player.id !== clientId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,7 +244,9 @@ export async function main(
|
||||||
const cursor = p.d ? cursorGrab : cursorHand
|
const cursor = p.d ? cursorGrab : cursorHand
|
||||||
if (p.color) {
|
if (p.color) {
|
||||||
const mask = p.d ? cursorGrabMask : cursorHandMask
|
const mask = p.d ? cursorGrabMask : cursorHandMask
|
||||||
cursors[key] = await Graphics.colorize(cursor, mask, p.color)
|
cursors[key] = await createImageBitmap(
|
||||||
|
Graphics.colorizedCanvas(cursor, mask, p.color)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
cursors[key] = cursor
|
cursors[key] = cursor
|
||||||
}
|
}
|
||||||
|
|
@ -376,6 +378,21 @@ export async function main(
|
||||||
|| 'anon')
|
|| 'anon')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let cursorDown: string = ''
|
||||||
|
let cursor: string = ''
|
||||||
|
let cursorState: boolean = false
|
||||||
|
const updatePlayerCursorState = (d: boolean) => {
|
||||||
|
cursorState = d
|
||||||
|
const [url, fallback] = d ? [cursorDown, 'grab'] : [cursor, 'default']
|
||||||
|
canvas.style.cursor = `url('${url}') ${CURSOR_W_2} ${CURSOR_H_2}, ${fallback}`
|
||||||
|
}
|
||||||
|
const updatePlayerCursorColor = (color: string) => {
|
||||||
|
cursorDown = Graphics.colorizedCanvas(cursorGrab, cursorGrabMask, color).toDataURL()
|
||||||
|
cursor = Graphics.colorizedCanvas(cursorHand, cursorHandMask, color).toDataURL()
|
||||||
|
updatePlayerCursorState(cursorState)
|
||||||
|
}
|
||||||
|
updatePlayerCursorColor(playerColor())
|
||||||
|
|
||||||
const doSetSpeedStatus = () => {
|
const doSetSpeedStatus = () => {
|
||||||
if (HUD.setReplaySpeed) {
|
if (HUD.setReplaySpeed) {
|
||||||
HUD.setReplaySpeed(REPLAY.speeds[REPLAY.speedIdx])
|
HUD.setReplaySpeed(REPLAY.speeds[REPLAY.speedIdx])
|
||||||
|
|
@ -522,11 +539,15 @@ export async function main(
|
||||||
|
|
||||||
_last_mouse_down = mouse
|
_last_mouse_down = mouse
|
||||||
}
|
}
|
||||||
|
} else if (type === Protocol.INPUT_EV_PLAYER_COLOR) {
|
||||||
|
updatePlayerCursorColor(evt[1])
|
||||||
} else if (type === Protocol.INPUT_EV_MOUSE_DOWN) {
|
} else if (type === Protocol.INPUT_EV_MOUSE_DOWN) {
|
||||||
const pos = { x: evt[1], y: evt[2] }
|
const pos = { x: evt[1], y: evt[2] }
|
||||||
_last_mouse_down = viewport.worldToViewport(pos)
|
_last_mouse_down = viewport.worldToViewport(pos)
|
||||||
|
updatePlayerCursorState(true)
|
||||||
} else if (type === Protocol.INPUT_EV_MOUSE_UP) {
|
} else if (type === Protocol.INPUT_EV_MOUSE_UP) {
|
||||||
_last_mouse_down = null
|
_last_mouse_down = null
|
||||||
|
updatePlayerCursorState(false)
|
||||||
} else if (type === Protocol.INPUT_EV_ZOOM_IN) {
|
} else if (type === Protocol.INPUT_EV_ZOOM_IN) {
|
||||||
const pos = { x: evt[1], y: evt[2] }
|
const pos = { x: evt[1], y: evt[2] }
|
||||||
RERENDER = true
|
RERENDER = true
|
||||||
|
|
@ -654,10 +675,10 @@ export async function main(
|
||||||
const texts: Array<FixedLengthArray<[string, number, number]>> = []
|
const texts: Array<FixedLengthArray<[string, number, number]>> = []
|
||||||
// Cursors
|
// Cursors
|
||||||
for (const p of Game.getActivePlayers(gameId, ts)) {
|
for (const p of Game.getActivePlayers(gameId, ts)) {
|
||||||
bmp = await getPlayerCursor(p)
|
if (shouldDrawPlayer(p)) {
|
||||||
pos = viewport.worldToViewport(p)
|
bmp = await getPlayerCursor(p)
|
||||||
ctx.drawImage(bmp, pos.x - CURSOR_W_2, pos.y - CURSOR_H_2)
|
pos = viewport.worldToViewport(p)
|
||||||
if (shouldDrawPlayerText(p)) {
|
ctx.drawImage(bmp, pos.x - CURSOR_W_2, pos.y - CURSOR_H_2)
|
||||||
// performance:
|
// performance:
|
||||||
// not drawing text directly here, to have less ctx
|
// not drawing text directly here, to have less ctx
|
||||||
// switches between drawImage and fillTxt
|
// switches between drawImage and fillTxt
|
||||||
|
|
|
||||||
|
|
@ -189,10 +189,6 @@ input:focus {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas.loaded {
|
|
||||||
cursor: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
kbd {
|
kbd {
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
@ -312,4 +308,4 @@ html.view-game body { overflow: hidden; }
|
||||||
|
|
||||||
html.view-replay { overflow: hidden; }
|
html.view-replay { overflow: hidden; }
|
||||||
html.view-replay body { overflow: hidden; }
|
html.view-replay body { overflow: hidden; }
|
||||||
html.view-replay canvas { cursor: grab; }
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue