threejs元宇宙入门 | 大帅老猿threejs特训

前言

之前看到过很多用threejs制作的炫酷场馆,本人对3D方面也很感兴趣,所以一直想学习一下threejs的使用。最近刚好Web3D胖达老师出了一期threejs元宇宙实战特训的直播课,就跟着学了下来。虽然只有6个小时的课程,但是看完之后还是感觉收获满满,就用这篇文章记录一下自己第一次学习threejs的成果。

成果展示

先看一看学习成果吧!

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

创建场馆模型

想要实现上面的效果,需要先通过软件创建一个3D的场馆模型,再用threejs中的api将场馆渲染到页面上,并实现各种动效。

软件及其常用快捷键

这里使用的建模软件是Blender,开源、免费、功能全面。
在这里插入图片描述

创建场馆主体

打开Blender软件后,默认会展示一个立方体,摄像机和灯光,可以点击A键全选,再点击delete键删除。点击shift+A,添加柱体模型。
在这里插入图片描述
点击左下角添加柱体按钮,调整顶点的数值,顶点即柱体的边的数量,数值越大,柱体越接近圆柱。
在这里插入图片描述
再通过缩放将圆柱调整到合适的大小。
在这里插入图片描述
接下来需要将圆柱挖空,选中圆柱,按tab键进入编辑模式,按3进入面选择模式,选中顶面,右键选择内插面。在这里插入图片描述
通过鼠标调整内插面的大小,确定后再右键选择挤出面,向下挤出,直到贴近底面。在这里插入图片描述
接下来是制作场馆的入口部分,调整视角至俯视图,选择线框模式,通过框选删除几条边作为入口。
在这里插入图片描述
删除后可以看到墙的侧面是空的,需要处理一下。在这里插入图片描述
这里需要在编辑模式下按2切换到边选择模式,选中墙体的一条边,然后按E键可以向外拉出面。
在这里插入图片描述
再按1切换至点选择模式,先选择拉出面的顶点,再按shift选择另一侧墙壁的顶点,右键选择吸附至像素点、选中项->活动项,就可以将两个顶点合并到一起了。
在这里插入图片描述
重复操作其它几个顶点,就完成了场馆主体模型的搭建。在这里插入图片描述

创建中间立柱模型

同创建场馆主体一样,添加一个6边的柱体,调整至合适的大小和位置,调整物体位置时可以先按G键,再按X、Y、Z键使物体只在一个轴上移动。

然后需要将柱体从中间部分凸出,在编辑模式下,选择右上方的线框模式,在按2切换至线选择模式,选中6条竖边,按ctrl+R键生成一个横向的切边,调整至柱体中间部分。
在这里插入图片描述
再按S键缩放,将边向外拉出,就达到了凸出的效果。
在这里插入图片描述
然后再添加一个立方体,调整大小和位置,进入编辑模式,点选择模式,选中立方体上方的4个顶点,按S键将顶面拉大一点。在这里插入图片描述
接着在其顶部通过ctrl+R创建一个切面,再选中各边,挤出各个面。
在这里插入图片描述
点击左侧移动按钮,将挤出的面向上提。
在这里插入图片描述
切换俯视图视角,点选择模式,选中顶点,使用缩放将顶部的宽度缩小一倍。当选中y轴方向上的
4个顶点时,可以依次输入 S X 0.5,即可达到该效果。
在这里插入图片描述
最后再通过缩放调整一下长度,就完成了。
在这里插入图片描述

制作2023字体模型

接下来需要在入口处添加一个2023字样的字体屏幕,后面会在屏幕上播放烟花视频。
切换到物体模式,选择添加文本,沿x轴移动到入口位置,按tab键输入2023,通过旋转让文字立起来。
在这里插入图片描述
此时可以看到模型的原点在左下角,需要将原点设置在模型的中心,右键选择设置原点,原点->几何中心即可。再将文字旋转至和y轴平行。
还需要将文字增加一点厚度,可以通过右侧的修改器选项按钮,选择实体化,调整厚度。
在这里插入图片描述
最后再给模型加一个底座,调整好位置和大小即可。
在这里插入图片描述

制作屏幕模型

场馆左侧有一个方形屏幕,中间操作台的6个面上也都有一个屏幕,这些直接通过立方体调整大小和位置就可完成。入口正对面是一个曲面屏,这个刚好可以利用场馆内侧的墙壁来制作。
选择场馆主体进入编辑模式,面选择模式,选中x轴两边数量相等的内侧墙壁面,按shift+D复制,将复制出来的面向外拉一点,然后右键,分离,选中项,调整至合适位置即可。
在这里插入图片描述

设置墙体背景

由于场馆的地面和墙体是一个物体,现在要给场馆的地面和墙体设置不同的背景,所以需要先分离一下。选中场馆,进入编辑模式,面选择模式,选中地面,右键,分离,选中项。在软件右侧场景集合里可以给每个模型重新命名,方便后面在threejs中获取到指定的模型。
在这里插入图片描述

准备一张大理石纹理的图片和一张墙体的图片,选中地面,点击软件上方的shading按钮,点击新建,新增一个材质。在这里插入图片描述
将准备好的大理石纹理图片拖入下图位置,点击颜色旁边的黄点,按住鼠标左键,将其连接到右边的基础色上,这样地面上就出现了大理石花纹了。
在这里插入图片描述
在编辑模式下点击上方UV Editing按钮,可以看到地面上只展示了图片上的一小块区域,我们需要让图片在地面上多平铺几次,让场馆看起来更大一些。在这里插入图片描述
鼠标点击左边区域,按A键全选,点击缩放按钮,将图中的圆向外拉倒合适大小即可。
在这里插入图片描述
点击上方modeling按钮,材质预览,可查看渲染效果。
在这里插入图片描述
墙面的背景操作步骤相同,选用不同的图片即可。因为墙体的面比较多,可以先在物体模式下选中墙体模型,再进入编辑模式,按A键全选,这样就可以在UV模式下看到所有面了。
在这里插入图片描述

调整屏幕UV

UV的位置和投影方式不对会导致视频播放时达不到我们想要的效果。方形屏幕的UV相对好调整一些,基本上只需要旋转UV的方向就可以了。

2023UV调整

由于2023现在任然是文字类型,需要先在物体模式下选中2023模型,右键,转换到,网格。在这里插入图片描述
在这里插入图片描述
选中2023,进入编辑模式,按A全选,点击上方UV Editing按钮,鼠标点击左侧UV编辑区域,按A全选,点击UV按钮,展开,块面投影,就可以看到2023正确显示在区域中了。
在这里插入图片描述
将UV选择模式切换至孤岛选择模式,调整一下2023的位置即可。
在这里插入图片描述

曲面屏UV调整

物体模式下选中曲面屏,进入编辑模式,点击上方UV Editing按钮,可以发现投影的方向是有问题的。在这里插入图片描述

老师在课上没有讲过曲面屏的调整方式,这里自己摸索了一下,就用了感觉比较简单的一种方法。点击左侧UV区域,按A键全选,然后点击上方UV,展开,展开,就可以看到曲面屏的面正确的显示在方框区域了。在这里插入图片描述
再通过变换将曲面屏铺满方框区域就可以了。
在这里插入图片描述

导出glb文件

全部完成后,点击左上方文件,导出,gltf 2.0,给文件命名,备用。在这里插入图片描述

获取角色模型

sketchfab上有很多已经做好的人物模型,可以直接下载使用。下载完成后需要在mixamo上给角色加上动作动画,这里我就使用胖达老师给我们准备好的角色。在这里插入图片描述

Threejs

所有准备工作都完成后,就可以开始写代码了。
使用vite新建一个项目,在项目中安装three即可。

npm install three

在这里插入图片描述
然后将准备好的模型、视频放入项目中,在srcx目录下新建一个js文件,并在index.html文件中引入。
在这里插入图片描述

创建场景、相机、渲染器

首先,我们需要创建threejs中最基础的3样东西,场景、相机、渲染器。

import * as THREE from 'three';
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";

// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.01,100);
// 创建渲染器
const renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);

// 设置背景
scene.background = new THREE.Color(0.2,0.2,0.2);

加载灯光

// 环境光
const ambientLight = new THREE.AmbientLight(0xffffff,0.8);
scene.add(ambientLight);

// 方向光
const directionLight = new THREE.DirectionalLight(0xffffff,0.2);
scene.add(directionLight);

加载场馆

使用GLTFLoader加载glb模型。

// 创建场馆
// 加载gltf/glb模型
new GLTFLoader().load("../resources/models/changguan.glb",(gltf)=>{
  console.log(gltf);
  scene.add(gltf.scene);

});

帧循环

// 帧循环
function animate(){
  requestAnimationFrame(animate);

  renderer.render(scene,camera);

}

animate();

做完这些,就已经可以在页面中看到我们制作的场馆模型了。

设置相机

运行项目后,在浏览器打开发现看到的画面和我们预期的不太一样。在这里插入图片描述

这是因为相机的位置问题,相机默认在原点,可以通过position将相机向外面挪一挪。

// 设置相机位置
camera.position.set(15,5,0);

再通过OrbitControls使用户可以控制相机,就可以通过鼠标来控制相机,查看整个场馆。

// 用户控制相机
const controls = new OrbitControls(camera,renderer.domElement);

在这里插入图片描述

点亮屏幕

接下来需要让各个屏幕播放对应的视频。在控制台中,可以看到在scene.children中存放着场馆中的所有物体模型。在这里插入图片描述
不过我们可以用一种更简单的方法拿到我们需要的模型,traverse函数。

  gltf.scene.traverse(child=>{
    console.log("name:",child.name);
  })

在这里插入图片描述
给对应的屏幕设置视频投影。

    if(child.name=='2023' || child.name=='造型01'){
      const video = document.createElement('video');
      video.src = "../resources/yanhua.mp4";
      video.muted = true;
      video.autoplay = "autoplay";
      video.loop = true;
      video.play();
      const videoTexture = new THREE.VideoTexture(video);
      const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});
      child.material = videoMaterial;
    }
    if(child.name=='屏幕1'||child.name=='操作屏'){
      const video = document.createElement('video');
      video.src = "../resources/video01.mp4";
      video.muted = true;
      video.autoplay = "autoplay";
      video.loop = true;
      video.play();
      const videoTexture = new THREE.VideoTexture(video);
      const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});
      child.material = videoMaterial;
    }
    if(child.name=='曲面屏'){
      const video = document.createElement('video');
      video.src = "../resources/video02.mp4";
      video.muted = true;
      video.autoplay = "autoplay";
      video.loop = true;
      video.play();
      const videoTexture = new THREE.VideoTexture(video);
      const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});
      child.material = videoMaterial;
    }

在这里插入图片描述
这里视频在播放时可能会有横向播放或者倒着播放的情况,这是因为该物体的UV方向问题,在blender中选中该模型,进入UV模式,旋转播放视频的面UV方向即可。

加载角色模型

和加载场馆模型类似。

// 创建人物模型
let playerMesh;

new GLTFLoader().load("../resources/models/player.glb",gltf=>{

  // 这里需要将人物模型提取出来,待后面备用
  playerMesh=gltf.scene;
  scene.add(playerMesh);

  // 人物位置
  playerMesh.position.set(13,0.18,0);

  // 人物方向
  playerMesh.rotateY(-Math.PI/2);
})

这样,我们就能看到角色出现在场馆中了。
在这里插入图片描述

角色控制

接下来需要让角色动起来,用按键W使角色向前移动。我们可以通过addEventListener实现。

window.addEventListener('keydown',e=>{
  // 前进
  if(e.key==='w'){

    playerMesh.translateZ(0.1);

  }
})

这里不再让用户控制相机,让用户控制角色,使相机跟随角色移动,永远处在角色的后方偏上的位置。将设置相机的代码先注释。
在这里插入图片描述
然后让相机跟随角色,给角色增加点光源。

在这里插入图片描述
为防止画面过亮,可以降低环境光亮度。
在这里插入图片描述
完成这些代码后,当我们按下W键,相机就会随着角色一起前进了。在这里插入图片描述

然后通过监听鼠标在浏览器窗口中水平方向的移动距离来控制角色转向。

// 鼠标转向
let prePos;
window.addEventListener('mousemove',e=>{
  if(prePos){
    playerMesh.rotateY((prePos - e.clientX)*0.01);
  }
  prePos = e.clientX;
  
})

在这里插入图片描述

通过THREE.Raycaster实现角色碰撞检测。
在这里插入图片描述
在这里插入图片描述

截取角色站立、行走动画

由于角色的站立和行走动画是在一起的,所以需要通过subclip函数剪切出我们需要的动画。

  // 剪切人物动作
  playerMixer = new THREE.AnimationMixer(gltf.scene);

  // 前30帧为行走动画
  const clipWalk = THREE.AnimationUtils.subclip(gltf.animations[0],'walk',0,30);
  actionWalk = playerMixer.clipAction(clipWalk);
  // actionWalk.play();

  // 后面为站立动画
  const clipIdle = THREE.AnimationUtils.subclip(gltf.animations[0],'idle',31,281);
  actionIdle = playerMixer.clipAction(clipIdle);

  // 默认站立
  actionIdle.play();

站立效果:
在这里插入图片描述

行走效果:
在这里插入图片描述
为了使动画切换更自然,使用渐变切换动画工具函数。

// 给动作切换时加一个淡入淡出效果,避免角色抖动
function crossPlay(curAction, newAction) {
  curAction.fadeOut(0.3);
  newAction.reset();
  newAction.setEffectiveWeight(1);
  newAction.play();
  newAction.fadeIn(0.3);
}

在按下W键时由站立到行走,松开W键时由行走到站立。

let isWalk = false;
const playerHalfHeight = new THREE.Vector3(0,0.4,0);
window.addEventListener('keydown',e=>{
  // 前进
  if(e.key==='w'){
    // 碰撞检测
    const curPos = playerMesh.position.clone();
    playerMesh.translateZ(1);
    const frontPos = playerMesh.position.clone();
    playerMesh.translateZ(-1);

    const frontVector3 = frontPos.sub(curPos).normalize();
    const raycasterFront = new THREE.Raycaster(playerMesh.position.clone().add(playerHalfHeight),frontVector3);
    const collisionResultsFrontObjs = raycasterFront.intersectObjects(scene.children);
    if(collisionResultsFrontObjs && collisionResultsFrontObjs[0] && collisionResultsFrontObjs[0].distance > 1){
      playerMesh.translateZ(0.1);
    }

    if(!isWalk){
      crossPlay(actionIdle, actionWalk);
      isWalk = true;
    }
  }
})

window.addEventListener('keyup',e=>{
  if(e.key==='w'){
    crossPlay(actionWalk, actionIdle);
    isWalk = false;
  }
})

在这里插入图片描述

增加阴影

最后给角色和场馆加上阴影,就大功告成了!在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

完整代码

import * as THREE from 'three';
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";

let playerMixer;
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.01,100);
// 创建渲染器
const renderer = new THREE.WebGLRenderer({antialias:true});
// 打开renderer阴影
renderer.shadowMap.enabled = true;

renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);

// 设置背景
scene.background = new THREE.Color(0.2,0.2,0.2);

// 设置相机位置
// camera.position.set(15,5,0);

// 用户控制相机
// const controls = new OrbitControls(camera,renderer.domElement);


// 环境光
const ambientLight = new THREE.AmbientLight(0xffffff,0.2);
scene.add(ambientLight);

// 方向光
const directionLight = new THREE.DirectionalLight(0xffffff,0.2);
// 打开灯光阴影
directionLight.castShadow = true;
scene.add(directionLight);

// 设置灯光阴影贴图大小
directionLight.shadow.mapSize.width = 2048;
directionLight.shadow.mapSize.height = 2048;

// 设置阴影体 远近 大小
const shadowDistance = 20;
directionLight.shadow.camera.near = 0.1; //默认值
directionLight.shadow.camera.far = 40; //默认值
directionLight.shadow.camera.left = -shadowDistance;
directionLight.shadow.camera.right = shadowDistance;
directionLight.shadow.camera.top = shadowDistance;
directionLight.shadow.camera.bottom = -shadowDistance;
directionLight.shadow.bias = -0.001;

directionLight.position.set(10,10,10);
directionLight.lookAt(new THREE.Vector3(0,0,0));

// 创建一个绿色盒子
// const boxGeometry = new THREE.BoxGeometry(1,1,1);
// const boxMaterial = new THREE.MeshBasicMaterial({color:0x00ff00});
// const boxMesh = new THREE.Mesh(boxGeometry,boxMaterial);
// scene.add(boxMesh);

// 创建场馆
// 加载gltf/glb模型
new GLTFLoader().load("../resources/models/changguan.glb",(gltf)=>{
  // console.log(gltf);
  scene.add(gltf.scene);

  gltf.scene.traverse(child=>{

    // 场馆投影
    child.castShadow = true;
    child.receiveShadow = true;

    if(child.name=='2023' || child.name=='造型01'){
      const video = document.createElement('video');
      video.src = "../resources/yanhua.mp4";
      video.muted = true;
      video.autoplay = "autoplay";
      video.loop = true;
      video.play();
      const videoTexture = new THREE.VideoTexture(video);
      const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});
      child.material = videoMaterial;
    }
    if(child.name=='屏幕1'||child.name=='操作屏'){
      const video = document.createElement('video');
      video.src = "../resources/video01.mp4";
      video.muted = true;
      video.autoplay = "autoplay";
      video.loop = true;
      video.play();
      const videoTexture = new THREE.VideoTexture(video);
      const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});
      child.material = videoMaterial;
    }
    if(child.name=='曲面屏'){
      const video = document.createElement('video');
      video.src = "../resources/video02.mp4";
      video.muted = true;
      video.autoplay = "autoplay";
      video.loop = true;
      video.play();
      const videoTexture = new THREE.VideoTexture(video);
      const videoMaterial = new THREE.MeshBasicMaterial({map: videoTexture});
      child.material = videoMaterial;
    }
  })

});

// 创建人物模型
let playerMesh;
let actionIdle; // 人物站立动画 
let actionWalk; // 人物走路动画
new GLTFLoader().load("../resources/models/player.glb",gltf=>{
  
  gltf.scene.traverse(child=>{
    child.receiveShadow = true;
    child.castShadow = true;
  })

  // 这里需要将人物模型提取出来,待后面备用
  playerMesh=gltf.scene;
  scene.add(playerMesh);

  // 人物位置
  playerMesh.position.set(13,0.18,0);

  // 人物方向
  playerMesh.rotateY(-Math.PI/2);

  // 相机跟着人物走
  playerMesh.add(camera);

  camera.position.set(0,2,-3);
  // 让相机看着人物的原点
  // camera.lookAt(playerMesh.position);
  camera.lookAt(new THREE.Vector3(0,0,1));

  // 增加人物的亮度,给人物背后加一个点光源
  const pointLight = new THREE.PointLight(0xffffff,0.8);
  scene.add(pointLight);
  // 让点光源跟着人物移动
  playerMesh.add(pointLight);
  // 设置点光源位置
  pointLight.position.set(0,1.5,-2);





  // 剪切人物动作
  playerMixer = new THREE.AnimationMixer(gltf.scene);

  // 前30帧为行走动画
  const clipWalk = THREE.AnimationUtils.subclip(gltf.animations[0],'walk',0,30);
  actionWalk = playerMixer.clipAction(clipWalk);
  // actionWalk.play();

  // 后面为站立动画
  const clipIdle = THREE.AnimationUtils.subclip(gltf.animations[0],'idle',31,281);
  actionIdle = playerMixer.clipAction(clipIdle);

  // 默认站立
  actionIdle.play();

})

let isWalk = false;
const playerHalfHeight = new THREE.Vector3(0,0.4,0);
window.addEventListener('keydown',e=>{
  // 前进
  if(e.key==='w'){
    // 碰撞检测
    const curPos = playerMesh.position.clone();
    playerMesh.translateZ(1);
    const frontPos = playerMesh.position.clone();
    playerMesh.translateZ(-1);

    const frontVector3 = frontPos.sub(curPos).normalize();
    const raycasterFront = new THREE.Raycaster(playerMesh.position.clone().add(playerHalfHeight),frontVector3);
    const collisionResultsFrontObjs = raycasterFront.intersectObjects(scene.children);
    if(collisionResultsFrontObjs && collisionResultsFrontObjs[0] && collisionResultsFrontObjs[0].distance > 1){
      playerMesh.translateZ(0.1);
    }

    if(!isWalk){
      crossPlay(actionIdle, actionWalk);
      isWalk = true;
    }
  }
})

window.addEventListener('keyup',e=>{
  if(e.key==='w'){
    crossPlay(actionWalk, actionIdle);
    isWalk = false;
  }
})

// 鼠标转向
let prePos;
window.addEventListener('mousemove',e=>{
  if(prePos){
    playerMesh.rotateY((prePos - e.clientX)*0.01);
  }
  prePos = e.clientX;
  
})

window.addEventListener('resize',()=>{
  camera.aspect = window.innerWidth/window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(window.innerWidth,window.innerHeight);
},false);

// 给动作切换时加一个淡入淡出效果,避免角色抖动
function crossPlay(curAction, newAction) {
  curAction.fadeOut(0.3);
  newAction.reset();
  newAction.setEffectiveWeight(1);
  newAction.play();
  newAction.fadeIn(0.3);
}

// 帧循环
function animate(){
  requestAnimationFrame(animate);

  renderer.render(scene,camera);

  if(playerMixer){
    playerMixer.update(0.015);
  }

}

animate();
  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用 JavaScript 内置的 Date 对象来获取当日的时间戳。可以使用 Date.now() 或 new Date().getTime() 方法来获取当前时间的时间戳(以毫秒为单位)。如下所示: ``` // 使用 Date.now() 获取当前时间戳 console.log(Date.now()); // 使用 new Date().getTime() 获取当前时间戳 console.log(new Date().getTime()); ``` 请注意,Date.now() 方法是 JavaScript 1.5 中新增的,如果你的代码要求兼容早期版本的浏览器,可以使用 new Date().getTime() 方法来获取当前时间戳。 ### 回答2: 在JavaScript中,可以使用`Date`对象来获取当前的时间戳。时间戳是指从1970年1月1日00:00:00 UTC(世界协调时间)到指定时间的总毫秒数。 要获取当日的时间戳,首先需要创建一个`Date`对象来表示当前时间。然后使用`getTime()`方法获取该对象的时间戳。 下面是获取当日时间戳的示例代码: ```javascript // 创建一个表示当前时间的Date对象 var today = new Date(); // 设置时间为当日的起始时间(00:00:00) today.setHours(0, 0, 0, 0); // 获取当日的时间戳 var timestamp = today.getTime(); console.log(timestamp); ``` 在代码中,首先创建一个表示当前时间的`Date`对象`today`。然后使用`setHours()`方法将时间设置为当日的起始时间(00:00:00)。 最后,使用`getTime()`方法获取`today`对象的时间戳,并将其打印到控制台上。 需要注意的是,获取的时间戳是相对于1970年1月1日00:00:00 UTC的总毫秒数,如果需要获取当前时间的本地时间戳,可以使用`getTime()`方法的返回值。 ### 回答3: 要使用JavaScript获取当前的时间戳,可以使用`Date.now()`函数。这个函数返回的是自1970年1月1日以来的毫秒数。为了得到当日的时间戳,我们需要对得到的时间戳进行处理。 首先,我们需要创建一个`Date`对象来获取当前的日期和时间。然后,我们可以使用`getFullYear()`函数获取年份,`getMonth()`函数获取月份,`getDate()`函数获取日期。这些函数都返回一个整数。 接下来,我们可以使用`setHours()`函数将时间设置为0点,以获取当日开始的时间。然后,使用`setMinutes()`、`setSeconds()`和`setMilliseconds()`函数将分、秒和毫秒设置为0。最后,使用`getTime()`函数获取当日开始的时间戳。 以下是一个示例代码: ```javascript var now = new Date(); now.setHours(0, 0, 0, 0); var timestamp = now.getTime(); console.log(timestamp); ``` 以上代码会在浏览器的控制台输出当日开始的时间戳。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值