Public
Edited
Mar 7, 2024
Insert cell
Insert cell
margin = 0.03 * width
Insert cell
fw = width
Insert cell
l = margin
Insert cell
r=fw-l
Insert cell
c = width / 2
Insert cell
fh = width / 2
Insert cell
t = margin
Insert cell
b = fh - t
Insert cell
hh = fh / 2
Insert cell
deadzone = 0.1
Insert cell
dzw = ((r - l) * deadzone) / 2
Insert cell
dzh = fh * 0.02
Insert cell
{
const el = svg`<svg
width=${fw} height=${fh}
stroke-width=${Math.min(fw, fh) * 0.02} stroke-linejoin="round"
style="touch-action:none;">
<clipPath id="clip">
<use href="#poly" />
</clipPath>
<rect x=0 y=0 width=${fw} height=${fh} fill=blue />
<polygon id="poly" points="
${c},${t}
${r - dzw},${hh - dzh}
${r},${hh - dzh}
${r},${hh + dzh}
${r - dzw},${hh + dzh}
${c},${b}
${l + dzw},${hh + dzh}
${l},${hh + dzh}
${l},${hh - dzh}
${l + dzw},${hh - dzh}
" stroke="black" fill="red" />
<rect id="filler" fill="green" clip-path="url(#clip)" x=${c} y=${t} width=100 height=${
b - t
} />
<text x=100 y=100>Hello</text>
<circle id="circle" cx=100 cy=100 r=10 fill="#fff7" />
</svg>`;
const circle = el.getElementById("circle");
const filler = el.getElementById("filler");

function send(ev) {
ev.preventDefault();
if (!ev.isPrimary) return;
const x = ev.offsetX,
y = ev.offsetY;
const offset = x - c;
filler.width.baseVal.value = Math.abs(offset);
filler.x.baseVal.value = offset >= 0 ? c : x;

circle.cx.baseVal.value = x;
circle.cy.baseVal.value = y;
}
el.addEventListener("pointerdown", send);
el.addEventListener("pointermove", send);

return el;
}
Insert cell
Insert cell
dummy = svg`<svg width=30vmin height=30vmin><rect fill=lightblue x=0 y=0 width=100 height=100 /></svg>`
Insert cell
Object.getPrototypeOf(dummy.getBoundingClientRect())
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more