<svg id="svg" stroke="red" fill="none">
<line id="line" x1="20" y1="100" x2="120" y2="100" />
<path id="path" d="M 20 100 A 80 80 0 0 1 120 100"/>
</svg>
<div id="control">
<span>h: </span>
<input type="range" min="10" max="100" value="20">
</div>
<div class="text">
click <br>
and <br>
drag
</div>
body {
margin: 0;
position: relative;
height: 100vh;
}
#svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
#control {
position: fixed;
top: 20px;
left: 20px;
}
.text {
display: flex;
align-items: center;
justify-content: center;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
text-align: center;
font-family: sans-serif;
line-height: 0.85;
font-size: 12vmax;
color: #ddd;
pointer-events: none;
}
const svg = document.getElementById('svg');
const line = document.getElementById('line');
const path = document.getElementById('path');
let isDrawing = false;
const start = { x: 20, y: 100 };
const end = { x: 120, y: 100 };
let h = 20;
let chordLength = Math.hypot(start.x - end.x, start.y - end.y);
let arcRadius = calcArcRadius(chordLength, h);
function calcArcRadius(c, h) {
return (c * c / 4 + h * h) / (2 * h);
}
function drawLine(start, end) {
line.setAttribute("x1", start.x);
line.setAttribute("y1", start.y);
line.setAttribute("x2", end.x);
line.setAttribute("y2", end.y);
}
function drawArc(start, r, end) {
// d="M mx,my A rx,ry x-axis-rotation large-arc-flag, sweep-flag x,y"
const d = `
M ${start.x} ${start.y}
A ${r} ${r} 0 0 1 ${end.x} ${end.y}`;
path.setAttribute("d", d);
}
svg.addEventListener('mousedown', (e) => {
if (!isDrawing) {
start.x = e.clientX;
start.y = e.clientY;
}
isDrawing = true;
});
svg.addEventListener('mouseup', (e) => {
isDrawing = false;
});
svg.addEventListener('mousemove', (e) => {
if (!isDrawing) return;
end.x = e.clientX;
end.y = e.clientY;
drawLine(start, end);
chordLength = Math.hypot(start.x - end.x, start.y - end.y);
arcRadius = calcArcRadius(chordLength, h);
drawArc(start, arcRadius, end);
});
document
.querySelector('#control input')
.addEventListener('input', (e) => {
h = +e.currentTarget.value;
arcRadius = calcArcRadius(chordLength, h);
drawArc(start, arcRadius, end);
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.