javascript - Can't get Three.js onDocumentMouseDown to work correctly -


i've looked @ lot of examples -- , borrowed -- , can't seem work right. want raycaster in ondocumentmousedown pick sprites when user clicks anywhere on visible surface of sprite. i'm getting misaligned result, in sprite may picked if user clicks right, above, or below sprite, , not pick @ if user clicks on left edge of sprite. misaligned, , @ loss figuring out doing wrong. guidance 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 {         (i = 0; < 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 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> 

in maketextsprite() function, after

var textwidth = metrics.width; 

add this

context.strokestyle = "white"; context.linewidth = 5; context.strokerect(0,0,canvas.width, canvas.height); 

and see, sprites have not size think of.

upd. can set size of canvas 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; 

and set scale of sprite

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

jsfiddle example


Comments

Popular posts from this blog

sql server - Cannot query correctly (MSSQL - PHP - JSON) -

php - trouble displaying mysqli database results in correct order -

C++ Linked List -