无法使Three.js onDocumentMouseDown正常工作 [英] Can't get Three.js onDocumentMouseDown to work correctly

查看:68
本文介绍了无法使Three.js onDocumentMouseDown正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看了很多示例-并从中借来了一些-似乎无法使其正常工作.我想要的是让onDocumentMouseDown中的raycaster在用户单击Sprite可见表面上的任意位置时拾取Sprite.我得到的是未对齐的结果,因为如果用户在精灵的上方,下方或下方单击一些,则可能会拾取该精灵,如果用户单击左侧边缘,则根本不会拾取它精灵的所以基本上有些事情是错位的,而我弄不清自己在做什么错.任何指导将不胜感激.

I've looked at a lot of examples -- and borrowed from some -- and can't seem to get this to work right. What I want is for the raycaster in onDocumentMouseDown to pick up sprites when the user clicks anywhere on the visible surface of a sprite. What I'm getting is a misaligned result, in that a sprite may be picked up if the user clicks somewhat to the right, above, or below the sprite, and will not pick it up at all if the user clicks on the left edge of the sprite. So basically something is misaligned, and I am at a loss for figuring out what I am doing wrong. Any guidance would be appreciated.

<script src="/common/three.js"></script>
<script src="/common/Detector.js"></script>
<script src="/common/CanvasRenderer.js"></script>


<script src="/common/GeometryUtils.js"></script>
<script src="/common/OrbitControls.js"></script>

<div id="WebGLCanvas"></div>



<script>
    var container, scene, camera, renderer, controls;
    var keyboard;

</script>

<script>




    // custom global variables
    var mouse = { x: 0, y: 0 };
    var raycaster;
    var sprites = new Array();
    init();
    try {
        for (i = 0; i < 10; i++) {
            var text = "Text " + i;
            var x = Math.random() * 100;
            var y = Math.random() * 100;
            var z = Math.random() * 100;
            var spritey = addOrUPdateSprite(text, i, x, y, z);
        }

    }
    catch (ex) {
        alert("error when creating sprite: " + ex.message);
    }


    animate();



    function init() {
        try {
            scene = new THREE.Scene();
            // CAMERA
            var cont = document.getElementById("WebGLCanvas");
            var SCREEN_WIDTH = window.innerWidth;
            OFFSET_TOP = document.getElementById("WebGLCanvas").getBoundingClientRect().top;
            var SCREEN_HEIGHT = window.innerHeight - OFFSET_TOP;    //;   //-document.getElementById("upper").clientHeight;
            var VIEW_ANGLE = 60;
            var ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT;
            var NEAR = 0.1;
            var FAR = 1000;
            camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
            scene.add(camera);
            camera.position.set(0, 100, 200);
            camera.lookAt(new THREE.Vector3());
            renderer = new THREE.WebGLRenderer({ antialias: true });
            container = document.getElementById('WebGLCanvas');
            container.appendChild(renderer.domElement);
            renderer.setSize(window.innerWidth, SCREEN_HEIGHT);

            controls = new THREE.OrbitControls(camera, renderer.domElement);
            //                spritey.position.normalize();

            raycaster = new THREE.Raycaster();
            document.addEventListener('mousedown', onDocumentMouseDown, false);
            document.addEventListener('touchstart', onDocumentTouchStart, false);
        }
        catch (ex) {
            alert("error " + ex.message);
        }


    }

    function animate() {
        requestAnimationFrame(animate);
        render();
        update();
    }

    function update() {
        controls.update();
    }

    function render() {
        renderer.render(scene, camera);
    }

    function addOrUPdateSprite(text, name, x, y, z) {
        var sprite = scene.getObjectByName(name);
        if (sprite == null) {
            sprite = makeTextSprite(text, { fontsize: 36, borderColor: { r: 255, g: 0, b: 0, a: 1.0 }, backgroundColor: { r: 255, g: 100, b: 100, a: 0.8 } });
            sprite.name = name;
            sprites.push(sprite);
            scene.add(sprite);
        }

        sprite.position.set(x, y, z);
    }

    function makeTextSprite(message, parameters) {
        if (parameters === undefined) parameters = {};
        var fontface = parameters.hasOwnProperty("fontface") ? parameters["fontface"] : "sans-serif";
        var fontsize = parameters.hasOwnProperty("fontsize") ? parameters["fontsize"] : 36;
        var borderThickness = parameters.hasOwnProperty("borderThickness") ? parameters["borderThickness"] : 1;
        var borderColor = parameters.hasOwnProperty("borderColor") ? parameters["borderColor"] : { r: 0, g: 0, b: 0, a: 1.0 };
        var backgroundColor = parameters.hasOwnProperty("backgroundColor") ? parameters["backgroundColor"] : { r: 255, g: 255, b: 255, a: 1.0 };
        var textColor = parameters.hasOwnProperty("textColor") ? parameters["textColor"] : { r: 0, g: 0, b: 0, a: 1.0 };

        var canvas = document.createElement('canvas');
        var context = canvas.getContext('2d');
        context.font = fontsize + "px " + fontface;
        var metrics = context.measureText(message);
        var textWidth = metrics.width;

        context.fillStyle = "rgba(" + backgroundColor.r + "," + backgroundColor.g + "," + backgroundColor.b + "," + backgroundColor.a + ")";
        context.strokeStyle = "rgba(" + borderColor.r + "," + borderColor.g + "," + borderColor.b + "," + borderColor.a + ")";

        context.lineWidth = borderThickness;
        roundRect(context, borderThickness / 2, borderThickness / 2, (textWidth + borderThickness) * 1.1, fontsize * 1.4 + borderThickness, 8);

        context.fillStyle = "rgba(" + textColor.r + ", " + textColor.g + ", " + textColor.b + ", 1.0)";
        context.fillText(message, borderThickness, fontsize + borderThickness);

        var texture = new THREE.Texture(canvas)
        texture.needsUpdate = true;

        var spriteMaterial = new THREE.SpriteMaterial({ map: texture, useScreenCoordinates: false });
        var sprite = new THREE.Sprite(spriteMaterial);
        sprite.scale.set(1.0 * fontsize, 0.5 * fontsize, 1.5 * fontsize);
        return sprite;


    }

    // function for drawing rounded rectangles
    function roundRect(ctx, x, y, w, h, r) {
        ctx.beginPath();
        ctx.moveTo(x + r, y);
        ctx.lineTo(x + w - r, y);
        ctx.quadraticCurveTo(x + w, y, x + w, y + r);
        ctx.lineTo(x + w, y + h - r);
        ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
        ctx.lineTo(x + r, y + h);
        ctx.quadraticCurveTo(x, y + h, x, y + h - r);
        ctx.lineTo(x, y + r);
        ctx.quadraticCurveTo(x, y, x + r, y);
        ctx.closePath();
        ctx.fill();
        ctx.stroke();
    }



    function onDocumentTouchStart(event) {
        event.preventDefault();

        event.clientX = event.touches[0].clientX;
        event.clientY = event.touches[0].clientY;
        onDocumentMouseDown(event);



    }

    function onDocumentMouseDown(event) {
        mouse.x = (event.clientX / renderer.domElement.clientWidth) * 2 - 1;
        mouse.y = -((event.clientY) / renderer.domElement.clientHeight) * 2 + 1;
        raycaster.setFromCamera(mouse, camera);

        var intersects = raycaster.intersectObjects(sprites, true);

        if (intersects.length > 0) {
            var obj = intersects[0].object;

            alert(obj.name);

            event.preventDefault();
        }


    }




</script>

推荐答案

在您的 makeTextSprite()函数中,

var textWidth = metrics.width;

添加此

context.strokeStyle = "white";
context.lineWidth = 5;
context.strokeRect(0,0,canvas.width, canvas.height);

您会看到,您的精灵没有您想像的大小.

and you will see, that your sprites have not the size you think of.

UPD.您可以像这样设置画布的大小

UPD. You can set the size of a canvas like this

var ctxFont = "bold " + fontsize + "px " + fontface;
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
context.font = ctxFont;
var metrics = context.measureText(message);
var textWidth = metrics.width;

canvas.width = textWidth + borderThickness * 2;
canvas.height = fontsize * 1.2 + (borderThickness * 2);
context = canvas.getContext('2d');
context.font = ctxFont;

然后设置精灵的比例

sprite.scale.set(canvas.width / 10, canvas.height /  10, 1);

jsfiddle 示例

这篇关于无法使Three.js onDocumentMouseDown正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆