【问题标题】:Can't make clickable button in CSS3DObject via Three.js无法通过 Three.js 在 CSS3DObject 中制作可点击按钮
【发布时间】:2022-01-01 03:41:55
【问题描述】:

我的目标是在 CSS3DObject 上制作一个用户可以与之交互的按钮。 我制作了一个由 6 个面(CSS3DObjects)组成的立方体。我的按钮在黄色一侧。 当我尝试单击它时出现问题。在“event.target”的帮助下,我发现我总是点击渲染器 div,但是当我尝试在浏览器检查模式下点击按钮时,我可以毫无问题地做到这一点。我还可以将<iframe> 放入运行良好的 CSS3DObject 中。
我想做什么:

  1. 提供pointer-events: none 的渲染器div 属性和pointer-events: auto 我的css3dobject 属性
  2. 正在更改渲染器 div 和 CSS3DObject 的 z-index 属性

所以我的代码如下所示:

JAVASCRIPT

import * as THREE from './three.module.js';
import {OrbitControls} from './OrbitControls.js'
import { CSS2DRenderer, CSS2DObject } from './CSS2DRenderer.js'
import { CSS3DRenderer, CSS3DObject} from './CSS3DRenderer.js'

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth/window.innerHeight,
  0.1,
  3000
)

camera.position.z = 800
camera.position.x = -800
camera.position.y = 800

let cssRenderer = new CSS3DRenderer();
cssRenderer.setSize( window.innerWidth, window.innerHeight );
cssRenderer.domElement.style.position = 'absolute';
cssRenderer.domElement.style.top = '0px';
document.body.appendChild( cssRenderer.domElement );


let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setClearColor("lightblue")
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)


const cssDiv = cssRenderer.domElement.childNodes[0]
cssDiv.classList.add('scene')
cssRenderer.domElement.classList.add('renderer')


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

let mouse = new THREE.Vector2();

const axesHelper = new THREE.AxesHelper( 1000 );
scene.add( axesHelper );


// RED SIDE
const redDiv = document.createElement('div')
redDiv.classList.add('side')
redDiv.classList.add('red')

let redBlock = new CSS3DObject(redDiv)
redBlock.position.set(0,0,500)
scene.add(redBlock)


// BLUE SIDE
const blueDiv = document.createElement('div')
blueDiv.classList.add('side')
blueDiv.classList.add('blue')

let blueBlock = new CSS3DObject(blueDiv)
blueBlock.position.set(-500,0,0)
blueBlock.rotation.y = -Math.PI/2
scene.add(blueBlock)

// YELLOW SIDE
const yellowDiv = document.createElement('div')
yellowDiv.classList.add('side')
yellowDiv.classList.add('yellow')
yellowDiv.insertAdjacentHTML('afterbegin',`
           <div class="container">
                <button class="test">Please</button>  
           </div>  
        `)

let yellowBlock = new CSS3DObject(yellowDiv)

yellowBlock.position.set(0,500,0)
yellowBlock.rotation.x = -Math.PI/2
scene.add(yellowBlock)



// GREEN SIDE
const greenDiv = document.createElement('div')
greenDiv.classList.add('side')
greenDiv.classList.add('green')

let greenBlock = new CSS3DObject(greenDiv)
greenBlock.position.set(500,0,0)
greenBlock.rotation.y = Math.PI/2
scene.add(greenBlock)

// ORANGE SIDE
const orangeDiv = document.createElement('div')
orangeDiv.classList.add('side')
orangeDiv.classList.add('orange')

let orangeBlock = new CSS3DObject(orangeDiv)
orangeBlock.position.set(0,0,-500)
orangeBlock.rotation.y = Math.PI
scene.add(orangeBlock)

// WHITE SIDE
const whiteDiv = document.createElement('div')
whiteDiv.classList.add('side')
whiteDiv.classList.add('white')

let whiteBlock = new CSS3DObject(whiteDiv)
whiteBlock.position.set(0,-500,0)
whiteBlock.rotation.x = Math.PI/2
scene.add(whiteBlock)

var controls = new OrbitControls(camera, cssRenderer.domElement)
controls.update()

var render = function () {
  requestAnimationFrame(render)

    cssRenderer.render( scene, camera );
    renderer.render(scene, camera)
    controls.update()
}

function onMouseMove(event) {
  event.preventDefault();
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;

  console.log(event.target)

}

render();


window.addEventListener('click', onMouseMove)

CSS

canvas{
  z-index: 0;
  display: block;
  position: absolute;
}

.renderer{
  pointer-events: none;
  z-index: 1;
}

.scene{
  pointer-events: none;
}

.container{
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  pointer-events: auto;
}

.test-button{
  border: 0;
  background-color: coral;
  width: 600px;
  height: 600px;
  cursor: pointer;
  border-radius: 3em;
  font-size: 40px;
  color: white;
  font-weight: 700;
}

.side{
  position: absolute;
  z-index: 1000;
  height: 1000px;
  width: 1000px;
  justify-content: center;
  align-items: center;
  transition: 1s;
  opacity: 1;
  pointer-events: all;
}

.red{
  background-color: #c92626;
}
.blue{
  background-color: #246fff;
}
.yellow{
  background-color: #fff424;
}
.orange{
  background-color: #fd6a0c;
}
.green{
  background-color: #128f02;
}
.white{
  background-color: #ffffff;
}

有什么方法可以避免点击渲染器 div?

【问题讨论】:

    标签: javascript css three.js


    【解决方案1】:

    所以我想我找到了解决方案。正如我之前所说的 &lt;iframe&gt; 工作正常。我所做的是将我的另一个 html 文件放入这个 iframe 中。第二个 html 文件有像 parent.document.querySelector('...') 这样的脚本,它帮助我从父 html 页面获取 html 选择器。希望它会帮助某人

    【讨论】:

      猜你喜欢
      • 2014-02-27
      • 2021-04-08
      • 2019-08-26
      • 2017-08-18
      • 2015-07-29
      • 1970-01-01
      • 1970-01-01
      • 2020-01-17
      • 2020-12-22
      相关资源
      最近更新 更多