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

1、效果图

效果图如下:

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布局中全局引入组件

到此这篇关于antd项目如何实现彩蛋效果的文章就介绍到这了,更多相关antd彩蛋内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

antd项目实现彩蛋效果的详细代码的更多相关文章

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

    这篇文章主要介绍了antd项目如何实现彩蛋效果,首先在components目录下创建Transform目录,包括index.css、index.js,index.js是主要的逻辑代码,下面对代码进行分析,需要的朋友可以参考下

  2. 手把手教你从零开始react+antd搭建项目

    本文将从最基础的项目搭建开始讲起,做一个基于react和antd的后台管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. 基于 antd pro 的短信验证码登录功能(流程分析)

    这篇文章主要介绍了基于 antd pro 的短信验证码登录功能(流程分析),本文通过实例代码流程分析给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

  4. react配合antd组件实现的管理系统示例代码

    这篇文章主要介绍了react配合antd组件实现的管理系统示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. React+Antd 实现可增删改表格的示例

    这篇文章主要介绍了React+Antd实现可增删改表格的示例,帮助大家更好的理解和学习使用React,感兴趣的朋友可以了解下

  6. 快速修改antd vue单个组件的默认样式

    这篇文章主要介绍了快速修改antd vue单个组件的默认样式方式,具有很好的参考价值,希望对大家有所帮助。

  7. 在react项目中使用antd的form组件,动态设置input框的值

    这篇文章主要介绍了在react项目中使用antd的form组件,动态设置input框的值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  8. 解决React在安装antd之后出现的Can't resolve './locale'问题(推荐)

    这篇文章主要介绍了解决React在安装antd之后出现的Can't resolve './locale'问题,本文给大家分享解决方案,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  9. webpack+react+antd脚手架优化的方法

    本篇文章主要介绍了webpack+react+antd脚手架优化的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. React引入antd-mobile+postcss搭建移动端

    本文给大家分享React引入antd-mobile+postcss搭建移动端的详细流程,文末给大家分享我的一些经验记录使用antd-mobile时发现我之前配置的postcss失效了,防止大家踩坑,特此把解决方案分享到脚本之家平台,需要的朋友参考下吧

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部