效果如下图所示:
模型正常交互,当按下键盘上的shift键的时候,按住鼠标可以自由的在模型上拖动纹理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 导入three.js -->
<script src="/libs/build/three.js"></script>
<script src="/libs/js/controls/OrbitControls.js"></script>
<script src="/libs/js/controls/PointerLockControls.js"></script>
<script src="/libs/js/loaders/GLTFLoader.js"></script>
<script src="/libs/js/renderers/CSS2DRenderer.js"></script>
<script src="/libs/js/loaders/FBXLoader.js"></script>
<script src="/libs/js/loaders/OBJLoader.js"></script>
<script src="/libs/js/loaders/MTLLoader.js"></script>
<script src="/libs/js/libs/fflate.min.js"></script>
<script src="/libs/js/loaders/DRACOLoader.js"></script>
</head>
<body>
<div id="webgl-output"></div>
<script src="./textrueMove.js"></script>
</body>
</html>
var scene; //----场景
var camera; //----摄像机
var renderer; //----渲染器
var mouse = new THREE.Vector2();
function init() {
//----------------------基础设置------------------------
//页面宽高
var innerWidth=window.innerWidth;
var innerHeight=window.innerHeight;
// 创建场景
scene = new THREE.Scene();
// 设置摄像机
camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 2000)
// 创建渲染器
renderer = new THREE.WebGLRenderer({ logarithmicDepthBuffer: true });
// 设置渲染器的初始颜色
renderer.setClearColor(new THREE.Color(0xeeeeee));
// 设置输出canvas画面的大小
renderer.setSize(innerWidth, innerHeight)
// 设置渲染物体阴影
renderer.shadowMapEnabled = true;
//设置为RGB颜色
renderer.outputEncoding = THREE.sRGBEncoding;
// 添加三维坐标系(红:x、绿:y、蓝:z)
var axes = new THREE.AxisHelper(20)
scene.add(axes);
//添加环境光
var ambientLight = new THREE.AmbientLight('#1f1f1f');
scene.add(ambientLight);
//添加平行光
directionalLight = new THREE.DirectionalLight("#858585");
directionalLight.position.set(500, 500, 500);
directionalLight.shadow.camera.near = 20; //产生阴影的最近距离
directionalLight.shadow.camera.far = 200; //产生阴影的最远距离
directionalLight.shadow.camera.left = -50; //产生阴影距离位置的最左边位置
directionalLight.shadow.camera.right = 50; //最右边
directionalLight.shadow.camera.top = 50; //最上边
directionalLight.shadow.camera.bottom = -50; //最下面
//开启阴影投射
directionalLight.castShadow = true;
scene.add(directionalLight);
// 设置相机位置和朝向
camera.position.x = 300;
camera.position.y = 300;
camera.position.z = 0;
let v = new THREE.Vector3(0, -200, 0);//向量
camera.lookAt(v)
//定义OrbitControls控制器,用于场景交互
var controls = new THREE.OrbitControls( camera, renderer.domElement );
//控制缩放范围
controls.minDistance = 2;
//相机距离观察目标点极大距离——模型最小状态
controls.maxDistance = 500;
// 上下旋转范围
controls.minPolarAngle = -Math.PI/2;
controls.maxPolarAngle = Math.PI/2;
// controls.target = v;//可以设置控制器的交互中心,默认是原点
// 将渲染器输出添加html元素中
document.getElementById('webgl-output').appendChild(renderer.domElement);
//------------------------加载模型和贴图-----------------------
//创建一个纹理对象
const texture = new THREE.TextureLoader().load('/model/image.png',function(){
renderer.render(scene, camera); //材质导入后渲染一下,保证出来的初始画面有贴图
});
// 创建材料,并将贴图应用到其map属性上
const material = new THREE.MeshBasicMaterial({
map: texture,
});
//加载obj模型
const loader = new THREE.OBJLoader();
loader.load('/model/123.obj', function(object) {
scene.add(object);
//将材质应用到模型上
object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material = material;
}
});
renderer.render(scene, camera)
})
renderer.render(scene, camera);
//-----------------------交互控制&移动贴图-----------------------
// 标记是否按下Shift键
let isShiftKeyDown = false;
//监听鼠标按下事件若按下鼠标的同时按下了shift键则禁用OrbitControls的交互
document.addEventListener('mousedown', event => {
//当监听的事件是鼠标事件的时候可以用event.shiftKey、event.ctrlKey,而event.key==''这个是监听键盘事件的时候才有用
if (event.shiftKey) {
isShiftKeyDown = true;
controls.enablePan = false;//(用于控制OrbitControls控制器的平移缩放)
controls.enableZoom = false;
}
});
//监听鼠标松开事件
//若前面按下了shift键,状态复原(鼠标按下时会再设置)
document.addEventListener('mouseup', () => {
if (isShiftKeyDown) {
isShiftKeyDown = false;
controls.enablePan = true;
controls.enableZoom = true;
}
});
//若按下了shift键移动,则改变material.map.offset属性
document.addEventListener('mousemove', event => {
if (isShiftKeyDown) {
const { width, height } = texture.image;
const scaleX = 1 / width;
const scaleY = 1 / height;
material.map.offset.x -= event.movementX * scaleX;
material.map.offset.y += event.movementY * scaleY;
renderer.render(scene, camera)
}
});
controls.addEventListener('change', () => {
renderer.render(scene, camera)
});
}
window.onload = init