Skip to content

Instantly share code, notes, and snippets.

@ferdaber
Last active September 6, 2022 18:01
Show Gist options
  • Save ferdaber/6da400effe91a904d824c2548ebf2a67 to your computer and use it in GitHub Desktop.
Save ferdaber/6da400effe91a904d824c2548ebf2a67 to your computer and use it in GitHub Desktop.
Animated Wedge Plotting
Animated Wedge Plotting
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Arc Plot</title>
</head>
<body>
<svg
id="svg"
viewBox="0 0 100 100"
width="500"
height="500"
xmlns="http://www.w3.org/2000/svg"
></svg>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
const svg = document.getElementById("svg");
function rad(deg) {
return (deg * Math.PI) / 180;
}
function deg(rad) {
return (rad * 180) / Math.PI;
}
function polarToRect(angleDeg, radius, offset) {
const x = Math.cos(rad(angleDeg)) * radius + offset[0],
y = Math.sin(rad(angleDeg)) * -radius + offset[1];
return [x, y];
}
let pathId = 0;
function createArc(d0, d1, r, c, stroke = "black") {
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.id = `path-${pathId++}`;
path.setAttribute("strokeWidth", "1");
path.setAttribute("stroke", stroke);
path.setAttribute("fill", "none");
const [x0, y0] = polarToRect(d0, r, c),
[x1, y1] = polarToRect(d1, r, c);
const sweepBit = Number(d0 > d1);
path.setAttribute(
"d",
`M ${x0} ${y0} A ${r} ${r} 0 0 ${sweepBit} ${x1} ${y1}`
);
svg.appendChild(path);
}
function createWedge(d0, d1, r0, r1, c, fill = "black") {
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.id = `path-${pathId++}`;
path.setAttribute("stroke", "none");
path.setAttribute("fill", fill);
const [x0, y0] = polarToRect(d0, r0, c),
[x1, y1] = polarToRect(d1, r0, c),
[x2, y2] = polarToRect(d1, r1, c),
[x3, y3] = polarToRect(d0, r1, c);
const sweepBit01 = Number(d0 > d1);
const sweepBit23 = 1 - sweepBit01;
path.setAttribute(
"d",
`M ${x0} ${y0} A ${r0} ${r0} 0 0 ${sweepBit01} ${x1} ${y1} L ${x2} ${y2} A ${r1} ${r1} 0 0 ${sweepBit23} ${x3} ${y3} Z`
);
svg.appendChild(path);
return path.id;
}
function updateWedge(pathId, d0, d1, r0, r1, c, fill = "black") {
const path = document.getElementById(pathId);
if (!path) {
throw new Error(`Cannot find path ID: ${pathId}`);
}
path.setAttribute("fill", fill);
const [x0, y0] = polarToRect(d0, r0, c),
[x1, y1] = polarToRect(d1, r0, c),
[x2, y2] = polarToRect(d1, r1, c),
[x3, y3] = polarToRect(d0, r1, c);
const sweepBit01 = Number(d0 > d1);
const sweepBit23 = 1 - sweepBit01;
path.setAttribute(
"d",
`M ${x0} ${y0} A ${r0} ${r0} 0 0 ${sweepBit01} ${x1} ${y1} L ${x2} ${y2} A ${r1} ${r1} 0 0 ${sweepBit23} ${x3} ${y3} Z`
);
return pathId;
}
const center = [50, 50];
const radius = 45;
const NUM_FRAMES = 64;
const startAngles = [0, 24, 72, 144, 240].map((x) => x + 90);
const endAngles = [24, 72, 144, 240, 360].map((x) => x + 90);
const colors = ["red", "blue", "green", "yellow", "orange"];
const START_ANGLE = startAngles[0];
let frame = 0,
wedgeIds;
const rafCb = () => {
if (!wedgeIds) {
wedgeIds = startAngles.map((_, idx) => {
const startAngle = startAngles[idx],
endAngle = endAngles[idx],
color = colors[idx];
const offsetStartAngle =
START_ANGLE + ((startAngle - START_ANGLE) * frame) / NUM_FRAMES;
const offsetEndAngle =
START_ANGLE + ((endAngle - START_ANGLE) * frame) / NUM_FRAMES;
return createWedge(
offsetStartAngle,
offsetEndAngle,
radius - 10,
radius,
center,
color
);
});
} else {
startAngles.forEach((_, idx) => {
const wedgeId = wedgeIds[idx],
startAngle = startAngles[idx],
endAngle = endAngles[idx],
color = colors[idx];
const offsetStartAngle =
START_ANGLE + ((startAngle - START_ANGLE) * frame) / NUM_FRAMES;
const offsetEndAngle =
START_ANGLE + ((endAngle - START_ANGLE) * frame) / NUM_FRAMES;
return updateWedge(
wedgeId,
offsetStartAngle,
offsetEndAngle,
radius - 10,
radius,
center,
color
);
});
}
frame++;
if (frame > NUM_FRAMES) {
return;
} else {
window.requestAnimationFrame(rafCb);
}
};
window.requestAnimationFrame(rafCb);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment