0

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>
dev m
  • 47
  • 1
  • 9
  • 1
    Take a look here: https://stackoverflow.com/q/29022438/1806348. It has many useful answers with code and mathematical solutions. – Jochem Kuijpers Sep 18 '19 at 21:05
  • Thank you for providing the link, but can you tell would the shape now exist, is it possible to add such CSS animation to the shape. The example in the link is made with JS +JQuery, can animation be used so, it would result like the image? – dev m Sep 19 '19 at 13:08
  • I'm afraid I don't understand what you are asking..? – Jochem Kuijpers Sep 20 '19 at 13:11
  • I have trouble making the shape as I have no idea where to start on that link and what actually draws the shape. Basically, after the shape is done, I must add an animation to it(dark blue and blue coloured in the image), which moves from 0% starting from the left edge where the colours fill the shape over time until the animation reaches to the right edge of the screen or 100%. – dev m Sep 20 '19 at 13:41
  • Do you know how bezier curves are defined (i.e. what the mathematical meaning is of the control points)? – Jochem Kuijpers Sep 20 '19 at 22:38
  • Unfortunately, not really, I just inquired here to find how I could achieve the functioning behind the image, so when everything is applied, the code makes the image look and operate like in the image. – dev m Sep 21 '19 at 00:10
  • Try reading up a bit on the math, it's not that complex. For example, the first 6-or-so chapters of https://pomax.github.io/bezierinfo/ should help you a lot in understanding them. Hopefully then you'll be able to figure out what you want to do with them :) – Jochem Kuijpers Sep 21 '19 at 01:22
  • I appreciate you sharing the link. Hopefully, I can later implement the animation transition as well into the curves. – dev m Sep 21 '19 at 10:08

0 Answers0