Rain-weather
因为可视化大屏的业务需求,需要绘制全屏的天气效果。共用canvas绘制了晴天、雨天、台风天三种天气。在此记录供参考。
- html代码
<canvas id="weather"></canvas>
- JavaScript代码
function rainWeather() {
// 获取 canvas 元素和 2D 上下文
const canvas = document.getElementById('weather')
const ctx = canvas.getContext('2d')
// 设置 canvas 宽度和高度
const width = document.body.clientWidth
const height = document.body.clientHeight
canvas.width = width
canvas.height = height
// 定义雨滴对象
class Raindrop {
constructor(x, y, speed, size) {
this.x = x
this.y = y
this.speed = speed
this.size = size
}
update() {
// 雨滴下落
this.y += this.speed
// 如果雨滴超出屏幕,则重新从顶部开始下落
if (this.y > height) {
this.y = -this.size
this.x = Math.random() * width
}
}
draw() {
// 绘制雨滴
ctx.beginPath()
ctx.moveTo(this.x, this.y)
ctx.lineTo(this.x, this.y + this.size)
ctx.strokeStyle = '#F5F5F5'
ctx.lineWidth = 1.5
ctx.globalAlpha = 0.5
ctx.stroke()
}
}
// 定义雨滴数组和数量
const raindrops = []
const NUM_RAINDROPS = 500
// 初始化雨滴数组
for (let i = 0; i < NUM_RAINDROPS; i++) {
const x = Math.random() * width
const y = Math.random() * height
const speed = 10 + Math.random() * 10
const size = 5 + Math.random() * 10
const raindrop = new Raindrop(x, y, speed, size)
raindrops.push(raindrop)
}
const cloudImage = new Image();
cloudImage.src = './img/cloud.png';
// 云朵数量 颜色
class Cloud {
constructor(image, x, y, speed, size) {
this.x = x
this.y = y
this.image = image
this.speed = speed
this.size = size
}
update() {
this.x += this.speed
if(this.x > width + this.image.width / 2) {
this.x = -this.image.width / 2
this.size = 1 + Math.random() * 0.4
}
}
draw() {
// 绘制云朵
const cloudW = this.image.width * this.size
const cloudH = this.image.height * this.size
ctx.drawImage(this.image, this.x - cloudW / 2, this.y - cloudH / 2, cloudW, cloudH);
}
}
const clouds = []
const NUM_CLOUDS = 15;
for (let i = 0; i < NUM_CLOUDS; i++) {
const x = Math.random() * width
const y = 10 + Math.random() * 50
const speed = Math.random() * 1.2
const size = Math.random()
const cloud = new Cloud(cloudImage, x, y, speed, size)
clouds.push(cloud)
}
// 绘制雨滴动画
function drawRaindrops() {
// 清除 canvas
ctx.clearRect(0, 0, width, height)
// 更新和绘制每个雨滴
raindrops.forEach(raindrop => {
raindrop.update()
raindrop.draw()
})
clouds.forEach((_, i) => {
clouds[i].draw(ctx);
clouds[i].update();
})
// 循环调用自身,实现动画效果
requestAnimationFrame(drawRaindrops)
}
// 开始绘制雨滴动画
drawRaindrops()
// cloudImage.onload = function() {
// drawRaindrops();
// };
}
rainWeather()