canvas 基本使用

98 阅读5分钟

参考文章:www.runoob.com/w3cnote/htm…

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>canvas</title>
	</head>
	<body>
		<h1 class="title"> canvas基本使用 </h1>
		<canvas id="tutorial" width="1000" height="600">
			你的浏览器不支持 canvas,请升级你的浏览器。
		</canvas>
	</body>
</html>

<script>
	let img = new Image();
	img.src = '/ao.jpeg';
	let yzbgi = new Image();
	yzbgi.src = '/yzbj2.jpeg';
	let sun = new Image();
	sun.src = '/ty.png';
	let earth = new Image();
	earth.src = '/dq.png';
	let moon = new Image();
	moon.src = '/yq.png';
	let sx = new Image();
	sx.src = '/sx.png';
	let jx = new Image();
	jx.src = '/jx.png';
	let twx = new Image();
	twx.src = '/twx.png';
	img.onload = () => {
		start();
	};

	function start() {
		var canvas = document.getElementById('tutorial');
		if (!canvas.getContext) return;
		var ctx = canvas.getContext('2d');

		// fillStyle 和 strokeStyle
		// fillStyle 设置或返回用于填充绘画的颜色、渐变或模式
		// strokeStyle 设置或返回用于笔触的颜色、渐变或模式

		// 填充矩形
		// ctx.fillStyle = '#ccd7e9';
		// ctx.fillRect(10, 10, 55, 50);
		// 描边矩形
		// ctx.strokeStyle = '#ccd7e9';
		// ctx.strokeRect(70, 70, 55, 50);
		// 绘制线段
		// ctx.strokeStyle = 'red';
		// ctx.beginPath();
		// ctx.moveTo(100, 50);
		// ctx.lineTo(200, 100);
		// ctx.closePath();
		// ctx.stroke();
		// 绘制三角形
		// ctx.strokeStyle = 'red';
		// ctx.beginPath();
		// ctx.moveTo(200, 50);
		// ctx.lineTo(300, 50);
		// ctx.lineTo(300, 100);
		// ctx.lineTo(200, 50); // 使用 closePath() 会自动绘制最后一条线
		// ctx.closePath();
		// ctx.stroke();
		// 填充三角形
		// ctx.fillStyle = 'red';
		// ctx.beginPath();
		// ctx.moveTo(350, 50);
		// ctx.lineTo(450, 50);
		// ctx.lineTo(450, 100);
		// ctx.lineTo(200, 50); // 使用 fill() 会闭合 自动绘制最后一条线
		// ctx.fill();
		// 绘制五角星
		// ctx.strokeStyle = '#d7e3d5';
		// ctx.beginPath();
		// ctx.moveTo(500, 50);
		// ctx.lineTo(600, 50);
		// ctx.lineTo(500, 100);
		// ctx.lineTo(550, 25);
		// ctx.lineTo(600, 100);
		// ctx.closePath();
		// ctx.stroke();
		// 填充五角星
		// ctx.fillStyle = '#d7e3d5';
		// ctx.beginPath();
		// ctx.moveTo(650, 50);
		// ctx.lineTo(750, 50);
		// ctx.lineTo(650, 100);
		// ctx.lineTo(700, 25);
		// ctx.lineTo(750, 100);
		// ctx.fill();
		// 绘制圆弧
		let PI = Math.PI;
		// ctx.strokeStyle = '#40bcee';
		// ctx.beginPath();
		// ctx.arc(500, 150, 100, 0, PI, false);
		// ctx.closePath();
		// ctx.stroke();
		// 绘制填充圆弧
		// ctx.fillStyle = '#40bcee';
		// ctx.beginPath();
		// ctx.arc(850, 150, 100, 0, PI * 2, false);
		// ctx.fill();
		// 绘制贝塞尔曲线
		// ctx.strokeStyle = '#7db6bf';
		// ctx.beginPath();
		// ctx.moveTo(100, 200);
		// ctx.bezierCurveTo(150, 150, 200, 250, 300, 200);
		// ctx.stroke();

		// line style 线条样式
		// lineWidth 线宽
		// ctx.strokeStyle = 'red';
		// ctx.lineWidth = 15;
		// ctx.beginPath();
		// ctx.moveTo(100, 50);
		// ctx.lineTo(200, 100);
		// ctx.closePath();
		// ctx.stroke();
		// lineCap 线条末端样式

		// 绘制一条线宽为10,线条末端为方形的线条
		// ctx.strokeStyle = '#7db6bf';
		// ctx.lineWidth = 10;
		// ctx.lineCap = 'butt';
		// ctx.beginPath();
		// ctx.moveTo(800, 300);
		// ctx.lineTo(1000, 300);
		// ctx.stroke();
		// 绘制一条线宽为20,线条末端为圆形的线条
		// ctx.strokeStyle = '#7db6bf';
		// ctx.lineWidth = 20;
		// ctx.lineCap = 'round';
		// ctx.beginPath();
		// ctx.moveTo(800, 400);
		// ctx.lineTo(1000, 400);
		// ctx.stroke();
		// 绘制一条线宽为30,线条末端以方形结束,但是增加了一个宽度和线段相同,高度是线度一半的矩形区域
		// ctx.strokeStyle = '#7db6bf';
		// ctx.lineWidth = 30;
		// ctx.lineCap = 'square';
		// ctx.beginPath();
		// ctx.moveTo(800, 500);
		// ctx.lineTo(1000, 500);
		// ctx.stroke();

		// lineJoin 设定线条与线条间接合处的样式
		// ctx.strokeStyle = '#96b97d';
		// ctx.lineWidth = 10;
		// ctx.lineJoin = 'round';
		// ctx.beginPath();
		// ctx.moveTo(300, 400);
		// ctx.lineTo(500, 400);
		// ctx.lineTo(500, 450);
		// ctx.closePath();
		// ctx.stroke();

		// 虚线:setLineDash 方法和 lineDashOffset 属性
		// ctx.strokeStyle = '#000';
		// ctx.lineWidth = 1;
		// ctx.setLineDash([20, 10]);
		// ctx.lineDashOffset = 0;
		// ctx.strokeRect(20, 450, 100, 100);

		// 绘制文本
		// ctx.restore();
		// ctx.fillStyle = '#0586fb';
		// ctx.strokeStyle = '#7db6bf';
		// ctx.font = 'bold 30px Arial';
		// ctx.textAlign = 'right';
		// ctx.textBaseline = 'top';
		// ctx.direction = 'inherit';
		// ctx.fillText('Hello World 注意看我', 500, 500, 500);
		// ctx.strokeText('Hello World', 500, 550);

		// 绘制图片
		// ctx.drawImage(img, 200, 50, 200, 100);
		// ctx.drawImage(img, 1070, 200, 200, 100, 500, 50, 200, 100);

		// 两个常用的方法:
		// save()	保存当前环境的状态。
		// restore()	返回之前保存过的路径状态和属性。
		// ctx.save(); // 保存默认状态

		// ctx.fillStyle = 'red'; // 在原有配置基础上对颜色做改变
		// ctx.fillRect(15, 15, 120, 120); // 使用新的设置绘制一个矩形

		// ctx.save(); // 保存当前状态
		// ctx.fillStyle = '#FFF'; // 再次改变颜色配置
		// ctx.fillRect(30, 30, 90, 90); // 使用新的配置绘制一个矩形

		// ctx.restore(); // 重新加载之前的颜色状态
		// ctx.fillRect(45, 45, 60, 60); // 使用上一次的配置绘制一个矩形

		// ctx.restore(); // 加载默认颜色配置
		// ctx.fillRect(60, 60, 30, 30); // 使用加载的配置绘制一个矩形

		// 变形
		// translate(x, y) 用来移动 canvas 的原点到指定的位置
		// rotate(angle) 旋转坐标轴
		// scale(x, y) 缩小或者放大
		// transform(a, b, c, d, e, f)
		/*
			a	水平缩放绘图。
			b	水平倾斜绘图。
      c	垂直倾斜绘图。
      d	垂直缩放绘图。
      e	水平移动绘图。
      f	垂直移动绘图。
			*/
		// 移动原点
		// ctx.save();
		// ctx.translate(10, 10);
		// ctx.fillStyle = '#40bcee';
		// ctx.fillRect(0, 0, 100, 100);
		// ctx.restore();
		// ctx.strokeStyle = 'red';
		// ctx.strokeRect(10, 10, 100, 100);
		// 旋转坐标轴
		// ctx.save();
		// ctx.translate(500, 200);
		// ctx.rotate((PI / 180) * 30);
		// ctx.fillStyle = '#000';
		// ctx.fillRect(0, 0, 1000, 600);
		// ctx.fillStyle = '#40bcee';

		// ctx.fillRect(0, 0, 100, 100);
		// ctx.restore();
		// ctx.save();
		// ctx.strokeStyle = 'red';
		// ctx.strokeRect(10, 10, 100, 100);
		// ctx.restore();
		// 放大
		// ctx.save();
		// ctx.fillStyle = '#40bcee';
		// ctx.strokeStyle = 'red';
		// ctx.scale(2, 2);
		// ctx.fillRect(20, 20, 100, 100);
		// ctx.strokeRect(200, 100, 100, 100);
		// ctx.restore();

		// 合成
		// globalCompositeOperation
		// ctx.fillStyle = '#40bcee';
		// ctx.fillRect(0, 0, 100, 100);
		// ctx.globalCompositeOperation = 'source-over';
		// ctx.fillStyle = '#0586fb';
		// ctx.fillRect(50, 50, 100, 100);

		// 裁剪
		// clip();
		// ctx.fillStyle = '#40bcee';
		// ctx.beginPath();
		// ctx.moveTo(100, 100);
		// ctx.lineTo(300, 100);
		// ctx.lineTo(300, 300);
		// ctx.lineTo(100, 300);
		// ctx.fill();
		// ctx.clip();
		// ctx.fillStyle = '#0586fb';
		// ctx.fillRect(200, 200, 400, 400);

		// 动画
		// 绘制太阳系
		let width = 1000;
		let height = 600;
		ctx.clearRect(0, 0, width, height); //清空画布
		ctx.drawImage(yzbgi, 0, 0, width, height); // 给画布填充背景图
		ctx.save();

		// 画太阳
		ctx.translate(width / 2, height / 2);
		ctx.drawImage(sun, -50, -50, 100, 100);

		// 地球轨道
		ctx.strokeStyle = 'rgba(255,255,255,.5)';
		ctx.beginPath();
		ctx.arc(0, 0, 150, 0, PI * 2, false);
		ctx.stroke();

		let time = new Date();
		// 画地球
		// 旋转坐标轴,确定地球位置,60秒转一圈
		ctx.rotate(((2 * PI) / 60) * time.getSeconds() + ((2 * PI) / 60000) * time.getMilliseconds());
		ctx.translate(150, 0);
		ctx.drawImage(earth, -20, -20, 40, 40);

		// 月球轨道
		ctx.beginPath();
		ctx.arc(0, 0, 30, 0, PI * 2, false);
		ctx.stroke();

		// 画月球
		// 旋转坐标轴,确定月球位置,6秒转一圈
		ctx.rotate(((2 * PI) / 6) * time.getSeconds() + ((2 * PI) / 6000) * time.getMilliseconds());
		ctx.translate(30, 0);
		ctx.drawImage(moon, -5, -5, 10, 10);
		ctx.restore();

		// 水星轨道
		ctx.save();
		ctx.translate(width / 2, height / 2);
		ctx.strokeStyle = 'rgba(255,255,255,.5)';
		ctx.beginPath();
		ctx.arc(0, 0, 80, 0, PI * 2, false);
		ctx.stroke();

		// 画水星
		// 旋转坐标轴,确定水星位置,88秒水星转一圈
		ctx.rotate(((2 * PI) / 88) * time.getSeconds() + ((2 * PI) / 88000) * time.getMilliseconds());
		ctx.translate(80, 0);
		ctx.drawImage(sx, -10, -10, 20, 20);
		ctx.restore();

		// 金星轨道
		ctx.save();
		ctx.translate(width / 2, height / 2);
		ctx.strokeStyle = 'rgba(255,255,255,.5)';
		ctx.beginPath();
		ctx.arc(0, 0, 105, 0, PI * 2, false);
		ctx.stroke();

		// 画金星
		// 旋转坐标轴,确定金星位置,30秒金星转一圈
		ctx.rotate(((2 * PI) / 30) * time.getSeconds() + ((2 * PI) / 30000) * time.getMilliseconds());
		ctx.translate(105, 0);
		ctx.drawImage(jx, -10, -10, 20, 20);
		ctx.restore();

		// 天王星轨道
		ctx.save();
		ctx.translate(width / 2, height / 2);
		ctx.strokeStyle = 'rgba(255,255,255,.5)';
		ctx.beginPath();
		ctx.arc(0, 0, 260, 0, PI * 2, false);
		ctx.stroke();

		// 画天王星
		// 旋转坐标轴,确定天王星位置,84秒天王星转一圈
		ctx.rotate(((2 * PI) / 84) * time.getSeconds() + ((2 * PI) / 84000) * time.getMilliseconds());
		ctx.translate(260, 0);
		ctx.drawImage(twx, -50, -25, 100, 50);
		ctx.restore();

		// 更新每帧动画
		window.requestAnimationFrame(start);
		// setTimeout(() => {
		// 	start();
		// }, 1000);
	}
</script>

<style>
	.title {
		text-align: center;
		margin-bottom: 10px;
	}
	#tutorial {
		margin: 0 auto;
		display: block;
		border: 1px solid #000;
	}
</style>