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
Post a Comment