Skip to content

Instantly share code, notes, and snippets.

@edykim
Created April 7, 2023 05:25
Show Gist options
  • Select an option

  • Save edykim/4e37972ec4ec8753387bb8bf9ac9fa9e to your computer and use it in GitHub Desktop.

Select an option

Save edykim/4e37972ec4ec8753387bb8bf9ac9fa9e to your computer and use it in GitHub Desktop.
low latency canvas and predicted events
<!DOCTYPE html>
<html lang="en">
<head>
<style>
* {
touch-action: none;
}
canvas {
width: 600px;
height: 600px;
border: 5px solid #333;
position: absolute;
left: 1rem;
top: 1rem;
}
#canvas-1 {
z-index: 100;
}
#canvas-2 {
z-index: 10;
}
</style>
<script>
window.addEventListener('DOMContentLoaded', setup);
function setup() {
install(document.querySelector('#canvas-1'), document.querySelector('#canvas-2'), { desynchronized: true });
}
function install(ele, eleBack, options) {
const context = ele.getContext('2d', options || {});
const subcontext = eleBack.getContext('2d', options || {});
let isDrawing = false;
let x = 0;
let y = 0;
ele.addEventListener('pointerdown', (e) => {
console.log('move')
x = e.offsetX;
y = e.offsetY;
isDrawing = true;
});
ele.addEventListener('pointermove', (e) => {
if (isDrawing) {
clearArea(subcontext);
e.getPredictedEvents().reduce((carry, e) => {
drawLine(subcontext, carry.x, carry.y, e.offsetX, e.offsetY, '#aaa');
carry.x = e.offsetX;
carry.y = e.offsetY;
return carry;
}, {x, y});
drawLine(context, x, y, e.offsetX, e.offsetY);
x = e.offsetX;
y = e.offsetY;
}
});
ele.addEventListener('pointerup', (e) => {
if (isDrawing) {
clearArea(subcontext);
drawLine(context, x, y, e.offsetX, e.offsetY);
x = 0;
y = 0;
isDrawing = false;
}
});
ele.addEventListener("dblclick", () => {
clearArea(context);
})
}
function drawLine(context, x1, y1, x2, y2, color) {
context.beginPath();
context.strokeStyle = color || '#000000';
context.lineWidth = 3;
context.lineJoin = "round";
context.moveTo(x1 * 2, y1 * 2);
context.lineTo(x2 * 2, y2 * 2);
context.closePath();
context.stroke();
}
function clearArea(context) {
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
}
</script>
</head>
<body>
<canvas id="canvas-1" width="1200" height="1200"></canvas>
<canvas id="canvas-2" width="1200" height="1200"></canvas>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment