先贴个图,效果可浏览??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>
|