Compare commits

...

7 Commits

Author SHA1 Message Date
0e9500196f add trackHover toggle 2026-01-02 00:28:20 -05:00
77cb74ad10 add screenshot script 2026-01-02 00:10:38 -05:00
4e5b4fb249 update screenshot 2026-01-02 00:07:58 -05:00
0753ef40d5 add border radius to rects; constrain to integeral cooridnates only 2026-01-01 23:58:22 -05:00
09ff88289b use ascii 2026-01-01 23:45:41 -05:00
388f7633e5 add screenshot 2026-01-01 23:40:27 -05:00
0db7cab23b fix README rectangle descriptions and remove unused Counter component
- Corrected rectangle corner coordinates to accurately show (cx, ay) and (ax, cy)
- Removed unused Counter.svelte component

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-01 23:24:39 -05:00
6 changed files with 51 additions and 23 deletions

View File

@ -19,6 +19,16 @@ npm run build
npm run preview npm run preview
``` ```
## Scripts
The `script/` folder contains utility scripts for development:
- **screenshot**: Captures a screenshot of the running dev server (localhost:5173) using Chrome headless mode
- Outputs to `screenshot.png` in the project root
- Requires Chrome/Chromium to be installed
- Dev server must be running before executing
- Usage: `./script/screenshot`
## Architecture ## Architecture
### Application Structure ### Application Structure

View File

@ -2,6 +2,8 @@
An interactive geometric visualization tool that demonstrates rectangle area calculations and their relationship to a line segment. An interactive geometric visualization tool that demonstrates rectangle area calculations and their relationship to a line segment.
![Application Screenshot](screenshot.png)
## Use Case ## Use Case
This tool provides a visual and interactive way to understand how moving a point affects the areas of rectangles formed with fixed anchor points. It's useful for: This tool provides a visual and interactive way to understand how moving a point affects the areas of rectangles formed with fixed anchor points. It's useful for:
@ -17,8 +19,8 @@ The visualization displays:
- **Point C** at (6, 7) - top-right anchor point - **Point C** at (6, 7) - top-right anchor point
- **Point B** - movable point that follows your mouse cursor - **Point B** - movable point that follows your mouse cursor
- **Line segment AC** - connecting the two fixed points - **Line segment AC** - connecting the two fixed points
- **Blue rectangle** - formed by points B and C - **Blue rectangle** - formed by point B and (cx, ay) = (6, 1)
- **Red rectangle** - formed by points B and A - **Red rectangle** - formed by point B and (ax, cy) = (1, 7)
As you move your mouse over the canvas, point B follows the cursor, and the application: As you move your mouse over the canvas, point B follows the cursor, and the application:
1. Calculates the width and height of both rectangles in real-time 1. Calculates the width and height of both rectangles in real-time
@ -56,7 +58,7 @@ npm run preview
## Interface ## Interface
The canvas displays an 8×8 grid where each cell is 40 pixels. Move your mouse over the grid to control point B and watch the rectangle areas update in real-time below the visualization. The canvas displays an 8x8 grid where each cell is 40 pixels. Move your mouse over the grid to control point B and watch the rectangle areas update in real-time below the visualization.
The calculation cards show: The calculation cards show:
- Current position of point B - Current position of point B

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,7 @@
#!/bin/bash
set -e
google-chrome --headless --disable-gpu \
--screenshot=$(pwd)/screenshot.png --window-size=1280,900 \
http://localhost:5173 2>/dev/null

View File

@ -8,6 +8,7 @@
const HEIGHT = 320; const HEIGHT = 320;
let userPoint = { x: 5, y: 2 }; let userPoint = { x: 5, y: 2 };
let trackHover = true;
// Rectangle coordinates // Rectangle coordinates
const blueRect = { x1: 6, y1: 1 }; // Blue rectangle corner const blueRect = { x1: 6, y1: 1 }; // Blue rectangle corner
@ -50,16 +51,33 @@
const width = Math.abs(corner2.x - corner1.x); const width = Math.abs(corner2.x - corner1.x);
const height = Math.abs(corner2.y - corner1.y); const height = Math.abs(corner2.y - corner1.y);
ctx.beginPath();
ctx.roundRect(x, y, width, height, 1);
ctx.fillStyle = color; ctx.fillStyle = color;
ctx.fillRect(x, y, width, height); ctx.fill();
// Add border
ctx.strokeStyle = color.replace('0.3', '0.8'); // Make border more opaque
ctx.lineWidth = 2;
ctx.stroke();
} }
function handleMouseMove(event) { function handleMouseMove(event) {
if (!trackHover) return;
const rect = canvas.getBoundingClientRect(); const rect = canvas.getBoundingClientRect();
const mouseX = event.clientX - rect.left; const mouseX = event.clientX - rect.left;
const mouseY = event.clientY - rect.top; const mouseY = event.clientY - rect.top;
userPoint = toCartesianCoords(mouseX, mouseY); // Add half grid unit offset for snapping to closest grid intersection
userPoint = {
x: Math.floor((mouseX + GRID_SIZE / 2) / GRID_SIZE),
y: Math.floor((HEIGHT - mouseY + GRID_SIZE / 2) / GRID_SIZE)
};
}
function handleCanvasClick() {
trackHover = !trackHover;
} }
function toCanvasCoords(x, y) { function toCanvasCoords(x, y) {
@ -194,27 +212,27 @@
<main> <main>
<h1>Line Segment Intersection</h1> <h1>Line Segment Intersection</h1>
<div class="canvas-container"> <div class="canvas-container">
<canvas bind:this={canvas} width={WIDTH} height={HEIGHT} on:mousemove={handleMouseMove}></canvas> <canvas bind:this={canvas} width={WIDTH} height={HEIGHT} on:mousemove={handleMouseMove} on:click={handleCanvasClick}></canvas>
</div> </div>
<div class="calculations"> <div class="calculations">
<h2>Rectangle Areas</h2> <h2>Rectangle Areas</h2>
<p class="point-c">Point B: ({userPoint.x.toFixed(2)}, {userPoint.y.toFixed(2)})</p> <p class="point-c">Point B: ({userPoint.x}, {userPoint.y})</p>
<div class="rect-calc blue" class:largest={blueArea > redArea}> <div class="rect-calc blue" class:largest={blueArea > redArea}>
<h3>Blue Rectangle</h3> <h3>Blue Rectangle</h3>
<p>Corner: ({blueRect.x1}, {blueRect.y1})</p> <p>Corner: ({blueRect.x1}, {blueRect.y1})</p>
<p>Width = |{blueRect.x1} - {userPoint.x.toFixed(2)}| = {blueWidth.toFixed(2)}</p> <p>Width = |{blueRect.x1} - {userPoint.x}| = {blueWidth}</p>
<p>Height = |{blueRect.y1} - {userPoint.y.toFixed(2)}| = {blueHeight.toFixed(2)}</p> <p>Height = |{blueRect.y1} - {userPoint.y}| = {blueHeight}</p>
<p class="area">Area = {blueWidth.toFixed(2)} × {blueHeight.toFixed(2)} = <strong>{blueArea.toFixed(2)}</strong></p> <p class="area">Area = {blueWidth} x {blueHeight} = <strong>{blueArea}</strong></p>
</div> </div>
<div class="rect-calc red" class:largest={redArea > blueArea}> <div class="rect-calc red" class:largest={redArea > blueArea}>
<h3>Red Rectangle</h3> <h3>Red Rectangle</h3>
<p>Corner: ({redRect.x1}, {redRect.y1})</p> <p>Corner: ({redRect.x1}, {redRect.y1})</p>
<p>Width = |{redRect.x1} - {userPoint.x.toFixed(2)}| = {redWidth.toFixed(2)}</p> <p>Width = |{redRect.x1} - {userPoint.x}| = {redWidth}</p>
<p>Height = |{redRect.y1} - {userPoint.y.toFixed(2)}| = {redHeight.toFixed(2)}</p> <p>Height = |{redRect.y1} - {userPoint.y}| = {redHeight}</p>
<p class="area">Area = {redWidth.toFixed(2)} × {redHeight.toFixed(2)} = <strong>{redArea.toFixed(2)}</strong></p> <p class="area">Area = {redWidth} x {redHeight} = <strong>{redArea}</strong></p>
</div> </div>
</div> </div>
</main> </main>
@ -240,6 +258,7 @@
canvas { canvas {
display: block; display: block;
cursor: pointer;
} }
.calculations { .calculations {

View File

@ -1,10 +0,0 @@
<script>
let count = $state(0)
const increment = () => {
count += 1
}
</script>
<button onclick={increment}>
count is {count}
</button>