'React - sinusoidal animation of lines
i recreated an animation that i have seen somewhere but cannot find now. it's a simple thing - like a propagating wave of lines. i've adapted a script i found that animates a line - this happens to be a React svg showing how a sine curve results from circular movement of a point. i have some javascript experience but i don't really know about React yet - so i created each element with a single CreateElement.. here's the question: how would i best create a series of lines (like with a loop) in which each line has an offset of a few deg for the point movement along the circle as well as a spatial offset of maybe one radius. i've adapted the script i found as follows below but i would like to miminize it - i.e. create the elements with a kind of loop. searching for 'loop' in context with CreateElement didn't get me far.. to me this kind of scripting is more like an evening passtime - as i have a demanding day time job,
const Sine = () => {
const [degree, setDegree] = React.useState(0);
const lastTimeRef = React.useRef(null);
const frameRef = React.useRef();
const animate = time => {
if (lastTimeRef.current != null) {
const delta = (time - lastTimeRef.current) * 0.08;
setDegree(previousDegree => (previousDegree + delta) % 360);
}
lastTimeRef.current = time;
frameRef.current = requestAnimationFrame(animate);
};
React.useEffect(() => {
frameRef.current = requestAnimationFrame(animate);
return () => cancelAnimationFrame(frameRef.current);
}, []);
return React.createElement(Draw, { degree: degree });
};
const factor = 20;
const offset = 15;
const sin = value => -Math.sin(value / 180 * Math.PI);
const cos = value => Math.cos(value / 180 * Math.PI);
const Draw = ({ degree }) =>
React.createElement("svg", { width: "1240", height: "650", viewBox: "0 -20 1240 650" },
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree) * factor,
x2: 1240,
y2: sin(degree) * factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + offset) * factor + factor,
x2: 1240,
y2: sin(degree + offset) * factor + factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 2*offset) * factor + 2*factor,
x2: 1240,
y2: sin(degree + 2*offset) * factor + 2*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 3*offset) * factor + 3*factor,
x2: 1240,
y2: sin(degree + 3*offset) * factor + 3*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 4*offset) * factor + 4*factor,
x2: 1240,
y2: sin(degree + 4*offset) * factor + 4*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 5*offset) * factor + 5*factor,
x2: 1240,
y2: sin(degree + 5*offset) * factor + 5*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 6*offset) * factor + 6*factor,
x2: 1240,
y2: sin(degree + 6*offset) * factor + 6*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 7*offset) * factor + 7*factor,
x2: 1240,
y2: sin(degree + 7*offset) * factor + 7*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 8*offset) * factor + 8*factor,
x2: 1240,
y2: sin(degree + 8*offset) * factor + 8*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 9*offset) * factor + 9*factor,
x2: 1240,
y2: sin(degree + 9*offset) * factor + 9*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 10*offset) * factor + 10*factor,
x2: 1240,
y2: sin(degree + 10*offset) * factor + 10*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 11*offset) * factor + 11*factor,
x2: 1240,
y2: sin(degree + 11*offset) * factor + 11*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 12*offset) * factor + 12*factor,
x2: 1240,
y2: sin(degree + 12*offset) * factor + 12*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 13*offset) * factor + 13*factor,
x2: 1240,
y2: sin(degree + 13*offset) * factor + 13*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 14*offset) * factor + 14*factor,
x2: 1240,
y2: sin(degree + 14*offset) * factor + 14*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 15*offset) * factor + 15*factor,
x2: 1240,
y2: sin(degree + 15*offset) * factor + 15*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 16*offset) * factor + 16*factor,
x2: 1240,
y2: sin(degree + 16*offset) * factor + 16*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 17*offset) * factor + 17*factor,
x2: 1240,
y2: sin(degree + 17*offset) * factor + 17*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 18*offset) * factor + 18*factor,
x2: 1240,
y2: sin(degree + 18*offset) * factor + 18*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 19*offset) * factor + 19*factor,
x2: 1240,
y2: sin(degree + 19*offset) * factor + 19*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 20*offset) * factor + 20*factor,
x2: 1240,
y2: sin(degree + 20*offset) * factor + 20*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 21*offset) * factor + 21*factor,
x2: 1240,
y2: sin(degree + 21*offset) * factor + 21*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 22*offset) * factor + 22*factor,
x2: 1240,
y2: sin(degree + 22*offset) * factor + 22*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 23*offset) * factor + 23*factor,
x2: 1240,
y2: sin(degree + 23*offset) * factor + 23*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 24*offset) * factor + 24*factor,
x2: 1240,
y2: sin(degree + 24*offset) * factor + 24*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 25*offset) * factor + 25*factor,
x2: 1240,
y2: sin(degree + 25*offset) * factor + 25*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 26*offset) * factor + 26*factor,
x2: 1240,
y2: sin(degree + 26*offset) * factor + 26*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 27*offset) * factor + 27*factor,
x2: 1240,
y2: sin(degree + 27*offset) * factor + 27*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 28*offset) * factor + 28*factor,
x2: 1240,
y2: sin(degree + 28*offset) * factor + 28*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 29*offset) * factor + 29*factor,
x2: 1240,
y2: sin(degree + 29*offset) * factor + 29*factor }),
React.createElement("line", {
className: "thin",
x1: 0,
y1: sin(degree + 30*offset) * factor + 30*factor,
x2: 1240,
y2: sin(degree + 30*offset) * factor + 30*factor }),
React.createElement("g", { transform: "translate(0 0)" },
parseFloat(Math.sin(degree / 180 * Math.PI)).toFixed(6)));
ReactDOM.render( React.createElement(Sine, null), document.getElementById('app'));
the css to go with it is:
body {
background-color: #000000;
margin: 0;
padding: 0;
}
html {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
svg {
stroke: #C1003D;
fill: transparent;
stroke-width: 4px;
max-width: 100%;
max-height: 100%;
}
.thin {
stroke: #60001E;
fill: transparent;
stroke-width: 5px;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
