I love the annotated geometry proof here. It doesn't take a lot of JavaScript to make. The main idea is to annotate the text and also the diagram, and then use the annotations plus CSS to drive the highlighting. I wanted to recreate a tiny bit of it to demonstrate how to make something like this. Live demo:
Let the straight line AB be divided into any two parts in C; the square of AB is equal to the squares of AC, CB, and to twice the rectangle contained by AC, CB.
I also put the code up on jsfiddle for you to play with (try settings / bottom results). How does it work? The text contains annotations:
<pre> the square of <span data-key="A-ADEB">AB</span> is equal to the squares of <span data-key="L-AC">AC</span>, <span data-key="L-CB">CB</span>, </pre>
The diagram also contains annotations:
<svg> <path data-key="L-AB" d="M 0,0 l 100,0"/> <path data-key="A-ADEB" d="M 0,0 l 0,100 l 100,0 l 0,-100 Z"/> <text data-key="P-A" text-anchor="end" x="0" y="0">A</text> </svg>
Then this JavaScript ties it all together:
const highlightable = document.querySelectorAll("*[data-key]"); for (let el of highlightable) { el.addEventListener('pointerover', () => highlight(el.dataset.key)); el.addEventListener('mouseout', () => highlight(null)); } function highlight(key) { for (let el of highlightable) { el.classList.toggle("highlight", el.dataset.key === key); } }
When you mouse over (or touch) an element that has a data-key
attribute, it will find all elements with that same key and add the highlight
class to them. Then those elements are displayed differently using CSS:
span[data-key^="L-"] { background: hsl(240, 75%, 95%); } span[data-key^="L-"].highlight { background: hsl(240, 50%, 80%); } path[data-key^="L-"] { stroke: black stroke-width: 0.75px; } path[data-key^="L-"].highlight { stroke: hsl(240, 100%, 60%); stroke-width: 2.5px; }
What is this funny ^= thing? It means the key must start with the pattern. I used L- to annotate line segments, A- to annotate areas, and P- to annotate points. So these rules will only apply to the line segments. Here's the CSS for areas:
span[data-key^="A-"] { background: hsl(240, 40%, 75%); } span[data-key^="A-"].highlight { background: hsl(240, 50%, 60%); } path[data-key^="A-"] { fill: none; } path[data-key^="A-"].highlight { fill: hsla(240, 50%, 50%, 0.5); }
I implemented this example a little differently from @sliminality's original code at her site. Her page is more polished and avoids some of the little glitches in my version, but I think my version may be useful if you want to get started making things like this. It's only ten lines of JavaScript, and all the rest is done with HTML + SVG + CSS. It works with the simple example here but I don't know if it will work for more complex pages. Fortunately, most of my pages are simple!
Labels: howto
Nice! I like that.
Viewing this with my a11y hat on, you might want to also include focus/blur instead of just mouse events, and make the points have non-negative tabindex?
Though I'm not really sure what a screen reader is going to do with the diagram anyways.
Tyr: very good points, yes, focus/blur seems like it'd be useful here.
Post a Comment