网络编程
位置:首页>> 网络编程>> JavaScript>> antd项目实现彩蛋效果的详细代码

antd项目实现彩蛋效果的详细代码

作者:小小愿望  发布时间:2023-09-14 12:51:20 

标签:antd,彩蛋

马上就要过节了,想把自己的项目搞得酷炫一些,对整个网站的按钮添加图标、飘花效果、首屏大图展示、顶部导航背景图,于是就写了这一遍文字,如有兴趣的小伙伴们可以一起学习进步,仅供参考。

1、效果图

效果图如下:

antd项目实现彩蛋效果的详细代码

2、首先在components目录下创建Transform目录,包括index.css、index.js

index.css主要定义了几种漂浮时的动画轨迹

/* index.css */
.animation1 {
 display: inline-block;
 position: fixed;
 z-index: 2000;
 opacity: 0;
 top: -40px;
 left: -40px;
 animation: animation1 8s linear infinite;
}

.animation2 {
 display: inline-block;
 position: fixed;
 z-index: 2000;
 opacity: 0;
 top: -40px;
 left: -40px;
 animation: animation2 9s 1s linear infinite;
}

.animation3 {
 display: inline-block;
 position: fixed;
 z-index: 2000;
 opacity: 0;
 top: -40px;
 left: -40px;
 animation: animation3 9s linear infinite;
}

.animation4 {
 display: inline-block;
 position: fixed;
 z-index: 2000;
 opacity: 0;
 top: -40px;
 left: -40px;
 animation: animation4 9s 2s linear infinite;
}

.animation5 {
 display: inline-block;
 position: fixed;
 z-index: 2000;
 opacity: 0;
 top: -40px;
 left: -40px;
 animation: animation5 9s 1s linear infinite;
}

.animation6 {
 display: inline-block;
 position: fixed;
 z-index: 2000;
 opacity: 0;
 top: -40px;
 left: -40px;
 animation: animation6 9s 3s linear infinite;
}

.animation7 {
 display: inline-block;
 position: fixed;
 z-index: 2000;
 opacity: 0;
 top: -40px;
 left: -40px;
 animation: animation7 8s linear infinite;
}

.animation8 {
 display: inline-block;
 position: fixed;
 z-index: 2000;
 opacity: 0;
 top: -40px;
 right: -200px;
 animation: animation8 10s linear infinite;
}

@keyframes animation1 {
 0% {
   top: 50%;
   left: -80px;
   opacity: 0;
 }

90% {
   opacity: 1;
 }

100% {
   top: 100%;
   left: 20%;
   opacity: 0;
 }
}

@keyframes animation2 {
 0% {
   top: 80px;
   left: -80px;
   opacity: 0;
 }

90% {
   opacity: 1;
 }

100% {
   top: 100%;
   left: 50%;
   opacity: 0;
 }
}

@keyframes animation3 {
 0% {
   top: 30%;
   left: 20%;
   opacity: 0;
 }

90% {
   opacity: 1;
 }

100% {
   top: 110%;
   left: 75%;
   opacity: 0;
 }
}

@keyframes animation4 {
 0% {
   top: -80px;
   left: -80px;
   opacity: 0;
 }

90% {
   opacity: 1;
 }

100% {
   top: 101%;
   left: 80%;
   opacity: 0;
 }
}

@keyframes animation5 {
 0% {
   top: 10%;
   left: 40%;
   opacity: 0;
 }

90% {
   opacity: 1;
 }

100% {
   top: 100%;
   left: 120%;
   opacity: 0;
 }
}

@keyframes animation6 {
 0% {
   top: -80px;
   left: 50%;
   opacity: 0;
 }

90% {
   opacity: 1;
 }

100% {
   top: 100%;
   left: 110%;
   opacity: 0;
 }
}

@keyframes animation7 {
 0% {
   top: -80px;
   left: 70%;
   opacity: 0;
 }

90% {
   opacity: 1;
 }

100% {
   top: 50%;
   left: 110%;
   opacity: 0;
 }
}
@keyframes animation8 {
 0% {
   top: -75px;
   right: -200px;
   opacity: 0;
   transform: rotate(0)
 }

50% {
   transform: rotate(-30deg)
 }

90% {
   opacity: 1;
 }

100% {
   top: 100%;
   right: 100%;
   transform: rotate(0);
   opacity: 0;
 }
}
:global .switchStyle {
 z-index: 31;
}

.shadeWrapper {
 z-index: 1050;
 position: fixed;
 top: 0;
 left: 200px;
 right: 0;
 bottom: 0;
 background: rgba(0, 0, 0, 0.3);
 display: flex;
 justify-content: center;
 align-items: center;

}
.shadeWrapper .shadeClose {
 cursor: pointer;
 font-size: 30px;
 position: absolute;
 right: 30px;
 top: 30px;
 color: #fff;
}

index.js是主要的逻辑代码,下面对代码进行分析,完整代码如下

  • 进入页面调用 this.getTableList()  方法,获取展示的图片列表,包括btn(按钮)、burst(首图)、float(漂浮)、header(顶部);

  • 紧接着调用 this.initStyle() 方法,首先对列表进行循环,选择出当前时间在开始时间、结束时间之间的一条数据,然后再根据showoption对展示位置进行判断,并添置flag标志;

  • 接下来调用 this.loadStyleString(sty) ,传入处理后的样式字符串,创建style标签,添加到head中。

对于漂浮的特效,由于只定义了七种轨迹,所以最多上传七张图片,initList(data, cb) 方法进行了处理,如果不够七张,则会递归重复传入数组,超过七张后截取前七张,然后回调。

对于首屏大图,一天内只出现一次,关闭时会同时设置localStorage的有效期,设置有效期一天,这样就可以判断当前日期是否和localStorage中存的一样啦。

顶部的开启、关闭特效只对float(漂浮)做了控制,有效期为七天,超时会重新显示。

// index.js
import React, { PureComponent } from 'react';
import { Switch } from 'antd';
import { CloseCircleOutlined } from '@ant-design/icons';
import './index.css';
import moment from 'moment';
Storage.prototype.setExpire = (key, value, expire) => {
 let obj = {
   data: value,
   time: Date.now(),
   expire: expire,
 };
 //localStorage 设置的值不能为对象,转为json字符串
 localStorage.setItem(key, JSON.stringify(obj));
};
Storage.prototype.getExpire = (key) => {
 let val = localStorage.getItem(key);
 if (!val) {
   return val;
 }
 val = JSON.parse(val);
 if (Date.now() - val.time > val.expire) {
   localStorage.removeItem(key);
   return null;
 }
 return val.data;
};
export default class Transform extends PureComponent {
 constructor(props) {
   super(props);
   let storage = localStorage.getExpire(`floatFlag`);
   if (storage == 'false' || storage == false) {
     storage = false;
   } else {
     storage = true;
   }
   this.state = {
     showBurst: false, // burst
     pathBurst: '', // burst path
     timeBurst: '', // burst time
     showFloat: false,
     showBtn: false,
     floatFlag: storage,
     floatList: [],
   };
 }

componentDidMount() {
   this.getTableList();
 }
 // 获取七条数据
 initList(data, cb) {
   if (data && data.length < 7) {
     let dt = data.concat(data);
     this.initList(dt, cb);
   } else {
     cb(data.slice(0, 7));
   }
 }
 // 获取列表
 getTableList() {
   let list = [
     {
       showoption: 'btn',
       starttime: '2022-09-03',
       endtime: '2023-09-03',
       imagaddress: [
         {
           path: 'https://img-blog.csdnimg.cn/3e93fe58b6444c2c8165e85756118888.png',
         },
       ],
     },
     {
       showoption: 'burst',
       starttime: '2022-09-03',
       endtime: '2023-09-03',
       imagaddress: [
         {
           path: 'https://img-blog.csdnimg.cn/a1c4ddc6b73b48c5a88512eba3a907fa.jpeg',
         },
       ],
     },
     {
       showoption: 'float',
       starttime: '2022-09-03',
       endtime: '2023-09-03',
       imagaddress: [
         {
           path: 'https://img-blog.csdnimg.cn/3e93fe58b6444c2c8165e85756118888.png',
         },
         {
           path: 'https://img-blog.csdnimg.cn/3e93fe58b6444c2c8165e85756118888.png',
         },
       ],
     },
     {
       showoption: 'header',
       starttime: '2022-09-03',
       endtime: '2023-09-03',
       imagaddress: [
         {
           path: 'https://img-blog.csdnimg.cn/a1c4ddc6b73b48c5a88512eba3a907fa.jpeg',
         },
       ],
     },
   ];
   this.setState(
     {
       tableList: list,
     },
     () => {
       this.initStyle();
     },
   );
 }
 add0(m) {
   return m < 10 ? '0' + m : m;
 }
 initStyle() {
   try {
     let tableList = JSON.parse(JSON.stringify(this.state.tableList));
     let resDt = [];
     let time = new Date();
     var y = time.getFullYear();
     var m = time.getMonth() + 1;
     var d = time.getDate();
     var H = time.getHours();
     var FEN = time.getMinutes();
     var Miao = time.getSeconds();
     let newDe = moment(
       `${y}-${this.add0(m)}-${this.add0(d)} ${this.add0(H)}:${this.add0(FEN)}:${this.add0(Miao)}`,
     ).format('YYYY-MM-DD HH:mm:ss');
     for (let index = 0; index < tableList.length; index++) {
       const element = tableList[index];
       let strDe = moment(`${element.starttime} 00:00:00`).format('YYYY-MM-DD HH:mm:ss');
       let endDe = moment(`${element.endtime} 23:59:59`).format('YYYY-MM-DD HH:mm:ss');
       if (moment(strDe).isBefore(moment(newDe)) && moment(newDe).isBefore(moment(endDe))) {
         resDt.push(element);
         // break;
       }
     }
     if (resDt && resDt.length > 0) {
       for (let idx = 0; idx < resDt.length; idx++) {
         const element = resDt[idx];
         if (element.showoption == 'float') {
           let str = element.imagaddress;
           let list = [];
           this.initList(str, (dt) => {
             list = dt;
           });
           this.setState({
             showFloat: true,
             showBtn: true,
             floatList: list,
           });
         } else if (element.showoption == 'btn') {
           let strBtn = element.imagaddress[0].path;
           let sty = `
             .ant-btn::before {
                 content: " ";
                 display: block;
                 background: url(${strBtn}) no-repeat!important;
                 background-size: 20px !important;
                 height: 100%;
                 width: 100%;
                 position: absolute;
                 top: -10px;
                 left: -10px;
                 opacity: 1;
             }
             `;
           let sty2 = `
             .ant-btn::before {
                 content: " ";
                 display: block;
                 background: transparent!important;
                 background-size: 20px !important;
                 height: 100%;
                 width: 100%;
                 position: absolute;
                 top: -10px;
                 left: -10px;
                 opacity: 1;
             }
             `;
           this.loadStyleString(sty);
         } else if (element.showoption == 'burst') {
           let tmZl = `${y}-${this.add0(m)}-${this.add0(d)}`;
           let flag = true;
           if (localStorage.getExpire(`timeBurstLocal`) == `${tmZl}`) {
             flag = false;
           }
           this.setState({
             showBurst: flag,
             pathBurst: element.imagaddress[0].path,
             timeBurst: tmZl,
           });
         } else if (element.showoption == 'header') {
           let strH = element.imagaddress[0].path;
           let styH = `
             .ant-pro-global-header {
               background-image: url(${strH});
               background-repeat: no-repeat;
               background-size: cover;
               // opacity: 0.8;
             }
             `;
           this.loadStyleString(styH);
         }
       }
     } else {
       this.setState({
         showFloat: false,
         showBtn: false,
         floatFlag: false,
         floatList: [],
       });
     }
   } catch (error) {
     this.setState({
       showFloat: false,
       showBtn: false,
       floatFlag: false,
       floatList: [],
     });
   }
 }
 loadStyleString(css) {
   var style = document.createElement('style');
   style.type = 'text/css';
   try {
     style.appendChild(document.createTextNode(css));
   } catch (ex) {
     style.styleSheet.cssText = css; //兼容IE
   }
   var head = document.getElementsByTagName('head')[0];
   head.appendChild(style);
 }
 // burst关闭
 CloseBurst() {
   this.setState(
     {
       showBurst: false,
       timeBurstLocal: this.state.timeBurst,
     },
     () => {
       // 有效期两天
       localStorage.setExpire(`timeBurstLocal`, `${this.state.timeBurstLocal}`, 86400000 * 2);
     },
   );
 }
 // 调用示例
 // loadStyleString("body{background-color:red}");
 selectHtml() {
   if (this.state.showFloat && this.state.floatFlag) {
     return (
       <React.Fragment>
         {this.state.floatList
           ? this.state.floatList.map((item, index) => {
               let width = Math.round(Math.random() * 20 + 30);
               return (
                 <div key={index} className={`animation${index}`}>
                   <img width={width} src={item.path} />
                 </div>
               );
             })
           : ''}
       </React.Fragment>
     );
   } else {
     return null;
   }
 }
 // 调用示例
 selectHtmlBurst() {
   var tempHeightRight = document.documentElement.clientHeight - 100;
   if (this.state.showBurst && this.state.pathBurst) {
     return (
       <React.Fragment>
         <div
           onClick={() => {
             this.CloseBurst();
           }}
           className="shadeWrapper"
           style={{ cursor: 'pointer' }}
         >
           <div
             onClick={() => {
               this.CloseBurst();
             }}
             className="shadeClose"
           >
             <CloseCircleOutlined />
           </div>
           <div>
             <img style={{ maxHeight: tempHeightRight }} src={this.state.pathBurst} />
           </div>
         </div>
       </React.Fragment>
     );
   } else {
     return null;
   }
 }
 // 开启/关闭特效
 switchCheck(e) {
   // 有效期七天
   localStorage.setExpire(`floatFlag`, e, 86400000 * 7);
   this.setState(
     {
       floatFlag: e,
     },
     () => {
       console.log('e', e);
       // this.initStyle();
     },
   );
 }
 render() {
   return (
     <React.Fragment>
       {this.state.showBtn ? (
         <div
           style={{
             display: 'inline-block',
             position: 'fixed',
             top: '10px',
             right: '300px',
             zIndex: '31',
           }}
         >
           <Switch
             checkedChildren="关闭特效"
             unCheckedChildren="开启特效"
             checked={this.state.floatFlag}
             onChange={(e) => this.switchCheck(e)}
           />
         </div>
       ) : null}
       {this.selectHtmlBurst()}
       {this.selectHtml()}
     </React.Fragment>
   );
 }
}

3、全局引入

在layout布局中全局引入组件

来源:https://juejin.cn/post/7140658007599218695

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com