注册
web

canvas绘制行星环绕

太阳与月亮.gif

前言


最近学校学了一些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)


结语


以上过程便能简单的绘制一个简易太阳系图形动画了,通过文档就能快速的绘制一个简单的图形,但是要绘制复杂的图形的话还是要花时间去研究一下文档。


作者:codePanda
来源:juejin.cn/post/7212442380263112760

0 个评论

要回复文章请先登录注册