Public
Edited
May 8, 2024
1 star
Insert cell
Insert cell
Insert cell
circle = {
// Create an SVG element
const svg = DOM.svg(300, 300);

// Circle parameters
const radius = 100;
const center = { x: 150, y: 150 };
const dotRadius = 5;
const duration = 4000; // 4 seconds

// Create the circle
const circle = document.createElementNS(
"http://www.w3.org/2000/svg",
"circle"
);
circle.setAttribute("cx", center.x);
circle.setAttribute("cy", center.y);
circle.setAttribute("r", radius);
circle.setAttribute("fill", "none");
circle.setAttribute("stroke", "black");

// Create the dot
const dot = document.createElementNS("http://www.w3.org/2000/svg", "circle");
dot.setAttribute("cx", center.x - radius - 50);
dot.setAttribute("cy", center.y);
dot.setAttribute("r", dotRadius);
dot.setAttribute("fill", "red");

// Add the circle and dot to the SVG
svg.appendChild(circle);
svg.appendChild(dot);

// Initialize animation variables
let start = null;
let direction = 1;

// Animation function for the dot
function animateDot(timestamp) {
if (!start) start = timestamp;
const elapsed = timestamp - start;

// Calculate the horizontal position
const totalDistance = 2 * (radius + 50);
const progress = (elapsed / duration) % 1; // Between 0 and 1
const xOffset =
direction === 1
? progress * totalDistance
: (1 - progress) * totalDistance;
const x = center.x - radius - 50 + xOffset;

// Update dot position
dot.setAttribute("cx", x);

// Change color when inside the circle
if (x >= center.x - radius && x <= center.x + radius) {
dot.setAttribute("fill", "green");
} else {
dot.setAttribute("fill", "red");
}

// Reverse direction every full cycle
if (elapsed >= duration) {
direction *= -1;
start = timestamp;
}

requestAnimationFrame(animateDot);
}

// Start the animation
requestAnimationFrame(animateDot);

// Return the SVG element
return svg;
}
Insert cell
{
// Create an SVG element
const svg = DOM.svg(300, 300);

// Define the vertices of the multi-vertex line
const points = [
{ x: 50, y: 250 },
{ x: 100, y: 100 },
{ x: 150, y: 200 },
{ x: 200, y: 50 },
{ x: 250, y: 150 }
];
const duration = 4000; // 4 seconds
const dotRadius = 5;

// Create the polyline
const polyline = document.createElementNS(
"http://www.w3.org/2000/svg",
"polyline"
);
polyline.setAttribute("points", points.map((p) => `${p.x},${p.y}`).join(" "));
polyline.setAttribute("fill", "none");
polyline.setAttribute("stroke", "black");

// Create the dot
const dot = document.createElementNS("http://www.w3.org/2000/svg", "circle");
dot.setAttribute("cx", points[0].x);
dot.setAttribute("cy", points[0].y);
dot.setAttribute("r", dotRadius);
dot.setAttribute("fill", "red");

// Add the polyline and dot to the SVG
svg.appendChild(polyline);
svg.appendChild(dot);

// Initialize animation variables
let start = null;
let direction = 1;

// Linear interpolation function between two points
function lerp(a, b, t) {
return {
x: a.x + (b.x - a.x) * t,
y: a.y + (b.y - a.y) * t
};
}

// Animation function for the dot
function animateDot(timestamp) {
if (!start) start = timestamp;
const elapsed = timestamp - start;

// Calculate the normalized progress along the polyline (0 to 1)
const totalDistance = points.length - 1;
const progress = (elapsed / duration) % 1; // Progress between 0 and 1
const t =
direction === 1
? progress * totalDistance
: (1 - progress) * totalDistance;

// Determine which segment the dot is on
const segment = Math.floor(t);
const segmentProgress = t - segment;

// Interpolate the dot position along the current segment
const a = points[segment];
const b = points[(segment + 1) % points.length];
const position = lerp(a, b, segmentProgress);

dot.setAttribute("cx", position.x);
dot.setAttribute("cy", position.y);

// Reverse direction after completing the animation cycle
if (elapsed >= duration) {
direction *= -1;
start = timestamp;
}

requestAnimationFrame(animateDot);
}

// Start the animation
requestAnimationFrame(animateDot);

// Return the SVG element
return svg;
}
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