七、全屏粒子特效

news2024/9/23 11:16:28

简介

给页面添加粒子光影特效。欢迎访问个人的简历网站预览效果

本章涉及修改与新增的文件:main.tsApp.vueutils
在这里插入图片描述

一、安装插件

  1. 安装 vue3-particles tsparticles插件 详细文档查看 tsParticles 官网
npm i vue3-particles

npm i tsparticles
  1. 创建配置文件 options.ts
// 在 utils 文件夹中 创建options.ts
export const options = {
  "fullScreen": {
    "zIndex": 1
  },
  "particles": {
    "bounce": {
      "horizontal": {
        "random": {
          "enable": false,
          "minimumValue": 0.1
        },
        "value": 1
      },
      "vertical": {
        "random": {
          "enable": false,
          "minimumValue": 0.1
        },
        "value": 1
      }
    },
    "collisions": {
      "absorb": {
        "speed": 2
      },
      "bounce": {
        "horizontal": {
          "random": {
            "enable": false,
            "minimumValue": 0.1
          },
          "value": 1
        },
        "vertical": {
          "random": {
            "enable": false,
            "minimumValue": 0.1
          },
          "value": 1
        }
      },
      "enable": false,
      "maxSpeed": 50,
      "mode": "bounce",
      "overlap": {
        "enable": false,
        "retries": 0
      }
    },
    "color": {
      "value": "#F29927",
    },
    "groups": {},
    "move": {
      "angle": {
        "offset": 0,
        "value": 50
      },
      "attract": {
        "distance": 200,
        "enable": false,
        "rotate": {
          "x": 3000,
          "y": 3000
        }
      },
      "center": {
        "x": 50,
        "y": 50,
        "mode": "percent",
        "radius": 0
      },
      "decay": 0,
      "distance": {},
      "direction": "none",
      "drift": 0,
      "enable": true,
      "gravity": {
        "acceleration": 9.81,
        "enable": false,
        "inverse": false,
        "maxSpeed": 50
      },
      "path": {
        "clamp": true,
        "delay": {
          "random": {
            "enable": false,
            "minimumValue": 0
          },
          "value": 0
        },
        "enable": false,
        "options": {}
      },
      "outModes": {
        "default": "out",
        "bottom": "out",
        "left": "out",
        "right": "out",
        "top": "out"
      },
      "random": false,
      "size": false,
      "speed": 2,
      "spin": {
        "acceleration": 0,
        "enable": false
      },
      "straight": false,
      "trail": {
        "enable": false,
        "length": 10,
        "fill": {}
      },
      "vibrate": false,
      "warp": false
    },
    "number": {
      "density": {
        "enable": true,
        "width": 1920,
        "height": 1080
      },
      "limit": 0,
      "value": 50
    },
    "opacity": {
      "random": {
        "enable": true,
        "minimumValue": 0.5
      },
      "value": {
        "min": 0.3,
        "max": 1
      },
      "animation": {
        "count": 0,
        "enable": true,
        "speed": 0.5,
        "decay": 0,
        "delay": 0,
        "sync": false,
        "mode": "auto",
        "startValue": "random",
        "destroy": "none",
        "minimumValue": 0.3
      }
    },
    "shape": {
      "close": true,
      "fill": true,
      "options": {},
      "type": "circle"
    },
    "size": {
      "random": {
        "enable": true,
        "minimumValue": 1
      },
      "value": {
        "min": 1,
        "max": 3
      },
      "animation": {
        "count": 0,
        "enable": true,
        "speed": 3,
        "decay": 0,
        "delay": 0,
        "sync": false,
        "mode": "auto",
        "startValue": "random",
        "destroy": "none",
        "minimumValue": 1
      }
    },
    "stroke": {
      "width": 0
    },
    "zIndex": {
      "random": {
        "enable": false,
        "minimumValue": 0
      },
      "value": 0,
      "opacityRate": 1,
      "sizeRate": 1,
      "velocityRate": 1
    },
    "destroy": {
      "bounds": {},
      "mode": "none",
      "split": {
        "count": 1,
        "factor": {
          "random": {
            "enable": false,
            "minimumValue": 0
          },
          "value": 3
        },
        "rate": {
          "random": {
            "enable": false,
            "minimumValue": 0
          },
          "value": {
            "min": 4,
            "max": 9
          }
        },
        "sizeOffset": true,
        "particles": {}
      }
    },
    "roll": {
      "darken": {
        "enable": false,
        "value": 0
      },
      "enable": false,
      "enlighten": {
        "enable": false,
        "value": 0
      },
      "mode": "vertical",
      "speed": 25
    },
    "tilt": {
      "random": {
        "enable": false,
        "minimumValue": 0
      },
      "value": 0,
      "animation": {
        "enable": false,
        "speed": 0,
        "decay": 0,
        "sync": false
      },
      "direction": "clockwise",
      "enable": false
    },
    "twinkle": {
      "lines": {
        "enable": false,
        "frequency": 0.05,
        "opacity": 1
      },
      "particles": {
        "enable": false,
        "frequency": 0.05,
        "opacity": 1
      }
    },
    "wobble": {
      "distance": 5,
      "enable": false,
      "speed": {
        "angle": 50,
        "move": 10
      }
    },
    "life": {
      "count": 0,
      "delay": {
        "random": {
          "enable": false,
          "minimumValue": 0
        },
        "value": 0,
        "sync": false
      },
      "duration": {
        "random": {
          "enable": false,
          "minimumValue": 0.0001
        },
        "value": 0,
        "sync": false
      }
    },
    "rotate": {
      "random": {
        "enable": false,
        "minimumValue": 0
      },
      "value": 0,
      "animation": {
        "enable": false,
        "speed": 0,
        "decay": 0,
        "sync": false
      },
      "direction": "clockwise",
      "path": false
    },
    "orbit": {
      "animation": {
        "count": 0,
        "enable": false,
        "speed": 1,
        "decay": 0,
        "delay": 0,
        "sync": false
      },
      "enable": false,
      "opacity": 1,
      "rotation": {
        "random": {
          "enable": false,
          "minimumValue": 0
        },
        "value": 45
      },
      "width": 1
    },
    "links": {
      "blink": false,
      "color": {
        "value": "random"
      },
      "consent": false,
      "distance": 100,
      "enable": false,
      "frequency": 1,
      "opacity": 1,
      "shadow": {
        "blur": 5,
        "color": {
          "value": "#000"
        },
        "enable": false
      },
      "triangles": {
        "enable": false,
        "frequency": 1
      },
      "width": 1,
      "warp": false
    },
    "repulse": {
      "random": {
        "enable": false,
        "minimumValue": 0
      },
      "value": 0,
      "enabled": false,
      "distance": 1,
      "duration": 1,
      "factor": 1,
      "speed": 1
    }
  },
}

二、修改文件中代码

  1. main.ts 中引入插件
import { createApp } from 'vue'
import './style.css'
import 'animate.css';
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import Particles from "vue3-particles";// 引入插件
import App from './App.vue'
const app = createApp(App)

app.use(Particles)
app.use(ElementPlus, { size: 'small', zIndex: 3000 })
app.mount('#app')
  1. App.vue 中使用插件
<template>
  <div class="app-background" @wheel="handleWheel">
    <!-- 上一页信息 -->
    <div class="absolute" @click="prev" style="top: 50px;">
      <img src="/up.svg" class="logo" alt="Email" />
    </div>

    <el-carousel ref="carousel" height="100vh" trigger="click" direction="vertical" :autoplay="false"
      @change="changeCarousel">
      <el-carousel-item>
        <first :count="count" ref="firstPage" />
      </el-carousel-item>
      <el-carousel-item>
        <second :count="count" />
      </el-carousel-item>
      <el-carousel-item>
        <third :count="count" ref="thirdPage" />
      </el-carousel-item>
      <el-carousel-item>
        <fourth :count="count" ref="fourthPage" />
      </el-carousel-item>
      <el-carousel-item>
        <fifth :count="count" ref="fifthPage" @showProject="showProject" />
      </el-carousel-item>
    </el-carousel>
    <!-- 下一页信息 -->
    <div class="absolute" @click="next" style="bottom: 50px;">
      <img src="/down.svg" class="logo" alt="Email" />
    </div>
    <!-- 项目经验详情 -->
    <el-dialog v-model="showDialog" center>
      <div class="family">
        <div class="text18" style="text-align: center;font-weight: bold;">{{ projectInfo.projectName }}</div>
        <div class="margin-top" style="text-align: center;">
          {{ projectInfo.projectStartTime }} - {{ projectInfo.projectEndTime }}
        </div>
        <div class="flex margin-top">
          <div style="min-width: 100px;">项目描述:</div>
          <div>{{ projectInfo.projectDescription }}</div>
        </div>
        <div class="flex margin-top">
          <div style="min-width: 100px;">项目职责:</div>
          <div>{{ projectInfo.projectDuty }}</div>
        </div>
        <div class="flex margin-top">
          <div style="min-width: 100px;">技术栈:</div>
          <div>{{ projectInfo.projectStack }}</div>
        </div>
        <div class="flex margin-top" v-if="projectInfo.projectOnline">
          <div style="min-width: 100px;">线上地址:</div>
          <el-link :href="projectInfo.projectOnline" target="_blank">
            {{ projectInfo.projectOnline }}
          </el-link>
        </div>
      </div>
    </el-dialog>
	// 使用粒子特效组件
    <vue-particles id="tsparticles" :particlesInit="particlesInit" :clickEffect="true" :options="options" />
  </div>
</template>

<script setup lang="ts">
import first from './components/First.vue'
import second from './components/Second.vue'
import third from './components/Third.vue'
import fourth from './components/Fourth.vue'
import fifth from './components/Fifth.vue'
import project from './utils/Project.ts'
import { options } from "./utils/options";
import { loadFull } from 'tsparticles'
import { ref } from 'vue'
const showDialog = ref(false)
const projectInfo = ref(project['center'])
const count = ref(0)
const firstPage = ref()
const thirdPage = ref()
const fourthPage = ref()
const fifthPage = ref()
const carousel = ref()
// 获取默认项目经验数据
const showProject = (value: any) => {
  if (project[value]) {
    projectInfo.value = project[value]
    showDialog.value = true
  }
}

// 上一页
const prev = () => {
  carousel.value.prev()
}

// 下一页
const next = () => {
  carousel.value.next()
}

let timer: any = null
const handleWheel = (e: any) => {
  if (showDialog.value) return
  let lock: Boolean = !timer;
  if (lock) {
    if (e.deltaY > 0) {
      next()
    } else if (e.deltaY < 0) {
      prev()
    }
    timer = setTimeout(() => {
      timer = null;
    }, 500);
  }
}

const handleKeyDown = (event: any) => {
  if (showDialog.value) return
  let lock: Boolean = !timer;
  if (lock) {
    if (event.key === 'ArrowUp') { prev() }
    else if (event.key === 'ArrowDown') { next() }
    timer = setTimeout(() => {
      timer = null;
    }, 500);
  }
}
// 监听键盘触发事件
document.addEventListener('keydown', handleKeyDown);

// 监听切换事件,重置和触发动态效果
const changeCarousel = (value: any) => {
  count.value = value
  if (value === 0) {
    firstPage.value.resetArr()
  } else if (value === 2) {
    thirdPage.value.resetArr()
  } else if (value === 3) {
    fourthPage.value.resetArr()
  } else if (value === 4) {
    fifthPage.value.resetArr()
  }
}

const particlesInit = async (engine: any) => {
  await loadFull(engine)
}
</script>

<style scoped>
.app-background {
  position: relative;
  width: 100%;
  height: 100vh;
  background-image: url('./assets/bgBig.png');
  background-repeat: no-repeat;
  background-position: center 0;
  background-size: cover;
}

.el-carousel__item {
  min-height: 100vh;
  background-color: rgba(10, 10, 10, 0.3);
}

::v-deep(.el-dialog) {
  background-color: rgb(250, 235, 215);
  animation: jackInTheBox;
  animation-duration: 1.5s;
}

.absolute {
  position: absolute;
  z-index: 10;
  left: calc(50% - 14px);
  opacity: .25;
  transition: all .4s linear 0s;
}

.absolute:hover {
  transform: scale(1.18);
  opacity: .85;
}

.logo {
  width: 28px;
  height: 28px;
}
</style> 

效果如下:

在这里插入图片描述

=> To Be Continued

点赞 评论 收藏 ~~ 留言讨论,如有错误,也希望大家不吝指出。 ~~ 点赞 评论 收藏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1075324.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

封装axios的post请求踩坑记录

今天自己封装axios请求时遇到了两个坑&#xff0c;所以记录一下。 第一个坑是我在代码的逻辑是只会发一次请求&#xff0c;但是在控制台却发现发了两次&#xff0c;第一次为不带参数的请求方式为options的预检请求&#xff0c;第二次的请求才是我真正需要发的post请求。在经过上…

基于Java+SpringBoot+Vue企业OA管理系统的设计与实现 前后端分离【Java毕业设计·文档报告·代码讲解·安装调试】

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

软件测试/测试开发丨利用ChatGPT 生成自动化测试脚本

点此获取更多相关资料 简介 自动化测试脚本可以模拟用户与应用程序的交互&#xff0c;例如点击按钮、输入数据、导航到不同的页面等等&#xff0c;以验证应用程序的正确性、性能和稳定性。 自动化测试在回归测试、冒烟测试等测试流程中都可以极大地起到节省时间、节省人力的作…

程序设计竞赛如何入门?

程序设计如何入门? 一、前言 对于刚接触竞赛的小白来说&#xff0c;了解以下几个问题至关重要。 程序设计竞赛难度如何&#xff1f;真小白怎么办&#xff1f;而且我数据结构什么的没上过或者学的很差怎么办&#xff1f;都说要刷题&#xff0c;但是怎么刷&#xff1f;刷多少…

QEMU背景知识

QEMU的两种模拟方案&#xff1a; 系统模拟 System Simulation&#xff1a;可以简单的理解为对整个计算机系统进行模拟&#xff08;CPU、Memory等&#xff09; 用户模式模拟 User Mode Simulation&#xff1a;基于模拟方案执行特定应用程序 除了模拟功能外&#xff0c;QUME工具…

如何巧用AI智能技术,让文物不再“无人问津”?

文物是文化与传统的象征&#xff0c;而博物馆则是展现文物的载体。传统的博物馆监控体系只是利用摄像头进行监控&#xff0c;无法将人工智能融入其中&#xff0c;使其更加智能化、信息化。那么&#xff0c;如何将AI技术与传统视频监控相融合呢&#xff1f;TSINGSEE青犀智能分析…

C++枚举(enum)

在本文中&#xff0c;您将学习使用枚举&#xff08;enum&#xff09;。此外&#xff0c;您还将学习C 编程中通常使用枚举的地方。枚举是用户定义的数据类型&#xff0c;由整数常量组成。可以使用关键字enum&#xff0c;定义枚举。 enum season { spring, summer, autumn, wint…

k8s简单部署nginx

文章目录 1. 前言2. 部署nginx2.1. **创建一个nginx的Deployment**2.2. **创建一个nginx的service** 3. 总结 1. 前言 前文提要&#xff1a; kubeadm简单搭建k8s集群第三方面板部署k8s 上篇文章我们简单部署了k8s的集群环境&#xff0c;相比一定迫不及待的想部署一个实际应用了…

底部Taber的抽取

1.会抽取一个布局样式 2.布局样式里面抽取一个底部样式 这个是layout的代码 <template><view class"layout-wrapper"><view class"layout-content"><slot></slot></view><!-- 底部 --><Tabbar :activeInde…

基于Java+SpringBoot+Vue宠物领养系统的设计与实现 前后端分离【Java毕业设计·文档报告·代码讲解·安装调试】

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

JVM源码剖析之线程的创建过程

说在前面&#xff1a; 对于Java线程的创建这个话题&#xff0c;似乎已经被"八股文"带偏&#xff5e; 大部分Java程序员从"八股文"得知创建Java线程有N种方式&#xff0c;比如new Thread、new Runnable、Callable、线程池等等&#xff5e; 而笔者写下这篇文…

Qemu系统模拟:1 简介

目录 1 后端/加速器2 特性简介3 运行 1 后端/加速器 系统模拟主要用于在host设备上运行guest OSQEMU支持多种hypervisors,同时也支持JIT模拟方案&#xff08;TCG&#xff09; 例如从上表我们可以看出&#xff0c;运行在x86硬件上的Linux系统支持KVM,Xen,TCG 2 特性简介 提供…

大数据集群(Hadoop生态)安装部署

目录 1. 简介 2. 前置要求 3. Hadoop集群角色 4. 角色和节点分配 5. 调整虚拟机内存 6. Zookeeper集群部署 7. Hadoop集群部署 7.1 下载Hadoop安装包、解压、配置软链接 7.2 修改配置文件&#xff1a;hadoop-env.sh 7.3 修改配置文件&#xff1a;core-site…

自动化机器人的开发框架

自动化领域有多个开源的框架和工具&#xff0c;用于自动化各种任务和流程。以下是一些常见的自动化开源框架和工具&#xff0c;以及它们的特点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.Robot…

【Java】Java中BigDecimal解决精度丢失问题

文章目录 1.我们先看一个例子2.BigDecimal中的一些方法3.值得注意的是如果要想无精度丢失的情况下计算结果&#xff0c;那么需要把double,float类型的参数转化为String类型的。并且使用BigDecimal(String)这个构造方法进行构造。 去获取结果。不然还是没有效果。4.在一般开发过…

python curl2pyreqs 生成接口脚本

下载 curl2pyreqs 库 pip install curl2pyreqs -i https://pypi.tuna.tsinghua.edu.cn/simple 打开调试模式&#xff0c;在Network这里获取 接口的cURL 打开cmd窗口&#xff0c;输入curl2pyreqs&#xff0c;会自动生成接口代码 curl2pyreqs 执行接口脚本&#xff0c;返回响应…

Docker基础操作容器

启动容器有两种方式&#xff0c;一种是基于镜像新建一个容器并启动&#xff0c;另外一个是将在终止状态&#xff08;exited&#xff09;的容器重新启动。 因为 Docker 的容器实在太轻量级了&#xff0c;很多时候用户都是随时删除和新创建容器。 新建并启动 所需要的命令主要…

火爆全网的头戴式耳机,Y2K辣妹时髦单品——Umelody轻律 U1头戴式耳机!

近些年&#xff0c;“复古”这阵风在时尚圈是越刮越猛。Y2K穿搭风更是火爆&#xff0c;最近火爆的Umelody轻律 U1头戴式耳机&#xff0c;可以说是通过单品来就能掌握其中的精髓&#xff0c;在众多博主和达人的穿搭中轮番上阵&#xff0c;无论是挂脖还是佩戴都特别好看&#xff…

STM32单片机入门学习(五)-按钮控制LED

按钮和LED接线 LED负极接B12,正极接VCC 按钮一端接B13,一端接GND&#xff0c;按下为低电平&#xff0c;松开为高电平 如图&#xff1a; 主程序代码&#xff1a;main.c #include "stm32f10x.h" #include "Delay.h" //delay函数所在头文件 #include …

基于Springboot实现影视影院订票选座管理系统【项目源码+论文说明】

基于Springboot实现影视影院订票选座管理系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个影城管理系统 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论…