一,
动画效果:
1,横屏滚动
2,根据横屏滚动的距离,左侧文本缩小放大
3,鼠标悬浮单张图片时根据悬浮位置发生倾斜效果
横屏滚动函数:
function handlerMouserScroll(event) { //鼠标滑动list横屏滑动效果
//获取滚轮跨距,兼容获取方式
let detail = event.wheelDelta || -event.detail || event.wheelDeltaY
// console.log('detail:'+detail)
/*反向*/
let moveForwardStep = -1
/*正向*/
let moveBackStep = 1
let step = 0
//如果跨步大于0,表明正向跨步,将跨步放大100倍,改变滑动速度,如果跨步小于0,表明反向跨步,将跨步放大500倍,改变滑动速度
step = detail > 0 ? moveForwardStep * 30 : moveBackStep * 30
// console.log('step:'+step)
/*覆盖当前滚动条的位置,单位是像素,叠增或剃减*/
roadMap.value.scrollLeft = roadMap.value.scrollLeft + step
// console.log('roadMap.value.scrollLeft:'+roadMap.value.scrollLeft)
//平滑值(越小越慢,不能小于等于0)
let slipNum = 0.8
//末尾值(越小,则越平稳,越大越仓促)
let endNum = 1
/*递减步伐值*/
let decreasingPaceNum = step
/*速度*/
let paceNum=20;
/*效果一*/
let t1 = setInterval(() => {
if (Math.abs(decreasingPaceNum) < endNum) {
clearInterval(t1)
console.log(roadMap.value.scrollLeft);
// if(roadMap.value.scrollLeft>350){
// goHideTrue.value = true;
// }else{
// goHideTrue.value = false;
// }
return
}
decreasingPaceNum = decreasingPaceNum * slipNum
roadMap.value.scrollLeft = roadMap.value.scrollLeft + decreasingPaceNum
textOpacity.value =1- roadMap.value.scrollLeft/500*0.7;
textScale.value = 1 - roadMap.value.scrollLeft/500*0.25;
}, paceNum)
}
其中在这个函数中下面两句代码实现左侧文本的透明度及大小的变化
textOpacity.value =1- roadMap.value.scrollLeft/500*0.7;
textScale.value = 1 - roadMap.value.scrollLeft/500*0.25;
抖动效果函数:
function shake(event) { //鼠标悬浮抖动效果
event.stopPropagation();
let x=0;
let y=0;
let width = event.currentTarget.offsetWidth;
let height =event.currentTarget.offsetHeight;
if (event.offsetX || event.offsetY) { //适用非Mozilla浏览器
x = event.offsetX;
y = event.offsetY;
} else if (event.layerX || event.layerY) { //兼容Mozilla浏览器
x = event.layerX;
y = event.layerY;
}
if(x<width/2 && y<height/2){
//左上
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(-5deg) rotateY(5deg) scale3d(1, 1, 1)"
},800)
}else if(x<width/2 && y> height/2){
//左下
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(5deg) rotateY(5deg) scale3d(1, 1, 1)"
},800)
}else if(x <width/2 && y == height/2 ){
//左中
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(0deg) rotateY(5deg) scale3d(1, 1, 1)"
},800)
}else if(x == width/2 && y<height/2){
//上中
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(-5deg) rotateY(0deg) scale3d(1, 1, 1)"
},800)
}else if(x > width/2 && y<height/2){
//右上
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(-5deg) rotateY(-5deg) scale3d(1, 1, 1)"
},800)
}else if(x>width/2 && y==height/2){
//右中
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(0deg) rotateY(-5deg) scale3d(1, 1, 1)"
},800)
}else if(x>width/2 && y>height/2){
// 右下
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(5deg) rotateY(-5deg) scale3d(1, 1, 1)"
},800)
}else if(x==width/2 && y>height/2){
//下中
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(5deg) rotateY(0deg) scale3d(1, 1, 1)"
},800)
}
// console.log('width:'+width+'height:'+height+'X:'+x+'Y:'+y);
}
组件完整代码:
<template>
<div class="MAP6">
<img class="p6Bg" src="../../assets/MA/p6Bg.png" alt="">
<div class="p6Text" :style="{
opacity:textOpacity,
transform: 'translate(0,-50%) scale('+textScale+')'
}">
<h1>20<br/> 23</h1>
<p>MILESTONE</p>
</div>
<div class="milestone-center-box" ref='roadMap'>
<div @mousewheel.stop="handlerMouserScroll" @DOMMouseScroll.stop="handlerMouserScroll" ref='roadlist' data-scroll="true" :style="{width:roadlistWidth}" class="wrapper">
<div v-for="(item, index) in roadMapList.arr" @mousemove.stop="shake" ref="roadItem" class="roadmap-item-box" :key="index">
<img @click="jump(item.link)" :src="['http://81.69.18.119:8080'+item.image]"/>
</div>
</div>
</div>
</div>
</template>
<script>
// @ is an alias to /src
import { fetch } from "../../common/http";
import { showToast } from 'vant';
import { ref, reactive, onMounted, onUnmounted,watch } from "vue";
export default {
name: 'Header',
setup (props) {
let roadMapList= reactive({
arr: []
})
let roadMap = ref(null);
let roadlist = ref(null);
let roadItem = ref(null);
let roadlistWidth = ref(0);
let left = 0;
// let goHideTrue = ref(false);
let textOpacity = ref(1);
let textScale = ref(1);
function goLeft(e) { //鼠标拖拽list跟随鼠标滑动效果 (效果被弃,该函数可实现拖拽滑动)
let disX = e.clientX - roadlist.value.offsetLeft;
roadlist.value.onmousemove = e => {
//用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
let left = e.clientX - disX;
if(left < 0 && left> -1541){
//移动当前元素
roadlist.value.style.left = left + "px";
}
};
roadlist.value.onmouseup = e => {
//鼠标弹起来的时候不再移动
roadlist.value.onmousemove = null;
//预防鼠标弹起来后还会循环(即预防鼠标放上去的时候还会移动)
roadlist.value.onmouseup = null;
};
}
function handlerMouserScroll(event) { //鼠标滑动list横屏滑动效果
//获取滚轮跨距,兼容获取方式
let detail = event.wheelDelta || -event.detail || event.wheelDeltaY
// console.log('detail:'+detail)
/*反向*/
let moveForwardStep = -1
/*正向*/
let moveBackStep = 1
let step = 0
//如果跨步大于0,表明正向跨步,将跨步放大100倍,改变滑动速度,如果跨步小于0,表明反向跨步,将跨步放大500倍,改变滑动速度
step = detail > 0 ? moveForwardStep * 30 : moveBackStep * 30
// console.log('step:'+step)
/*覆盖当前滚动条的位置,单位是像素,叠增或剃减*/
roadMap.value.scrollLeft = roadMap.value.scrollLeft + step
// console.log('roadMap.value.scrollLeft:'+roadMap.value.scrollLeft)
//平滑值(越小越慢,不能小于等于0)
let slipNum = 0.8
//末尾值(越小,则越平稳,越大越仓促)
let endNum = 1
/*递减步伐值*/
let decreasingPaceNum = step
/*速度*/
let paceNum=20;
/*效果一*/
let t1 = setInterval(() => {
if (Math.abs(decreasingPaceNum) < endNum) {
clearInterval(t1)
console.log(roadMap.value.scrollLeft);
// if(roadMap.value.scrollLeft>350){
// goHideTrue.value = true;
// }else{
// goHideTrue.value = false;
// }
return
}
decreasingPaceNum = decreasingPaceNum * slipNum
roadMap.value.scrollLeft = roadMap.value.scrollLeft + decreasingPaceNum
textOpacity.value =1- roadMap.value.scrollLeft/500*0.7;
textScale.value = 1 - roadMap.value.scrollLeft/500*0.25;
}, paceNum)
}
function shake(event) { //鼠标悬浮抖动效果
event.stopPropagation();
let x=0;
let y=0;
let width = event.currentTarget.offsetWidth;
let height =event.currentTarget.offsetHeight;
if (event.offsetX || event.offsetY) { //适用非Mozilla浏览器
x = event.offsetX;
y = event.offsetY;
} else if (event.layerX || event.layerY) { //兼容Mozilla浏览器
x = event.layerX;
y = event.layerY;
}
if(x<width/2 && y<height/2){
//左上
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(-5deg) rotateY(5deg) scale3d(1, 1, 1)"
},800)
}else if(x<width/2 && y> height/2){
//左下
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(5deg) rotateY(5deg) scale3d(1, 1, 1)"
},800)
}else if(x <width/2 && y == height/2 ){
//左中
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(0deg) rotateY(5deg) scale3d(1, 1, 1)"
},800)
}else if(x == width/2 && y<height/2){
//上中
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(-5deg) rotateY(0deg) scale3d(1, 1, 1)"
},800)
}else if(x > width/2 && y<height/2){
//右上
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(-5deg) rotateY(-5deg) scale3d(1, 1, 1)"
},800)
}else if(x>width/2 && y==height/2){
//右中
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(0deg) rotateY(-5deg) scale3d(1, 1, 1)"
},800)
}else if(x>width/2 && y>height/2){
// 右下
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(5deg) rotateY(-5deg) scale3d(1, 1, 1)"
},800)
}else if(x==width/2 && y>height/2){
//下中
event.currentTarget.animate({
transform: "perspective(1000px) rotateX(5deg) rotateY(0deg) scale3d(1, 1, 1)"
},800)
}
// console.log('width:'+width+'height:'+height+'X:'+x+'Y:'+y);
}
function getList(){
fetch("url", {}).then(
(res) => {
// console.log(res);
if(res.code == 200){
if(window.innerWidth>1600){
roadlistWidth.value = (406*res.data.length+610)+'px';
}else{
roadlistWidth.value = (360*res.data.length+610)+'px';
}
roadMapList.arr = res.data;
// console.log(roadMapList.arr);
}
},
(err) => {
showToast("网络错误");
}
);
}
function jump(url){
if(url){
window.location.href = url;
}
}
getList();
// watch(() => props.p6GoLeft, (newP6GoLeft,oldP6GoLeft) => {
// //监听
// if(newP6GoLeft){
// // scrollLeft();
// }else if(!newP6GoLeft && oldP6GoLeft){
// // scrollRight();
// }
// })
return {
handlerMouserScroll,
roadMapList,
roadMap,
roadlist,
roadlistWidth,
roadItem,
goLeft,
shake,
// goHideTrue,
textOpacity,
textScale,
jump
}
}
}
</script>
<style>
@import url("../../assets/font/font.css");
.MAP6{
width: 100%;
height: 100%;
background-color: #000;
position: relative;
overflow: hidden;
}
.MAP6 .p6Bg{
width: 100%;
/* height: 100%; */
position: absolute;
left: 0;
bottom: 0;
}
.MAP6 .p6Bg img{
width: 100%;
height: 100%;
}
.MAP6 .p6Text{
width: 273px;
height: 416px;
position: absolute;
top:50%;
left:105px;
transform: translate(0,-50%) scale(1);
color: #fff;
}
.MAP6 .p6Text h1{
font-size: 192px;
font-weight: bolder;
font-style: italic;
font-family: Montserrat-BlackItalic;
line-height: 160px;
margin-left: 40px;
position: absolute;
top:0;
}
.MAP6 .p6Text p{
font-size: 56px;
font-weight: bolder;
font-family: Montserrat-Black;
margin-top: 32px;
position: absolute;
bottom: 0;
}
.milestone-center-box{
width: 100%; /*no*/
height: 496px;
position: absolute;
top:50%;
/* left: 80%; */
transform: translate(0,-50%);
overflow: scroll;
scrollbar-width:none;
-ms-overflow-style:none;
display: flex;
align-items: center;
}
::-webkit-scrollbar{display:none}
.milestone-center-box .wrapper{
/* width: 2981px; */
display: flex;
flex-wrap: nowrap;
position: absolute;
padding-left: 610px;/*no*/
}
.milestone-center-box .wrapper .roadmap-item-box{
width: 360px; /*no*/
/* height: 482px; */
margin-left: 45px;
border-radius: 20px;
will-change: transform;
transition: all 400ms cubic-bezier(0.03, 0.98, 0.52, 0.99) 0s;
transform: perspective(1000px) rotateX(0deg) rotateY(0deg) scale3d(1, 1, 1);
}
.milestone-center-box .wrapper .roadmap-item-box:first-child{
margin-left: 0;
}
.milestone-center-box .wrapper .roadmap-item-box img{
width: 360px; /*no*/
height: 416px;
cursor:pointer;
}
.goLeftAni {
animation: goLeftAni 1s linear 1 forwards;
}
.goRightAni {
animation: goRightAni 1s linear 1 forwards;
}
.goHideAni {
animation: goHideAni 1s linear 1 forwards;
}
.goHShowAni {
animation: goHShowAni 1s linear 1 forwards;
}
@keyframes goLeftAni {
0% {
left: 80%;
}
100% {
left: 50%;
}
}
@keyframes goRightAni {
0% {
left: 50%;
}
100% {
left: 80%;
}
}
@keyframes goHideAni {
0% {
opacity: 1;
transform: translate(0,-50%) scale(1);
}
100% {
opacity: 0.3;
transform: translate(0,-50%) scale(0.75);
}
}
@keyframes goHShowAni {
0% {
opacity: 0.3;
transform: translate(0,-50%) scale(0.75);
}
100% {
opacity: 1;
transform:translate(0,-50%) scale(1);
}
}
@media (max-height:750px){
.MAP6 .p6Text{
height: 418px;
}
.milestone-center-box{
/* width: 1029px; */
height: 434px;
}
.milestone-center-box .wrapper .roadmap-item-box{
width: 313px;
height: 418px;
}
.milestone-center-box .wrapper .roadmap-item-box img{
width: 313px;
height: 418px;
}
}
</style>
二,
动画效果:两边图像根据中间元素的拖拽位置展示
首先左右两张图片元素的定位,
右边图片采用img标签,平铺整个盒子‘mbp4img’,左侧图片以背景图的形式放入div盒子,方便改变左侧盒子的宽度以此实现左侧图片展示部分图像
<div class="mbp4img">
<!-- <div class="imgLeft"></div> -->
<img class="imgRight" src="../../assets/MB/p41.png" alt="">
<div ref='imgLeft' class="imgLeft"></div>
<div @mousedown="goLeft($event)" class="line" ref='line'>
<div class="round">
<img class="goleft" @mousedown="prevent(e)" draggable=“false” src="../../assets/MB/goleft.png" alt="">
<img class="goright" @mousedown="prevent(e)" draggable=“false” src="../../assets/MB/goright.png" alt="">
</div>
</div>
</div>
.mbp4img{
display: inline-block;
margin-top: 2rem;
position: relative;
overflow: hidden;
border-radius: 38px;
}
.mbp4img .imgLeft{
width: 50%;
height: 100%;
background: url('../../assets/MB/p42.png') no-repeat top left;
position: absolute;
top:0;
left: 0;
}
.line{
width: 4px;
height:100%;
background-color: #ff8a00;
border: 1px solid #a96a1e;
position: absolute;
top:0;
left: 50%;
}
.line .round{
width: 48px;
height: 48px;
border-radius: 30px;
background-color: #0e0d0d;
border: 6px solid #ff8a00;
position: absolute;
top:50%;
left:50%;
transform: translate(-50%,-50%);
}
.line .round img{
position: absolute;
top:50%;
transform: translate(0,-50%);
}
.line .round .goleft{
left:4px;
}
.line .round .goright{
right:4px;
}
实现拖拽中间元素改变左边图片展示大小函数:
function goLeft(e) {
console.log(111111)
let disX = e.clientX - line.value.offsetLeft;
document.onmousemove = e => {
//用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
let left = e.clientX - disX;
if(left >=0 && left <=999){
//移动当前元素
line.value.style.left = left + "px";
imgLeft.value.style.width = left + "px";
if(left <=20){
line.value.style.left = 0 + "px";
imgLeft.value.style.width = 0 + "px";
}
if(left >=980){
line.value.style.left = 998 + "px";
imgLeft.value.style.width = 998 + "px";
}
}
};
document.onmouseup = e => {
//鼠标弹起来的时候不再移动
document.onmousemove = null;
//预防鼠标弹起来后还会循环(即预防鼠标放上去的时候还会移动)
document.onmouseup = null;
};
}
组件完整代码:
<template>
<div class="MBP4">
<div class="mbp4Text">
<h1>UNITY3D MODELING</h1>
<p>The powerful 3D modeling engine revolutionizes model creation, editing, and publishing on official<br/>
websites, eliminating the need for expensive industrial software and graphics workstations. </p>
</div>
<div class="mbp4img">
<!-- <div class="imgLeft"></div> -->
<img class="imgRight" src="../../assets/MB/p41.png" alt="">
<div ref='imgLeft' class="imgLeft"></div>
<div @mousedown="goLeft($event)" class="line" ref='line'>
<div class="round">
<img class="goleft" @mousedown="prevent(e)" draggable=“false” src="../../assets/MB/goleft.png" alt="">
<img class="goright" @mousedown="prevent(e)" draggable=“false” src="../../assets/MB/goright.png" alt="">
</div>
</div>
</div>
</div>
</template>
<script>
// @ is an alias to /src
import { ref } from "vue";
export default {
name: 'MBP4',
setup () {
let line = ref(null);
let imgLeft =ref(null);
function goLeft(e) {
console.log(111111)
let disX = e.clientX - line.value.offsetLeft;
document.onmousemove = e => {
//用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
let left = e.clientX - disX;
if(left >=0 && left <=999){
//移动当前元素
line.value.style.left = left + "px";
imgLeft.value.style.width = left + "px";
if(left <=20){
line.value.style.left = 0 + "px";
imgLeft.value.style.width = 0 + "px";
}
if(left >=980){
line.value.style.left = 998 + "px";
imgLeft.value.style.width = 998 + "px";
}
}
};
document.onmouseup = e => {
//鼠标弹起来的时候不再移动
document.onmousemove = null;
//预防鼠标弹起来后还会循环(即预防鼠标放上去的时候还会移动)
document.onmouseup = null;
};
}
function prevent(ev){
var oEvent=ev||event;
if(oEvent.preventDefault){
oEvent.preventDefault();
}else{
oEvent.returnValue=false;
}
}
return {
goLeft,
// goRight,
line,
imgLeft,
prevent
}
}
}
</script>
<style>
@import url("../../assets/font/font.css");
.MBP4{
width: 100%;
height: 100%;
background-color: #000;
border-top: 1px solid transparent;
text-align: center;
overflow: hidden;
}
.mbp4Text{
color: #fff;
text-align: center;
margin-top: 6rem;
}
.mbp4Text h1{
font-size: 48px;
font-weight: bolder;
font-family: Montserrat-Black;
}
.mbp4Text p{
font-size: 20px;
line-height: 35px;
margin-top: 1rem;
font-family: Montserrat-Medium;
}
.mbp4img{
display: inline-block;
margin-top: 2rem;
position: relative;
overflow: hidden;
border-radius: 38px;
}
.mbp4img .imgLeft{
width: 50%;
height: 100%;
background: url('../../assets/MB/p42.png') no-repeat top left;
position: absolute;
top:0;
left: 0;
}
.line{
width: 4px;
height:100%;
background-color: #ff8a00;
border: 1px solid #a96a1e;
position: absolute;
top:0;
left: 50%;
}
.line .round{
width: 48px;
height: 48px;
border-radius: 30px;
background-color: #0e0d0d;
border: 6px solid #ff8a00;
position: absolute;
top:50%;
left:50%;
transform: translate(-50%,-50%);
}
.line .round img{
position: absolute;
top:50%;
transform: translate(0,-50%);
}
.line .round .goleft{
left:4px;
}
.line .round .goright{
right:4px;
}
</style>
三,
动画效果:
1,鼠标在两侧元素区域滑动,两侧元素滑动到中心位置,同时中心位置文案缩小隐藏
2,元素到达中心位置后形成前后关系的图片列表,并且向下滑动鼠标,图片逐渐向下隐藏,后一张图片向前来到第一张的位置,隐藏图片添加到列表最后
3,向上滑动鼠标,列表变成两张图片向两侧分开,并逐渐放大显示中间文案
文档结构:默认隐藏中间的图片列表,显示中间文案及左右图片
<div class="MAP7 page7">
<div class="map7Text" :class="{Map7Zoom1:p7AniGo,Map7Zoom8:!p7AniGo}">
<h1>NEWS</h1>
<p>MetaOil is an innovative platform that provides Web3 business<br/>
solutions for the oil and gas industry on the one hand, and an<br/>
immersive experience for users on the other, building a new<br/>
world where the energy industry meets the digital economy</p>
</div>
<div class="imgsList" data-scroll="true" v-show='imgsListShow' @mousewheel="scrollBottom" @DOMMouseScroll="scrollBottom">
<div v-for="(item, index) in Map7list.arr" :style="styles(index)" ref='map7Item' @click='jump(item.link)' :key="key+index">
<img :src="['http://81.69.18.119:8080'+item.image]" alt="">
<p>{{item.title}}</p>
</div>
</div>
<div class="left" @mousewheel="RLscroll" @DOMMouseScroll="RLscroll" @click='jump(leftObj.obj.link)' v-show='!imgsListShow' :class="{Map7Zoom2:p7AniGo,Map7Zoom5:!p7AniGo}">
<img v-if="leftObj.obj" :src="['http://81.69.18.119:8080'+leftObj.obj.image]" alt="">
<p v-if="leftObj.obj">{{leftObj.obj.title}}</p>
</div>
<div class="right" @mousewheel="RLscroll" @DOMMouseScroll="RLscroll" @click='jump(rightObj.obj.link)' v-show='!imgsListShow' :class="{Map7Zoom3:p7AniGo,Map7Zoom4:!p7AniGo}">
<img v-if="rightObj.obj" :src="['http://81.69.18.119:8080'+rightObj.obj.image]" alt="">
<p v-if="rightObj.obj">{{rightObj.obj.title}}</p>
</div>
</div>
实现:首先使用css3动画写出中间文字缩小隐藏,左右图片向中间滑动重叠的效果
.Map7Zoom1 {
animation: Map7Zoom1 2s linear 1 forwards;
}
@keyframes Map7Zoom1 {
from {
transform: scale(1);
}
to {
transform: scale(0);
}
}
.Map7Zoom2 {
animation: Map7Zoom2 2s linear 1 forwards;
}
@keyframes Map7Zoom2 {
from {
left:-643px;
opacity: 1;
transform: scale(1) translate(0,-50%);
}
to {
left: 237px;
opacity: 0.9;
transform: scale(0.95) translate(0,-59%);
}
}
.Map7Zoom3 {
animation: Map7Zoom3 2s linear 1 forwards;
}
使用js函数控制动画执行时间,p7AniGo为true时动画执行,左右及中间动画执行结束隐藏之前的左右两端图片显示我们之前隐藏的图片列表
function RLscroll(event){
event.stopPropagation();
let detail = event.wheelDelta || -event.detail || event.wheelDeltaY
if(detail<0 ){
p7AniGo.value = true;
setTimeout(function(){
imgsListShow.value =true;
},2000)
}
}
中间图片列表实现鼠标下滑,第一张图片下滑并更新列表的操作
第一张图片下滑之后从图片列表数组中删除(因为dom的渲染机制,数组的最后一个元素在页面最前面所以用pop(),我们获取到图片数组的时候需要先对数组进行翻转,这样数组的最后一位就是原数据的第一位了),删除之后使用unshift将删除的数据放在数组的第一位,这样是实现了数组的更新
然后更新页面列表元素的key值,实现页面的重新渲染
Map7list.arr.pop();
Map7list.arr.unshift(lastItem);
key.value = key.value + 1;
function scrollBottom(event){
//获取滚轮跨距,兼容获取方式
event.stopPropagation();
emit('bottomIsShow', { data: false })
let detail = event.wheelDelta || -event.detail || event.wheelDeltaY
if(detail>0){
p7AniGo.value =false;
imgsListShow.value =false;
}else if(flag){
flag = false;
map7Item.value[Map7list.arr.length-1].animate({
top: 750 +'px'
},1000)
var timer1 = setTimeout(() => {
clearTimeout(timer1);
var lastItem =Map7list.arr[Map7list.arr.length-1];
Map7list.arr.pop();
Map7list.arr.unshift(lastItem);
key.value = key.value + 1;
flag = true
}, 1000);
}
}
上完整组件代码:
<template>
<div class="MAP7 page7">
<div class="map7Text" :class="{Map7Zoom1:p7AniGo,Map7Zoom8:!p7AniGo}">
<h1>NEWS</h1>
<p>MetaOil is an innovative platform that provides Web3 business<br/>
solutions for the oil and gas industry on the one hand, and an<br/>
immersive experience for users on the other, building a new<br/>
world where the energy industry meets the digital economy</p>
</div>
<div class="imgsList" data-scroll="true" v-show='imgsListShow' @mousewheel="scrollBottom" @DOMMouseScroll="scrollBottom">
<div v-for="(item, index) in Map7list.arr" :style="styles(index)" ref='map7Item' @click='jump(item.link)' :key="key+index">
<img :src="['http://81.69.18.119:8080'+item.image]" alt="">
<p>{{item.title}}</p>
</div>
</div>
<div class="left" @mousewheel="RLscroll" @DOMMouseScroll="RLscroll" @click='jump(leftObj.obj.link)' v-show='!imgsListShow' :class="{Map7Zoom2:p7AniGo,Map7Zoom5:!p7AniGo}">
<img v-if="leftObj.obj" :src="['http://81.69.18.119:8080'+leftObj.obj.image]" alt="">
<p v-if="leftObj.obj">{{leftObj.obj.title}}</p>
</div>
<div class="right" @mousewheel="RLscroll" @DOMMouseScroll="RLscroll" @click='jump(rightObj.obj.link)' v-show='!imgsListShow' :class="{Map7Zoom3:p7AniGo,Map7Zoom4:!p7AniGo}">
<img v-if="rightObj.obj" :src="['http://81.69.18.119:8080'+rightObj.obj.image]" alt="">
<p v-if="rightObj.obj">{{rightObj.obj.title}}</p>
</div>
</div>
</template>
<script>
// @ is an alias to /src
import { fetch } from "../../common/http";
import { showToast } from 'vant';
import { ref, reactive, onMounted, onUnmounted,watch } from "vue";
export default {
name: 'Header',
// props: {
// p7AniGo: Boolean,
// },
setup (props, { emit }) {
let map7Item = ref(null);
let flag = true;
let key = ref(0);
let intervalTimer1;
let intervalTimer2;
let scrollBottomIndex = 0;
let imgsListShow = ref(false);
let p7AniGo = ref(false)
let Map7list = reactive({
arr:[]
})
let leftObj = reactive({
obj:{}
});
let rightObj = reactive({
obj:{}
})
// let scrollTopUp = 0;
function styles(index) {
let x = Map7list.arr.length-index;
return {
transform: 'translateY('+-x*30+'px) scale('+(1-x*0.05)+')',
opacity: 1-x*0.05,
}
}
function scrollBottom(event){
//获取滚轮跨距,兼容获取方式
event.stopPropagation();
emit('bottomIsShow', { data: false })
let detail = event.wheelDelta || -event.detail || event.wheelDeltaY
if(detail>0){
p7AniGo.value =false;
imgsListShow.value =false;
}else if(flag){
flag = false;
map7Item.value[Map7list.arr.length-1].animate({
top: 750 +'px'
},1000)
var timer1 = setTimeout(() => {
clearTimeout(timer1);
var lastItem =Map7list.arr[Map7list.arr.length-1];
Map7list.arr.pop();
Map7list.arr.unshift(lastItem);
key.value = key.value + 1;
flag = true
}, 1000);
}
}
function getProjectList(){
fetch("url", {}).then(
(res) => {
if(res.code == 200){
Map7list.arr = res.data.reverse(); //翻转数组
if(Map7list.arr.length>=2){
leftObj.obj = Map7list.arr[Map7list.arr.length-2];
rightObj.obj = Map7list.arr[Map7list.arr.length-1];
}
}
},
(err) => {
showToast("网络错误");
}
);
}
function RLscroll(event){
event.stopPropagation();
let detail = event.wheelDelta || -event.detail || event.wheelDeltaY
if(detail<0 ){
p7AniGo.value = true;
setTimeout(function(){
imgsListShow.value =true;
},2000)
}
}
function jump(url){
if(url){
window.location.href = url;
}
}
getProjectList();
return {
Map7list,
map7Item,
scrollBottom,
styles,
key,
getProjectList,
leftObj,
rightObj,
imgsListShow,
p7AniGo,
RLscroll,
jump,
}
}
}
</script>
<style>
@import url("../../assets/font/font.css");
.MAP7{
width: 100%;
height: 100%;
background-color: #000;
border-top:1px solid transparent;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.map7Text{
color: #fff;
margin-top: 40px;
text-align: center;
}
.map7Text h1{
font-size: 56px;
font-weight: bolder;
font-family: Montserrat-Black;
}
.map7Text p{
font-size: 20px;
line-height: 35px;
margin-top: 80px;
font-family: Montserrat-Regular;
}
.left,.right{
width: 965px;
height: 560px;
position: absolute;
top:50%;
/* bottom:40px; */
transform:scale(1) translate(0,-50%);
margin-top: 40px;
border-radius: 20px;
overflow: hidden;
cursor:pointer;
}
.MAP7 .left{
left: -643px
}
.MAP7 .right{
right: -643px
}
.left img,.right img{
width: 100%;
height: 70.114%;
}
.left p,.right p{
width: 100%;
height: 29.886%;
background-color: #343434;
padding-top: 45px;
padding-left: 40px;
font-size: 36px;
color: #fff;
font-family: Montserrat-Regular;
margin-top: -5px;
}
.imgsList{
width: 67%;
height: 560px;
position: absolute;
top:200px;
left: 50%;
transform: translate( -50%, 0 );
}
.imgsList div{
width: 100%;
/* height: 100%; */
position: absolute;
top:0;
left: 0;
border-radius: 20px;
overflow: hidden;
cursor:pointer;
}
.imgsList div img{
width: 100%;
height: 70.114%;
}
.imgsList div p{
width: 100%;
height: 115px;
background-color: #343434;
/* padding-top: 45px; */
padding-left: 40px;
font-size: 36px;
color: #fff;
display: flex;
align-items: center;
margin-top: -5px;
}
.imgsList .imgOne{
opacity: 0.7;
transform: scale(0.90) translate(0,-75px);
}
.imgsList .imgTwo{
opacity: 0.8;
transform: scale(0.925) translate(0,-50px);
}
.Map7Zoom1 {
animation: Map7Zoom1 2s linear 1 forwards;
}
@keyframes Map7Zoom1 {
from {
transform: scale(1);
}
to {
transform: scale(0);
}
}
.Map7Zoom2 {
animation: Map7Zoom2 2s linear 1 forwards;
}
@keyframes Map7Zoom2 {
from {
left:-643px;
opacity: 1;
transform: scale(1) translate(0,-50%);
}
to {
left: 237px;
opacity: 0.9;
transform: scale(0.95) translate(0,-59%);
}
}
.Map7Zoom3 {
animation: Map7Zoom3 2s linear 1 forwards;
}
@keyframes Map7Zoom3 {
from {
right: -643px;
}
to {
right: 237px;
}
}
/* .Map7Zoom4 {
animation: Map7Zoom4 2s linear 1 2s forwards;
}
@keyframes Map7Zoom4 {
from {
top:187px;
}
to {
top: 750px;
}
} */
.Map7Zoom4 {
animation: Map7Zoom4 2s linear 1 forwards;
}
@keyframes Map7Zoom4 {
from {
right: 237px ;
}
to {
right: -643px;
}
}
.Map7Zoom5 {
animation: Map7Zoom5 2s linear 1 forwards;
}
@keyframes Map7Zoom5 {
from {
left: 237px;
opacity: 0.9;
transform: scale(0.95) translate(0,-59%);
}
to {
left:-643px;
opacity: 1;
transform: scale(1) translate(0,-50%);
}
}
.Map7Zoom8 {
animation: Map7Zoom8 2s linear 1 forwards;
}
@keyframes Map7Zoom8 {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
</style>
4,
动画效果:向下滑动鼠标,外圈正向旋转,内里图标反向旋转,向上滑动鼠标,大圈反向旋转,内里小图标正向旋转
先上文档结构:
<div class="leftImg">
<div class="imgbox" @mousewheel.stop="wheelScrollRotate" @DOMMouseScroll.stop="wheelScrollRotate">
<div ref="rotateBox" :style = "rotateStyle1.obj" id="rotateBox" class="imgborder">
<img src="../../assets/MA/p41.png" alt="">
<img :style = "rotateStyle2.obj" src="../../assets/MA/p42.png" alt="">
<img :style = "rotateStyle2.obj" src="../../assets/MA/p43.png" alt="">
<img :style = "rotateStyle2.obj" src="../../assets/MA/p44.png" alt="">
</div>
<img class="p4icon" src="../../assets/MA/P4icon.png" alt="">
</div>
</div>
css样式,/*no*/不会默认吧px单位改为rem,因为rem计算后的定位在不同分辨率的屏幕下无法做到准确定位,(因为宽高比的不同,rem针对宽做计算)
.MAP4 .p4Con .leftImg{
width: 49.72%;
height: 100%;
display: flex;
align-items: center;
}
.MAP4 .p4Con .leftImg .imgbox{
width: 467px;/*no*/
height: 467px;/*no*/
position: relative;
margin-left: 12.15%;
margin-top: 80px;
display: flex;
align-items: center;
justify-content: center;
}
.MAP4 .p4Con .leftImg .imgbox .imgborder{
width: 467px;/*no*/
height: 467px;/*no*/
position: relative;
transform:rotate(0deg);
}
.MAP4 .p4Con .leftImg .imgbox .p4icon{
position: absolute;
/* top:50%;
left: 50%;
transform: translate(-52%,-51%); */
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img{
position: absolute;
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img:first-child{
width: 467px; /*no*/
height: 467px; /*no*/
top:0;
left: 0;
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img:nth-child(2){
top: 16px; /*no*/
left: 203px; /*no*/
transform:rotate(0deg);
/* transform: translate(-50%,0); */
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img:nth-child(3){
top: 312px; /*no*/
right: 48px; /*no*/
transform:rotate(0deg);
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img:nth-child(4){
top:315px; /*no*/
left:51px; /*no*/
transform:rotate(0deg);
/* transform: translate(0,-40%); */
}
js部分
getDeg计算当前元素以旋转的度数,detail判断鼠标滑动的方向,大于0向上滑动,小于0向下滑动
let flag = true;
function wheelScrollRotate(){
event.stopPropagation();
let detail = event.wheelDelta || -event.detail || event.wheelDeltaY
if(!flag){
return
}
let angle = getDeg();
// console.log(angle);
flag = false
if(detail<0){ //大于0向上,小于0向下
let degree = 0;
var timer1 = setInterval(() =>{
if(degree>=119){
flag = true
clearInterval(timer1);
}
degree += 1;
rotateStyle1.obj.transform = `rotate(${angle+degree}deg)`;
rotateStyle2.obj.transform = `rotate(${-angle-degree}deg)`;
}, 2);
}else{
let degree = 0;
var timer1 = setInterval(() =>{
if(degree>=119){
flag = true
clearInterval(timer1);
}
degree += 1;
rotateStyle1.obj.transform = `rotate(${angle-degree}deg)`;
rotateStyle2.obj.transform = `rotate(${-angle+degree}deg)`;
}, 2);
}
}
function getDeg(){
var el = document.getElementById("rotateBox");
var st = window.getComputedStyle(el, null);
var tr = st.getPropertyValue("-webkit-transform") ||
st.getPropertyValue("-moz-transform") ||
st.getPropertyValue("-ms-transform") ||
st.getPropertyValue("-o-transform") ||
st.getPropertyValue("transform") ||
"FAIL";
var values = tr.split('(')[1].split(')')[0].split(',');
var a = values[0];
var b = values[1];
var c = values[2];
var d = values[3];
var scale = Math.sqrt(a * a + b * b);
var sin = b / scale;
var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
return angle
}
完整的组件代码:
<template>
<div class="MAP4">
<img class="Map4Bg" src="../../assets/MA/p4bg.png" alt="">
<div class="p4Con">
<div class="leftImg">
<div class="imgbox" @mousewheel.stop="wheelScrollRotate" @DOMMouseScroll.stop="wheelScrollRotate">
<div ref="rotateBox" :style = "rotateStyle1.obj" id="rotateBox" class="imgborder">
<img src="../../assets/MA/p41.png" alt="">
<img :style = "rotateStyle2.obj" src="../../assets/MA/p42.png" alt="">
<img :style = "rotateStyle2.obj" src="../../assets/MA/p43.png" alt="">
<img :style = "rotateStyle2.obj" src="../../assets/MA/p44.png" alt="">
</div>
<img class="p4icon" src="../../assets/MA/P4icon.png" alt="">
</div>
</div>
<div class="rightText">
<h1>CARBON TRADING</h1>
<p>
MetaOil will use blockchain technology to establish a<br/>
carbon trading platform, convert carbon emissions of<br/>
oil and gas companies into tradable carbon credits,<br/>
and provide them with offsets and trading services.
</p>
</div>
</div>
</div>
</template>
<script>
// @ is an alias to /src
import { ref, reactive, onMounted, onUnmounted } from "vue";
export default {
name: 'Header',
props: {
p4GoUp: Boolean,
},
setup(){
let rotateStyle1 = reactive({
obj: {
transform: 'rotate(0deg)',
}
})
let rotateStyle2 = reactive({
obj: {
transform: 'rotate(0deg)',
}
})
let flag = true;
function wheelScrollRotate(){
event.stopPropagation();
let detail = event.wheelDelta || -event.detail || event.wheelDeltaY
if(!flag){
return
}
let angle = getDeg();
// console.log(angle);
flag = false
if(detail<0){ //大于0向上,小于0向下
let degree = 0;
var timer1 = setInterval(() =>{
if(degree>=119){
flag = true
clearInterval(timer1);
}
degree += 1;
rotateStyle1.obj.transform = `rotate(${angle+degree}deg)`;
rotateStyle2.obj.transform = `rotate(${-angle-degree}deg)`;
}, 2);
}else{
let degree = 0;
var timer1 = setInterval(() =>{
if(degree>=119){
flag = true
clearInterval(timer1);
}
degree += 1;
rotateStyle1.obj.transform = `rotate(${angle-degree}deg)`;
rotateStyle2.obj.transform = `rotate(${-angle+degree}deg)`;
}, 2);
}
}
function getDeg(){
var el = document.getElementById("rotateBox");
var st = window.getComputedStyle(el, null);
var tr = st.getPropertyValue("-webkit-transform") ||
st.getPropertyValue("-moz-transform") ||
st.getPropertyValue("-ms-transform") ||
st.getPropertyValue("-o-transform") ||
st.getPropertyValue("transform") ||
"FAIL";
var values = tr.split('(')[1].split(')')[0].split(',');
var a = values[0];
var b = values[1];
var c = values[2];
var d = values[3];
var scale = Math.sqrt(a * a + b * b);
var sin = b / scale;
var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
return angle
}
return{
wheelScrollRotate,
rotateStyle1,
rotateStyle2
}
}
}
</script>
<style>
@import url("../../assets/font/font.css");
.MAP4{
width: 100%;
height: 100%;
position: relative;
background-color: #000;
}
.MAP4 .Map4Bg{
width: 100%;
height: 100%;
}
.MAP4 .Map4Bg img{
width: 100%;
/* height: 100%; */
}
.MAP4 .p4Con{
width: 100%;
height: 100%;
position: absolute;
top:0;
left: 0;
display: flex;
align-items: center;
}
.MAP4 .p4Con .leftImg{
width: 49.72%;
height: 100%;
display: flex;
align-items: center;
}
.MAP4 .p4Con .leftImg .imgbox{
width: 467px;/*no*/
height: 467px;/*no*/
position: relative;
margin-left: 12.15%;
margin-top: 80px;
display: flex;
align-items: center;
justify-content: center;
}
.MAP4 .p4Con .leftImg .imgbox .imgborder{
width: 467px;/*no*/
height: 467px;/*no*/
position: relative;
transform:rotate(0deg);
}
.MAP4 .p4Con .leftImg .imgbox .p4icon{
position: absolute;
/* top:50%;
left: 50%;
transform: translate(-52%,-51%); */
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img{
position: absolute;
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img:first-child{
width: 467px; /*no*/
height: 467px; /*no*/
top:0;
left: 0;
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img:nth-child(2){
top: 16px; /*no*/
left: 203px; /*no*/
transform:rotate(0deg);
/* transform: translate(-50%,0); */
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img:nth-child(3){
top: 312px; /*no*/
right: 48px; /*no*/
transform:rotate(0deg);
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img:nth-child(4){
top:315px; /*no*/
left:51px; /*no*/
transform:rotate(0deg);
/* transform: translate(0,-40%); */
}
.MAP4 .p4Con .rightText{
width: 724px;
color: #fff;
text-align: left;
margin-top: 80px;
}
.MAP4 .p4Con .rightText h1{
font-size: 56px;
font-weight: bolder;
font-family: Montserrat-Black;
}
.MAP4 .p4Con .rightText p{
font-size: 20px;
margin-top: 67px;
line-height: 40px;
font-family: Montserrat-Medium;
}
@media (min-width:2880px){
.MAP4 .p4Con .leftImg .imgbox{
width: 934px;/*no*/
height: 934px;/*no*/
}
.MAP4 .p4Con .leftImg .imgbox .imgborder{
width: 934px;/*no*/
height: 934px;/*no*/
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img:first-child{
width: 934px; /*no*/
height: 934px; /*no*/
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img:nth-child(2){
top: 32px; /*no*/
left: 406px; /*no*/
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img:nth-child(3){
top: 624px; /*no*/
right: 96px; /*no*/
transform:rotate(0deg);
}
.MAP4 .p4Con .leftImg .imgbox .imgborder img:nth-child(4){
top:750px; /*no*/
left:750px; /*no*/
transform:rotate(0deg);
/* transform: translate(0,-40%); */
}
}
</style>
5,
纯纯的css3动画,元素的浮动,背景图和眼睛图的放大效果
眼镜图的放大效果,之所以用背景图,因为发现img标签在vue3.0的项目下无法放大到超出屏幕宽高
.MB1ani {
animation: MB1ani 1.5s linear 1 forwards;
}
@keyframes MB1ani {
0% {
background-size: 1440px 900px;
background-position:50% 30%;
}
100% {
background-size: 4320px 5400px;
background-position:50% 28%;
display: none;
}
}
蓝色背景图的放大
.MB1Animation2 {
animation: MB1Animation2 0.3s linear 1 forwards;
}
@keyframes MB1Animation2 {
0% {
width: 1008px;
height: 441px;
top:135px;
left:216px;
}
100% {
width: 100%;
height: 100%;
left:0px;
top:55px;
}
}
文字的向上效果
.MB1Animation4 {
animation: MB1Animation4 1s linear 1 forwards;
}
@keyframes MB1Animation4 {
0% {
top: 464px;
}
100% {
top: -200px;
}
}
元素的悬浮效果
.MB1Animation5 {
animation: MB1Animation5 2.5s linear infinite;
}
@keyframes MB1Animation5 {
0% {
top: 155px;
left: 140px;
}
50% {
top: 163px;
left: 155px;
}
100% {
top: 155px;
left: 140px;
}
}
完整组件代码:
<template>
<div class="MBP1">
<div class="MBP1Box ">
<img src="../../assets/MB/MBP1bg.png" alt="" class="MBP1bg" :class="{MB1Animation2:p1animation}">
<div class="yanjing" :class="{MB1ani:p1animation}"></div>
</div>
<div class="suspension">
<img :class="{MB1Animation5:!p1animation,MB1Animation9:p1animation}" src="../../assets/MB/mbp11.png" alt="">
<img :class="{MB1Animation6:!p1animation,MB1Animation10:p1animation}" src="../../assets/MB/mbp12.png" alt="">
<img :class="{MB1Animation7:!p1animation,MB1Animation11:p1animation}" src="../../assets/MB/mbp13.png" alt="">
<img :class="{MB1Animation8:!p1animation,MB1Animation12:p1animation}" src="../../assets/MB/mbp14.png" alt="">
</div>
<div class="MBP1text" :class="{MB1Animation4:p1animation}">
<h1>SOLUTIONS & SERVICES</h1>
<P>MetaOil will provide various solutions and services to oil and gas companies, <br/>
including technical applications such as VR/AR, NFT, GameFi, carbon credit trading <br/>
and blockchain, as well as training and consulting services.</P>
</div>
</div>
</template>
<script>
// @ is an alias to /src
export default {
name: 'MBP1',
props: {
p1animation: Boolean
},
}
</script>
<style>
@import url("../../assets/font/font.css");
.MBP1{
width: 100%;
height: 100%;
overflow: hidden;
background-color: #000;
}
.MBP1Box{
width: 100%;
height: 100%;
margin: 0 auto;
position: relative;
}
.MBP1bg{
width: 1008px;
height: 441px;
position: absolute;
top:55px;
left:216px;
}
.yanjing{
width: 100%;
height: 100%;
position: absolute;
top:0px;
left:0px;
background: url(../../assets/MB/yanjing.png) no-repeat;
background-position:50% 38%;
background-size: 100% 100%;
}
.suspension{
width: 100%;
height: 900px;
position: absolute;
top:0;
left: 0;
}
.suspension img:first-child{
position: absolute;
top: 155px;
left: 140px;
}
.suspension img:nth-child(2){
position: absolute;
top: 172px;
right: 80px;
}
.suspension img:nth-child(3){
position: absolute;
left: 127px;
bottom: 240px;
}
.suspension img:nth-child(4){
position: absolute;
right:182px ;
bottom: 368px;
}
.MBP1text{
width: 100%;
color: #fff;
text-align: center;
position: absolute;
top: 464px;
}
.MBP1text h1{
font-size: 56px;
font-weight: bolder;
font-family: Montserrat-Black;
}
.MBP1text p{
font-size: 20px;
margin-top: 20px;
line-height: 40px;
font-family: Montserrat-Medium;
}
.MB1ani {
animation: MB1ani 1.5s linear 1 forwards;
}
@keyframes MB1ani {
0% {
background-size: 1440px 900px;
background-position:50% 30%;
}
100% {
background-size: 4320px 5400px;
background-position:50% 28%;
display: none;
}
}
.MB1Animation2 {
animation: MB1Animation2 0.3s linear 1 forwards;
}
@keyframes MB1Animation2 {
0% {
width: 1008px;
height: 441px;
top:135px;
left:216px;
}
100% {
width: 100%;
height: 100%;
left:0px;
top:55px;
}
}
.MB1Animation4 {
animation: MB1Animation4 1s linear 1 forwards;
}
@keyframes MB1Animation4 {
0% {
top: 464px;
}
100% {
top: -200px;
}
}
.MB1Animation5 {
animation: MB1Animation5 2.5s linear infinite;
}
@keyframes MB1Animation5 {
0% {
top: 155px;
left: 140px;
}
50% {
top: 163px;
left: 155px;
}
100% {
top: 155px;
left: 140px;
}
}
.MB1Animation6 {
animation: MB1Animation6 2.5s linear infinite;
}
@keyframes MB1Animation6 {
0% {
top: 172px;
right: 80px;
}
50% {
top: 185px;
right: 95px;
}
100% {
top: 172px;
right: 80px;
}
}
.MB1Animation7 {
animation: MB1Animation7 2.5s linear infinite;
}
@keyframes MB1Animation7 {
0% {
left: 127px;
bottom: 240px;
}
50% {
left: 135px;
bottom: 255px;
}
100% {
left: 127px;
bottom: 240px;
}
}
.MB1Animation8 {
animation: MB1Animation8 2.5s linear infinite;
}
@keyframes MB1Animation8 {
0% {
right:182px ;
bottom: 368px;
}
50% {
right:190px ;
bottom: 383px;
}
100% {
right:182px ;
bottom: 368px;
}
}
.MB1Animation9 {
animation: MB1Animation9 2s linear 1 forwards;
}
@keyframes MB1Animation9 {
0% {
top: 155px;
left: 140px;
}
100% {
top: -200px;
left: -200px;
}
}
.MB1Animation10 {
animation: MB1Animation10 2s linear 1 forwards;
}
@keyframes MB1Animation10 {
0% {
top: 172px;
right: 80px;
}
100% {
top: -152px;
right: -186px;
}
}
.MB1Animation11 {
animation: MB1Animation11 2s linear 1 forwards;
}
@keyframes MB1Animation11 {
0% {
left: 127px;
bottom: 123px;
}
100% {
left: -166px;
bottom: -196px;
}
}
.MB1Animation12 {
animation: MB1Animation12 2s linear 1 forwards;
}
@keyframes MB1Animation12 {
0% {
right:182px ;
bottom: 249px;
}
100% {
right:-147px ;
bottom: -142px;
}
}
</style>