1.hover实现方式
<template>
<div class="global-setting" ref="dragElement">
<div class="setting-sub-btn" style="--i: 0">
<el-popover placement="bottom" title="字体大小" :width="200" trigger="click">
<div style="font-size: 20px" class="font-setting flex-center">
<div class="font-btn" @click="reduceSize">A -</div>
<input v-model="globalFontSize" class="font-global-size" />
<div class="font-btn" @click="globalFontSize += 2">A +</div>
</div>
<template #reference>
<SvgIcon class="icon" name="font-size" :iconStyle="{ width: '1.6rem', height: '1.6rem' }" />
</template>
</el-popover>
</div>
<div class="setting-sub-btn padding-6" style="--i: 1">
<el-icon v-if="type === 'dark'" color="#b8b8b8" class="icon" size="24px"><MoonNight /></el-icon>
<el-icon v-else color="#b8b8b8" class="icon" size="24px"><Sunny /></el-icon>
<!-- <SvgIcon name="moon" :iconStyle="{ width: '1.5rem', height: '1.5rem' }" /> -->
</div>
<div class="setting-sub-btn padding-6" style="--i: 2">
<el-icon color="#b8b8b8" class="icon" size="24px"><Edit /></el-icon>
</div>
<div class="setting-sub-btn padding-6" style="--i: 3">
<SvgIcon class="icon" name="progress" :iconStyle="{ width: '1.6rem', height: '1.6rem' }" />
</div>
<div class="setting-btn padding-6">
<el-icon class="icon" size="32px"><Setting /></el-icon>
</div>
</div>
</template>
<script setup>
let globalFontSize = ref(0)
let type = ref('light')
watch(
() => globalFontSize.value,
val => {
// 挂载时,加载文件内容,并初始化
if (val >= 0) {
const root = document.querySelector(':root')
console.log('root', root)
root.style.setProperty('--font-base-size', val + 'px')
}
},
{ immediate: true }
)
const reduceSize = () => {
if (globalFontSize.value === 0) return
globalFontSize.value -= 2
}
const themeProperty = {
light: {
'--theme-bg': '#ffffff',
'--font-color': '#03103a',
'--scroll-thumb-bgColor': '#acaeb1',
'--el-color-primary': '#6241d5',
'--el-color-primary-light-3': '#c5b8f5',
'--pre-image': `url(${new URL(`../../assets/img/taskBg.png`, import.meta.url).href})`
},
dark: {
'--theme-bg': '#262627',
'--font-color': '#fff',
'--scroll-thumb-bgColor': '#c0c2c5',
'--el-color-primary': '#6241d5',
'--el-color-primary-light-3': '#c5b8f5',
'--pre-image': `url(${new URL(`../../assets/img/taskBg-dark.jpeg`, import.meta.url).href})`
}
}
onMounted(() => {
type.value = localStorage.getItem('theme') || 'light'
if (type.value === 'dark') {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
changeeProperty()
move()
})
const toggle = () => {
if (type.value === 'light') {
type.value = 'dark'
document.documentElement.classList.add('dark')
} else {
type.value = 'light'
document.documentElement.classList.remove('dark')
}
localStorage.setItem('theme', type.value)
changeeProperty()
}
const changeeProperty = () => {
const theme = themeProperty[type.value]
for (const [key, value] of Object.entries(theme)) {
document.documentElement.style.setProperty(key, value)
}
}
let dragElement = ref(null)
let startX = ref(0)
let startY = ref(0)
const move = () => {
// 鼠标按下时记录初始位置
function handleMouseDown(event) {
event.preventDefault()
startX.value = event.clientX - dragElement.value.offsetLeft
startY.value = event.clientY - dragElement.value.offsetTop
window.addEventListener('mousemove', handleMouseMove)
window.addEventListener('mouseup', handleMouseUp)
}
// 移动元素到新位置
function handleMouseMove(event) {
event.preventDefault()
dragElement.value.style.left = event.clientX - startX.value + 'px'
dragElement.value.style.top = event.clientY - startY.value + 'px'
}
// 松开鼠标后取消事件监听器
function handleMouseUp() {
window.removeEventListener('mousemove', handleMouseMove)
window.removeEventListener('mouseup', handleMouseUp)
}
dragElement.value.addEventListener('mousedown', handleMouseDown)
}
</script>
<style lang="scss" scoped>
.global-setting {
cursor: move;
position: absolute;
top: 58%;
right: 2vh;
z-index: 99;
width: 140px;
height: 140px;
border-radius: 50%;
background-color: transparent; /* 背景色 */
display: flex; /* 弹性布局 */
justify-content: center; /* 居中排列 */
align-items: center;
.setting-btn {
position: absolute; /* 绝对定位 */
transform: translateX(-50%);
width: 50px;
height: 50px;
background: var(--theme-bg);
display: flex; /* 弹性布局 */
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
border-radius: 50%; /* 设置按钮圆形 */
border: 1px solid #ece7e7;
transform: rotate(0deg);
transition: all 1.25s;
}
.setting-sub-btn {
position: absolute; /* 绝对定位 */
left: 0px;
display: flex; /* 弹性布局 */
flex-direction: column;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
border-radius: 50%; /* 设置span标签为圆形 */
transform-origin: 70px;
cursor: pointer; /* 鼠标悬停是为小手 */
transform: rotate(0deg) translateX(55px); /* 沿着水平方向向右移动80个像素,但不进行旋转 */
transition: all 1s;
.icon {
width: 33px !important;
height: 33px !important;
padding: 4px;
background: var(--theme-bg);
border-radius: 50%;
transform: rotate(calc(360deg / -4 * var(--i))); /* 旋转工具标签 */
border: 1px solid #ece7e7;
transition: all 1s;
}
}
}
.global-setting:hover .setting-sub-btn {
transform: rotate(calc(360deg / 4 * var(--i))); /* 旋转工具标签 */
}
.global-setting:hover .setting-btn {
transform: rotate(90deg); /* 旋转加号标签 */
}
.font-setting {
user-select: none;
width: 100%;
margin: 0 auto;
border: 1px solid #f0f0f0;
.font-btn {
cursor: Pointer;
with: 25%;
text-align: center;
}
.font-global-size {
width: 30%;
border-left: 1px solid #f0f0f0;
border-right: 1px solid #f0f0f0;
padding: 0 12px;
margin: 0 12px;
}
}
.font-btn:hover {
color: blue;
}
</style>
2.点击实现方式(通过label标签)
<template>
<div class="container">
<input type="checkbox" id="menu" checked="checked" />
<label for="menu">
<div class="circle">
<img src="../assets/img/bg.png" alt="" />
</div>
</label>
<ul class="items">
<li><img src="../assets/img/bg.png" alt="" /></li>
<li><img src="../assets/img/bg.png" alt="" /></li>
<li><img src="../assets/img/bg.png" alt="" /></li>
<li><img src="../assets/img/bg.png" alt="" /></li>
<li><img src="../assets/img/bg.png" alt="" /></li>
<li><img src="../assets/img/bg.png" alt="" /></li>
</ul>
</div>
</template>
<style>
/* 基本配置 */
* {
padding: 0px;
margin: 0px;
}
body {
display: flex;
align-items: center;
align-content: center;
justify-content: space-around;
background-color: #eceff1;
}
.container {
margin: 0 auto;
width: 500px;
height: 500px;
position: relative;
}
/* 设置基本样式 */
.circle {
width: 70px;
height: 70px;
background-color: #fff;
border-radius: 50%;
display: flex;
text-align: center;
justify-content: center;
align-content: center;
align-items: center;
position: absolute;
z-index: 999;
bottom: 10px;
left: 10px;
}
.circle img {
width: 100%;
}
.items li {
width: 70px;
height: 70px;
background-color: #fff;
border-radius: 50%;
display: flex;
text-align: center;
position: absolute;
bottom: 10px;
left: 10px;
display: block;
transition: 1s;
z-index: 0;
}
li img {
width: 100%;
margin-top: 8px;
}
/* 这是通过过渡实现的效果 */
#menu:not(:checked) ~ .items li:nth-child(1) {
transform: rotate(0deg) translateY(-110px);
}
#menu:not(:checked) ~ .items li:nth-child(2) {
transform: rotate(60deg) translateY(-110px);
}
#menu:not(:checked) ~ .items li:nth-child(3) {
transform: rotate(120deg) translateY(-110px);
}
#menu:not(:checked) ~ .items li:nth-child(4) {
transform: rotate(180deg) translateY(-110px);
}
#menu:not(:checked) ~ .items li:nth-child(5) {
transform: rotate(240deg) translateY(-110px);
}
#menu:not(:checked) ~ .items li:nth-child(6) {
transform: rotate(300deg) translateY(-110px);
}
.items li:nth-child(1) img {
transform: rotate(-90deg);
}
.items li:nth-child(2) img {
transform: rotate(-150deg);
}
.items li:nth-child(3) img {
transform: rotate(-210deg);
}
.items li:nth-child(4) img {
transform: rotate(-270deg);
}
.items li:nth-child(5) img {
transform: rotate(-330deg);
}
.items li:nth-child(6) img {
transform: rotate(-390deg);
}
#menu:not(:checked) ~ label .circle {
animation-name: disappear;
animation-duration: 180.5ms;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
@keyframes disappear {
0% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
100% {
transform: scale(0.85) rotate(-45deg);
}
}
#menu:checked ~ label .circle {
animation-name: appear;
animation-duration: 0.5ms;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
#menu:checked ~ label .circle:hover {
width: 80px;
height: 80px;
bottom: 5px;
left: 5px;
}
@keyframes appear {
0% {
transform: scale(0.85) rotate(45deg);
}
50% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
</style>