用HTML+CSS+JS实现一个简单的弹幕滚动留言板

news2024/9/25 17:13:09

在线演示地址:https://www.ewbang.com/community/board.html

本文利用HTML+CSS+JS写了一个简单的弹幕滚动留言板小功能。

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <meta name="keywords" content="" />
    <meta name="description" content="" />
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        html,
        body {
            height: 100%;
            user-select: none;
        }

        .screen {
            overflow: hidden;
            position: relative;
            height: 100%;
            background-repeat: no-repeat;
            background-size: 100% 100%;
        }

        .send {
            position: absolute;
            bottom: 0;
            width: 100%;
            height: 80px;
            line-height: 80px;
            background-color: rgba(10, 10, 10, 0.6);
            text-align: center;
        }

        .input {
            position: absolute;
            left: 50%;
            top: 50%;
            margin: -20px -350px;
            font-size: 0;
        }

        .text {
            float: left;
            width: 600px;
            height: 40px;
            border: none;
            border-radius: 8px 0 0 8px;
        }

        .s_show div {
            position: absolute;
            font-size: 18px;
            font-weight: bold;
        }

        .btn {
            float: left;
            width: 100px;
            background-color: orange;
            line-height: 40px;
            font-size: 18px;
            color: #fff;
            cursor: pointer;
            border-radius: 0 8px 8px 0;
        }

        html,
        body {
            margin: 0;
            overflow: hidden;
            width: 100%;
            height: 100%;
            cursor: none;
            background: black;
            background: linear-gradient(to bottom, #000000 0%, #5788fe 100%);
        }

        .filter {
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
            background: #fe5757;
            animation: colorChange 30s ease-in-out infinite;
            animation-fill-mode: both;
            mix-blend-mode: overlay;
        }

        @keyframes colorChange {

            0%,
            100% {
                opacity: 0;
            }

            50% {
                opacity: 0.9;
            }
        }

        .landscape {
            position: absolute;
            bottom: 0px;
            left: 0;
            width: 100%;
            height: 100%;
            background-size: 1000px 250px;
            background-repeat: repeat-x;
            background-position: center bottom;
        }
    </style>
    <title>弹幕留言板</title>
</head>

<body>
    <div class="screen">
        <div class="landscape"></div>
        <div class="filter"></div>
        <canvas id="canvas"></canvas>
        <div class="send">
            <div class="input clearfix">
                <input type="text" class="text" />
                <div class="btn">发送弹幕</div>
            </div>
        </div>
        <div class="s_show">
            <div class="magictime twisterInUp">
                小狐狸789 :
                【跟你谈钱的老板才是好人,跟你谈理想的,都TM不想给你钱!】— 2022-12-28
                01:19:37
            </div>

            <div class="magictime twisterInUp">
                小猫999 : 【那些年立下的FLAG自己删了吧,反正也没人记得。】— 2022-11-08
                19:39:49
            </div>

            <div class="magictime twisterInUp">
                酷猫000 : 【失眠睡不着,可能是因为,你手机还有电。】— 2023-07-13
                00:37:00
            </div>

            <div class="magictime twisterInUp">
                聪明狮子520 : 【过年不吃胖,怎么对得起,死去的鸡鸭鱼猪?】— 2023-04-19
                18:28:43
            </div>

            <div class="magictime twisterInUp">
                酷狼789 :
                【今天真是幸运的一天,终于实现了身价翻倍,因为猪价又翻了番。】—
                2023-01-20 20:37:00
            </div>

            <div class="magictime twisterInUp">
                快乐狗123 : 【你爱不爱你的工作,工作都会在那等你,不离不弃。】—
                2023-01-31 23:03:35
            </div>

            <div class="magictime twisterInUp">
                梦幻兔子520 :
                【懒是一个很好的托辞,说的好像你勤奋了就能干成大事一样。】— 2023-05-11
                15:56:11
            </div>

            <div class="magictime twisterInUp">
                酷鸟789 : 【不要再抑郁下去了孩子,你要像一个,神经病一样活泼开朗。】—
                2023-04-12 13:59:07
            </div>

            <div class="magictime twisterInUp">
                勇敢熊000 : 【再努力一点,你就能走向,人生癫疯。】— 2023-05-15
                10:25:04
            </div>

            <div class="magictime twisterInUp">
                幸运老虎666 : 【一路上有你,苦一点也愿意,苦很多免谈。】— 2023-03-23
                14:18:44
            </div>

            <div class="magictime twisterInUp">
                聪明熊000 : 【怕鬼真的太幼稚了,我带你看看人心。】— 2023-07-02
                09:13:57
            </div>

            <div class="magictime twisterInUp">
                幸运狗1314 : 【大家喜欢和你一起,是为了,显示他们的好看。】—
                2023-07-18 13:50:43
            </div>

            <div class="magictime twisterInUp">
                酷狗000 : 【要不是生活所迫,谁愿意把自己,弄得一身才华。】— 2023-08-26
                07:21:47
            </div>

            <div class="magictime twisterInUp">
                聪明狮子123 : 【攒了一年头皮屑,只为给你下场雪。】— 2023-06-09
                17:35:14
            </div>

            <div class="magictime twisterInUp">
                疯狂老虎520 : 【大人只分利弊,小孩才分对错。】— 2023-09-27 18:16:39
            </div>

            <div class="magictime twisterInUp">
                聪明狐狸000 : 【每一个抖腿的人,心里都有一台缝纫机。】— 2022-12-04
                05:37:25
            </div>

            <div class="magictime twisterInUp">
                大猫999 :
                【小时候最怕梦到自己找厕所,最最可怕的是,人没醒来厕所却找到了。】—
                2023-04-15 06:42:35
            </div>

            <div class="magictime twisterInUp">
                幸运狗789 : 【我真是个败家子,上亿的家产,一觉醒来就没了。】—
                2023-01-15 12:01:47
            </div>

            <div class="magictime twisterInUp">
                聪明狐狸456 : 【女生之间的友谊啊,就像塑料花,虽然假但永不凋零。】—
                2023-08-29 02:51:44
            </div>

            <div class="magictime twisterInUp">
                酷熊888 :
                【当你觉得生活对你不公时,秤秤体重,照照镜子,你会觉得一切又合乎情理。】—
                2023-09-11 02:50:45
            </div>
        </div>
    </div>

    <script>
        function Star(id, x, y) {
            this.id = id;
            this.x = x;
            this.y = y;
            this.r = Math.floor(Math.random() * 2) + 1;
            var alpha = (Math.floor(Math.random() * 10) + 1) / 10 / 2;
            this.color = "rgba(255,255,255," + alpha + ")";
        }

        Star.prototype.draw = function () {
            ctx.fillStyle = this.color;
            ctx.shadowBlur = this.r * 2;
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
            ctx.closePath();
            ctx.fill();
        };

        Star.prototype.move = function () {
            this.y -= 0.15;
            if (this.y <= -10) this.y = HEIGHT + 10;
            this.draw();
        };

        Star.prototype.die = function () {
            stars[this.id] = null;
            delete stars[this.id];
        };

        function Dot(id, x, y, r) {
            this.id = id;
            this.x = x;
            this.y = y;
            this.r = Math.floor(Math.random() * 5) + 1;
            this.maxLinks = 2;
            this.speed = 0.5;
            this.a = 0.5;
            this.aReduction = 0.005;
            this.color = "rgba(255,255,255," + this.a + ")";
            this.linkColor = "rgba(255,255,255," + this.a / 4 + ")";

            this.dir = Math.floor(Math.random() * 140) + 200;
        }

        Dot.prototype.draw = function () {
            ctx.fillStyle = this.color;
            ctx.shadowBlur = this.r * 2;
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
            ctx.closePath();
            ctx.fill();
        };

        Dot.prototype.link = function () {
            if (this.id == 0) return;
            var previousDot1 = getPreviousDot(this.id, 1);
            var previousDot2 = getPreviousDot(this.id, 2);
            var previousDot3 = getPreviousDot(this.id, 3);
            if (!previousDot1) return;
            ctx.strokeStyle = this.linkColor;
            ctx.moveTo(previousDot1.x, previousDot1.y);
            ctx.beginPath();
            ctx.lineTo(this.x, this.y);
            if (previousDot2 != false) ctx.lineTo(previousDot2.x, previousDot2.y);
            if (previousDot3 != false) ctx.lineTo(previousDot3.x, previousDot3.y);
            ctx.stroke();
            ctx.closePath();
        };

        function getPreviousDot(id, stepback) {
            if (id == 0 || id - stepback < 0) return false;
            if (typeof dots[id - stepback] != "undefined")
                return dots[id - stepback];
            else return false;
        }

        Dot.prototype.move = function () {
            this.a -= this.aReduction;
            if (this.a <= 0) {
                this.die();
                return;
            }
            this.color = "rgba(255,255,255," + this.a + ")";
            this.linkColor = "rgba(255,255,255," + this.a / 4 + ")";
            (this.x = this.x + Math.cos(degToRad(this.dir)) * this.speed),
            (this.y = this.y + Math.sin(degToRad(this.dir)) * this.speed);

            this.draw();
            this.link();
        };

        Dot.prototype.die = function () {
            dots[this.id] = null;
            delete dots[this.id];
        };

        var canvas = document.getElementById("canvas"),
            ctx = canvas.getContext("2d"),
            WIDTH,
            HEIGHT,
            mouseMoving = false,
            mouseMoveChecker,
            mouseX,
            mouseY,
            stars = [],
            initStarsPopulation = 80,
            dots = [],
            dotsMinDist = 2,
            maxDistFromCursor = 50;

        setCanvasSize();
        init();

        function setCanvasSize() {
            (WIDTH = document.documentElement.clientWidth),
            (HEIGHT = document.documentElement.clientHeight);

            canvas.setAttribute("width", WIDTH);
            canvas.setAttribute("height", HEIGHT);
        }

        function init() {
            ctx.strokeStyle = "white";
            ctx.shadowColor = "white";
            for (var i = 0; i < initStarsPopulation; i++) {
                stars[i] = new Star(
                    i,
                    Math.floor(Math.random() * WIDTH),
                    Math.floor(Math.random() * HEIGHT)
                );
                //stars[i].draw();
            }
            ctx.shadowBlur = 0;
            animate();
        }

        function animate() {
            ctx.clearRect(0, 0, WIDTH, HEIGHT);

            for (var i in stars) {
                stars[i].move();
            }
            for (var i in dots) {
                dots[i].move();
            }
            drawIfMouseMoving();
            requestAnimationFrame(animate);
        }

        window.onmousemove = function (e) {
            mouseMoving = true;
            mouseX = e.clientX;
            mouseY = e.clientY;
            clearInterval(mouseMoveChecker);
            mouseMoveChecker = setTimeout(function () {
                mouseMoving = false;
            }, 100);
        };

        function drawIfMouseMoving() {
            if (!mouseMoving) return;

            if (dots.length == 0) {
                dots[0] = new Dot(0, mouseX, mouseY);
                dots[0].draw();
                return;
            }

            var previousDot = getPreviousDot(dots.length, 1);
            var prevX = previousDot.x;
            var prevY = previousDot.y;

            var diffX = Math.abs(prevX - mouseX);
            var diffY = Math.abs(prevY - mouseY);

            if (diffX < dotsMinDist || diffY < dotsMinDist) return;

            var xVariation = Math.random() > 0.5 ? -1 : 1;
            xVariation =
                xVariation * Math.floor(Math.random() * maxDistFromCursor) + 1;
            var yVariation = Math.random() > 0.5 ? -1 : 1;
            yVariation =
                yVariation * Math.floor(Math.random() * maxDistFromCursor) + 1;
            dots[dots.length] = new Dot(
                dots.length,
                mouseX + xVariation,
                mouseY + yVariation
            );
            dots[dots.length - 1].draw();
            dots[dots.length - 1].link();
        }

        function degToRad(deg) {
            return deg * (Math.PI / 180);
        }
    </script>

    <script>
        //初始化函数
        var aShowList = document.querySelectorAll(".s_show div"); //获取元素 H5
        var oShow = document.querySelector(".s_show");
        var oSend = document.querySelector(".send");
        var oBtn = document.querySelector(".btn");
        var oText = document.querySelector(".text");
        oBtn.onclick = function () {
            //鼠标点击事件
            var oDiv = document.createElement("div"); //创建div
            oDiv.innerHTML = oText.value; //添加弹幕内容
            oDiv.className = "magictime twisterInUp"; //弹幕特效
            oShow.appendChild(oDiv); //添加一个子节点
            init(oDiv); //初始化
            oText.value = "";
            time = time1;
        };

        for (var i = 0; i < aShowList.length; i++) {
            init(aShowList[i]); //执行初始化函数
        }

        function init(obj) {
            //接受弹幕对象
            //确定top值的随机区间
            var screenHeight = document.documentElement.clientHeight; //获取屏幕可视高度
            var maxTop = screenHeight - oSend.offsetHeight - obj.offsetHeight; //高度差范围
            obj.style.top = maxTop * Math.random() + "px";
            //控制left值
            var screenWidth = document.documentElement.clientWidth; //获取可视宽度
            var maxLeft = screenWidth - obj.offsetWidth; //随机宽度差
            obj.style.left = maxLeft + "px";
            //弹幕的随机颜色
            obj.style.color = randomColor();
            move(Math.random() * 5 + 1, obj, maxLeft);
        }
        //弹幕移动函数
        function move(k, obj, maxLeft) {
            var speed = k; //控制速度的变量
            maxLeft -= speed; //往左移动
            if (maxLeft > -obj.offsetWidth) {
                obj.style.left = maxLeft + "px";
                requestAnimationFrame(function () {
                    move(k, obj, maxLeft);
                }); //H5新增的动画函数
            } else {
                init(obj); //重新初始化 营造循环弹幕效果
            }
        }
        //随机颜色函数
        function randomColor() {
            return "#" + Math.random().toString(16).slice(-6); //一行简化版截取后六位
        }
    </script>
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1142931.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

shell实验

1&#xff0e;编写脚本for1.sh&#xff0c;使用for循环创建20账户&#xff0c;账户名前缀由用户从键盘输入&#xff0c;账户初始密码由用户输入&#xff0c;例如&#xff1a;test1、test2、test3、....、test10 编写脚本&#xff0c;使用read -p提醒用户从键盘输入账户名前缀以…

轻量封装WebGPU渲染系统示例<1>-彩色三角形(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/version-1.01/src/voxgpu/sample/VertColorTriangle.ts 此示例渲染系统实现的特性: 1. 用户态与系统态隔离。 2. 高频调用与低频调用隔离。 3. 面向用户的易用性封装。 4. 渲染数据和渲染机制分离。 …

FL Studio21最新中文版DAW数字音频工作站

大概从去年开始&#xff0c;“电子音乐制作技术”成为越来越常见的说法。一开始我们觉得这种说法太过于笼统&#xff0c;因为电子音乐制作的技术早已不限于用在电子音乐&#xff0c;它更像是现代音乐制作技术。毕竟现代化的90%的音乐都是这么做出来的。 对&#xff0c;我们说的…

如何使用 Rask AI 进行视频本地化

链接&#xff1a; Login or Sign up Rask AI 是一个提供视频本地化服务的平台&#xff0c;支持 60 多种语言。该服务的主要功能包括&#xff1a; VoiceClone&#xff1a;利用 AI 生成来自原始影片发言人的语音&#xff0c;让你可以将其用作全球范围内品牌形象的一部分。Mul…

如何做到在 5 分钟之内将应用大小减少 60% 的?

移动设备的资源总是有限的。有限的电量&#xff0c;有限的存储&#xff0c;有限的处理能力&#xff0c;有限的内存&#xff0c;有限的网络带宽……无论你面对的是 Android 还是 iOS&#xff0c;这都是真理。 在前几个月&#xff0c;我在开发一个安卓应用。当有人尝试用错误的密…

蓝桥杯 第 2 场算法双周赛 第3题 摆玩具【算法赛】 c++ 贪心

题目 摆玩具【算法赛】https://www.lanqiao.cn/problems/5888/learning/?contest_id145 问题描述 小蓝是一个热爱收集玩具的小伙子&#xff0c;他拥有 n 个不同的玩具。 这天&#xff0c;他把 n 个玩具按照高度顺序从矮到高摆放在了窗台上&#xff0c;然后&#xff0c;他希…

JetBrains ReSharper Ultimate 2023.2.2

JetBrains ReSharper Ultimate 国外知名软件公司JetBrains专为软件开发软件编程人员制作的各类应用工具箱&#xff0c;如&#xff1b;PHP集成开发工具PHPStorm&#xff0c;Java整合开发工具IntelliJ IDEA&#xff0c;Python集成开发工具PyCharm&#xff0c;HTML/CSS/JS开发工具…

conda虚拟环境笔记收录

1、安装conda 增加执行权限&#xff1a; chmod x Anaconda3-2023.03-1-Linux-x86_64.sh 开始执行&#xff1a;./Anaconda3-2023.03-1-Linux-x86_64.sh2、查看版本 conda --version3、查看当前虚拟环境 虚拟环境和全局环境有前缀可见 如果不进行设置&#xff0c;重新启动就变成…

hdlbits系列verilog解答(移位寄存器)-23

文章目录 一、问题描述二、verilog源码三、仿真结果 一、问题描述 您将获得一个具有两个输入和一个输出的模块 my_dff &#xff08;实现 D 触发器&#xff09;。实例化其中的三个&#xff0c;然后将它们链接在一起以形成长度为 3 的移位寄存器。端口 clk 需要连接到所有实例。…

uniapp 在 Android Studio 模拟器中运行项目

在开发App时&#xff0c;无论是使用 Flutter 还是 React native&#xff0c;还是使用uni-app 开发跨端App时&#xff0c;总是需要运行调试。一般调试分为两种。 第一&#xff1a;真机调试 第二&#xff1a;模拟器调试 真机调试的好处是可以看到更好的效果&#xff0c;缺点就是…

2023年中国冷风机分类、销量及市场规模分析[图]

冷风机通常是指一种设备&#xff0c;用于通过冷却空气来调节室内或工业环境的温度。这些设备通过循环空气并通过冷却元件&#xff08;如冷却盘或冷凝器&#xff09;来降低空气的温度&#xff0c;从而实现温度控制。冷风机在家庭、商业和工业领域都有广泛的应用&#xff0c;可以…

Linux Mint 21.2 “EDGE” ISO 发布

Linux Mint 团队近日宣布发布最新 Linux Mint 21.2 “Victoria “版本的 “EDGE “ISO 版本&#xff0c;并提供下载。 “这个镜像是为那些硬件太新而无法启动 Linux Mint 21.x 中包含的 5.15 LTS 内核的用户制作的。 Linux Mint 21.2 “Victoria “于2023年7月中旬发布&#x…

【开源】基于SpringBoot的城市桥梁道路管理系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询城市桥梁4.2 新增城市桥梁4.3 编辑城市桥梁4.4 删除城市桥梁4.5 查询单个城市桥梁 五、免责说明 一、摘要 1.1 项目介绍 基于VueSpringBootMySQL的城市桥梁道路管理系统&#xff0c;支持…

JAVA实现智能停车场管理系统 开源

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容A. 车主端功能B. 停车工作人员功能C. 系统管理员功能1. 停车位模块2. 车辆模块3. 停车记录模块4. IC卡模块5. IC卡挂失模块 三、界面展示3.1 登录注册3.2 车辆模块3.3 停车位模块3.4 停车数据模块3.5 IC卡档案模块3.6 IC卡挂…

了解RAID5和RAID6的区别,让数据存储更安全

RAID&#xff08;Redundant array of inexpensive disk&#xff09;通过给磁盘阵列增加冗余磁盘提高了磁盘阵列的可靠性。 所谓冗余磁盘&#xff0c;即该磁盘不用于存放实际数据&#xff0c;而用来存放一些冗余信息&#xff0c;而这些冗余信息可用来在必要的时候进行有效数据恢…

在docker中创建EMQX 加数据卷

1、从虚拟容器中复制出来文件 docker run --rm emqx/emqx:5.3.0 sh -c cd /opt/emqx && tar -c etc | tar -C $PWD -x 2、将这三个文件夹分别赋予最高权限&#xff0c;也可以777可以755 chmod -R 777 data chmod -R 777 etc chmod -R 777 log 3、创建容器代码 docke…

【鸿蒙软件开发】ArkTS基础组件之Select(下拉菜单)、Slider(滑动条)

文章目录 前言一、Select下拉菜单1.1 子组件1.2 接口参数 1.3 属性1.4 事件1.5 示例代码 二、Slider2.1 子组件2.2 接口参数&#xff1a;SliderStyle枚举说明 2.3 属性2.4 事件SliderChangeMode枚举说明 2.5 示例代码 总结 前言 Select组件&#xff1a;提供下拉选择菜单&#…

【Java基础】JDK8-17新特性

JDK8-17新特性 文章目录 JDK8-17新特性1. 如何学习新特性2. Java8新特性&#xff1a;Lambda表达式3. Java8新特性&#xff1a;函数式(Functional)接口3.1 什么是函数式接口3.2 如何理解函数式接口3.3 举例3.4 Java 内置函数式接口3.4.1 之前的函数式接口3.4.2 四大核心函数式接…

Vue3.3指北(三)

Vue3.3指北 1、Vue2和Vue31.1、 Vue2 选项式 API vs Vue3 组合式API1.2、Vue3的优势 2、组合式API - setup2.1、setup选项2.2、setup中写代码的特点2.3、<script setup>语法糖2.4、props和context 3、组合式API - reactive和ref函数3.1、reactive3.2、ref3.3、reactive 对…

2023年中国背光显示面板分类、市场规模及企业分析[图]

背光显示面板行业&#xff0c;指生产背光显示面板及其相关配件的制造商和供应商&#xff0c;这些制造商和供应商主要为电视机、电脑显示器、智能手机等电子产品提供背光显示面板及配件。背光显示面板是一种电子器件&#xff0c;其功能主要是将电信号转化为视觉图像&#xff0c;…