先贴个图,效果可浏览 dom
在B站看到一个纯css的菜单效果,看着不错啊
给个三连不谢,执行一贯风格,被我看到了那不就是我的了
[H5小案例] 纯CSS实现炫酷3D电竞菜单_哔哩哔哩_bilibili
草率了,代码不全!
为什么B站投的币不能收回...
正文开始
B站上所写是原生搞得,敲下来代码太多了还有一些css看不到,我这个人比较懒,那就用vue去搞一下
- 挂载元素
<div class="menu_css_wrap"> <starry class="starry"></starry> <div class="center"><!--居中--> <div class="outer circle"><!--正圆--></div> <div class="outer outer_one"><!--第一环--> <div class="outer_one_piece" v-for="(item,index) in 36" :key="index+'one'"></div> </div> <div class="outer outer_two"><!--第二环--> <div class="outer_two_piece" v-for="(item,index) in 36" :key="index+'two'"></div> </div> <div class="outer outer_three"><!--第三环--> <div class="outer_three_piece" v-for="(item,index) in 36" :key="index+'three'"></div> </div> <div class="outer outer_four"><!--第四环--> <div class="outer_four_piece" v-for="(item,index) in 36" :key="index+'four'"></div> </div> <div class="outer outer_five"><!--第五环--> <div class="outer_five_piece" v-for="(item,index) in 35" :key="index+'five'"></div> </div> <div class="outer outer_six"><!--第六环--> <div class="outer_six_piece" @click="actionShow(index)" v-for="(item,index) in menusData" :key="index+'six'"> <span>{{ item.title }}</span> <div class="line"></div> <div class="tip">{{ item.tip }}</div> </div> <div class="outer_six_piece blank" v-for="(item,index) in 30" :key="index+'six_blank'"></div> </div> </div> </div>
- 执行一步js
// 星空背景 import starry from '@/components/jsCode/starry/index'; export default { name: "index", components:{ starry, }, data(){ return{ // 菜单数据 menusData:[ { title: '几处早莺争暖树', tip: '谁家新燕啄新泥', }, { title: '一道残阳铺水中', tip: '半江瑟瑟半江红' }, { title: '醉卧沙场君莫笑', tip: '古来征战几人回' }, { title: '烟笼寒水月笼沙', tip: '夜泊秦淮近酒家' }, { title: 'Active', tip: 'Yes,Show Time!' } ] } }, methods:{ // 路由跳转 actionShow(index){ switch (index) { case 0: break; case 1: break; case 2: break; case 3: break; case 4: this.$router.push('/wrap'); break; default: } }, init(){ // 初始化加载样式 for(let i = 1; i < 37; i++){ // 第一环 let outer_one = document.querySelector('.center .outer_one_piece:nth-child('+i+')'); outer_one.style.transform = 'rotateZ('+i*10+'deg)'; outer_one.style['-webkit-transform'] = 'rotateZ('+i*10+'deg)'; // 第二环 let outer_two = document.querySelector('.center .outer_two_piece:nth-child('+i+')'); outer_two.style.transform = 'rotateZ('+i*10+'deg)'; outer_two.style['-webkit-transform'] = 'rotateZ('+i*10+'deg)'; // 第三环 let outer_three = document.querySelector('.center .outer_three_piece:nth-child('+i+')'); outer_three.style.transform = 'rotateZ('+i*4+'deg)'; outer_three.style['-webkit-transform'] = 'rotateZ('+i*4+'deg)'; // 第四环 let outer_four = document.querySelector('.center .outer_four_piece:nth-child('+i+')'); outer_four.style.transform = 'rotateZ(-'+i*4+'deg)'; outer_four.style['-webkit-transform'] = 'rotateZ(-'+i*4+'deg)'; // 第五环 let outer_five = document.querySelector('.center .outer_five_piece:nth-child('+i+')'); outer_five.style.transform = 'rotateZ(-'+i*4+'deg)'; outer_five.style['-webkit-transform'] = 'rotateZ(-'+i*4+'deg)'; // 第六环 if(i < 6){ let outer_six = document.querySelector('.center .outer_six_piece:nth-child('+i+')'); outer_six.style.transform = 'rotateZ(-'+(i+2)*12+'deg)'; outer_six.style['-webkit-transform'] = 'rotateZ(-'+(i+2)*12+'deg)'; }else{ // 第六环 blank let outer_six_blank = document.querySelector('.blank:nth-child('+i+')'); outer_six_blank.style.transform = 'rotateZ(-'+i*12+'deg)'; outer_six_blank.style['-webkit-transform'] = 'rotateZ(-'+i*12+'deg)'; } } } }, mounted() { setTimeout(()=>{ document.getElementsByClassName('center')[0].style.opacity = 1; this.init(); },500); } }
- css(使用到了sass)
.menu_css_wrap{ margin: 0; padding: 0; width: 100%; height: 100%; background: #0b0b0e; overflow: hidden; animation: scale 1s 1s forwards; perspective-origin: center top; perspective: 1500px; // 背景星空组件 .starry{ width: 100%; height: 100%; position:absolute; z-index: -10; opacity: 0.3; } .center{ opacity: 0; height: 50px; width: 50px; left: 0; right: 0; top: 30%; position: absolute; margin: auto; transform: rotateX(35deg) rotateY(-25deg) rotateZ(80deg) scale(0.5); .outer{ position: absolute; width: 100%; height: 100%; top: 50%; left: 50%; } .circle{ border-radius: 50%; background: #de0b46; box-shadow: 0 0 70px 20px hsl(343,91%,46%); transform: translate(-50%,-50%); } .outer_one{ transform: translate(-100px,-50%); .outer_one_piece{ position: absolute; border-radius: 2px; width: 10px; height: 30px; background: #de0b46; box-shadow: 0 0 20px 0 #de0b46; transform-origin: 100px 0; } } .outer_two{ transform: translate(-300px,-50%); @for $i from 1 through 36 { .outer_two_piece:nth-child(#{$i}){ animation: marquee 3.6s ($i * 0.1s) infinite linear; } } .outer_two_piece{ position: absolute; border-radius: 2px; width: 30px; height: 5px; background: #de0b46; box-shadow: 0 0 20px 0 #de0b46; transform-origin: 300px 0; opacity: 0.2; } } .outer_three{ transform: translate(-400px,-50%); @for $i from 1 through 36 { .outer_three_piece:nth-child(#{$i}){ animation: marquee 3.6s ($i * 0.1s) infinite linear; } } .outer_three_piece{ position: absolute; border-radius: 2px; width: 50px; height: 5px; background: #55e2f9; box-shadow: 0 0 20px 0 #55e2f9; transform-origin: 400px 0; opacity: 0.2; } } .outer_four{ transform: translate(-450px,-50%) rotate(-30deg); transform-origin: 450px 0; @for $i from 1 through 36 { .outer_four_piece:nth-child(#{$i}){ animation: marquee 3.6s ($i * 0.1s) infinite linear; } } .outer_four_piece{ position: absolute; border-radius: 2px; width: 6px; height: 5px; background: #de0b46; box-shadow: 0 0 20px 0 #de0b46; transform-origin: 450px 0; opacity: 0.2; } } .outer_five{ transform: translate(-400px,-100%) rotate(-30deg); transform-origin: 450px 0; @for $i from 1 through 36 { .outer_five_piece:nth-child(#{$i}){ animation: marquee 3.6s (3.6s - $i * 0.1s) infinite linear; } } .outer_five_piece{ position: absolute; border-radius: 2px; width: 6px; height: 5px; background: #de0b46; box-shadow: 0 0 20px 0 #de0b46; transform-origin: 400px 0; opacity: 0.2; } } .outer_six{ transform: translate(500px,-50%); .outer_six_piece{ position: absolute; border-radius: 100px; width: 240px; height: 20px; border: 3px solid #de0b46; font-weight: 900; padding: 30px; font-size: 30px; box-shadow: 0 0 25px rgba(222,11,70,0.27); transition: all 1s .1s; color: white; text-align: left; background: transparent; transform-origin: -500px 0; } // 文字 span{ display: block; width: 100%; position: absolute; top: 20px; left: 30px; transition: all .2s .3s; } // 直线 .line{ opacity: 0; position: absolute; width: 540px; height: 5px; left: -520px; transform: rotateZ(4deg); transform-origin: center; top: 25px; background: #de0b46; transition: all .4s .2s; } // 文字提示 .tip{ font-size: 22px; position: absolute; top: 20px; left: 105%; opacity: 0; -webkit-transition: all .2s .3s; -moz-transition: all .2s .3s; -o-transition: all .2s .3s; transition: all .2s .3s; font-weight: 400; color: #85dfe4; width: 100%; } .blank{ opacity: .1; background: 0; pointer-events: none; box-shadow: 0 0 10px rgba(255,255,255,0.27); border: 6px solid #3d4b6d; } .outer_six_piece:hover{ width: 300px; cursor: pointer; color: white; background: #de0b46; box-shadow: 0 0 55px rgba(222,11,70,0.77); } .outer_six_piece:hover span{ text-shadow: 0 13px 0 rgba(30,30,30,0.4); left: 100px; } .outer_six_piece:hover .tip{ opacity: 1; left: 100%; top: -40%; } .outer_six_piece:hover .line{ opacity: 1; } } } } // 跑马灯动画 @keyframes marquee { 0%{ opacity: 1; } 25%{ opacity: 0.25; } 50%{ opacity: 0.50; } 75%{ opacity: 0.75; } 100%{ opacity: 1; } }
介绍就不说了,都是基础的css跟js
背景的星空是网上找的效果图(注意网上的有部分公布的代码里使用setInterval,别忘了销毁)
这是我用的星空
<template>
<div class="starry_wrap">
<canvas id="canvas"></canvas>
</div>
</template>
<script>
window.addEventListener('resize', init);
function init() {
let canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
w = canvas.width = window.innerWidth,
h = canvas.height = window.innerHeight,
hue = 217,
stars = [],
count = 0,
maxStars = 1400;
let canvas2 = document.createElement('canvas'),
ctx2 = canvas2.getContext('2d');
canvas2.width = 100;
canvas2.height = 100;
let half = canvas2.width/2,
gradient2 = ctx2.createRadialGradient(half, half, 0, half, half, half);
gradient2.addColorStop(0.025, '#fff');
gradient2.addColorStop(0.1, 'hsl(' + hue + ', 61%, 33%)');
gradient2.addColorStop(0.25, 'hsl(' + hue + ', 64%, 6%)');
gradient2.addColorStop(1, 'transparent');
ctx2.fillStyle = gradient2;
ctx2.beginPath();
ctx2.arc(half, half, half, 0, Math.PI * 2);
ctx2.fill();
function random(min, max) {
if (arguments.length < 2) {
max = min;
min = 0;
}
if (min > max) {
let hold = max;
max = min;
min = hold;
}
return Math.floor(Math.random() * (max - min + 1)) + min;
}
let Star = function() {
this.orbitRadius = random(w / 2 - 50);
this.radius = random(100, this.orbitRadius) / 10;
this.orbitX = w / 2;
this.orbitY = h / 2;
this.timePassed = random(0, maxStars);
this.speed = random(this.orbitRadius) / 900000;
this.alpha = random(2, 10) / 10;
count++;
stars[count] = this;
}
Star.prototype.draw = function() {
let x = Math.sin(this.timePassed + 1) * this.orbitRadius + this.orbitX,
y = Math.cos(this.timePassed) * this.orbitRadius/2 + this.orbitY,
twinkle = random(10);
if (twinkle === 1 && this.alpha > 0) {
this.alpha -= 0.05;
} else if (twinkle === 2 && this.alpha < 1) {
this.alpha += 0.05;
}
ctx.globalAlpha = this.alpha;
ctx.drawImage(canvas2, x - this.radius / 2, y - this.radius / 2, this.radius, this.radius);
this.timePassed += this.speed;
}
for (let i = 0; i < maxStars; i++) {
new Star();
}
function animation() {
ctx.globalCompositeOperation = 'source-over';
ctx.globalAlpha = 0.8;
ctx.fillStyle = 'hsla(' + hue + ', 64%, 6%, 1)';
ctx.fillRect(0, 0, w, h)
ctx.globalCompositeOperation = 'lighter';
for (let i = 1, l = stars.length; i < l; i++) {
stars[i].draw();
}
window.requestAnimationFrame(animation);
}
animation();
}
export default {
name: "index",
data(){
return{
}
},
methods:{
},
mounted() {
init();
},
destroyed(){
window.removeEventListener('resize',init);
}
}
</script>