Как сделать эту кривую Безье похожей на кривую на изображении - PullRequest
0 голосов
/ 18 сентября 2019

Я много раз пытался создать кривую Безье, которая бы напоминала этот путь , по которому в конце концов движется солнце.Я руководствовался тем, что использовал SVG для создания эффекта, а затем добавил CSS, чтобы заполнить пустоту формы после того, как форма была нарисована с помощью javascript или в этом случае SVG.

Может кто-нибудь помочь с тем, как я должен в конечном итогесделать форму в коде, как я пытался с SVG, но, несмотря ни на что, форма не дает плавности и оставляет несколько выпуклостей на линии Безье по сравнению с изображением .

Вот SVG.Он находится в разработке, но идея заключается в том, что безье имеет ту же плавность, что и кривая на изображении, и позже может быть применено к CSS-эффектам, которые могут быть остановлены и запущены в случайные моменты при необходимости.Возможно ли такое действие даже с помощью CSS?Имеется в виду заполнить форму SVG такими способами, как она изображена на изображении.

// 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>
...