Pythagoras theorem
Interactive demo
Change the length of the sides to calculate the hypotenuse (the longest side of a right-angled triangle). Click anywhere in the image to do this. It is a bit clumsy, but you will manage 😃
Source code
// FIXME temp hack for safari modules const settings = { textColor: '#4b4b4b', primaryColor: '#ce5127', brandColor: '#e98a70', secondaryColor: '#27a2cc', tertiaryColor: '#86cfe4', backgroundColor: '#F9F4F2' } // setup const canvas = document.querySelector('canvas') const context = canvas.getContext('2d') const [width, height] = [canvas.width, canvas.height] const gridSize = 50 const margin = 2 * gridSize // lengths let [a, b] = [5, 12] let c = Math.sqrt(a * a + b * b) // common style context.font = '36px Helvetica' context.textBaseline = 'middle' context.fillStyle = settings ? settings.tertiaryColor : 'black' context.lineWidth = 10 context.miterLimit = 1 context.strokeStyle = 'white' const drawBackground = () => { context.save() // clear background context.fillRect(0, 0, width, height) // draw grid context.lineWidth = 2 context.strokeStyle = settings ? settings.secondaryColor : 'black' context.beginPath() for (let x = gridSize; x < width; x += gridSize) { context.moveTo(x, 0) context.lineTo(x, height) } for (let y = gridSize; y < height; y += gridSize) { context.moveTo(0, y) context.lineTo(width, y) } context.stroke() // draw axes context.beginPath() context.lineWidth = 5 context.strokeStyle = 'black' context.moveTo(2 * gridSize, 0) context.lineTo(2 * gridSize, height) context.moveTo(0, 6 * gridSize) context.lineTo(width, 6 * gridSize) context.stroke() context.restore() } const drawTriangle = () => { context.save() // y up context.scale(1, -1) context.translate(margin, margin - height) // draw triangle context.beginPath() context.moveTo(0, 0) context.lineTo(0, gridSize * a) context.lineTo(gridSize * b, 0) context.closePath() context.stroke() // right angle context.lineWidth = 5 context.beginPath() context.moveTo(0, 25) context.lineTo(25, 25) context.lineTo(25, 0) context.stroke() context.restore() } const drawNumbers = () => { context.save() // FIXME magic number coordinates context.fillText(`a = ${a}`, 2.25 * gridSize, 4.5 * gridSize) context.fillText(`b = ${b}`, 6.25 * gridSize, 6.5 * gridSize) context.fillText(`c = √(a² + b²)`, 7.25 * gridSize, 1.5 * gridSize) context.fillText(`c = √${a}² + ${b}²)`, 7.25 * gridSize, 2.5 * gridSize) context.fillText(`c = ≈${c.toFixed(2)}`, 7.25 * gridSize, 3.5 * gridSize) context.restore() } const update = () => { drawBackground() drawTriangle() drawNumbers() } const touch = e => { const rect = canvas.getBoundingClientRect() const [x, y] = [e.clientX - rect.left, e.clientY - rect.top] a = 6 - ~~(y / gridSize) b = ~~(x / gridSize) - 3 c = Math.sqrt(a * a + b * b) update() } canvas.addEventListener('click', touch) canvas.addEventListener('touch', touch) update()