- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我真的很喜欢谷歌乐高构建网站上的相机控制。 https://www.buildwithchrome.com/builder
如何使用按钮控制视角?
放大/缩小和旋转到固定位置会很棒。
我正在玩 this 来自 Three.js/examples 的演示。也许有人可以告诉我一个方向。预先非常感谢您!
<div class="perspective">
<div class="rotate">
<div class="build-rotate">
<a data-rotate="315" href="#rotate315"></a>
<a data-rotate="45" href="#rotate0"></a>
<a data-rotate="225" href="#rotate225"></a>
<a data-rotate="135" href="#rotate135"></a>
<a class="rotate-free" href="#"></a>
<img src="https://www.buildwithchrome.com/v2-2-1.376043847035368998/img/build/rotate-indicator.png" style="transform: rotate(77.3493023426611deg);">
</div>
</div>
<a href="#" id="zoomIn" class="zoomin">+</a>
<a href="#" id="zoomOut" class="zoomout">-</a>
</div>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = 650;
var FLOOR = -250;
var container;
var camera, scene, controls;
var renderer;
var mesh;
var textureCube;
var cameraCube, sceneCube;
var loader;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
// CAMERA
camera = new THREE.PerspectiveCamera( 25, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
camera.position.set( 185, 40, 170 );
controls = new THREE.OrbitControls( camera, previewDiv );
controls.maxPolarAngle = Math.PI / 2;
controls.minDistance = 200;
controls.maxDistance = 500;
// SCENE
scene = new THREE.Scene();
// SKYBOX
sceneCube = new THREE.Scene();
cameraCube = new THREE.PerspectiveCamera( 25, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
sceneCube.add( cameraCube );
var r = "textures/cube/pisa/";
var urls = [ r + "px.jpg", r + "nx.jpg",
r + "py.jpg", r + "ny.jpg",
r + "pz.jpg", r + "nz.jpg" ];
textureCube = THREE.ImageUtils.loadTextureCube( urls );
var shader = THREE.ShaderLib[ "cube" ];
shader.uniforms[ "tCube" ].value = textureCube;
var material = new THREE.ShaderMaterial( {
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
depthWrite: false,
side: THREE.BackSide
} ),
mesh = new THREE.Mesh( new THREE.BoxGeometry( 100, 100, 100 ), material );
sceneCube.add( mesh );
// LIGHTS
var light = new THREE.PointLight( 0xffffff, 1 );
light.position.set( 2, 5, 1 );
light.position.multiplyScalar( 30 );
scene.add( light );
var light = new THREE.PointLight( 0xffffff, 0.75 );
light.position.set( -12, 4.6, 2.4 );
light.position.multiplyScalar( 30 );
scene.add( light );
scene.add( new THREE.AmbientLight( 0x050505 ) );
// RENDERER
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
renderer.domElement.style.position = "relative";
renderer.autoClear = false;
var previewDiv = document.getElementById("preview");
previewDiv.appendChild (renderer.domElement);
//
renderer.gammaInput = true;
renderer.gammaOutput = true;
// EVENTS
window.addEventListener( 'resize', onWindowResize, false );
window.addEventListener( 'mousemove', onDocumentMouseMove, false );
// LOADER
var start = Date.now();
// new way via CTMLoader and separate parts
loaderCTM = new THREE.CTMLoader( true );
document.body.appendChild( loaderCTM.statusDomElement );
var position = new THREE.Vector3( -105, -78, -40 );
var scale = new THREE.Vector3( 30, 30, 30 );
loaderCTM.loadParts( "models/ctm/camaro/camaro.js", function( geometries, materials ) {
hackMaterials( materials );
for ( var i = 0; i < geometries.length; i ++ ) {
var mesh = new THREE.Mesh( geometries[ i ], materials[ i ] );
mesh.position.copy( position );
mesh.scale.copy( scale );
scene.add( mesh );
}
loaderCTM.statusDomElement.style.display = "none";
var end = Date.now();
console.log( "load time:", end - start, "ms" );
}, { useWorker: true } );
}
//
function hackMaterials( materials ) {
for ( var i = 0; i < materials.length; i ++ ) {
var m = materials[ i ];
if ( m.name.indexOf( "Body" ) !== -1 ) {
var mm = new THREE.MeshPhongMaterial( { map: m.map } );
mm.envMap = textureCube;
mm.combine = THREE.MixOperation;
mm.reflectivity = 0.75;
materials[ i ] = mm;
} else if ( m.name.indexOf( "mirror" ) !== -1 ) {
var mm = new THREE.MeshPhongMaterial( { map: m.map } );
mm.envMap = textureCube;
mm.combine = THREE.MultiplyOperation;
materials[ i ] = mm;
} else if ( m.name.indexOf( "glass" ) !== -1 ) {
var mm = new THREE.MeshPhongMaterial( { map: m.map } );
mm.envMap = textureCube;
mm.color.copy( m.color );
mm.combine = THREE.MixOperation;
mm.reflectivity = 0.25;
mm.opacity = m.opacity;
mm.transparent = true;
materials[ i ] = mm;
} else if ( m.name.indexOf( "Material.001" ) !== -1 ) {
var mm = new THREE.MeshPhongMaterial( { map: m.map } );
mm.shininess = 30;
mm.color.setHex( 0x404040 );
mm.metal = true;
materials[ i ] = mm;
}
materials[ i ].side = THREE.DoubleSide;
}
}
//
function createScene( geometry, materials, x, y, z, s ) {
loader.statusDomElement.style.display = "none";
geometry.center();
hackMaterials( materials );
var material = new THREE.MeshFaceMaterial( materials );
mesh = new THREE.Mesh( geometry, material );
mesh.position.set( x, y, z );
mesh.scale.set( s, s, s );
scene.add( mesh );
}
//
function onWindowResize( event ) {
SCREEN_WIDTH = window.innerWidth;
SCREEN_HEIGHT = window.innerHeight;
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
camera.updateProjectionMatrix();
cameraCube.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
cameraCube.updateProjectionMatrix();
}
function onDocumentMouseMove(event) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
}
//
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
controls.update();
cameraCube.rotation.copy( camera.rotation );
renderer.clear();
renderer.render( sceneCube, cameraCube );
renderer.render( scene, camera );
}
.scene{
position: relative;
width: 1000px;
height: 1000px;
background-color: #eee;
}
.perspective{
position: absolute;
left: 24px;
top: 24px;
width: 60px;
z-index: 10;
}
.rotate {
border-radius: 5px;
width: 60px;
height: 60px;
background: #fff;
margin-bottom: 24px;
position: relative;
}
.rotate .build-rotate {
position: absolute;
height: 40px;
width: 40px;
top: 50%;
left: 50%;
margin-top: -20px;
margin-left: -20px;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
}
.rotate .build-rotate a {
float: left;
width: 20px;
margin: 0;
padding: 0;
height: 20px;
position: relative;
z-index: 26;
background: transparent url(https://www.buildwithchrome.com/v2-2-1.376043847035368998/img/v2/builder-rotator-bg.png) no-repeat 0 0;
background-size: 40px 240px;
}
.rotate .build-rotate a:nth-child(1) {
background-position: 0 0;
}
.rotate .build-rotate a:nth-child(1):hover {
background-position: 0 -160px;
}
.rotate .build-rotate a:nth-child(2) {
background-position: -20px 0;
}
.rotate .build-rotate a:nth-child(2):hover {
background-position: -20px -40px;
}
.rotate .build-rotate a:nth-child(3) {
background-position: 0 -20px;
}
.rotate .build-rotate a:nth-child(3):hover {
background-position: 0 -140px;
}
.rotate .build-rotate a:nth-child(4) {
background-position: -20px -20px;
}
.rotate .build-rotate a:nth-child(4):hover {
background-position: -20px -100px;
}
.rotate .build-rotate img {
position: absolute;
top: 10px;
left: 10px;
height: 20px;
width: 20px;
margin-top: 0;
margin-left: 0;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
z-index: 25;
}
.rotate .build-rotate .rotate-free, .rotate .build-rotate .rotate-free:hover, .rotate .build-rotate .rotate-free:active {
display: block;
width: 25px;
height: 25px;
position: absolute;
top: 7px;
left: 8px;
border-radius: 13px;
background: transparent;
}
a.zoomin, a.zoomout {
width: 60px;
height: 61px;
background-color: #fff;
border-radius: 4px;
display: block;
color: #555;
font-size: 40px;
border: none;
text-align: center;
background-position: center center;
background-repeat: no-repeat;
cursor: pointer;
position: relative;
}
a.zoomin {
border-bottom: 1px #f5f5f5 solid;
border-radius: 3px 3px 0 0;
}
a.zoomout {
border-top: 1px #f5f5f5 solid;
border-radius: 0 0 3px 3px;
}
a.zoomin:hover, a.zoomout:hover {
background-color: #f7f7f7;
}
<div class="scene">
</div>
<div class="perspective">
<div class="rotate">
<div class="build-rotate">
<a data-rotate="315" href="#rotate315"></a>
<a data-rotate="45" href="#rotate0"></a>
<a data-rotate="225" href="#rotate225"></a>
<a data-rotate="135" href="#rotate135"></a>
<a class="rotate-free" href="#"></a>
<img src="https://www.buildwithchrome.com/v2-2-1.376043847035368998/img/build/rotate-indicator.png" style="transform: rotate(77.3493023426611deg);">
</div>
</div>
<a href="#" id="zoomIn" class="zoomin">+</a>
<a href="#" id="zoomOut" class="zoomout">-</a>
</div>
最佳答案
我想这就是您正在寻找的。检查这个例子:
http://mrdoob.github.io/three.js/examples/misc_controls_pointerlock.html
基本上,您添加
<script src="js/controls/PointerLockControls.js"></script>
然后像这样的东西应该可以工作。
controls = new THREE.PointerLockControls( camera );
scene.add( controls.getObject() );
var onKeyDown = function ( event ) {
switch ( event.keyCode ) {
case 38: // up
case 87: // w
moveForward = true;
break;
case 37: // left
case 65: // a
moveLeft = true; break;
case 40: // down
case 83: // s
moveBackward = true;
break;
case 39: // right
case 68: // d
moveRight = true;
break;
case 32: // space
if ( canJump === true ) velocity.y += 350;
canJump = false;
break;
}
};
var onKeyUp = function ( event ) {
switch( event.keyCode ) {
case 38: // up
case 87: // w
moveForward = false;
break;
case 37: // left
case 65: // a
moveLeft = false;
break;
case 40: // down
case 83: // s
moveBackward = false;
break;
case 39: // right
case 68: // d
moveRight = false;
break;
}
};
仔细阅读整个代码的示例,这真的很有帮助!
关于javascript - ThreeJS 带按钮的相机控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32057003/
我们想要创建一个 3D 鞋子设计工具,您可以在其中设计图案并将其上传到鞋子上。 我正在尝试将图像放置在 Threejs Material 上。我可以更新 map ,但纹理很模糊。我是 Threejs
我正在尝试在 ThreeJS 中加载 FBX 模型。如果我加载模型,它只会从底部显示,而不是从顶部显示。似乎只渲染了一侧。 有没有人想解决这个问题? 我的加载函数: _LoadAnimatedMode
使用 Three.js,(虽然我相信这与数学更相关)我有一组可以创建二维几何体的二维点。例如正方形、矩形、五边形或自定义 2D 形状。基于原始的 2D 形状,我想创建一种方法来像附图那样均匀地向内或向
我正在尝试创建一个在所有方面都镜像的对象。它几乎可以正常工作,但我不确定我在这里做错了什么。我只能看到某些 Angular 部分反射,并且反射的范围比被反射的物体(大象)大得多。这是代码:
无论导入场景,还是通过代码创建每个网格和灯光,都会出现以下问题。 我的场景由一个平面、一个立方体和一个聚光灯组成。聚光灯在 y 轴上旋转 45 度。在示例 1 中,它位于点 (4, 0, 4)。在示例
上下文: 我正在开发一个非常简单的 THREE.JS 项目,我相信它已经以非常好的方式进行了优化。我正在使用 WebGLRenderer 来显示每 50 毫秒从音频信号中提取的大量波特图。这非常酷,但
我正在编写一个全景查看器。图像显示在具有可变数量面的球体中。我希望它只在相机方向渲染脸部(以获得更好的性能)。 ThreeJS 会自动执行此操作吗?或者我可以声明不渲染的混搭的特定面吗? 像mash.
我使用十六进制值设置几何颜色 RichGeometry.prototype = new THREE.Geometry(); RichGeometry.prototype.constructor = R
因此,我查看了此处的所有其他影子问题,但似乎没有一个与我的相关,或者我只是忽略了它大约 10 次。 https://gist.github.com/Sinistralis/58249d2f9aefa8
所以我有一个 ThreeJS 场景,并且添加了一些球体(多 Material )。我还添加了定向光: this.light = new THREE.DirectionalLight( 0xFFFFFF
我在“two.js”中创建了一个立方体,但我想创建同一个立方体 3 次,然后将它们作为目标,以便可以使用“Tweenmax”单独对它们进行动画处理 我是 Three.js 的新手,因此我们将不胜感激
我想要实现的是让特定的网格体向特定的向量移动,直到它最终被玩家停止。 到目前为止,我已经成功获取了单击 Canvas 的 XY 坐标,并使用以下代码将它们投影到 3D 中。不幸的是,我不确定采取什么方
我遇到了 Object3D 组中的面上未接收到阴影的问题。 阴影从物体转换并被地面接收,但阴影在应该被接收的时候却没有被彼此接收。 我四处搜寻,但似乎找不到类似的问题,这让我相信我的设置不正确。 有人
我正在尝试为我的类(class)创建一个场景,其中必须克隆一组对象(模型)并将其显示在随机位置。我为此创建了一个函数,但不幸的是,它只能将同一个对象从一个地方传输到另一个地方。我需要添加更多对象而不是
我正在尝试动态更改选定顶点的颜色。引用https://jsfiddle.net/pmankar/m70cpxes/ ,我创建了一个二十面体几何点云几何体,并且在单击事件时我想更改顶点 100 的颜色。
我已将球体添加到场景中,并在场景中添加了一些平面几何图形,当我放大时,我希望平面几何图形看起来更小,当我缩小时,平面几何图形应该显得更大,我不知道如何解决这个问题有人可以帮我解决这个问题吗? 最佳答案
我开始学习使用 Threejs 创建旋转 3D 立方体。我关注了this教程,但为对象的旋转设置动画不起作用。 在此之前,我收到旋转未定义的错误。我在 animate() 中使用以下代码解决了这个问题
当我执行某些几何体的渲染时,我可以在控制台中看到此警告: THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter sho
您好,我有一个疑问: 我已经实现了光线投射器,并且已经进行了手动测试,但是我不知道为什么在3D模型上进行的大多数点击都没有得到交点。 首先,我将向您展示我单击的点,然后向您显示在Web控制台中记录的点
您好,我有一个疑问: 我研究过: https://threejs.org/docs/#api/materials/PointsMaterial 我已经调整了该示例以与我现有的代码一起使用。 目的是在我
我是一名优秀的程序员,十分优秀!