canvas - Bezier 贝塞尔曲线

二次贝塞尔:quadraticCurveTo(cpx, cpy, x, y)

三次贝塞尔:bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y)

cpx和cpy是控制点坐标,x和y是终止点坐标html

效果图:
在这里插入图片描述web

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
		#cvs {
			background-color: #ccc;
		}
	</style>
</head>
<body>
	<div id='container'>
		<canvas id='cvs'>
			sorry, your browser doesn't support canvas API.
		</canvas>
	</div>
</body>
<script>
	window.onload = function() {
		// 获取画布
		const cvs = document.querySelector('#cvs')
		cvs.width = 800
		cvs.height = 600
		// 获取画笔
		const ctx = cvs.getContext('2d')

		// 草原
		drawPrairie(ctx)

		// 天空
		drawSky(ctx)

		// 云朵
		drawClouds(ctx)

		function drawPrairie(ctx) {
			ctx.save()

			ctx.beginPath()
			ctx.moveTo(0, 420)
			ctx.bezierCurveTo(250, 300, 350, 550, 800, 400)
			ctx.lineTo(800, 600)
			ctx.lineTo(0, 600)
			ctx.closePath()

			const grd = ctx.createLinearGradient(0, 600, 600, 0)
			grd.addColorStop(0, '#00aa58')
			grd.addColorStop(0.3, '#63aa7b')
			grd.addColorStop(1, '#04aa00')

			ctx.fillStyle = grd

			ctx.fill()

			ctx.restore()
		}

		function drawSky(ctx) {
			ctx.save()

			ctx.beginPath()
			ctx.moveTo(0, 420)
			ctx.bezierCurveTo(250, 300, 350, 550, 800, 400)
			ctx.lineTo(800, 0)
			ctx.lineTo(0, 0)
			ctx.closePath()

			const grd = ctx.createRadialGradient(400, 0, 50, 400, 0, 200)
			grd.addColorStop(0, '#42a9aa')
			grd.addColorStop(1, '#2491aa')

			ctx.fillStyle = grd

			ctx.fill()

			ctx.restore()
		}

		function drawClouds(ctx) {
			for(let i = 0; i < 5; i++) {
				const x0 = 500 * Math.random() + 50
				const y0 = 200 * Math.random() + 50
				const c0 = 100 * Math.random() + 50

				// 单个云朵
				drawCloud(ctx, x0, y0, c0)
			}
		}

		function drawCloud(ctx, cx, cy, cw) {
			const maxWidth = 800
			cx = cx % maxWidth
			const ch = cw * 0.6

			ctx.beginPath()

			const grd = ctx.createLinearGradient(0, 0, 0, cy)
			grd.addColorStop(0, 'rgba(255, 255, 255, 0.8')
			grd.addColorStop(1, 'rgba(255, 255, 255, 0.5')

			ctx.arc(cx, cy, cw * 0.19, 0, 360)
			ctx.arc(cx + cw * 0.08, cy - ch * 0.3, cw * 0.11, 0, 360)
			ctx.arc(cx + cw * 0.3, cy - ch * 0.25, cw * 0.25, 0, 360)
			ctx.arc(cx + cw * 0.6, cy, cw * 0.21, 0, 360)
			ctx.arc(cx + cw * 0.3, cy - ch * 0.1, cw * 0.28, 0, 360)

			ctx.fillStyle = grd
			ctx.fill()
		}
	}
</script>
</html>