<meta charset="utf8"> <style> body { margin: 0; font-family: sans-serif; } canvas { width: 100vw; height: 100vh; position: absolute; top: 0; z-index: 69; } h2 { margin-top: 3rem; } h2.active { color: red; } div { display: flex; width: 100%; justify-content: space-around; } </style> <canvas></canvas> <div> <h2>Opción 1</h2> <h2>Opción 2</h2> <h2>Opción 3</h2> </div> <script> const canvas = document.querySelector('canvas') const ctx = canvas.getContext('2d') const items = [...document.querySelectorAll('h2')] let lines = [] function resizeCanvas () { canvas.width = canvas.clientWidth canvas.height = canvas.clientHeight window.requestAnimationFrame(render) } window.addEventListener('resize', resizeCanvas) resizeCanvas() let drawing = false let wasDrawing = false canvas.addEventListener('mousedown', () => { drawing = true wasDrawing = true }, true) canvas.addEventListener('mouseenter', () => { drawing = wasDrawing lastPos = null }, true) canvas.addEventListener('mousemove', draw, true) canvas.addEventListener('mouseup', () => { drawing = false wasDrawing = false }, true) canvas.addEventListener('mouseleave', () => drawing = false, true) let lastPos = null let lastSelectedItem function draw(event) { const pos = { x: event.clientX, y: event.clientY } if (lastPos) { lines.push({ start: lastPos, end: pos }) const selectedItem = items .map(item => { const rect = item.getBoundingClientRect() const distance = Math.abs((rect.x + rect.width / 2) - pos.x) + Math.abs((rect.y + rect.height / 2) - pos.y) return { item, distance } }) .reduce((prev, item) => item.distance < prev.distance ? item : prev) .item if (lastSelectedItem != selectedItem) { lines = [] } for (const item of items) { if (item == selectedItem) { item.classList.add('active') } else { item.classList.remove('active') } } lastSelectedItem = selectedItem window.requestAnimationFrame(render) } lastPos = drawing ? pos : null } function render() { ctx.clearRect(0, 0, canvas.width, canvas.height) ctx.strokeStyle = "red" for (const line of lines) { ctx.beginPath(); ctx.lineWidth = 3; ctx.moveTo(line.start.x, line.start.y); ctx.lineTo(line.end.x, line.end.y); ctx.stroke(); ctx.closePath(); } } </script>