假设您正在绘制较小的渲染目标来填充画布,它应该只是
const rect = renderer.domElement.getBoundingClientRect();
const x = (touches[0].clientX - rect.left) * renderTargetWidth / rect.width;
const y = (touches[0].clientY - rect.top ) * renderTargetHeight / rect.height;
现在 X 和 Y 在渲染目标中以像素为单位,尽管您可能想要翻转 Y
const y = renderTargetHeight -
(touches[0].clientY - rect.top) * renderTargetHeight / rect.height;
注意鼠标也不例外。事实上,这应该工作
function computeRenderTargetRelativePosition(e) {
const rect = renderer.domElement.getBoundingClientRect();
const x = (e.clientX - rect.left) * renderTargetWidth / rect.width;
const y = (e.clientY - rect.top ) * renderTargetHeight / rect.height;
return {x, y};
}
renderer.domElement.addEventListener('mousemove', (e) => {
const pos = computeRenderTargetRelativePosition(e);
... do something with pos...
});
renderer.domElement.addEventListener('touchmove', (e) => {
const pos = computeRenderTargetRelativePosition(e.touches[0]);
... do something with pos...
});
唯一的复杂情况是,如果您应用 CSS 转换,那么您需要不同的代码。
'use strict';
/* global THREE */
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
const rtWidth = 24;
const rtHeight = 12;
const renderTarget = new THREE.WebGLRenderTarget(rtWidth, rtHeight);
const rtCamera = new THREE.OrthographicCamera(0, rtWidth, rtHeight, 0, -1, 1);
const rtScene = new THREE.Scene();
const boxWidth = 1;
const boxHeight = 1;
const boxDepth = 1;
const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);
const rtMaterial = new THREE.MeshBasicMaterial({color: 'red'});
const rtCube = new THREE.Mesh(geometry, rtMaterial);
rtScene.add(rtCube);
const camera = new THREE.Camera();
const scene = new THREE.Scene();
const planeGeo = new THREE.PlaneBufferGeometry(2, 2);
const material = new THREE.MeshBasicMaterial({
//color: 'blue',
map: renderTarget.texture,
});
const plane = new THREE.Mesh(planeGeo, material);
scene.add(plane);
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render(time) {
time *= 0.001;
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
}
// draw render target scene to render target
renderer.setRenderTarget(renderTarget);
renderer.render(rtScene, rtCamera);
renderer.setRenderTarget(null);
// render the scene to the canvas
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
function setPos(e) {
const rect = renderer.domElement.getBoundingClientRect();
const x = (e.clientX - rect.left) * rtWidth / rect.width;
const y = rtHeight - (e.clientY - rect.top ) * rtHeight / rect.height;
rtCube.position.set(x, y, 0);
}
renderer.domElement.addEventListener('mousemove', (e) => {
setPos(e);
});
renderer.domElement.addEventListener('touchmove', (e) => {
e.preventDefault();
setPos(e.touches[0]);
}, {passive: false});
}
main();
body {
margin: 0;
}
#c {
width: 100vw;
height: 100vh;
display: block;
}
<canvas id="c"></canvas>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r105/three.min.js"></script>