blob: 4e951bec9f6a4727f2ce897265bc783d259d89e3 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Wadsworth/Wheatstone</title>
<style>
svg {
display: block;
margin: 1em auto;
border: 1px solid black;
height: 32em;
max-height: 80vh;
}
.pointer {
transform: none;
transform-origin: 50% 50%;
}
.pointer path, .pointer circle {
stroke: black;
stroke-width: 1px;
}
.pointer circle {
fill: transparent;
}
</style>
<script>
let dragging = null;
let svg = null;
function start(element) { dragging = element; }
function stop() { dragging = null; }
function update(element, diff) {
element.dataset.angle = Number(element.dataset.angle) + diff;
element.style.transform = `rotate(${Math.floor(element.dataset.angle)}deg)`;
}
function onmove(event) {
if (dragging) {
const rect = svg.getBoundingClientRect();
const x = event.clientX - (rect.left + rect.width / 2);
const y = event.clientY - (rect.top + rect.height / 2);
const theta = Math.atan2(y, x) - Math.atan2(y - event.movementY, x - event.movementX);
let diff = theta * 180.0 / Math.PI;
if (diff > 180) { diff -= 360.0; } // We jump back full circle to keep the diff values meaningful in context.
if (diff < -180) { diff += 360.0; }
update(dragging, diff);
svg.querySelectorAll(".pointer").forEach((x) => {
if (x != dragging) {
const ratio = Number(dragging.dataset.ratio) / Number(x.dataset.ratio);
update(x, diff * ratio);
}
});
}
}
</script>
<svg onload="svg = this" onmousemove="onmove(event)" onmouseleave="stop()" onmouseup="stop()" viewBox="0 0 100 100">
<g data-angle="0" data-ratio="27" class="pointer">
<path d="M49 50 L80 50 Z"/>
<circle onmousedown="start(this.parentNode)" cx="85" cy="50" r="5"/>
</g>
<g data-angle="0" data-ratio="26" class="pointer">
<path d="M49 50 L70 50 Z"/>
<circle onmousedown="start(this.parentNode)" cx="75" cy="50" r="5"/>
</g>
</svg>
|