Rise,
<canvas width="400" height="200" style="outline:1px solid black;cursor:none;"></canvas>
<script>
"use strict"
class Point {
constructor(x, y, radius) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = "#0000FF";
}
render(game) {
game.ctx2d.beginPath();
game.ctx2d.fillStyle = this.color;
game.ctx2d.arc(this.x, this.y, this.radius, 0, 7);
game.ctx2d.fill();
}
}
class Cursor extends Point {
constructor(x, y, radius, length, filter) {
super(x, y, radius);
this.length = length;
this.filter = filter;
this.color = "#" + ("000000" + (Math.random() * 0xffffff | 0).toString(16)).slice(-6);
this.points = new Set();
}
search(points) {
this.points.clear();
for (let point of points) {
point.color = "#0000FF";
if (this.filter(this, point)) {
point.color = "#7FFF00";
this.points.add(point);
}
}
}
render(game) {
this.search(game.points);
game.ctx2d.beginPath();
game.ctx2d.strokeStyle = this.color;
for (let point of this.points) {
game.ctx2d.moveTo(this.x, this.y);
game.ctx2d.lineTo(point.x, point.y);
}
game.ctx2d.closePath();
game.ctx2d.stroke();
super.render(game);
}
}
class Game {
constructor(canvas, cursor, points) {
this.ctx2d = canvas.getContext('2d');
this.cursor = cursor;
this.points = new Set(points);
this.render();
canvas.onmousemove = (e) => {
this.cursor.x = e.offsetX;
this.cursor.y = e.offsetY;
this.render();
};
}
render() {
this.ctx2d.clearRect(0, 0, 400, 200);
for (let point of this.points)
point.render(this);
this.cursor.render(this);
}
}
const theGame = new Game(
document.querySelector('canvas'),
new Cursor(200, 100, 2, 50, (A, B) => B.x > A.x - A.length && B.x < A.x + A.length && B.y > A.y - A.length && B.y < A.y + A.length),
new Array(10 * 20).fill(0).map((v, i) => new Point(20 * (i % 20) + 10, 20 * (i / 20 | 0) + 10, 2))
);
</script>