website

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

Angle.jsx (1734B)


      1 import Label from './Label.jsx';
      2 import { useContext } from 'preact/hooks';
      3 import { PlotContext } from '../../scripts/contexts.js';
      4 import { getColourClass, getMidpoint, interpolateDistance, sumVectors, getVector } from '../../scripts/graphUtils.js';
      5 
      6 function getArc(points, radius) {
      7   const start = interpolateDistance(points[1], points[0], radius);
      8   const end = interpolateDistance(points[1], points[2], radius);
      9   return [start, end];
     10 }
     11 
     12 function RightAngle({ points, radius, colour }) {
     13   const [start, end] = getArc(points, radius);
     14   const midpoint = sumVectors(start, getVector(points[1], end));
     15   return <polygon points={[points[1], start, midpoint, end]} class={getColourClass(colour)} />
     16 }
     17 
     18 function AngleArc({ points, radius, colour }) {
     19   const [start, end] = getArc(points, radius);
     20   return <path d={`M ${start} A ${radius} ${radius} 0 0 1 ${end}`} class={getColourClass(colour)} />;
     21 }
     22 
     23 function AngleLabel({ points, radius, colour, children }) {
     24   const point = interpolateDistance(points[1], getMidpoint(getArc(points, 1)), 1.5 * radius);
     25   return <Label point={point} colour={colour}>{children}</Label>;
     26 }
     27 
     28 export default function Angle({ points, right = false, arcs = 1, label = null, colour = "auto" }) {
     29   const p = useContext(PlotContext);
     30   const radius = 10 * p.strokeWidth;
     31   const concentricGap = 1.5 * p.strokeWidth;
     32   return (
     33     <g>
     34       {right ? (
     35                 <RightAngle points={points} radius={0.8 * radius} colour={colour} />
     36       ) : Array.from({ length: arcs }).map(
     37         (_, i) => <AngleArc points={points} radius={(radius + i*concentricGap)} colour={colour} />
     38       )}
     39       {label && <AngleLabel points={points} radius={radius} colour={colour}>{label}</AngleLabel>}
     40     </g>
     41   );
     42 }