实现一个动态按钮组,并且将视频作为背景
不知道各位是否知道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')
})
})
注意
不知道为什么视频没有播放,不知道是视频链接的原因,还是视频版权问题,目前还没解决,等之后找到解决办法。