2024-08-09



// 引入Three.js库
import * as THREE from 'three';
 
// 创建场景
const scene = new THREE.Scene();
 
// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
 
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
 
// 创建几何体
const geometry = new THREE.BoxGeometry();
 
// 基础纹理
const basicTexture = new THREE.TextureLoader().load('path/to/basic.jpg');
const basicMaterial = new THREE.MeshBasicMaterial({ map: basicTexture });
const basicCube = new THREE.Mesh(geometry, basicMaterial);
scene.add(basicCube);
 
// 凹凸纹理
const bumpTexture = new THREE.TextureLoader().load('path/to/bump.jpg');
const bumpMaterial = new THREE.MeshPhongMaterial({ map: basicTexture, bumpMap: bumpTexture, bumpScale: 1 });
const bumpCube = new THREE.Mesh(geometry, bumpMaterial);
scene.add(bumpCube);
 
// 法向贴图
const normalTexture = new THREE.TextureLoader().load('path/to/normal.jpg');
const normalMaterial = new THREE.MeshPhongMaterial({ normalMap: normalTexture });
const normalCube = new THREE.Mesh(geometry, normalMaterial);
scene.add(normalCube);
 
// 环境贴图
const envTexture = new THREE.TextureLoader().load('path/to/env.jpg');
const envMaterial = new THREE.MeshPhongMaterial({ envMap: envTexture });
const envCube = new THREE.Mesh(geometry, envMaterial);
scene.add(envCube);
 
// Canvas贴图
function generateCanvasTexture() {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  canvas.width = 128;
  canvas.height = 128;
  ctx.fillStyle = 'red';
  ctx.fillRect(0, 0, 64, 64);
  ctx.fillStyle = 'green';
  ctx.fillRect(64, 0, 64, 64);
  return new THREE.CanvasTexture(canvas);
}
const canvasTexture = generateCanvasTexture();
const canvasMaterial = new THREE.MeshPhongMaterial({ map: canvasTexture });
const canvasCube = new THREE.Mesh(geometry, canvasMaterial);
scene.add(canvasCube);
 
// 设置相机位置并开始渲染循环
camera.position.z = 5;
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

这段代码展示了如何在Three.js中加载并应用不同类型的贴图。它首先创建了一个场景、相机和渲染器,然后定义了一个立方体几何体。接着,它演示了如何使用基本纹理、凹凸纹理、法向贴图、环境贴图和Canvas贴图。最后,它设置了相机位置并启动了渲染循环。

2024-08-09



// 引入Three.js库
import * as THREE from 'three';
 
// 创建场景
const scene = new THREE.Scene();
 
// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
 
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
 
// 加载3D模型
const onModelLoad = (object) => {
  // 将模型的坐标系统转换为右手坐标系统
  object.traverse(function (child) {
    if (child.isMesh) {
      child.geometry.center();
    }
  });
 
  // 将模型添加到场景中
  scene.add(object);
 
  // 设置相机位置并对准场景中心
  camera.position.z = 5;
  const controls = new THREE.OrbitControls(camera, renderer.domElement);
  controls.target.set(0, 0, 0);
  controls.update();
};
 
const loader = new THREE.GLTFLoader();
loader.load('path/to/your/model.glb', onModelLoad, (xhr) => {
  console.log((xhr.loaded / xhr.total * 100) + '% loaded');
}, (error) => {
  console.error(error);
});
 
// 渲染循环
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
 
animate();

这段代码展示了如何使用Three.js加载一个GLB格式的3D模型,并将其添加到场景中。同时,代码中包含了将模型的坐标系统从模型原始坐标系统转换为Three.js使用的右手坐标系统的逻辑。最后,通过OrbitControls类提供的相机跟踪功能,用户可以绕模型的中心视图来查看场景。

2024-08-09

要在JavaScript数组中移除特定的对象,可以使用filter方法来创建一个新数组,该数组不包含要移除的对象。这里是一个例子:




let array = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }];
 
// 要移除的对象的id
let idToRemove = 2;
 
// 使用filter方法创建一个不包含特定对象的新数组
array = array.filter(item => item.id !== idToRemove);
 
console.log(array);
// 输出: [{ id: 1, name: 'Alice' }, { id: 3, name: 'Charlie' }]

在这个例子中,我们使用了一个箭头函数item => item.id !== idToRemove来测试数组中的每个元素,并保留那些不符合条件的元素。这样我们就得到了一个新的数组,其中不包含具有特定id的对象。

2024-08-09

在JavaScript中,删除数组中的某个元素可以通过多种方法实现,以下是六种简洁的方法:

  1. 使用splice()方法:



let arr = [1, 2, 3, 4, 5];
let index = arr.indexOf(3);
arr.splice(index, 1); // 删除元素3
  1. 使用filter()方法:



let arr = [1, 2, 3, 4, 5];
arr = arr.filter(item => item !== 3); // 删除元素3
  1. 使用slice()方法结合concat()方法:



let arr = [1, 2, 3, 4, 5];
let index = arr.indexOf(3);
arr = arr.slice(0, index).concat(arr.slice(index + 1)); // 删除元素3
  1. 使用slice()方法结合展开运算符:



let arr = [1, 2, 3, 4, 5];
let index = arr.indexOf(3);
arr = [...arr.slice(0, index), ...arr.slice(index + 1)]; // 删除元素3
  1. 使用forEach()结合push()方法:



let arr = [1, 2, 3, 4, 5];
let newArr = [];
arr.forEach(item => {
  if (item !== 3) {
    newArr.push(item);
  }
});
arr = newArr; // 删除元素3
  1. 使用map()方法:



let arr = [1, 2, 3, 4, 5];
arr = arr.map(item => item === 3 ? null : item).filter(item => item); // 删除元素3

以上方法均可以实现删除数组中的特定元素,选择合适的方法取决于具体场景和个人喜好。

2024-08-09



// 检查值是否为 null、undefined 或 NaN
function isNil(value) {
  return value === null || value === undefined || Number.isNaN(value);
}
 
// 转换 null、undefined 或 NaN 为指定的默认值
function defaultTo(value, defaultValue) {
  return isNil(value) ? defaultValue : value;
}
 
// 检查值是否不是 null、undefined 或 NaN
function isNotNil(value) {
  return value !== null && value !== undefined && !Number.isNaN(value);
}
 
// 转换 null 或 undefined 为 null
function nullify(value) {
  return (value === undefined) ? null : value;
}
 
// 检查值是否为 null 或 undefined
function isNullOrUndefined(value) {
  return value === null || value === undefined;
}
 
// 检查值是否为 NaN
function isNaN(value) {
  return Number.isNaN(value);
}
 
// 使用提供的回调函数处理 null 或 undefined 值
function nullthrows(value, message) {
  if (value === null || value === undefined) {
    throw new Error(message || 'Got a null or undefined value');
  }
  return value;
}
 
// 使用提供的回调函数处理 NaN 值
function nanthrows(value, message) {
  if (Number.isNaN(value)) {
    throw new Error(message || 'Got a NaN value');
  }
  return value;
}
 
// 使用提供的回调函数处理 null、undefined 或 NaN 值
function nullish(value, callback) {
  if (value === null || value === undefined || Number.isNaN(value)) {
    return callback(value);
  }
  return value;
}
 
// 使用提供的默认值处理 null、undefined 或 NaN 值
function nullishCoalesce(value, defaultValue) {
  return value ?? defaultValue;
}
 
// 使用提供的回调函数处理 null 或 undefined 值,并返回处理结果
function nullCallback(value, callback) {
  return (value === null || value === undefined) ? callback(value) : value;
}
 
// 使用提供的回调函数处理 NaN 值,并返回处理结果
function nanCallback(value, callback) {
  return Number.isNaN(value) ? callback(value) : value;
}
 
// 使用提供的回调函数处理 null 或 undefined 或 NaN 值,并返回处理结果
function nullishCallback(value, callback) {
  if (value === null || value === undefined || Number.isNaN(value)) {
    return callback(value);
  }
  return value;
}
 
// 使用提供的默认值处理 null、undefined 或 NaN 值,并返回处理结果
function nullishDefault(value, defaultValue) {
  return value ?? defaultValue;
}
 
// 使用提供的回调函数处理 nul
2024-08-09

报错解释:

Vue3+TS+Vite项目在打包后出现静态资源(如JavaScript和CSS文件)404无法加载,通常是由于资源的引用路径不正确导致的。可能的原因包括:

  1. 静态资源的引用路径不正确,可能是相对路径或者绝对路径设置错误。
  2. 打包配置问题,可能是Vite或者Vue3的配置项没有正确设置。
  3. 服务器配置问题,如Nginx或Apache没有正确配置为静态资源服务的目录。
  4. 文件确实不存在于服务器的指定路径。

解决方法:

  1. 检查Vite配置文件是否正确设置了base选项,这个选项会影响资源的引用路径。
  2. 确保打包后的文件确实存在于正确的输出目录中。
  3. 如果使用了服务器如Nginx或Apache,检查服务器配置是否正确指向了静态资源目录。
  4. 清除缓存并重新打包部署,有时候是因为浏览器缓存了旧的资源。
  5. 检查控制台网络请求信息,查看404错误的具体资源路径,确认路径是否正确。
  6. 如果是路由的问题,确保Vue Router的模式(mode)设置正确,对于SPA应用通常应该是history模式。

如果以上步骤无法解决问题,可以进一步检查服务器的访问日志,查看更详细的错误信息。

2024-08-09

在Windows 10上升级Node.js版本,可以通过以下步骤进行:

  1. 打开命令提示符(CMD)或PowerShell。
  2. 运行以下命令以安装nvm(Node Version Manager):



nvm install latest
  1. 确认安装成功后,可以通过以下命令切换到新版本:



nvm use latest
  1. 如果需要设置新版本为默认版本,可以使用:



nvm alias default latest
  1. 检查Node.js版本,确保升级成功:



node -v

注意:如果系统中已安装旧版本的Node.js,可能需要先卸载旧版本再进行升级。

如果没有安装nvm,可以从Node.js官网下载最新的安装程序来进行升级:

  1. 访问Node.js官网下载页面:https://nodejs.org/en/download/
  2. 下载Windows Installer (.msi)。
  3. 运行安装程序,按照提示完成安装。

确保在升级前备份重要数据,以防万一升级过程中出现问题。

2024-08-09

报错解释:

这个错误表示JavaScript运行时的堆内存已经达到了限制,无法分配更多的内存。JavaScript在浏览器中运行时,有一个内存限制,如果尝试使用的内存超过这个限制,就会发生内存溢出错误。

解决方法:

  1. 优化代码:检查代码中是否有内存泄露,例如未释放的全局变量或者闭包,并修复它们。
  2. 增加内存限制:如果你在Node.js环境中遇到这个问题,可以通过命令行参数来增加内存限制。例如,在Node.js中运行node --max-old-space-size=4096 index.js将会给JavaScript分配4GB的内存。
  3. 分批处理数据:如果问题是由处理大量数据造成的,尝试分批次处理数据,而不是一次性处理所有数据。
  4. 使用更好的算法:对于需要大量内存的操作,考虑是否有更好的算法可以减少内存使用。
  5. 重启应用:如果是长时间运行的服务,可以定期重启应用以清理内存。

确保在进行更改时进行充分的测试,以确保解决方案不会引入新的问题。

2024-08-09

Mapbox GL JS 是一个用于创建交互式地图的开源库。以下是如何使用 Mapbox GL JS 创建一个简单的地图实例:

  1. 首先,在 HTML 文件中包含 Mapbox GL JS 库:



<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mapbox GL JS 示例</title>
<script src='https://api.mapbox.com/mapbox-gl-js/v2.3.1/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v2.3.1/mapbox-gl.css' rel='stylesheet' />
</head>
<body>
<div id='map' style='width: 100%; height: 400px;'></div>
<script>
  1. 接下来,在脚本标签中编写初始化地图和添加图层的代码:



mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN'; // 替换为你的 Mapbox 访问令牌
var map = new mapboxgl.Map({
    container: 'map', // 地图容器的 ID
    style: 'mapbox://styles/mapbox/streets-v11', // 地图样式
    center: [0, 0], // 地图中心点坐标
    zoom: 1 // 地图缩放级别
});
 
// 地图加载完成后的回调函数
map.on('load', function() {
    // 添加图层
    map.addLayer({
        'id': 'points-of-interest',
        'type': 'symbol',
        'source': {
            'type': 'geojson',
            'data': {
                'type': 'FeatureCollection',
                'features': [
                    {
                        'type': 'Feature',
                        'geometry': {
                            'type': 'Point',
                            'coordinates': [0, 0]
                        }
                    }
                ]
            }
        },
        'layout': {
            'icon-image': 'harbor-15',
            'icon-size': 1
        }
    });
});
</script>
</body>
</html>

在这个例子中,我们首先引入了 Mapbox GL JS 库,并设置了地图的容器。然后,我们创建了一个新的 Mapbox 地图实例,并在地图加载完成后,通过 map.on('load', function() {...}) 添加了一个新的图层,这个图层是一个点图层,使用 GeoJSON 数据源,并显示一个图标。

请确保将 'YOUR_MAPBOX_ACCESS_TOKEN' 替换为你自己的 Mapbox 访问令牌,你可以在 Mapbox 官网注册账号后获取。

这个简单的示例展示了如何使用 Mapbox GL JS 创建一个地图,并向其添加一个自定义图层。

2024-08-09

在JavaScript中,可以使用多种方法来合并或拼接字符串。以下是五种常见的方法:

  1. 使用加号(+)操作符。
  2. 使用字符串的concat方法。
  3. 使用模板字符串(ES6特性)。
  4. 使用数组的join方法。
  5. 使用String.prototype.valueOfString.prototype.toString方法。

以下是每种方法的示例代码:




// 方法1: 使用加号操作符
let str1 = "Hello";
let str2 = "World";
let result1 = str1 + " " + str2; // "Hello World"
 
// 方法2: 使用concat方法
let result2 = str1.concat(" ", str2); // "Hello World"
 
// 方法3: 使用模板字符串(ES6)
let result3 = `${str1} ${str2}`; // "Hello World"
 
// 方法4: 使用数组的join方法
let result4 = [str1, " ", str2].join(""); // "Hello World"
 
// 方法5: 使用valueOf或toString方法
let result5 = String(str1).valueOf() + " " + String(str2).valueOf(); // "Hello World"
 
// 输出结果
console.log(result1); // "Hello World"
console.log(result2); // "Hello World"
console.log(result3); // "Hello World"
console.log(result4); // "Hello World"
console.log(result5); // "Hello World"

每种方法都可以实现字符串的拼接,选择哪种方法取决于具体的编码风格和需求。