javaScript蓝桥杯---视频弹幕

news2024/11/26 4:44:56

目录

  • 一、介绍
  • 二、准备
  • 三、⽬标
  • 四、代码
  • 五、完成


一、介绍

弹幕指直接显现在视频上的评论,可以以滚动、停留甚⾄更多动作特效⽅式出现在视频上,是观看视频的⼈发送的简短评论。通过发送弹幕可以给观众⼀种“实时互动”的错觉,弹幕的出现让观看过程充满乐趣。本题需要在已提供的基础项⽬中,完成视频弹幕的功能。

二、准备

开始答题前,需要先打开本题的项⽬代码⽂件夹,⽬录结构如下:

├── effect.gif
├── css
│ └── style.css
├── video
│ └── video1.webm
├── index.html
└── js
└── index.js

其中:

  • index.html 是主⻚⾯。
  • js/index.js 是需要补充代码的 js ⽂件。
  • css/style.css 是样式⽂件。
  • effect.gif 是完成的效果图。
  • video 是存放视频的⽂件夹。

在浏览器中预览 index.html ⻚⾯,显示如下所示:
在这里插入图片描述

三、⽬标

请在 js/index.js ⽂件中补全代码。具体需求如下:

  1. 补全 renderBullet 函数中的代码,控制弹幕的显示颜⾊和移动。功能说明如下:
    • 每个弹幕内容包裹在 span 标签中,作为⼦节点插⼊到 #video 元素节点内。
    • ⽣成的 span 元素节点相对于 #video 元素绝对定位 ,初始位置的 left 是 #video 元素的宽, top 是 #video 元素的⾼内的随机数。

    注意:需求中所需样式可直接通过已提供的 getEleStyle ⽅法获取。

    • 弹幕每隔 bulletConfig.time (弹幕配置对象) 时间,向左移动距离为bulletConfig.speed (弹幕配置对象)。
    • 当弹幕最右端完全移出 #video 元素时,移除 span 元素。
  2. 补全 #sendBulletBtn 元素的绑定事件,点击发送按钮,输⼊框中的⽂字出现在弹幕中,样式不同于普通弹幕(样式红⾊字体红⾊框已设置,类名为 create-bullet )。通过调⽤renderBullet ⽅法和正确的传参实现功能。

最终效果可参考⽂件夹下⾯的 gif 图,图⽚名称为 effect.gif(提示:可以通过 VS Code 或者浏览器预览gif 图⽚)。
在这里插入图片描述

四、代码

index.html

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>视频弹幕</title>
    <link rel="stylesheet" href="./css/style.css" />
  </head>

  <body>
    <div class="container">
      <div class="video-header">
        <h1 class="title">workerman基础</h1>
        <div class="video-info">
          <span>13.2亿播放</span>
          <span>656.5万弹幕</span>
          <span>2022-12-11 15:29:24</span>
        </div>
      </div>
      <div id="video">
        <video src="./video/video1.webm" poster="" id="vd" controls>
          您的浏览器不支持 video 标签。
        </video>
      </div>
      <div class="player-sending-area">
        <p class="player-video-info">231 人正在看,4396 条弹幕</p>
        <div class="switch-box">
          <input
            type="checkbox"
            name=""
            id="switchButton"
            class="switch"
            checked
          />
          <label for="switchButton"></label>
        </div>
        <input
          type="text"
          name=""
          id="bulletContent"
          placeholder="请输入您的弹幕"
        />
        <button id="sendBulletBtn">发送</button>
      </div>
    </div>
    <script src="./js/index.js"></script>
  </body>
</html>

css/style.css

* {
  margin: 0;
  padding: 0;
}

.container {
  width: 850px;
  margin: 0px auto;
}

.container .video-header {
  box-sizing: border-box;
  padding: 24px 0;
}

.container .video-header .title {
  font-size: 20px;
  font-family: PingFang SC, HarmonyOS_Regular, Helvetica Neue, Microsoft YaHei,
    sans-serif;
  font-weight: 500;
  margin-bottom: 6px;
  color: #18191c;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.container .video-header .video-info {
  display: flex;
  align-items: center;
}

.container .video-header .video-info span {
  margin-right: 12px;
  font-size: 13px;
  color: #9499a0;
}

#video {
  width: 850px;
  height: 560px;
  background-color: #000;
  position: relative;
  overflow: hidden;
}

#video > video {
  width: 100%;
  height: 100%;
}

#video > span {
  position: absolute;
  white-space: nowrap;
  color: #fff;
  font-size: 16px;
}

#video > .create-bullet {
  border: 1px solid red;
  box-shadow: 0 0 5px 5px rgb(255, 84, 84);
  padding: 5px 10px;
  border-radius: 10px;
  color: red !important;
  background-color: rgba(255, 255, 255, 0.5);
}

.container .player-sending-area {
  display: flex;
  align-items: center;
  width: 830px;
  height: 50px;
  background-color: #fff;
  box-shadow: 0 1px 5px rgb(207, 207, 207);
  padding: 0 10px;
}

.container .player-sending-area .player-video-info {
  font-size: 14px;
  color: rgb(95, 95, 95);
  margin: 0 15px;
}

.container .player-sending-area .switch-box {
  width: 48px;
}

.container .player-sending-area .switch-box .switch {
  display: none;
}

.container .player-sending-area .switch-box label {
  position: relative;
  display: block;
  margin: 1px;
  height: 28px;
  cursor: pointer;
}

.container .player-sending-area .switch-box label::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -13px;
  margin-left: -14px;
  width: 26px;
  height: 26px;
  border-radius: 100%;
  background-color: #fff;
  box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.06);
  transform: translateX(-9px);
  transition: all 0.3s ease;
}

.container .player-sending-area .switch-box .switch:checked ~ label::before {
  transform: translateX(10px);
}

.container .player-sending-area .switch-box label::after {
  content: "";
  display: block;
  border-radius: 30px;
  height: 28px;
  background-color: #dcdfe6;
  transition: all 0.3s ease;
}

.container .player-sending-area .switch-box .switch:checked ~ label::after {
  background-color: #00a1d6;
}

.container .player-sending-area > input {
  width: 250px;
  height: 30px;
  margin-left: 20px;
  border: 1px solid #e7e7e7;
  outline: none;
  text-indent: 10px;
  background-color: rgb(245, 244, 244);
  font-size: 12px;
  color: rgb(36, 35, 35);
}

.container .player-sending-area > input::placeholder {
  font-size: 12px;
}

.container .player-sending-area > button {
  width: 60px;
  height: 32px;
  color: #fff;
  background-color: #00a1d6;
  border: none;
}

js/index.js

const bullets = [
  "前方高能",
  "原来如此",
  "这么简单",
  "学到了",
  "学费了",
  "666666",
  "111111",
  "workerman",
  "学习了",
  "别走,奋斗到天明",
];

/**
 * @description 根据 bulletConfig 配置在 videoEle 元素最右边生成弹幕,并移动到最左边,弹幕最后消失
 * @param {Object} bulletConfig 弹幕配置
 * @param {Element} videoEle 视频元素
 * @param {boolean} isCreate 是否为新增发送的弹幕,为 true 表示为新增的弹幕
 *
 */
function renderBullet(bulletConfig, videoEle, isCreate = false) {
  const spanEle = document.createElement("SPAN");
  spanEle.classList.add(`bullet${index}`);
  if (isCreate) {
    spanEle.classList.add("create-bullet");
  }
  // TODO:控制弹幕的显示颜色和移动,每隔 bulletConfig.time 时间,弹幕移动的距离  bulletConfig.speed
}

document.querySelector("#sendBulletBtn").addEventListener("click", () => {
  // TODO:点击发送按钮,输入框中的文字出现在弹幕中
});

function getEleStyle(ele) {
  // 获得元素的width,height,left,right,top,bottom
  return ele.getBoundingClientRect();
}

function getRandomNum(end, start = 0) {
  // 获得随机数,范围是 从start到 end
  return Math.floor(start + Math.random() * (end - start + 1));
}

// 设置 index 是为了弹幕数组循环滚动
let index = 0;
const videoEle = document.querySelector("#video");
// 弹幕配置
const bulletConfig = {
  isHide: false, // 是否隐藏
  speed: 5, // 弹幕的移动距离
  time: 50, // 弹幕每隔多少ms移动一次
  value: "", // 弹幕的内容
};
let isPlay = false;
let timer; // 保存定时器
document.querySelector("#vd").addEventListener("play", () => {
  // 监听视频播放事件,当视频播放时,每隔 1000s 加载一条弹幕
  isPlay = true;
  bulletConfig.value = bullets[index++];
  renderBullet(bulletConfig, videoEle);
  timer = setInterval(() => {
    bulletConfig.value = bullets[index++];
    renderBullet(bulletConfig, videoEle);
    if (index >= bullets.length) {
      index = 0;
    }
  }, 1000);
});

document.querySelector("#vd").addEventListener("pause", () => {
  isPlay = false;
  clearInterval(timer);
});

document.querySelector("#switchButton").addEventListener("change", (e) => {
  if (e.target.checked) {
    bulletConfig.isHide = false;
  } else {
    bulletConfig.isHide = true;
  }
});

五、完成


/**
 * @description 根据 bulletConfig 配置在 videoEle 元素最右边生成弹幕,并移动到最左边,弹幕最后消失
 * @param {Object} bulletConfig 弹幕配置
 * @param {Element} videoEle 视频元素
 * @param {boolean} isCreate 是否为新增发送的弹幕,为 true 表示为新增的弹幕
 *
 */
function renderBullet(bulletConfig, videoEle, isCreate = false) {
  const spanEle = document.createElement('SPAN')
  spanEle.classList.add(`bullet${index}`)
  if (isCreate) {
    spanEle.classList.add('create-bullet')
  }
  // TODO:控制弹幕的显示颜色和移动,每隔 bulletConfig.time 时间,弹幕移动的距离  bulletConfig.speed
  if (bulletConfig.isHide) {
    return
  }
  //设置弹幕随机颜色
  spanEle.style.color = `rgb(${getRandomNum(255)},${getRandomNum(255)},${getRandomNum(255)})`
  //设置弹幕内容
  spanEle.innerHTML = bulletConfig.value
  //   ⽣成的 span 元素节点相对于 #video 元素绝对定位 ,
  spanEle.style.position = 'absolute'
  //初始位置的 left 是 #video 元素的宽,
  let leftSpan = getEleStyle(videoEle).width
  spanEle.style.left = leftSpan + 'px'
  // top 是 #video 元素的⾼内的随机数。
  spanEle.style.top = getRandomNum(getEleStyle(videoEle).height) + 'px'
  let _timer = setInterval(() => {
    //弹幕每隔 bulletConfig.time (弹幕配置对象) 时间,向左移动距离为
    leftSpan -= bulletConfig.speed
    spanEle.style.left = leftSpan + 'px'
    //每个弹幕内容包裹在 span 标签中,作为⼦节点插⼊到 #video 元素节点内
    videoEle.appendChild(spanEle)
    if (leftSpan < 0) {
      clearInterval(_timer)
      videoEle.removeChild(spanEle)
    }
  }, bulletConfig.time)
}

document.querySelector('#sendBulletBtn').addEventListener('click', () => {
  // TODO:点击发送按钮,输入框中的文字出现在弹幕中
  bulletConfig.value = document.querySelector('#bulletContent').value
  renderBullet(bulletConfig, videoEle, true)
})

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

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

相关文章

Segment Anything Model (SAM)——卷起来了,那个号称分割一切的CV大模型他来了

最近每天打开微信看到10个公众号里面差不多有11个都在各种玩赚chatGPT&#xff0c;每个都在说是各种大好风口&#xff0c;哎&#xff0c;看得眼睛都是累的。 今天下午无意间看到Meta发布了一款号称能分割一切的CV大模型&#xff0c;CV圈也开始卷起来&#xff0c;今年各种大模型…

chatgpt赋能python:Python在图片处理方面的应用

Python在图片处理方面的应用 在当今数字化的时代&#xff0c;图像处理已成为不可避免的技术。越来越多的业务需要对图片进行处理、识别和分析。Python是一种易于使用且适合处理图像的编程语言。Python中有许多图像处理库&#xff0c;例如Pillow、Scikit-Image和OpenCV等&#…

基于BP神经网络的PID智能控制

基于BP神经网络的PID智能控制 基于BP神经网络的PID整定原理经典的增量式数字PID控制算法为&#xff1a;BP神经网络结构&#xff1a;学习算法仿真模型Matlab代码仿真效果图结论python仿真参考文献 基于BP神经网络的PID整定原理 PID控制要获得较好的控制效果&#xff0c;就必须通…

山东大学单片机原理与应用实验 3.4 矩阵键盘扫描实验

目录 一、实验题目 二、实验要求 三、实验过程及结果记录 1. 在Proteus 环境下建立图1所示原理图&#xff0c;并将其保存为keyscan_self.DSN 文件。 2. 编写控制源程序&#xff0c;将其保存为keyscan_self.asm 或keyscan_self.c。 3. 将源程序添加到U1 中&#xff0c;并构…

chatgpt赋能python:Python如何将空格变成换行

Python如何将空格变成换行 Python是一种流行的编程语言&#xff0c;有着许多实用的功能和库。在这篇文章中&#xff0c;我们将介绍如何使用Python将空格变成换行的方法。这是一种有用的技巧&#xff0c;可以帮助你在处理文本时更加方便。 为什么需要将空格变成换行 将空格变…

eNSP数据抓包时弹不出Wireshark.exe

文章目录 原因&#xff1a;wireshark的版本问题解决方法&#xff1a;操作例图 原因&#xff1a;wireshark的版本问题 上述2.6.6版本安装后&#xff0c;ensp工具路径正确&#xff0c;数据抓包也始终打不开wireshark&#xff0c;但是直接打开是可以打开的。安装3.6.3版本后&#…

零基础使用ChatGPT写一个小游戏---文末附源码

ChatGPT&#xff1a;赋能自然语言处理的多种应用领域 ChatGPT是当今最先进的人工智能对话系统之一&#xff0c;已经被证明可以支持许多不同的自然语言处理应用程序。以下是ChatGPT可以运行的几个领域&#xff1a; 聊天机器人 ChatGPT作为一个建立在自然语言处理技术上的人工…

chatgpt赋能python:Python数据拟合

Python 数据拟合 在数据分析和机器学习领域&#xff0c;数据拟合是非常重要的一步。Python作为一种流行的编程语言&#xff0c;在数据拟合方面拥有强大的工具和库&#xff0c;因此被广泛使用。本文将介绍Python中常用的一些数据拟合方法&#xff0c;并演示如何使用它们。 线性…

200道网络安全常见面试题合集(附答案解析+配套资料)

有不少小伙伴面临跳槽或者找工作&#xff0c;本文总结了常见的安全岗位面试题&#xff0c;方便各位复习。祝各位事业顺利&#xff0c;财运亨通。在网络安全的道路上越走越远&#xff01; 所有的资料都整理成了PDF&#xff0c;面试题和答案将会持续更新&#xff0c;因为无论如何…

宝塔-如何部署自己的nodejs项目并跑起来【已解决】

我自己做了一个项目&#xff0c;前端后端都是自己做&#xff0c;后端就用的nodejs写的接口&#xff0c;但是本地每次访问都要启动一次&#xff0c;所以我准备放到服务器上&#xff0c;这样接口就能一直跑了 先看效果 这里可以看到我现在是本地的ip在访问接口&#xff0c;以为我…

什么是端到端解决方案

通过“端到端”流程打通&#xff0c;将各相关部门的业务环节衔接起来&#xff0c;消灭“断头路”&#xff0c;不断提高内部的效率并满足客户的需求&#xff0c;最终实现企业效益最大化。 不同语境下的端到端 端到端在不同领域有多重含义&#xff0c;是一个非常复杂且抽象的名…

机器学习算法:UMAP 深入理解

导读 降维是机器学习从业者可视化和理解大型高维数据集的常用方法。最广泛使用的可视化技术之一是 t-SNE&#xff0c;但它的性能受到数据集规模的影响&#xff0c;并且正确使用它可能需要一定学习成本。 UMAP 是 McInnes 等人开发的新算法。与t-SNE相比&#xff0c;它具有许多…

4090 深度学习性能实测

测试结果 测试平台&#xff1a; 显卡&#xff1a;影驰金属大师4090 cpu&#xff1a;i7 12700k 测试方法 李沐老师micro-benchmarkings B站视频 测试 1.矩阵计算速度 transformer的核心操作是矩阵乘法&#xff0c;通过测试矩阵计算的tflops可以得到硬件的计算上限。 ma…

操作系统实验一到实验九合集(哈工大李治军)

操作系统实验 作者寄语 操作系统实验的学习是一个循序渐进的过程&#xff0c;初次看linux-0.11中的代码&#xff0c;看着满屏的汇编语言&#xff0c;确实头疼。但通过学习赵炯博士的Linux内核0.11完全注释&#xff0c;结合着王爽老师的汇编语言一书&#xff0c;我逐渐理解每段…

jmeter压测数据库

1.查询数据库对应的URL可点击jmeter操作指南书的图表&#xff0c;找到对应的数据库url即可 2.为避免在连接数据库时会报编码/时区上的错误&#xff0c;可以在URL后面添加两个参数 ?useUnicode true //反正乱码 &characterEncodingUTF-8 //国际编码 &serverTimezoneUT…

非常全面的数字人解决方案(含源码)

github TheRamU/Fay: 语音互动&#xff0c;直播自动带货 虚拟数字人 (github.com) gitee fay: 这是一个数字人项目&#xff0c;包含python内核及ue数字人模型&#xff0c;可以用于做数字助理及自动直播&#xff0c;又或者作为你的应用入口也很帅 (gitee.com) 2022.10.27 补…

I/O框架知识

I/0框架 什么是流&#xff1f; 概念&#xff1a;内存与存储设备之间传输数据的通道 流的分类 按方向&#xff08;重点&#xff09; 输入流: 将<存储设备>的内容读入到<内存>中&#xff0c; 输出流&#xff1a;将<内存>中的内容写入到<存储设备>中 …

socket编程之connect()

5 connect() connect&#xff08;&#xff09; 系统调用将文件描述符 sockfd 引用的套接字连接到 addr 指定的地址。 2.1 包含头文件 #include <sys/types.h> #include <sys/socket.h>2.2 函数主体 int connect(int sockfd, const struct sockaddr *ad…

chatgpt赋能python:Python平铺图片的SEO优化

Python平铺图片的SEO优化 在网站设计中&#xff0c;图片是一个重要的元素。但是&#xff0c;使用大量的图片会导致网站加载速度变慢&#xff0c;从而影响用户的体验。为了解决这个问题&#xff0c;我们可以使用平铺图片&#xff0c;这样可以减小图片的大小&#xff0c;提高网站…

腾讯云国际版注册流程详解

作为国内三大云厂商之一的腾讯云&#xff0c;相信很多人都不会陌生&#xff0c;我们使用的微信、QQ等都是依托于腾讯云的服务器&#xff0c;实力自然是不容小觑&#xff0c;而腾讯云近年来也是在海外市场不断布局&#xff0c;影响力显著增长&#xff0c;不管是个人建站还是企业…