canvas绘制行星环绕
前言
最近学校学了一些JavaScript课程,其中涉及到了部分有关于canvas的知识点,万万没想到老师只是用了一节课提了一下有关canvas的一些有关使用就布置下来了一个作业--采用canvas绘制一个简易太阳系,咱作为学生还能说啥,只能冲啦。
实现原理
只是单纯的canvas方法的使用再加上一点点js的使用就可以实现这个简单的实例啦。
实现代码
html部分
<!-- 画布元素 -->
<canvas id="canvas"></canvas>
初始化画布
js获取画布元素,初始化画布背景色为黑色,设置画布真实绘制宽高为1200,浏览器呈现宽高为600px,getContext('2d')
获取画布的2D上下文。
let canvas = document.getElementById('canvas')
canvas.style.background = 'black'
// 浏览器渲染出画布宽高
canvas.style.width = 600 + 'px'
canvas.style.height = 600 + 'px'
// 绘制画布真实宽高
canvas.width = 1200
canvas.height = 1200
let context = canvas.getContext('2d');
绘制太阳
绘制一个圆心为(600,600)半径为100的圆,在绘制前有几点要了解,因为canvas只支持两种形式的图形绘制:矩形和路径(由一系列点连成的线段),所以我们要使用到路径绘制函数。其中beginPath()
新建一条路径,在该路径闭合前,图像绘制将在该路径中进行,其中fillSyle
设置的是图像填充色,通常以closePath()
闭合该路径,但由于fill()
会自动闭合路径所以closePath()
可以省去。详情可以参考MDN|Canvas
context.beginPath() // 开始路径绘制
context.arc(600, 600, 100, 0, Math.PI*2, true)
context.fillStyle = 'red' // 图形填充色
context.fill() // 进行填充
绘制地球轨道
与上面太阳的绘制相差不大,将填充换为了描边。strokeStyle
定义图形轮廓颜色,stroke()
开始绘制轮廓,最后采用closePath()
闭合路径。
context.beginPath()
context.arc(600, 600, 300, 0, Math.PI*2, true) // 圆心(300,300) 半径为150的圆环
context.strokeStyle = 'rgb(255,255,255,0.3)'
context.stroke()
context.closePath()
绘制地球
注意: 这里地球的圆心坐标为(0,0)这是因为我们调用了translate()
这一函数,通过这一函数我们将起始点偏移到指定位置,下文将以此坐标为新的起始点。此外需要用save()
保存当前画布状态,不然后续循环会出问题。再调用rotate()
方法实现旋转,其中rotate()
是使得其下文绘制的图形实现旋转,旋转中心为当前起始点坐标。
context.save(); // 保存当前状态
var angle=time*Math.PI/180/8;
context.translate(600,600); // 起始点偏移量,太阳中心
context.rotate(angle);
context.translate(300,0); // 地球,月球轨道中心
context.beginPath()
context.arc(0,0,40,0,2*Math.PI,false);
context.fillStyle = 'blue'
context.strokeStyle = 'blue'
context.fill()
月球轨道及月球
// 月球轨道
context.beginPath()
context.arc(0, 0, 100, 0, Math.PI*2, true)
context.strokeStyle = 'rgb(255,255,255,0.3)'
context.stroke()
context.closePath()
context.rotate(-8*angle);
// 月球
context.beginPath()
context.arc(100,0,20,0,2*Math.PI,false);
context.fillStyle = '#fff'
context.fill()
js完整部分
定义一个绘制函数draw()
,通过setInterval()
函数循环调用,其中要注意在使用save()
函数后要调用restore()
函数恢复状态,为下次的绘制做准备。
let canvas = document.getElementById('canvas')
canvas.style.background = 'black'
// 浏览器渲染出画布宽高
canvas.style.width = 600 + 'px'
canvas.style.height = 600 + 'px'
// 绘制画布真实宽高
canvas.width = 1200
canvas.height = 1200
let context = canvas.getContext('2d');
// context.scale(2, 2)
let time = 0
function draw() {
context.clearRect(0,0,canvas.width,canvas.height); // 清除所选区域
// 绘制太阳
context.beginPath() // 开始路径绘制
context.arc(600, 600, 100, 0, Math.PI*2, true)
context.fillStyle = 'red' // 图形填充色
context.fill() // 进行填充
// 绘制地球轨道
context.beginPath()
context.arc(600, 600, 300, 0, Math.PI*2, true) // 圆心(300,300) 半径为150的圆环
context.strokeStyle = 'rgb(255,255,255,0.3)'
context.stroke()
context.closePath()
context.save(); // 保存当前状态
var angle=time*Math.PI/180/8;
context.translate(600,600); // 起始点偏移量,太阳中心
context.rotate(angle);
context.translate(300,0); // 地球,月球轨道中心
// 地球
context.beginPath()
context.arc(0,0,40,0,2*Math.PI,false);
context.fillStyle = 'blue'
context.strokeStyle = 'blue'
context.fill()
// 月球轨道
context.beginPath()
context.arc(0, 0, 100, 0, Math.PI*2, true)
context.strokeStyle = 'rgb(255,255,255,0.3)'
context.stroke()
context.closePath()
context.rotate(-8*angle);
// 月球
context.beginPath()
context.arc(100,0,20,0,2*Math.PI,false);
context.fillStyle = '#fff'
context.fill()
context.restore(); // 恢复状态
time++
}
setInterval(draw,30)
结语
以上过程便能简单的绘制一个简易太阳系图形动画了,通过文档就能快速的绘制一个简单的图形,但是要绘制复杂的图形的话还是要花时间去研究一下文档。
来源:juejin.cn/post/7212442380263112760