HTML飞舞的花瓣代码(文末福利)

写在前面

明天就是妇女节啦,小编给大家准备了一个非常有趣的代码,无需安装软件,直接下载即可打开~(ps:文末有福利哦)

picture.image

完整代码


                          
<!DOCTYPE HTML>
                          
<HTML>
                          
<TITLE>飘落的花瓣</TITLE>
                          
<META NAME="Generator" CONTENT="EditPlus">
                          
<META NAME="Author" CONTENT="">
                          
<META NAME="Keywords" CONTENT="">
                          
<META NAME="Description" CONTENT="">
                          
<style>
                          
    html,
                          
    body {
                          
        width: 100%;
                          
        height: 100%;
                          
        margin: 0;
                          
        padding: 0;
                          
        overflow: hidden;
                          
    }
                          
    .container {
                          
        width: 100%;
                          
        height: 100%;
                          
        margin: 0;
                          
        padding: 0;
                          
        background-color: #000000;
                          
    }
                          
</style>
                          
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
                          
</HEAD>
                          
<BODY>
                          
    <div id="jsi-cherry-container" class="container"></div>
                          
    <script>
                          
        var RENDERER = {
                          
            INIT_CHERRY_BLOSSOM_COUNT: 30,
                          
            MAX_ADDING_INTERVAL: 10,
                          
            init: function () {
                          
                this.setParameters();
                          
                this.reconstructMethods();
                          
                this.createCherries();
                          
                this.render();
                          
            },
                          
            setParameters: function () {
                          
                this.$container = $('#jsi-cherry-container');
                          
                this.width = this.$container.width();
                          
                this.height = this.$container.height();
                          
                this.context = $('<canvas />').attr({ width: this.width, height: this.height }).appendTo(this.$container).get(0).getContext('2d');
                          
                this.cherries = [];
                          
                this.maxAddingInterval = Math.round(this.MAX_ADDING_INTERVAL * 1000 / this.width);
                          
                this.addingInterval = this.maxAddingInterval;
                          
            },
                          
            reconstructMethods: function () {
                          
                this.render = this.render.bind(this);
                          
            },
                          
            createCherries: function () {
                          
                for (var i = 0, length = Math.round(this.INIT_CHERRY_BLOSSOM_COUNT * this.width / 1000); i < length; i++) {
                          
                    this.cherries.push(new CHERRY_BLOSSOM(this, true));
                          
                }
                          
            },
                          
            render: function () {
                          
                requestAnimationFrame(this.render);
                          
                this.context.clearRect(0, 0, this.width, this.height);
                          
                this.cherries.sort(function (cherry1, cherry2) {
                          
                    return cherry1.z - cherry2.z;
                          
                });
                          
                for (var i = this.cherries.length - 1; i >= 0; i--) {
                          
                    if (!this.cherries[i].render(this.context)) {
                          
                        this.cherries.splice(i, 1);
                          
                    }
                          
                }
                          
                if (--this.addingInterval == 0) {
                          
                    this.addingInterval = this.maxAddingInterval;
                          
                    this.cherries.push(new CHERRY_BLOSSOM(this, false));
                          
                }
                          
            }
                          
        };
                          
        var CHERRY_BLOSSOM = function (renderer, isRandom) {
                          
            this.renderer = renderer;
                          
            this.init(isRandom);
                          
        };
                          
        CHERRY_BLOSSOM.prototype = {
                          
            FOCUS_POSITION: 300,
                          
            FAR_LIMIT: 600,
                          
            MAX_RIPPLE_COUNT: 100,
                          
            RIPPLE_RADIUS: 100,
                          
            SURFACE_RATE: 0.5,
                          
            SINK_OFFSET: 20,
                          
            init: function (isRandom) {
                          
                this.x = this.getRandomValue(-this.renderer.width, this.renderer.width);
                          
                this.y = isRandom ? this.getRandomValue(0, this.renderer.height) : this.renderer.height * 1.5;
                          
                this.z = this.getRandomValue(0, this.FAR_LIMIT);
                          
                this.vx = this.getRandomValue(-2, 2);
                          
                this.vy = -2;
                          
                this.theta = this.getRandomValue(0, Math.PI * 2);
                          
                this.phi = this.getRandomValue(0, Math.PI * 2);
                          
                this.psi = 0;
                          
                this.dpsi = this.getRandomValue(Math.PI / 600, Math.PI / 300);
                          
                this.opacity = 0;
                          
                this.endTheta = false;
                          
                this.endPhi = false;
                          
                this.rippleCount = 0;
                          
                var axis = this.getAxis(),
                          
                    theta = this.theta + Math.ceil(-(this.y + this.renderer.height * this.SURFACE_RATE) / this.vy) * Math.PI / 500;
                          
                theta %= Math.PI * 2;
                          
                this.offsetY = 40 * ((theta <= Math.PI / 2 || theta >= Math.PI * 3 / 2) ? -1 : 1);
                          
                this.thresholdY = this.renderer.height / 2 + this.renderer.height * this.SURFACE_RATE * axis.rate;
                          
                this.entityColor = this.renderer.context.createRadialGradient(0, 40, 0, 0, 40, 80);
                          
                this.entityColor.addColorStop(0, 'hsl(330, 70%, ' + 50 * (0.3 + axis.rate) + '%)');
                          
                this.entityColor.addColorStop(0.05, 'hsl(330, 40%,' + 55 * (0.3 + axis.rate) + '%)');
                          
                this.entityColor.addColorStop(1, 'hsl(330, 20%, ' + 70 * (0.3 + axis.rate) + '%)');
                          
                this.shadowColor = this.renderer.context.createRadialGradient(0, 40, 0, 0, 40, 80);
                          
                this.shadowColor.addColorStop(0, 'hsl(330, 40%, ' + 30 * (0.3 + axis.rate) + '%)');
                          
                this.shadowColor.addColorStop(0.05, 'hsl(330, 40%,' + 30 * (0.3 + axis.rate) + '%)');
                          
                this.shadowColor.addColorStop(1, 'hsl(330, 20%, ' + 40 * (0.3 + axis.rate) + '%)');
                          
            },
                          
            getRandomValue: function (min, max) {
                          
                return min + (max - min) * Math.random();
                          
            },
                          
            getAxis: function () {
                          
                var rate = this.FOCUS_POSITION / (this.z + this.FOCUS_POSITION),
                          
                    x = this.renderer.width / 2 + this.x * rate,
                          
                    y = this.renderer.height / 2 - this.y * rate;
                          
                return { rate: rate, x: x, y: y };
                          
            },
                          
            renderCherry: function (context, axis) {
                          
                context.beginPath();
                          
                context.moveTo(0, 40);
                          
                context.bezierCurveTo(-60, 20, -10, -60, 0, -20);
                          
                context.bezierCurveTo(10, -60, 60, 20, 0, 40);
                          
                context.fill();
                          
                for (var i = -4; i < 4; i++) {
                          
                    context.beginPath();
                          
                    context.moveTo(0, 40);
                          
                    context.quadraticCurveTo(i * 12, 10, i * 4, -24 + Math.abs(i) * 2);
                          
                    context.stroke();
                          
                }
                          
            },
                          
            render: function (context) {
                          
                var axis = this.getAxis();
                          
                if (axis.y == this.thresholdY && this.rippleCount < this.MAX_RIPPLE_COUNT) {
                          
                    context.save();
                          
                    context.lineWidth = 2;
                          
                    context.strokeStyle = 'hsla(0, 0%, 100%, ' + (this.MAX_RIPPLE_COUNT - this.rippleCount) / this.MAX_RIPPLE_COUNT + ')';
                          
                    context.translate(axis.x + this.offsetY * axis.rate * (this.theta <= Math.PI ? -1 : 1), axis.y);
                          
                    context.scale(1, 0.3);
                          
                    context.beginPath();
                          
                    context.arc(0, 0, this.rippleCount / this.MAX_RIPPLE_COUNT * this.RIPPLE_RADIUS * axis.rate, 0, Math.PI * 2, false);
                          
                    context.stroke();
                          
                    context.restore();
                          
                    this.rippleCount++;
                          
                }
                          
                if (axis.y < this.thresholdY || (!this.endTheta || !this.endPhi)) {
                          
                    if (this.y <= 0) {
                          
                        this.opacity = Math.min(this.opacity + 0.01, 1);
                          
                    }
                          
                    context.save();
                          
                    context.globalAlpha = this.opacity;
                          
                    context.fillStyle = this.shadowColor;
                          
                    context.strokeStyle = 'hsl(330, 30%,' + 40 * (0.3 + axis.rate) + '%)';
                          
                    context.translate(axis.x, Math.max(axis.y, this.thresholdY + this.thresholdY - axis.y));
                          
                    context.rotate(Math.PI - this.theta);
                          
                    context.scale(axis.rate * -Math.sin(this.phi), axis.rate);
                          
                    context.translate(0, this.offsetY);
                          
                    this.renderCherry(context, axis);
                          
                    context.restore();
                          
                }
                          
                context.save();
                          
                context.fillStyle = this.entityColor;
                          
                context.strokeStyle = 'hsl(330, 40%,' + 70 * (0.3 + axis.rate) + '%)';
                          
                context.translate(axis.x, axis.y + Math.abs(this.SINK_OFFSET * Math.sin(this.psi) * axis.rate));
                          
                context.rotate(this.theta);
                          
                context.scale(axis.rate * Math.sin(this.phi), axis.rate);
                          
                context.translate(0, this.offsetY);
                          
                this.renderCherry(context, axis);
                          
                context.restore();
                          
                if (this.y <= -this.renderer.height / 4) {
                          
                    if (!this.endTheta) {
                          
                        for (var theta = Math.PI / 2, end = Math.PI * 3 / 2; theta <= end; theta += Math.PI) {
                          
                            if (this.theta < theta && this.theta + Math.PI / 200 > theta) {
                          
                                this.theta = theta;
                          
                                this.endTheta = true;
                          
                                break;
                          
                            }
                          
                        }
                          
                    }
                          
                    if (!this.endPhi) {
                          
                        for (var phi = Math.PI / 8, end = Math.PI * 7 / 8; phi <= end; phi += Math.PI * 3 / 4) {
                          
                            if (this.phi < phi && this.phi + Math.PI / 200 > phi) {
                          
                                this.phi = Math.PI / 8;
                          
                                this.endPhi = true;
                          
                                break;
                          
                            }
                          
                        }
                          
                    }
                          
                }
                          
                if (!this.endTheta) {
                          
                    if (axis.y == this.thresholdY) {
                          
                        this.theta += Math.PI / 200 * ((this.theta < Math.PI / 2 || (this.theta >= Math.PI && this.theta < Math.PI * 3 / 2)) ? 1 : -1);
                          
                    } else {
                          
                        this.theta += Math.PI / 500;
                          
                    }
                          
                    this.theta %= Math.PI * 2;
                          
                }
                          
                if (this.endPhi) {
                          
                    if (this.rippleCount == this.MAX_RIPPLE_COUNT) {
                          
                        this.psi += this.dpsi;
                          
                        this.psi %= Math.PI * 2;
                          
                    }
                          
                } else {
                          
                    this.phi += Math.PI / ((axis.y == this.thresholdY) ? 200 : 500);
                          
                    this.phi %= Math.PI;
                          
                }
                          
                if (this.y <= -this.renderer.height * this.SURFACE_RATE) {
                          
                    this.x += 2;
                          
                    this.y = -this.renderer.height * this.SURFACE_RATE;
                          
                } else {
                          
                    this.x += this.vx;
                          
                    this.y += this.vy;
                          
                }
                          
                return this.z > -this.FOCUS_POSITION && this.z < this.FAR_LIMIT && this.x < this.renderer.width * 1.5;
                          
            }
                          
        };
                          
        $(function () {
                          
            RENDERER.init();
                          
        });
                          
    </script>
                          
</BODY>
                          
</HTML>
                      

picture.image

代码分析

这段代码是一个HTML页面,其中包含一个canvas元素和相关的JavaScript代码。这个页面创建了一个飘落花瓣的动画效果。具体分析如下:

  1. 首先定义了HTML结构,<div id="jsi-cherry-container"></div> 是一个用于承载花瓣动画的容器。

  2. CSS样式部分设置了整个页面和容器的宽高为100%,且隐藏了滚动条。

  3. JavaScript部分首先引入了jQuery库(虽然在这个示例中没有直接使用)。

  4. RENDERER对象是动画的核心逻辑,它包含了初始化、设置参数、重构方法、创建花瓣以及渲染循环等方法。在init方法中,通过setParameters设定画布大小、获取容器元素、创建2D渲染上下文并初始化花瓣数组。createCherries方法用于生成初始数量的花瓣对象。render方法是动画渲染循环,每一帧会清除画布内容,重新排序花瓣,然后逐一渲染每个花瓣,并按照一定间隔添加新的花瓣。

  5. CHERRY_BLOSSOM类代表单个花瓣,其构造函数接受一个RENDERER对象作为参数,并初始化花瓣的各种属性,包括位置、速度、颜色渐变等。该类中的init方法用于随机或指定方式初始化花瓣状态,render方法则负责绘制花瓣及涟漪效果。

  6. 整个动画模拟了花瓣从画面顶部飘落并在接触到水面时产生涟漪的效果,通过不断更新花瓣的位置和角度,在canvas上绘制出动态变化的花瓣图像。

picture.image

下载代码

公众号的对话框内回复“ html014

无需提取码即可飞速下载

picture.image

系列推荐

Python李峋同款跳动的爱心代码

我用python实现了一只喜羊羊!

一起来看python流星雨吧!

啥?我的世界居然开源了……

HTML龙年大吉烟花代码

HTML超好看的蓝色爱心

无限弹窗!满屏表白代码来啦

C++《黑客帝国》同款炫酷代码雨

C语言满屏飘字表白代码

……更多精彩见主页

picture.image

节日福利

点赞、爱心、评论 以下视频即可参与抽奖

小编将在后台抽取幸运观众 免费 赠送下面随机图书哦( 包邮

截止日期:2024年3月15日

注:获奖用户请在24小时内联系小编哦~

picture.image

写在最后

我是一只有趣的兔子,感谢你的喜欢!

picture.image

0
0
0
0
评论
未登录
暂无评论