繁体   English   中英

对单个实体进行Aframe纹理控制

[英]Aframe texture control over individual entities

我想知道如何在一个实体上设置纹理,但是只能在那个实体上设置纹理,然后通过选择纹理按钮来放置更多内容,所以我的代码无法正常工作,但是我想使其功能更像我的世界原始的《我的世界》框架演示做了。 如果有人可以使我的代码正常工作,那将是真正的帮助。 所有被注释掉的脚本是因为我想找到一种更好的方法来做我想做的事情。 本质上,我想在底部的菜单中选择一个纹理,然后在我的实体上使用该纹理。

 <!DOCTYPE html> <html> <head> <script src="https://aframe.io/releases/0.9.0/aframe.min.js"></script> <script src="https://unpkg.com/aframe-controller-cursor-component@0.2.x/dist/aframe-controller-cursor-component.min.js"></script> <script> /** * Snap entity to the closest interval specified by `snap`. * Offset entity by `offset`. */ AFRAME.registerComponent('snap', { dependencies: ['position'], schema: { offset: {type: 'vec3'}, snap: {type: 'vec3'} }, init: function () { this.originalPos = this.el.getAttribute('position'); }, update: function () { const data = this.data; const pos = AFRAME.utils.clone(this.originalPos); pos.x = Math.floor(pos.x / data.snap.x) * data.snap.x + data.offset.x; pos.y = Math.floor(pos.y / data.snap.y) * data.snap.y + data.offset.y; pos.z = Math.floor(pos.z / data.snap.z) * data.snap.z + data.offset.z; this.el.setAttribute('position', pos); } }); </script> <script>/** * Spawn entity at the intersection point on click, given the properties passed. * * `<a-entity intersection-spawn="mixin: box; material.color: red">` will spawn * `<a-entity mixin="box" material="color: red">` at intersection point. */ AFRAME.registerComponent('intersection-spawn', { schema: { default: '', parse: AFRAME.utils.styleParser.parse }, init: function () { const data = this.data; const el = this.el; el.addEventListener(data.event, evt => { // Create element. (element create below v const spawnEl = document.createElement('a-entity'); // Snap intersection point to grid and offset from center. (position) spawnEl.setAttribute('position', evt.detail.intersection.point); // Set components and properties. Object.keys(data).forEach(name => { if (name === 'event') { return; } AFRAME.utils.entity.setComponentProperty(spawnEl, name, data[name]); }); // Append to scene. el.sceneEl.appendChild(spawnEl); }); } });</script> <script> function startTimer(duration, display) { var timer = duration, minutes, seconds; setInterval(function () { minutes = parseInt(timer / 60, 10) seconds = parseInt(timer % 60, 10); minutes = minutes < 10 ? "0" + minutes : minutes; seconds = seconds < 10 ? "0" + seconds : seconds; display.textContent = minutes + ":" + seconds; if (--timer < 0) { timer = duration; } }, 1000); } window.onload = function () { var fiveMinutes = 60 * 10, display = document.querySelector('#time'); startTimer(fiveMinutes, display); }; </script> <style> .transparentBox { width: 200px; background-color: #6969697a; margin-right: 600px; border-radius: 10px; border: 2px solid black; } html { width: 800px; height: 600px; cursor: crosshair; } a-scene { cursor: crosshair; width: 800px; height: 600px; } body { cursor: crosshair; width: 800px; height: 600px; } .Container { margin-right: 8px; } </style> </head> <body> <!-- aframe overlay --> <div class="Container" style="position:relative;"> <!-- <a-scene id="updateMe" inspector="https://cdn.jsdelivr.net/gh/aframevr/aframe-inspector@master/dist/aframe-inspector.min.js"> --> <a-scene embedded> <a-assets> <img id="groundTexture" src="floor.jpg"> <img id="skyTexture" src="https://cdn.aframe.io/a-painter/images/sky.jpg"> <a-mixin id="voxel1" geometry="primitive: box; height: 0.6; width: 0.6; depth: 0.6" material="id: theImage; src: Box.jpg; color: #696969; roughness: 1; metalness: 0" snap="offset: 0.4 0.4 0.4; snap: 0.6 0.6 0.6" ></a-mixin> <a-mixin id="voxel2" geometry="primitive: box; height: 0.6; width: 0.6; depth: 0.6" material="id: theImage; src: Brick.jpg; color: #696969; roughness: 1; metalness: 0" snap="offset: 0.4 0.4 0.4; snap: 0.6 0.6 0.6" ></a-mixin> <a-mixin id="voxel3" geometry="primitive: box; height: 0.6; width: 0.6; depth: 0.6" material="id: theImage; src: Steel.jpg; color: #696969; roughness: 1; metalness: 0" snap="offset: 0.4 0.4 0.4; snap: 0.6 0.6 0.6" ></a-mixin> <a-mixin id="voxel4" geometry="primitive: box; height: 0.6; width: 0.6; depth: 0.6" material="id: theImage; src: Pcb.jpg; color: #696969; roughness: 1; metalness: 0" snap="offset: 0.4 0.4 0.4; snap: 0.6 0.6 0.6" ></a-mixin> <a-mixin id="voxel5" geometry="primitive: box; height: 0.6; width: 0.6; depth: 0.6" material="id: theImage; src: Grass.jpg; color: #696969; roughness: 1; metalness: 0" snap="offset: 0.4 0.4 0.4; snap: 0.6 0.6 0.6" ></a-mixin> <a-mixin id="voxel6" geometry="primitive: box; height: 0.6; width: 0.6; depth: 0.6" material="id: theImage; src: Ice.jpg; color: #696969; roughness: 1; metalness: 0" snap="offset: 0.4 0.4 0.4; snap: 0.6 0.6 0.6" ></a-mixin> <a-mixin id="voxel7" geometry="primitive: box; height: 0.6; width: 0.6; depth: 0.6" material="id: theImage; src: Fabric.jpg; color: #696969; roughness: 1; metalness: 0" snap="offset: 0.4 0.4 0.4; snap: 0.6 0.6 0.6" ></a-mixin> </a-assets> <a-obj-model rotation="-90 45 0" position="0 2 0" src="tinker.obj" mtl="obj.mtl"></a-obj-model> <a-cylinder id="ground" src="#groundTexture" radius="30" height="0.1"></a-cylinder> <a-sky id="background" src="#skyTexture" theta-length="90" radius="30"></a-sky> <!-- Camera. --> <a-camera fly="true" position="0 0.75 15" wasd-controls="acceleration: 20" wasd-controls-enabled="true" fov="90" reverse-mouse-drag="false"> <a-cursor id="Save1" intersection-spawn="event: click; mixin: voxel1"></a-cursor> <a-cursor id="Save2" intersection-spawn="event: click; mixin: voxel2"></a-cursor> <a-cursor id="Save3" intersection-spawn="event: click; mixin: voxel3"></a-cursor> <a-cursor id="Save4" intersection-spawn="event: click; mixin: voxel4"></a-cursor> <a-cursor id="Save5" intersection-spawn="event: click; mixin: voxel5"></a-cursor> <a-cursor id="Save6" intersection-spawn="event: click; mixin: voxel6"></a-cursor> <a-cursor id="Save7" intersection-spawn="event: click; mixin: voxel7"></a-cursor> </a-camera> </a-scene> <!-- /aframe overlay --> <center> <div style="position:absolute; margin-right:8px; top:0px; width:205px; height:180px; left:0px; z-index:1000;"> <div class="transparentBox"> <b><h1 color="#FFFFFF" id="time">10:00</h1></b> <p style="font-size:20px;font-family:monospace;margin-top:-20px;">Camera Height:</p> <h1><b><a>&uarr;</a>~~<a>&darr;</a></b></h1> <iframe src="250-milliseconds-of-silence.mp3" allow="autoplay" id="audio" style="display:none"></iframe> <audio autoplay loop id="track"> <source src="Magic_Scout_-_Cottages.mp3" type="audio/mpeg"> Your browser does not support the audio element. </audio><center> <button class="button" id="myBtn">Menu</button> </center> </div> <div id="myModal" class="modal"> <center> <!-- Modal content --> <div class="modal-content"> <span id="clickMe" type="button" value="clickme" onclick="startTimer()" class="close">&times;</span> <center> <p class="beginMenuText"><b>Welcome to SandBox!</b></p> <p class="Text">WASD to move, Space place blocks.</p> <p class="Text2">You have 10 min. before the game restarts and all is lost.</p> <p class="Text2point5">Have fun...</p> </center> <p class="Text3"><b><u>Credits:</u></b></p> <p class="Text4">All music by <b>Kevin MacLeod</b></p> <p class="Text5"><b>Aframe</b> by the Aframe authors.</p> <p class="Text6">(Licenced under the <b>MIT Licence</b>)</p> <p class="Text7">Inspiration from other <b>WebVR Projects.</b></p> <p class="Text8">Voxel textures can be changed using the menu at the <b>bottom</b>.</p> <p class="Text9"><b>Enjoy!</b></p> <div class="unmute" onclick="document.getElementById('track').muted = !document.getElementById('track').muted;$(this).toggleClass('mute')"></div> </div> </center> </div> <div class="textureMenu"> <div class="textureBox" id="Kill1" ><img src="Box.jpg" height="45" width="45"></div> <p class="spacer">~</p> <div class="textureBox" id="Kill2"><img src="Brick.jpg" height="45" width="45"></div> <p class="spacer">~</p> <div class="textureBox" id="Kill3"><img src="Steel.jpg" height="45" width="45"></div> <p class="spacer">~</p> <div class="textureBox" id="Kill4"><img src="Pcb.jpg" height="45" width="45"></div> <p class="spacer">~</p> <div class="textureBox" id="Kill5"><img src="Grass.jpg" height="45" width="45"></div> <p class="spacer">~</p> <div class="textureBox" id="Kill6"><img src="Ice.jpg" height="45" width="45"></div> <p class="spacer">~</p> <div class="textureBox" id="Kill7"><img src="Fabric.jpg" height="45" width="45"></div> </div> </div> </center> </div> </body> <head> <!--<script> document.getElementById('Kill1').addEventListener('click', function () { var mixinEl = document.getElementById('Save1'); if (mixinEl.getAttribute('mixin') === 'voxel') { mixinEl.setAttribute('mixin',: 'voxel1'); } }; </script> <script> document.getElementById('Kill2').addEventListener('click', function () { var mixinEl = document.getElementById('Save2'); if (mixinEl.getAttribute('mixin') === 'voxel') { mixinEl.setAttribute('mixin',: 'voxel2'); } }; </script> <script> document.getElementById('Kill3').addEventListener('click', function () { var mixinEl = document.getElementById('Save3'); if (mixinEl.getAttribute('mixin') === 'voxel') { mixinEl.setAttribute('mixin',: 'voxel3'); } }; </script> <script> document.getElementById('Kill4').addEventListener('click', function () { var mixinEl = document.getElementById('Save4'); if (mixinEl.getAttribute('mixin') === 'voxel') { mixinEl.setAttribute('mixin',: 'voxel4'); } }; </script> <script> document.getElementById('Kill5').addEventListener('click', function () { var mixinEl = document.getElementById('Save5'); if (mixinEl.getAttribute('mixin') === 'voxel') { mixinEl.setAttribute('mixin',: 'voxel5'); } }; </script> <script> document.getElementById('Kill6').addEventListener('click', function () { var mixinEl = document.getElementById('Save6'); if (mixinEl.getAttribute('mixin') === 'voxel') { mixinEl.setAttribute('mixin',: 'voxel6'); } }; </script> <script> document.getElementById('Kill7').addEventListener('click', function () { var mixinEl = document.getElementById('Save7'); if (mixinEl.getAttribute('mixin') === 'voxel') { mixinEl.setAttribute('mixin',: 'voxel7'); } }; </script>--> <style> .spacer { float: left; } .textureBox { width: 47px; height: 47px; border: 2px solid black; float: left; } .textureMenu { height: 50px; width: 412px; padding: 10px; background-color: #6969697a; border: 2px solid black; border-radius: 10px; display:inline-block; position: absolute; left: 200%; top: 313%; transform: translate(-50%, -50%); } .Text9 { font-size: 25px; font-family: monospace; margin-top: -13px; border-bottom: 2px dashed black; } .Text8 { font-size: 25px; font-family: monospace; margin-top: -13px; } .Text7 { font-size: 18px; font-family: monospace; margin-top: -13px; border-bottom: 2px dashed black; } .Text6 { font-size: 10px; font-family: monospace; margin-top: -20px; line-height: 1.3; } .Text5 { font-size: 15px; font-family: monospace; margin-top: -22px; line-height: 1.3; } .Text4 { font-size: 15px; font-family: monospace; margin-top: -27px; line-height: 1.3; } .Text3 { font-size: 20px; font-family: monospace; margin-top: -30px; line-height: 1.3; } .Text2point5 { font-size: 25px; font-family: monospace; margin-top: -30px; line-height: 1; } .Text2 { font-size: 25px; font-family: monospace; margin-top: -30px; line-height: 1; } .Text { font-size: 25px; font-family: monospace; margin-top: -40px; } .beginMenuText { font-size: 45px; font-family: monospace; margin-top: auto; border-bottom: 3px dashed black; } .unmute { background-image: url(http://franriavilla.in/images/unmute.png); background-size: cover; width: 35px; height: 30px; cursor: pointer; } .mute { background-image: url(http://franriavilla.in/images/mute.png); } /* The Modal (background) */ .modal { display: initial; /* Hidden by default */ position: fixed; /* Stay in place */ z-index: 1; /* Sit on top */ left: 0; top: 0; width: 100%; /* Full width */ height: 600px; /* Full height */ overflow: auto; /* Enable scroll if needed */ background-color: rgb(0,0,0); /* Fallback color */ background-color: rgba(0,0,0,0.65); /* Black w/ opacity */ width: 800px; margin-right: 8px; margin-top: 8px; } /* Modal Content/Box */ .modal-content { background-color: #94989e; margin-top: 8px; /* 15% from the top and centered */ padding: 20px; border: 1px solid #888; width: 500px; /* Could be more or less, depending on screen size */ border-radius: 20px; z-index: 20000; } /* The Close Button */ .close { color: #FFF; float: right; margin-top: -15px; font-size: 35px; font-weight: bold; } .close:hover, .close:focus { color: black; text-decoration: none; cursor: pointer; } </style> <script> // Get the modal var modal = document.getElementById('myModal'); // Get the button that opens the modal var btn = document.getElementById("myBtn"); // Get the <span> element that closes the modal var span = document.getElementsByClassName("close")[0]; // When the user clicks on the button, open the modal btn.onclick = function() { modal.style.display = "block"; } // When the user clicks on <span> (x), close the modal span.onclick = function() { modal.style.display = "none"; } // When the user clicks anywhere outside of the modal, close it window.onclick = function(event) { if (event.target == modal) { modal.style.display = "none"; } } </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <style> .button { border-radius: 25px; font-size: 20px; color: white; background-color: #6969697a; border-color: white; } </style> </head> </html> 

切换纹理可以通过两种方式完成

  • 诸如<a-box><a-sphere>实体之类<a-box>框架原语很简单。 只需更改material.src属性

     el.setAttribute('material', 'src', newTexture) 
  • 模型可能很难处理,因为您需要切换mesh.map.texture属性(可能在所有子对象上,而不仅仅是在一个网格上)。

     var mesh = this.el.getObject3D('mesh') var loader = new THREE.TextureLoader(); loader.load( url, (texture) => { // onLoad callback mesh.material.map = texture mesh.material.needsUpdate = true this.switch = !this.switch } ) 


选择可能以百万分之一的方式完成。

最初,我想存储有关纹理的信息,并在单击<a-box>时访问它,但是一种简单的方法是拥有几张图像

 <img class=".images" ....> <img class=".images" ....> 

在每个无框架原语上的组件是:

在这些图像上检测点击->存储信息->单击我们时使用它:

检测图像点击:

this.el.addEventListener('click', (e) => {
  if (!this.selectedTexture) {
  return
  }
  this.el.setAttribute("material", "src", this.selectedTexture)
})

单击时应用纹理:

 this.el.addEventListener('click', (e) => { if (!this.selectedTexture) { return } this.el.setAttribute("material", "src", this.selectedTexture) }) 

小提琴包含以上所有内容。 两个框可单独切换纹理,其余两个框将应用所选图像作为纹理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM