I have been trying all over and over to produce a bezier curve that would resemble this path on which eventually, the sun moves. I was guided to use SVG in producing the effect, and then add CSS to fill the hollowness of the shape after the shape has been drawn with javascript or in this case SVG.
Can someone assist on how I should eventually make the shape in code, as I tried with SVG, but no matter what, the shape do not produce the smoothness and leaves in a few bumps in the bezier line when compared to the image.
Here is the SVG. It is in development, but the idea is the bezier has the same smoothness as the curve on the image, and later be applicable to CSS effects that could be stopped and started at random moments when needed. Is such action even possible with CSS? Meaning to fill an SVG shape with such ways it is portrayed in the image.
// The smoothing ratio
const smoothing = 0.2
const points = [
[15, 35],
[40, 30],
[65, 10],
[95, 5],
[115, 20],
[125, 25],
]
//there should be more attributes here eventually.
const line = (pointA, pointB) => {
const lengthX = pointB[0] - pointA[0]
const lengthY = pointB[1] - pointA[1]
return {
length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
angle: Math.atan2(lengthY, lengthX)
}
}
const controlPoint = (current, previous, next, reverse) => {
const p = previous || current
const n = next || current
const o = line(p, n)
const angle = o.angle + (reverse ? Math.PI : 0)
const length = o.length * smoothing
const x = current[0] + Math.cos(angle) * length
const y = current[1] + Math.sin(angle) * length
return [x, y]
}
const bezierCommand = (point, i, a) => {
const cps = controlPoint(a[i - 1], a[i - 2], point)
const cpe = controlPoint(point, a[i - 1], a[i + 1], true)
return `C ${cps[0]},${cps[1]} ${cpe[0]},${cpe[1]} ${point[0]},${point[1]}`
}
const svgPath = (points, command) => {
const d = points.reduce((acc, point, i, a) => i === 0
? `M ${point[0]},${point[1]}`
: `${acc} ${command(point, i, a)}`
, '')
return `<path d="${d}" fill="none" stroke="black" />`
}
const svg = document.querySelector('.svg')
svg.innerHTML = svgPath(points, bezierCommand)
<svg viewBox="0 0 200 50" class="svg">
</svg>