website

source code for the ttmaths.uk website
Log | Files | Refs | README

commit 9fe6c5e8dbd05fb3831db07ed2847b2682a9edbc
parent 4a29c8c91bad7bd788117a8e0084e576e159080e
Author: hrryt <harry@mayesfield.uk>
Date:   Fri, 14 Aug 2026 16:32:40 +0100

Use stroke width as the base constant size unit

Diffstat:
Msrc/components/graphing/Angle.jsx | 4++--
Msrc/components/graphing/Graph.jsx | 32++++++++++++++++++--------------
Msrc/components/graphing/Label.jsx | 6+++---
Msrc/components/graphing/Point.jsx | 2+-
Msrc/scripts/contexts.js | 2+-
Msrc/styles/svg.css | 1+
6 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/src/components/graphing/Angle.jsx b/src/components/graphing/Angle.jsx @@ -1,6 +1,6 @@ import Label from './Label.jsx'; import { useContext } from 'preact/hooks'; -import { ScaleFactorContext } from '../../scripts/contexts.js'; +import { StrokeWidthContext } from '../../scripts/contexts.js'; import { getColourClass, getMidpoint, interpolateDistance } from '../../scripts/utils.js'; function getArc(points, radius) { @@ -20,7 +20,7 @@ function AngleLabel({ points, radius, colour, children }) { } export default function Angle({ points, radius = 0.5, arcs = 1, label = null, colour = "auto" }) { - const concentricGap = 7 * useContext(ScaleFactorContext); + const concentricGap = 3 * useContext(StrokeWidthContext); return ( <g> {Array.from({ length: arcs }).map( diff --git a/src/components/graphing/Graph.jsx b/src/components/graphing/Graph.jsx @@ -1,4 +1,5 @@ -import { ScaleFactorContext } from '../../scripts/contexts.js'; +import { useContext } from 'preact/hooks'; +import { StrokeWidthContext } from '../../scripts/contexts.js'; import Label from './Label.jsx'; function Grid({ viewBox }) { @@ -9,15 +10,17 @@ function Grid({ viewBox }) { function Axes({ viewBox }) { const [ minX, minY, width, height ] = viewBox; + const arrowheadHeight = 4 * useContext(StrokeWidthContext); return ( <g> - <path class="axis" d={`M ${minX},0 h ${width-.1}`} marker-end="url(#arrow)"/> - <path class="axis" d={`M 0,${minY} v ${height-.1}`} marker-end="url(#arrow)"/> + <path class="axis" d={`M ${minX},0 h ${ width - arrowheadHeight}`} marker-end="url(#arrowhead)"/> + <path class="axis" d={`M 0,${minY} v ${height - arrowheadHeight}`} marker-end="url(#arrowhead)"/> </g> ); } -function AxisTicks({ every = 1, viewBox }) { +function AxisTicks({ viewBox }) { + const every = Math.floor(20 * useContext(StrokeWidthContext)); const [ minX, minY, width, height ] = viewBox; return ( <g> @@ -39,8 +42,8 @@ function AxisTicks({ every = 1, viewBox }) { <Label point={[0, 0]} position="bottom-left">0</Label> </g> <g> - <Label weight="bold" point={[minX + width, 0]} position="bottom-left" spacing={7}>x</Label> - <Label weight="bold" point={[0, minY + height]} position="bottom-left" spacing={7}>y</Label> + <Label weight="bold" point={[minX + width, 0]} position="bottom-left" spacing={3}>x</Label> + <Label weight="bold" point={[0, minY + height]} position="bottom-left" spacing={3}>y</Label> </g> </g> ) @@ -48,16 +51,17 @@ function AxisTicks({ every = 1, viewBox }) { export default function Graph({ children, viewBox, width="300", height="300" }) { const scaleFactor = Math.max(viewBox[2] / width, viewBox[3] / height); + const strokeWidth = 2.5 * scaleFactor; const style = ` text { font-size: ${scaleFactor}em; - stroke-width: ${4 * scaleFactor}; + stroke-width: ${1.6 * strokeWidth}; } path,polygon,line,polyline,circle,ellipse { - stroke-width: ${2.5 * scaleFactor}; + stroke-width: ${strokeWidth}; } path#grid { - stroke-width: ${0.5 * scaleFactor}; + stroke-width: ${0.2 * strokeWidth}; } `; return ( @@ -67,9 +71,9 @@ export default function Graph({ children, viewBox, width="300", height="300" }) > <defs> <marker - id='arrow' + id='arrowhead' viewBox="0 0 4 4" - refX="3" refY="2" + refX="0" refY="2" markerWidth="4" markerHeight="4" orient="auto" > @@ -126,12 +130,12 @@ export default function Graph({ children, viewBox, width="300", height="300" }) {style} </style> </defs> - <ScaleFactorContext value={scaleFactor}> + <StrokeWidthContext value={strokeWidth}> <Grid viewBox={viewBox} /> <Axes viewBox={viewBox} /> - <AxisTicks every={Math.floor(50 * scaleFactor)} viewBox={viewBox} /> + <AxisTicks viewBox={viewBox} /> {children} - </ScaleFactorContext> + </StrokeWidthContext> </svg> ); } diff --git a/src/components/graphing/Label.jsx b/src/components/graphing/Label.jsx @@ -1,5 +1,5 @@ import { useContext } from 'preact/hooks'; -import { ScaleFactorContext } from '../../scripts/contexts.js'; +import { StrokeWidthContext } from '../../scripts/contexts.js'; import { getColourClass } from '../../scripts/utils.js'; function getPosition(position) { @@ -19,10 +19,10 @@ function getPosition(position) { } } -export default function Label({ point, position='central', spacing=3, weight="normal", colour='auto', children }) { +export default function Label({ point, position='central', spacing=1, weight="normal", colour='auto', children }) { const [x, y] = point; const [dominantBaseline, textAnchor, dx, dy] = getPosition(position); - const scaledSpacing = spacing * useContext(ScaleFactorContext); + const scaledSpacing = spacing * useContext(StrokeWidthContext); return ( <text x={x} y={-y} dx={scaledSpacing * dx} dy={scaledSpacing * -dy} transform='scale(1 -1)' diff --git a/src/components/graphing/Point.jsx b/src/components/graphing/Point.jsx @@ -5,7 +5,7 @@ export default function Point({ point, label=null, colour="auto", position="top" return ( <g> <path marker-start="url(#cross)" d={`M ${point}`} class={getColourClass(colour)}/> - {label && <Label point={point} position={position} spacing={10} colour={colour}>{label}</Label>} + {label && <Label point={point} position={position} spacing={5} colour={colour}>{label}</Label>} </g> ); } diff --git a/src/scripts/contexts.js b/src/scripts/contexts.js @@ -1,3 +1,3 @@ import { createContext } from 'preact'; -export const ScaleFactorContext = createContext(null); +export const StrokeWidthContext = createContext(null); diff --git a/src/styles/svg.css b/src/styles/svg.css @@ -31,6 +31,7 @@ line.marker, polyline.marker { polygon.marker { fill-opacity: 1; + stroke-width: 0; } text {