mirror of
https://gitlab.com/Anson-Projects/projects.git
synced 2025-06-15 14:36:47 +00:00
make a cute little canvas to draw on and hook it up to some ojs
This commit is contained in:
parent
51c03d9213
commit
7cd96f1997
@ -2,8 +2,7 @@ const kProgressiveAttr = "data-src";
|
||||
let categoriesLoaded = false;
|
||||
|
||||
window.quartoListingCategory = (category) => {
|
||||
// category is URI encoded in EJS template for UTF-8 support
|
||||
category = decodeURIComponent(atob(category));
|
||||
category = atob(category);
|
||||
if (categoriesLoaded) {
|
||||
activateCategory(category);
|
||||
setCategoryHash(category);
|
||||
|
114
posts/2025-05-25-Brachistochrone/index.qmd
Normal file
114
posts/2025-05-25-Brachistochrone/index.qmd
Normal file
@ -0,0 +1,114 @@
|
||||
---
|
||||
title: "Brachistochrone"
|
||||
description: |
|
||||
Lets create a double pendulum in Observable JS!
|
||||
date: 2025-05-09
|
||||
categories:
|
||||
- Observable JS
|
||||
- Code
|
||||
- Math
|
||||
---
|
||||
|
||||
This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text
|
||||
|
||||
:::{.column-screen}
|
||||
```{ojs}
|
||||
//| echo: false
|
||||
|
||||
|
||||
viewof canvas = {
|
||||
const height = 500;
|
||||
const canvas = html`<canvas width=${width} height="${height}" style="border: 1px solid #ccc; cursor: crosshair;"></canvas>`;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
let isDrawing = false;
|
||||
let lastX = 0;
|
||||
let lastY = 0;
|
||||
let pathLength = 0;
|
||||
let pathHistory = [{time: Date.now(), length: 0}];
|
||||
|
||||
// Drawing settings
|
||||
ctx.strokeStyle = '#000';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.lineCap = 'round';
|
||||
ctx.lineJoin = 'round';
|
||||
|
||||
canvas.addEventListener('mousedown', (e) => {
|
||||
if (!isDrawing) {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.arc(300, 100, 5, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = 'red';
|
||||
ctx.fill();
|
||||
ctx.arc(600, 300, 5, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = 'red';
|
||||
ctx.fill();
|
||||
pathLength = 0;
|
||||
pathHistory = [{time: Date.now(), length: 0}];
|
||||
canvas.value = {length: pathLength, history: pathHistory};
|
||||
canvas.dispatchEvent(new CustomEvent("input"));
|
||||
}
|
||||
isDrawing = true;
|
||||
[lastX, lastY] = [e.offsetX, e.offsetY];
|
||||
});
|
||||
|
||||
canvas.addEventListener('mousemove', (e) => {
|
||||
if (!isDrawing) return;
|
||||
|
||||
// Calculate distance
|
||||
const distance = Math.sqrt(
|
||||
Math.pow(e.offsetX - lastX, 2) +
|
||||
Math.pow(e.offsetY - lastY, 2)
|
||||
);
|
||||
const angle = Math.atan2(e.offsetY - lastY, e.offsetX - lastX)
|
||||
pathLength += distance;
|
||||
|
||||
// Draw
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(lastX, lastY);
|
||||
ctx.lineTo(e.offsetX, e.offsetY);
|
||||
ctx.stroke();
|
||||
[lastX, lastY] = [e.offsetX, e.offsetY];
|
||||
|
||||
// Update value and emit event
|
||||
pathHistory.push({time: Date.now(), length: pathLength});
|
||||
canvas.value = {length: pathLength, history: pathHistory};
|
||||
canvas.dispatchEvent(new CustomEvent("input"));
|
||||
});
|
||||
|
||||
canvas.addEventListener('mouseup', () => isDrawing = false);
|
||||
canvas.addEventListener('mouseout', () => isDrawing = false);
|
||||
|
||||
// Initial value
|
||||
canvas.value = {length: 0, history: pathHistory};
|
||||
return canvas;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
```{ojs}
|
||||
//| echo: false
|
||||
md`Current path length: **${canvas.length?.toFixed(0) || 0} pixels**`
|
||||
```
|
||||
|
||||
```{ojs}
|
||||
//| echo: false
|
||||
import {Plot} from "@observablehq/plot"
|
||||
|
||||
pathChart = Plot.plot({
|
||||
width: width,
|
||||
height: 200,
|
||||
y: {label: "Path Length (pixels)"},
|
||||
x: {label: "Time", type: "time"},
|
||||
marks: [
|
||||
Plot.line(canvas.history || [], {
|
||||
x: "time",
|
||||
y: "length",
|
||||
stroke: "steelblue",
|
||||
strokeWidth: 2
|
||||
})
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text This is a bunch of text
|
Loading…
x
Reference in New Issue
Block a user