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

news2024/11/15 16:37:40

本代码的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.coloradmin.cn/o/1901319.html

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

相关文章

【C语言】第四十二弹---一万六千字教你从0到1实现通讯录

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 目录 1、通讯录分析和设计 1.1、通讯录的功能说明 1.2、程序的分析和设计 1.2.1、数据结构的分析 1.2.2、文件结构设计 2、通讯录的结构分析 2.1、创建通…

mysql5.6的安装步骤

1.下载mysql 下载地址&#xff1a;https://downloads.mysql.com/archives/community/ 在这里我们下载zip的包 2.解压mysql包到指定目录 3. 添加my.ini文件 # For advice on how to change settings please see # http://dev.mysql.com/doc/refman/5.6/en/server-configurat…

docker-compose Install gitlab 17.1.1

gitlab 前言 GitLab 是一个非常流行的开源 DevOps 平台,用于软件开发项目的整个生命周期管理。它提供了从版本控制、持续集成/持续部署(CI/CD)、项目规划到监控和安全的一系列工具。 前提要求 Linux安装 docker docker-compose 参考Windows 10 ,11 2022 docker docker-c…

11.x86游戏实战-汇编指令add sub inc dec

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;10.x86游戏实战-汇编指令lea 首先双击下图红框位置 然后在下图红框位置输入0 然…

瞰景Smart3D使用体验分享

引言 作为一名建筑设计师&#xff0c;我一直在寻找能够提升工作效率和设计质量的软件工具。瞰景Smart3D&#xff08;Smart3D&#xff09;是一款备受推崇的3D建模和设计软件&#xff0c;广泛应用于建筑、工程和施工&#xff08;AEC&#xff09;行业。经过一段时间的使用&#x…

MySQL表的增删改查(CRUD)

MySQL表的增删改查&#xff08;CRUD&#xff09; 文章目录 MySQL表的增删改查&#xff08;CRUD&#xff09;1. Create1.1 单行数据 全列插入1.2 多行数据 指定列插入1.3 插入否则更新1.4 替换 2. Retrieve2.1 SELECT 列2.1.1 全列查询2.1.2 指定列查询2.1.3 查询字段为表达式…

荞面打造的甜蜜魔法:甜甜圈

食家巷荞面甜甜圈是一款具有特色的美食。它以荞面为主要原料&#xff0c;相较于普通面粉&#xff0c;荞面具有更高的营养价值&#xff0c;富含膳食纤维、维生素和矿物质。荞面甜甜圈的口感可能会更加扎实和有嚼劲&#xff0c;同时带着荞面特有的谷物香气。在制作过程中&#xf…

一款纯 js 实现的大模型应用服务 FastGPT 解读

背景介绍 最近被不同的人安利了 FastGPT 项目&#xff0c;实际上手体验了一下&#xff0c;使用流程类似之前调研过的 Dify, 包含的功能主要是&#xff1a;任务流的编排&#xff0c;知识库管理&#xff0c;另外还有一些外部工具的调用能力。使用页面如下所示&#xff1a; 实际…

游戏服务器搭建选VPS还是专用服务器?

游戏服务器搭建选VPS&#xff0c;VPS能够提供控制、性能和稳定性。它不仅仅是让游戏保持活力。它有助于减少延迟问题&#xff0c;增强您的游戏体验。 想象一下&#xff1a;你正沉浸在一场游戏中。 胜利在望。突然&#xff0c;屏幕卡住——服务器延迟。 很崩溃&#xff0c;对…

Drools开源业务规则引擎(四)- 规则流(rule flow)及手把手教你构建jBPM项目

文章目录 Drools开源业务规则引擎&#xff08;四&#xff09;- 规则流&#xff08;rule flow&#xff09;及手把手教你构建jBPM项目1.什么是规则流2.构建jBPM项目2.1.添加maven依赖2.2.创建kmodule.xml2.3.新建drl文件和bpmn2文件2.4.测试方法2.5.日志输出 3.Eclipse安装jBPM流…

24西安电子科技大学马克思主义学院—考研录取情况

01、马克思主义学院各个方向 02、24马克思主义学院近三年复试分数线对比 PS&#xff1a;马院24年院线相对于23年院线增加15分&#xff0c;反映了大家对于马克思主义理论学习与研究的热情高涨&#xff0c;也彰显了学院在人才培养、学科建设及学术研究等方面的不断进步与成就。 6…

Apache Seata应用侧启动过程剖析——注册中心与配置中心模块

本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 Apache Seata应用侧启动过程剖析——注册中心与配置中心模块 前言 在Seata的应用侧&#xf…

Docker逃逸CVE-2019-5736、procfs云安全漏洞复现,全文5k字,超详细解析!

Docker容器挂载procfs 逃逸 procfs是展示系统进程状态的虚拟文件系统&#xff0c;包含敏感信息。直接将其挂载到不受控的容器内&#xff0c;特别是容器默认拥有root权限且未启用用户隔离时&#xff0c;将极大地增加安全风险。因此&#xff0c;需谨慎处理&#xff0c;确保容器环…

最适合mysql5.6安装的linux版本-实战

文章目录 一, 适合安装mysql5.6的linu版本1. CentOS 72. Ubuntu 14.04 LTS (Trusty Tahr)3. Debian 8 (Jessie)4. Red Hat Enterprise Linux (RHEL) 7 二, 具体以Ubuntu 14.04 LTS (Trusty Tahr)为例安装虚拟机安装Ubuntu 14.04 LTS (Trusty Tahr) 自己弄安装ssh(便于远程访问,…

入职字节外包2个月后,我离职了...

有一种打工人的羡慕&#xff0c;叫做“大厂”。 真是年少不知大厂香&#xff0c;错把青春插稻秧。 但是&#xff0c;在深圳有一群比大厂员工更庞大的群体&#xff0c;他们顶着大厂的“名”&#xff0c;做着大厂的工作&#xff0c;还可以享受大厂的伙食&#xff0c;却没有大厂…

短视频商城系统源码揭秘:架构设计与实现

在短视频平台和电商平台蓬勃发展的背景下&#xff0c;短视频商城系统应运而生&#xff0c;融合了短视频内容和电商功能&#xff0c;给用户带来了全新的购物体验。本文将揭示短视频商城系统的源码架构设计与实现&#xff0c;帮助开发者了解该系统的内部工作原理及其关键技术。 …

C++11中新特性介绍-之(二)

11.自动类型推导 (1) auto类型自动推导 auto自动推导变量的类型 auto并不代表某个实际的类型&#xff0c;只是一个类型声明的占位符 auto并不是万能的在任意场景下都能推导&#xff0c;使用auto声明的变量必须进行初始化&#xff0c;以让编译器推导出它的实际类型&#xff0c;…

自然之美无需雕琢

《自然之美&#xff0c;无需雕琢 ”》在这个颜值至上的时代&#xff0c;但在温馨氛围中&#xff0c;单依纯以一种意想不到的方式&#xff0c;为我们诠释了自然之美的真谛。而医生的回答&#xff0c;如同一股清流耳目一新。“我说医生你看我这张脸&#xff0c;有没有哪里要动的。…

团队编程:提升代码质量与知识共享的利器

目录 前言1. 什么是团队编程&#xff1f;1.1 团队编程的起源1.2 团队编程的工作流程 2. 团队编程的优势2.1 提高代码质量2.2 促进知识共享2.3 增强团队协作2.4 提高开发效率 3. 团队编程的挑战3.1 开发成本较高3.2 需要良好的团队协作3.3 个人风格和习惯的差异3.4 长时间的集中…

2024亚太杯数学建模竞赛(B题)的全面解析

你是否在寻找数学建模比赛的突破点&#xff1f;数学建模进阶思路&#xff01; 作为经验丰富的数学建模团队&#xff0c;我们将为你带来2024亚太杯数学建模竞赛&#xff08;B题&#xff09;的全面解析。这个解决方案包不仅包括完整的代码实现&#xff0c;还有详尽的建模过程和解…