我正在使用Threejs画布渲染3d模型,并使用另一个(隐藏的)Fabricjs画布作为纹理应用。
我实现了将3d坐标从threejs画布转换为2d画布的功能。现在,我需要按照this问题的评论中的建议,将3d画布上的单击和拖动事件“复制”或“散发”到隐藏的2d画布上。
我和我的进步犯了一个密码。如果单击左画布,则将在相同的坐标中生成一个点,但会在2d画布中生成一个点。 我需要能够直接从左侧threejs画布中单击并拖动画布对象。
查看我制作的密码笔 Codepen
<div id="c-left">
<h3>Renderer</h3>
<div id="renderer"></div>
</div>
<div id="c-right">
<h3>Canvas</h3>
<canvas id="canvas" width="512" height="512"></canvas>
</div>
<script>
console.clear();
console.log("starting scripts...");
/**
* Fabricjs
* @type {fabric}
*/
var canvas = new fabric.Canvas( "canvas" );
canvas.backgroundColor = "#FFBE9F";
var rectangle = new fabric.Rect( {
top: 100,
left: 100,
fill: '#FF6E27',
width: 100,
height: 100,
transparentCorners: false,
centeredScaling: true,
borderColor: 'black',
cornerColor: 'black',
corcerStrokeColor: 'black'
} );
canvas.add( rectangle );
/**
* Threejs
*/
var containerHeight = "512";
var containerWidth = "512";
var camera, renderer, container, scene, texture, material, geometry,
cube;
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var onClickPosition = new THREE.Vector2();
init();
animate();
/**
* Configurator init function
*/
function init() {
/**
* Camera
*/
camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 0.01, 100 );
camera.position.set( 0, 0, 3.5 );
/**
* Renderer
*/
container = document.getElementById( "renderer" );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( containerWidth, containerHeight );
camera.aspect = container.clientWidth / container.clientHeight;
camera.updateProjectionMatrix();
container.appendChild( renderer.domElement );
/**
* Scene
*/
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x000000 );
/**
* Texture and material
*/
texture = new THREE.Texture( document.getElementById( "canvas" ) );
texture.anisotropy = renderer.capabilities.getMaxAnisotropy();
material = new THREE.MeshBasicMaterial( { map: texture } );
/**
* Model
*/
geometry = new THREE.BoxGeometry( 1, 1, 1 );
cube = new THREE.Mesh( geometry, material );
scene.add( cube );
}
/**
* Configurator frame render function
*/
function animate() {
requestAnimationFrame( animate );
cube.rotation.x += 0.004;
cube.rotation.y += 0.001;
texture.needsUpdate = true;
renderer.render( scene, camera );
}
/**
* Listeners
*/
container.addEventListener( "mousedown", onMouseClick, false );
/**
* Other methods
*/
function onMouseClick( evt ) {
evt.preventDefault();
var array = getMousePosition( container, evt.clientX, evt.clientY );
onClickPosition.fromArray( array );
var intersects = getIntersects( onClickPosition, scene.children );
if ( intersects.length > 0 && intersects[ 0 ].uv ) {
var uv = intersects[ 0 ].uv;
intersects[ 0 ].object.material.map.transformUv( uv );
var circle = new fabric.Circle({
radius: 3,
left: getRealPosition( "x", uv.x ),
top: getRealPosition( "y", uv.y ),
fill: 'red'
});
canvas.add( circle );
}
}
function getRealPosition( axis, value ) {
let CORRECTION_VALUE = axis === "x"
? 4.5
: 5.5;
return Math.round( value * 512 ) - CORRECTION_VALUE;
}
var getMousePosition = function ( dom, x, y ) {
var rect = dom.getBoundingClientRect();
return [ ( x - rect.left ) / rect.width, ( y - rect.top ) / rect.height ];
};
var getIntersects = function ( point, objects ) {
mouse.set( ( point.x * 2 ) - 1, - ( point.y * 2 ) + 1 );
raycaster.setFromCamera( mouse, camera );
return raycaster.intersectObjects( objects );
};
</script>
答案 0 :(得分:0)
您需要使用element.dispatchEvent。
您创建一个新事件:
var evt2 = new Event('mousedown', { clientX: value, clientY: value2 });
您发现值和value2从圆的顶部和左侧开始,并将在canvas._offset
中找到的x和y的值相加
此时,您的evt2具有正确的值,您可以使用
canvas.upperCanvasEl.dispatchEvent(evt2);