彩虹,简称虹,是气象中的一种光学现象,当太阳光照射到半空中的水滴,光线被折射及反射,在天空上形成拱形的七彩光谱,由外圈至内圈呈红、橙、黄、绿、蓝、靛、紫七种颜色。事实上彩虹有无数种颜色,比如,在红色和橙色之间还有许多种细微差别的颜色,但为了简便起见,所以只用七种颜色作为区别。
使用JavaScript来操作Canvas,绘制彩虹和云朵。运行效果:

源码如下:
- html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>彩虹title>
- <style>
- body {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100vh;
- margin: 0;
- background-color: #F0FFFF; /* 青白色背景 */
- }
- canvas {
- border: 2px solid #000;
- background-color: #87CEEB; /* 天蓝色 */
- }
- style>
- head>
- <body>
- <canvas id="rainbowCanvas" width="400" height="300">canvas>
-
- <script>
- const canvas = document.getElementById('rainbowCanvas');
- const ctx = canvas.getContext('2d');
-
- function drawRainbow() {
- const centerX = canvas.width / 2;
- const centerY = canvas.height;
- const radius = canvas.height * 0.8;
-
- // 彩虹颜色
- const colors = [
- '#FF0000', // 红
- '#FF7F00', // 橙
- '#FFFF00', // 黄
- '#00FF00', // 绿
- '#0000FF', // 蓝
- '#4B0082', // 靛
- '#9400D3' // 紫
- ];
-
- // 绘制彩虹
- for (let i = colors.length - 1; i >= 0; i--) {
- ctx.beginPath();
- ctx.arc(centerX, centerY, radius - i * 20, Math.PI, 0, false);
- ctx.strokeStyle = colors[i];
- ctx.lineWidth = 20;
- ctx.stroke();
- }
-
- // 绘制云朵
- function drawCloud(x, y, size) {
- ctx.beginPath();
- ctx.arc(x, y, size, 0, Math.PI * 2);
- ctx.arc(x + size, y - size / 2, size * 0.8, 0, Math.PI * 2);
- ctx.arc(x + size * 2, y, size, 0, Math.PI * 2);
- ctx.fillStyle = 'white';
- ctx.fill();
- }
-
- drawCloud(50, 50, 30);
- drawCloud(canvas.width - 100, 80, 25);
- }
-
- drawRainbow();
- script>
- body>
- html>
-
下免改进云彩代码,让云彩从左向右不停地移动。源码如下:
- html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>彩虹与移动的云朵title>
- <style>
- body {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100vh;
- margin: 0;
- background-color: #F0FFFF; /* 青白色背景 */
- }
- canvas {
- border: 2px solid #000;
- background-color: #87CEEB; /* 天蓝色 */
- }
- style>
- head>
- <body>
- <canvas id="rainbowCanvas" width="400" height="300">canvas>
-
- <script>
- // 获取canvas元素和2D绘图上下文
- const canvas = document.getElementById('rainbowCanvas');
- const ctx = canvas.getContext('2d');
-
- // 定义云朵对象数组,每个云朵包含位置、大小和速度信息
- const clouds = [
- { x: 50, y: 50, size: 30, speed: 0.5 },
- { x: canvas.width - 100, y: 80, size: 25, speed: 0.3 }
- ];
-
- // 绘制彩虹的函数
- function drawRainbow() {
- const centerX = canvas.width / 2;
- const centerY = canvas.height;
- const radius = canvas.height * 0.8;
-
- // 定义彩虹的颜色数组
- const colors = [
- '#FF0000', // 红
- '#FF7F00', // 橙
- '#FFFF00', // 黄
- '#00FF00', // 绿
- '#0000FF', // 蓝
- '#4B0082', // 靛
- '#9400D3' // 紫
- ];
-
- // 从外到内绘制彩虹的每一道颜色
- for (let i = colors.length - 1; i >= 0; i--) {
- ctx.beginPath();
- ctx.arc(centerX, centerY, radius - i * 20, Math.PI, 0, false);
- ctx.strokeStyle = colors[i];
- ctx.lineWidth = 20;
- ctx.stroke();
- }
- }
-
- // 绘制单个云朵的函数
- function drawCloud(x, y, size) {
- ctx.beginPath();
- // 绘制三个部分组成的云朵形状
- ctx.arc(x, y, size, 0, Math.PI * 2);
- ctx.arc(x + size, y - size / 2, size * 0.8, 0, Math.PI * 2);
- ctx.arc(x + size * 2, y, size, 0, Math.PI * 2);
- ctx.fillStyle = 'white';
- ctx.fill();
- }
-
- // 更新云朵位置的函数
- function updateClouds() {
- clouds.forEach(cloud => {
- // 移动云朵
- cloud.x += cloud.speed;
- // 如果云朵完全移出画布右侧,将其移回左侧
- if (cloud.x > canvas.width + cloud.size * 2) {
- cloud.x = -cloud.size * 2;
- }
- });
- }
-
- // 主绘制函数,用于动画循环
- function draw() {
- // 清除整个画布
- ctx.clearRect(0, 0, canvas.width, canvas.height);
- // 绘制彩虹
- drawRainbow();
- // 绘制所有云朵
- clouds.forEach(cloud => drawCloud(cloud.x, cloud.y, cloud.size));
- // 更新云朵位置
- updateClouds();
- // 请求下一帧动画
- requestAnimationFrame(draw);
- }
-
- // 开始动画循环
- draw();
- script>
- body>
- html>
其中,requestAnimationFrame 是一个现代浏览器提供的用于优化动画性能的 JavaScript 方法,来创建平滑的动画。它允许您告诉浏览器您希望执行一个动画,并请求浏览器在下一次重绘之前调用指定的函数来更新动画。这个方法的主要目的是为了创建更加流畅和高效的动画。使用方法:
function animate() {
// 更新动画状态
// ...
// 请求下一帧
requestAnimationFrame(animate);
}
// 开始动画循环
animate();