实现一个动态按钮组,并且将视频作为背景

8,920 阅读6分钟

实现一个动态按钮组,并且将视频作为背景

不知道各位是否知道wallenpaper壁纸引擎,其中里面可以将我们自己的html导入当成我们的电脑壁纸,所以,嘿嘿嘿,懂得都懂。大家之后可以慢慢完善,做一个自己的壁纸。 先看效果,当我们点击中间的按钮,会依次展开各种小按钮,当展开后,我们再次点击,就会依次关闭。

整体布局

整个 HTML 页面主要包含了一个视频背景和一个动态按钮组容器,按钮组中包含了多个链接和图标元素。同时借助于外部的 CSS 和 JavaScript 文件,实现了样式控制和动态效果。

<!DOCTYPE html>
<html lang="en">

<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="./style.css">
</head>

<body>
    <video autoplay loop>
        <!-- 嵌入视频资源,并设定视频属性 -->
        <source src="https://wallpaper-static.cheetahfun.com/wallpaper/sites/dynamics/vm8.mp4" type="video/mp4">
        <!-- 视频资源地址和格式 -->
    </video>
    <div class="content">
        <!-- 页面主体容器 -->
        <div class="Box">
            <!-- 按钮组容器 -->
            <div class="box">
                <!-- 菜单按钮容器 -->
                <ion-icon name="apps-outline"></ion-icon> <!-- 菜单按钮图标 -->
            </div>
            <div>
                <!-- 面板容器,包含了多个链接和图标元素 -->
                <a href="#" class="panel" style="--i:0">
                    <!-- 面板元素,包含链接和图标 -->
                    <ion-icon name="airplane-outline"></ion-icon> <!-- 图标元素 -->
                </a>
                <a href="#" class="panel" style="--i:1">
                    <ion-icon name="barbell-outline"></ion-icon>
                </a>
                <a href="#" class="panel" style="--i:2">
                    <ion-icon name="build-outline"></ion-icon>
                </a>
                <a href="#" class="panel" style="--i:3">
                    <ion-icon name="chatbox-outline"></ion-icon>
                </a>
                <a href="#" class="panel" style="--i:4">
                    <ion-icon name="cloud-upload-outline"></ion-icon>
                </a>
                <a href="#" class="panel" style="--i:5">
                    <ion-icon name="contrast-outline"></ion-icon>
                </a>
            </div>
        </div>
    </div>
    <script src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"></script> <!-- 引入 ionicons 图标库 -->
    <script src="./script.js"></script> <!-- 引入外部 JavaScript 脚本 -->

</html>

CSS实现布局

首先,通过 body 设置整个页面的背景颜色为黑色,然后设置 .content 距离页面顶部和左侧的距离为 70vw 和 70vh。这样内容就不会从页面的左上角开始了,而是在距离页面左上角一定距离的位置。

视频的 CSS 样式如下:position: fixed; 让视频背景覆盖整个页面,object-fit: cover; 保证视频的实际大小和宽高比与其容器(页面)的大小和宽高比相符,width: 100%; height: 100%; 让视频铺满整个容器。

.box 中 content 的值为空字符串,创建一个空元素。.box 的背景色为黑色,盒子的位置是绝对的,放置在页面的中央位置。同时,z-index 设置为 1,可以让这个盒子在页面上浮现,和其它内容区分开。.box ion-icon 显示在盒子内部,并为其增加一个白色图标。

接下来的 .panel 类代表了一组面板,初始状态下,这些面板都是不可见的。clip-path 属性可以定义剪切路径,用于创建非常规的形状。backdrop-filter 属性可以为元素添加半透明的背景模糊效果,让背景显得更加柔和,形成一个更加美观的页面效果。

.panel 的 transform 和 transition 属性被用来调整面板的展开时的过渡效果。

通过应用的 .active 类,面板可以展开,并且opacity、 width 和 height 的值恢复到有可见的状态。为了实现动画的效果,添加了 transition-delay 属性来每个面板之间的显示时间间隔。

/* 设置整个页面的背景颜色为黑色 */
body {
    margin: 0; /* 去除默认外边距 */
    padding: 0; /* 去除默认内边距 */
    background: #000000; 
  }
  
  /* 设置内容距离页面顶部和左侧的距离为 70vw 和 60vh */
  .content {
     margin-top: 70vh; 
     margin-left: 60vw;
  }
  
  /* 视频的CSS样式 */
  video {
      position: fixed; /* 位置固定,不随页面滚动而改变 */
      top: 0; /* 位置在页面顶部 */
      left: 0; /* 位置在页面左侧 */
      object-fit: cover; /* 填充容器代码 */
      width: 100%; /* 宽度铺满整个页面 */
      height: 100%; /* 高度铺满整个页面 */
      z-index: -1; /* 将视频与其他内容相分离,位于整个页面的底部 */
  }
  
  /* 设计一个圆形的盒子 */
  .Box {
      position: relative;
      font-size: 18px; 
      border-radius: 50%; /* 设置为50%的圆角,形成圆形的效果 */
  }
  
  /* 为了形成浮现的效果,创建一个看似空白的盒子 */
  .box {
      content: ""; /* 没有实际内容 */
      background: #000; /* 盒子背景为黑色 */ 
      position: absolute; /* 位置固定 */
      top: 50%; /* 距离顶部50%的位置 */
      left: 50%; /* 距离左侧50%的位置 */
      transform: translate(-50%, -50%); /* 平移到中心 */
      width: 4em; /* 宽度为4em */
      height: 4em; /* 高度为4em */
      border-radius: 50%; /* 设置圆角,形成圆形的效果 */
      z-index: 1; /* 盒子在面板上浮现 */
      box-shadow: 0 0 1em rgba(0, 0, 0, 0.8); /* 创建一个黑色阴影 */
      display: flex; /* 让盒子内部的元素居中 */
      justify-content: center; /* 水平居中 */
      align-items: center; /* 垂直居中 */
  }
  
  /* 盒子内部的图标 */
  .box ion-icon {
      color: #fff; /* 图标颜色为白色 */
      font-size: 1.3em; /* 图标的字体大小 */
  }
  
  /* 设计一组可以展开的面板 */
  .panel {
      background: rgba(0, 0, 0, 0.5); /* 设置面板背景颜色 */
      text-decoration: none; /* 去除默认超链接下划线 */
      width: 11.7em; /* 设置面板的宽度 */
      height: 10em; /* 设置面板的高度 */
      position: absolute; /* 位置固定 */
      top: 50%; /* 距离顶部50%的位置 */
      left: 50%; /* 距离左侧50%的位置 */
      color: #fff; /* 设置字体颜色为白色 */
      transform-origin: top center; /* 支点位于顶部中心 */
      transition: width 0.1s, height 0.1s, opacity 0.2s; /* 在展开面板时设置过度效果 */
      clip-path: polygon(50% 0%, 0% 100%, 100% 100%); /* 设置非常规形状,用于创建三角形效果 */
      backdrop-filter: blur(2px); /* 在背景上添加边缘模糊 */
  }
  
  /* 为每个面板定义一个动画 */
  .panel {
      transition-delay: calc(0.08s * var(--i)); /* 设置过渡延迟 */
      transform: translateX(-50%) rotate(calc(60deg * var(--i))); /* 展开动画 */
  }
  
  /* 设计合适的图标 */
  .panel ion-icon {
      transform: translateX(-50%) rotate(calc(60deg * var(--i))); /* 图标跟随动画产生偏移 */
  }
  
  /* 鼠标悬停时修改面板背景颜色 */
  .panel:hover {
      background: rgba(0, 0, 0, 0.8);
  }
  
  /* 面板中图标的大小位置 */
  .panel ion-icon {
      font-size: 2.5em;
      position: absolute;
      top: 50%;
      left: 50%;
  }
  
  /* 面板初始状态被隐藏 */
  .panel {
      opacity: 0; /* 初始面板透明 */
      width: 0; /* 初始面板宽度为0 */
      height: 0; /* 初始面板高度为0 */
  }
  
  /* 激活状态下修改面板的尺寸和颜色 */
  .active {
      opacity: 1; /* 面板透明度为1 */
      height: 10em; /* 面板高度为10em */
      width: 11.7em; /* 面板宽度为11.7em */
  }
  

js实现

这里的js就比较简单,单纯只是添加了点击事件而已。它在点击一个按钮后,改变面板的状态(active 和非 active)。

  • 首先使用 document.querySelector() 方法获取了一个 class 为 "box" 的元素,该元素是菜单按钮。
  • 然后使用 document.querySelectorAll() 方法获取了所有 class 为 "panel" 的元素,也就是面板。
  • 接下来,对菜单按钮添加了一个 click 事件监听器,当用户点击按钮时,会执行一个匿名函数。
  • 在该函数中,使用了 panels.forEach() 方法,遍历了所有面板元素。
  • 在面板元素中添加或删除一个 class 为 "active" 的类,以改变它的状态。
  • 最终,通过使用 .classList.toggle() 方法,将面板的状态在 "active" 和非 "active" 之间切换。
// 获取菜单按钮元素
var active = document.querySelector('.box')

// 获取所有面板元素
var panels = document.querySelectorAll('.panel')

// 为菜单按钮添加点击事件监听器
active.addEventListener('click', () => {
    // 遍历所有面板元素
    panels.forEach(panel => {
        // 切换每个面板元素的 "active" 状态
        panel.classList.toggle('active')
    })
})

注意

不知道为什么视频没有播放,不知道是视频链接的原因,还是视频版权问题,目前还没解决,等之后找到解决办法。

源码

掘金/动态按钮 · Mr-W-Y-P/Html-css-js-demo - 码云 - 开源中国 (gitee.com)