Skip to content

Commit 6a1a83b

Browse files
authored
Create circle-vs-rectangle.html
1 parent f89564c commit 6a1a83b

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

circle-vs-rectangle.html

+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<html>
2+
<head><title>Circle and Rectangle Intersection</title>
3+
<style>
4+
canvas {
5+
background: #eee;
6+
}
7+
</style>
8+
</head>
9+
<body>
10+
<canvas width=800 height=400></canvas>
11+
12+
<script>
13+
const canvas = document.querySelector('canvas');
14+
const ctx = canvas.getContext('2d');
15+
16+
let selectedObject = null;
17+
18+
19+
class Sprite {
20+
constructor(top, left, width, height) {
21+
this.top= top; this.left = left;
22+
this.width = width; this.height = height;
23+
}
24+
right() { return this.left + this.width; }
25+
bottom() { return this.top + this.height; }
26+
27+
moveTo(x, y) {
28+
this.left = x;
29+
this.top = y;
30+
}
31+
32+
containsMouse(x, y) {
33+
return (this.top < y && y < this.top + this.height &&
34+
this.left < x && x < this.left + this.width);
35+
}
36+
}
37+
38+
class Rect extends Sprite {
39+
// no need to have constructor.
40+
41+
draw() {
42+
ctx.beginPath();
43+
ctx.fillStyle = 'rgba(50, 50, 205, .6)';
44+
ctx.rect(this.left, this.top, this.width, this.height);
45+
ctx.fill();
46+
if (selectedObject == this) {
47+
ctx.strokeStyle = 'black';
48+
ctx.stroke();
49+
}
50+
}
51+
}
52+
53+
class Circle extends Sprite {
54+
constructor(centerX, centerY, radius) {
55+
super(centerY - radius, centerX - radius, 2 * radius, 2* radius);
56+
this.radius = radius;
57+
}
58+
59+
centerX() { return this.left + this.width / 2; }
60+
centerY() { return this.top + this.height / 2; }
61+
62+
draw() {
63+
ctx.beginPath();
64+
ctx.moveTo(this.centerX() + this.radius, this.centerY());
65+
ctx.arc(this.centerX(), this.centerY(), this.radius, 0, 2 * Math.PI);
66+
ctx.fillStyle = 'rgba(100, 205, 100, .6)';
67+
if (connector.dist < this.radius) {
68+
ctx.fillStyle = 'rgba(205, 100, 100, .6)';
69+
70+
}
71+
ctx.fill();
72+
if (selectedObject == this) {
73+
ctx.strokeStyle = 'black';
74+
ctx.stroke();
75+
}
76+
}
77+
}
78+
79+
function clamp(val, low, high) {
80+
if (val < low) return low;
81+
if (val > high) return high;
82+
return val;
83+
}
84+
85+
86+
class CenterConnector {
87+
constructor() {
88+
this.nearestX = 0;
89+
this.nearestY = 0;
90+
this.dist = 0;
91+
}
92+
93+
update() {
94+
this.nearestX = clamp(circle.centerX(), rect.left, rect.right());
95+
this.nearestY = clamp(circle.centerY(), rect.top, rect.bottom());
96+
this.dist = Math.sqrt( (this.nearestX - circle.centerX()) ** 2 +
97+
(this.nearestY - circle.centerY()) ** 2);
98+
}
99+
100+
draw() {
101+
ctx.beginPath();
102+
ctx.strokeStyle = 'red';
103+
ctx.fillStyle = 'red';
104+
ctx.moveTo(this.nearestX, this.nearestY);
105+
ctx.arc(this.nearestX, this.nearestY, 3, 0, 2*Math.PI);
106+
ctx.fill();
107+
ctx.lineTo(circle.centerX(), circle.centerY());
108+
ctx.stroke();
109+
ctx.arc(circle.centerX(), circle.centerY(), 3, 0, 2*Math.PI);
110+
ctx.fill();
111+
ctx.font = '18px sans-serif';
112+
ctx.fillText('' + Math.floor(this.dist),
113+
(this.nearestX + circle.centerX()) / 2 + 20,
114+
(this.nearestY + circle.centerY()) / 2 + 20);
115+
}
116+
}
117+
118+
const rect = new Rect(40, 40, 100, 75);
119+
const circle = new Circle(280, 70, 60);
120+
const connector = new CenterConnector();
121+
122+
123+
function gameLoop() {
124+
ctx.clearRect(0, 0, canvas.width, canvas.height);
125+
rect.draw();
126+
circle.draw();
127+
connector.update();
128+
connector.draw();
129+
}
130+
131+
window.setInterval(gameLoop, 100);
132+
133+
let gripX = 0, gripY = 0;
134+
canvas.addEventListener('mousedown', (e) => {
135+
selectedObject = null;
136+
for (let sprite of [circle, rect]) {
137+
if (sprite.containsMouse(e.x, e.y)) {
138+
selectedObject = sprite;
139+
gripX = e.x - sprite.left;
140+
gripY = e.y - sprite.top;
141+
}
142+
}
143+
})
144+
145+
canvas.addEventListener('mousemove', (e) => {
146+
if (!e.buttons) return;
147+
if (selectedObject == null) return;
148+
selectedObject.moveTo(e.x - gripX, e.y - gripY);
149+
})
150+
151+
</script>
152+
</body>
153+
</html>

0 commit comments

Comments
 (0)