WEB 3D技术 three.js 3D贺卡(4) 添加鼠标滚轮移动屏幕 改变贺卡文字功能

好,上文 WEB 3D技术 three.js 3D贺卡(3) 点光源灯光动画效果 那么 我们来做一下 鼠标滚动相机和滚动时不同文字的切换
在这里插入图片描述
首先 我们要设置多个场景 其实也不能完全叫场景 也可以说多个位置
反正简单说就是多个位置 展现多个场景

我们先在代码的最下面 加上一个对象数组

let scenes = [{text: "圣诞快乐",callback:() => {}},{text: "感谢在这么大的世界遇见了你",callback:() => {}},{text: "愿陪你去探寻世界的每一个角落",callback:() => {}},{text: "愿将天上的星星送给你",callback:() => {}},{text: "愿有人去终成眷属",callback:() => {}}
]

在这里插入图片描述
这里 我们写了个数组 然后里面每一个下标都是对象,对象里面 text字段是要展示的文本 然后 callback 是一个回调函数
这里 我们数组的每一个索引 相当于一个场景

然后 我们要给一个索引值 来记录它的位置
首先 因为我们需要一个响应式变量 vue3声明响应式变量 我们需要先导入 vue内的这个ref

import { ref } from "vue"

在这里插入图片描述
然后 最下面 我们声明索引

let index = ref(0);

在这里插入图片描述
我们用这个索引 来记录当前所处的场景

接下来 我们来监听鼠标的一个滚轮事件
这样写

window.addEventListener(// 监听用户鼠标滚轮事件"wheel", (e)=>{// 判断是否是向上滚轮if(e.deltaY > 0) {// 将index的索引值加一index.value++;// 判断 如果 index 的索引值 已经大于 scenes数组的长度了if(index.value > scenes.length - 1) {//将index 索引值归0index.value = 0;}}scenes[index.value].callback();}
)

我们监听了 wheel 鼠标滚轮事件
然后判断如果滚轮网上滚动 就触发我们if中的逻辑 将index先加一 然后判断 如果index索引的数值已经大于了 scenes数组的长度的话 那就将 index索引值归0
在这里插入图片描述
然后 我们来写一个定义相机移动函数 用补间动画控制相机移动

// 使用补间动画移动相机
let timeLine1 = gsap.timeline();
let timeline2 = gsap.timeline();
/
/ 定义相机移动函数
function tranlateCamera(position,target) {timeLine1.to(camera.position, {x: position.x,y: position.y,z: position.z,duration: 1,ease: "power2.inOut"})timeline2.to(controls.target, {x: target.x,y: target.y,z: target.z,duration: 1,ease: "power2.inOut"})
}

在这里插入图片描述
这里 我们 tranlateCamera 函数 接受了两个参数 position 和 target
他们分别控制
position用来控制 camera 相机的 position 下的 x y z 位置属性 简单说 移动相机
target用来控制 controls控制器的 target属性的下的x y z属性 target是控制相机聚焦的点 简单说 就是你旋转整个场景 它相机聚焦的一个中心点位置

通过 补间动画对象.to 进行控制

然后 我们就来改 scenes数组
这样写

let scenes = [{text: "圣诞快乐",callback:() => {tranlateCamera(new THREE.Vector3(-3.23, 3, 4.06),new THREE.Vector3(-8, 2, 0))}},{text: "感谢在这么大的世界遇见了你",callback:() => {tranlateCamera(new THREE.Vector3(7, 0, 23),new THREE.Vector3(0, 0, 0))}},{text: "愿陪你去探寻世界的每一个角落",callback:() => {tranlateCamera(new THREE.Vector3(10, 3, 0),new THREE.Vector3(5, 2, 0))}},{text: "愿将天上的星星送给你",callback:() => {tranlateCamera(new THREE.Vector3(7, 0, 23),new THREE.Vector3(0, 0, 0))}},{text: "愿有人去终成眷属",callback:() => {tranlateCamera(new THREE.Vector3(-20, 1.3, 6.6),new THREE.Vector3(5, 2, 0))}}
]

我们编写了每一个下标的 callback 函数
这里因为我们塑标滚轮事件 你每次滚动 都会调用对应下标的 callback
在这里插入图片描述
然后 就会根据事件给的定位参数 来到对应的位置 和找到 对应的相机聚焦点

我们运行项目
在这里插入图片描述
然后滚动鼠标滚轮 整个摄像头都会移动
在这里插入图片描述
当然 你别鼠标滚动的太频繁了,要等它整个界面移动完毕。
不然就会上一个没执行完 你下一个又触发了 整个界面动来动去的。

那么 这里这个问题 我们就可以做个防抖
首先 大家要清楚 我们两个补间动画给的duration 时间都是一秒
那么 这里 如下图修改滚轮事件
在这里插入图片描述
定义一个叫 isAnimate 的变量 初始值是false
然后 如果这个值为true 我们直接 函数 return 出去 不执行下面的逻辑了 就是防止你上一个动画还没结束 下一个动画又开始了
然后 我们 执行callback 就是开启动画后
开启定时器 一秒之后 再将 isAnimate 赋值会false
那就是 每次执行完 callback 后面一秒内 isAnimate 都是true
再进入事件 都会触发到if retrun 就不会执行动画了 而 动画执行完 1秒 定时器正好也是1秒
就会将 isAnimate 回归false 然后再次触发 就又能进来了

这样 我们整个的滚动切换就算是OK了
在这里插入图片描述
然后 我们来写这个文字的效果
我们在 template中这样写

<divclass="scenes"style="position: fixed;left: 0;top: 0;z-index: 10;pointer-events: none;transition: all 1s;"
><divv-for="item in scenes":key="item.text"style="width: 100vw;height: 100vh":style="{transform: `translate3d(0, ${-index * 100}vh,0)`}"><h1style="padding:100px 50px; font-size: 50px; color: #fff">{{ item.text }}</h1></div>
</div>

在这里插入图片描述
这里 我们最外层元素 固定定位在页面的左上角
然后下面 v-for循环 遍历 scenes数组
用 index 控制 transform属性

然后 我们在屏幕上滚动鼠标滚轮
在这里插入图片描述
这边文字就会一直发生变化了
在这里插入图片描述

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

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

相关文章

RocketMQ高可用架构涉及常用功能整理

RocketMQ高可用架构涉及常用功能整理 1. 集群高可用系统架构和相关组件1.1 架构说明1.2 相关概念说明1.3 消息模型1.3.1 点对点模型1.3.2 发布订阅模型1.3.3 消息过滤 2. rocketmq的核心参数3. rocketmq常用命令4. 事务性4.1 数据写入流程4.2 数据读流程4.3 事务消息 5. 疑问和…

如何查看Mosquitto的连接数量

Mosquitto 提供了一套管理 API&#xff0c;允许你通过 HTTP 或 WebSocket 连接来监控和管理 MQTT 代理。这个 API 需要通过配置文件启用。方法如下&#xff1a; 1、启用管理 API&#xff1a; 要启用管理 API&#xff0c;你需要编辑 Mosquitto 的配置文件&#xff0c;通常是 mo…

AOSP Android源码编译

从头搭建Android源码编译环境&#xff08;Ubuntu 18.04 / 20.04 / 22.04&#xff09;_ubuntu搭建android编译环境-CSDN博客Android系统编译流程详解(一)-腾讯云开发者社区-腾讯云 (tencent.com) Android系统源码的整编和单编 - schips - 博客园 (cnblogs.com) 修改初始化文件…

Linux下HTTP隧道技术的应用场景与优势分析

亲爱的Linux侠们&#xff0c;今天我们来聊一聊Linux下HTTP隧道技术的应用场景与优势。在这个网络时代&#xff0c;HTTP隧道技术就如同一位神秘的“魔法师”&#xff0c;为我们解决了许多棘手的网络问题。 首先&#xff0c;让我们来看看HTTP隧道技术在哪些场景下能大展身手。 …

GenAI的“关键一跃”:推理与知识

当前的人工智能领域正通过生成式人工智能&#xff08;GenAI&#xff09;经历一场重大转变。这一转变不仅代表了技术上的飞跃&#xff0c;更标志着人工智能领域的范式转变&#xff0c;引发了有关GenAI的独特特性及其深远影响的关键问题讨论。 植根于计算革命的丰富历史&#xff…

JavaWeb——002JS Vue快速入门

目录 一、JS快速入门​编辑 1、什么是JavaScript?​编辑 2、JS引入方式​编辑 2.1、示例代码 3、JS基础语法 3.1、书写语法 3.2、变量​编辑 3.3、数据类型 3.4、运算符​编辑 3.5、流程控制语句​编辑 4、JS函数 4.1、第一种函数定义方式 function funcName(参数…

【统计分析数学模型】聚类分析

【统计分析数学模型】聚类分析 一、聚类分析1. 基本原理2. 距离的度量&#xff08;1&#xff09;变量的测量尺度&#xff08;2&#xff09;距离&#xff08;3&#xff09;R语言计算距离 三、聚类方法1. 系统聚类法2. K均值法 三、示例1. Q型聚类&#xff08;1&#xff09;问题描…

大白话解析LevelDB: Block Iterator

文章目录 Block IteratorIterator 接口Block Iterator 的实现Block Iterator 的私有成员Block Iterator 的构造函数Block::Iter::Valid()Block::Iter::status()Block::Iter::key()Block::Iter::value()Block::Iter::Next()Block::Iter::Prev()Block::Iter::Seek(const Slice&am…

【2024软件测试面试必会技能】Appium自动化(4):Appium工作原理及Desired Capabilities配置

Appium工作原理 Appium工作原理图如下&#xff1a; 脚本请求——>4723端口appium server——>解析参数给PC端4724端口——>发送给设备4724端口——>通过设备4724端口发给bootstrap.jar——>Bootstrap.jar把命令发给uiautomator&#xff1b; sonWireProtocol&a…

java常用应用程序编程接口(API)——Objects类和包装类

前言&#xff1a; Object类和Objects类是完全不同的两个类&#xff0c;之前有说过Object类&#xff0c;这次说一下Objects类。打好基础&#xff0c;daydayup! Object类可以看这篇&#xff1a;java常用应用程序编程接口&#xff08;API&#xff09;——Object类概述及常用方法 O…

计算机网络基础之计算机网络组成与分类

计算机网络基础 计算机网络是计算机技术与通信技术发展相结合的产物&#xff0c;并在用户需求的促进下得到进一步的发展。通信技术为计算机之间的数据传输和交换提供了必需的手段&#xff0c;而计算机技术又渗透到了通信领域&#xff0c;提高了通信网络的性能。 计算机网络的…

Codeforces Round 926 (Div. 2) C. Sasha and the Casino

题目链接 思路: 他想知道自己是否可以赢取尽量多的数量的硬币。即他要采取措施让自己的硬币在任何情况下&#xff08;不会连输超过x次&#xff09;都要不断增多。 即我们考虑第一次&#xff0c;第二次&#xff0c;&#xff0c;&#xff0c;第x次&#xff0c;每一次都有赢和输的…

【谈一谈】: 我们工作中的单例模式有哪些写法?

单例模式的多种写法 我们要实现一个单例,首先最重要的是什么? 当然是把构造函数私有化,变成private类型,(为啥? 单例单例,如果谁都能通过构造函数创建对象,还叫单例吗?是不~) 嗯~我们构造函数私有化后,我们应该操作啥呢? 接着我们需要提供一个方法,这个方法要保证初始化有且…

数据脱敏(六)脱敏算法-加密算法

脱敏算法篇使用阿里云数据脱敏算法为模板,使用算子平台快速搭建流程来展示数据 "加密脱敏"是一种数据处理技术&#xff0c;主要用于保护个人隐私和数据安全。它通过将敏感信息&#xff08;如姓名、身份证号、电话号码等&#xff09;进行加密处理&#xff0c;使其无法…

力扣题目-178. 分数排名

力扣题目-178. 分数排名 仅作学习&#xff0c;不作他用 题干 表: Scores Column NameTypeidintscoredecimal 在 SQL 中&#xff0c;id 是该表的主键。 该表的每一行都包含了一场比赛的分数。Score 是一个有两位小数点的浮点值。 查询并对分数进行排序。排名按以下规则计算…

阿里同学聊测试开发与测试平台

在一线大厂&#xff0c;没有测试这个岗位&#xff0c;只有测开这个岗位&#xff0c;即使是做业务测试&#xff0c;那么你的title也是测开。 所以想聊一聊测开的看法&#xff0c;但不代表这是正确的看法&#xff0c;仅供参考。 没来阿里之前我对测开的看法 一直以为专职做自动…

DIcom调试Planar configuration

最近和CBCT组同事调dicom图像 这边得图像模块老不兼容对方得dicom文件。 vtk兼容&#xff0c;自己写得原生解析不兼容。 给对方调好了格式&#xff0c;下次生成文件还会有错。 简单记录下&#xff0c;日后备查。 今天对方又加了 个字段&#xff1a;Planar configuration 查…

Gradio学习(二)—————学习block布局

直接上代码 import gradio as gr with gr.Blocks() as demo: with gr.Tab(“Lion”) gr.Button(“new Lion”) with gr.Tab(“Tiger”): gr.Button(“new Tiger”) #因为在虚拟机中启动&#xff0c;而不是pycharm 所以指定主机ip (1.1.1.1)和端口号,如果是在pycharm 中&#…

【常识】大数据设计基础知识

底层存储&#xff1a;hadoop&#xff08;hdfsmapreduce&#xff09; Hadoop已经有十几年的历史&#xff0c;它是大数据领域的存储基石&#xff0c;HDFS目前仍然没有成熟替代品;MapR 文件系统在业内已经具有一定知名度了&#xff0c;不仅 MapR 宣布它自己的文件系统比 HDFS 快2-…

浙大版C语言题目集-函数题6

6-3 给定两个均不超过9的正整数a和n&#xff0c;要求编写函数求aaaaaa⋯aa⋯a&#xff08;n个a&#xff09;之和。 其中函数fn须返回的是n个a组成的数字&#xff1b;SumA返回要求的和。 #include <stdio.h>int fn( int a, int n ); int SumA( int a, int n );int main…