Sun-weather
因为可视化大屏的业务需求,需要绘制全屏的天气效果。共用canvas绘制了晴天、雨天、台风天三种天气。在此记录供参考。
- html代码
<canvas id="weather"></canvas>
- JavaScript代码
function sunWeather() {
// 获取画布和上下文
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
// 创建图像对象
const img = new Image();
img.src = './img/sunshine.png';
img.width = 2800;
img.height = 2800;
// 定义旋转角度和旋转中心
let angle = 0;
const cx = width;
const cy = img.height / 2;
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 loop() {
// 清除画布
ctx.clearRect(0, 0, width, height);
// 绘制图像
ctx.save();
ctx.translate(cx, 0);
ctx.rotate(angle * Math.PI / 1800);
ctx.drawImage(img, -img.width / 2, -img.height / 2, img.width, img.height);
ctx.restore();
clouds.forEach((_, i) => {
clouds[i].draw(ctx);
clouds[i].update();
})
// 更新旋转角度
angle += 0.5;
// 循环动画
requestAnimationFrame(loop);
}
// 加载图像后启动动画
img.onload = function() {
loop();
};
}
sunWeather();