typhoon-weather
因为可视化大屏的业务需求,需要绘制全屏的天气效果。共用canvas绘制了晴天、雨天、台风天三种天气。在此记录供参考。
- html代码
<canvas id="weather"></canvas>
- JavaScript代码
function typhoonWeather() {
const canvas = document.getElementById('weather');
const ctx = canvas.getContext('2d');
// 设置 Canvas 大小
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const width = canvas.width
const height = canvas.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 img = new Image()
img.src = './img/typhoon.png'
img.width = 1000
img.height = 1000
// 图片加载完成后绘制
img.onload = function() {
// 设置 canvas 中心点
const centerX = width / 2;
const centerY = height / 2;
// 定义旋转角度和每帧旋转的角度增量
let angle = 0;
const angleDelta = Math.PI / 1440;
// 开始动画循环
function animate() {
// 清空画布
ctx.clearRect(0, 0, width, height);
raindrops.forEach(raindrop => {
raindrop.update()
raindrop.draw()
})
// 将坐标系移动到 canvas 中心点
ctx.translate(centerX, centerY);
// 旋转图片
ctx.rotate(-angle);
ctx.drawImage(img, -img.width / 2, -img.height / 2, img.width, img.height);
// 恢复坐标系
ctx.rotate(angle);
ctx.translate(-centerX, -centerY);
// 更新旋转角度
angle += angleDelta;
// 循环动画
requestAnimationFrame(animate);
}
// 开始动画
animate();
}
}
typhoonWeather();