javascript - How to make this bezier curve resemble the one in the image
问题描述
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>
解决方案
推荐阅读
- java - @Transactional 在带有 CrudRepository 的 Spring Boot 中不起作用
- internet-explorer - 有没有办法将 Webdriver 切换到打开新窗口并自动关闭父窗口的新会话?
- java - 绑定2个arraylists android
- python - selenium web 抓取中 .send_keys 的意外令牌错误
- apache-spark - 惰性数据结构的工作原理
- javascript - 即使使用布尔开关,Javascript 倒数计时器也太快了
- html - 角度 html 页面中的 URL 未呈现正确的页面
- json - 使用项目 1 的服务帐户 Json 密钥从项目 2 中的 Python Cloud Function 访问 Project1 的 BigQuery DataStore
- node.js - 通过 Cloudflare 为 socket.io 提供 HTTPS
- mongodb - 在更新时更改字符串以将一些“/”放在它的中间 MongoDb