星辰宇宙动态页面vue版,超好看的前端页面。附源码与应用教程(若依)

本代码的html版本,来源自“山羊の前端小窝”作者,我对此进行了vue版本转换以及相关应用。特此与大家一起分享~

1、直接上效果图:

带文字版:文字呼吸式缩放。

纯净版:

默认展示效果:

缩放与旋转后:

2、代码

话不多说,直接上代码

<template>
  <div id="threejs-scene">
    <div class="header-text" ref="headerText">万千星辰,<span @click="redirectToPage" style="font-weight: bold">我</span>,会归于何方?</div>
  </div>
</template>

<!--//我在上方做了个跳转,这是在若依中设置的,不需要的直接删除即可-->

<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

//需要npm install相关插件,一般会有提示,请直接安装

export default {
  mounted() {
    console.clear();
    // 创建场景
    this.scene = new THREE.Scene();
    this.scene.background = new THREE.Color(0x160016);

    // 创建相机
    this.camera = new THREE.PerspectiveCamera(
      60,
      window.innerWidth / window.innerHeight,
      1,
      1000
    );
    this.camera.position.set(0, 4, 21);

    // 创建渲染器
    this.renderer = new THREE.WebGLRenderer();
    // 设置渲染器大小
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    // 把渲染器加入到页面中
    this.$el.appendChild(this.renderer.domElement);

    // 监听窗口大小变化事件
    window.addEventListener("resize", this.handleWindowResize);

    // 创建控制器
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    // 开启阻尼效果
    this.controls.enableDamping = true;
    // 禁用面板
    this.controls.enablePan = false;

    // 创建全局uniform
    this.gu = {
      time: { value: 0 },
    };

    // 创建时钟
    this.clock = new THREE.Clock();

    // 生成点云数据
    this.generatePointCloud();

    // 设置渲染循环
    this.renderer.setAnimationLoop(this.animate);
  },
  methods: {
    redirectToPage() {
      // 页面跳转
      this.$router.push({path:"/loginForUser"});
    },
    handleWindowResize() {
      this.camera.aspect = window.innerWidth / window.innerHeight;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(window.innerWidth, window.innerHeight);
    },
    generatePointCloud() {
      let pts = [];
      let sizes = [];
      let shift = [];

      // 创建移动函数
      const pushShift = () => {
        shift.push(
          Math.random() * Math.PI,
          Math.random() * Math.PI * 2,
          (Math.random() * 0.9 + 0.1) * Math.PI * 0.1,
          Math.random() * 0.9 + 0.1
        );
      };

      // 创建点的顶点数组(中间的球体)
      for (let i = 0; i < 50000; i++) {
        sizes.push(Math.random() * 1.5 + 0.5);
        pushShift();
        pts.push(
          new THREE.Vector3()
            .randomDirection()
            .multiplyScalar(Math.random() * 0.5 + 9.5)
        );
      }

      // 添加更多的点(旁边围绕的)
      for (let i = 0; i < 100000; i++) {
        let r = 10,
          R = 40;
        let rand = Math.pow(Math.random(), 1.5);
        let radius = Math.sqrt(R * R * rand + (1 - rand) * r * r);

        pts.push(
          new THREE.Vector3().setFromCylindricalCoords(
            radius,
            Math.random() * 2 * Math.PI,
            (Math.random() - 0.5) * 2
          )
        );
        sizes.push(Math.random() * 1.5 + 0.5);
        pushShift();
      }

      // 创建点云几何体
      let geometry = new THREE.BufferGeometry().setFromPoints(pts);
      geometry.setAttribute("sizes", new THREE.Float32BufferAttribute(sizes, 1));
      geometry.setAttribute("shift", new THREE.Float32BufferAttribute(shift, 4));

      // 创建点云材质
      let material = new THREE.PointsMaterial({
        size: 0.125,
        transparent: true,
        depthTest: false,
        blending: THREE.AdditiveBlending,
        onBeforeCompile: (shader) => {
          shader.uniforms.time = this.gu.time;
          shader.vertexShader = `
            uniform float time;
            attribute float sizes;
            attribute vec4 shift;
            varying vec3 vColor;
            ${shader.vertexShader}
            `
            .replace(`gl_PointSize = size;`, `gl_PointSize = size * sizes;`)
            .replace(
              `#include <color_vertex>`,
              `#include <color_vertex>
                float d = length(abs(position)/vec3(40.,10.,40));
                d=clamp(d,0.,1.);
                vColor = mix(vec3(220., 84., 190.),vec3(67., 11., 245.),d)/255.;`
            )
            //上文vColor为调整颜色的东西,可自定义!
            .replace(
              `#include <begin_vertex>`,
              `#include <begin_vertex>
                      float t = time;
                      float moveT = mod(shift.x + shift.z * t,PI2);
                      float moveS = mod(shift.y + shift.z * t,PI2);
                      transformed += vec3(cos(moveS) * sin(moveT),cos(moveT),sin(moveS)*sin(moveT)) * shift.w;
                      `
            );
          shader.fragmentShader = `
                  varying vec3 vColor;
                  ${shader.fragmentShader}
                  `
            .replace(
              `#include <clipping_planes_fragment>`,
              `#include <clipping_planes_fragment>
                            float d = length(gl_PointCoord.xy - 0.5);
                        `
            )
            .replace(
              `vec4 diffuseColor = vec4( diffuse, opacity );`,
              `vec4 diffuseColor = vec4(vColor, smoothstep(0.5, 0.1, length(gl_PointCoord.xy - 0.5))/* * 0.5+0.5*/);`
            );
        },
      });

      // 创建点云对象并添加到场景中
      this.points = new THREE.Points(geometry, material);
      this.points.rotation.order = "ZYX";
      this.points.rotation.z = 0.2;
      this.scene.add(this.points);
    },
    animate() {
      this.controls.update();
      // 获取时钟对象(clock)的已经流逝的时间(t)并将他乘0.5
      let t = this.clock.getElapsedTime() * 0.5;
      this.gu.time.value = t * Math.PI;
      this.points.rotation.y = t * 0.05;
      this.renderer.render(this.scene, this.camera);

      // 更新文字的缩放比例
        //如果不想要文字,请注释掉文字所在的div,以及下面两行:
      let scale = 1 + 0.2 * Math.sin(t);
      this.$refs.headerText.style.transform = `scale(${scale})`;
    },
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.handleWindowResize);
    this.renderer.setAnimationLoop(null);
  },
};
</script>

<style scoped>
.header-text {
  position: absolute;
  top: 45%;
  left: 35%;
  transform: translate(-50%, -50%);
  font-size: 50px;
  font-weight: bold;
  color: #f8df70;
  opacity: 90%;
  text-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
  z-index: 10;
  font-family: 'Comic Sans MS', 'Comic Sans', cursive;
  text-align: center;
  cursor: pointer; /* 让文本在鼠标悬停时显示光标,表明可以点击 */
}

#threejs-scene {
  overflow: hidden;
  margin: 0;
}
</style>

3、在若依登录前的应用:

当前我实现的效果为:前端页面运行后,直接跳转到星辰页,再靠点击触发登录跳转。

(1)创建页面

复制原有的login.vue页面,将副本命名为:loginForUser用于放原有的登录页面,原有页面替换为上文代码👆

(2)找到router路由位置:添加路由

  {
    path: '/loginForUser',
    component: () => import('@/views/loginForUser'),
    hidden: true
  },

{
    path: '',
    component: Layout,
    redirect: 'loginForUser',
    children: [
      {
        path: 'loginForUser',
        component: () => import('@/views/loginForUser'),
        name: 'Index',
        meta: { title: '首页', icon: 'dashboard', affix: true }
      }
    ]
  },

//请将上文loginForUser,替换为你的当前登录页面的名称

注意,做到这一步,一般还是无法跳转的,需要下一步修改:

(3)找到permission.js页面,修改访问白名单,实现跳转逻辑。

permission.js代码参考:

import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getToken } from '@/utils/auth'
import { isRelogin } from '@/utils/request'

NProgress.configure({ showSpinner: false })

const whiteList = ['/login', '/loginForUser','/register']
//添加了:'/loginForUser',

router.beforeEach((to, from, next) => {
  NProgress.start()
  if (getToken()) {
    to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
    /* has token*/
    if (to.path === '/login'|| to.path === '/loginForUser')  {
      //添加了: to.path === '/loginForUser'
      next({ path: '/' })
      NProgress.done()
    } else if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      if (store.getters.roles.length === 0) {
        isRelogin.show = true
        // 判断当前用户是否已拉取完user_info信息
        store.dispatch('GetInfo').then(() => {
          isRelogin.show = false
          store.dispatch('GenerateRoutes').then(accessRoutes => {
            // 根据roles权限生成可访问的路由表
            router.addRoutes(accessRoutes) // 动态添加可访问路由表
            next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
          })
        }).catch(err => {
            store.dispatch('LogOut').then(() => {
              Message.error(err)
              next({ path: '/' })
            })
          })
      } else {
        next()
      }
    }
  } else {
    // 没有token
    if (whiteList.indexOf(to.path) !== -1) {
      // 在免登录白名单,直接进入
      next()
    } else {
      next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})

(4)星辰页面(login.vue)加入路由跳转:

<template>
  <div id="threejs-scene">
    <div class="header-text" ref="headerText">万千星辰,<span @click="redirectToPage"             
    style="font-weight: bold">我</span>,会归于何方?</div>
  </div>
</template>
<!--页面中,引入点击事件:@click="redirectToPage"-->
<script>

    //……其它代码
 methods: {    
    redirectToPage() {
      
      this.$router.push({path:"/loginForUser"});
      // path就是你在router文件中写的,我的为 /loginForUser
        
    },

 }

</script>

最后贴一个原作者的视频地址:希望大家也可以支持一下原作者~

【JS】星辰宇宙教学 或许这就是代码的魅力 (附源码)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

简单的手动实现spring中的自动装配案例

简简单单的实现一个spring中的自动装配和容器管理的小骚操作。 1&#xff0c;创建AutoSetBean.java 使用injectBeans静态方法&#xff0c;可以扫描指定包下的所有带MyInject注解的字段&#xff0c;如果在beans的Map中存在这个字段的实例化类&#xff0c;则执行装配。 import…

【UE5.1 角色练习】13-枪械射击——拿出与收起武器

目录 效果 步骤 一、安装射击武器 二、拿武器和收武器 效果 步骤 一、安装射击武器 1. 在虚幻商城中将“FPS Weapon Bundle”添加到工程中&#xff0c;由于我们使用的是5.1版本&#xff0c;我们可以先将该资产放入UE4工程中&#xff0c;然后迁移到5.1版本的工程 2. 打开角…

alphazero学习

AlphaGoZero是AlphaGo算法的升级版本。不需要像训练AlphaGo那样&#xff0c;不需要用人类棋局这些先验知识训练&#xff0c;用MCTS自我博弈产生实时动态产生训练样本。用MCTS来创建训练集&#xff0c;然后训练nnet建模的策略网络和价值网络。就是用MCTSPlayer产生的数据来训练和…

Spring与Quartz整合

Quartz框架是一个轻量级的任务调度框架&#xff0c;它提供了许多内置的功能&#xff0c;包括&#xff1a;支持作业的调度、集群调度、持久化、任务持久化、任务依赖、优先级、并发控制、失败重试等。同时也支持自定义作业类型和触发器类型。与Spring整合步骤如下&#xff1a; …

深入解析.[datastore@cyberfear.com].mkp勒索病毒:威胁与防范

引言 在数字化时代&#xff0c;网络安全问题日益严峻&#xff0c;其中勒索病毒&#xff08;Ransomware&#xff09;作为一种极具破坏性的恶意软件&#xff0c;严重威胁着个人用户和企业机构的数据安全。.[ datastorecyberfear.com].mkp勒索病毒便是这一领域中的一颗“毒瘤”&am…

2.5 C#视觉程序开发实例1----IO_Manager实现脉冲输出控制

2.5 C#视觉程序开发实例1----IO_Manager实现脉冲输出控制 1 目标效果视频 目标效果展示 IO_Manager 2 信号输出流程说明 为了防止线程不同步导致输出信号没有被输出&#xff0c; 尽量使用一个输出队列来进行输出的管理 3 IO_Manager中添加内容 3.0 添加两个类 1 Out_Sta…

【课程总结】Day13(下):人脸识别和MTCNN模型

前言 在上一章课程【课程总结】Day13(上):使用YOLO进行目标检测,我们了解到目标检测有两种策略,一种是以YOLO为代表的策略:特征提取→切片→分类回归;另外一种是以MTCNN为代表的策略:先图像切片→特征提取→分类和回归。因此,本章内容将深入了解MTCNN模型,包括:MTC…

Windows 11文件资源管理器选项卡的4个高级用法,肯定有你喜欢的

作为一个每天使用文件资源管理器来管理我的工作流程的人,选项卡帮助我为处于不同完成阶段的工作创建了不同的文件夹。以下是我使用选项卡提高工作效率的最佳技巧。 打开和关闭选项卡 假设你的计算机上安装了Windows 11的最新更新,请按Ctrl+E打开文件资源管理器。在我发现“…

STM32智能家居掌上屏实战:从WiFi连接到MQTT通信,打造你的家庭物联网网关

摘要: 本文深入探讨一种基于STM32的智能家居掌上屏设计方案&#xff0c;详细阐述其硬件架构、软件设计以及通信协议等关键技术细节。该方案利用WiFi构建局域网&#xff0c;实现与各类传感器、执行器的便捷交互&#xff0c;并通过TFT彩屏提供直观的控制和数据展示&#xff0c;旨…

五、保存数据到Excel、sqlite(爬虫及数据可视化)

五、保存数据到Excel、sqlite&#xff08;爬虫及数据可视化&#xff09; 1&#xff0c;保存数据到excel1.1 保存九九乘法表到excel&#xff08;1&#xff09;代码testXwlt.py&#xff08;2&#xff09;excel保存结果 1.2 爬取电影详情并保存到excel&#xff08;1&#xff09;代…

大模型周报|15 篇必读的大模型论文

大家好&#xff0c;今日必读的大模型论文来啦&#xff01; 1.谷歌推出风格感知拖放新方法 Magic Insert 来自谷歌的研究团队提出了 Magic Insert&#xff0c;用于以物理上可信的方式将用户提供的图像中的对象拖放到不同风格的目标图像中&#xff0c;同时与目标图像的风格相匹…

基于CLIP特征的多模态大模型中的视觉短板问题

【论文极速读】 基于CLIP特征的多模态大模型中的视觉短板问题 FesianXu 20240706 at Tencent WeChat search team 前言 今天读到篇CVPR 24’的论文 [1]&#xff0c;讨论了常见的多模态大模型&#xff08;大多都基于CLIP语义特征&#xff0c;以下简称为MLLM&#xff09;中的视觉…

Git错误分析

错误案例1&#xff1a; 原因&#xff1a;TortoiseGit多次安装导致&#xff0c;会记录首次安装路径&#xff0c;若安装路径改变&#xff0c;需要配置最后安装的路径。

HTML5使用<details>标签:展开/收缩信息

details 标签提供了一种替代 JavaScript 的方法&#xff0c;它主要是提供了一个展开/收缩区域。details 标签中可以使用 summary 标签从属于 details 标签&#xff0c;单击 summary 标签中的内容文字时&#xff0c;details 标签中的其他所有从属元素将会展开或收缩。语法如下&a…

Redies基础篇(一)

Redis 是一个高性能的key-value数据库。Redies支持存储的value类型相对更多&#xff0c;包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作&#xff0c;而且这些操作都是原子性的&#xff…

小白必看!推荐三本高质量python书籍,让你直接原地起飞

Python是一种多功能语言。它经常用作Web应用程序的脚本语言&#xff0c;嵌入到软件产品中&#xff0c;以及人工智能和系统任务管理。它既简单又强大&#xff0c;非常适合初学者和专业程序员。 python的自学书籍非常多&#xff0c;涉及基础入门、web开发、机器学习、数据分析、…

印度第二大移动提供商 3.75 亿数据待售

一个名为“xenZen”的威胁行为者已在 BreachForums 上出售 Airtel 的数据库。 该列表包含来自 3.75 亿客户的数据。 数据详情&#xff1a; 手机号码 名 出生日期 父亲的名字 地址 电子邮件ID 类型 国籍 阿达尔 带照片的身份证明详细信息 地址详细信息证明等 鉴于…

003-基于Sklearn的机器学习入门:回归分析(上)

本节及后续章节将介绍机器学习中的几种经典回归算法&#xff0c;所选方法都在Sklearn库中聚类模块有具体实现。本节为上篇&#xff0c;将介绍基础的线性回归方法&#xff0c;包括线性回归、逻辑回归、多项式回归和岭回归等。 2.1 回归分析概述 回归&#xff08;Regression&…

3-3 超参数

3-3 超参数 什么是超参数 超参数也是一种参数&#xff0c;它具有参数的特性&#xff0c;比如未知&#xff0c;也就是它不是一个已知常量。是一种手工可配置的设置&#xff0c;需要为它根据已有或现有的经验&#xff0c;指定“正确”的值&#xff0c;也就是人为为它设定一个值&…

SAP PS学习笔记01 - PS概述,创建Project和WBS

本章开始学习PS&#xff08;Project System&#xff09;。 1&#xff0c;PS的概述 PS&#xff08;Project System&#xff09;是SAP企业资源规划系统中的一个关键模块&#xff0c;主要用于项目管理。 它提供了一个全面的框架来规划、控制和执行项目&#xff0c;涵盖了从项目启…