给网页添加五角星的动画效果

这段代码的作用是在网页上创建一个画布,并在画布上绘制五角星的动画效果。具体实现如下:

创建画布

首先,代码创建了一个新的canvas元素,并将其添加到文档的body中。同时,通过getContext方法获取画布的2D渲染上下文,并将其赋值给变量ctx,以便在之后的代码中使用。代码如下:

const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");

设置画布属性

接下来,代码设置了canvas的宽高和位置,并将其设置为不响应鼠标事件,以便在画布上绘制动画时不会影响用户的交互。代码如下:

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.position = "fixed";
canvas.style.top = "0";
canvas.style.left = "0";
canvas.style.zIndex = "1";
canvas.style.pointerEvents = "none";

代码的作用是在浏览器窗口中生成一个画布,并在画布上生成随机大小、颜色和位置的五角星粒子,使其以随机速度下落并逐渐消失,从而呈现出类似雪花飘落的效果。

具体来说,代码的执行过程如下:

  1. 创建一个 <canvas> 元素,并将其添加到当前页面的 <body> 元素中。

  2. 获取 <canvas> 的上下文对象 ctx,并设置其属性以使其充满整个窗口,并且鼠标不会与其交互。

  3. 创建一个

    class Particle
    

    Particle 类,表示五角星粒子。该类包含以下属性:

    • xy 表示五角星粒子的坐标位置。
    • size 表示五角星粒子的大小。
    • speed 包含 xy 两个分量,表示五角星粒子的下落速度(在 x 轴和 y 轴方向上的速度)。
    • color 表示五角星粒子的颜色。 该类还包含以下方法:
    • update 方法用于更新五角星粒子的位置和大小,当五角星粒子下落到画布底部时,重新设置其位置和大小。
    • draw 方法用于将五角星粒子绘制到画布上。
  4. 定义一个函数 generateParticles,用于生成指定数量的五角星粒子,并将其加入到一个数组 particles 中。

  5. 定义一个函数 loop,用于循环更新和绘制所有五角星粒子,并使用 requestAnimationFrame 函数实现动画效果。

  6. 定义一个函数 startAnimation,用于生成五角星粒子并启动动画循环。

  7. 定义一个函数 resizeCanvas,用于在窗口大小改变时重新设置 <canvas> 的大小。

  8. 调用 resizeCanvasstartAnimation 函数,启动五角星粒子下落动画。同时,当窗口大小改变时,调用 resizeCanvas 函数重新设置 <canvas> 的大小。

以上是代码的大致作用和执行过程。下面是对代码的解释和说明:

  • canvas 是一个 HTML5 元素,可以用于在网页上绘制图形。通过设置 canvas.widthcanvas.height 属性,可以指定画布的宽度和高度。
  • getContext("2d") 方法可以获取 <canvas> 的上下文对象,用于绘制图形。
  • 通过设置 canvas.style 属性,可以将画布固定在页面上,并使其在 z 轴方向上置于最上层。
  • Math.random() 函数可以生成一个 0 到 1 之间的随机数。
  • requestAnimationFrame() 方法用于在下一次浏览器重绘之前,通知浏览器执行指定的回调函数来更新动画,这样可以确保回调函数在浏览器的优化时间间隔内调用,从而实现更加流畅的动画效果。

五角星下落动画

此代码创建了一个用 HTML5 Canvas 实现的五角星下落动画。当打开此 HTML 页面时,它将自动开始播放动画。

代码解释

创建画布

代码首先使用 document.createElement() 创建一个新的 canvas 元素,并将其添加到文档的 body 中。

const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");

它还获取了画布的上下文对象并存储在变量 ctx 中,这是用于在画布上绘制元素的必要对象。

接下来,代码为画布设置了位置和大小,并禁用了鼠标事件。

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.position = "fixed";
canvas.style.top = "0";
canvas.style.left = "0";
canvas.style.zIndex = "1";
canvas.style.pointerEvents = "none";

粒子的类定义

在定义了画布后,代码定义了一个叫 Particle 的类来表示下落的五角星。每个五角星都有一个 x 和 y 坐标、大小、速度和颜色。在此代码中,五角星的速度在 speedMax 范围内随机生成。颜色是随机的。

class Particle {
    constructor(x, y, size) {
        this.x = x;
        this.y = y;
        this.size = size;
        this.speed = {
            x: Dx + Math.random() * speedMax,
            y: Dy + Math.random() * speedMax
        };
        this.color = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`;
    }

    update() {
        this.x += this.speed.x;
        this.y += this.speed.y;
        if (this.size > 0.2) this.size -= fadeSpeedMax;
        if (this.y > window.innerHeight) {
            this.y = 0;
            this.x = Math.random() * window.innerWidth;
            this.size = Math.random() * particleMaxSize;
        }
    }

    draw() {
        // 绘制五角星
    }
}

生成五角星

接下来,代码定义了一个 generateParticles 函数来随机生成五角星,用 Particle 类的实例表示。particleCount 定义了需要创建的五角星数量,particleMaxSize 定义了五角星的最大大小。使用 Math.random() 方法随机生成五角星的大小和位置。

const particles = [];
const particleCount = 300; // 五角星数量
const particleMaxSize = 20; // 最大五角星大小

function generateParticles() {
    for (let i = 0; i < particleCount; i++) {
        const x = Math.random() * window.innerWidth;
        const y = Math.random() * window.innerHeight;
        const size = Math.random() * particleMaxSize;
        const particle = new Particle(x, y, size);
        particles.push(particle);
    }
}

绘制和更新五角星

最后,代码定义了一个循环函数 loop在画布上清除现有五角星,更新每个五角星的位置和大小,然后在画布上绘制。

function loop() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    particles.forEach(particle => {
        particle.update();
        particle.draw();
    });
    requestAnimationFrame(loop);
}

resizeCanvas()函数中,每当浏览器窗口大小发生变化时,重新设置画布的宽和高,以适应新的窗口大小。

function resizeCanvas() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
}

startAnimation()函数中,首先调用generateParticles()函数,生成了particleCount个随机位置和随机大小的五角星,并将它们存储在particles数组中。然后调用loop()函数,开始动画循环。在loop()函数中,首先调用ctx.clearRect()函数清空画布,然后循环遍历particles数组中的每个五角星,分别调用其update()draw()方法,更新其位置和绘制。最后使用requestAnimationFrame()函数,在下一次浏览器绘制之前,再次调用loop()函数,实现动画效果。

function startAnimation() {
    generateParticles();
    loop();
}

总结:

这段代码实现了一个随机下落的五角星动画效果。它首先创建了一个画布,并将其设置为全屏,并且禁用了鼠标事件。然后,定义了一个Particle类来表示五角星对象,并在类中实现了绘制和更新五角星的方法。接下来,通过generateParticles()函数生成了一定数量的随机五角星对象,并将它们存储在particles数组中。最后,通过loop()函数来实现动画循环,循环遍历particles数组中的五角星对象,更新其位置并将其绘制到画布上,最终实现了一个五角星随机下落的动画效果。同时,在浏览器窗口大小发生变化时,画布会自适应调整大小。

完整代码实现:

// ---------------------------------绘制动画开始---------------------------------

// 创建画布
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");

// 设置画布的宽高和位置,鼠标不响应
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.position = "fixed";
canvas.style.top = "0";
canvas.style.left = "0";
canvas.style.zIndex = "1";
canvas.style.pointerEvents = "none";


const particles = [];
const particleCount = 300;//五角星数量
const particleMaxSize = 20;//最大五角星大小
const speedMax = 0.05;//五角星下落速度
const fadeSpeedMax = 0.05;//五角星消失速度
const Dx = 0;//下落x轴速度(正负号代表方向)
const Dy = 1;//下落y轴速度(正负号代表方向)

class Particle {
    constructor(x, y, size) {
        this.x = x;
        this.y = y;
        this.size = size;
        this.speed = {
            x: Dx + Math.random() * speedMax,
            y: Dy + Math.random() * speedMax
        };
        this.color = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`;
    }

    update() {
        this.x += this.speed.x;
        this.y += this.speed.y;
        if (this.size > 0.2) this.size -= fadeSpeedMax;
        if (this.y > window.innerHeight) {
            this.y = 0;
            this.x = Math.random() * window.innerWidth;
            this.size = Math.random() * particleMaxSize;
        }
    }

    draw() {
        const x = this.x;
        const y = this.y;
        const size = this.size;
        const color = this.color;

        ctx.beginPath();
        for (var i = 0; i < 5; i++) {
            ctx.lineTo(Math.cos((18 + i * 72) / 180 * Math.PI) * size + x,
                -Math.sin((18 + i * 72) / 180 * Math.PI) * size + y);
            ctx.lineTo(Math.cos((54 + i * 72) / 180 * Math.PI) * size / 2 + x,
                -Math.sin((54 + i * 72) / 180 * Math.PI) * size / 2 + y);
        }
        ctx.closePath();
        ctx.fillStyle = color;
        ctx.fill();
    }
}

function generateParticles() {
    for (let i = 0; i < particleCount; i++) {
        const x = Math.random() * window.innerWidth;
        const y = Math.random() * window.innerHeight;
        const size = Math.random() * particleMaxSize;
        const particle = new Particle(x, y, size);
        particles.push(particle);
    }
}

function loop() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    particles.forEach(particle => {
        particle.update();
        particle.draw();
    });
    requestAnimationFrame(loop);
}

function startAnimation() {
    generateParticles();
    loop();
}

function resizeCanvas() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
}

resizeCanvas();
startAnimation();
window.addEventListener('resize', resizeCanvas);

// ---------------------------------绘制动画结束---------------------------------